2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
10 #include "root/dsystem.h"
11 #include "root/rmem.h"
12 #include "root/root.h"
18 #include "expression.h"
23 #include "statement.h"
24 #include "declaration.h"
25 #include "aggregate.h"
37 bool typeMerge(Scope
*sc
, TOK op
, Type
**pt
, Expression
**pe1
, Expression
**pe2
);
38 bool isArrayOpValid(Expression
*e
);
39 Expression
*expandVar(int result
, VarDeclaration
*v
);
40 TypeTuple
*toArgTypes(Type
*t
);
41 bool checkAssignEscape(Scope
*sc
, Expression
*e
, bool gag
);
42 bool checkParamArgumentEscape(Scope
*sc
, FuncDeclaration
*fdc
, Identifier
*par
, Expression
*arg
, bool gag
);
43 bool checkAccess(AggregateDeclaration
*ad
, Loc loc
, Scope
*sc
, Dsymbol
*smember
);
44 bool checkNestedRef(Dsymbol
*s
, Dsymbol
*p
);
45 bool checkFrameAccess(Loc loc
, Scope
*sc
, AggregateDeclaration
*ad
, size_t istart
= 0);
46 bool symbolIsVisible(Module
*mod
, Dsymbol
*s
);
47 VarDeclaration
*copyToTemp(StorageClass stc
, const char *name
, Expression
*e
);
48 Expression
*extractSideEffect(Scope
*sc
, const char *name
, Expression
**e0
, Expression
*e
, bool alwaysCopy
= false);
49 Type
*getTypeInfoType(Type
*t
, Scope
*sc
);
50 bool MODimplicitConv(MOD modfrom
, MOD modto
);
51 MATCH
MODmethodConv(MOD modfrom
, MOD modto
);
52 void MODMatchToBuffer(OutBuffer
*buf
, unsigned char lhsMod
, unsigned char rhsMod
);
54 void unSpeculative(Scope
*sc
, RootObject
*o
);
55 bool arrayExpressionToCommonType(Scope
*sc
, Expressions
*exps
, Type
**pt
);
56 bool checkDefCtor(Loc loc
, Type
*t
);
57 bool isDotOpDispatch(Expression
*e
);
58 bool functionParameters(Loc loc
, Scope
*sc
, TypeFunction
*tf
, Type
*tthis
, Expressions
*arguments
, FuncDeclaration
*fd
, Type
**prettype
, Expression
**peprefix
);
59 Expression
*getRightThis(Loc loc
, Scope
*sc
, AggregateDeclaration
*ad
, Expression
*e1
, Declaration
*var
, int flag
= 0);
60 bool isNeedThisScope(Scope
*sc
, Declaration
*d
);
61 Expression
*resolveUFCS(Scope
*sc
, CallExp
*ce
);
62 bool checkUnsafeAccess(Scope
*sc
, Expression
*e
, bool readonly
, bool printmsg
);
63 bool isSafeCast(Expression
*e
, Type
*tfrom
, Type
*tto
);
64 FuncDeclaration
*isFuncAddress(Expression
*e
, bool *hasOverloads
= NULL
);
65 Expression
*callCpCtor(Scope
*sc
, Expression
*e
);
67 Expression
*resolve(Loc loc
, Scope
*sc
, Dsymbol
*s
, bool hasOverloads
);
68 Expression
*resolveUFCSProperties(Scope
*sc
, Expression
*e1
, Expression
*e2
= NULL
);
69 Expression
*resolvePropertiesX(Scope
*sc
, Expression
*e1
, Expression
*e2
= NULL
);
70 Expression
*trySemantic(Expression
*e
, Scope
*sc
);
71 Expression
*unaSemantic(UnaExp
*e
, Scope
*sc
);
72 Expression
*binSemantic(BinExp
*e
, Scope
*sc
);
73 Expression
*binSemanticProp(BinExp
*e
, Scope
*sc
);
74 Expression
*semantic(Expression
*e
, Scope
*sc
);
75 Expression
*semanticY(DotIdExp
*exp
, Scope
*sc
, int flag
);
76 Expression
*semanticY(DotTemplateInstanceExp
*exp
, Scope
*sc
, int flag
);
78 /****************************************
79 * Preprocess arguments to function.
81 * exps[] tuples expanded, properties resolved, rewritten in place
83 * true a semantic error occurred
86 static bool preFunctionParameters(Scope
*sc
, Expressions
*exps
)
93 for (size_t i
= 0; i
< exps
->dim
; i
++)
95 Expression
*arg
= (*exps
)[i
];
97 arg
= resolveProperties(sc
, arg
);
98 if (arg
->op
== TOKtype
)
100 arg
->error("cannot pass type %s as a function argument", arg
->toChars());
101 arg
= new ErrorExp();
104 else if (checkNonAssignmentArrayOp(arg
))
106 arg
= new ErrorExp();
115 class ExpressionSemanticVisitor
: public Visitor
121 ExpressionSemanticVisitor(Scope
*sc
)
130 result
= new ErrorExp();
133 /*********************
134 * Mark the operand as will never be dereferenced,
135 * which is useful info for @safe checks.
136 * Do before semantic() on operands rewrites them.
138 static void setNoderefOperand(UnaExp
*e
)
140 if (e
->e1
->op
== TOKdotid
)
141 ((DotIdExp
*)e
->e1
)->noderef
= true;
144 /*********************
145 * Mark the operands as will never be dereferenced,
146 * which is useful info for @safe checks.
147 * Do before semantic() on operands rewrites them.
149 static void setNoderefOperands(BinExp
*e
)
151 if (e
->e1
->op
== TOKdotid
)
152 ((DotIdExp
*)e
->e1
)->noderef
= true;
153 if (e
->e2
->op
== TOKdotid
)
154 ((DotIdExp
*)e
->e2
)->noderef
= true;
157 static FuncDeclaration
*resolveOverloadSet(Loc loc
, Scope
*sc
,
158 OverloadSet
*os
, Objects
* tiargs
, Type
*tthis
, Expressions
*arguments
)
160 FuncDeclaration
*f
= NULL
;
161 for (size_t i
= 0; i
< os
->a
.dim
; i
++)
163 Dsymbol
*s
= os
->a
[i
];
164 if (tiargs
&& s
->isFuncDeclaration())
166 if (FuncDeclaration
*f2
= resolveFuncCall(loc
, sc
, s
, tiargs
, tthis
, arguments
, 1))
172 /* Error if match in more than one overload set,
173 * even if one is a 'better' match than the other.
175 ScopeDsymbol::multiplyDefined(loc
, f
, f2
);
182 ::error(loc
, "no overload matches for %s", os
->toChars());
188 /****************************************************
189 * Determine if `exp`, which takes the address of `v`, can do so safely.
192 * exp = expression that takes the address of `v`
193 * v = the variable getting its address taken
195 * `true` if ok, `false` for error
197 static bool checkAddressVar(Scope
*sc
, UnaExp
*e
, VarDeclaration
*v
)
201 if (!v
->canTakeAddressOf())
203 e
->error("cannot take address of %s", e
->e1
->toChars());
206 if (sc
->func
&& !sc
->intypeof
&& !v
->isDataseg())
208 const char *p
= v
->isParameter() ? "parameter" : "local";
209 if (global
.params
.vsafe
)
211 // Taking the address of v means it cannot be set to 'scope' later
212 v
->storage_class
&= ~STCmaybescope
;
213 v
->doNotInferScope
= true;
214 if (v
->storage_class
& STCscope
&& sc
->func
->setUnsafe())
216 e
->error("cannot take address of scope %s %s in @safe function %s", p
, v
->toChars(), sc
->func
->toChars());
220 else if (sc
->func
->setUnsafe())
222 e
->error("cannot take address of %s %s in @safe function %s", p
, v
->toChars(), sc
->func
->toChars());
230 static bool checkVectorElem(Expression
*e
, Expression
*elem
)
232 if (elem
->isConst() == 1)
235 e
->error("constant expression expected, not %s", elem
->toChars());
240 void visit(Expression
*e
)
243 e
->type
= e
->type
->semantic(e
->loc
, sc
);
245 e
->type
= Type::tvoid
;
249 void visit(IntegerExp
*e
)
252 if (e
->type
->ty
== Terror
)
254 assert(e
->type
->deco
);
259 void visit(RealExp
*e
)
262 e
->type
= Type::tfloat64
;
264 e
->type
= e
->type
->semantic(e
->loc
, sc
);
268 void visit(ComplexExp
*e
)
271 e
->type
= Type::tcomplex80
;
273 e
->type
= e
->type
->semantic(e
->loc
, sc
);
277 void visit(IdentifierExp
*exp
)
279 if (exp
->type
) // This is used as the dummy expression
286 Dsymbol
*s
= sc
->search(exp
->loc
, exp
->ident
, &scopesym
);
294 /* See if the symbol was a member of an enclosing 'with'
296 WithScopeSymbol
*withsym
= scopesym
->isWithScopeSymbol();
297 if (withsym
&& withsym
->withstate
->wthis
)
299 /* Disallow shadowing
301 // First find the scope of the with
303 while (scwith
->scopesym
!= scopesym
)
305 scwith
= scwith
->enclosing
;
308 // Look at enclosing scopes for symbols with the same name,
309 // in the same function
310 for (Scope
*scx
= scwith
; scx
&& scx
->func
== scwith
->func
; scx
= scx
->enclosing
)
313 if (scx
->scopesym
&& scx
->scopesym
->symtab
&&
314 (s2
= scx
->scopesym
->symtab
->lookup(s
->ident
)) != NULL
&&
317 exp
->error("with symbol %s is shadowing local symbol %s", s
->toPrettyChars(), s2
->toPrettyChars());
323 // Same as wthis.ident
324 // TODO: DotIdExp.semantic will find 'ident' from 'wthis' again.
325 // The redudancy should be removed.
326 e
= new VarExp(exp
->loc
, withsym
->withstate
->wthis
);
327 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
334 Declaration
*d
= s
->isDeclaration();
336 checkAccess(exp
->loc
, sc
, NULL
, d
);
339 /* If f is really a function template,
340 * then replace f with the function template declaration.
342 FuncDeclaration
*f
= s
->isFuncDeclaration();
345 TemplateDeclaration
*td
= getFuncTemplateDecl(f
);
348 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
349 td
= td
->overroot
; // then get the start
350 e
= new TemplateExp(exp
->loc
, td
, f
);
356 // Haven't done overload resolution yet, so pass 1
357 e
= resolve(exp
->loc
, sc
, s
, true);
365 AggregateDeclaration
*ad
= sc
->getStructClassScope();
366 if (ad
&& ad
->aliasthis
)
369 e
= new IdentifierExp(exp
->loc
, Id::This
);
370 e
= new DotIdExp(exp
->loc
, e
, ad
->aliasthis
->ident
);
371 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
372 e
= trySemantic(e
, sc
);
381 if (exp
->ident
== Id::ctfe
)
383 if (sc
->flags
& SCOPEctfe
)
385 exp
->error("variable __ctfe cannot be read at compile time");
389 // Create the magic __ctfe bool variable
390 VarDeclaration
*vd
= new VarDeclaration(exp
->loc
, Type::tbool
, Id::ctfe
, NULL
);
391 vd
->storage_class
|= STCtemp
;
392 Expression
*e
= new VarExp(exp
->loc
, vd
);
398 // If we've reached this point and are inside a with() scope then we may
399 // try one last attempt by checking whether the 'wthis' object supports
400 // dynamic dispatching via opDispatch.
401 // This is done by rewriting this expression as wthis.ident.
402 for (Scope
*sc2
= sc
; sc2
; sc2
= sc2
->enclosing
)
407 if (WithScopeSymbol
*ss
= sc2
->scopesym
->isWithScopeSymbol())
409 if (ss
->withstate
->wthis
)
412 e
= new VarExp(exp
->loc
, ss
->withstate
->wthis
);
413 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
414 e
= trySemantic(e
, sc
);
425 /* Look for what user might have meant
427 if (const char *n
= importHint(exp
->ident
->toChars()))
428 exp
->error("`%s` is not defined, perhaps `import %s;` is needed?", exp
->ident
->toChars(), n
);
429 else if (Dsymbol
*s2
= sc
->search_correct(exp
->ident
))
430 exp
->error("undefined identifier `%s`, did you mean %s `%s`?", exp
->ident
->toChars(), s2
->kind(), s2
->toChars());
431 else if (const char *p
= Scope::search_correct_C(exp
->ident
))
432 exp
->error("undefined identifier `%s`, did you mean `%s`?", exp
->ident
->toChars(), p
);
434 exp
->error("undefined identifier `%s`", exp
->ident
->toChars());
438 void visit(DsymbolExp
*e
)
440 result
= resolve(e
->loc
, sc
, e
->s
, e
->hasOverloads
);
443 void visit(ThisExp
*e
)
451 FuncDeclaration
*fd
= hasThis(sc
); // fd is the uplevel function with the 'this' variable
453 /* Special case for typeof(this) and typeof(super) since both
454 * should work even if they are not inside a non-static member function
456 if (!fd
&& sc
->intypeof
== 1)
458 // Find enclosing struct or class
459 for (Dsymbol
*s
= sc
->getStructClassScope(); 1; s
= s
->parent
)
463 e
->error("%s is not in a class or struct scope", e
->toChars());
466 ClassDeclaration
*cd
= s
->isClassDeclaration();
473 StructDeclaration
*sd
= s
->isStructDeclaration();
487 assert(e
->var
->parent
);
488 e
->type
= e
->var
->type
;
489 if (e
->var
->checkNestedReference(sc
, e
->loc
))
492 sc
->callSuper
|= CSXthis
;
497 e
->error("'this' is only defined in non-static member functions, not %s", sc
->parent
->toChars());
501 void visit(SuperExp
*e
)
509 FuncDeclaration
*fd
= hasThis(sc
);
510 ClassDeclaration
*cd
;
513 /* Special case for typeof(this) and typeof(super) since both
514 * should work even if they are not inside a non-static member function
516 if (!fd
&& sc
->intypeof
== 1)
518 // Find enclosing class
519 for (s
= sc
->getStructClassScope(); 1; s
= s
->parent
)
523 e
->error("%s is not in a class scope", e
->toChars());
526 cd
= s
->isClassDeclaration();
532 e
->error("class %s has no 'super'", s
->toChars());
545 assert(e
->var
&& e
->var
->parent
);
548 while (s
&& s
->isTemplateInstance())
550 if (s
->isTemplateDeclaration()) // allow inside template constraint
553 cd
= s
->isClassDeclaration();
554 //printf("parent is %s %s\n", fd->toParent()->kind(), fd->toParent()->toChars());
559 e
->error("no base class for %s", cd
->toChars());
560 e
->type
= e
->var
->type
;
564 e
->type
= cd
->baseClass
->type
;
565 e
->type
= e
->type
->castMod(e
->var
->type
->mod
);
568 if (e
->var
->checkNestedReference(sc
, e
->loc
))
572 sc
->callSuper
|= CSXsuper
;
577 e
->error("'super' is only allowed in non-static class member functions");
581 void visit(NullExp
*e
)
583 // NULL is the same as (void *)0
589 e
->type
= Type::tnull
;
593 void visit(StringExp
*e
)
610 for (u
= 0; u
< e
->len
;)
612 p
= utf_decodeChar((utf8_t
*)e
->string
, e
->len
, &u
, &c
);
625 e
->string
= buffer
.extractData();
628 e
->type
= new TypeDArray(Type::tdchar
->immutableOf());
633 for (u
= 0; u
< e
->len
;)
635 p
= utf_decodeChar((utf8_t
*)e
->string
, e
->len
, &u
, &c
);
643 buffer
.writeUTF16(c
);
649 buffer
.writeUTF16(0);
650 e
->string
= buffer
.extractData();
653 e
->type
= new TypeDArray(Type::twchar
->immutableOf());
662 e
->type
= new TypeDArray(Type::tchar
->immutableOf());
665 e
->type
= e
->type
->semantic(e
->loc
, sc
);
666 //e->type = e->type->immutableOf();
667 //printf("type = %s\n", e->type->toChars());
672 void visit(ArrayLiteralExp
*e
)
680 /* Perhaps an empty array literal [ ] should be rewritten as null?
684 e
->basis
= semantic(e
->basis
, sc
);
685 if (arrayExpressionSemantic(e
->elements
, sc
) || (e
->basis
&& e
->basis
->op
== TOKerror
))
687 expandTuples(e
->elements
);
691 e
->elements
->push(e
->basis
);
692 bool err
= arrayExpressionToCommonType(sc
, e
->elements
, &t0
);
698 e
->type
= t0
->arrayOf();
699 e
->type
= e
->type
->semantic(e
->loc
, sc
);
701 /* Disallow array literals of type void being used.
703 if (e
->elements
->dim
> 0 && t0
->ty
== Tvoid
)
705 e
->error("%s of type %s has no value", e
->toChars(), e
->type
->toChars());
709 semanticTypeInfo(sc
, e
->type
);
714 void visit(AssocArrayLiteralExp
*e
)
722 // Run semantic() on each element
723 bool err_keys
= arrayExpressionSemantic(e
->keys
, sc
);
724 bool err_vals
= arrayExpressionSemantic(e
->values
, sc
);
725 if (err_keys
|| err_vals
)
727 expandTuples(e
->keys
);
728 expandTuples(e
->values
);
729 if (e
->keys
->dim
!= e
->values
->dim
)
731 e
->error("number of keys is %u, must match number of values %u", e
->keys
->dim
, e
->values
->dim
);
737 err_keys
= arrayExpressionToCommonType(sc
, e
->keys
, &tkey
);
738 err_vals
= arrayExpressionToCommonType(sc
, e
->values
, &tvalue
);
739 if (err_keys
|| err_vals
)
742 if (tkey
== Type::terror
|| tvalue
== Type::terror
)
745 e
->type
= new TypeAArray(tvalue
, tkey
);
746 e
->type
= e
->type
->semantic(e
->loc
, sc
);
748 semanticTypeInfo(sc
, e
->type
);
753 void visit(StructLiteralExp
*e
)
762 if (e
->sd
->sizeok
!= SIZEOKdone
)
765 if (arrayExpressionSemantic(e
->elements
, sc
)) // run semantic() on each element
767 expandTuples(e
->elements
);
769 /* Fit elements[] to the corresponding type of field[].
771 if (!e
->sd
->fit(e
->loc
, sc
, e
->elements
, e
->stype
))
774 /* Fill out remainder of elements[] with default initializers for fields[]
776 if (!e
->sd
->fill(e
->loc
, e
->elements
, false))
778 /* An error in the initializer needs to be recorded as an error
779 * in the enclosing function or template, since the initializer
780 * will be part of the stuct declaration.
782 global
.increaseErrorCount();
786 if (checkFrameAccess(e
->loc
, sc
, e
->sd
, e
->elements
->dim
))
789 e
->type
= e
->stype
? e
->stype
: e
->sd
->type
;
793 void visit(TypeExp
*exp
)
795 if (exp
->type
->ty
== Terror
)
798 //printf("TypeExp::semantic(%s)\n", exp->type->toChars());
803 exp
->type
->resolve(exp
->loc
, sc
, &e
, &t
, &s
, true);
806 //printf("e = %s %s\n", Token::toChars(e->op), e->toChars());
811 //printf("t = %d %s\n", t->ty, t->toChars());
812 exp
->type
= t
->semantic(exp
->loc
, sc
);
817 //printf("s = %s %s\n", s->kind(), s->toChars());
818 e
= resolve(exp
->loc
, sc
, s
, true);
823 if (global
.params
.vcomplex
)
824 exp
->type
->checkComplexTransition(exp
->loc
);
829 void visit(ScopeExp
*exp
)
837 ScopeDsymbol
*sds2
= exp
->sds
;
838 TemplateInstance
*ti
= sds2
->isTemplateInstance();
841 WithScopeSymbol
*withsym
;
842 if (!ti
->findTempDecl(sc
, &withsym
) ||
843 !ti
->semanticTiargs(sc
))
845 if (withsym
&& withsym
->withstate
->wthis
)
847 Expression
*e
= new VarExp(exp
->loc
, withsym
->withstate
->wthis
);
848 e
= new DotTemplateInstanceExp(exp
->loc
, e
, ti
);
849 result
= semantic(e
, sc
);
852 if (ti
->needsTypeInference(sc
))
854 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
856 Dsymbol
*p
= td
->toParent2();
857 FuncDeclaration
*fdthis
= hasThis(sc
);
858 AggregateDeclaration
*ad
= p
? p
->isAggregateDeclaration() : NULL
;
859 if (fdthis
&& ad
&& isAggregate(fdthis
->vthis
->type
) == ad
&&
860 (td
->_scope
->stc
& STCstatic
) == 0)
862 Expression
*e
= new DotTemplateInstanceExp(exp
->loc
, new ThisExp(exp
->loc
), ti
->name
, ti
->tiargs
);
863 result
= semantic(e
, sc
);
867 else if (OverloadSet
*os
= ti
->tempdecl
->isOverloadSet())
869 FuncDeclaration
*fdthis
= hasThis(sc
);
870 AggregateDeclaration
*ad
= os
->parent
->isAggregateDeclaration();
871 if (fdthis
&& ad
&& isAggregate(fdthis
->vthis
->type
) == ad
)
873 Expression
*e
= new DotTemplateInstanceExp(exp
->loc
, new ThisExp(exp
->loc
), ti
->name
, ti
->tiargs
);
874 result
= semantic(e
, sc
);
878 // ti is an instance which requires IFTI.
880 exp
->type
= Type::tvoid
;
885 if (!ti
->inst
|| ti
->errors
)
888 Dsymbol
*s
= ti
->toAlias();
892 exp
->type
= Type::tvoid
;
896 sds2
= s
->isScopeDsymbol();
899 ti
= sds2
->isTemplateInstance();
900 //printf("+ sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
904 if (VarDeclaration
*v
= s
->isVarDeclaration())
908 exp
->error("forward reference of %s %s", v
->kind(), v
->toChars());
911 if ((v
->storage_class
& STCmanifest
) && v
->_init
)
913 /* When an instance that will be converted to a constant exists,
914 * the instance representation "foo!tiargs" is treated like a
915 * variable name, and its recursive appearance check (note that
916 * it's equivalent with a recursive instantiation of foo) is done
917 * separately from the circular initialization check for the
918 * eponymous enum variable declaration.
921 * enum bool foo = foo; // recursive definition check (v.inuse)
924 * enum bool bar = bar!T; // recursive instantiation check (ti.inuse)
929 exp
->error("recursive expansion of %s '%s'", ti
->kind(), ti
->toPrettyChars());
933 Expression
*e
= v
->expandInitializer(exp
->loc
);
942 //printf("s = %s, '%s'\n", s->kind(), s->toChars());
943 Expression
*e
= resolve(exp
->loc
, sc
, s
, true);
944 //printf("-1ScopeExp::semantic()\n");
949 //printf("sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
950 //printf("\tparent = '%s'\n", sds2->parent->toChars());
953 if (Type
*t
= sds2
->getType()) // (Aggregate|Enum)Declaration
955 Expression
*ex
= new TypeExp(exp
->loc
, t
);
956 result
= semantic(ex
, sc
);
960 if (TemplateDeclaration
*td
= sds2
->isTemplateDeclaration())
962 result
= semantic(new TemplateExp(exp
->loc
, td
), sc
);
967 exp
->type
= Type::tvoid
;
968 //printf("-2ScopeExp::semantic() %s\n", exp->toChars());
972 void visit(NewExp
*exp
)
974 if (exp
->type
) // if semantic() already run
980 // Bugzilla 11581: With the syntax `new T[edim]` or `thisexp.new T[edim]`,
981 // T should be analyzed first and edim should go into arguments iff it's
983 Expression
*edim
= NULL
;
984 if (!exp
->arguments
&& exp
->newtype
->ty
== Tsarray
)
986 edim
= ((TypeSArray
*)exp
->newtype
)->dim
;
987 exp
->newtype
= ((TypeNext
*)exp
->newtype
)->next
;
990 ClassDeclaration
*cdthis
= NULL
;
993 exp
->thisexp
= semantic(exp
->thisexp
, sc
);
994 if (exp
->thisexp
->op
== TOKerror
)
996 cdthis
= exp
->thisexp
->type
->isClassHandle();
999 exp
->error("'this' for nested class must be a class type, not %s", exp
->thisexp
->type
->toChars());
1003 sc
= sc
->push(cdthis
);
1004 exp
->type
= exp
->newtype
->semantic(exp
->loc
, sc
);
1009 exp
->type
= exp
->newtype
->semantic(exp
->loc
, sc
);
1011 if (exp
->type
->ty
== Terror
)
1016 if (exp
->type
->toBasetype()->ty
== Ttuple
)
1019 exp
->type
= new TypeSArray(exp
->type
, edim
);
1020 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1021 if (exp
->type
->ty
== Terror
)
1026 // --> new T[](edim)
1027 exp
->arguments
= new Expressions();
1028 exp
->arguments
->push(edim
);
1029 exp
->type
= exp
->type
->arrayOf();
1033 exp
->newtype
= exp
->type
; // in case type gets cast to something else
1034 Type
*tb
= exp
->type
->toBasetype();
1035 //printf("tb: %s, deco = %s\n", tb->toChars(), tb->deco);
1037 if (arrayExpressionSemantic(exp
->newargs
, sc
) ||
1038 preFunctionParameters(sc
, exp
->newargs
))
1042 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
1043 preFunctionParameters(sc
, exp
->arguments
))
1048 if (exp
->thisexp
&& tb
->ty
!= Tclass
)
1050 exp
->error("e.new is only for allocating nested classes, not %s", tb
->toChars());
1054 size_t nargs
= exp
->arguments
? exp
->arguments
->dim
: 0;
1055 Expression
*newprefix
= NULL
;
1057 if (tb
->ty
== Tclass
)
1059 ClassDeclaration
*cd
= ((TypeClass
*)tb
)->sym
;
1061 if (cd
->sizeok
!= SIZEOKdone
)
1064 cd
->ctor
= cd
->searchCtor();
1065 if (cd
->noDefaultCtor
&& !nargs
&& !cd
->defaultCtor
)
1067 exp
->error("default construction is disabled for type %s", cd
->type
->toChars());
1071 if (cd
->isInterfaceDeclaration())
1073 exp
->error("cannot create instance of interface %s", cd
->toChars());
1076 if (cd
->isAbstract())
1078 exp
->error("cannot create instance of abstract class %s", cd
->toChars());
1079 for (size_t i
= 0; i
< cd
->vtbl
.dim
; i
++)
1081 FuncDeclaration
*fd
= cd
->vtbl
[i
]->isFuncDeclaration();
1082 if (fd
&& fd
->isAbstract())
1083 errorSupplemental(exp
->loc
, "function '%s' is not implemented", fd
->toFullSignature());
1087 // checkDeprecated() is already done in newtype->semantic().
1091 /* We need a 'this' pointer for the nested class.
1092 * Ensure we have the right one.
1094 Dsymbol
*s
= cd
->toParent2();
1095 //printf("cd isNested, parent = %s '%s'\n", s->kind(), s->toPrettyChars());
1096 if (ClassDeclaration
*cdn
= s
->isClassDeclaration())
1100 // Supply an implicit 'this' and try again
1101 exp
->thisexp
= new ThisExp(exp
->loc
);
1102 for (Dsymbol
*sp
= sc
->parent
; 1; sp
= sp
->parent
)
1106 exp
->error("outer class %s 'this' needed to 'new' nested class %s", cdn
->toChars(), cd
->toChars());
1109 ClassDeclaration
*cdp
= sp
->isClassDeclaration();
1112 if (cdp
== cdn
|| cdn
->isBaseOf(cdp
, NULL
))
1114 // Add a '.outer' and try again
1115 exp
->thisexp
= new DotIdExp(exp
->loc
, exp
->thisexp
, Id::outer
);
1117 exp
->thisexp
= semantic(exp
->thisexp
, sc
);
1118 if (exp
->thisexp
->op
== TOKerror
)
1120 cdthis
= exp
->thisexp
->type
->isClassHandle();
1122 if (cdthis
!= cdn
&& !cdn
->isBaseOf(cdthis
, NULL
))
1124 //printf("cdthis = %s\n", cdthis->toChars());
1125 exp
->error("'this' for nested class must be of type %s, not %s",
1126 cdn
->toChars(), exp
->thisexp
->type
->toChars());
1129 if (!MODimplicitConv(exp
->thisexp
->type
->mod
, exp
->newtype
->mod
))
1131 exp
->error("nested type %s should have the same or weaker constancy as enclosing type %s",
1132 exp
->newtype
->toChars(), exp
->thisexp
->type
->toChars());
1136 else if (exp
->thisexp
)
1138 exp
->error("e.new is only for allocating nested classes");
1141 else if (FuncDeclaration
*fdn
= s
->isFuncDeclaration())
1143 // make sure the parent context fdn of cd is reachable from sc
1144 if (checkNestedRef(sc
->parent
, fdn
))
1146 exp
->error("outer function context of %s is needed to 'new' nested class %s",
1147 fdn
->toPrettyChars(), cd
->toPrettyChars());
1154 else if (exp
->thisexp
)
1156 exp
->error("e.new is only for allocating nested classes");
1162 // Prepend the size argument to newargs[]
1163 Expression
*e
= new IntegerExp(exp
->loc
, cd
->size(exp
->loc
), Type::tsize_t
);
1165 exp
->newargs
= new Expressions();
1166 exp
->newargs
->shift(e
);
1168 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, cd
->aggNew
, NULL
, tb
, exp
->newargs
);
1169 if (!f
|| f
->errors
)
1171 exp
->checkDeprecated(sc
, f
);
1172 exp
->checkPurity(sc
, f
);
1173 exp
->checkSafety(sc
, f
);
1174 exp
->checkNogc(sc
, f
);
1175 checkAccess(cd
, exp
->loc
, sc
, f
);
1177 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1179 if (functionParameters(exp
->loc
, sc
, tf
, NULL
, exp
->newargs
, f
, &rettype
, &newprefix
))
1182 exp
->allocator
= f
->isNewDeclaration();
1183 assert(exp
->allocator
);
1187 if (exp
->newargs
&& exp
->newargs
->dim
)
1189 exp
->error("no allocator for %s", cd
->toChars());
1196 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, cd
->ctor
, NULL
, tb
, exp
->arguments
, 0);
1197 if (!f
|| f
->errors
)
1199 exp
->checkDeprecated(sc
, f
);
1200 exp
->checkPurity(sc
, f
);
1201 exp
->checkSafety(sc
, f
);
1202 exp
->checkNogc(sc
, f
);
1203 checkAccess(cd
, exp
->loc
, sc
, f
);
1205 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1206 if (!exp
->arguments
)
1207 exp
->arguments
= new Expressions();
1208 if (functionParameters(exp
->loc
, sc
, tf
, exp
->type
, exp
->arguments
, f
, &exp
->type
, &exp
->argprefix
))
1211 exp
->member
= f
->isCtorDeclaration();
1212 assert(exp
->member
);
1218 exp
->error("no constructor for %s", cd
->toChars());
1223 else if (tb
->ty
== Tstruct
)
1225 StructDeclaration
*sd
= ((TypeStruct
*)tb
)->sym
;
1227 if (sd
->sizeok
!= SIZEOKdone
)
1230 sd
->ctor
= sd
->searchCtor();
1231 if (sd
->noDefaultCtor
&& !nargs
)
1233 exp
->error("default construction is disabled for type %s", sd
->type
->toChars());
1236 // checkDeprecated() is already done in newtype->semantic().
1240 // Prepend the uint size argument to newargs[]
1241 Expression
*e
= new IntegerExp(exp
->loc
, sd
->size(exp
->loc
), Type::tsize_t
);
1243 exp
->newargs
= new Expressions();
1244 exp
->newargs
->shift(e
);
1246 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, sd
->aggNew
, NULL
, tb
, exp
->newargs
);
1247 if (!f
|| f
->errors
)
1249 exp
->checkDeprecated(sc
, f
);
1250 exp
->checkPurity(sc
, f
);
1251 exp
->checkSafety(sc
, f
);
1252 exp
->checkNogc(sc
, f
);
1253 checkAccess(sd
, exp
->loc
, sc
, f
);
1255 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1257 if (functionParameters(exp
->loc
, sc
, tf
, NULL
, exp
->newargs
, f
, &rettype
, &newprefix
))
1260 exp
->allocator
= f
->isNewDeclaration();
1261 assert(exp
->allocator
);
1265 if (exp
->newargs
&& exp
->newargs
->dim
)
1267 exp
->error("no allocator for %s", sd
->toChars());
1272 if (sd
->ctor
&& nargs
)
1274 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, sd
->ctor
, NULL
, tb
, exp
->arguments
, 0);
1275 if (!f
|| f
->errors
)
1277 exp
->checkDeprecated(sc
, f
);
1278 exp
->checkPurity(sc
, f
);
1279 exp
->checkSafety(sc
, f
);
1280 exp
->checkNogc(sc
, f
);
1281 checkAccess(sd
, exp
->loc
, sc
, f
);
1283 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1284 if (!exp
->arguments
)
1285 exp
->arguments
= new Expressions();
1286 if (functionParameters(exp
->loc
, sc
, tf
, exp
->type
, exp
->arguments
, f
, &exp
->type
, &exp
->argprefix
))
1289 exp
->member
= f
->isCtorDeclaration();
1290 assert(exp
->member
);
1292 if (checkFrameAccess(exp
->loc
, sc
, sd
, sd
->fields
.dim
))
1297 if (!exp
->arguments
)
1298 exp
->arguments
= new Expressions();
1300 if (!sd
->fit(exp
->loc
, sc
, exp
->arguments
, tb
))
1302 if (!sd
->fill(exp
->loc
, exp
->arguments
, false))
1304 if (checkFrameAccess(exp
->loc
, sc
, sd
, exp
->arguments
? exp
->arguments
->dim
: 0))
1308 exp
->type
= exp
->type
->pointerTo();
1310 else if (tb
->ty
== Tarray
&& nargs
)
1312 Type
*tn
= tb
->nextOf()->baseElemOf();
1313 Dsymbol
*s
= tn
->toDsymbol(sc
);
1314 AggregateDeclaration
*ad
= s
? s
->isAggregateDeclaration() : NULL
;
1315 if (ad
&& ad
->noDefaultCtor
)
1317 exp
->error("default construction is disabled for type %s", tb
->nextOf()->toChars());
1320 for (size_t i
= 0; i
< nargs
; i
++)
1322 if (tb
->ty
!= Tarray
)
1324 exp
->error("too many arguments for array");
1328 Expression
*arg
= (*exp
->arguments
)[i
];
1329 arg
= resolveProperties(sc
, arg
);
1330 arg
= arg
->implicitCastTo(sc
, Type::tsize_t
);
1331 arg
= arg
->optimize(WANTvalue
);
1332 if (arg
->op
== TOKint64
&& (sinteger_t
)arg
->toInteger() < 0)
1334 exp
->error("negative array index %s", arg
->toChars());
1337 (*exp
->arguments
)[i
] = arg
;
1338 tb
= ((TypeDArray
*)tb
)->next
->toBasetype();
1341 else if (tb
->isscalar())
1346 else if (nargs
== 1)
1348 Expression
*e
= (*exp
->arguments
)[0];
1349 e
= e
->implicitCastTo(sc
, tb
);
1350 (*exp
->arguments
)[0] = e
;
1354 exp
->error("more than one argument for construction of %s", exp
->type
->toChars());
1358 exp
->type
= exp
->type
->pointerTo();
1362 exp
->error("new can only create structs, dynamic arrays or class objects, not %s's", exp
->type
->toChars());
1366 //printf("NewExp: '%s'\n", toChars());
1367 //printf("NewExp:type '%s'\n", exp->type->toChars());
1368 semanticTypeInfo(sc
, exp
->type
);
1372 result
= Expression::combine(newprefix
, exp
);
1378 void visit(NewAnonClassExp
*e
)
1380 Expression
*d
= new DeclarationExp(e
->loc
, e
->cd
);
1381 sc
= sc
->push(); // just create new scope
1382 sc
->flags
&= ~SCOPEctfe
; // temporary stop CTFE
1383 d
= semantic(d
, sc
);
1386 if (!e
->cd
->errors
&& sc
->intypeof
&& !sc
->parent
->inNonRoot())
1388 ScopeDsymbol
*sds
= sc
->tinst
? (ScopeDsymbol
*)sc
->tinst
: sc
->_module
;
1389 sds
->members
->push(e
->cd
);
1392 Expression
*n
= new NewExp(e
->loc
, e
->thisexp
, e
->newargs
, e
->cd
->type
, e
->arguments
);
1394 Expression
*c
= new CommaExp(e
->loc
, d
, n
);
1395 result
= semantic(c
, sc
);
1398 void visit(SymOffExp
*e
)
1400 //var->semantic(sc);
1402 e
->type
= e
->var
->type
->pointerTo();
1403 if (VarDeclaration
*v
= e
->var
->isVarDeclaration())
1405 if (v
->checkNestedReference(sc
, e
->loc
))
1408 else if (FuncDeclaration
*f
= e
->var
->isFuncDeclaration())
1410 if (f
->checkNestedReference(sc
, e
->loc
))
1416 void visit(VarExp
*e
)
1418 if (FuncDeclaration
*fd
= e
->var
->isFuncDeclaration())
1420 //printf("L%d fd = %s\n", __LINE__, f->toChars());
1421 if (!fd
->functionSemantic())
1426 e
->type
= e
->var
->type
;
1428 if (e
->type
&& !e
->type
->deco
)
1429 e
->type
= e
->type
->semantic(e
->loc
, sc
);
1431 /* Fix for 1161 doesn't work because it causes protection
1432 * problems when instantiating imported templates passing private
1433 * variables as alias template parameters.
1435 //checkAccess(e->loc, sc, NULL, e->var);
1437 if (VarDeclaration
*vd
= e
->var
->isVarDeclaration())
1439 if (vd
->checkNestedReference(sc
, e
->loc
))
1441 // Bugzilla 12025: If the variable is not actually used in runtime code,
1442 // the purity violation error is redundant.
1443 //checkPurity(sc, vd);
1445 else if (FuncDeclaration
*fd
= e
->var
->isFuncDeclaration())
1447 // TODO: If fd isn't yet resolved its overload, the checkNestedReference
1448 // call would cause incorrect validation.
1449 // Maybe here should be moved in CallExp, or AddrExp for functions.
1450 if (fd
->checkNestedReference(sc
, e
->loc
))
1453 else if (e
->var
->isOverDeclaration())
1455 e
->type
= Type::tvoid
; // ambiguous type?
1461 void visit(TupleExp
*exp
)
1470 exp
->e0
= semantic(exp
->e0
, sc
);
1472 // Run semantic() on each argument
1474 for (size_t i
= 0; i
< exp
->exps
->dim
; i
++)
1476 Expression
*e
= (*exp
->exps
)[i
];
1477 e
= semantic(e
, sc
);
1480 exp
->error("%s has no value", e
->toChars());
1483 else if (e
->op
== TOKerror
)
1486 (*exp
->exps
)[i
] = e
;
1491 expandTuples(exp
->exps
);
1492 exp
->type
= new TypeTuple(exp
->exps
);
1493 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1494 //printf("-TupleExp::semantic(%s)\n", exp->toChars());
1498 void visit(FuncExp
*exp
)
1500 Expression
*e
= exp
;
1502 sc
= sc
->push(); // just create new scope
1503 sc
->flags
&= ~SCOPEctfe
; // temporary stop CTFE
1504 sc
->protection
= Prot(PROTpublic
); // Bugzilla 12506
1506 if (!exp
->type
|| exp
->type
== Type::tvoid
)
1508 /* fd->treq might be incomplete type,
1509 * so should not semantic it.
1510 * void foo(T)(T delegate(int) dg){}
1511 * foo(a=>a); // in IFTI, treq == T delegate(int)
1513 //if (exp->fd->treq)
1514 // exp->fd->treq = exp->fd->treq->semantic(exp->loc, sc);
1518 // Set target of return type inference
1519 if (exp
->fd
->treq
&& !exp
->fd
->type
->nextOf())
1521 TypeFunction
*tfv
= NULL
;
1522 if (exp
->fd
->treq
->ty
== Tdelegate
||
1523 (exp
->fd
->treq
->ty
== Tpointer
&& exp
->fd
->treq
->nextOf()->ty
== Tfunction
))
1524 tfv
= (TypeFunction
*)exp
->fd
->treq
->nextOf();
1527 TypeFunction
*tfl
= (TypeFunction
*)exp
->fd
->type
;
1528 tfl
->next
= tfv
->nextOf();
1532 //printf("td = %p, treq = %p\n", exp->td, exp->fd->treq);
1535 assert(exp
->td
->parameters
&& exp
->td
->parameters
->dim
);
1536 exp
->td
->semantic(sc
);
1537 exp
->type
= Type::tvoid
; // temporary type
1539 if (exp
->fd
->treq
) // defer type determination
1542 if (exp
->matchType(exp
->fd
->treq
, sc
, &fe
) > MATCHnomatch
)
1550 unsigned olderrors
= global
.errors
;
1551 exp
->fd
->semantic(sc
);
1552 if (olderrors
== global
.errors
)
1554 exp
->fd
->semantic2(sc
);
1555 if (olderrors
== global
.errors
)
1556 exp
->fd
->semantic3(sc
);
1558 if (olderrors
!= global
.errors
)
1560 if (exp
->fd
->type
&& exp
->fd
->type
->ty
== Tfunction
&& !exp
->fd
->type
->nextOf())
1561 ((TypeFunction
*)exp
->fd
->type
)->next
= Type::terror
;
1566 // Type is a "delegate to" or "pointer to" the function literal
1567 if ((exp
->fd
->isNested() && exp
->fd
->tok
== TOKdelegate
) ||
1568 (exp
->tok
== TOKreserved
&& exp
->fd
->treq
&& exp
->fd
->treq
->ty
== Tdelegate
))
1570 exp
->type
= new TypeDelegate(exp
->fd
->type
);
1571 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1573 exp
->fd
->tok
= TOKdelegate
;
1577 exp
->type
= new TypePointer(exp
->fd
->type
);
1578 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1579 //exp->type = exp->fd->type->pointerTo();
1581 /* A lambda expression deduced to function pointer might become
1582 * to a delegate literal implicitly.
1584 * auto foo(void function() fp) { return 1; }
1585 * assert(foo({}) == 1);
1587 * So, should keep fd->tok == TOKreserve if fd->treq == NULL.
1589 if (exp
->fd
->treq
&& exp
->fd
->treq
->ty
== Tpointer
)
1591 // change to non-nested
1592 exp
->fd
->tok
= TOKfunction
;
1593 exp
->fd
->vthis
= NULL
;
1596 exp
->fd
->tookAddressOf
++;
1603 // used from CallExp::semantic()
1604 Expression
*callExpSemantic(FuncExp
*exp
, Scope
*sc
, Expressions
*arguments
)
1606 if ((!exp
->type
|| exp
->type
== Type::tvoid
) && exp
->td
&& arguments
&& arguments
->dim
)
1608 for (size_t k
= 0; k
< arguments
->dim
; k
++)
1609 { Expression
*checkarg
= (*arguments
)[k
];
1610 if (checkarg
->op
== TOKerror
)
1616 assert(exp
->td
->parameters
&& exp
->td
->parameters
->dim
);
1617 exp
->td
->semantic(sc
);
1619 TypeFunction
*tfl
= (TypeFunction
*)exp
->fd
->type
;
1620 size_t dim
= Parameter::dim(tfl
->parameters
);
1621 if (arguments
->dim
< dim
)
1622 { // Default arguments are always typed, so they don't need inference.
1623 Parameter
*p
= Parameter::getNth(tfl
->parameters
, arguments
->dim
);
1625 dim
= arguments
->dim
;
1628 if ((!tfl
->varargs
&& arguments
->dim
== dim
) ||
1629 ( tfl
->varargs
&& arguments
->dim
>= dim
))
1631 Objects
*tiargs
= new Objects();
1632 tiargs
->reserve(exp
->td
->parameters
->dim
);
1634 for (size_t i
= 0; i
< exp
->td
->parameters
->dim
; i
++)
1636 TemplateParameter
*tp
= (*exp
->td
->parameters
)[i
];
1637 for (size_t u
= 0; u
< dim
; u
++)
1638 { Parameter
*p
= Parameter::getNth(tfl
->parameters
, u
);
1639 if (p
->type
->ty
== Tident
&&
1640 ((TypeIdentifier
*)p
->type
)->ident
== tp
->ident
)
1641 { Expression
*e
= (*arguments
)[u
];
1642 tiargs
->push(e
->type
);
1643 u
= dim
; // break inner loop
1648 TemplateInstance
*ti
= new TemplateInstance(exp
->loc
, exp
->td
, tiargs
);
1649 Expression
*se
= new ScopeExp(exp
->loc
, ti
);
1650 return semantic(se
, sc
);
1652 exp
->error("cannot infer function literal type");
1653 return new ErrorExp();
1655 return semantic(exp
, sc
);
1658 void visit(DeclarationExp
*e
)
1666 unsigned olderrors
= global
.errors
;
1668 /* This is here to support extern(linkage) declaration,
1669 * where the extern(linkage) winds up being an AttribDeclaration
1672 Dsymbol
*s
= e
->declaration
;
1676 AttribDeclaration
*ad
= s
->isAttribDeclaration();
1679 if (ad
->decl
&& ad
->decl
->dim
== 1)
1688 VarDeclaration
*v
= s
->isVarDeclaration();
1691 // Do semantic() on initializer first, so:
1694 e
->declaration
->semantic(sc
);
1695 s
->parent
= sc
->parent
;
1698 //printf("inserting '%s' %p into sc = %p\n", s->toChars(), s, sc);
1699 // Insert into both local scope and function scope.
1700 // Must be unique in both.
1705 e
->error("declaration %s is already defined", s
->toPrettyChars());
1710 // Bugzilla 11720 - include Dataseg variables
1711 if ((s
->isFuncDeclaration() ||
1712 s
->isAggregateDeclaration() ||
1713 s
->isEnumDeclaration() ||
1714 (v
&& v
->isDataseg())) &&
1715 !sc
->func
->localsymtab
->insert(s
))
1717 e
->error("declaration %s is already defined in another scope in %s",
1718 s
->toPrettyChars(), sc
->func
->toChars());
1723 // Disallow shadowing
1724 for (Scope
*scx
= sc
->enclosing
; scx
&& scx
->func
== sc
->func
; scx
= scx
->enclosing
)
1727 if (scx
->scopesym
&& scx
->scopesym
->symtab
&&
1728 (s2
= scx
->scopesym
->symtab
->lookup(s
->ident
)) != NULL
&&
1731 e
->error("%s %s is shadowing %s %s", s
->kind(), s
->ident
->toChars(), s2
->kind(), s2
->toPrettyChars());
1738 if (!s
->isVarDeclaration())
1741 if (sc2
->stc
& (STCpure
| STCnothrow
| STCnogc
))
1743 sc2
->stc
&= ~(STCpure
| STCnothrow
| STCnogc
);
1744 e
->declaration
->semantic(sc2
);
1747 s
->parent
= sc
->parent
;
1749 if (global
.errors
== olderrors
)
1751 e
->declaration
->semantic2(sc
);
1752 if (global
.errors
== olderrors
)
1754 e
->declaration
->semantic3(sc
);
1757 // todo: error in declaration should be propagated.
1759 e
->type
= Type::tvoid
;
1763 void visit(TypeidExp
*exp
)
1765 Type
*ta
= isType(exp
->obj
);
1766 Expression
*ea
= isExpression(exp
->obj
);
1767 Dsymbol
*sa
= isDsymbol(exp
->obj
);
1769 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1773 ta
->resolve(exp
->loc
, sc
, &ea
, &ta
, &sa
, true);
1778 if (Dsymbol
*sym
= getDsymbol(ea
))
1779 ea
= resolve(exp
->loc
, sc
, sym
, false);
1781 ea
= semantic(ea
, sc
);
1782 ea
= resolveProperties(sc
, ea
);
1784 if (ea
->op
== TOKtype
)
1790 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1791 exp
->error("no type for typeid(%s)", ea
? ea
->toChars() : (sa
? sa
->toChars() : ""));
1795 if (global
.params
.vcomplex
)
1796 ta
->checkComplexTransition(exp
->loc
);
1799 if (ea
&& ta
->toBasetype()->ty
== Tclass
)
1801 /* Get the dynamic type, which is .classinfo
1803 ea
= semantic(ea
, sc
);
1804 e
= new TypeidExp(ea
->loc
, ea
);
1805 e
->type
= Type::typeinfoclass
->type
;
1807 else if (ta
->ty
== Terror
)
1813 // Handle this in the glue layer
1814 e
= new TypeidExp(exp
->loc
, ta
);
1815 e
->type
= getTypeInfoType(ta
, sc
);
1817 semanticTypeInfo(sc
, ta
);
1821 e
= new CommaExp(exp
->loc
, ea
, e
); // execute ea
1822 e
= semantic(e
, sc
);
1828 void visit(TraitsExp
*e
)
1830 result
= semanticTraits(e
, sc
);
1833 void visit(HaltExp
*e
)
1835 e
->type
= Type::tvoid
;
1839 void visit(IsExp
*e
)
1841 /* is(targ id tok tspec)
1842 * is(targ id : tok2)
1843 * is(targ id == tok2)
1846 //printf("IsExp::semantic(%s)\n", toChars());
1847 if (e
->id
&& !(sc
->flags
& SCOPEcondition
))
1849 e
->error("can only declare type aliases within static if conditionals or static asserts");
1854 Scope
*sc2
= sc
->copy(); // keep sc->flags
1857 sc2
->flags
|= SCOPEfullinst
;
1858 Type
*t
= e
->targ
->trySemantic(e
->loc
, sc2
);
1861 goto Lno
; // errors, so condition is false
1863 if (e
->tok2
!= TOKreserved
)
1868 if (e
->targ
->ty
!= Tstruct
)
1870 if (((TypeStruct
*)e
->targ
)->sym
->isUnionDeclaration())
1876 if (e
->targ
->ty
!= Tstruct
)
1878 if (!((TypeStruct
*)e
->targ
)->sym
->isUnionDeclaration())
1884 if (e
->targ
->ty
!= Tclass
)
1886 if (((TypeClass
*)e
->targ
)->sym
->isInterfaceDeclaration())
1892 if (e
->targ
->ty
!= Tclass
)
1894 if (!((TypeClass
*)e
->targ
)->sym
->isInterfaceDeclaration())
1899 if (!e
->targ
->isConst())
1905 if (!e
->targ
->isImmutable())
1911 if (!e
->targ
->isShared())
1917 if (!e
->targ
->isWild())
1923 // If class or interface, get the base class and interfaces
1924 if (e
->targ
->ty
!= Tclass
)
1928 ClassDeclaration
*cd
= ((TypeClass
*)e
->targ
)->sym
;
1929 Parameters
*args
= new Parameters
;
1930 args
->reserve(cd
->baseclasses
->dim
);
1931 if (cd
->_scope
&& !cd
->symtab
)
1932 cd
->semantic(cd
->_scope
);
1933 for (size_t i
= 0; i
< cd
->baseclasses
->dim
; i
++)
1935 BaseClass
*b
= (*cd
->baseclasses
)[i
];
1936 args
->push(new Parameter(STCin
, b
->type
, NULL
, NULL
));
1938 tded
= new TypeTuple(args
);
1943 if (e
->targ
->ty
!= Tenum
)
1946 tded
= ((TypeEnum
*)e
->targ
)->sym
->getMemtype(e
->loc
);
1949 if (tded
->ty
== Terror
)
1954 if (e
->targ
->ty
!= Tdelegate
)
1956 tded
= ((TypeDelegate
*)e
->targ
)->next
; // the underlying function type
1962 if (e
->targ
->ty
!= Tfunction
)
1966 /* Generate tuple from function parameter types.
1968 assert(tded
->ty
== Tfunction
);
1969 Parameters
*params
= ((TypeFunction
*)tded
)->parameters
;
1970 size_t dim
= Parameter::dim(params
);
1971 Parameters
*args
= new Parameters
;
1973 for (size_t i
= 0; i
< dim
; i
++)
1975 Parameter
*arg
= Parameter::getNth(params
, i
);
1976 assert(arg
&& arg
->type
);
1977 /* If one of the default arguments was an error,
1978 don't return an invalid tuple
1980 if (e
->tok2
== TOKparameters
&& arg
->defaultArg
&&
1981 arg
->defaultArg
->op
== TOKerror
)
1983 args
->push(new Parameter(arg
->storageClass
, arg
->type
,
1984 (e
->tok2
== TOKparameters
) ? arg
->ident
: NULL
,
1985 (e
->tok2
== TOKparameters
) ? arg
->defaultArg
: NULL
));
1987 tded
= new TypeTuple(args
);
1991 /* Get the 'return type' for the function,
1992 * delegate, or pointer to function.
1994 if (e
->targ
->ty
== Tfunction
)
1995 tded
= ((TypeFunction
*)e
->targ
)->next
;
1996 else if (e
->targ
->ty
== Tdelegate
)
1998 tded
= ((TypeDelegate
*)e
->targ
)->next
;
1999 tded
= ((TypeFunction
*)tded
)->next
;
2001 else if (e
->targ
->ty
== Tpointer
&&
2002 ((TypePointer
*)e
->targ
)->next
->ty
== Tfunction
)
2004 tded
= ((TypePointer
*)e
->targ
)->next
;
2005 tded
= ((TypeFunction
*)tded
)->next
;
2012 /* Generate a type tuple of the equivalent types used to determine if a
2013 * function argument of this type can be passed in registers.
2014 * The results of this are highly platform dependent, and intended
2015 * primarly for use in implementing va_arg().
2017 tded
= toArgTypes(e
->targ
);
2019 goto Lno
; // not valid for a parameter
2023 if (e
->targ
->ty
!= Tvector
)
2025 tded
= ((TypeVector
*)e
->targ
)->basetype
;
2033 else if (e
->tspec
&& !e
->id
&& !(e
->parameters
&& e
->parameters
->dim
))
2035 /* Evaluate to true if targ matches tspec
2039 e
->tspec
= e
->tspec
->semantic(e
->loc
, sc
);
2040 //printf("targ = %s, %s\n", e->targ->toChars(), e->targ->deco);
2041 //printf("tspec = %s, %s\n", e->tspec->toChars(), e->tspec->deco);
2042 if (e
->tok
== TOKcolon
)
2044 if (e
->targ
->implicitConvTo(e
->tspec
))
2051 if (e
->targ
->equals(e
->tspec
))
2059 /* Evaluate to true if targ matches tspec.
2060 * If true, declare id as an alias for the specialized type.
2061 * is(targ == tspec, tpl)
2062 * is(targ : tspec, tpl)
2063 * is(targ id == tspec)
2064 * is(targ id : tspec)
2065 * is(targ id == tspec, tpl)
2066 * is(targ id : tspec, tpl)
2069 Identifier
*tid
= e
->id
? e
->id
: Identifier::generateId("__isexp_id");
2070 e
->parameters
->insert(0, new TemplateTypeParameter(e
->loc
, tid
, NULL
, NULL
));
2073 dedtypes
.setDim(e
->parameters
->dim
);
2076 MATCH m
= deduceType(e
->targ
, sc
, e
->tspec
, e
->parameters
, &dedtypes
);
2077 //printf("targ: %s\n", e->targ->toChars());
2078 //printf("tspec: %s\n", e->tspec->toChars());
2079 if (m
<= MATCHnomatch
||
2080 (m
!= MATCHexact
&& e
->tok
== TOKequal
))
2086 tded
= (Type
*)dedtypes
[0];
2091 tiargs
[0] = e
->targ
;
2093 /* Declare trailing parameters
2095 for (size_t i
= 1; i
< e
->parameters
->dim
; i
++)
2097 TemplateParameter
*tp
= (*e
->parameters
)[i
];
2098 Declaration
*s
= NULL
;
2100 m
= tp
->matchArg(e
->loc
, sc
, &tiargs
, i
, e
->parameters
, &dedtypes
, &s
);
2101 if (m
<= MATCHnomatch
)
2105 s
->addMember(sc
, sc
->sds
);
2106 else if (!sc
->insert(s
))
2107 e
->error("declaration %s is already defined", s
->toChars());
2109 unSpeculative(sc
, s
);
2116 /* Declare id as an alias for type targ. Evaluate to true
2127 Tuple
*tup
= isTuple(tded
);
2129 s
= new TupleDeclaration(e
->loc
, e
->id
, &(tup
->objects
));
2131 s
= new AliasDeclaration(e
->loc
, e
->id
, tded
);
2133 /* The reason for the !tup is unclear. It fails Phobos unittests if it is not there.
2134 * More investigation is needed.
2136 if (!tup
&& !sc
->insert(s
))
2137 e
->error("declaration %s is already defined", s
->toChars());
2139 s
->addMember(sc
, sc
->sds
);
2141 unSpeculative(sc
, s
);
2144 result
= new IntegerExp(e
->loc
, 1, Type::tbool
);
2149 result
= new IntegerExp(e
->loc
, 0, Type::tbool
);
2152 void visit(BinAssignExp
*exp
)
2160 Expression
*e
= exp
->op_overload(sc
);
2167 if (exp
->e1
->checkReadModifyWrite(exp
->op
, exp
->e2
))
2170 if (exp
->e1
->op
== TOKarraylength
)
2172 // arr.length op= e2;
2173 e
= ArrayLengthExp::rewriteOpAssign(exp
);
2174 e
= semantic(e
, sc
);
2178 if (exp
->e1
->op
== TOKslice
|| exp
->e1
->type
->ty
== Tarray
|| exp
->e1
->type
->ty
== Tsarray
)
2180 if (exp
->e1
->op
== TOKslice
)
2181 ((SliceExp
*)exp
->e1
)->arrayop
= true;
2184 if (exp
->e2
->implicitConvTo(exp
->e1
->type
->nextOf()))
2187 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
->nextOf());
2189 else if (Expression
*ex
= typeCombine(exp
, sc
))
2194 exp
->type
= exp
->e1
->type
;
2195 result
= arrayOp(exp
, sc
);
2199 exp
->e1
= semantic(exp
->e1
, sc
);
2200 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
2201 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
2202 exp
->type
= exp
->e1
->type
;
2203 if (exp
->checkScalar())
2206 int arith
= (exp
->op
== TOKaddass
|| exp
->op
== TOKminass
|| exp
->op
== TOKmulass
||
2207 exp
->op
== TOKdivass
|| exp
->op
== TOKmodass
|| exp
->op
== TOKpowass
);
2208 int bitwise
= (exp
->op
== TOKandass
|| exp
->op
== TOKorass
|| exp
->op
== TOKxorass
);
2209 int shift
= (exp
->op
== TOKshlass
|| exp
->op
== TOKshrass
|| exp
->op
== TOKushrass
);
2211 if (bitwise
&& exp
->type
->toBasetype()->ty
== Tbool
)
2212 exp
->e2
= exp
->e2
->implicitCastTo(sc
, exp
->type
);
2213 else if (exp
->checkNoBool())
2216 if ((exp
->op
== TOKaddass
|| exp
->op
== TOKminass
) &&
2217 exp
->e1
->type
->toBasetype()->ty
== Tpointer
&&
2218 exp
->e2
->type
->toBasetype()->isintegral())
2220 result
= scaleFactor(exp
, sc
);
2224 if (Expression
*ex
= typeCombine(exp
, sc
))
2230 if (arith
&& exp
->checkArithmeticBin())
2232 if ((bitwise
|| shift
) && exp
->checkIntegralBin())
2236 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
2237 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
2240 if (!Target::isVectorOpSupported(exp
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
2242 result
= exp
->incompatibleTypes();
2246 if (exp
->e1
->op
== TOKerror
|| exp
->e2
->op
== TOKerror
)
2249 e
= exp
->checkOpAssignTypes(sc
);
2250 if (e
->op
== TOKerror
)
2256 assert(e
->op
== TOKassign
|| e
== exp
);
2257 result
= ((BinExp
*)e
)->reorderSettingAAElem(sc
);
2260 void visit(CompileExp
*exp
)
2262 sc
= sc
->startCTFE();
2263 exp
->e1
= semantic(exp
->e1
, sc
);
2264 exp
->e1
= resolveProperties(sc
, exp
->e1
);
2266 if (exp
->e1
->op
== TOKerror
)
2271 if (!exp
->e1
->type
->isString())
2273 exp
->error("argument to mixin must be a string type, not %s", exp
->e1
->type
->toChars());
2276 exp
->e1
= exp
->e1
->ctfeInterpret();
2277 StringExp
*se
= exp
->e1
->toStringExp();
2280 exp
->error("argument to mixin must be a string, not (%s)", exp
->e1
->toChars());
2283 se
= se
->toUTF8(sc
);
2284 unsigned errors
= global
.errors
;
2285 Parser
p(exp
->loc
, sc
->_module
, (utf8_t
*)se
->string
, se
->len
, 0);
2287 //printf("p.loc.linnum = %d\n", p.loc.linnum);
2288 Expression
*e
= p
.parseExpression();
2291 assert(global
.errors
!= errors
); // should have caught all these cases
2294 if (p
.token
.value
!= TOKeof
)
2296 exp
->error("incomplete mixin expression (%s)", se
->toChars());
2299 result
= semantic(e
, sc
);
2302 void visit(ImportExp
*e
)
2307 sc
= sc
->startCTFE();
2308 e
->e1
= semantic(e
->e1
, sc
);
2309 e
->e1
= resolveProperties(sc
, e
->e1
);
2311 e
->e1
= e
->e1
->ctfeInterpret();
2312 if (e
->e1
->op
!= TOKstring
)
2314 e
->error("file name argument must be a string, not (%s)", e
->e1
->toChars());
2317 se
= (StringExp
*)e
->e1
;
2318 se
= se
->toUTF8(sc
);
2319 name
= (char *)se
->string
;
2321 if (!global
.params
.fileImppath
)
2323 e
->error("need -Jpath switch to import text file %s", name
);
2327 /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory
2328 * ('Path Traversal') attacks.
2329 * http://cwe.mitre.org/data/definitions/22.html
2332 name
= FileName::safeSearchPath(global
.filePath
, name
);
2335 e
->error("file %s cannot be found or not in a path specified with -J", se
->toChars());
2339 if (global
.params
.verbose
)
2340 message("file %.*s\t(%s)", (int)se
->len
, (char *)se
->string
, name
);
2341 if (global
.params
.moduleDeps
!= NULL
)
2343 OutBuffer
*ob
= global
.params
.moduleDeps
;
2344 Module
* imod
= sc
->instantiatingModule();
2346 if (!global
.params
.moduleDepsFile
)
2347 ob
->writestring("depsFile ");
2348 ob
->writestring(imod
->toPrettyChars());
2349 ob
->writestring(" (");
2350 escapePath(ob
, imod
->srcfile
->toChars());
2351 ob
->writestring(") : ");
2352 if (global
.params
.moduleDepsFile
)
2353 ob
->writestring("string : ");
2354 ob
->writestring((char *) se
->string
);
2355 ob
->writestring(" (");
2356 escapePath(ob
, name
);
2357 ob
->writestring(")");
2365 e
->error("cannot read file %s", f
.toChars());
2371 se
= new StringExp(e
->loc
, f
.buffer
, f
.len
);
2374 result
= semantic(se
, sc
);
2381 void visit(AssertExp
*exp
)
2383 if (Expression
*ex
= unaSemantic(exp
, sc
))
2388 exp
->e1
= resolveProperties(sc
, exp
->e1
);
2389 // BUG: see if we can do compile time elimination of the Assert
2390 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
2391 exp
->e1
= exp
->e1
->toBoolean(sc
);
2394 exp
->msg
= semantic(exp
->msg
, sc
);
2395 exp
->msg
= resolveProperties(sc
, exp
->msg
);
2396 exp
->msg
= exp
->msg
->implicitCastTo(sc
, Type::tchar
->constOf()->arrayOf());
2397 exp
->msg
= exp
->msg
->optimize(WANTvalue
);
2400 if (exp
->e1
->op
== TOKerror
)
2405 if (exp
->msg
&& exp
->msg
->op
== TOKerror
)
2411 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
2412 bool f2
= exp
->msg
&& checkNonAssignmentArrayOp(exp
->msg
);
2416 if (exp
->e1
->isBool(false))
2418 FuncDeclaration
*fd
= sc
->parent
->isFuncDeclaration();
2420 fd
->hasReturnExp
|= 4;
2421 sc
->callSuper
|= CSXhalt
;
2424 for (size_t i
= 0; i
< sc
->fieldinit_dim
; i
++)
2425 sc
->fieldinit
[i
] |= CSXhalt
;
2428 if (!global
.params
.useAssert
)
2430 Expression
*e
= new HaltExp(exp
->loc
);
2431 e
= semantic(e
, sc
);
2436 exp
->type
= Type::tvoid
;
2440 void visit(DotIdExp
*exp
)
2442 Expression
*e
= semanticY(exp
, sc
, 1);
2443 if (e
&& isDotOpDispatch(e
))
2445 unsigned errors
= global
.startGagging();
2446 e
= resolvePropertiesX(sc
, e
);
2447 if (global
.endGagging(errors
))
2448 e
= NULL
; /* fall down to UFCS */
2455 if (!e
) // if failed to find the property
2457 /* If ident is not a valid property, rewrite:
2462 e
= resolveUFCSProperties(sc
, exp
);
2467 void visit(DotTemplateExp
*e
)
2469 if (Expression
*ex
= unaSemantic(e
, sc
))
2477 void visit(DotVarExp
*exp
)
2485 exp
->var
= exp
->var
->toAlias()->isDeclaration();
2487 exp
->e1
= semantic(exp
->e1
, sc
);
2489 if (TupleDeclaration
*tup
= exp
->var
->isTupleDeclaration())
2494 * tuple(e1.a, e1.b, e1.c)
2496 Expression
*e0
= NULL
;
2497 Expression
*ev
= sc
->func
? extractSideEffect(sc
, "__tup", &e0
, exp
->e1
) : exp
->e1
;
2499 Expressions
*exps
= new Expressions
;
2500 exps
->reserve(tup
->objects
->dim
);
2501 for (size_t i
= 0; i
< tup
->objects
->dim
; i
++)
2503 RootObject
*o
= (*tup
->objects
)[i
];
2505 if (o
->dyncast() == DYNCAST_EXPRESSION
)
2507 e
= (Expression
*)o
;
2508 if (e
->op
== TOKdsymbol
)
2510 Dsymbol
*s
= ((DsymbolExp
*)e
)->s
;
2511 e
= new DotVarExp(exp
->loc
, ev
, s
->isDeclaration());
2514 else if (o
->dyncast() == DYNCAST_DSYMBOL
)
2516 e
= new DsymbolExp(exp
->loc
, (Dsymbol
*)o
);
2518 else if (o
->dyncast() == DYNCAST_TYPE
)
2520 e
= new TypeExp(exp
->loc
, (Type
*)o
);
2524 exp
->error("%s is not an expression", o
->toChars());
2530 Expression
*e
= new TupleExp(exp
->loc
, e0
, exps
);
2531 e
= semantic(e
, sc
);
2536 exp
->e1
= exp
->e1
->addDtorHook(sc
);
2538 Type
*t1
= exp
->e1
->type
;
2540 if (FuncDeclaration
*fd
= exp
->var
->isFuncDeclaration())
2542 // for functions, do checks after overload resolution
2543 if (!fd
->functionSemantic())
2546 /* Bugzilla 13843: If fd obviously has no overloads, we should
2547 * normalize AST, and it will give a chance to wrap fd with FuncExp.
2549 if (fd
->isNested() || fd
->isFuncLiteralDeclaration())
2552 Expression
*e
= resolve(exp
->loc
, sc
, fd
, false);
2553 result
= Expression::combine(exp
->e1
, e
);
2557 exp
->type
= fd
->type
;
2560 else if (exp
->var
->isOverDeclaration())
2562 exp
->type
= Type::tvoid
; // ambiguous type?
2566 exp
->type
= exp
->var
->type
;
2567 if (!exp
->type
&& global
.errors
)
2569 // var is goofed up, just return 0
2574 if (t1
->ty
== Tpointer
)
2577 exp
->type
= exp
->type
->addMod(t1
->mod
);
2579 Dsymbol
*vparent
= exp
->var
->toParent();
2580 AggregateDeclaration
*ad
= vparent
? vparent
->isAggregateDeclaration() : NULL
;
2582 if (Expression
*e1x
= getRightThis(exp
->loc
, sc
, ad
, exp
->e1
, exp
->var
, 1))
2586 /* Later checkRightThis will report correct error for invalid field variable access.
2588 Expression
*e
= new VarExp(exp
->loc
, exp
->var
);
2589 e
= semantic(e
, sc
);
2593 checkAccess(exp
->loc
, sc
, exp
->e1
, exp
->var
);
2595 VarDeclaration
*v
= exp
->var
->isVarDeclaration();
2596 if (v
&& (v
->isDataseg() || (v
->storage_class
& STCmanifest
)))
2598 Expression
*e
= expandVar(WANTvalue
, v
);
2606 if (v
&& v
->isDataseg()) // fix bugzilla 8238
2609 checkAccess(exp
->loc
, sc
, exp
->e1
, v
);
2610 Expression
*e
= new VarExp(exp
->loc
, v
);
2611 e
= new CommaExp(exp
->loc
, exp
->e1
, e
);
2612 e
= semantic(e
, sc
);
2618 //printf("-DotVarExp::semantic('%s')\n", exp->toChars());
2622 void visit(DotTemplateInstanceExp
*exp
)
2624 // Indicate we need to resolve by UFCS.
2625 Expression
*e
= semanticY(exp
, sc
, 1);
2627 e
= resolveUFCSProperties(sc
, exp
);
2631 void visit(DelegateExp
*e
)
2639 e
->e1
= semantic(e
->e1
, sc
);
2640 e
->type
= new TypeDelegate(e
->func
->type
);
2641 e
->type
= e
->type
->semantic(e
->loc
, sc
);
2642 FuncDeclaration
*f
= e
->func
->toAliasFunc();
2643 AggregateDeclaration
*ad
= f
->toParent()->isAggregateDeclaration();
2645 e
->e1
= getRightThis(e
->loc
, sc
, ad
, e
->e1
, f
);
2646 if (f
->type
->ty
== Tfunction
)
2648 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
2649 if (!MODmethodConv(e
->e1
->type
->mod
, f
->type
->mod
))
2651 OutBuffer thisBuf
, funcBuf
;
2652 MODMatchToBuffer(&thisBuf
, e
->e1
->type
->mod
, tf
->mod
);
2653 MODMatchToBuffer(&funcBuf
, tf
->mod
, e
->e1
->type
->mod
);
2654 e
->error("%smethod %s is not callable using a %s%s",
2655 funcBuf
.peekString(), f
->toPrettyChars(), thisBuf
.peekString(), e
->e1
->toChars());
2659 if (ad
&& ad
->isClassDeclaration() && ad
->type
!= e
->e1
->type
)
2661 // A downcast is required for interfaces, see Bugzilla 3706
2662 e
->e1
= new CastExp(e
->loc
, e
->e1
, ad
->type
);
2663 e
->e1
= semantic(e
->e1
, sc
);
2668 void visit(DotTypeExp
*exp
)
2676 if (Expression
*e
= unaSemantic(exp
, sc
))
2682 exp
->type
= exp
->sym
->getType()->addMod(exp
->e1
->type
->mod
);
2686 void visit(CallExp
*exp
)
2690 result
= exp
; // semantic() already run
2695 Objects
*tiargs
= NULL
; // initial list of template arguments
2696 Expression
*ethis
= NULL
;
2698 Expression
*e1org
= exp
->e1
;
2700 if (exp
->e1
->op
== TOKcomma
)
2702 /* Rewrite (a,b)(args) as (a,(b(args)))
2704 CommaExp
*ce
= (CommaExp
*)exp
->e1
;
2707 result
= semantic(ce
, sc
);
2711 if (exp
->e1
->op
== TOKdelegate
)
2713 DelegateExp
*de
= (DelegateExp
*)exp
->e1
;
2714 exp
->e1
= new DotVarExp(de
->loc
, de
->e1
, de
->func
, de
->hasOverloads
);
2715 result
= semantic(exp
, sc
);
2719 if (exp
->e1
->op
== TOKfunction
)
2721 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
2722 preFunctionParameters(sc
, exp
->arguments
))
2727 // Run e1 semantic even if arguments have any errors
2728 FuncExp
*fe
= (FuncExp
*)exp
->e1
;
2729 exp
->e1
= callExpSemantic(fe
, sc
, exp
->arguments
);
2730 if (exp
->e1
->op
== TOKerror
)
2737 if (Expression
*ex
= resolveUFCS(sc
, exp
))
2744 * foo!(tiargs)(funcargs)
2746 if (exp
->e1
->op
== TOKscope
)
2748 ScopeExp
*se
= (ScopeExp
*)exp
->e1
;
2749 TemplateInstance
*ti
= se
->sds
->isTemplateInstance();
2752 /* Attempt to instantiate ti. If that works, go with it.
2753 * If not, go with partial explicit specialization.
2755 WithScopeSymbol
*withsym
;
2756 if (!ti
->findTempDecl(sc
, &withsym
) ||
2757 !ti
->semanticTiargs(sc
))
2761 if (withsym
&& withsym
->withstate
->wthis
)
2763 exp
->e1
= new VarExp(exp
->e1
->loc
, withsym
->withstate
->wthis
);
2764 exp
->e1
= new DotTemplateInstanceExp(exp
->e1
->loc
, exp
->e1
, ti
);
2767 if (ti
->needsTypeInference(sc
, 1))
2769 /* Go with partial explicit specialization
2771 tiargs
= ti
->tiargs
;
2772 assert(ti
->tempdecl
);
2773 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
2774 exp
->e1
= new TemplateExp(exp
->loc
, td
);
2775 else if (OverDeclaration
*od
= ti
->tempdecl
->isOverDeclaration())
2776 exp
->e1
= new VarExp(exp
->loc
, od
);
2778 exp
->e1
= new OverExp(exp
->loc
, ti
->tempdecl
->isOverloadSet());
2782 Expression
*e1x
= semantic(exp
->e1
, sc
);
2783 if (e1x
->op
== TOKerror
)
2794 * expr.foo!(tiargs)(funcargs)
2797 if (exp
->e1
->op
== TOKdotti
&& !exp
->e1
->type
)
2799 DotTemplateInstanceExp
*se
= (DotTemplateInstanceExp
*)exp
->e1
;
2800 TemplateInstance
*ti
= se
->ti
;
2802 /* Attempt to instantiate ti. If that works, go with it.
2803 * If not, go with partial explicit specialization.
2805 if (!se
->findTempDecl(sc
) ||
2806 !ti
->semanticTiargs(sc
))
2810 if (ti
->needsTypeInference(sc
, 1))
2812 /* Go with partial explicit specialization
2814 tiargs
= ti
->tiargs
;
2815 assert(ti
->tempdecl
);
2816 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
2817 exp
->e1
= new DotTemplateExp(exp
->loc
, se
->e1
, td
);
2818 else if (OverDeclaration
*od
= ti
->tempdecl
->isOverDeclaration())
2820 exp
->e1
= new DotVarExp(exp
->loc
, se
->e1
, od
, true);
2823 exp
->e1
= new DotExp(exp
->loc
, se
->e1
, new OverExp(exp
->loc
, ti
->tempdecl
->isOverloadSet()));
2827 Expression
*e1x
= semantic(exp
->e1
, sc
);
2828 if (e1x
->op
== TOKerror
)
2839 //printf("Lagain: %s\n", exp->toChars());
2841 if (exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
)
2843 // semantic() run later for these
2847 if (exp
->e1
->op
== TOKdotid
)
2849 DotIdExp
*die
= (DotIdExp
*)exp
->e1
;
2850 exp
->e1
= semantic(die
, sc
);
2851 /* Look for e1 having been rewritten to expr.opDispatch!(string)
2852 * We handle such earlier, so go back.
2853 * Note that in the rewrite, we carefully did not run semantic() on e1
2855 if (exp
->e1
->op
== TOKdotti
&& !exp
->e1
->type
)
2865 exp
->error("recursive evaluation of %s", exp
->toChars());
2869 Expression
*ex
= unaSemantic(exp
, sc
);
2878 /* Look for e1 being a lazy parameter
2880 if (exp
->e1
->op
== TOKvar
)
2882 VarExp
*ve
= (VarExp
*)exp
->e1
;
2883 if (ve
->var
->storage_class
& STClazy
)
2885 // lazy paramaters can be called without violating purity and safety
2886 Type
*tw
= ve
->var
->type
;
2887 Type
*tc
= ve
->var
->type
->substWildTo(MODconst
);
2888 TypeFunction
*tf
= new TypeFunction(NULL
, tc
, 0, LINKd
, STCsafe
| STCpure
);
2889 (tf
= (TypeFunction
*)tf
->semantic(exp
->loc
, sc
))->next
= tw
; // hack for bug7757
2890 TypeDelegate
*t
= new TypeDelegate(tf
);
2891 ve
->type
= t
->semantic(exp
->loc
, sc
);
2893 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
2894 if (v
&& ve
->checkPurity(sc
, v
))
2898 if (exp
->e1
->op
== TOKsymoff
&& ((SymOffExp
*)exp
->e1
)->hasOverloads
)
2900 SymOffExp
*se
= (SymOffExp
*)exp
->e1
;
2901 exp
->e1
= new VarExp(se
->loc
, se
->var
, true);
2902 exp
->e1
= semantic(exp
->e1
, sc
);
2904 else if (exp
->e1
->op
== TOKdot
)
2906 DotExp
*de
= (DotExp
*) exp
->e1
;
2908 if (de
->e2
->op
== TOKoverloadset
)
2911 tthis
= de
->e1
->type
;
2915 else if (exp
->e1
->op
== TOKstar
&& exp
->e1
->type
->ty
== Tfunction
)
2917 // Rewrite (*fp)(arguments) to fp(arguments)
2918 exp
->e1
= ((PtrExp
*)exp
->e1
)->e1
;
2922 t1
= exp
->e1
->type
? exp
->e1
->type
->toBasetype() : NULL
;
2924 if (exp
->e1
->op
== TOKerror
)
2929 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
2930 preFunctionParameters(sc
, exp
->arguments
))
2935 // Check for call operator overload
2938 if (t1
->ty
== Tstruct
)
2940 StructDeclaration
*sd
= ((TypeStruct
*)t1
)->sym
;
2941 sd
->size(exp
->loc
); // Resolve forward references to construct object
2942 if (sd
->sizeok
!= SIZEOKdone
)
2945 sd
->ctor
= sd
->searchCtor();
2947 // First look for constructor
2948 if (exp
->e1
->op
== TOKtype
&& sd
->ctor
)
2950 if (!sd
->noDefaultCtor
&& !(exp
->arguments
&& exp
->arguments
->dim
))
2953 StructLiteralExp
*sle
= new StructLiteralExp(exp
->loc
, sd
, NULL
, exp
->e1
->type
);
2954 if (!sd
->fill(exp
->loc
, sle
->elements
, true))
2956 if (checkFrameAccess(exp
->loc
, sc
, sd
, sle
->elements
->dim
))
2958 // Bugzilla 14556: Set concrete type to avoid further redundant semantic().
2959 sle
->type
= exp
->e1
->type
;
2961 /* Constructor takes a mutable object, so don't use
2962 * the immutable initializer symbol.
2964 sle
->useStaticInit
= false;
2966 Expression
*e
= sle
;
2967 if (CtorDeclaration
*cf
= sd
->ctor
->isCtorDeclaration())
2969 e
= new DotVarExp(exp
->loc
, e
, cf
, true);
2971 else if (TemplateDeclaration
*td
= sd
->ctor
->isTemplateDeclaration())
2973 e
= new DotTemplateExp(exp
->loc
, e
, td
);
2975 else if (OverloadSet
*os
= sd
->ctor
->isOverloadSet())
2977 e
= new DotExp(exp
->loc
, e
, new OverExp(exp
->loc
, os
));
2981 e
= new CallExp(exp
->loc
, e
, exp
->arguments
);
2982 result
= semantic(e
, sc
);
2985 // No constructor, look for overload of opCall
2986 if (search_function(sd
, Id::call
))
2987 goto L1
; // overload of opCall, therefore it's a call
2989 if (exp
->e1
->op
!= TOKtype
)
2991 if (sd
->aliasthis
&& exp
->e1
->type
!= exp
->att1
)
2993 if (!exp
->att1
&& exp
->e1
->type
->checkAliasThisRec())
2994 exp
->att1
= exp
->e1
->type
;
2995 exp
->e1
= resolveAliasThis(sc
, exp
->e1
);
2998 exp
->error("%s %s does not overload ()", sd
->kind(), sd
->toChars());
3002 /* It's a struct literal
3005 Expression
*e
= new StructLiteralExp(exp
->loc
, sd
, exp
->arguments
, exp
->e1
->type
);
3006 result
= semantic(e
, sc
);
3009 else if (t1
->ty
== Tclass
)
3012 // Rewrite as e1.call(arguments)
3013 Expression
*e
= new DotIdExp(exp
->loc
, exp
->e1
, Id::call
);
3014 e
= new CallExp(exp
->loc
, e
, exp
->arguments
);
3015 result
= semantic(e
, sc
);
3018 else if (exp
->e1
->op
== TOKtype
&& t1
->isscalar())
3022 // Make sure to use the the enum type itself rather than its
3023 // base type (see bugzilla 16346)
3024 if (exp
->e1
->type
->ty
== Tenum
)
3029 if (!exp
->arguments
|| exp
->arguments
->dim
== 0)
3031 e
= t1
->defaultInitLiteral(exp
->loc
);
3033 else if (exp
->arguments
->dim
== 1)
3035 e
= (*exp
->arguments
)[0];
3036 e
= e
->implicitCastTo(sc
, t1
);
3037 e
= new CastExp(exp
->loc
, e
, t1
);
3041 exp
->error("more than one argument for construction of %s", t1
->toChars());
3044 result
= semantic(e
, sc
);
3049 if ((exp
->e1
->op
== TOKdotvar
&& t1
->ty
== Tfunction
) ||
3050 exp
->e1
->op
== TOKdottd
)
3052 UnaExp
*ue
= (UnaExp
*)(exp
->e1
);
3054 Expression
*ue1
= ue
->e1
;
3055 Expression
*ue1old
= ue1
; // need for 'right this' check
3057 if (ue1
->op
== TOKvar
&&
3058 (v
= ((VarExp
*)ue1
)->var
->isVarDeclaration()) != NULL
&&
3061 ue
->e1
= new TypeExp(ue1
->loc
, ue1
->type
);
3066 DotTemplateExp
*dte
;
3068 if (exp
->e1
->op
== TOKdotvar
)
3070 dve
= (DotVarExp
*)(exp
->e1
);
3078 dte
= (DotTemplateExp
*)(exp
->e1
);
3082 // Do overload resolution
3083 exp
->f
= resolveFuncCall(exp
->loc
, sc
, s
, tiargs
, ue1
? ue1
->type
: NULL
, exp
->arguments
);
3084 if (!exp
->f
|| exp
->f
->errors
|| exp
->f
->type
->ty
== Terror
)
3086 if (exp
->f
->interfaceVirtual
)
3088 /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent
3090 BaseClass
*b
= exp
->f
->interfaceVirtual
;
3091 ClassDeclaration
*ad2
= b
->sym
;
3092 ue
->e1
= ue
->e1
->castTo(sc
, ad2
->type
->addMod(ue
->e1
->type
->mod
));
3093 ue
->e1
= semantic(ue
->e1
, sc
);
3095 int vi
= exp
->f
->findVtblIndex((Dsymbols
*)&ad2
->vtbl
, (int)ad2
->vtbl
.dim
);
3097 exp
->f
= ad2
->vtbl
[vi
]->isFuncDeclaration();
3100 if (exp
->f
->needThis())
3102 AggregateDeclaration
*ad
= exp
->f
->toParent2()->isAggregateDeclaration();
3103 ue
->e1
= getRightThis(exp
->loc
, sc
, ad
, ue
->e1
, exp
->f
);
3104 if (ue
->e1
->op
== TOKerror
)
3110 tthis
= ue
->e1
->type
;
3111 if (!(exp
->f
->type
->ty
== Tfunction
&& ((TypeFunction
*)exp
->f
->type
)->isscope
))
3113 if (global
.params
.vsafe
&& checkParamArgumentEscape(sc
, exp
->f
, Id::This
, ethis
, false))
3118 /* Cannot call public functions from inside invariant
3119 * (because then the invariant would have infinite recursion)
3121 if (sc
->func
&& sc
->func
->isInvariantDeclaration() &&
3122 ue
->e1
->op
== TOKthis
&&
3123 exp
->f
->addPostInvariant()
3126 exp
->error("cannot call public/export function %s from invariant", exp
->f
->toChars());
3130 exp
->checkDeprecated(sc
, exp
->f
);
3131 exp
->checkPurity(sc
, exp
->f
);
3132 exp
->checkSafety(sc
, exp
->f
);
3133 exp
->checkNogc(sc
, exp
->f
);
3134 checkAccess(exp
->loc
, sc
, ue
->e1
, exp
->f
);
3135 if (!exp
->f
->needThis())
3137 exp
->e1
= Expression::combine(ue
->e1
, new VarExp(exp
->loc
, exp
->f
, false));
3141 if (ue1old
->checkRightThis(sc
))
3143 if (exp
->e1
->op
== TOKdotvar
)
3146 exp
->e1
->type
= exp
->f
->type
;
3150 exp
->e1
= new DotVarExp(exp
->loc
, dte
->e1
, exp
->f
, false);
3151 exp
->e1
= semantic(exp
->e1
, sc
);
3152 if (exp
->e1
->op
== TOKerror
)
3154 ue
= (UnaExp
*)exp
->e1
;
3157 // See if we need to adjust the 'this' pointer
3158 AggregateDeclaration
*ad
= exp
->f
->isThis();
3159 ClassDeclaration
*cd
= ue
->e1
->type
->isClassHandle();
3160 if (ad
&& cd
&& ad
->isClassDeclaration())
3162 if (ue
->e1
->op
== TOKdottype
)
3164 ue
->e1
= ((DotTypeExp
*)ue
->e1
)->e1
;
3165 exp
->directcall
= true;
3167 else if (ue
->e1
->op
== TOKsuper
)
3168 exp
->directcall
= true;
3169 else if ((cd
->storage_class
& STCfinal
) != 0) // Bugzilla 14211
3170 exp
->directcall
= true;
3174 ue
->e1
= ue
->e1
->castTo(sc
, ad
->type
->addMod(ue
->e1
->type
->mod
));
3175 ue
->e1
= semantic(ue
->e1
, sc
);
3179 // If we've got a pointer to a function then deference it
3180 // https://issues.dlang.org/show_bug.cgi?id=16483
3181 if (exp
->e1
->type
->ty
== Tpointer
&& exp
->e1
->type
->nextOf()->ty
== Tfunction
)
3183 Expression
*e
= new PtrExp(exp
->loc
, exp
->e1
);
3184 e
->type
= exp
->e1
->type
->nextOf();
3189 else if (exp
->e1
->op
== TOKsuper
)
3191 // Base class constructor call
3192 AggregateDeclaration
*ad
= sc
->func
? sc
->func
->isThis() : NULL
;
3193 ClassDeclaration
*cd
= ad
? ad
->isClassDeclaration() : NULL
;
3194 if (!cd
|| !cd
->baseClass
|| !sc
->func
->isCtorDeclaration())
3196 exp
->error("super class constructor call must be in a constructor");
3199 if (!cd
->baseClass
->ctor
)
3201 exp
->error("no super class constructor for %s", cd
->baseClass
->toChars());
3205 if (!sc
->intypeof
&& !(sc
->callSuper
& CSXhalt
))
3207 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
3208 exp
->error("constructor calls not allowed in loops or after labels");
3209 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
3210 exp
->error("multiple constructor calls");
3211 if ((sc
->callSuper
& CSXreturn
) && !(sc
->callSuper
& CSXany_ctor
))
3212 exp
->error("an earlier return statement skips constructor");
3213 sc
->callSuper
|= CSXany_ctor
| CSXsuper_ctor
;
3216 tthis
= cd
->type
->addMod(sc
->func
->type
->mod
);
3217 if (OverloadSet
*os
= cd
->baseClass
->ctor
->isOverloadSet())
3218 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, NULL
, tthis
, exp
->arguments
);
3220 exp
->f
= resolveFuncCall(exp
->loc
, sc
, cd
->baseClass
->ctor
, NULL
, tthis
, exp
->arguments
, 0);
3221 if (!exp
->f
|| exp
->f
->errors
)
3223 exp
->checkDeprecated(sc
, exp
->f
);
3224 exp
->checkPurity(sc
, exp
->f
);
3225 exp
->checkSafety(sc
, exp
->f
);
3226 exp
->checkNogc(sc
, exp
->f
);
3227 checkAccess(exp
->loc
, sc
, NULL
, exp
->f
);
3229 exp
->e1
= new DotVarExp(exp
->e1
->loc
, exp
->e1
, exp
->f
, false);
3230 exp
->e1
= semantic(exp
->e1
, sc
);
3233 else if (exp
->e1
->op
== TOKthis
)
3235 // same class constructor call
3236 AggregateDeclaration
*ad
= sc
->func
? sc
->func
->isThis() : NULL
;
3237 if (!ad
|| !sc
->func
->isCtorDeclaration())
3239 exp
->error("constructor call must be in a constructor");
3243 if (!sc
->intypeof
&& !(sc
->callSuper
& CSXhalt
))
3245 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
3246 exp
->error("constructor calls not allowed in loops or after labels");
3247 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
3248 exp
->error("multiple constructor calls");
3249 if ((sc
->callSuper
& CSXreturn
) && !(sc
->callSuper
& CSXany_ctor
))
3250 exp
->error("an earlier return statement skips constructor");
3251 sc
->callSuper
|= CSXany_ctor
| CSXthis_ctor
;
3254 tthis
= ad
->type
->addMod(sc
->func
->type
->mod
);
3255 if (OverloadSet
*os
= ad
->ctor
->isOverloadSet())
3256 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, NULL
, tthis
, exp
->arguments
);
3258 exp
->f
= resolveFuncCall(exp
->loc
, sc
, ad
->ctor
, NULL
, tthis
, exp
->arguments
, 0);
3259 if (!exp
->f
|| exp
->f
->errors
)
3261 exp
->checkDeprecated(sc
, exp
->f
);
3262 exp
->checkPurity(sc
, exp
->f
);
3263 exp
->checkSafety(sc
, exp
->f
);
3264 exp
->checkNogc(sc
, exp
->f
);
3265 //checkAccess(exp->loc, sc, NULL, exp->f); // necessary?
3267 exp
->e1
= new DotVarExp(exp
->e1
->loc
, exp
->e1
, exp
->f
, false);
3268 exp
->e1
= semantic(exp
->e1
, sc
);
3271 // BUG: this should really be done by checking the static
3273 if (exp
->f
== sc
->func
)
3275 exp
->error("cyclic constructor call");
3279 else if (exp
->e1
->op
== TOKoverloadset
)
3281 OverloadSet
*os
= ((OverExp
*)exp
->e1
)->vars
;
3282 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, tiargs
, tthis
, exp
->arguments
);
3286 exp
->e1
= new DotVarExp(exp
->loc
, ethis
, exp
->f
, false);
3288 exp
->e1
= new VarExp(exp
->loc
, exp
->f
, false);
3293 exp
->error("function expected before (), not '%s'", exp
->e1
->toChars());
3296 else if (t1
->ty
== Terror
)
3300 else if (t1
->ty
!= Tfunction
)
3306 if (exp
->e1
->op
== TOKfunction
)
3308 // function literal that direct called is always inferred.
3309 assert(((FuncExp
*)exp
->e1
)->fd
);
3310 exp
->f
= ((FuncExp
*)exp
->e1
)->fd
;
3311 tf
= (TypeFunction
*)exp
->f
->type
;
3312 p
= "function literal";
3314 else if (t1
->ty
== Tdelegate
)
3316 TypeDelegate
*td
= (TypeDelegate
*)t1
;
3317 assert(td
->next
->ty
== Tfunction
);
3318 tf
= (TypeFunction
*)(td
->next
);
3321 else if (t1
->ty
== Tpointer
&& ((TypePointer
*)t1
)->next
->ty
== Tfunction
)
3323 tf
= (TypeFunction
*)(((TypePointer
*)t1
)->next
);
3324 p
= "function pointer";
3326 else if (exp
->e1
->op
== TOKdotvar
&&
3327 ((DotVarExp
*)exp
->e1
)->var
->isOverDeclaration())
3329 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
3330 exp
->f
= resolveFuncCall(exp
->loc
, sc
, dve
->var
, tiargs
, dve
->e1
->type
, exp
->arguments
, 2);
3333 if (exp
->f
->needThis())
3336 dve
->type
= exp
->f
->type
;
3337 dve
->hasOverloads
= false;
3340 exp
->e1
= new VarExp(dve
->loc
, exp
->f
, false);
3341 Expression
*e
= new CommaExp(exp
->loc
, dve
->e1
, exp
);
3342 result
= semantic(e
, sc
);
3345 else if (exp
->e1
->op
== TOKvar
&&
3346 ((VarExp
*)exp
->e1
)->var
->isOverDeclaration())
3348 s
= ((VarExp
*)exp
->e1
)->var
;
3351 else if (exp
->e1
->op
== TOKtemplate
)
3353 s
= ((TemplateExp
*)exp
->e1
)->td
;
3355 exp
->f
= resolveFuncCall(exp
->loc
, sc
, s
, tiargs
, NULL
, exp
->arguments
);
3356 if (!exp
->f
|| exp
->f
->errors
)
3358 if (exp
->f
->needThis())
3362 // Supply an implicit 'this', as in
3364 Expression
*ex
= new ThisExp(exp
->loc
);
3365 ex
= semantic(ex
, sc
);
3366 exp
->e1
= new DotVarExp(exp
->loc
, ex
, exp
->f
, false);
3369 else if (isNeedThisScope(sc
, exp
->f
))
3371 exp
->error("need 'this' for '%s' of type '%s'", exp
->f
->toChars(), exp
->f
->type
->toChars());
3375 exp
->e1
= new VarExp(exp
->e1
->loc
, exp
->f
, false);
3380 exp
->error("function expected before (), not %s of type %s", exp
->e1
->toChars(), exp
->e1
->type
->toChars());
3384 if (!tf
->callMatch(NULL
, exp
->arguments
))
3389 argExpTypesToCBuffer(&buf
, exp
->arguments
);
3392 tthis
->modToBuffer(&buf
);
3394 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3395 ::error(exp
->loc
, "%s %s %s is not callable using argument types %s",
3396 p
, exp
->e1
->toChars(), parametersTypeToChars(tf
->parameters
, tf
->varargs
),
3402 // Purity and safety check should run after testing arguments matching
3405 exp
->checkPurity(sc
, exp
->f
);
3406 exp
->checkSafety(sc
, exp
->f
);
3407 exp
->checkNogc(sc
, exp
->f
);
3408 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3411 else if (sc
->func
&& sc
->intypeof
!= 1 && !(sc
->flags
& SCOPEctfe
))
3414 if (!tf
->purity
&& !(sc
->flags
& SCOPEdebug
) && sc
->func
->setImpure())
3416 exp
->error("pure %s '%s' cannot call impure %s '%s'",
3417 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3420 if (!tf
->isnogc
&& sc
->func
->setGC())
3422 exp
->error("@nogc %s '%s' cannot call non-@nogc %s '%s'",
3423 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3426 if (tf
->trust
<= TRUSTsystem
&& sc
->func
->setUnsafe())
3428 exp
->error("@safe %s '%s' cannot call @system %s '%s'",
3429 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3436 if (t1
->ty
== Tpointer
)
3438 Expression
*e
= new PtrExp(exp
->loc
, exp
->e1
);
3444 else if (exp
->e1
->op
== TOKvar
)
3446 // Do overload resolution
3447 VarExp
*ve
= (VarExp
*)exp
->e1
;
3449 exp
->f
= ve
->var
->isFuncDeclaration();
3453 if (ve
->hasOverloads
)
3454 exp
->f
= resolveFuncCall(exp
->loc
, sc
, exp
->f
, tiargs
, NULL
, exp
->arguments
, 2);
3457 exp
->f
= exp
->f
->toAliasFunc();
3458 TypeFunction
*tf
= (TypeFunction
*)exp
->f
->type
;
3459 if (!tf
->callMatch(NULL
, exp
->arguments
))
3464 argExpTypesToCBuffer(&buf
, exp
->arguments
);
3467 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3468 ::error(exp
->loc
, "%s %s is not callable using argument types %s",
3469 exp
->e1
->toChars(), parametersTypeToChars(tf
->parameters
, tf
->varargs
),
3475 if (!exp
->f
|| exp
->f
->errors
)
3478 if (exp
->f
->needThis())
3480 // Change the ancestor lambdas to delegate before hasThis(sc) call.
3481 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3486 // Supply an implicit 'this', as in
3489 Expression
*ex
= new ThisExp(exp
->loc
);
3490 ex
= semantic(ex
, sc
);
3491 exp
->e1
= new DotVarExp(exp
->loc
, ex
, ve
->var
);
3492 // Note: we cannot use f directly, because further overload resolution
3493 // through the supplied 'this' may cause different result.
3496 else if (isNeedThisScope(sc
, exp
->f
))
3498 exp
->error("need 'this' for '%s' of type '%s'", exp
->f
->toChars(), exp
->f
->type
->toChars());
3503 exp
->checkDeprecated(sc
, exp
->f
);
3504 exp
->checkPurity(sc
, exp
->f
);
3505 exp
->checkSafety(sc
, exp
->f
);
3506 exp
->checkNogc(sc
, exp
->f
);
3507 checkAccess(exp
->loc
, sc
, NULL
, exp
->f
);
3508 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3514 if (ve
->hasOverloads
)
3516 exp
->e1
= new VarExp(ve
->loc
, exp
->f
, false);
3517 exp
->e1
->type
= exp
->f
->type
;
3521 assert(t1
->ty
== Tfunction
);
3523 Expression
*argprefix
;
3524 if (!exp
->arguments
)
3525 exp
->arguments
= new Expressions();
3526 if (functionParameters(exp
->loc
, sc
, (TypeFunction
*)(t1
), tthis
, exp
->arguments
, exp
->f
, &exp
->type
, &argprefix
))
3531 exp
->e1
= e1org
; // Bugzilla 10922, avoid recursive expression printing
3532 exp
->error("forward reference to inferred return type of function call '%s'", exp
->toChars());
3536 if (exp
->f
&& exp
->f
->tintro
)
3538 Type
*t
= exp
->type
;
3540 TypeFunction
*tf
= (TypeFunction
*)exp
->f
->tintro
;
3542 if (tf
->next
->isBaseOf(t
, &offset
) && offset
)
3544 exp
->type
= tf
->next
;
3545 result
= Expression::combine(argprefix
, exp
->castTo(sc
, t
));
3550 // Handle the case of a direct lambda call
3551 if (exp
->f
&& exp
->f
->isFuncLiteralDeclaration() &&
3552 sc
->func
&& !sc
->intypeof
)
3554 exp
->f
->tookAddressOf
= 0;
3557 result
= Expression::combine(argprefix
, exp
);
3560 void visit(AddrExp
*exp
)
3568 if (Expression
*ex
= unaSemantic(exp
, sc
))
3573 int wasCond
= exp
->e1
->op
== TOKquestion
;
3574 if (exp
->e1
->op
== TOKdotti
)
3576 DotTemplateInstanceExp
* dti
= (DotTemplateInstanceExp
*)exp
->e1
;
3577 TemplateInstance
*ti
= dti
->ti
;
3579 //assert(ti->needsTypeInference(sc));
3581 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
3583 Dsymbol
*s
= ti
->toAlias();
3584 FuncDeclaration
*f
= s
->isFuncDeclaration();
3587 exp
->e1
= new DotVarExp(exp
->e1
->loc
, dti
->e1
, f
);
3588 exp
->e1
= semantic(exp
->e1
, sc
);
3592 else if (exp
->e1
->op
== TOKscope
)
3594 TemplateInstance
*ti
= ((ScopeExp
*)exp
->e1
)->sds
->isTemplateInstance();
3597 //assert(ti->needsTypeInference(sc));
3599 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
3601 Dsymbol
*s
= ti
->toAlias();
3602 FuncDeclaration
*f
= s
->isFuncDeclaration();
3605 exp
->e1
= new VarExp(exp
->e1
->loc
, f
);
3606 exp
->e1
= semantic(exp
->e1
, sc
);
3610 exp
->e1
= exp
->e1
->toLvalue(sc
, NULL
);
3611 if (exp
->e1
->op
== TOKerror
)
3616 if (checkNonAssignmentArrayOp(exp
->e1
))
3621 exp
->error("cannot take address of %s", exp
->e1
->toChars());
3625 bool hasOverloads
= false;
3626 if (FuncDeclaration
*f
= isFuncAddress(exp
, &hasOverloads
))
3628 if (!hasOverloads
&& f
->checkForwardRef(exp
->loc
))
3631 else if (!exp
->e1
->type
->deco
)
3633 if (exp
->e1
->op
== TOKvar
)
3635 VarExp
*ve
= (VarExp
*)exp
->e1
;
3636 Declaration
*d
= ve
->var
;
3637 exp
->error("forward reference to %s %s", d
->kind(), d
->toChars());
3640 exp
->error("forward reference to %s", exp
->e1
->toChars());
3644 exp
->type
= exp
->e1
->type
->pointerTo();
3646 // See if this should really be a delegate
3647 if (exp
->e1
->op
== TOKdotvar
)
3649 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
3650 FuncDeclaration
*f
= dve
->var
->isFuncDeclaration();
3653 f
= f
->toAliasFunc(); // FIXME, should see overloads - Bugzilla 1983
3654 if (!dve
->hasOverloads
)
3659 e
= new DelegateExp(exp
->loc
, dve
->e1
, f
, dve
->hasOverloads
);
3660 else // It is a function pointer. Convert &v.f() --> (v, &V.f())
3661 e
= new CommaExp(exp
->loc
, dve
->e1
, new AddrExp(exp
->loc
, new VarExp(exp
->loc
, f
, dve
->hasOverloads
)));
3662 e
= semantic(e
, sc
);
3667 // Look for misaligned pointer in @safe mode
3668 if (checkUnsafeAccess(sc
, dve
, !exp
->type
->isMutable(), true))
3671 if (dve
->e1
->op
== TOKvar
&& global
.params
.vsafe
)
3673 VarExp
*ve
= (VarExp
*)dve
->e1
;
3674 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3677 if (!checkAddressVar(sc
, exp
, v
))
3681 else if ((dve
->e1
->op
== TOKthis
|| dve
->e1
->op
== TOKsuper
) && global
.params
.vsafe
)
3683 ThisExp
*ve
= (ThisExp
*)dve
->e1
;
3684 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3685 if (v
&& v
->storage_class
& STCref
)
3687 if (!checkAddressVar(sc
, exp
, v
))
3692 else if (exp
->e1
->op
== TOKvar
)
3694 VarExp
*ve
= (VarExp
*)exp
->e1
;
3696 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3699 if (!checkAddressVar(sc
, exp
, v
))
3702 ve
->checkPurity(sc
, v
);
3705 FuncDeclaration
*f
= ve
->var
->isFuncDeclaration();
3708 /* Because nested functions cannot be overloaded,
3709 * mark here that we took its address because castTo()
3710 * may not be called with an exact match.
3712 if (!ve
->hasOverloads
|| f
->isNested())
3716 if (f
->isFuncLiteralDeclaration())
3718 if (!f
->FuncDeclaration::isNested())
3720 /* Supply a 'null' for a this pointer if no this is available
3722 Expression
*e
= new DelegateExp(exp
->loc
, new NullExp(exp
->loc
, Type::tnull
), f
, ve
->hasOverloads
);
3723 e
= semantic(e
, sc
);
3728 Expression
*e
= new DelegateExp(exp
->loc
, exp
->e1
, f
, ve
->hasOverloads
);
3729 e
= semantic(e
, sc
);
3737 /* Should probably supply 'this' after overload resolution,
3740 Expression
*ethis
= new ThisExp(exp
->loc
);
3741 Expression
*e
= new DelegateExp(exp
->loc
, ethis
, f
, ve
->hasOverloads
);
3742 e
= semantic(e
, sc
);
3746 if (sc
->func
&& !sc
->intypeof
)
3748 if (sc
->func
->setUnsafe())
3750 exp
->error("'this' reference necessary to take address of member %s in @safe function %s",
3751 f
->toChars(), sc
->func
->toChars());
3757 else if ((exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
) && global
.params
.vsafe
)
3759 ThisExp
*ve
= (ThisExp
*)exp
->e1
;
3760 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3763 if (!checkAddressVar(sc
, exp
, v
))
3767 else if (exp
->e1
->op
== TOKcall
)
3769 CallExp
*ce
= (CallExp
*)exp
->e1
;
3770 if (ce
->e1
->type
->ty
== Tfunction
)
3772 TypeFunction
*tf
= (TypeFunction
*)ce
->e1
->type
;
3773 if (tf
->isref
&& sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
3775 exp
->error("cannot take address of ref return of %s() in @safe function %s",
3776 ce
->e1
->toChars(), sc
->func
->toChars());
3780 else if (exp
->e1
->op
== TOKindex
)
3785 * check 'a' the same as for a regular variable
3787 IndexExp
*ei
= (IndexExp
*)exp
->e1
;
3788 Type
*tyi
= ei
->e1
->type
->toBasetype();
3789 if (tyi
->ty
== Tsarray
&& ei
->e1
->op
== TOKvar
)
3791 VarExp
*ve
= (VarExp
*)ei
->e1
;
3792 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3795 if (!checkAddressVar(sc
, exp
, v
))
3798 ve
->checkPurity(sc
, v
);
3804 /* a ? b : c was transformed to *(a ? &b : &c), but we still
3805 * need to do safety checks
3807 assert(exp
->e1
->op
== TOKstar
);
3808 PtrExp
*pe
= (PtrExp
*)exp
->e1
;
3809 assert(pe
->e1
->op
== TOKquestion
);
3810 CondExp
*ce
= (CondExp
*)pe
->e1
;
3811 assert(ce
->e1
->op
== TOKaddress
);
3812 assert(ce
->e2
->op
== TOKaddress
);
3814 // Re-run semantic on the address expressions only
3815 ce
->e1
->type
= NULL
;
3816 ce
->e1
= semantic(ce
->e1
, sc
);
3817 ce
->e2
->type
= NULL
;
3818 ce
->e2
= semantic(ce
->e2
, sc
);
3821 result
= exp
->optimize(WANTvalue
);
3824 void visit(PtrExp
*exp
)
3832 Expression
*e
= exp
->op_overload(sc
);
3839 Type
*tb
= exp
->e1
->type
->toBasetype();
3843 exp
->type
= ((TypePointer
*)tb
)->next
;
3848 exp
->error("using * on an array is no longer supported; use *(%s).ptr instead", exp
->e1
->toChars());
3849 exp
->type
= ((TypeArray
*)tb
)->next
;
3850 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
->pointerTo());
3854 exp
->error("can only * a pointer, not a '%s'", exp
->e1
->type
->toChars());
3860 if (exp
->checkValue())
3866 void visit(NegExp
*exp
)
3874 Expression
*e
= exp
->op_overload(sc
);
3881 exp
->type
= exp
->e1
->type
;
3882 Type
*tb
= exp
->type
->toBasetype();
3883 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
3885 if (!isArrayOpValid(exp
->e1
))
3887 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
3894 if (!Target::isVectorOpSupported(tb
, exp
->op
))
3896 result
= exp
->incompatibleTypes();
3899 if (exp
->e1
->checkNoBool())
3901 if (exp
->e1
->checkArithmetic())
3907 void visit(UAddExp
*exp
)
3911 Expression
*e
= exp
->op_overload(sc
);
3918 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
))
3920 result
= exp
->incompatibleTypes();
3923 if (exp
->e1
->checkNoBool())
3925 if (exp
->e1
->checkArithmetic())
3931 void visit(ComExp
*exp
)
3939 Expression
*e
= exp
->op_overload(sc
);
3946 exp
->type
= exp
->e1
->type
;
3947 Type
*tb
= exp
->type
->toBasetype();
3948 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
3950 if (!isArrayOpValid(exp
->e1
))
3952 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
3959 if (!Target::isVectorOpSupported(tb
, exp
->op
))
3961 result
= exp
->incompatibleTypes();
3964 if (exp
->e1
->checkNoBool())
3966 if (exp
->e1
->checkIntegral())
3972 void visit(NotExp
*e
)
3980 setNoderefOperand(e
);
3982 // Note there is no operator overload
3983 if (Expression
*ex
= unaSemantic(e
, sc
))
3989 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
3990 if (e
->e1
->op
== TOKtype
)
3991 e
->e1
= resolveAliasThis(sc
, e
->e1
);
3993 e
->e1
= resolveProperties(sc
, e
->e1
);
3994 e
->e1
= e
->e1
->toBoolean(sc
);
3995 if (e
->e1
->type
== Type::terror
)
4001 if (!Target::isVectorOpSupported(e
->e1
->type
->toBasetype(), e
->op
))
4003 result
= e
->incompatibleTypes();
4006 // Bugzilla 13910: Today NotExp can take an array as its operand.
4007 if (checkNonAssignmentArrayOp(e
->e1
))
4010 e
->type
= Type::tbool
;
4014 void visit(DeleteExp
*exp
)
4016 if (Expression
*ex
= unaSemantic(exp
, sc
))
4021 exp
->e1
= resolveProperties(sc
, exp
->e1
);
4022 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, NULL
);
4023 if (exp
->e1
->op
== TOKerror
)
4028 exp
->type
= Type::tvoid
;
4030 AggregateDeclaration
*ad
= NULL
;
4031 Type
*tb
= exp
->e1
->type
->toBasetype();
4035 ClassDeclaration
*cd
= ((TypeClass
*)tb
)->sym
;
4037 if (cd
->isCOMinterface())
4038 { /* Because COM classes are deleted by IUnknown.Release()
4040 exp
->error("cannot delete instance of COM interface %s", cd
->toChars());
4048 tb
= ((TypePointer
*)tb
)->next
->toBasetype();
4049 if (tb
->ty
== Tstruct
)
4051 ad
= ((TypeStruct
*)tb
)->sym
;
4052 FuncDeclaration
*f
= ad
->aggDelete
;
4053 FuncDeclaration
*fd
= ad
->dtor
;
4057 semanticTypeInfo(sc
, tb
);
4062 * ea = copy e1 to a tmp to do side effects only once
4063 * eb = call destructor
4064 * ec = call deallocator
4066 Expression
*ea
= NULL
;
4067 Expression
*eb
= NULL
;
4068 Expression
*ec
= NULL
;
4069 VarDeclaration
*v
= NULL
;
4073 v
= copyToTemp(0, "__tmpea", exp
->e1
);
4075 ea
= new DeclarationExp(exp
->loc
, v
);
4081 Expression
*e
= ea
? new VarExp(exp
->loc
, v
) : exp
->e1
;
4082 e
= new DotVarExp(Loc(), e
, fd
, false);
4083 eb
= new CallExp(exp
->loc
, e
);
4084 eb
= semantic(eb
, sc
);
4089 Type
*tpv
= Type::tvoid
->pointerTo();
4090 Expression
*e
= ea
? new VarExp(exp
->loc
, v
) : exp
->e1
->castTo(sc
, tpv
);
4091 e
= new CallExp(exp
->loc
, new VarExp(exp
->loc
, f
, false), e
);
4092 ec
= semantic(e
, sc
);
4094 ea
= Expression::combine(ea
, eb
);
4095 ea
= Expression::combine(ea
, ec
);
4104 Type
*tv
= tb
->nextOf()->baseElemOf();
4105 if (tv
->ty
== Tstruct
)
4107 ad
= ((TypeStruct
*)tv
)->sym
;
4109 semanticTypeInfo(sc
, ad
->type
);
4114 exp
->error("cannot delete type %s", exp
->e1
->type
->toChars());
4123 err
|= exp
->checkPurity(sc
, ad
->dtor
);
4124 err
|= exp
->checkSafety(sc
, ad
->dtor
);
4125 err
|= exp
->checkNogc(sc
, ad
->dtor
);
4127 if (ad
->aggDelete
&& tb
->ty
!= Tarray
)
4129 err
|= exp
->checkPurity(sc
, ad
->aggDelete
);
4130 err
|= exp
->checkSafety(sc
, ad
->aggDelete
);
4131 err
|= exp
->checkNogc(sc
, ad
->aggDelete
);
4137 if (!sc
->intypeof
&& sc
->func
&&
4139 sc
->func
->setUnsafe())
4141 exp
->error("%s is not @safe but is used in @safe function %s", exp
->toChars(), sc
->func
->toChars());
4150 void visit(CastExp
*exp
)
4152 //static int x; assert(++x < 10);
4161 exp
->to
= exp
->to
->semantic(exp
->loc
, sc
);
4162 if (exp
->to
== Type::terror
)
4165 if (!exp
->to
->hasPointers())
4166 setNoderefOperand(exp
);
4168 // When e1 is a template lambda, this cast may instantiate it with
4170 exp
->e1
= inferType(exp
->e1
, exp
->to
);
4173 if (Expression
*ex
= unaSemantic(exp
, sc
))
4178 Expression
*e1x
= resolveProperties(sc
, exp
->e1
);
4179 if (e1x
->op
== TOKerror
)
4184 if (e1x
->checkType())
4190 exp
->error("cannot cast %s", exp
->e1
->toChars());
4194 if (!exp
->to
) // Handle cast(const) and cast(immutable), etc.
4196 exp
->to
= exp
->e1
->type
->castMod(exp
->mod
);
4197 exp
->to
= exp
->to
->semantic(exp
->loc
, sc
);
4198 if (exp
->to
== Type::terror
)
4202 if (exp
->to
->ty
== Ttuple
)
4204 exp
->error("cannot cast %s to tuple type %s", exp
->e1
->toChars(), exp
->to
->toChars());
4207 if (exp
->e1
->type
->ty
!= Tvoid
||
4208 (exp
->e1
->op
== TOKfunction
&& exp
->to
->ty
== Tvoid
) ||
4209 exp
->e1
->op
== TOKtype
||
4210 exp
->e1
->op
== TOKtemplate
)
4212 if (exp
->e1
->checkValue())
4216 // cast(void) is used to mark e1 as unused, so it is safe
4217 if (exp
->to
->ty
== Tvoid
)
4219 exp
->type
= exp
->to
;
4224 if (!exp
->to
->equals(exp
->e1
->type
) && exp
->mod
== (unsigned char)~0)
4226 if (Expression
*e
= exp
->op_overload(sc
))
4228 result
= e
->implicitCastTo(sc
, exp
->to
);
4233 Type
*t1b
= exp
->e1
->type
->toBasetype();
4234 Type
*tob
= exp
->to
->toBasetype();
4236 if (tob
->ty
== Tstruct
&& !tob
->equals(t1b
))
4244 // Rewrite as to.call(e1)
4245 Expression
*e
= new TypeExp(exp
->loc
, exp
->to
);
4246 e
= new CallExp(exp
->loc
, e
, exp
->e1
);
4247 e
= trySemantic(e
, sc
);
4255 if (!t1b
->equals(tob
) && (t1b
->ty
== Tarray
|| t1b
->ty
== Tsarray
))
4257 if (checkNonAssignmentArrayOp(exp
->e1
))
4261 // Look for casting to a vector type
4262 if (tob
->ty
== Tvector
&& t1b
->ty
!= Tvector
)
4264 result
= new VectorExp(exp
->loc
, exp
->e1
, exp
->to
);
4268 Expression
*ex
= exp
->e1
->castTo(sc
, exp
->to
);
4269 if (ex
->op
== TOKerror
)
4275 // Check for unsafe casts
4276 if (sc
->func
&& !sc
->intypeof
&&
4277 !isSafeCast(ex
, t1b
, tob
) &&
4278 sc
->func
->setUnsafe())
4280 exp
->error("cast from %s to %s not allowed in safe code", exp
->e1
->type
->toChars(), exp
->to
->toChars());
4287 void visit(VectorExp
*exp
)
4295 exp
->e1
= semantic(exp
->e1
, sc
);
4296 exp
->type
= exp
->to
->semantic(exp
->loc
, sc
);
4297 if (exp
->e1
->op
== TOKerror
|| exp
->type
->ty
== Terror
)
4303 Type
*tb
= exp
->type
->toBasetype();
4304 assert(tb
->ty
== Tvector
);
4305 TypeVector
*tv
= (TypeVector
*)tb
;
4306 Type
*te
= tv
->elementType();
4307 exp
->dim
= (int)(tv
->size(exp
->loc
) / te
->size(exp
->loc
));
4309 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
4311 if (exp
->e1
->op
== TOKarrayliteral
)
4313 for (size_t i
= 0; i
< exp
->dim
; i
++)
4315 // Do not stop on first error - check all AST nodes even if error found
4316 res
|= checkVectorElem(exp
, ((ArrayLiteralExp
*)exp
->e1
)->getElement(i
));
4319 else if (exp
->e1
->type
->ty
== Tvoid
)
4320 res
= checkVectorElem(exp
, exp
->e1
);
4322 Expression
*e
= exp
;
4328 void visit(SliceExp
*exp
)
4336 // operator overloading should be handled in ArrayExp already.
4338 if (Expression
*ex
= unaSemantic(exp
, sc
))
4343 exp
->e1
= resolveProperties(sc
, exp
->e1
);
4344 if (exp
->e1
->op
== TOKtype
&& exp
->e1
->type
->ty
!= Ttuple
)
4346 if (exp
->lwr
|| exp
->upr
)
4348 exp
->error("cannot slice type '%s'", exp
->e1
->toChars());
4351 Expression
*e
= new TypeExp(exp
->loc
, exp
->e1
->type
->arrayOf());
4352 result
= semantic(e
, sc
);
4355 if (!exp
->lwr
&& !exp
->upr
)
4357 if (exp
->e1
->op
== TOKarrayliteral
)
4359 // Convert [a,b,c][] to [a,b,c]
4360 Type
*t1b
= exp
->e1
->type
->toBasetype();
4361 Expression
*e
= exp
->e1
;
4362 if (t1b
->ty
== Tsarray
)
4365 e
->type
= t1b
->nextOf()->arrayOf();
4370 if (exp
->e1
->op
== TOKslice
)
4372 // Convert e[][] to e[]
4373 SliceExp
*se
= (SliceExp
*)exp
->e1
;
4374 if (!se
->lwr
&& !se
->upr
)
4380 if (isArrayOpOperand(exp
->e1
))
4382 // Convert (a[]+b[])[] to a[]+b[]
4387 if (exp
->e1
->op
== TOKerror
)
4392 if (exp
->e1
->type
->ty
== Terror
)
4395 Type
*t1b
= exp
->e1
->type
->toBasetype();
4396 if (t1b
->ty
== Tpointer
)
4398 if (((TypePointer
*)t1b
)->next
->ty
== Tfunction
)
4400 exp
->error("cannot slice function pointer %s", exp
->e1
->toChars());
4403 if (!exp
->lwr
|| !exp
->upr
)
4405 exp
->error("need upper and lower bound to slice pointer");
4408 if (sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
4410 exp
->error("pointer slicing not allowed in safe functions");
4414 else if (t1b
->ty
== Tarray
)
4417 else if (t1b
->ty
== Tsarray
)
4419 if (!exp
->arrayop
&& global
.params
.vsafe
)
4421 /* Slicing a static array is like taking the address of it.
4422 * Perform checks as if e[] was &e
4424 VarDeclaration
*v
= NULL
;
4425 if (exp
->e1
->op
== TOKdotvar
)
4427 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
4428 if (dve
->e1
->op
== TOKvar
)
4430 VarExp
*ve
= (VarExp
*)dve
->e1
;
4431 v
= ve
->var
->isVarDeclaration();
4433 else if (dve
->e1
->op
== TOKthis
|| dve
->e1
->op
== TOKsuper
)
4435 ThisExp
*ve
= (ThisExp
*)dve
->e1
;
4436 v
= ve
->var
->isVarDeclaration();
4437 if (v
&& !(v
->storage_class
& STCref
))
4441 else if (exp
->e1
->op
== TOKvar
)
4443 VarExp
*ve
= (VarExp
*)exp
->e1
;
4444 v
= ve
->var
->isVarDeclaration();
4446 else if (exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
)
4448 ThisExp
*ve
= (ThisExp
*)exp
->e1
;
4449 v
= ve
->var
->isVarDeclaration();
4454 if (!checkAddressVar(sc
, exp
, v
))
4459 else if (t1b
->ty
== Ttuple
)
4461 if (!exp
->lwr
&& !exp
->upr
)
4466 if (!exp
->lwr
|| !exp
->upr
)
4468 exp
->error("need upper and lower bound to slice tuple");
4472 else if (t1b
->ty
== Tvector
)
4474 // Convert e1 to corresponding static array
4475 TypeVector
*tv1
= (TypeVector
*)t1b
;
4476 t1b
= tv1
->basetype
;
4477 t1b
= t1b
->castMod(tv1
->mod
);
4478 exp
->e1
->type
= t1b
;
4482 exp
->error("%s cannot be sliced with []",
4483 t1b
->ty
== Tvoid
? exp
->e1
->toChars() : t1b
->toChars());
4487 /* Run semantic on lwr and upr.
4490 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
|| t1b
->ty
== Ttuple
)
4492 // Create scope for 'length' variable
4493 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, exp
);
4494 sym
->loc
= exp
->loc
;
4495 sym
->parent
= sc
->scopesym
;
4500 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4501 exp
->lwr
= semantic(exp
->lwr
, sc
);
4502 exp
->lwr
= resolveProperties(sc
, exp
->lwr
);
4503 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4504 exp
->lwr
= exp
->lwr
->implicitCastTo(sc
, Type::tsize_t
);
4508 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4509 exp
->upr
= semantic(exp
->upr
, sc
);
4510 exp
->upr
= resolveProperties(sc
, exp
->upr
);
4511 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4512 exp
->upr
= exp
->upr
->implicitCastTo(sc
, Type::tsize_t
);
4516 if ((exp
->lwr
&& exp
->lwr
->type
== Type::terror
) ||
4517 (exp
->upr
&& exp
->upr
->type
== Type::terror
))
4522 if (t1b
->ty
== Ttuple
)
4524 exp
->lwr
= exp
->lwr
->ctfeInterpret();
4525 exp
->upr
= exp
->upr
->ctfeInterpret();
4526 uinteger_t i1
= exp
->lwr
->toUInteger();
4527 uinteger_t i2
= exp
->upr
->toUInteger();
4532 if (exp
->e1
->op
== TOKtuple
) // slicing an expression tuple
4534 te
= (TupleExp
*)exp
->e1
;
4536 length
= te
->exps
->dim
;
4538 else if (exp
->e1
->op
== TOKtype
) // slicing a type tuple
4541 tup
= (TypeTuple
*)t1b
;
4542 length
= Parameter::dim(tup
->arguments
);
4547 if (i2
< i1
|| length
< i2
)
4549 exp
->error("string slice [%llu .. %llu] is out of bounds", i1
, i2
);
4553 size_t j1
= (size_t) i1
;
4554 size_t j2
= (size_t) i2
;
4556 if (exp
->e1
->op
== TOKtuple
)
4558 Expressions
*exps
= new Expressions
;
4559 exps
->setDim(j2
- j1
);
4560 for (size_t i
= 0; i
< j2
- j1
; i
++)
4562 (*exps
)[i
] = (*te
->exps
)[j1
+ i
];
4564 e
= new TupleExp(exp
->loc
, te
->e0
, exps
);
4568 Parameters
*args
= new Parameters
;
4569 args
->reserve(j2
- j1
);
4570 for (size_t i
= j1
; i
< j2
; i
++)
4572 Parameter
*arg
= Parameter::getNth(tup
->arguments
, i
);
4575 e
= new TypeExp(exp
->e1
->loc
, new TypeTuple(args
));
4577 e
= semantic(e
, sc
);
4582 exp
->type
= t1b
->nextOf()->arrayOf();
4583 // Allow typedef[] -> typedef[]
4584 if (exp
->type
->equals(t1b
))
4585 exp
->type
= exp
->e1
->type
;
4587 if (exp
->lwr
&& exp
->upr
)
4589 exp
->lwr
= exp
->lwr
->optimize(WANTvalue
);
4590 exp
->upr
= exp
->upr
->optimize(WANTvalue
);
4592 IntRange lwrRange
= getIntRange(exp
->lwr
);
4593 IntRange uprRange
= getIntRange(exp
->upr
);
4595 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
)
4597 Expression
*el
= new ArrayLengthExp(exp
->loc
, exp
->e1
);
4598 el
= semantic(el
, sc
);
4599 el
= el
->optimize(WANTvalue
);
4600 if (el
->op
== TOKint64
)
4602 dinteger_t length
= el
->toInteger();
4603 IntRange
bounds(SignExtendedNumber(0), SignExtendedNumber(length
));
4604 exp
->upperIsInBounds
= bounds
.contains(uprRange
);
4607 else if (t1b
->ty
== Tpointer
)
4609 exp
->upperIsInBounds
= true;
4614 exp
->lowerIsLessThanUpper
= (lwrRange
.imax
<= uprRange
.imin
);
4616 //printf("upperIsInBounds = %d lowerIsLessThanUpper = %d\n", upperIsInBounds, lowerIsLessThanUpper);
4622 void visit(ArrayLengthExp
*e
)
4630 if (Expression
*ex
= unaSemantic(e
, sc
))
4635 e
->e1
= resolveProperties(sc
, e
->e1
);
4637 e
->type
= Type::tsize_t
;
4641 void visit(IntervalExp
*e
)
4649 Expression
*le
= e
->lwr
;
4650 le
= semantic(le
, sc
);
4651 le
= resolveProperties(sc
, le
);
4653 Expression
*ue
= e
->upr
;
4654 ue
= semantic(ue
, sc
);
4655 ue
= resolveProperties(sc
, ue
);
4657 if (le
->op
== TOKerror
)
4662 if (ue
->op
== TOKerror
)
4671 e
->type
= Type::tvoid
;
4675 void visit(DelegatePtrExp
*e
)
4680 e
->e1
= resolveProperties(sc
, e
->e1
);
4682 if (e
->e1
->op
== TOKerror
)
4687 e
->type
= Type::tvoidptr
;
4692 void visit(DelegateFuncptrExp
*e
)
4697 e
->e1
= resolveProperties(sc
, e
->e1
);
4699 if (e
->e1
->op
== TOKerror
)
4704 e
->type
= e
->e1
->type
->nextOf()->pointerTo();
4709 void visit(ArrayExp
*exp
)
4713 Expression
*e
= exp
->op_overload(sc
);
4720 if (isAggregate(exp
->e1
->type
))
4721 exp
->error("no [] operator overload for type %s", exp
->e1
->type
->toChars());
4723 exp
->error("only one index allowed to index %s", exp
->e1
->type
->toChars());
4727 void visit(DotExp
*exp
)
4729 exp
->e1
= semantic(exp
->e1
, sc
);
4730 exp
->e2
= semantic(exp
->e2
, sc
);
4732 if (exp
->e1
->op
== TOKtype
)
4737 if (exp
->e2
->op
== TOKtype
)
4742 if (exp
->e2
->op
== TOKtemplate
)
4744 TemplateDeclaration
*td
= ((TemplateExp
*)exp
->e2
)->td
;
4745 Expression
*e
= new DotTemplateExp(exp
->loc
, exp
->e1
, td
);
4746 result
= semantic(e
, sc
);
4750 exp
->type
= exp
->e2
->type
;
4754 void visit(CommaExp
*e
)
4762 // Allow `((a,b),(x,y))`
4763 if (e
->allowCommaExp
)
4765 if (e
->e1
&& e
->e1
->op
== TOKcomma
)
4766 ((CommaExp
*)e
->e1
)->allowCommaExp
= true;
4767 if (e
->e2
&& e
->e2
->op
== TOKcomma
)
4768 ((CommaExp
*)e
->e2
)->allowCommaExp
= true;
4771 if (Expression
*ex
= binSemanticProp(e
, sc
))
4776 e
->e1
= e
->e1
->addDtorHook(sc
);
4778 if (checkNonAssignmentArrayOp(e
->e1
))
4781 e
->type
= e
->e2
->type
;
4782 if (e
->type
!= Type::tvoid
&& !e
->allowCommaExp
&& !e
->isGenerated
)
4783 e
->deprecation("Using the result of a comma expression is deprecated");
4787 void visit(IndexExp
*exp
)
4795 // operator overloading should be handled in ArrayExp already.
4798 exp
->e1
= semantic(exp
->e1
, sc
);
4799 assert(exp
->e1
->type
); // semantic() should already be run on it
4800 if (exp
->e1
->op
== TOKtype
&& exp
->e1
->type
->ty
!= Ttuple
)
4802 exp
->e2
= semantic(exp
->e2
, sc
);
4803 exp
->e2
= resolveProperties(sc
, exp
->e2
);
4805 if (exp
->e2
->op
== TOKtype
)
4806 nt
= new TypeAArray(exp
->e1
->type
, exp
->e2
->type
);
4808 nt
= new TypeSArray(exp
->e1
->type
, exp
->e2
);
4809 Expression
*e
= new TypeExp(exp
->loc
, nt
);
4810 result
= semantic(e
, sc
);
4813 if (exp
->e1
->op
== TOKerror
)
4818 if (exp
->e1
->type
->ty
== Terror
)
4821 // Note that unlike C we do not implement the int[ptr]
4823 Type
*t1b
= exp
->e1
->type
->toBasetype();
4825 if (t1b
->ty
== Tvector
)
4827 // Convert e1 to corresponding static array
4828 TypeVector
*tv1
= (TypeVector
*)t1b
;
4829 t1b
= tv1
->basetype
;
4830 t1b
= t1b
->castMod(tv1
->mod
);
4831 exp
->e1
->type
= t1b
;
4834 /* Run semantic on e2
4837 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
|| t1b
->ty
== Ttuple
)
4839 // Create scope for 'length' variable
4840 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, exp
);
4841 sym
->loc
= exp
->loc
;
4842 sym
->parent
= sc
->scopesym
;
4845 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4846 exp
->e2
= semantic(exp
->e2
, sc
);
4847 exp
->e2
= resolveProperties(sc
, exp
->e2
);
4848 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4849 if (exp
->e2
->op
== TOKtuple
)
4851 TupleExp
*te
= (TupleExp
*)exp
->e2
;
4852 if (te
->exps
&& te
->exps
->dim
== 1)
4853 exp
->e2
= Expression::combine(te
->e0
, (*te
->exps
)[0]); // bug 4444 fix
4857 if (exp
->e2
->type
== Type::terror
)
4860 if (checkNonAssignmentArrayOp(exp
->e1
))
4866 if (((TypePointer
*)t1b
)->next
->ty
== Tfunction
)
4868 exp
->error("cannot index function pointer %s", exp
->e1
->toChars());
4871 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4872 if (exp
->e2
->type
== Type::terror
)
4874 exp
->e2
= exp
->e2
->optimize(WANTvalue
);
4875 if (exp
->e2
->op
== TOKint64
&& exp
->e2
->toInteger() == 0)
4877 else if (sc
->func
&& sc
->func
->setUnsafe())
4879 exp
->error("safe function '%s' cannot index pointer '%s'",
4880 sc
->func
->toPrettyChars(), exp
->e1
->toChars());
4883 exp
->type
= ((TypeNext
*)t1b
)->next
;
4887 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4888 if (exp
->e2
->type
== Type::terror
)
4890 exp
->type
= ((TypeNext
*)t1b
)->next
;
4895 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4896 if (exp
->e2
->type
== Type::terror
)
4898 exp
->type
= t1b
->nextOf();
4904 TypeAArray
*taa
= (TypeAArray
*)t1b
;
4905 /* We can skip the implicit conversion if they differ only by
4906 * constness (Bugzilla 2684, see also bug 2954b)
4908 if (!arrayTypeCompatibleWithoutCasting(exp
->e2
->type
, taa
->index
))
4910 exp
->e2
= exp
->e2
->implicitCastTo(sc
, taa
->index
); // type checking
4911 if (exp
->e2
->type
== Type::terror
)
4915 semanticTypeInfo(sc
, taa
);
4917 exp
->type
= taa
->next
;
4923 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4924 if (exp
->e2
->type
== Type::terror
)
4926 exp
->e2
= exp
->e2
->ctfeInterpret();
4927 uinteger_t index
= exp
->e2
->toUInteger();
4932 if (exp
->e1
->op
== TOKtuple
)
4934 te
= (TupleExp
*)exp
->e1
;
4936 length
= te
->exps
->dim
;
4938 else if (exp
->e1
->op
== TOKtype
)
4941 tup
= (TypeTuple
*)t1b
;
4942 length
= Parameter::dim(tup
->arguments
);
4947 if (length
<= index
)
4949 exp
->error("array index [%llu] is outside array bounds [0 .. %llu]",
4950 index
, (ulonglong
)length
);
4955 if (exp
->e1
->op
== TOKtuple
)
4957 e
= (*te
->exps
)[(size_t)index
];
4958 e
= Expression::combine(te
->e0
, e
);
4961 e
= new TypeExp(exp
->e1
->loc
, Parameter::getNth(tup
->arguments
, (size_t)index
)->type
);
4967 exp
->error("%s must be an array or pointer type, not %s",
4968 exp
->e1
->toChars(), exp
->e1
->type
->toChars());
4972 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
)
4974 Expression
*el
= new ArrayLengthExp(exp
->loc
, exp
->e1
);
4975 el
= semantic(el
, sc
);
4976 el
= el
->optimize(WANTvalue
);
4977 if (el
->op
== TOKint64
)
4979 exp
->e2
= exp
->e2
->optimize(WANTvalue
);
4980 dinteger_t length
= el
->toInteger();
4983 IntRange
bounds(SignExtendedNumber(0), SignExtendedNumber(length
- 1));
4984 exp
->indexIsInBounds
= bounds
.contains(getIntRange(exp
->e2
));
4992 void visit(PostExp
*exp
)
5000 if (Expression
*ex
= binSemantic(exp
, sc
))
5005 Expression
*e1x
= resolveProperties(sc
, exp
->e1
);
5006 if (e1x
->op
== TOKerror
)
5013 Expression
*e
= exp
->op_overload(sc
);
5020 if (exp
->e1
->checkReadModifyWrite(exp
->op
))
5022 if (exp
->e1
->op
== TOKslice
)
5024 const char *s
= exp
->op
== TOKplusplus
? "increment" : "decrement";
5025 exp
->error("cannot post-%s array slice '%s', use pre-%s instead", s
, exp
->e1
->toChars(), s
);
5029 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
5031 Type
*t1
= exp
->e1
->type
->toBasetype();
5032 if (t1
->ty
== Tclass
|| t1
->ty
== Tstruct
|| exp
->e1
->op
== TOKarraylength
)
5034 /* Check for operator overloading,
5035 * but rewrite in terms of ++e instead of e++
5038 /* If e1 is not trivial, take a reference to it
5040 Expression
*de
= NULL
;
5041 if (exp
->e1
->op
!= TOKvar
&& exp
->e1
->op
!= TOKarraylength
)
5044 VarDeclaration
*v
= copyToTemp(STCref
, "__postref", exp
->e1
);
5045 de
= new DeclarationExp(exp
->loc
, v
);
5046 exp
->e1
= new VarExp(exp
->e1
->loc
, v
);
5050 * auto tmp = e1; ++e1; tmp
5052 VarDeclaration
*tmp
= copyToTemp(0, "__pitmp", exp
->e1
);
5053 Expression
*ea
= new DeclarationExp(exp
->loc
, tmp
);
5055 Expression
*eb
= exp
->e1
->syntaxCopy();
5056 eb
= new PreExp(exp
->op
== TOKplusplus
? TOKpreplusplus
: TOKpreminusminus
, exp
->loc
, eb
);
5058 Expression
*ec
= new VarExp(exp
->loc
, tmp
);
5060 // Combine de,ea,eb,ec
5062 ea
= new CommaExp(exp
->loc
, de
, ea
);
5063 e
= new CommaExp(exp
->loc
, ea
, eb
);
5064 e
= new CommaExp(exp
->loc
, e
, ec
);
5065 e
= semantic(e
, sc
);
5070 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
5073 if (exp
->e1
->checkScalar())
5075 if (exp
->e1
->checkNoBool())
5078 if (exp
->e1
->type
->ty
== Tpointer
)
5079 e
= scaleFactor(exp
, sc
);
5081 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
5082 e
->type
= exp
->e1
->type
;
5086 void visit(PreExp
*exp
)
5088 Expression
*e
= exp
->op_overload(sc
);
5089 // printf("PreExp::semantic('%s')\n", exp->toChars());
5097 // Rewrite as e1+=1 or e1-=1
5098 if (exp
->op
== TOKpreplusplus
)
5099 e
= new AddAssignExp(exp
->loc
, exp
->e1
, new IntegerExp(exp
->loc
, 1, Type::tint32
));
5101 e
= new MinAssignExp(exp
->loc
, exp
->e1
, new IntegerExp(exp
->loc
, 1, Type::tint32
));
5102 result
= semantic(e
, sc
);
5105 void visit(AssignExp
*exp
)
5107 //printf("e1->op = %d, '%s'\n", exp->e1->op, Token::toChars(exp->e1->op));
5108 //printf("e2->op = %d, '%s'\n", exp->e2->op, Token::toChars(exp->e2->op));
5115 Expression
*e1old
= exp
->e1
;
5117 if (exp
->e2
->op
== TOKcomma
)
5119 /* Rewrite to get rid of the comma from rvalue
5121 if (!((CommaExp
*)exp
->e2
)->isGenerated
)
5122 exp
->deprecation("Using the result of a comma expression is deprecated");
5124 exp
->e2
= Expression::extractLast(exp
->e2
, &e0
);
5125 Expression
*e
= Expression::combine(e0
, exp
);
5126 result
= semantic(e
, sc
);
5130 /* Look for operator overloading of a[arguments] = e2.
5131 * Do it before e1->semantic() otherwise the ArrayExp will have been
5132 * converted to unary operator overloading already.
5134 if (exp
->e1
->op
== TOKarray
)
5138 ArrayExp
*ae
= (ArrayExp
*)exp
->e1
;
5139 ae
->e1
= semantic(ae
->e1
, sc
);
5140 ae
->e1
= resolveProperties(sc
, ae
->e1
);
5141 Expression
*ae1old
= ae
->e1
;
5143 const bool maybeSlice
=
5144 (ae
->arguments
->dim
== 0 ||
5145 (ae
->arguments
->dim
== 1 && (*ae
->arguments
)[0]->op
== TOKinterval
));
5146 IntervalExp
*ie
= NULL
;
5147 if (maybeSlice
&& ae
->arguments
->dim
)
5149 assert((*ae
->arguments
)[0]->op
== TOKinterval
);
5150 ie
= (IntervalExp
*)(*ae
->arguments
)[0];
5155 if (ae
->e1
->op
== TOKerror
)
5160 Expression
*e0
= NULL
;
5161 Expression
*ae1save
= ae
->e1
;
5162 ae
->lengthVar
= NULL
;
5164 Type
*t1b
= ae
->e1
->type
->toBasetype();
5165 AggregateDeclaration
*ad
= isAggregate(t1b
);
5168 if (search_function(ad
, Id::indexass
))
5171 res
= resolveOpDollar(sc
, ae
, &e0
);
5172 if (!res
) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)
5174 if (res
->op
== TOKerror
)
5180 res
= semantic(exp
->e2
, sc
);
5181 if (res
->op
== TOKerror
)
5188 /* Rewrite (a[arguments] = e2) as:
5189 * a.opIndexAssign(e2, arguments)
5191 Expressions
*a
= (Expressions
*)ae
->arguments
->copy();
5192 a
->insert(0, exp
->e2
);
5193 res
= new DotIdExp(exp
->loc
, ae
->e1
, Id::indexass
);
5194 res
= new CallExp(exp
->loc
, res
, a
);
5195 if (maybeSlice
) // a[] = e2 might be: a.opSliceAssign(e2)
5196 res
= trySemantic(res
, sc
);
5198 res
= semantic(res
, sc
);
5201 res
= Expression::combine(e0
, res
);
5207 if (maybeSlice
&& search_function(ad
, Id::sliceass
))
5210 res
= resolveOpDollar(sc
, ae
, ie
, &e0
);
5211 if (res
->op
== TOKerror
)
5217 res
= semantic(exp
->e2
, sc
);
5218 if (res
->op
== TOKerror
)
5225 /* Rewrite (a[i..j] = e2) as:
5226 * a.opSliceAssign(e2, i, j)
5228 Expressions
*a
= new Expressions();
5235 res
= new DotIdExp(exp
->loc
, ae
->e1
, Id::sliceass
);
5236 res
= new CallExp(exp
->loc
, res
, a
);
5237 res
= semantic(res
, sc
);
5238 res
= Expression::combine(e0
, res
);
5243 // No operator overloading member function found yet, but
5244 // there might be an alias this to try.
5245 if (ad
->aliasthis
&& t1b
!= ae
->att1
)
5247 if (!ae
->att1
&& t1b
->checkAliasThisRec())
5250 /* Rewrite (a[arguments] op e2) as:
5251 * a.aliasthis[arguments] op e2
5253 ae
->e1
= resolveAliasThis(sc
, ae1save
, true);
5259 ae
->e1
= ae1old
; // recovery
5260 ae
->lengthVar
= NULL
;
5263 /* Run exp->e1 semantic.
5266 Expression
*e1x
= exp
->e1
;
5268 /* With UFCS, e.f = value
5274 if (e1x
->op
== TOKdotti
)
5276 DotTemplateInstanceExp
*dti
= (DotTemplateInstanceExp
*)e1x
;
5277 Expression
*e
= semanticY(dti
, sc
, 1);
5280 result
= resolveUFCSProperties(sc
, e1x
, exp
->e2
);
5285 else if (e1x
->op
== TOKdotid
)
5287 DotIdExp
*die
= (DotIdExp
*)e1x
;
5288 Expression
*e
= semanticY(die
, sc
, 1);
5289 if (e
&& isDotOpDispatch(e
))
5291 unsigned errors
= global
.startGagging();
5292 e
= resolvePropertiesX(sc
, e
, exp
->e2
);
5293 if (global
.endGagging(errors
))
5294 e
= NULL
; /* fall down to UFCS */
5303 result
= resolveUFCSProperties(sc
, e1x
, exp
->e2
);
5310 if (e1x
->op
== TOKslice
)
5311 ((SliceExp
*)e1x
)->arrayop
= true;
5313 e1x
= semantic(e1x
, sc
);
5316 /* We have f = value.
5322 if (Expression
*e
= resolvePropertiesX(sc
, e1x
, exp
->e2
))
5327 if (e1x
->checkRightThis(sc
))
5330 assert(exp
->e1
->type
);
5332 Type
*t1
= exp
->e1
->type
->toBasetype();
5334 /* Run exp->e2 semantic.
5335 * Different from other binary expressions, the analysis of e2
5336 * depends on the result of e1 in assignments.
5339 Expression
*e2x
= inferType(exp
->e2
, t1
->baseElemOf());
5341 e2x
= semantic(e2x
, sc
);
5342 e2x
= resolveProperties(sc
, e2x
);
5344 if (e2x
->op
== TOKtype
)
5345 e2x
= resolveAliasThis(sc
, e2x
); //https://issues.dlang.org/show_bug.cgi?id=17684
5346 if (e2x
->op
== TOKerror
)
5351 if (e2x
->checkValue())
5356 /* Rewrite tuple assignment as a tuple of assignments.
5359 Expression
*e2x
= exp
->e2
;
5362 if (exp
->e1
->op
== TOKtuple
&& e2x
->op
== TOKtuple
)
5364 TupleExp
*tup1
= (TupleExp
*)exp
->e1
;
5365 TupleExp
*tup2
= (TupleExp
*)e2x
;
5366 size_t dim
= tup1
->exps
->dim
;
5367 Expression
*e
= NULL
;
5368 if (dim
!= tup2
->exps
->dim
)
5370 exp
->error("mismatched tuple lengths, %d and %d", (int)dim
, (int)tup2
->exps
->dim
);
5375 e
= new IntegerExp(exp
->loc
, 0, Type::tint32
);
5376 e
= new CastExp(exp
->loc
, e
, Type::tvoid
); // avoid "has no effect" error
5377 e
= Expression::combine(Expression::combine(tup1
->e0
, tup2
->e0
), e
);
5381 Expressions
*exps
= new Expressions
;
5383 for (size_t i
= 0; i
< dim
; i
++)
5385 Expression
*ex1
= (*tup1
->exps
)[i
];
5386 Expression
*ex2
= (*tup2
->exps
)[i
];
5387 (*exps
)[i
] = new AssignExp(exp
->loc
, ex1
, ex2
);
5389 e
= new TupleExp(exp
->loc
, Expression::combine(tup1
->e0
, tup2
->e0
), exps
);
5391 result
= semantic(e
, sc
);
5395 /* Look for form: e1 = e2->aliasthis.
5397 if (exp
->e1
->op
== TOKtuple
)
5399 TupleDeclaration
*td
= isAliasThisTuple(e2x
);
5403 assert(exp
->e1
->type
->ty
== Ttuple
);
5404 TypeTuple
*tt
= (TypeTuple
*)exp
->e1
->type
;
5406 Expression
*e0
= NULL
;
5407 Expression
*ev
= extractSideEffect(sc
, "__tup", &e0
, e2x
);
5409 Expressions
*iexps
= new Expressions();
5412 for (size_t u
= 0; u
< iexps
->dim
; u
++)
5415 Expression
*e
= (*iexps
)[u
];
5417 Parameter
*arg
= Parameter::getNth(tt
->arguments
, u
);
5418 //printf("[%d] iexps->dim = %d, ", u, iexps->dim);
5419 //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars());
5420 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars());
5422 if (!arg
|| !e
->type
->implicitConvTo(arg
->type
))
5424 // expand initializer to tuple
5425 if (expandAliasThisTuples(iexps
, u
) != -1)
5427 if (iexps
->dim
<= u
)
5434 e2x
= new TupleExp(e2x
->loc
, e0
, iexps
);
5435 e2x
= semantic(e2x
, sc
);
5436 if (e2x
->op
== TOKerror
)
5441 // Do not need to overwrite exp->e2
5448 /* Inside constructor, if this is the first assignment of object field,
5449 * rewrite this to initializing the field.
5451 if (exp
->op
== TOKassign
&& exp
->e1
->checkModifiable(sc
) == 2)
5453 //printf("[%s] change to init - %s\n", exp->loc.toChars(), toChars());
5454 exp
->op
= TOKconstruct
;
5456 // Bugzilla 13515: set Index::modifiable flag for complex AA element initialization
5457 if (exp
->e1
->op
== TOKindex
)
5459 Expression
*e1x
= ((IndexExp
*)exp
->e1
)->markSettingAAElem();
5460 if (e1x
->op
== TOKerror
)
5467 else if (exp
->op
== TOKconstruct
&& exp
->e1
->op
== TOKvar
&&
5468 ((VarExp
*)exp
->e1
)->var
->storage_class
& (STCout
| STCref
))
5470 exp
->memset
|= referenceInit
;
5473 /* If it is an assignment from a 'foreign' type,
5474 * check for operator overloading.
5476 if (exp
->memset
& referenceInit
)
5478 // If this is an initialization of a reference,
5481 else if (t1
->ty
== Tstruct
)
5483 Expression
*e1x
= exp
->e1
;
5484 Expression
*e2x
= exp
->e2
;
5485 StructDeclaration
*sd
= ((TypeStruct
*)t1
)->sym
;
5487 if (exp
->op
== TOKconstruct
)
5489 Type
*t2
= e2x
->type
->toBasetype();
5490 if (t2
->ty
== Tstruct
&& sd
== ((TypeStruct
*)t2
)->sym
)
5493 if (sd
->sizeok
!= SIZEOKdone
)
5496 sd
->ctor
= sd
->searchCtor();
5498 // Bugzilla 15661: Look for the form from last of comma chain.
5499 Expression
*e2y
= e2x
;
5500 while (e2y
->op
== TOKcomma
)
5501 e2y
= ((CommaExp
*)e2y
)->e2
;
5503 CallExp
*ce
= (e2y
->op
== TOKcall
) ? (CallExp
*)e2y
: NULL
;
5504 DotVarExp
*dve
= (ce
&& ce
->e1
->op
== TOKdotvar
)
5505 ? (DotVarExp
*)ce
->e1
: NULL
;
5506 if (sd
->ctor
&& ce
&& dve
&& dve
->var
->isCtorDeclaration() &&
5507 e2y
->type
->implicitConvTo(t1
))
5509 /* Look for form of constructor call which is:
5510 * __ctmp.ctor(arguments...)
5513 /* Before calling the constructor, initialize
5514 * variable with a bit copy of the default
5517 AssignExp
*ae
= exp
;
5518 if (sd
->zeroInit
== 1 && !sd
->isNested())
5520 // Bugzilla 14606: Always use BlitExp for the special expression: (struct = 0)
5521 ae
= new BlitExp(ae
->loc
, ae
->e1
, new IntegerExp(exp
->loc
, 0, Type::tint32
));
5525 // Keep ae->op == TOKconstruct
5526 ae
->e2
= sd
->isNested() ? t1
->defaultInitLiteral(exp
->loc
) : t1
->defaultInit(exp
->loc
);
5528 ae
->type
= e1x
->type
;
5530 /* Replace __ctmp being constructed with e1.
5531 * We need to copy constructor call expression,
5532 * because it may be used in other place.
5534 DotVarExp
*dvx
= (DotVarExp
*)dve
->copy();
5536 CallExp
*cx
= (CallExp
*)ce
->copy();
5540 Expression::extractLast(e2x
, &e0
);
5542 Expression
*e
= Expression::combine(ae
, cx
);
5543 e
= Expression::combine(e0
, e
);
5544 e
= semantic(e
, sc
);
5550 /* We have a copy constructor for this
5552 if (e2x
->op
== TOKquestion
)
5555 * a ? e1 = b : e1 = c;
5557 CondExp
*econd
= (CondExp
*)e2x
;
5558 Expression
*ea1
= new ConstructExp(econd
->e1
->loc
, e1x
, econd
->e1
);
5559 Expression
*ea2
= new ConstructExp(econd
->e1
->loc
, e1x
, econd
->e2
);
5560 Expression
*e
= new CondExp(exp
->loc
, econd
->econd
, ea1
, ea2
);
5561 result
= semantic(e
, sc
);
5565 if (e2x
->isLvalue())
5567 if (!e2x
->type
->implicitConvTo(e1x
->type
))
5569 exp
->error("conversion error from %s to %s", e2x
->type
->toChars(), e1x
->type
->toChars());
5574 * (e1 = e2).postblit();
5576 * Blit assignment e1 = e2 returns a reference to the original e1,
5577 * then call the postblit on it.
5579 Expression
*e
= e1x
->copy();
5580 e
->type
= e
->type
->mutableOf();
5581 e
= new BlitExp(exp
->loc
, e
, e2x
);
5582 e
= new DotVarExp(exp
->loc
, e
, sd
->postblit
, false);
5583 e
= new CallExp(exp
->loc
, e
);
5584 result
= semantic(e
, sc
);
5589 /* The struct value returned from the function is transferred
5590 * so should not call the destructor on it.
5592 e2x
= valueNoDtor(e2x
);
5596 else if (!e2x
->implicitConvTo(t1
))
5599 if (sd
->sizeok
!= SIZEOKdone
)
5602 sd
->ctor
= sd
->searchCtor();
5606 /* Look for implicit constructor call
5608 * e1 = init, e1.ctor(e2)
5611 einit
= new BlitExp(exp
->loc
, e1x
, e1x
->type
->defaultInit(exp
->loc
));
5612 einit
->type
= e1x
->type
;
5615 e
= new DotIdExp(exp
->loc
, e1x
, Id::ctor
);
5616 e
= new CallExp(exp
->loc
, e
, e2x
);
5617 e
= new CommaExp(exp
->loc
, einit
, e
);
5618 e
= semantic(e
, sc
);
5622 if (search_function(sd
, Id::call
))
5624 /* Look for static opCall
5625 * (See bugzilla 2702 for more discussion)
5627 * e1 = typeof(e1).opCall(arguments)
5629 e2x
= typeDotIdExp(e2x
->loc
, e1x
->type
, Id::call
);
5630 e2x
= new CallExp(exp
->loc
, e2x
, exp
->e2
);
5632 e2x
= semantic(e2x
, sc
);
5633 e2x
= resolveProperties(sc
, e2x
);
5634 if (e2x
->op
== TOKerror
)
5639 if (e2x
->checkValue())
5643 else // Bugzilla 11355
5645 AggregateDeclaration
*ad2
= isAggregate(e2x
->type
);
5646 if (ad2
&& ad2
->aliasthis
&& !(exp
->att2
&& e2x
->type
== exp
->att2
))
5648 if (!exp
->att2
&& exp
->e2
->type
->checkAliasThisRec())
5649 exp
->att2
= exp
->e2
->type
;
5651 /* Rewrite (e1 op e2) as:
5652 * (e1 op e2.aliasthis)
5654 exp
->e2
= new DotIdExp(exp
->e2
->loc
, exp
->e2
, ad2
->aliasthis
->ident
);
5655 result
= semantic(exp
, sc
);
5660 else if (exp
->op
== TOKassign
)
5662 if (e1x
->op
== TOKindex
&&
5663 ((IndexExp
*)e1x
)->e1
->type
->toBasetype()->ty
== Taarray
)
5670 * ref __aakey = key;
5672 * (__aakey in __aatmp
5673 * ? __aatmp[__aakey].opAssign(__aaval)
5674 * : ConstructExp(__aatmp[__aakey], __aaval));
5676 IndexExp
*ie
= (IndexExp
*)e1x
;
5677 Type
*t2
= e2x
->type
->toBasetype();
5679 Expression
*e0
= NULL
;
5680 Expression
*ea
= extractSideEffect(sc
, "__aatmp", &e0
, ie
->e1
);
5681 Expression
*ek
= extractSideEffect(sc
, "__aakey", &e0
, ie
->e2
);
5682 Expression
*ev
= extractSideEffect(sc
, "__aaval", &e0
, e2x
);
5684 AssignExp
*ae
= (AssignExp
*)exp
->copy();
5685 ae
->e1
= new IndexExp(exp
->loc
, ea
, ek
);
5686 ae
->e1
= semantic(ae
->e1
, sc
);
5687 ae
->e1
= ae
->e1
->optimize(WANTvalue
);
5689 Expression
*e
= ae
->op_overload(sc
);
5692 Expression
*ey
= NULL
;
5693 if (t2
->ty
== Tstruct
&& sd
== t2
->toDsymbol(sc
))
5697 else if (!ev
->implicitConvTo(ie
->type
) && sd
->ctor
)
5699 // Look for implicit constructor call
5700 // Rewrite as S().ctor(e2)
5701 ey
= new StructLiteralExp(exp
->loc
, sd
, NULL
);
5702 ey
= new DotIdExp(exp
->loc
, ey
, Id::ctor
);
5703 ey
= new CallExp(exp
->loc
, ey
, ev
);
5704 ey
= trySemantic(ey
, sc
);
5709 ex
= new IndexExp(exp
->loc
, ea
, ek
);
5710 ex
= semantic(ex
, sc
);
5711 ex
= ex
->optimize(WANTvalue
);
5712 ex
= ex
->modifiableLvalue(sc
, ex
); // allocate new slot
5713 ey
= new ConstructExp(exp
->loc
, ex
, ey
);
5714 ey
= semantic(ey
, sc
);
5715 if (ey
->op
== TOKerror
)
5722 // Bugzilla 14144: The whole expression should have the common type
5723 // of opAssign() return and assigned AA entry.
5724 // Even if there's no common type, expression should be typed as void.
5726 if (!typeMerge(sc
, TOKquestion
, &t
, &ex
, &ey
))
5728 ex
= new CastExp(ex
->loc
, ex
, Type::tvoid
);
5729 ey
= new CastExp(ey
->loc
, ey
, Type::tvoid
);
5731 e
= new CondExp(exp
->loc
, new InExp(exp
->loc
, ek
, ea
), ex
, ey
);
5733 e
= Expression::combine(e0
, e
);
5734 e
= semantic(e
, sc
);
5741 Expression
*e
= exp
->op_overload(sc
);
5750 assert(exp
->op
== TOKblit
);
5755 else if (t1
->ty
== Tclass
)
5757 // Disallow assignment operator overloads for same type
5758 if (exp
->op
== TOKassign
&& !exp
->e2
->implicitConvTo(exp
->e1
->type
))
5760 Expression
*e
= exp
->op_overload(sc
);
5768 else if (t1
->ty
== Tsarray
)
5770 // SliceExp cannot have static array type without context inference.
5771 assert(exp
->e1
->op
!= TOKslice
);
5773 Expression
*e1x
= exp
->e1
;
5774 Expression
*e2x
= exp
->e2
;
5776 if (e2x
->implicitConvTo(e1x
->type
))
5778 if (exp
->op
!= TOKblit
&&
5779 ((e2x
->op
== TOKslice
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5780 (e2x
->op
== TOKcast
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5781 (e2x
->op
!= TOKslice
&& e2x
->isLvalue())))
5783 if (e1x
->checkPostblit(sc
, t1
))
5787 // e2 matches to t1 because of the implicit length match, so
5788 if (isUnaArrayOp(e2x
->op
) || isBinArrayOp(e2x
->op
))
5790 // convert e1 to e1[]
5791 // e.g. e1[] = a[] + b[];
5792 SliceExp
*sle
= new SliceExp(e1x
->loc
, e1x
, NULL
, NULL
);
5793 sle
->arrayop
= true;
5794 e1x
= semantic(sle
, sc
);
5798 // convert e2 to t1 later
5799 // e.g. e1 = [1, 2, 3];
5804 if (e2x
->implicitConvTo(t1
->nextOf()->arrayOf()) > MATCHnomatch
)
5806 uinteger_t dim1
= ((TypeSArray
*)t1
)->dim
->toInteger();
5807 uinteger_t dim2
= dim1
;
5808 if (e2x
->op
== TOKarrayliteral
)
5810 ArrayLiteralExp
*ale
= (ArrayLiteralExp
*)e2x
;
5811 dim2
= ale
->elements
? ale
->elements
->dim
: 0;
5813 else if (e2x
->op
== TOKslice
)
5815 Type
*tx
= toStaticArrayType((SliceExp
*)e2x
);
5817 dim2
= ((TypeSArray
*)tx
)->dim
->toInteger();
5821 exp
->error("mismatched array lengths, %d and %d", (int)dim1
, (int)dim2
);
5826 // May be block or element-wise assignment, so
5827 // convert e1 to e1[]
5828 if (exp
->op
!= TOKassign
)
5830 // If multidimensional static array, treat as one large array
5831 dinteger_t dim
= ((TypeSArray
*)t1
)->dim
->toInteger();
5835 t
= t
->nextOf()->toBasetype();
5836 if (t
->ty
!= Tsarray
)
5838 dim
*= ((TypeSArray
*)t
)->dim
->toInteger();
5839 e1x
->type
= t
->nextOf()->sarrayOf(dim
);
5842 SliceExp
*sle
= new SliceExp(e1x
->loc
, e1x
, NULL
, NULL
);
5843 sle
->arrayop
= true;
5844 e1x
= semantic(sle
, sc
);
5846 if (e1x
->op
== TOKerror
)
5851 if (e2x
->op
== TOKerror
)
5859 t1
= e1x
->type
->toBasetype();
5862 /* Check the mutability of e1.
5864 if (exp
->e1
->op
== TOKarraylength
)
5866 // e1 is not an lvalue, but we let code generator handle it
5867 ArrayLengthExp
*ale
= (ArrayLengthExp
*)exp
->e1
;
5869 Expression
*ale1x
= ale
->e1
;
5870 ale1x
= ale1x
->modifiableLvalue(sc
, exp
->e1
);
5871 if (ale1x
->op
== TOKerror
)
5878 Type
*tn
= ale
->e1
->type
->toBasetype()->nextOf();
5879 checkDefCtor(ale
->loc
, tn
);
5880 semanticTypeInfo(sc
, tn
);
5882 else if (exp
->e1
->op
== TOKslice
)
5884 Type
*tn
= exp
->e1
->type
->nextOf();
5885 if (exp
->op
== TOKassign
&& !tn
->isMutable())
5887 exp
->error("slice %s is not mutable", exp
->e1
->toChars());
5891 // For conditional operator, both branches need conversion.
5892 SliceExp
*se
= (SliceExp
*)exp
->e1
;
5893 while (se
->e1
->op
== TOKslice
)
5894 se
= (SliceExp
*)se
->e1
;
5895 if (se
->e1
->op
== TOKquestion
&&
5896 se
->e1
->type
->toBasetype()->ty
== Tsarray
)
5898 se
->e1
= se
->e1
->modifiableLvalue(sc
, exp
->e1
);
5899 if (se
->e1
->op
== TOKerror
)
5908 Expression
*e1x
= exp
->e1
;
5910 // Try to do a decent error message with the expression
5911 // before it got constant folded
5912 if (e1x
->op
!= TOKvar
)
5913 e1x
= e1x
->optimize(WANTvalue
);
5915 if (exp
->op
== TOKassign
)
5916 e1x
= e1x
->modifiableLvalue(sc
, e1old
);
5918 if (e1x
->op
== TOKerror
)
5926 /* Tweak e2 based on the type of e1.
5928 Expression
*e2x
= exp
->e2
;
5929 Type
*t2
= e2x
->type
->toBasetype();
5931 // If it is a array, get the element type. Note that it may be
5932 // multi-dimensional.
5934 while (telem
->ty
== Tarray
)
5935 telem
= telem
->nextOf();
5937 if (exp
->e1
->op
== TOKslice
&&
5938 t1
->nextOf() && (telem
->ty
!= Tvoid
|| e2x
->op
== TOKnull
) &&
5939 e2x
->implicitConvTo(t1
->nextOf())
5942 // Check for block assignment. If it is of type void[], void[][], etc,
5943 // '= null' is the only allowable block assignment (Bug 7493)
5945 exp
->memset
|= blockAssign
; // make it easy for back end to tell what this is
5946 e2x
= e2x
->implicitCastTo(sc
, t1
->nextOf());
5947 if (exp
->op
!= TOKblit
&& e2x
->isLvalue() &&
5948 exp
->e1
->checkPostblit(sc
, t1
->nextOf()))
5951 else if (exp
->e1
->op
== TOKslice
&&
5952 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
) &&
5953 t2
->nextOf()->implicitConvTo(t1
->nextOf()))
5955 // Check element-wise assignment.
5957 /* If assigned elements number is known at compile time,
5958 * check the mismatch.
5960 SliceExp
*se1
= (SliceExp
*)exp
->e1
;
5961 TypeSArray
*tsa1
= (TypeSArray
*)toStaticArrayType(se1
);
5962 TypeSArray
*tsa2
= NULL
;
5963 if (e2x
->op
== TOKarrayliteral
)
5964 tsa2
= (TypeSArray
*)t2
->nextOf()->sarrayOf(((ArrayLiteralExp
*)e2x
)->elements
->dim
);
5965 else if (e2x
->op
== TOKslice
)
5966 tsa2
= (TypeSArray
*)toStaticArrayType((SliceExp
*)e2x
);
5967 else if (t2
->ty
== Tsarray
)
5968 tsa2
= (TypeSArray
*)t2
;
5971 uinteger_t dim1
= tsa1
->dim
->toInteger();
5972 uinteger_t dim2
= tsa2
->dim
->toInteger();
5975 exp
->error("mismatched array lengths, %d and %d", (int)dim1
, (int)dim2
);
5980 if (exp
->op
!= TOKblit
&&
5981 ((e2x
->op
== TOKslice
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5982 (e2x
->op
== TOKcast
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5983 (e2x
->op
!= TOKslice
&& e2x
->isLvalue())))
5985 if (exp
->e1
->checkPostblit(sc
, t1
->nextOf()))
5989 if (0 && global
.params
.warnings
!= DIAGNOSTICoff
&& !global
.gag
&& exp
->op
== TOKassign
&&
5990 e2x
->op
!= TOKslice
&& e2x
->op
!= TOKassign
&&
5991 e2x
->op
!= TOKarrayliteral
&& e2x
->op
!= TOKstring
&&
5992 !(e2x
->op
== TOKadd
|| e2x
->op
== TOKmin
||
5993 e2x
->op
== TOKmul
|| e2x
->op
== TOKdiv
||
5994 e2x
->op
== TOKmod
|| e2x
->op
== TOKxor
||
5995 e2x
->op
== TOKand
|| e2x
->op
== TOKor
||
5996 e2x
->op
== TOKpow
||
5997 e2x
->op
== TOKtilde
|| e2x
->op
== TOKneg
))
5999 const char* e1str
= exp
->e1
->toChars();
6000 const char* e2str
= e2x
->toChars();
6001 exp
->warning("explicit element-wise assignment %s = (%s)[] is better than %s = %s",
6002 e1str
, e2str
, e1str
, e2str
);
6005 Type
*t2n
= t2
->nextOf();
6006 Type
*t1n
= t1
->nextOf();
6008 if (t2n
->equivalent(t1n
) ||
6009 (t1n
->isBaseOf(t2n
, &offset
) && offset
== 0))
6011 /* Allow copy of distinct qualifier elements.
6013 * char[] dst; const(char)[] src;
6016 * class C {} class D : C {}
6020 if (isArrayOpValid(e2x
))
6022 // Don't add CastExp to keep AST for array operations
6024 e2x
->type
= exp
->e1
->type
->constOf();
6027 e2x
= e2x
->castTo(sc
, exp
->e1
->type
->constOf());
6031 /* Bugzilla 15778: A string literal has an array type of immutable
6032 * elements by default, and normally it cannot be convertible to
6033 * array type of mutable elements. But for element-wise assignment,
6034 * elements need to be const at best. So we should give a chance
6035 * to change code unit size for polysemous string literal.
6037 if (e2x
->op
== TOKstring
)
6038 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
->constOf());
6040 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
);
6042 if (t1n
->toBasetype()->ty
== Tvoid
&& t2n
->toBasetype()->ty
== Tvoid
)
6044 if (!sc
->intypeof
&& sc
->func
&& sc
->func
->setUnsafe())
6046 exp
->error("cannot copy void[] to void[] in @safe code");
6053 if (0 && global
.params
.warnings
!= DIAGNOSTICoff
&& !global
.gag
&& exp
->op
== TOKassign
&&
6054 t1
->ty
== Tarray
&& t2
->ty
== Tsarray
&&
6055 e2x
->op
!= TOKslice
&&
6056 t2
->implicitConvTo(t1
))
6057 { // Disallow ar[] = sa (Converted to ar[] = sa[])
6058 // Disallow da = sa (Converted to da = sa[])
6059 const char* e1str
= exp
->e1
->toChars();
6060 const char* e2str
= e2x
->toChars();
6061 const char* atypestr
= exp
->e1
->op
== TOKslice
? "element-wise" : "slice";
6062 exp
->warning("explicit %s assignment %s = (%s)[] is better than %s = %s",
6063 atypestr
, e1str
, e2str
, e1str
, e2str
);
6065 if (exp
->op
== TOKblit
)
6066 e2x
= e2x
->castTo(sc
, exp
->e1
->type
);
6068 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
);
6070 if (e2x
->op
== TOKerror
)
6076 t2
= exp
->e2
->type
->toBasetype();
6078 /* Look for array operations
6080 if ((t2
->ty
== Tarray
|| t2
->ty
== Tsarray
) && isArrayOpValid(exp
->e2
))
6082 // Look for valid array operations
6083 if (!(exp
->memset
& blockAssign
) && exp
->e1
->op
== TOKslice
&&
6084 (isUnaArrayOp(exp
->e2
->op
) || isBinArrayOp(exp
->e2
->op
)))
6086 exp
->type
= exp
->e1
->type
;
6087 if (exp
->op
== TOKconstruct
) // Bugzilla 10282: tweak mutability of e1 element
6088 exp
->e1
->type
= exp
->e1
->type
->nextOf()->mutableOf()->arrayOf();
6089 result
= arrayOp(exp
, sc
);
6093 // Drop invalid array operations in e2
6094 // d = a[] + b[], d = (a[] + b[])[0..2], etc
6095 if (checkNonAssignmentArrayOp(exp
->e2
, !(exp
->memset
& blockAssign
) && exp
->op
== TOKassign
))
6098 // Remains valid array assignments
6099 // d = d[], d = [1,2,3], etc
6102 /* Don't allow assignment to classes that were allocated on the stack with:
6103 * scope Class c = new Class();
6106 if (exp
->e1
->op
== TOKvar
&& exp
->op
== TOKassign
)
6108 VarExp
*ve
= (VarExp
*)exp
->e1
;
6109 VarDeclaration
*vd
= ve
->var
->isVarDeclaration();
6110 if (vd
&& (vd
->onstack
|| vd
->mynew
))
6112 assert(t1
->ty
== Tclass
);
6113 exp
->error("cannot rebind scope variables");
6116 if (exp
->e1
->op
== TOKvar
&& ((VarExp
*)exp
->e1
)->var
->ident
== Id::ctfe
)
6118 exp
->error("cannot modify compiler-generated variable __ctfe");
6121 exp
->type
= exp
->e1
->type
;
6123 Expression
*res
= exp
->op
== TOKassign
? exp
->reorderSettingAAElem(sc
) : exp
;
6124 checkAssignEscape(sc
, res
, false);
6128 void visit(CatAssignExp
*exp
)
6136 //printf("CatAssignExp::semantic() %s\n", toChars());
6137 Expression
*e
= exp
->op_overload(sc
);
6144 if (exp
->e1
->op
== TOKslice
)
6146 SliceExp
*se
= (SliceExp
*)exp
->e1
;
6147 if (se
->e1
->type
->toBasetype()->ty
== Tsarray
)
6149 exp
->error("cannot append to static array %s", se
->e1
->type
->toChars());
6154 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
6155 if (exp
->e1
->op
== TOKerror
)
6160 if (exp
->e2
->op
== TOKerror
)
6166 if (checkNonAssignmentArrayOp(exp
->e2
))
6169 Type
*tb1
= exp
->e1
->type
->toBasetype();
6170 Type
*tb1next
= tb1
->nextOf();
6171 Type
*tb2
= exp
->e2
->type
->toBasetype();
6173 if ((tb1
->ty
== Tarray
) &&
6174 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
6175 (exp
->e2
->implicitConvTo(exp
->e1
->type
)
6176 || (tb2
->nextOf()->implicitConvTo(tb1next
) &&
6177 (tb2
->nextOf()->size(Loc()) == tb1next
->size(Loc())))
6182 if (exp
->e1
->checkPostblit(sc
, tb1next
))
6184 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
6186 else if ((tb1
->ty
== Tarray
) &&
6187 exp
->e2
->implicitConvTo(tb1next
)
6191 if (exp
->e2
->checkPostblit(sc
, tb2
))
6193 exp
->e2
= exp
->e2
->castTo(sc
, tb1next
);
6194 exp
->e2
= doCopyOrMove(sc
, exp
->e2
);
6196 else if (tb1
->ty
== Tarray
&&
6197 (tb1next
->ty
== Tchar
|| tb1next
->ty
== Twchar
) &&
6198 exp
->e2
->type
->ty
!= tb1next
->ty
&&
6199 exp
->e2
->implicitConvTo(Type::tdchar
)
6201 { // Append dchar to char[] or wchar[]
6202 exp
->e2
= exp
->e2
->castTo(sc
, Type::tdchar
);
6204 /* Do not allow appending wchar to char[] because if wchar happens
6205 * to be a surrogate pair, nothing good can result.
6210 exp
->error("cannot append type %s to type %s", tb2
->toChars(), tb1
->toChars());
6213 if (exp
->e2
->checkValue())
6216 exp
->type
= exp
->e1
->type
;
6217 result
= exp
->reorderSettingAAElem(sc
);
6220 void visit(PowAssignExp
*exp
)
6228 Expression
*e
= exp
->op_overload(sc
);
6235 if (exp
->e1
->checkReadModifyWrite(exp
->op
, exp
->e2
))
6238 assert(exp
->e1
->type
&& exp
->e2
->type
);
6239 if (exp
->e1
->op
== TOKslice
|| exp
->e1
->type
->ty
== Tarray
|| exp
->e1
->type
->ty
== Tsarray
)
6242 if (exp
->e2
->implicitConvTo(exp
->e1
->type
->nextOf()))
6245 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
->nextOf());
6247 else if (Expression
*ex
= typeCombine(exp
, sc
))
6253 // Check element types are arithmetic
6254 Type
*tb1
= exp
->e1
->type
->nextOf()->toBasetype();
6255 Type
*tb2
= exp
->e2
->type
->toBasetype();
6256 if (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
6257 tb2
= tb2
->nextOf()->toBasetype();
6259 if ( (tb1
->isintegral() || tb1
->isfloating()) &&
6260 (tb2
->isintegral() || tb2
->isfloating()))
6262 exp
->type
= exp
->e1
->type
;
6263 result
= arrayOp(exp
, sc
);
6269 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
6272 if ((exp
->e1
->type
->isintegral() || exp
->e1
->type
->isfloating()) &&
6273 (exp
->e2
->type
->isintegral() || exp
->e2
->type
->isfloating()))
6275 Expression
*e0
= NULL
;
6276 e
= exp
->reorderSettingAAElem(sc
);
6277 e
= Expression::extractLast(e
, &e0
);
6280 if (exp
->e1
->op
== TOKvar
)
6282 // Rewrite: e1 = e1 ^^ e2
6283 e
= new PowExp(exp
->loc
, exp
->e1
->syntaxCopy(), exp
->e2
);
6284 e
= new AssignExp(exp
->loc
, exp
->e1
, e
);
6288 // Rewrite: ref tmp = e1; tmp = tmp ^^ e2
6289 VarDeclaration
*v
= copyToTemp(STCref
, "__powtmp", exp
->e1
);
6290 Expression
*de
= new DeclarationExp(exp
->e1
->loc
, v
);
6291 VarExp
*ve
= new VarExp(exp
->e1
->loc
, v
);
6292 e
= new PowExp(exp
->loc
, ve
, exp
->e2
);
6293 e
= new AssignExp(exp
->loc
, new VarExp(exp
->e1
->loc
, v
), e
);
6294 e
= new CommaExp(exp
->loc
, de
, e
);
6296 e
= Expression::combine(e0
, e
);
6297 e
= semantic(e
, sc
);
6301 result
= exp
->incompatibleTypes();
6304 void visit(AddExp
*exp
)
6312 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6317 Expression
*e
= exp
->op_overload(sc
);
6324 Type
*tb1
= exp
->e1
->type
->toBasetype();
6325 Type
*tb2
= exp
->e2
->type
->toBasetype();
6328 if (tb1
->ty
== Tdelegate
||
6329 (tb1
->ty
== Tpointer
&& tb1
->nextOf()->ty
== Tfunction
))
6331 err
|= exp
->e1
->checkArithmetic();
6333 if (tb2
->ty
== Tdelegate
||
6334 (tb2
->ty
== Tpointer
&& tb2
->nextOf()->ty
== Tfunction
))
6336 err
|= exp
->e2
->checkArithmetic();
6341 if ((tb1
->ty
== Tpointer
&& exp
->e2
->type
->isintegral()) ||
6342 (tb2
->ty
== Tpointer
&& exp
->e1
->type
->isintegral()))
6344 result
= scaleFactor(exp
, sc
);
6348 if (tb1
->ty
== Tpointer
&& tb2
->ty
== Tpointer
)
6350 result
= exp
->incompatibleTypes();
6354 if (Expression
*ex
= typeCombine(exp
, sc
))
6360 Type
*tb
= exp
->type
->toBasetype();
6361 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6363 if (!isArrayOpValid(exp
))
6365 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6372 tb1
= exp
->e1
->type
->toBasetype();
6373 if (!Target::isVectorOpSupported(tb1
, exp
->op
, tb2
))
6375 result
= exp
->incompatibleTypes();
6378 if ((tb1
->isreal() && exp
->e2
->type
->isimaginary()) ||
6379 (tb1
->isimaginary() && exp
->e2
->type
->isreal()))
6381 switch (exp
->type
->toBasetype()->ty
)
6385 exp
->type
= Type::tcomplex32
;
6390 exp
->type
= Type::tcomplex64
;
6395 exp
->type
= Type::tcomplex80
;
6405 void visit(MinExp
*exp
)
6413 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6418 Expression
*e
= exp
->op_overload(sc
);
6425 Type
*t1
= exp
->e1
->type
->toBasetype();
6426 Type
*t2
= exp
->e2
->type
->toBasetype();
6429 if (t1
->ty
== Tdelegate
||
6430 (t1
->ty
== Tpointer
&& t1
->nextOf()->ty
== Tfunction
))
6432 err
|= exp
->e1
->checkArithmetic();
6434 if (t2
->ty
== Tdelegate
||
6435 (t2
->ty
== Tpointer
&& t2
->nextOf()->ty
== Tfunction
))
6437 err
|= exp
->e2
->checkArithmetic();
6442 if (t1
->ty
== Tpointer
)
6444 if (t2
->ty
== Tpointer
)
6446 // Need to divide the result by the stride
6447 // Replace (ptr - ptr) with (ptr - ptr) / stride
6450 // make sure pointer types are compatible
6451 if (Expression
*ex
= typeCombine(exp
, sc
))
6457 exp
->type
= Type::tptrdiff_t
;
6458 stride
= t2
->nextOf()->size();
6461 e
= new IntegerExp(exp
->loc
, 0, Type::tptrdiff_t
);
6465 e
= new DivExp(exp
->loc
, exp
, new IntegerExp(Loc(), stride
, Type::tptrdiff_t
));
6466 e
->type
= Type::tptrdiff_t
;
6469 else if (t2
->isintegral())
6470 e
= scaleFactor(exp
, sc
);
6473 exp
->error("can't subtract %s from pointer", t2
->toChars());
6479 if (t2
->ty
== Tpointer
)
6481 exp
->type
= exp
->e2
->type
;
6482 exp
->error("can't subtract pointer from %s", exp
->e1
->type
->toChars());
6486 if (Expression
*ex
= typeCombine(exp
, sc
))
6492 Type
*tb
= exp
->type
->toBasetype();
6493 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6495 if (!isArrayOpValid(exp
))
6497 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6504 t1
= exp
->e1
->type
->toBasetype();
6505 t2
= exp
->e2
->type
->toBasetype();
6506 if (!Target::isVectorOpSupported(t1
, exp
->op
, t2
))
6508 result
= exp
->incompatibleTypes();
6511 if ((t1
->isreal() && t2
->isimaginary()) ||
6512 (t1
->isimaginary() && t2
->isreal()))
6514 switch (exp
->type
->ty
)
6518 exp
->type
= Type::tcomplex32
;
6523 exp
->type
= Type::tcomplex64
;
6528 exp
->type
= Type::tcomplex80
;
6538 void visit(CatExp
*exp
)
6540 //printf("CatExp::semantic() %s\n", exp->toChars());
6547 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6552 Expression
*e
= exp
->op_overload(sc
);
6559 Type
*tb1
= exp
->e1
->type
->toBasetype();
6560 Type
*tb2
= exp
->e2
->type
->toBasetype();
6562 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
6563 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
6567 /* BUG: Should handle things like:
6572 Type
*tb1next
= tb1
->nextOf();
6573 Type
*tb2next
= tb2
->nextOf();
6575 // Check for: array ~ array
6576 if (tb1next
&& tb2next
&&
6577 (tb1next
->implicitConvTo(tb2next
) >= MATCHconst
||
6578 tb2next
->implicitConvTo(tb1next
) >= MATCHconst
||
6579 (exp
->e1
->op
== TOKarrayliteral
&& exp
->e1
->implicitConvTo(tb2
)) ||
6580 (exp
->e2
->op
== TOKarrayliteral
&& exp
->e2
->implicitConvTo(tb1
))
6584 /* Bugzilla 9248: Here to avoid the case of:
6585 * void*[] a = [cast(void*)1];
6586 * void*[] b = [cast(void*)2];
6589 * a ~ [cast(void*)b];
6592 /* Bugzilla 14682: Also to avoid the case of:
6596 * a ~ cast(int[])[];
6601 // Check for: array ~ element
6602 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
) && tb2
->ty
!= Tvoid
)
6604 if (exp
->e1
->op
== TOKarrayliteral
)
6606 exp
->e2
= exp
->e2
->isLvalue() ? callCpCtor(sc
, exp
->e2
) : valueNoDtor(exp
->e2
);
6607 // Bugzilla 14686: Postblit call appears in AST, and this is
6608 // finally translated to an ArrayLiteralExp in below otpimize().
6610 else if (exp
->e1
->op
== TOKstring
)
6612 // No postblit call exists on character (integer) value.
6616 if (exp
->e2
->checkPostblit(sc
, tb2
))
6618 // Postblit call will be done in runtime helper function
6621 if (exp
->e1
->op
== TOKarrayliteral
&& exp
->e1
->implicitConvTo(tb2
->arrayOf()))
6623 exp
->e1
= exp
->e1
->implicitCastTo(sc
, tb2
->arrayOf());
6624 exp
->type
= tb2
->arrayOf();
6627 if (exp
->e2
->implicitConvTo(tb1next
) >= MATCHconvert
)
6629 exp
->e2
= exp
->e2
->implicitCastTo(sc
, tb1next
);
6630 exp
->type
= tb1next
->arrayOf();
6632 if (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
6634 // Make e2 into [e2]
6635 exp
->e2
= new ArrayLiteralExp(exp
->e2
->loc
, exp
->e2
);
6636 exp
->e2
->type
= exp
->type
;
6638 result
= exp
->optimize(WANTvalue
);
6642 // Check for: element ~ array
6643 if ((tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
) && tb1
->ty
!= Tvoid
)
6645 if (exp
->e2
->op
== TOKarrayliteral
)
6647 exp
->e1
= exp
->e1
->isLvalue() ? callCpCtor(sc
, exp
->e1
) : valueNoDtor(exp
->e1
);
6649 else if (exp
->e2
->op
== TOKstring
)
6654 if (exp
->e1
->checkPostblit(sc
, tb1
))
6658 if (exp
->e2
->op
== TOKarrayliteral
&& exp
->e2
->implicitConvTo(tb1
->arrayOf()))
6660 exp
->e2
= exp
->e2
->implicitCastTo(sc
, tb1
->arrayOf());
6661 exp
->type
= tb1
->arrayOf();
6664 if (exp
->e1
->implicitConvTo(tb2next
) >= MATCHconvert
)
6666 exp
->e1
= exp
->e1
->implicitCastTo(sc
, tb2next
);
6667 exp
->type
= tb2next
->arrayOf();
6669 if (tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
)
6671 // Make e1 into [e1]
6672 exp
->e1
= new ArrayLiteralExp(exp
->e1
->loc
, exp
->e1
);
6673 exp
->e1
->type
= exp
->type
;
6675 result
= exp
->optimize(WANTvalue
);
6681 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
) &&
6682 (tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
) &&
6683 (tb1next
->mod
|| tb2next
->mod
) &&
6684 (tb1next
->mod
!= tb2next
->mod
)
6687 Type
*t1
= tb1next
->mutableOf()->constOf()->arrayOf();
6688 Type
*t2
= tb2next
->mutableOf()->constOf()->arrayOf();
6689 if (exp
->e1
->op
== TOKstring
&& !((StringExp
*)exp
->e1
)->committed
)
6692 exp
->e1
= exp
->e1
->castTo(sc
, t1
);
6693 if (exp
->e2
->op
== TOKstring
&& !((StringExp
*)exp
->e2
)->committed
)
6696 exp
->e2
= exp
->e2
->castTo(sc
, t2
);
6699 if (Expression
*ex
= typeCombine(exp
, sc
))
6704 exp
->type
= exp
->type
->toHeadMutable();
6706 Type
*tb
= exp
->type
->toBasetype();
6707 if (tb
->ty
== Tsarray
)
6708 exp
->type
= tb
->nextOf()->arrayOf();
6709 if (exp
->type
->ty
== Tarray
&& tb1next
&& tb2next
&&
6710 tb1next
->mod
!= tb2next
->mod
)
6712 exp
->type
= exp
->type
->nextOf()->toHeadMutable()->arrayOf();
6714 if (Type
*tbn
= tb
->nextOf())
6716 if (exp
->checkPostblit(sc
, tbn
))
6719 Type
*t1
= exp
->e1
->type
->toBasetype();
6720 Type
*t2
= exp
->e2
->type
->toBasetype();
6721 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
6722 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
6724 // Normalize to ArrayLiteralExp or StringExp as far as possible
6725 e
= exp
->optimize(WANTvalue
);
6729 //printf("(%s) ~ (%s)\n", exp->e1->toChars(), exp->e2->toChars());
6730 result
= exp
->incompatibleTypes();
6736 void visit(MulExp
*exp
)
6744 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6749 Expression
*e
= exp
->op_overload(sc
);
6756 if (Expression
*ex
= typeCombine(exp
, sc
))
6762 Type
*tb
= exp
->type
->toBasetype();
6763 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6765 if (!isArrayOpValid(exp
))
6767 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6774 if (exp
->checkArithmeticBin())
6777 if (exp
->type
->isfloating())
6779 Type
*t1
= exp
->e1
->type
;
6780 Type
*t2
= exp
->e2
->type
;
6786 else if (t2
->isreal())
6790 else if (t1
->isimaginary())
6792 if (t2
->isimaginary())
6795 switch (t1
->toBasetype()->ty
)
6798 exp
->type
= Type::tfloat32
;
6802 exp
->type
= Type::tfloat64
;
6806 exp
->type
= Type::tfloat80
;
6814 exp
->e1
->type
= exp
->type
;
6815 exp
->e2
->type
= exp
->type
;
6816 e
= new NegExp(exp
->loc
, exp
);
6817 e
= semantic(e
, sc
);
6822 exp
->type
= t2
; // t2 is complex
6824 else if (t2
->isimaginary())
6826 exp
->type
= t1
; // t1 is complex
6829 else if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
6831 result
= exp
->incompatibleTypes();
6837 void visit(DivExp
*exp
)
6845 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6849 Expression
*e
= exp
->op_overload(sc
);
6856 if (Expression
*ex
= typeCombine(exp
, sc
))
6862 Type
*tb
= exp
->type
->toBasetype();
6863 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6865 if (!isArrayOpValid(exp
))
6867 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6874 if (exp
->checkArithmeticBin())
6877 if (exp
->type
->isfloating())
6879 Type
*t1
= exp
->e1
->type
;
6880 Type
*t2
= exp
->e2
->type
;
6885 if (t2
->isimaginary())
6889 e
= new NegExp(exp
->loc
, exp
);
6890 e
= semantic(e
, sc
);
6895 else if (t2
->isreal())
6899 else if (t1
->isimaginary())
6901 if (t2
->isimaginary())
6903 switch (t1
->toBasetype()->ty
)
6906 exp
->type
= Type::tfloat32
;
6910 exp
->type
= Type::tfloat64
;
6914 exp
->type
= Type::tfloat80
;
6922 exp
->type
= t2
; // t2 is complex
6924 else if (t2
->isimaginary())
6926 exp
->type
= t1
; // t1 is complex
6929 else if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
6931 result
= exp
->incompatibleTypes();
6937 void visit(ModExp
*exp
)
6945 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6950 Expression
*e
= exp
->op_overload(sc
);
6957 if (Expression
*ex
= typeCombine(exp
, sc
))
6963 Type
*tb
= exp
->type
->toBasetype();
6964 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6966 if (!isArrayOpValid(exp
))
6968 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6974 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
6976 result
= exp
->incompatibleTypes();
6980 if (exp
->checkArithmeticBin())
6983 if (exp
->type
->isfloating())
6985 exp
->type
= exp
->e1
->type
;
6986 if (exp
->e2
->type
->iscomplex())
6988 exp
->error("cannot perform modulo complex arithmetic");
6995 Module
*loadStdMath()
6997 static Import
*impStdMath
= NULL
;
7000 Identifiers
*a
= new Identifiers();
7002 Import
*s
= new Import(Loc(), a
, Id::math
, NULL
, false);
7006 s
->mod
->importAll(NULL
);
7007 s
->mod
->semantic(NULL
);
7011 return impStdMath
->mod
;
7014 void visit(PowExp
*exp
)
7022 //printf("PowExp::semantic() %s\n", exp->toChars());
7023 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7028 Expression
*e
= exp
->op_overload(sc
);
7035 if (Expression
*ex
= typeCombine(exp
, sc
))
7041 Type
*tb
= exp
->type
->toBasetype();
7042 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7044 if (!isArrayOpValid(exp
))
7046 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7053 if (exp
->checkArithmeticBin())
7056 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7058 result
= exp
->incompatibleTypes();
7062 // For built-in numeric types, there are several cases.
7063 // TODO: backend support, especially for e1 ^^ 2.
7065 // First, attempt to fold the expression.
7066 e
= exp
->optimize(WANTvalue
);
7067 if (e
->op
!= TOKpow
)
7069 e
= semantic(e
, sc
);
7074 // Determine if we're raising to an integer power.
7075 sinteger_t intpow
= 0;
7076 if (exp
->e2
->op
== TOKint64
&& ((sinteger_t
)exp
->e2
->toInteger() == 2 || (sinteger_t
)exp
->e2
->toInteger() == 3))
7077 intpow
= exp
->e2
->toInteger();
7078 else if (exp
->e2
->op
== TOKfloat64
&& (exp
->e2
->toReal() == ldouble((sinteger_t
)exp
->e2
->toReal())))
7079 intpow
= (sinteger_t
)(exp
->e2
->toReal());
7081 // Deal with x^^2, x^^3 immediately, since they are of practical importance.
7082 if (intpow
== 2 || intpow
== 3)
7084 // Replace x^^2 with (tmp = x, tmp*tmp)
7085 // Replace x^^3 with (tmp = x, tmp*tmp*tmp)
7086 VarDeclaration
*tmp
= copyToTemp(0, "__powtmp", exp
->e1
);
7087 Expression
*de
= new DeclarationExp(exp
->loc
, tmp
);
7088 Expression
*ve
= new VarExp(exp
->loc
, tmp
);
7090 /* Note that we're reusing ve. This should be ok.
7092 Expression
*me
= new MulExp(exp
->loc
, ve
, ve
);
7094 me
= new MulExp(exp
->loc
, me
, ve
);
7095 e
= new CommaExp(exp
->loc
, de
, me
);
7096 e
= semantic(e
, sc
);
7101 Module
*mmath
= loadStdMath();
7104 //exp->error("requires std.math for ^^ operators");
7107 // Leave handling of PowExp to the backend, or throw
7108 // an error gracefully if no backend support exists.
7109 if (Expression
*ex
= typeCombine(exp
, sc
))
7117 e
= new ScopeExp(exp
->loc
, mmath
);
7119 if (exp
->e2
->op
== TOKfloat64
&& exp
->e2
->toReal() == CTFloat::half
)
7121 // Replace e1 ^^ 0.5 with .std.math.sqrt(x)
7122 e
= new CallExp(exp
->loc
, new DotIdExp(exp
->loc
, e
, Id::_sqrt
), exp
->e1
);
7126 // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
7127 e
= new CallExp(exp
->loc
, new DotIdExp(exp
->loc
, e
, Id::_pow
), exp
->e1
, exp
->e2
);
7129 e
= semantic(e
, sc
);
7133 void visit(ShlExp
*exp
)
7135 //printf("ShlExp::semantic(), type = %p\n", exp->type);
7142 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7147 Expression
*e
= exp
->op_overload(sc
);
7154 if (exp
->checkIntegralBin())
7156 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7158 result
= exp
->incompatibleTypes();
7161 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7162 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7163 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7165 exp
->type
= exp
->e1
->type
;
7169 void visit(ShrExp
*exp
)
7177 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7182 Expression
*e
= exp
->op_overload(sc
);
7189 if (exp
->checkIntegralBin())
7191 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7193 result
= exp
->incompatibleTypes();
7196 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7197 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7198 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7200 exp
->type
= exp
->e1
->type
;
7204 void visit(UshrExp
*exp
)
7212 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7217 Expression
*e
= exp
->op_overload(sc
);
7224 if (exp
->checkIntegralBin())
7226 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7228 result
= exp
->incompatibleTypes();
7231 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7232 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7233 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7235 exp
->type
= exp
->e1
->type
;
7239 void visit(AndExp
*exp
)
7247 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7252 Expression
*e
= exp
->op_overload(sc
);
7259 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7260 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7262 exp
->type
= exp
->e1
->type
;
7267 if (Expression
*ex
= typeCombine(exp
, sc
))
7273 Type
*tb
= exp
->type
->toBasetype();
7274 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7276 if (!isArrayOpValid(exp
))
7278 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7285 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7287 result
= exp
->incompatibleTypes();
7290 if (exp
->checkIntegralBin())
7296 void visit(OrExp
*exp
)
7304 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7309 Expression
*e
= exp
->op_overload(sc
);
7316 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7317 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7319 exp
->type
= exp
->e1
->type
;
7324 if (Expression
*ex
= typeCombine(exp
, sc
))
7330 Type
*tb
= exp
->type
->toBasetype();
7331 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7333 if (!isArrayOpValid(exp
))
7335 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7342 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7344 result
= exp
->incompatibleTypes();
7347 if (exp
->checkIntegralBin())
7353 void visit(XorExp
*exp
)
7361 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7366 Expression
*e
= exp
->op_overload(sc
);
7373 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7374 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7376 exp
->type
= exp
->e1
->type
;
7381 if (Expression
*ex
= typeCombine(exp
, sc
))
7387 Type
*tb
= exp
->type
->toBasetype();
7388 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7390 if (!isArrayOpValid(exp
))
7392 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7399 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7401 result
= exp
->incompatibleTypes();
7404 if (exp
->checkIntegralBin())
7410 void visit(OrOrExp
*exp
)
7418 setNoderefOperands(exp
);
7420 // same as for AndAnd
7421 Expression
*e1x
= semantic(exp
->e1
, sc
);
7423 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7424 if (e1x
->op
== TOKtype
)
7425 e1x
= resolveAliasThis(sc
, e1x
);
7427 e1x
= resolveProperties(sc
, e1x
);
7428 e1x
= e1x
->toBoolean(sc
);
7429 unsigned cs1
= sc
->callSuper
;
7431 if (sc
->flags
& SCOPEcondition
)
7433 /* If in static if, don't evaluate e2 if we don't have to.
7435 e1x
= e1x
->optimize(WANTvalue
);
7436 if (e1x
->isBool(true))
7438 result
= new IntegerExp(exp
->loc
, 1, Type::tbool
);
7443 Expression
*e2x
= semantic(exp
->e2
, sc
);
7444 sc
->mergeCallSuper(exp
->loc
, cs1
);
7446 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7447 if (e2x
->op
== TOKtype
)
7448 e2x
= resolveAliasThis(sc
, e2x
);
7450 e2x
= resolveProperties(sc
, e2x
);
7452 bool f1
= checkNonAssignmentArrayOp(e1x
);
7453 bool f2
= checkNonAssignmentArrayOp(e2x
);
7457 // Unless the right operand is 'void', the expression is converted to 'bool'.
7458 if (e2x
->type
->ty
!= Tvoid
)
7459 e2x
= e2x
->toBoolean(sc
);
7461 if (e2x
->op
== TOKtype
|| e2x
->op
== TOKscope
)
7463 exp
->error("%s is not an expression", exp
->e2
->toChars());
7466 if (e1x
->op
== TOKerror
)
7471 if (e2x
->op
== TOKerror
)
7477 // The result type is 'bool', unless the right operand has type 'void'.
7478 if (e2x
->type
->ty
== Tvoid
)
7479 exp
->type
= Type::tvoid
;
7481 exp
->type
= Type::tbool
;
7488 void visit(AndAndExp
*exp
)
7496 setNoderefOperands(exp
);
7499 Expression
*e1x
= semantic(exp
->e1
, sc
);
7501 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7502 if (e1x
->op
== TOKtype
)
7503 e1x
= resolveAliasThis(sc
, e1x
);
7505 e1x
= resolveProperties(sc
, e1x
);
7506 e1x
= e1x
->toBoolean(sc
);
7507 unsigned cs1
= sc
->callSuper
;
7509 if (sc
->flags
& SCOPEcondition
)
7511 /* If in static if, don't evaluate e2 if we don't have to.
7513 e1x
= e1x
->optimize(WANTvalue
);
7514 if (e1x
->isBool(false))
7516 result
= new IntegerExp(exp
->loc
, 0, Type::tbool
);
7521 Expression
*e2x
= semantic(exp
->e2
, sc
);
7522 sc
->mergeCallSuper(exp
->loc
, cs1
);
7524 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7525 if (e2x
->op
== TOKtype
)
7526 e2x
= resolveAliasThis(sc
, e2x
);
7528 e2x
= resolveProperties(sc
, e2x
);
7530 bool f1
= checkNonAssignmentArrayOp(e1x
);
7531 bool f2
= checkNonAssignmentArrayOp(e2x
);
7535 // Unless the right operand is 'void', the expression is converted to 'bool'.
7536 if (e2x
->type
->ty
!= Tvoid
)
7537 e2x
= e2x
->toBoolean(sc
);
7539 if (e2x
->op
== TOKtype
|| e2x
->op
== TOKscope
)
7541 exp
->error("%s is not an expression", exp
->e2
->toChars());
7544 if (e1x
->op
== TOKerror
)
7549 if (e2x
->op
== TOKerror
)
7555 // The result type is 'bool', unless the right operand has type 'void'.
7556 if (e2x
->type
->ty
== Tvoid
)
7557 exp
->type
= Type::tvoid
;
7559 exp
->type
= Type::tbool
;
7566 void visit(InExp
*exp
)
7574 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7579 Expression
*e
= exp
->op_overload(sc
);
7586 Type
*t2b
= exp
->e2
->type
->toBasetype();
7591 TypeAArray
*ta
= (TypeAArray
*)t2b
;
7593 // Special handling for array keys
7594 if (!arrayTypeCompatible(exp
->e1
->loc
, exp
->e1
->type
, ta
->index
))
7596 // Convert key to type of key
7597 exp
->e1
= exp
->e1
->implicitCastTo(sc
, ta
->index
);
7600 semanticTypeInfo(sc
, ta
->index
);
7602 // Return type is pointer to value
7603 exp
->type
= ta
->nextOf()->pointerTo();
7608 result
= exp
->incompatibleTypes();
7617 void visit(RemoveExp
*e
)
7619 if (Expression
*ex
= binSemantic(e
, sc
))
7627 void visit(CmpExp
*exp
)
7635 setNoderefOperands(exp
);
7637 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7642 Type
*t1
= exp
->e1
->type
->toBasetype();
7643 Type
*t2
= exp
->e2
->type
->toBasetype();
7644 if ((t1
->ty
== Tclass
&& exp
->e2
->op
== TOKnull
) ||
7645 (t2
->ty
== Tclass
&& exp
->e1
->op
== TOKnull
))
7647 exp
->error("do not use null when comparing class types");
7651 Expression
*e
= exp
->op_overload(sc
);
7654 if (!e
->type
->isscalar() && e
->type
->equals(exp
->e1
->type
))
7656 exp
->error("recursive opCmp expansion");
7659 if (e
->op
== TOKcall
)
7661 e
= new CmpExp(exp
->op
, exp
->loc
, e
, new IntegerExp(exp
->loc
, 0, Type::tint32
));
7662 e
= semantic(e
, sc
);
7668 if (Expression
*ex
= typeCombine(exp
, sc
))
7674 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7675 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7679 exp
->type
= Type::tbool
;
7681 // Special handling for array comparisons
7682 t1
= exp
->e1
->type
->toBasetype();
7683 t2
= exp
->e2
->type
->toBasetype();
7684 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
|| t1
->ty
== Tpointer
) &&
7685 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
|| t2
->ty
== Tpointer
))
7687 Type
*t1next
= t1
->nextOf();
7688 Type
*t2next
= t2
->nextOf();
7689 if (t1next
->implicitConvTo(t2next
) < MATCHconst
&&
7690 t2next
->implicitConvTo(t1next
) < MATCHconst
&&
7691 (t1next
->ty
!= Tvoid
&& t2next
->ty
!= Tvoid
))
7693 exp
->error("array comparison type mismatch, %s vs %s", t1next
->toChars(), t2next
->toChars());
7696 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
7697 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
7699 semanticTypeInfo(sc
, t1
->nextOf());
7702 else if (t1
->ty
== Tstruct
|| t2
->ty
== Tstruct
||
7703 (t1
->ty
== Tclass
&& t2
->ty
== Tclass
))
7705 if (t2
->ty
== Tstruct
)
7706 exp
->error("need member function opCmp() for %s %s to compare", t2
->toDsymbol(sc
)->kind(), t2
->toChars());
7708 exp
->error("need member function opCmp() for %s %s to compare", t1
->toDsymbol(sc
)->kind(), t1
->toChars());
7711 else if (t1
->iscomplex() || t2
->iscomplex())
7713 exp
->error("compare not defined for complex operands");
7716 else if (t1
->ty
== Taarray
|| t2
->ty
== Taarray
)
7718 exp
->error("%s is not defined for associative arrays", Token::toChars(exp
->op
));
7721 else if (!Target::isVectorOpSupported(t1
, exp
->op
, t2
))
7723 result
= exp
->incompatibleTypes();
7728 bool r1
= exp
->e1
->checkValue();
7729 bool r2
= exp
->e2
->checkValue();
7737 // Refer rel_integral[] table
7738 case TOKunord
: altop
= TOKerror
; break;
7739 case TOKlg
: altop
= TOKnotequal
; break;
7740 case TOKleg
: altop
= TOKerror
; break;
7741 case TOKule
: altop
= TOKle
; break;
7742 case TOKul
: altop
= TOKlt
; break;
7743 case TOKuge
: altop
= TOKge
; break;
7744 case TOKug
: altop
= TOKgt
; break;
7745 case TOKue
: altop
= TOKequal
; break;
7746 default: altop
= TOKreserved
; break;
7748 if (altop
== TOKerror
&&
7749 (t1
->ty
== Tarray
|| t1
->ty
== Tsarray
||
7750 t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
7752 exp
->error("'%s' is not defined for array comparisons", Token::toChars(exp
->op
));
7755 if (altop
!= TOKreserved
)
7757 if (!t1
->isfloating())
7759 if (altop
== TOKerror
)
7761 const char *s
= exp
->op
== TOKunord
? "false" : "true";
7762 exp
->error("floating point operator '%s' always returns %s for non-floating comparisons",
7763 Token::toChars(exp
->op
), s
);
7767 exp
->error("use '%s' for non-floating comparisons rather than floating point operator '%s'",
7768 Token::toChars(altop
), Token::toChars(exp
->op
));
7773 exp
->error("use std.math.isNaN to deal with NaN operands rather than floating point operator '%s'",
7774 Token::toChars(exp
->op
));
7779 //printf("CmpExp: %s, type = %s\n", e->toChars(), e->type->toChars());
7783 void visit(EqualExp
*exp
)
7785 //printf("EqualExp::semantic('%s')\n", toChars());
7792 setNoderefOperands(exp
);
7794 if (Expression
*e
= binSemanticProp(exp
, sc
))
7799 if (exp
->e1
->op
== TOKtype
|| exp
->e2
->op
== TOKtype
)
7801 result
= exp
->incompatibleTypes();
7806 Type
*t1
= exp
->e1
->type
;
7807 Type
*t2
= exp
->e2
->type
;
7808 if (t1
->ty
== Tenum
&& t2
->ty
== Tenum
&& !t1
->equivalent(t2
))
7809 exp
->deprecation("Comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`",
7810 t1
->toChars(), t2
->toChars());
7813 /* Before checking for operator overloading, check to see if we're
7814 * comparing the addresses of two statics. If so, we can just see
7815 * if they are the same symbol.
7817 if (exp
->e1
->op
== TOKaddress
&& exp
->e2
->op
== TOKaddress
)
7819 AddrExp
*ae1
= (AddrExp
*)exp
->e1
;
7820 AddrExp
*ae2
= (AddrExp
*)exp
->e2
;
7821 if (ae1
->e1
->op
== TOKvar
&& ae2
->e1
->op
== TOKvar
)
7823 VarExp
*ve1
= (VarExp
*)ae1
->e1
;
7824 VarExp
*ve2
= (VarExp
*)ae2
->e1
;
7826 if (ve1
->var
== ve2
->var
)
7828 // They are the same, result is 'true' for ==, 'false' for !=
7829 result
= new IntegerExp(exp
->loc
, (exp
->op
== TOKequal
), Type::tbool
);
7835 if (Expression
*e
= exp
->op_overload(sc
))
7841 if (Expression
*e
= typeCombine(exp
, sc
))
7847 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7848 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7852 exp
->type
= Type::tbool
;
7854 // Special handling for array comparisons
7855 if (!arrayTypeCompatible(exp
->loc
, exp
->e1
->type
, exp
->e2
->type
))
7857 if (exp
->e1
->type
!= exp
->e2
->type
&& exp
->e1
->type
->isfloating() && exp
->e2
->type
->isfloating())
7859 // Cast both to complex
7860 exp
->e1
= exp
->e1
->castTo(sc
, Type::tcomplex80
);
7861 exp
->e2
= exp
->e2
->castTo(sc
, Type::tcomplex80
);
7864 if (exp
->e1
->type
->toBasetype()->ty
== Taarray
)
7865 semanticTypeInfo(sc
, exp
->e1
->type
->toBasetype());
7867 Type
*t1
= exp
->e1
->type
->toBasetype();
7868 Type
*t2
= exp
->e2
->type
->toBasetype();
7870 if (!Target::isVectorOpSupported(t1
, exp
->op
, t2
))
7872 result
= exp
->incompatibleTypes();
7879 void visit(IdentityExp
*exp
)
7887 setNoderefOperands(exp
);
7889 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7895 if (Expression
*ex
= typeCombine(exp
, sc
))
7901 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7902 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7906 exp
->type
= Type::tbool
;
7908 if (exp
->e1
->type
!= exp
->e2
->type
&& exp
->e1
->type
->isfloating() && exp
->e2
->type
->isfloating())
7910 // Cast both to complex
7911 exp
->e1
= exp
->e1
->castTo(sc
, Type::tcomplex80
);
7912 exp
->e2
= exp
->e2
->castTo(sc
, Type::tcomplex80
);
7915 Type
*tb1
= exp
->e1
->type
->toBasetype();
7916 Type
*tb2
= exp
->e2
->type
->toBasetype();
7917 if (!Target::isVectorOpSupported(tb1
, exp
->op
, tb2
))
7919 result
= exp
->incompatibleTypes();
7926 void visit(CondExp
*exp
)
7934 if (exp
->econd
->op
== TOKdotid
)
7935 ((DotIdExp
*)exp
->econd
)->noderef
= true;
7937 Expression
*ec
= semantic(exp
->econd
, sc
);
7938 ec
= resolveProperties(sc
, ec
);
7939 ec
= ec
->toBoolean(sc
);
7941 unsigned cs0
= sc
->callSuper
;
7942 unsigned *fi0
= sc
->saveFieldInit();
7943 Expression
*e1x
= semantic(exp
->e1
, sc
);
7944 e1x
= resolveProperties(sc
, e1x
);
7946 unsigned cs1
= sc
->callSuper
;
7947 unsigned *fi1
= sc
->fieldinit
;
7948 sc
->callSuper
= cs0
;
7949 sc
->fieldinit
= fi0
;
7950 Expression
*e2x
= semantic(exp
->e2
, sc
);
7951 e2x
= resolveProperties(sc
, e2x
);
7953 sc
->mergeCallSuper(exp
->loc
, cs1
);
7954 sc
->mergeFieldInit(exp
->loc
, fi1
);
7956 if (ec
->op
== TOKerror
)
7961 if (ec
->type
== Type::terror
)
7965 if (e1x
->op
== TOKerror
)
7970 if (e1x
->type
== Type::terror
)
7974 if (e2x
->op
== TOKerror
)
7979 if (e2x
->type
== Type::terror
)
7983 bool f0
= checkNonAssignmentArrayOp(exp
->econd
);
7984 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7985 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7989 Type
*t1
= exp
->e1
->type
;
7990 Type
*t2
= exp
->e2
->type
;
7991 // If either operand is void the result is void, we have to cast both
7992 // the expression to void so that we explicitly discard the expression
7993 // value if any (bugzilla 16598)
7994 if (t1
->ty
== Tvoid
|| t2
->ty
== Tvoid
)
7996 exp
->type
= Type::tvoid
;
7997 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
);
7998 exp
->e2
= exp
->e2
->castTo(sc
, exp
->type
);
8004 if (Expression
*ex
= typeCombine(exp
, sc
))
8009 switch (exp
->e1
->type
->toBasetype()->ty
)
8014 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
8017 switch (exp
->e2
->type
->toBasetype()->ty
)
8022 exp
->e1
= exp
->e1
->castTo(sc
, exp
->e2
->type
);
8025 if (exp
->type
->toBasetype()->ty
== Tarray
)
8027 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
);
8028 exp
->e2
= exp
->e2
->castTo(sc
, exp
->type
);
8031 exp
->type
= exp
->type
->merge2();
8033 /* Bugzilla 14696: If either e1 or e2 contain temporaries which need dtor,
8034 * make them conditional.
8036 * cond ? (__tmp1 = ..., __tmp1) : (__tmp2 = ..., __tmp2)
8038 * (auto __cond = cond) ? (... __tmp1) : (... __tmp2)
8039 * and replace edtors of __tmp1 and __tmp2 with:
8040 * __tmp1->edtor --> __cond && __tmp1.dtor()
8041 * __tmp2->edtor --> __cond || __tmp2.dtor()
8048 void visit(FileInitExp
*e
)
8050 //printf("FileInitExp::semantic()\n");
8051 e
->type
= Type::tstring
;
8055 void visit(LineInitExp
*e
)
8057 e
->type
= Type::tint32
;
8061 void visit(ModuleInitExp
*e
)
8063 //printf("ModuleInitExp::semantic()\n");
8064 e
->type
= Type::tstring
;
8068 void visit(FuncInitExp
*e
)
8070 //printf("FuncInitExp::semantic()\n");
8071 e
->type
= Type::tstring
;
8074 result
= e
->resolveLoc(Loc(), sc
);
8080 void visit(PrettyFuncInitExp
*e
)
8082 //printf("PrettyFuncInitExp::semantic()\n");
8083 e
->type
= Type::tstring
;
8086 result
= e
->resolveLoc(Loc(), sc
);
8093 /**********************************
8094 * Try to run semantic routines.
8095 * If they fail, return NULL.
8097 Expression
*trySemantic(Expression
*exp
, Scope
* sc
)
8099 //printf("+trySemantic(%s)\n", toChars());
8100 unsigned errors
= global
.startGagging();
8101 Expression
*e
= semantic(exp
, sc
);
8102 if (global
.endGagging(errors
))
8106 //printf("-trySemantic(%s)\n", toChars());
8110 /**************************
8111 * Helper function for easy error propagation.
8112 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8114 Expression
*unaSemantic(UnaExp
*e
, Scope
*sc
)
8116 Expression
*e1x
= semantic(e
->e1
, sc
);
8117 if (e1x
->op
== TOKerror
)
8123 /**************************
8124 * Helper function for easy error propagation.
8125 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8127 Expression
*binSemantic(BinExp
*e
, Scope
*sc
)
8129 Expression
*e1x
= semantic(e
->e1
, sc
);
8130 Expression
*e2x
= semantic(e
->e2
, sc
);
8132 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
8133 if (e1x
->op
== TOKtype
)
8134 e1x
= resolveAliasThis(sc
, e1x
);
8135 if (e2x
->op
== TOKtype
)
8136 e2x
= resolveAliasThis(sc
, e2x
);
8138 if (e1x
->op
== TOKerror
)
8140 if (e2x
->op
== TOKerror
)
8147 Expression
*binSemanticProp(BinExp
*e
, Scope
*sc
)
8149 if (Expression
*ex
= binSemantic(e
, sc
))
8151 Expression
*e1x
= resolveProperties(sc
, e
->e1
);
8152 Expression
*e2x
= resolveProperties(sc
, e
->e2
);
8153 if (e1x
->op
== TOKerror
)
8155 if (e2x
->op
== TOKerror
)
8162 // entrypoint for semantic ExpressionSemanticVisitor
8163 Expression
*semantic(Expression
*e
, Scope
*sc
)
8165 ExpressionSemanticVisitor v
= ExpressionSemanticVisitor(sc
);
8170 Expression
*semanticX(DotIdExp
*exp
, Scope
*sc
)
8172 //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
8173 if (Expression
*ex
= unaSemantic(exp
, sc
))
8176 if (exp
->ident
== Id::_mangleof
)
8180 switch (exp
->e1
->op
)
8183 ds
= ((ScopeExp
*)exp
->e1
)->sds
;
8186 ds
= ((VarExp
*)exp
->e1
)->var
;
8189 ds
= ((DotVarExp
*)exp
->e1
)->var
;
8191 case TOKoverloadset
:
8192 ds
= ((OverExp
*)exp
->e1
)->vars
;
8196 TemplateExp
*te
= (TemplateExp
*)exp
->e1
;
8197 ds
= te
->fd
? (Dsymbol
*)te
->fd
: te
->td
;
8202 if (FuncDeclaration
*f
= ds
->isFuncDeclaration())
8204 if (f
->checkForwardRef(exp
->loc
))
8205 return new ErrorExp();
8208 mangleToBuffer(ds
, &buf
);
8209 const char *s
= buf
.extractString();
8210 Expression
*e
= new StringExp(exp
->loc
, const_cast<char*>(s
), strlen(s
));
8211 e
= semantic(e
, sc
);
8219 if (exp
->e1
->op
== TOKvar
&& exp
->e1
->type
->toBasetype()->ty
== Tsarray
&& exp
->ident
== Id::length
)
8221 // bypass checkPurity
8222 return exp
->e1
->type
->dotExp(sc
, exp
->e1
, exp
->ident
, exp
->noderef
? 2 : 0);
8225 if (exp
->e1
->op
== TOKdot
)
8230 exp
->e1
= resolvePropertiesX(sc
, exp
->e1
);
8232 if (exp
->e1
->op
== TOKtuple
&& exp
->ident
== Id::offsetof
)
8234 /* 'distribute' the .offsetof to each of the tuple elements.
8236 TupleExp
*te
= (TupleExp
*)exp
->e1
;
8237 Expressions
*exps
= new Expressions();
8238 exps
->setDim(te
->exps
->dim
);
8239 for (size_t i
= 0; i
< exps
->dim
; i
++)
8241 Expression
*e
= (*te
->exps
)[i
];
8242 e
= semantic(e
, sc
);
8243 e
= new DotIdExp(e
->loc
, e
, Id::offsetof
);
8246 // Don't evaluate te->e0 in runtime
8247 Expression
*e
= new TupleExp(exp
->loc
, NULL
, exps
);
8248 e
= semantic(e
, sc
);
8251 if (exp
->e1
->op
== TOKtuple
&& exp
->ident
== Id::length
)
8253 TupleExp
*te
= (TupleExp
*)exp
->e1
;
8254 // Don't evaluate te->e0 in runtime
8255 Expression
*e
= new IntegerExp(exp
->loc
, te
->exps
->dim
, Type::tsize_t
);
8259 // Bugzilla 14416: Template has no built-in properties except for 'stringof'.
8260 if ((exp
->e1
->op
== TOKdottd
|| exp
->e1
->op
== TOKtemplate
) && exp
->ident
!= Id::stringof
)
8262 exp
->error("template %s does not have property '%s'", exp
->e1
->toChars(), exp
->ident
->toChars());
8263 return new ErrorExp();
8268 exp
->error("expression %s does not have property '%s'", exp
->e1
->toChars(), exp
->ident
->toChars());
8269 return new ErrorExp();
8275 // Resolve e1.ident without seeing UFCS.
8276 // If flag == 1, stop "not a property" error and return NULL.
8277 Expression
*semanticY(DotIdExp
*exp
, Scope
*sc
, int flag
)
8279 //printf("DotIdExp::semanticY(this = %p, '%s')\n", this, toChars());
8281 //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }
8283 /* Special case: rewrite this.id and super.id
8284 * to be classtype.id and baseclasstype.id
8285 * if we have no this pointer.
8287 if ((exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
) && !hasThis(sc
))
8289 if (AggregateDeclaration
*ad
= sc
->getStructClassScope())
8291 if (exp
->e1
->op
== TOKthis
)
8293 exp
->e1
= new TypeExp(exp
->e1
->loc
, ad
->type
);
8297 ClassDeclaration
*cd
= ad
->isClassDeclaration();
8298 if (cd
&& cd
->baseClass
)
8299 exp
->e1
= new TypeExp(exp
->e1
->loc
, cd
->baseClass
->type
);
8304 Expression
*e
= semanticX(exp
, sc
);
8310 if (exp
->e1
->op
== TOKdot
)
8312 DotExp
*de
= (DotExp
*)exp
->e1
;
8322 Type
*t1b
= exp
->e1
->type
->toBasetype();
8324 if (eright
->op
== TOKscope
) // also used for template alias's
8326 ScopeExp
*ie
= (ScopeExp
*)eright
;
8327 int flags
= SearchLocalsOnly
;
8329 /* Disable access to another module's private imports.
8330 * The check for 'is sds our current module' is because
8331 * the current module should have access to its own imports.
8333 if (ie
->sds
->isModule() && ie
->sds
!= sc
->_module
)
8334 flags
|= IgnorePrivateImports
;
8335 if (sc
->flags
& SCOPEignoresymbolvisibility
)
8336 flags
|= IgnoreSymbolVisibility
;
8337 Dsymbol
*s
= ie
->sds
->search(exp
->loc
, exp
->ident
, flags
);
8338 /* Check for visibility before resolving aliases because public
8339 * aliases to private symbols are public.
8341 if (s
&& !(sc
->flags
& SCOPEignoresymbolvisibility
) && !symbolIsVisible(sc
->_module
, s
))
8343 if (s
->isDeclaration())
8344 ::error(exp
->loc
, "%s is not visible from module %s", s
->toPrettyChars(), sc
->_module
->toChars());
8346 ::deprecation(exp
->loc
, "%s is not visible from module %s", s
->toPrettyChars(), sc
->_module
->toChars());
8351 if (Package
*p
= s
->isPackage())
8352 checkAccess(exp
->loc
, sc
, p
);
8354 // if 's' is a tuple variable, the tuple is returned.
8357 exp
->checkDeprecated(sc
, s
);
8359 EnumMember
*em
= s
->isEnumMember();
8362 return em
->getVarExp(exp
->loc
, sc
);
8365 VarDeclaration
*v
= s
->isVarDeclaration();
8368 //printf("DotIdExp:: Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
8370 (!v
->type
->deco
&& v
->inuse
))
8373 exp
->error("circular reference to %s '%s'", v
->kind(), v
->toPrettyChars());
8375 exp
->error("forward reference to %s '%s'", v
->kind(), v
->toPrettyChars());
8376 return new ErrorExp();
8378 if (v
->type
->ty
== Terror
)
8379 return new ErrorExp();
8381 if ((v
->storage_class
& STCmanifest
) && v
->_init
&& !exp
->wantsym
)
8383 /* Normally, the replacement of a symbol with its initializer is supposed to be in semantic2().
8384 * Introduced by https://github.com/dlang/dmd/pull/5588 which should probably
8385 * be reverted. `wantsym` is the hack to work around the problem.
8389 ::error(exp
->loc
, "circular initialization of %s '%s'", v
->kind(), v
->toPrettyChars());
8390 return new ErrorExp();
8392 e
= v
->expandInitializer(exp
->loc
);
8394 e
= semantic(e
, sc
);
8402 eleft
= new ThisExp(exp
->loc
);
8403 e
= new DotVarExp(exp
->loc
, eleft
, v
);
8404 e
= semantic(e
, sc
);
8408 e
= new VarExp(exp
->loc
, v
);
8410 { e
= new CommaExp(exp
->loc
, eleft
, e
);
8415 return semantic(e
, sc
);
8418 FuncDeclaration
*f
= s
->isFuncDeclaration();
8421 //printf("it's a function\n");
8422 if (!f
->functionSemantic())
8423 return new ErrorExp();
8427 eleft
= new ThisExp(exp
->loc
);
8428 e
= new DotVarExp(exp
->loc
, eleft
, f
, true);
8429 e
= semantic(e
, sc
);
8433 e
= new VarExp(exp
->loc
, f
, true);
8435 { e
= new CommaExp(exp
->loc
, eleft
, e
);
8441 if (TemplateDeclaration
*td
= s
->isTemplateDeclaration())
8444 e
= new DotTemplateExp(exp
->loc
, eleft
, td
);
8446 e
= new TemplateExp(exp
->loc
, td
);
8447 e
= semantic(e
, sc
);
8450 if (OverDeclaration
*od
= s
->isOverDeclaration())
8452 e
= new VarExp(exp
->loc
, od
, true);
8455 e
= new CommaExp(exp
->loc
, eleft
, e
);
8456 e
->type
= Type::tvoid
; // ambiguous type?
8460 OverloadSet
*o
= s
->isOverloadSet();
8462 { //printf("'%s' is an overload set\n", o->toChars());
8463 return new OverExp(exp
->loc
, o
);
8466 if (Type
*t
= s
->getType())
8468 return semantic(new TypeExp(exp
->loc
, t
), sc
);
8471 TupleDeclaration
*tup
= s
->isTupleDeclaration();
8476 e
= new DotVarExp(exp
->loc
, eleft
, tup
);
8477 e
= semantic(e
, sc
);
8480 e
= new TupleExp(exp
->loc
, tup
);
8481 e
= semantic(e
, sc
);
8485 ScopeDsymbol
*sds
= s
->isScopeDsymbol();
8488 //printf("it's a ScopeDsymbol %s\n", exp->ident->toChars());
8489 e
= new ScopeExp(exp
->loc
, sds
);
8490 e
= semantic(e
, sc
);
8492 e
= new DotExp(exp
->loc
, eleft
, e
);
8496 Import
*imp
= s
->isImport();
8499 ie
= new ScopeExp(exp
->loc
, imp
->pkg
);
8500 return semantic(ie
, sc
);
8503 // BUG: handle other cases like in IdentifierExp::semantic()
8506 else if (exp
->ident
== Id::stringof
)
8508 const char *p
= ie
->toChars();
8509 e
= new StringExp(exp
->loc
, const_cast<char *>(p
), strlen(p
));
8510 e
= semantic(e
, sc
);
8513 if (ie
->sds
->isPackage() ||
8514 ie
->sds
->isImport() ||
8515 ie
->sds
->isModule())
8521 s
= ie
->sds
->search_correct(exp
->ident
);
8523 exp
->error("undefined identifier '%s' in %s '%s', did you mean %s '%s'?",
8524 exp
->ident
->toChars(), ie
->sds
->kind(), ie
->sds
->toPrettyChars(), s
->kind(), s
->toChars());
8526 exp
->error("undefined identifier '%s' in %s '%s'",
8527 exp
->ident
->toChars(), ie
->sds
->kind(), ie
->sds
->toPrettyChars());
8528 return new ErrorExp();
8530 else if (t1b
->ty
== Tpointer
&& exp
->e1
->type
->ty
!= Tenum
&&
8531 exp
->ident
!= Id::_init
&& exp
->ident
!= Id::__sizeof
&&
8532 exp
->ident
!= Id::__xalignof
&& exp
->ident
!= Id::offsetof
&&
8533 exp
->ident
!= Id::_mangleof
&& exp
->ident
!= Id::stringof
)
8535 Type
*t1bn
= t1b
->nextOf();
8538 AggregateDeclaration
*ad
= isAggregate(t1bn
);
8539 if (ad
&& !ad
->members
) // Bugzilla 11312
8548 if (flag
&& t1bn
->ty
== Tvoid
)
8550 e
= new PtrExp(exp
->loc
, exp
->e1
);
8551 e
= semantic(e
, sc
);
8552 return e
->type
->dotExp(sc
, e
, exp
->ident
, flag
| (exp
->noderef
? 2 : 0));
8556 if (exp
->e1
->op
== TOKtype
|| exp
->e1
->op
== TOKtemplate
)
8558 e
= exp
->e1
->type
->dotExp(sc
, exp
->e1
, exp
->ident
, flag
| (exp
->noderef
? 2 : 0));
8560 e
= semantic(e
, sc
);
8565 // Resolve e1.ident!tiargs without seeing UFCS.
8566 // If flag == 1, stop "not a property" error and return NULL.
8567 Expression
*semanticY(DotTemplateInstanceExp
*exp
, Scope
*sc
, int flag
)
8569 DotIdExp
*die
= new DotIdExp(exp
->loc
, exp
->e1
, exp
->ti
->name
);
8571 Expression
*e
= semanticX(die
, sc
);
8574 exp
->e1
= die
->e1
; // take back
8576 Type
*t1b
= exp
->e1
->type
->toBasetype();
8577 if (t1b
->ty
== Tarray
|| t1b
->ty
== Tsarray
|| t1b
->ty
== Taarray
||
8578 t1b
->ty
== Tnull
|| (t1b
->isTypeBasic() && t1b
->ty
!= Tvoid
))
8580 /* No built-in type has templatized properties, so do shortcut.
8581 * It is necessary in: 1024.max!"a < b"
8586 e
= semanticY(die
, sc
, flag
);
8587 if (flag
&& e
&& isDotOpDispatch(e
))
8589 /* opDispatch!tiargs would be a function template that needs IFTI,
8590 * so it's not a template
8592 e
= NULL
; /* fall down to UFCS */
8599 if (e
->op
== TOKerror
)
8601 if (e
->op
== TOKdotvar
)
8603 DotVarExp
*dve
= (DotVarExp
*)e
;
8604 if (FuncDeclaration
*fd
= dve
->var
->isFuncDeclaration())
8606 TemplateDeclaration
*td
= fd
->findTemplateDeclRoot();
8609 e
= new DotTemplateExp(dve
->loc
, dve
->e1
, td
);
8610 e
= semantic(e
, sc
);
8613 else if (dve
->var
->isOverDeclaration())
8615 exp
->e1
= dve
->e1
; // pull semantic() result
8616 if (!exp
->findTempDecl(sc
))
8618 if (exp
->ti
->needsTypeInference(sc
))
8620 exp
->ti
->semantic(sc
);
8621 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8622 return new ErrorExp();
8623 Dsymbol
*s
= exp
->ti
->toAlias();
8624 Declaration
*v
= s
->isDeclaration();
8627 if (v
->type
&& !v
->type
->deco
)
8628 v
->type
= v
->type
->semantic(v
->loc
, sc
);
8629 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8630 e
= semantic(e
, sc
);
8633 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8634 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8635 e
= semantic(e
, sc
);
8639 else if (e
->op
== TOKvar
)
8641 VarExp
*ve
= (VarExp
*)e
;
8642 if (FuncDeclaration
*fd
= ve
->var
->isFuncDeclaration())
8644 TemplateDeclaration
*td
= fd
->findTemplateDeclRoot();
8647 e
= new TemplateExp(ve
->loc
, td
);
8648 e
= semantic(e
, sc
);
8651 else if (OverDeclaration
*od
= ve
->var
->isOverDeclaration())
8653 exp
->ti
->tempdecl
= od
;
8654 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8655 e
= semantic(e
, sc
);
8659 if (e
->op
== TOKdottd
)
8661 DotTemplateExp
*dte
= (DotTemplateExp
*)e
;
8662 exp
->e1
= dte
->e1
; // pull semantic() result
8664 exp
->ti
->tempdecl
= dte
->td
;
8665 if (!exp
->ti
->semanticTiargs(sc
))
8666 return new ErrorExp();
8667 if (exp
->ti
->needsTypeInference(sc
))
8669 exp
->ti
->semantic(sc
);
8670 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8671 return new ErrorExp();
8672 Dsymbol
*s
= exp
->ti
->toAlias();
8673 Declaration
*v
= s
->isDeclaration();
8674 if (v
&& (v
->isFuncDeclaration() || v
->isVarDeclaration()))
8676 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8677 e
= semantic(e
, sc
);
8680 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8681 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8682 e
= semantic(e
, sc
);
8685 else if (e
->op
== TOKtemplate
)
8687 exp
->ti
->tempdecl
= ((TemplateExp
*)e
)->td
;
8688 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8689 e
= semantic(e
, sc
);
8692 else if (e
->op
== TOKdot
)
8694 DotExp
*de
= (DotExp
*)e
;
8696 if (de
->e2
->op
== TOKoverloadset
)
8698 if (!exp
->findTempDecl(sc
) ||
8699 !exp
->ti
->semanticTiargs(sc
))
8701 return new ErrorExp();
8703 if (exp
->ti
->needsTypeInference(sc
))
8705 exp
->ti
->semantic(sc
);
8706 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8707 return new ErrorExp();
8708 Dsymbol
*s
= exp
->ti
->toAlias();
8709 Declaration
*v
= s
->isDeclaration();
8712 if (v
->type
&& !v
->type
->deco
)
8713 v
->type
= v
->type
->semantic(v
->loc
, sc
);
8714 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8715 e
= semantic(e
, sc
);
8718 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8719 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8720 e
= semantic(e
, sc
);
8724 else if (e
->op
== TOKoverloadset
)
8726 OverExp
*oe
= (OverExp
*)e
;
8727 exp
->ti
->tempdecl
= oe
->vars
;
8728 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8729 e
= semantic(e
, sc
);
8733 e
->error("%s isn't a template", e
->toChars());
8734 return new ErrorExp();