Mercurial > projects > ddmd
comparison dmd/FuncDeclaration.d @ 137:09c858522d55
merge
author | Trass3r |
---|---|
date | Mon, 13 Sep 2010 23:29:00 +0200 |
parents | af1bebfd96a4 |
children | bc45b1c53019 |
comparison
equal
deleted
inserted
replaced
136:9d194c848e3a | 137:09c858522d55 |
---|---|
307 | 307 |
308 if (!originalType) | 308 if (!originalType) |
309 originalType = type; | 309 originalType = type; |
310 if (!type.deco) | 310 if (!type.deco) |
311 { | 311 { |
312 sc = sc.push(); | |
313 sc.stc |= storage_class & STC.STCref; // forward refness to function type | |
314 type = type.semantic(loc, sc); | |
315 sc = sc.pop(); | |
316 | |
312 /* Apply const, immutable and shared storage class | 317 /* Apply const, immutable and shared storage class |
313 * to the function type | 318 * to the function type |
314 */ | 319 */ |
315 type = type.semantic(loc, sc); | |
316 StorageClass stc = storage_class; | 320 StorageClass stc = storage_class; |
317 if (type.isInvariant()) | 321 if (type.isImmutable()) |
318 stc |= STC.STCimmutable; | 322 stc |= STC.STCimmutable; |
319 if (type.isConst()) | 323 if (type.isConst()) |
320 stc |= STC.STCconst; | 324 stc |= STC.STCconst; |
321 if (type.isShared() || storage_class & STC.STCsynchronized) | 325 if (type.isShared() || storage_class & STC.STCsynchronized) |
322 stc |= STC.STCshared; | 326 stc |= STC.STCshared; |
327 if (type.isWild()) | |
328 stc |= STC.STCwild; | |
323 switch (stc & STC.STC_TYPECTOR) | 329 switch (stc & STC.STC_TYPECTOR) |
324 { | 330 { |
325 case STC.STCimmutable: | 331 case STC.STCimmutable: |
326 case STC.STCimmutable | STC.STCconst: | 332 case STC.STCimmutable | STC.STCconst: |
327 case STC.STCimmutable | STC.STCconst | STC.STCshared: | 333 case STC.STCimmutable | STC.STCconst | STC.STCshared: |
328 case STC.STCimmutable | STC.STCshared: | 334 case STC.STCimmutable | STC.STCshared: |
335 case STC.STCimmutable | STC.STCwild: | |
336 case STC.STCimmutable | STC.STCconst | STC.STCwild: | |
337 case STC.STCimmutable | STC.STCconst | STC.STCshared | STC.STCwild: | |
338 case STC.STCimmutable | STC.STCshared | STC.STCwild: | |
329 // Don't use toInvariant(), as that will do a merge() | 339 // Don't use toInvariant(), as that will do a merge() |
330 type = type.makeInvariant(); | 340 type = type.makeInvariant(); |
331 goto Lmerge; | 341 goto Lmerge; |
332 | 342 |
333 case STC.STCconst: | 343 case STC.STCconst: |
344 case STC.STCconst | STC.STCwild: | |
334 type = type.makeConst(); | 345 type = type.makeConst(); |
335 goto Lmerge; | 346 goto Lmerge; |
336 | 347 |
337 case STC.STCshared | STC.STCconst: | 348 case STC.STCshared | STC.STCconst: |
349 case STC.STCshared | STC.STCconst | STC.STCwild: | |
338 type = type.makeSharedConst(); | 350 type = type.makeSharedConst(); |
339 goto Lmerge; | 351 goto Lmerge; |
340 | 352 |
341 case STC.STCshared: | 353 case STC.STCshared: |
342 type = type.makeShared(); | 354 type = type.makeShared(); |
355 goto Lmerge; | |
356 | |
357 case STC.STCwild: | |
358 type = type.makeWild(); | |
359 goto Lmerge; | |
360 | |
361 case STC.STCshared | STC.STCwild: | |
362 type = type.makeSharedWild(); | |
363 goto Lmerge; | |
364 | |
343 Lmerge: | 365 Lmerge: |
344 if (!(type.ty == Tfunction && !type.nextOf())) | 366 if (!(type.ty == Tfunction && !type.nextOf())) |
345 /* Can't do merge if return type is not known yet | 367 /* Can't do merge if return type is not known yet |
346 */ | 368 */ |
347 type.deco = type.merge().deco; | 369 type.deco = type.merge().deco; |
352 | 374 |
353 default: | 375 default: |
354 assert(0); | 376 assert(0); |
355 } | 377 } |
356 } | 378 } |
357 //type.print(); | 379 storage_class &= ~STC.STCref; |
358 if (type.ty != TY.Tfunction) | 380 if (type.ty != TY.Tfunction) |
359 { | 381 { |
360 error("%s must be a function", toChars()); | 382 error("%s must be a function", toChars()); |
361 return; | 383 return; |
362 } | 384 } |
376 error("functions cannot be scope"); | 398 error("functions cannot be scope"); |
377 | 399 |
378 if (isAbstract() && !isVirtual()) | 400 if (isAbstract() && !isVirtual()) |
379 error("non-virtual functions cannot be abstract"); | 401 error("non-virtual functions cannot be abstract"); |
380 | 402 |
381 if ((f.isConst() || f.isInvariant()) && !isThis()) | 403 if ((f.isConst() || f.isImmutable()) && !isThis()) |
382 error("without 'this' cannot be const/immutable"); | 404 error("without 'this' cannot be const/immutable"); |
383 | 405 |
384 if (isAbstract() && isFinal()) | 406 if (isAbstract() && isFinal()) |
385 error("cannot be both final and abstract"); | 407 error("cannot be both final and abstract"); |
386 static if (false) { | 408 static if (false) { |
963 else | 985 else |
964 { assert(thandle.ty == TY.Tpointer); | 986 { assert(thandle.ty == TY.Tpointer); |
965 thandle = thandle.nextOf().constOf().pointerTo(); | 987 thandle = thandle.nextOf().constOf().pointerTo(); |
966 } | 988 } |
967 } | 989 } |
968 else if (storage_class & STC.STCimmutable || type.isInvariant()) | 990 else if (storage_class & STC.STCimmutable || type.isImmutable()) |
969 { | 991 { |
970 if (thandle.ty == TY.Tclass) | 992 if (thandle.ty == TY.Tclass) |
971 thandle = thandle.invariantOf(); | 993 thandle = thandle.invariantOf(); |
972 else | 994 else |
973 { assert(thandle.ty == TY.Tpointer); | 995 { assert(thandle.ty == TY.Tpointer); |
1052 sc2.insert(argptr); | 1074 sc2.insert(argptr); |
1053 argptr.parent = this; | 1075 argptr.parent = this; |
1054 } | 1076 } |
1055 } | 1077 } |
1056 } | 1078 } |
1057 | 1079 static if(false) { |
1058 // Propagate storage class from tuple parameters to their element-parameters. | 1080 // Propagate storage class from tuple parameters to their element-parameters. |
1059 if (f.parameters) | 1081 if (f.parameters) |
1060 { | 1082 { |
1061 foreach (arg; f.parameters) | 1083 foreach (arg; f.parameters) |
1062 { | 1084 { |
1070 narg.storageClass = arg.storageClass; | 1092 narg.storageClass = arg.storageClass; |
1071 } | 1093 } |
1072 } | 1094 } |
1073 } | 1095 } |
1074 } | 1096 } |
1075 | 1097 } |
1076 /* Declare all the function parameters as variables | 1098 /* Declare all the function parameters as variables |
1077 * and install them in parameters[] | 1099 * and install them in parameters[] |
1078 */ | 1100 */ |
1079 size_t nparams = Parameter.dim(f.parameters); | 1101 size_t nparams = Parameter.dim(f.parameters); |
1080 if (nparams) | 1102 if (nparams) |
2397 | 2419 |
2398 Type tb = type.toBasetype(); | 2420 Type tb = type.toBasetype(); |
2399 assert(tb.ty == Tfunction); | 2421 assert(tb.ty == Tfunction); |
2400 TypeFunction tf = cast(TypeFunction)tb; | 2422 TypeFunction tf = cast(TypeFunction)tb; |
2401 Type tret = tf.next.toBasetype(); | 2423 Type tret = tf.next.toBasetype(); |
2402 if (tf.varargs) | 2424 if (tf.varargs && arguments && parameters && arguments.dim != parameters.dim) |
2403 { | 2425 { |
2404 cantInterpret = 1; | 2426 cantInterpret = 1; |
2405 error("Variadic functions are not yet implemented in CTFE"); | 2427 error("C-style variadic functions are not yet implemented in CTFE"); |
2406 return null; | 2428 return null; |
2407 } | 2429 } |
2408 | 2430 |
2409 // Ensure there are no lazy parameters | 2431 // Ensure there are no lazy parameters |
2410 if (tf.parameters) | 2432 if (tf.parameters) |
2545 printf("interpreted arg[%d] = %s\n", i, earg.toChars()); | 2567 printf("interpreted arg[%d] = %s\n", i, earg.toChars()); |
2546 } | 2568 } |
2547 } | 2569 } |
2548 } | 2570 } |
2549 // Don't restore the value of 'this' upon function return | 2571 // Don't restore the value of 'this' upon function return |
2550 if (needThis() && thisarg.op==TOKvar) { | 2572 if (needThis() && thisarg.op == TOKvar && istate) { |
2551 VarDeclaration thisvar = (cast(VarExp)thisarg).var.isVarDeclaration(); | 2573 VarDeclaration thisvar = (cast(VarExp)thisarg).var.isVarDeclaration(); |
2552 foreach (size_t i, Dsymbol s; istate.vars) | 2574 foreach (size_t i, Dsymbol s; istate.vars) |
2553 { | 2575 { |
2554 auto v = cast(VarDeclaration)s; | 2576 auto v = cast(VarDeclaration)s; |
2555 if (v == thisvar) | 2577 if (v == thisvar) |
2560 } | 2582 } |
2561 } | 2583 } |
2562 | 2584 |
2563 /* Save the values of the local variables used | 2585 /* Save the values of the local variables used |
2564 */ | 2586 */ |
2565 scope Expressions valueSaves = new Expressions(); | 2587 scope valueSaves = new Expressions(); |
2566 if (istate && !isNested()) | 2588 if (istate && !isNested()) |
2567 { | 2589 { |
2568 //printf("saving local variables...\n"); | 2590 //printf("saving local variables...\n"); |
2569 valueSaves.setDim(istate.vars.dim); | 2591 valueSaves.setDim(istate.vars.dim); |
2570 foreach (size_t i, Dsymbol s3; istate.vars) | 2592 foreach (size_t i, Dsymbol s3; istate.vars) |
3833 | 3855 |
3834 block_appendexp(irs.blx.curblock, e); | 3856 block_appendexp(irs.blx.curblock, e); |
3835 } | 3857 } |
3836 } | 3858 } |
3837 | 3859 |
3860 /********************************************* | |
3861 * Return the function's parameter list, and whether | |
3862 * it is variadic or not. | |
3863 */ | |
3864 | |
3865 Parameters getParameters(int *pvarargs) | |
3866 { | |
3867 Parameters fparameters; | |
3868 int fvarargs; | |
3869 | |
3870 if (type) | |
3871 { | |
3872 assert(type.ty == Tfunction); | |
3873 auto fdtype = cast(TypeFunction)type; | |
3874 fparameters = fdtype.parameters; | |
3875 fvarargs = fdtype.varargs; | |
3876 } | |
3877 else // Constructors don't have type's | |
3878 { | |
3879 CtorDeclaration fctor = isCtorDeclaration(); | |
3880 assert(fctor); | |
3881 fparameters = fctor.arguments; | |
3882 fvarargs = fctor.varargs; | |
3883 } | |
3884 if (pvarargs) | |
3885 *pvarargs = fvarargs; | |
3886 return fparameters; | |
3887 } | |
3888 | |
3838 override FuncDeclaration isFuncDeclaration() { return this; } | 3889 override FuncDeclaration isFuncDeclaration() { return this; } |
3839 } | 3890 } |
3840 | 3891 |
3841 alias Vector!FuncDeclaration FuncDeclarations; | 3892 alias Vector!FuncDeclaration FuncDeclarations; |