Mercurial > projects > ddmd
comparison dmd/TemplateDeclaration.d @ 130:60bb0fe4563e
dmdfe 2.037 first main iteration
author | Eldar Insafutdinov <e.insafutdinov@gmail.com> |
---|---|
date | Thu, 09 Sep 2010 22:51:44 +0100 |
parents | e6e542f37b94 |
children | 206db751bd4c |
comparison
equal
deleted
inserted
replaced
129:010eb8f0e18d | 130:60bb0fe4563e |
---|---|
17 import dmd.TypeDelegate; | 17 import dmd.TypeDelegate; |
18 import dmd.IntegerExp; | 18 import dmd.IntegerExp; |
19 import dmd.TypeSArray; | 19 import dmd.TypeSArray; |
20 import dmd.StringExp; | 20 import dmd.StringExp; |
21 import dmd.TOK; | 21 import dmd.TOK; |
22 import dmd.Argument; | 22 import dmd.Parameter; |
23 import dmd.CtorDeclaration; | 23 import dmd.CtorDeclaration; |
24 import dmd.TypeFunction; | 24 import dmd.TypeFunction; |
25 import dmd.TY; | 25 import dmd.TY; |
26 import dmd.OutBuffer; | 26 import dmd.OutBuffer; |
27 import dmd.Declaration; | 27 import dmd.Declaration; |
542 | 542 |
543 version (DMDV2) { | 543 version (DMDV2) { |
544 if (m && constraint && !(flag & 1)) | 544 if (m && constraint && !(flag & 1)) |
545 { /* Check to see if constraint is satisfied. | 545 { /* Check to see if constraint is satisfied. |
546 */ | 546 */ |
547 makeParamNamesVisibleInConstraint(paramscope); | |
547 Expression e = constraint.syntaxCopy(); | 548 Expression e = constraint.syntaxCopy(); |
548 paramscope.flags |= SCOPE.SCOPEstaticif; | 549 paramscope.flags |= SCOPE.SCOPEstaticif; |
549 e = e.semantic(paramscope); | 550 e = e.semantic(paramscope); |
550 e = e.optimize(WANTvalue | WANTinterpret); | 551 e = e.optimize(WANTvalue | WANTinterpret); |
551 if (e.isBool(true)) { | 552 if (e.isBool(true)) { |
685 size_t nargsi; // array size of targsi | 686 size_t nargsi; // array size of targsi |
686 int fptupindex = -1; | 687 int fptupindex = -1; |
687 int tuple_dim = 0; | 688 int tuple_dim = 0; |
688 MATCH match = MATCHexact; | 689 MATCH match = MATCHexact; |
689 FuncDeclaration fd = onemember.toAlias().isFuncDeclaration(); | 690 FuncDeclaration fd = onemember.toAlias().isFuncDeclaration(); |
690 Arguments fparameters; // function parameter list | 691 Parameters fparameters; // function parameter list |
691 int fvarargs; // function varargs | 692 int fvarargs; // function varargs |
692 scope Objects dedtypes = new Objects(); // for T:T*, the dedargs is the T*, dedtypes is the T | 693 scope Objects dedtypes = new Objects(); // for T:T*, the dedargs is the T*, dedtypes is the T |
693 | 694 |
694 static if (false) | 695 static if (false) |
695 { | 696 { |
715 ScopeDsymbol paramsym = new ScopeDsymbol(); | 716 ScopeDsymbol paramsym = new ScopeDsymbol(); |
716 paramsym.parent = scope_.parent; | 717 paramsym.parent = scope_.parent; |
717 Scope paramscope = scope_.push(paramsym); | 718 Scope paramscope = scope_.push(paramsym); |
718 | 719 |
719 TemplateTupleParameter tp = isVariadic(); | 720 TemplateTupleParameter tp = isVariadic(); |
721 int tp_is_declared = 0; | |
720 | 722 |
721 static if (false) | 723 static if (false) |
722 { | 724 { |
723 for (i = 0; i < dedargs.dim; i++) | 725 for (i = 0; i < dedargs.dim; i++) |
724 { | 726 { |
755 for (size_t i = 0; i < tuple_dim; i++) | 757 for (size_t i = 0; i < tuple_dim; i++) |
756 { | 758 { |
757 t.objects[i] = targsi[n + i]; | 759 t.objects[i] = targsi[n + i]; |
758 } | 760 } |
759 declareParameter(paramscope, tp, t); | 761 declareParameter(paramscope, tp, t); |
762 tp_is_declared = 1; | |
760 } | 763 } |
761 else | 764 else |
762 n = nargsi; | 765 n = nargsi; |
763 | 766 |
764 memcpy(dedargs.ptr, targsi.ptr, n * (*dedargs.ptr).sizeof); | 767 memcpy(dedargs.ptr, targsi.ptr, n * (*dedargs.ptr).sizeof); |
806 assert(fctor); | 809 assert(fctor); |
807 fparameters = fctor.arguments; | 810 fparameters = fctor.arguments; |
808 fvarargs = fctor.varargs; | 811 fvarargs = fctor.varargs; |
809 } | 812 } |
810 | 813 |
811 nfparams = Argument.dim(fparameters); // number of function parameters | 814 nfparams = Parameter.dim(fparameters); // number of function parameters |
812 nfargs = fargs ? fargs.dim : 0; // number of function arguments | 815 nfargs = fargs ? fargs.dim : 0; // number of function arguments |
813 | 816 |
814 /* Check for match of function arguments with variadic template | 817 /* Check for match of function arguments with variadic template |
815 * parameter, such as: | 818 * parameter, such as: |
816 * | 819 * |
819 */ | 822 */ |
820 if (tp) // if variadic | 823 if (tp) // if variadic |
821 { | 824 { |
822 if (nfparams == 0 && nfargs != 0) // if no function parameters | 825 if (nfparams == 0 && nfargs != 0) // if no function parameters |
823 { | 826 { |
827 if (tp_is_declared) | |
828 goto L2; | |
824 auto t = new Tuple(); | 829 auto t = new Tuple(); |
825 //printf("t = %p\n", t); | 830 //printf("t = %p\n", t); |
826 dedargs[parameters.dim - 1] = t; | 831 dedargs[parameters.dim - 1] = t; |
827 declareParameter(paramscope, tp, t); | 832 declareParameter(paramscope, tp, t); |
828 goto L2; | 833 goto L2; |
846 continue; | 851 continue; |
847 | 852 |
848 if (fvarargs) // variadic function doesn't | 853 if (fvarargs) // variadic function doesn't |
849 goto Lnomatch; // go with variadic template | 854 goto Lnomatch; // go with variadic template |
850 | 855 |
856 if (tp_is_declared) | |
857 goto L2; | |
858 | |
851 /* The types of the function arguments | 859 /* The types of the function arguments |
852 * now form the tuple argument. | 860 * now form the tuple argument. |
853 */ | 861 */ |
854 auto t = new Tuple(); | 862 auto t = new Tuple(); |
855 dedargs[parameters.dim - 1] = t; | 863 dedargs[parameters.dim - 1] = t; |
913 break; | 921 break; |
914 i += tuple_dim - 1; | 922 i += tuple_dim - 1; |
915 continue; | 923 continue; |
916 } | 924 } |
917 | 925 |
918 Argument fparam = Argument.getNth(fparameters, i); | 926 auto fparam = Parameter.getNth(fparameters, i); |
919 | 927 |
920 if (i >= nfargs) // if not enough arguments | 928 if (i >= nfargs) // if not enough arguments |
921 { | 929 { |
922 if (fparam.defaultArg) | 930 if (fparam.defaultArg) |
923 { | 931 { |
961 if (!m && fparam.type.toBasetype().ty == Tdelegate) | 969 if (!m && fparam.type.toBasetype().ty == Tdelegate) |
962 { | 970 { |
963 TypeDelegate td = cast(TypeDelegate)fparam.type.toBasetype(); | 971 TypeDelegate td = cast(TypeDelegate)fparam.type.toBasetype(); |
964 TypeFunction tf = cast(TypeFunction)td.next; | 972 TypeFunction tf = cast(TypeFunction)td.next; |
965 | 973 |
966 if (!tf.varargs && Argument.dim(tf.parameters) == 0) | 974 if (!tf.varargs && Parameter.dim(tf.parameters) == 0) |
967 { | 975 { |
968 m = farg.type.deduceType(paramscope, tf.next, parameters, dedtypes); | 976 m = farg.type.deduceType(paramscope, tf.next, parameters, dedtypes); |
969 if (!m && tf.next.toBasetype().ty == Tvoid) | 977 if (!m && tf.next.toBasetype().ty == Tvoid) |
970 m = MATCHconvert; | 978 m = MATCHconvert; |
971 } | 979 } |
1098 | 1106 |
1099 version (DMDV2) { | 1107 version (DMDV2) { |
1100 if (constraint) | 1108 if (constraint) |
1101 { /* Check to see if constraint is satisfied. | 1109 { /* Check to see if constraint is satisfied. |
1102 */ | 1110 */ |
1111 makeParamNamesVisibleInConstraint(paramscope); | |
1103 Expression e = constraint.syntaxCopy(); | 1112 Expression e = constraint.syntaxCopy(); |
1104 paramscope.flags |= SCOPE.SCOPEstaticif; | 1113 paramscope.flags |= SCOPE.SCOPEstaticif; |
1105 e = e.semantic(paramscope); | 1114 e = e.semantic(paramscope); |
1106 e = e.optimize(WANTvalue | WANTinterpret); | 1115 e = e.optimize(WANTvalue | WANTinterpret); |
1107 if (e.isBool(true)) { | 1116 if (e.isBool(true)) { |
1364 */ | 1373 */ |
1365 override bool isOverloadable() | 1374 override bool isOverloadable() |
1366 { | 1375 { |
1367 return true; | 1376 return true; |
1368 } | 1377 } |
1378 | |
1379 /**************************** | |
1380 * Declare all the function parameters as variables | |
1381 * and add them to the scope | |
1382 */ | |
1383 void makeParamNamesVisibleInConstraint(Scope paramscope) | |
1384 { | |
1385 /* We do this ONLY if there is only one function in the template. | |
1386 */ | |
1387 FuncDeclaration fd = onemember && onemember.toAlias() ? | |
1388 onemember.toAlias().isFuncDeclaration() : NULL; | |
1389 if (fd) | |
1390 { | |
1391 paramscope.parent = fd; | |
1392 Parameters fparameters; // function parameter list | |
1393 int fvarargs; // function varargs | |
1394 if (fd.type) | |
1395 { | |
1396 assert(fd.type.ty == Tfunction); | |
1397 TypeFunction fdtype = cast(TypeFunction )fd.type; | |
1398 fparameters = fdtype.parameters; | |
1399 fvarargs = fdtype.varargs; | |
1400 } | |
1401 else // Constructors don't have type's | |
1402 { CtorDeclaration fctor = fd.isCtorDeclaration(); | |
1403 assert(fctor); | |
1404 fparameters = fctor.arguments; | |
1405 fvarargs = fctor.varargs; | |
1406 } | |
1407 size_t nfparams = Parameter.dim(fparameters); // Num function parameters | |
1408 for (int i = 0; i < nfparams; i++) | |
1409 { | |
1410 Parameter fparam = Parameter.getNth(fparameters, i).syntaxCopy(); | |
1411 if (!fparam.ident) | |
1412 continue; // don't add it, if it has no name | |
1413 Type vtype = fparam.type.syntaxCopy(); | |
1414 // isPure will segfault if called on a ctor, because fd->type is null. | |
1415 if (fd.type && fd.isPure()) | |
1416 vtype = vtype.addMod(MODconst); | |
1417 VarDeclaration v = new VarDeclaration(loc, vtype, fparam.ident, null); | |
1418 v.storage_class |= STCparameter; | |
1419 // Not sure if this condition is correct/necessary. | |
1420 // It's from func.c | |
1421 if (//fd->type && fd->type->ty == Tfunction && | |
1422 fvarargs == 2 && i + 1 == nfparams) | |
1423 v.storage_class |= STCvariadic; | |
1424 | |
1425 v.storage_class |= fparam.storageClass & (STCin | STCout | STCref | STClazy | STCfinal | STC_TYPECTOR | STCnodtor); | |
1426 v.semantic(paramscope); | |
1427 if (!paramscope.insert(v)) | |
1428 error("parameter %s.%s is already defined", toChars(), v.toChars()); | |
1429 else | |
1430 v.parent = this; | |
1431 } | |
1432 } | |
1433 } | |
1369 } | 1434 } |