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 }