Mercurial > projects > ldc
comparison dmd/expression.c @ 1618:a87f1d6ff48e
Merge DMD r303: harmonize
---
dmd/expression.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++-----
dmd/expression.h | 8 +++++
dmd/template.c | 27 ++++++++++++-------
3 files changed, 95 insertions(+), 18 deletions(-)
author | Leandro Lucarella <llucax@gmail.com> |
---|---|
date | Wed, 06 Jan 2010 15:18:21 -0300 |
parents | c94049033c20 |
children | c61782a76dff |
comparison
equal
deleted
inserted
replaced
1617:6820110de311 | 1618:a87f1d6ff48e |
---|---|
1185 | 1185 |
1186 void Expression::checkEscape() | 1186 void Expression::checkEscape() |
1187 { | 1187 { |
1188 } | 1188 } |
1189 | 1189 |
1190 void Expression::checkEscapeRef() | |
1191 { | |
1192 } | |
1193 | |
1190 void Expression::checkScalar() | 1194 void Expression::checkScalar() |
1191 { | 1195 { |
1192 if (!type->isscalar()) | 1196 if (!type->isscalar()) |
1193 error("'%s' is not a scalar, it is a %s", toChars(), type->toChars()); | 1197 error("'%s' is not a scalar, it is a %s", toChars(), type->toChars()); |
1194 } | 1198 } |
1201 | 1205 |
1202 Expression *Expression::checkIntegral() | 1206 Expression *Expression::checkIntegral() |
1203 { | 1207 { |
1204 if (!type->isintegral()) | 1208 if (!type->isintegral()) |
1205 { error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); | 1209 { error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); |
1206 return new IntegerExp(0); | 1210 return new ErrorExp(); |
1207 } | 1211 } |
1208 return this; | 1212 return this; |
1209 } | 1213 } |
1210 | 1214 |
1211 Expression *Expression::checkArithmetic() | 1215 Expression *Expression::checkArithmetic() |
1212 { | 1216 { |
1213 if (!type->isintegral() && !type->isfloating()) | 1217 if (!type->isintegral() && !type->isfloating()) |
1214 { error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars()); | 1218 { error("'%s' is not of arithmetic type, it is a %s", toChars(), type->toChars()); |
1215 return new IntegerExp(0); | 1219 return new ErrorExp(); |
1216 } | 1220 } |
1217 return this; | 1221 return this; |
1218 } | 1222 } |
1219 | 1223 |
1220 void Expression::checkDeprecated(Scope *sc, Dsymbol *s) | 1224 void Expression::checkDeprecated(Scope *sc, Dsymbol *s) |
3996 void SymOffExp::checkEscape() | 4000 void SymOffExp::checkEscape() |
3997 { | 4001 { |
3998 VarDeclaration *v = var->isVarDeclaration(); | 4002 VarDeclaration *v = var->isVarDeclaration(); |
3999 if (v) | 4003 if (v) |
4000 { | 4004 { |
4001 if (!v->isDataseg()) | 4005 if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) |
4002 error("escaping reference to local variable %s", v->toChars()); | 4006 { /* BUG: This should be allowed: |
4007 * void foo() | |
4008 * { int a; | |
4009 * int* bar() { return &a; } | |
4010 * } | |
4011 */ | |
4012 error("escaping reference to local %s", v->toChars()); | |
4013 } | |
4003 } | 4014 } |
4004 } | 4015 } |
4005 | 4016 |
4006 void SymOffExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) | 4017 void SymOffExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) |
4007 { | 4018 { |
4047 type = new TypeDelegate(tf); | 4058 type = new TypeDelegate(tf); |
4048 type = type->semantic(loc, sc); | 4059 type = type->semantic(loc, sc); |
4049 } | 4060 } |
4050 #endif | 4061 #endif |
4051 } | 4062 } |
4063 | |
4052 /* Fix for 1161 doesn't work because it causes protection | 4064 /* Fix for 1161 doesn't work because it causes protection |
4053 * problems when instantiating imported templates passing private | 4065 * problems when instantiating imported templates passing private |
4054 * variables as alias template parameters. | 4066 * variables as alias template parameters. |
4055 */ | 4067 */ |
4056 //accessCheck(loc, sc, NULL, var); | 4068 //accessCheck(loc, sc, NULL, var); |
4082 e = new FuncExp(loc, fd); | 4094 e = new FuncExp(loc, fd); |
4083 e->type = type; | 4095 e->type = type; |
4084 return e; | 4096 return e; |
4085 } | 4097 } |
4086 #endif | 4098 #endif |
4099 | |
4087 return this; | 4100 return this; |
4088 } | 4101 } |
4089 | 4102 |
4090 char *VarExp::toChars() | 4103 char *VarExp::toChars() |
4091 { | 4104 { |
4108 if (v->isScope() && !v->noscope) | 4121 if (v->isScope() && !v->noscope) |
4109 error("escaping reference to scope local %s", v->toChars()); | 4122 error("escaping reference to scope local %s", v->toChars()); |
4110 else if (v->storage_class & STCvariadic) | 4123 else if (v->storage_class & STCvariadic) |
4111 error("escaping reference to variadic parameter %s", v->toChars()); | 4124 error("escaping reference to variadic parameter %s", v->toChars()); |
4112 } | 4125 } |
4126 } | |
4127 } | |
4128 | |
4129 void VarExp::checkEscapeRef() | |
4130 { | |
4131 VarDeclaration *v = var->isVarDeclaration(); | |
4132 if (v) | |
4133 { | |
4134 if (!v->isDataseg() && !(v->storage_class & (STCref | STCout))) | |
4135 error("escaping reference to local variable %s", v->toChars()); | |
4113 } | 4136 } |
4114 } | 4137 } |
4115 | 4138 |
4116 #if DMDV2 | 4139 #if DMDV2 |
4117 int VarExp::isLvalue() | 4140 int VarExp::isLvalue() |
4739 break; | 4762 break; |
4740 | 4763 |
4741 case TOKinvariant: | 4764 case TOKinvariant: |
4742 case TOKimmutable: | 4765 case TOKimmutable: |
4743 if (!targ->isInvariant()) | 4766 if (!targ->isInvariant()) |
4767 goto Lno; | |
4768 tded = targ; | |
4769 break; | |
4770 | |
4771 case TOKshared: | |
4772 if (!targ->isShared()) | |
4744 goto Lno; | 4773 goto Lno; |
4745 tded = targ; | 4774 tded = targ; |
4746 break; | 4775 break; |
4747 #endif | 4776 #endif |
4748 | 4777 |
4832 dedtypes.data[0] = NULL; | 4861 dedtypes.data[0] = NULL; |
4833 | 4862 |
4834 m = targ->deduceType(NULL, tspec, ¶meters, &dedtypes); | 4863 m = targ->deduceType(NULL, tspec, ¶meters, &dedtypes); |
4835 if (m == MATCHnomatch || | 4864 if (m == MATCHnomatch || |
4836 (m != MATCHexact && tok == TOKequal)) | 4865 (m != MATCHexact && tok == TOKequal)) |
4866 { | |
4837 goto Lno; | 4867 goto Lno; |
4868 } | |
4838 else | 4869 else |
4839 { | 4870 { |
4840 assert(dedtypes.dim == 1); | 4871 assert(dedtypes.dim == 1); |
4841 tded = (Type *)dedtypes.data[0]; | 4872 tded = (Type *)dedtypes.data[0]; |
4842 if (!tded) | 4873 if (!tded) |
4852 goto Lyes; | 4883 goto Lyes; |
4853 } | 4884 } |
4854 else if (tspec) | 4885 else if (tspec) |
4855 { | 4886 { |
4856 /* Evaluate to TRUE if targ matches tspec | 4887 /* Evaluate to TRUE if targ matches tspec |
4888 * is(targ == tspec) | |
4889 * is(targ : tspec) | |
4857 */ | 4890 */ |
4858 tspec = tspec->semantic(loc, sc); | 4891 tspec = tspec->semantic(loc, sc); |
4859 //printf("targ = %s\n", targ->toChars()); | 4892 //printf("targ = %s\n", targ->toChars()); |
4860 //printf("tspec = %s\n", tspec->toChars()); | 4893 //printf("tspec = %s\n", tspec->toChars()); |
4861 if (tok == TOKcolon) | 4894 if (tok == TOKcolon) |
5663 * as: | 5696 * as: |
5664 * .ident(e1) | 5697 * .ident(e1) |
5665 */ | 5698 */ |
5666 unsigned errors = global.errors; | 5699 unsigned errors = global.errors; |
5667 global.gag++; | 5700 global.gag++; |
5701 Type *t1 = e1->type; | |
5668 e = e1->type->dotExp(sc, e1, ident); | 5702 e = e1->type->dotExp(sc, e1, ident); |
5669 global.gag--; | 5703 global.gag--; |
5670 if (errors != global.errors) // if failed to find the property | 5704 if (errors != global.errors) // if failed to find the property |
5671 { | 5705 { |
5672 global.errors = errors; | 5706 global.errors = errors; |
5707 e1->type = t1; // kludge to restore type | |
5673 e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident); | 5708 e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident); |
5674 e = new CallExp(loc, e, e1); | 5709 e = new CallExp(loc, e, e1); |
5675 } | 5710 } |
5676 e = e->semantic(sc); | 5711 e = e->semantic(sc); |
5677 return e; | 5712 return e; |
5861 (t1->ty == Tpointer && !t1->nextOf()->isMutable()) || | 5896 (t1->ty == Tpointer && !t1->nextOf()->isMutable()) || |
5862 !var->type->isMutable() || | 5897 !var->type->isMutable() || |
5863 !var->type->isAssignable() || | 5898 !var->type->isAssignable() || |
5864 var->storage_class & STCmanifest | 5899 var->storage_class & STCmanifest |
5865 ) | 5900 ) |
5866 error("cannot modify const/invariant %s", toChars()); | 5901 error("cannot modify const/immutable expression %s", toChars()); |
5867 } | 5902 } |
5868 #endif | 5903 #endif |
5869 return this; | 5904 return this; |
5870 } | 5905 } |
5871 | 5906 |
6938 return optimize(WANTvalue); | 6973 return optimize(WANTvalue); |
6939 } | 6974 } |
6940 return this; | 6975 return this; |
6941 } | 6976 } |
6942 | 6977 |
6978 void AddrExp::checkEscape() | |
6979 { | |
6980 e1->checkEscapeRef(); | |
6981 } | |
6982 | |
6943 /************************************************************/ | 6983 /************************************************************/ |
6944 | 6984 |
6945 PtrExp::PtrExp(Loc loc, Expression *e) | 6985 PtrExp::PtrExp(Loc loc, Expression *e) |
6946 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) | 6986 : UnaExp(loc, TOKstar, sizeof(PtrExp), e) |
6947 { | 6987 { |
6992 int PtrExp::isLvalue() | 7032 int PtrExp::isLvalue() |
6993 { | 7033 { |
6994 return 1; | 7034 return 1; |
6995 } | 7035 } |
6996 #endif | 7036 #endif |
7037 | |
7038 void PtrExp::checkEscapeRef() | |
7039 { | |
7040 e1->checkEscape(); | |
7041 } | |
6997 | 7042 |
6998 Expression *PtrExp::toLvalue(Scope *sc, Expression *e) | 7043 Expression *PtrExp::toLvalue(Scope *sc, Expression *e) |
6999 { | 7044 { |
7000 #if 0 | 7045 #if 0 |
7001 tym = tybasic(e1->ET->Tty); | 7046 tym = tybasic(e1->ET->Tty); |
7570 } | 7615 } |
7571 return e; | 7616 return e; |
7572 } | 7617 } |
7573 | 7618 |
7574 if (t->ty == Tarray) | 7619 if (t->ty == Tarray) |
7620 { | |
7575 type = e1->type; | 7621 type = e1->type; |
7622 } | |
7576 else | 7623 else |
7577 type = t->nextOf()->arrayOf(); | 7624 type = t->nextOf()->arrayOf(); |
7578 return e; | 7625 return e; |
7579 | 7626 |
7580 Lerror: | 7627 Lerror: |
7582 if (t->ty == Tvoid) | 7629 if (t->ty == Tvoid) |
7583 s = e1->toChars(); | 7630 s = e1->toChars(); |
7584 else | 7631 else |
7585 s = t->toChars(); | 7632 s = t->toChars(); |
7586 error("%s cannot be sliced with []", s); | 7633 error("%s cannot be sliced with []", s); |
7587 e = new IntegerExp(0); | 7634 e = new ErrorExp(); |
7588 return e; | 7635 return e; |
7589 } | 7636 } |
7590 | 7637 |
7591 void SliceExp::checkEscape() | 7638 void SliceExp::checkEscape() |
7592 { | 7639 { |
7593 e1->checkEscape(); | 7640 e1->checkEscape(); |
7641 } | |
7642 | |
7643 void SliceExp::checkEscapeRef() | |
7644 { | |
7645 e1->checkEscapeRef(); | |
7594 } | 7646 } |
7595 | 7647 |
7596 #if DMDV2 | 7648 #if DMDV2 |
7597 int SliceExp::isLvalue() | 7649 int SliceExp::isLvalue() |
7598 { | 7650 { |
7636 : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1) | 7688 : UnaExp(loc, TOKarraylength, sizeof(ArrayLengthExp), e1) |
7637 { | 7689 { |
7638 } | 7690 } |
7639 | 7691 |
7640 Expression *ArrayLengthExp::semantic(Scope *sc) | 7692 Expression *ArrayLengthExp::semantic(Scope *sc) |
7641 { Expression *e; | 7693 { |
7642 | |
7643 #if LOGSEMANTIC | 7694 #if LOGSEMANTIC |
7644 printf("ArrayLengthExp::semantic('%s')\n", toChars()); | 7695 printf("ArrayLengthExp::semantic('%s')\n", toChars()); |
7645 #endif | 7696 #endif |
7646 if (!type) | 7697 if (!type) |
7647 { | 7698 { |
7788 } | 7839 } |
7789 | 7840 |
7790 void CommaExp::checkEscape() | 7841 void CommaExp::checkEscape() |
7791 { | 7842 { |
7792 e2->checkEscape(); | 7843 e2->checkEscape(); |
7844 } | |
7845 | |
7846 void CommaExp::checkEscapeRef() | |
7847 { | |
7848 e2->checkEscapeRef(); | |
7793 } | 7849 } |
7794 | 7850 |
7795 #if DMDV2 | 7851 #if DMDV2 |
7796 int CommaExp::isLvalue() | 7852 int CommaExp::isLvalue() |
7797 { | 7853 { |
9969 { | 10025 { |
9970 e1->checkEscape(); | 10026 e1->checkEscape(); |
9971 e2->checkEscape(); | 10027 e2->checkEscape(); |
9972 } | 10028 } |
9973 | 10029 |
10030 void CondExp::checkEscapeRef() | |
10031 { | |
10032 e1->checkEscapeRef(); | |
10033 e2->checkEscapeRef(); | |
10034 } | |
10035 | |
9974 | 10036 |
9975 Expression *CondExp::checkToBoolean() | 10037 Expression *CondExp::checkToBoolean() |
9976 { | 10038 { |
9977 e1 = e1->checkToBoolean(); | 10039 e1 = e1->checkToBoolean(); |
9978 e2 = e2->checkToBoolean(); | 10040 e2 = e2->checkToBoolean(); |