| 476 | 476 | e = new CommaExp(loc, ae, new VarExp(loc, tmp)); |
|---|
| 477 | 477 | e = e->semantic(sc); |
|---|
| 478 | 478 | } |
|---|
| 479 | 479 | return e; |
|---|
| 480 | 480 | } |
|---|
| 481 | 481 | #endif |
|---|
| 482 | 482 | |
|---|
| 483 | 483 | /**************************************** |
|---|
| 484 | 484 | * Now that we know the exact type of the function we're calling, |
|---|
| 485 | 485 | * the arguments[] need to be adjusted: |
|---|
| 486 | 486 | * 1. implicitly convert argument to the corresponding parameter type |
|---|
| 487 | 487 | * 2. add default arguments for any missing arguments |
|---|
| 488 | 488 | * 3. do default promotions on arguments corresponding to ... |
|---|
| 489 | 489 | * 4. add hidden _arguments[] argument |
|---|
| 490 | 490 | * 5. call copy constructor for struct value arguments |
|---|
| 491 | 491 | * Returns: |
|---|
| 492 | 492 | * return type from function |
|---|
| 493 | 493 | */ |
|---|
| 494 | 494 | |
|---|
| 495 | 495 | Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf, |
|---|
| 497 | 497 | { |
|---|
| 498 | 498 | //printf("functionParameters()\n"); |
|---|
| 499 | 499 | assert(arguments); |
|---|
| 500 | 500 | size_t nargs = arguments ? arguments->dim : 0; |
|---|
| 501 | 501 | size_t nparams = Parameter::dim(tf->parameters); |
|---|
| 502 | 502 | |
|---|
| 503 | 503 | if (nargs > nparams && tf->varargs == 0) |
|---|
| 504 | 504 | error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars()); |
|---|
| 505 | 505 | |
|---|
| 506 | 506 | unsigned n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams) |
|---|
| 507 | 507 | |
|---|
| 508 | 508 | unsigned wildmatch = 0; |
|---|
| 509 | 509 | int done = 0; |
|---|
| 510 | 510 | for (size_t i = 0; i < n; i++) |
|---|
| 511 | 511 | { |
|---|
| 512 | 512 | Expression *arg; |
|---|
| 513 | 513 | |
|---|
| 514 | 514 | if (i < nargs) |
|---|
| 515 | 515 | arg = (Expression *)arguments->data[i]; |
|---|
| 516 | 516 | else |
|---|
| 762 | 762 | !se->var->isFuncDeclaration()->isUnique()) |
|---|
| 763 | 763 | arg->error("function %s is overloaded", arg->toChars()); |
|---|
| 764 | 764 | } |
|---|
| 765 | 765 | arg->rvalue(); |
|---|
| 766 | 766 | } |
|---|
| 767 | 767 | arg = arg->optimize(WANTvalue); |
|---|
| 768 | 768 | L3: |
|---|
| 769 | 769 | arguments->data[i] = (void *) arg; |
|---|
| 770 | 770 | if (done) |
|---|
| 771 | 771 | break; |
|---|
| 772 | 772 | } |
|---|
| 773 | 773 | |
|---|
| 774 | 774 | // If D linkage and variadic, add _arguments[] as first argument |
|---|
| 775 | 775 | if (tf->linkage == LINKd && tf->varargs == 1) |
|---|
| 776 | 776 | { |
|---|
| 777 | 777 | assert(arguments->dim >= nparams); |
|---|
| 778 | 778 | Expression *e = createTypeInfoArray(sc, (Expression **)&arguments->data[nparams], |
|---|
| 779 | 779 | arguments->dim - nparams); |
|---|
| 780 | 780 | arguments->insert(0, e); |
|---|
| 781 | 781 | } |
|---|
| 782 | 787 | Type *tret = tf->next; |
|---|
| 783 | 788 | if (wildmatch) |
|---|
| 784 | 789 | { /* Adjust function return type based on wildmatch |
|---|
| 785 | 790 | */ |
|---|
| 786 | 791 | //printf("wildmatch = x%x\n", wildmatch); |
|---|
| 787 | 792 | assert(tret->isWild()); |
|---|
| 788 | 793 | if (wildmatch & MODconst || wildmatch & (wildmatch - 1)) |
|---|
| 789 | 794 | tret = tret->constOf(); |
|---|
| 790 | 795 | else if (wildmatch & MODimmutable) |
|---|
| 791 | 796 | tret = tret->invariantOf(); |
|---|
| 792 | 797 | else |
|---|
| 793 | 798 | { assert(wildmatch & MODmutable); |
|---|
| 794 | 799 | tret = tret->mutableOf(); |
|---|
| 795 | 800 | } |
|---|
| 796 | 801 | } |
|---|
| 797 | 802 | return tret; |
|---|
| 798 | 803 | } |
|---|
| 799 | 804 | |
|---|
| 800 | 805 | /************************************************** |
|---|
| 801 | 806 | * Write expression out to buf, but wrap it |
|---|
| 3819 | 3824 | else if (thisexp) |
|---|
| 3820 | 3825 | { error("e.new is only for allocating nested classes"); |
|---|
| 3821 | 3826 | goto Lerr; |
|---|
| 3822 | 3827 | } |
|---|
| 3823 | 3828 | |
|---|
| 3824 | 3829 | FuncDeclaration *f = NULL; |
|---|
| 3825 | 3830 | if (cd->ctor) |
|---|
| 3826 | 3831 | f = resolveFuncCall(sc, loc, cd->ctor, NULL, NULL, arguments, 0); |
|---|
| 3827 | 3832 | if (f) |
|---|
| 3828 | 3833 | { |
|---|
| 3829 | 3834 | checkDeprecated(sc, f); |
|---|
| 3830 | 3835 | member = f->isCtorDeclaration(); |
|---|
| 3831 | 3836 | assert(member); |
|---|
| 3832 | 3837 | |
|---|
| 3833 | 3838 | cd->accessCheck(loc, sc, member); |
|---|
| 3834 | 3839 | |
|---|
| 3835 | 3840 | tf = (TypeFunction *)f->type; |
|---|
| 3836 | 3841 | |
|---|
| 3837 | 3842 | if (!arguments) |
|---|
| 3838 | 3843 | arguments = new Expressions(); |
|---|
| 3840 | 3845 | |
|---|
| 3841 | 3846 | type = type->addMod(tf->nextOf()->mod); |
|---|
| 3842 | 3847 | } |
|---|
| 3843 | 3848 | else |
|---|
| 3844 | 3849 | { |
|---|
| 3845 | 3850 | if (arguments && arguments->dim) |
|---|
| 3846 | 3851 | { error("no constructor for %s", cd->toChars()); |
|---|
| 3847 | 3852 | goto Lerr; |
|---|
| 3848 | 3853 | } |
|---|
| 3849 | 3854 | } |
|---|
| 3850 | 3855 | |
|---|
| 3851 | 3856 | if (cd->aggNew) |
|---|
| 3852 | 3857 | { |
|---|
| 3853 | 3858 | // Prepend the size argument to newargs[] |
|---|
| 3854 | 3859 | Expression *e = new IntegerExp(loc, cd->size(loc), Type::tsize_t); |
|---|
| 3855 | 3860 | if (!newargs) |
|---|
| 3856 | 3861 | newargs = new Expressions(); |
|---|
| 3857 | 3862 | newargs->shift(e); |
|---|
| 3858 | 3863 | |
|---|
| 3859 | 3864 | f = cd->aggNew->overloadResolve(loc, NULL, newargs); |
|---|
| 3860 | 3865 | allocator = f->isNewDeclaration(); |
|---|
| 3861 | 3866 | assert(allocator); |
|---|
| 3862 | 3867 | |
|---|
| 3863 | 3868 | tf = (TypeFunction *)f->type; |
|---|
| 3865 | 3870 | } |
|---|
| 3866 | 3871 | else |
|---|
| 3867 | 3872 | { |
|---|
| 3868 | 3873 | if (newargs && newargs->dim) |
|---|
| 3869 | 3874 | { error("no allocator for %s", cd->toChars()); |
|---|
| 3870 | 3875 | goto Lerr; |
|---|
| 3871 | 3876 | } |
|---|
| 3872 | 3877 | } |
|---|
| 3873 | 3878 | } |
|---|
| 3874 | 3879 | else if (tb->ty == Tstruct) |
|---|
| 3875 | 3880 | { |
|---|
| 3876 | 3881 | TypeStruct *ts = (TypeStruct *)tb; |
|---|
| 3877 | 3882 | StructDeclaration *sd = ts->sym; |
|---|
| 3878 | 3883 | TypeFunction *tf; |
|---|
| 3879 | 3884 | |
|---|
| 3880 | 3885 | FuncDeclaration *f = NULL; |
|---|
| 3881 | 3886 | if (sd->ctor) |
|---|
| 3882 | 3887 | f = resolveFuncCall(sc, loc, sd->ctor, NULL, NULL, arguments, 0); |
|---|
| 3883 | 3888 | if (f) |
|---|
| 3884 | 3889 | { |
|---|
| 3885 | 3890 | checkDeprecated(sc, f); |
|---|
| 3886 | 3891 | member = f->isCtorDeclaration(); |
|---|
| 3887 | 3892 | assert(member); |
|---|
| 3888 | 3893 | |
|---|
| 3889 | 3894 | sd->accessCheck(loc, sc, member); |
|---|
| 3890 | 3895 | |
|---|
| 3891 | 3896 | tf = (TypeFunction *)f->type; |
|---|
| 3892 | 3897 | type = tf->next; |
|---|
| 3893 | 3898 | |
|---|
| 3894 | 3899 | if (!arguments) |
|---|
| 3895 | 3900 | arguments = new Expressions(); |
|---|
| 3897 | 3902 | } |
|---|
| 3898 | 3903 | else |
|---|
| 3899 | 3904 | { |
|---|
| 3900 | 3905 | if (arguments && arguments->dim) |
|---|
| 3901 | 3906 | { error("no constructor for %s", sd->toChars()); |
|---|
| 3902 | 3907 | goto Lerr; |
|---|
| 3903 | 3908 | } |
|---|
| 3904 | 3909 | } |
|---|
| 3905 | 3910 | |
|---|
| 3906 | 3911 | |
|---|
| 3907 | 3912 | if (sd->aggNew) |
|---|
| 3908 | 3913 | { |
|---|
| 3909 | 3914 | // Prepend the uint size argument to newargs[] |
|---|
| 3910 | 3915 | Expression *e = new IntegerExp(loc, sd->size(loc), Type::tuns32); |
|---|
| 3911 | 3916 | if (!newargs) |
|---|
| 3912 | 3917 | newargs = new Expressions(); |
|---|
| 3913 | 3918 | newargs->shift(e); |
|---|
| 3914 | 3919 | |
|---|
| 3915 | 3920 | f = sd->aggNew->overloadResolve(loc, NULL, newargs); |
|---|
| 3916 | 3921 | allocator = f->isNewDeclaration(); |
|---|
| 3917 | 3922 | assert(allocator); |
|---|
| 3918 | 3923 | |
|---|
| 3919 | 3924 | tf = (TypeFunction *)f->type; |
|---|