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
16 #include "root/rmem.h"
17 #include "root/root.h"
23 #include "expression.h"
28 #include "statement.h"
29 #include "declaration.h"
30 #include "aggregate.h"
42 bool typeMerge(Scope
*sc
, TOK op
, Type
**pt
, Expression
**pe1
, Expression
**pe2
);
43 bool isArrayOpValid(Expression
*e
);
44 Expression
*expandVar(int result
, VarDeclaration
*v
);
45 TypeTuple
*toArgTypes(Type
*t
);
46 bool checkAssignEscape(Scope
*sc
, Expression
*e
, bool gag
);
47 bool checkParamArgumentEscape(Scope
*sc
, FuncDeclaration
*fdc
, Identifier
*par
, Expression
*arg
, bool gag
);
48 bool checkAccess(AggregateDeclaration
*ad
, Loc loc
, Scope
*sc
, Dsymbol
*smember
);
49 bool checkNestedRef(Dsymbol
*s
, Dsymbol
*p
);
50 bool checkFrameAccess(Loc loc
, Scope
*sc
, AggregateDeclaration
*ad
, size_t istart
= 0);
51 bool symbolIsVisible(Module
*mod
, Dsymbol
*s
);
52 VarDeclaration
*copyToTemp(StorageClass stc
, const char *name
, Expression
*e
);
53 Expression
*extractSideEffect(Scope
*sc
, const char *name
, Expression
**e0
, Expression
*e
, bool alwaysCopy
= false);
54 Type
*getTypeInfoType(Type
*t
, Scope
*sc
);
55 bool MODimplicitConv(MOD modfrom
, MOD modto
);
56 MATCH
MODmethodConv(MOD modfrom
, MOD modto
);
57 void MODMatchToBuffer(OutBuffer
*buf
, unsigned char lhsMod
, unsigned char rhsMod
);
59 void unSpeculative(Scope
*sc
, RootObject
*o
);
60 bool arrayExpressionToCommonType(Scope
*sc
, Expressions
*exps
, Type
**pt
);
61 bool checkDefCtor(Loc loc
, Type
*t
);
62 bool isDotOpDispatch(Expression
*e
);
63 bool functionParameters(Loc loc
, Scope
*sc
, TypeFunction
*tf
, Type
*tthis
, Expressions
*arguments
, FuncDeclaration
*fd
, Type
**prettype
, Expression
**peprefix
);
64 Expression
*getRightThis(Loc loc
, Scope
*sc
, AggregateDeclaration
*ad
, Expression
*e1
, Declaration
*var
, int flag
= 0);
65 bool isNeedThisScope(Scope
*sc
, Declaration
*d
);
66 Expression
*resolveUFCS(Scope
*sc
, CallExp
*ce
);
67 bool checkUnsafeAccess(Scope
*sc
, Expression
*e
, bool readonly
, bool printmsg
);
68 bool isSafeCast(Expression
*e
, Type
*tfrom
, Type
*tto
);
69 FuncDeclaration
*isFuncAddress(Expression
*e
, bool *hasOverloads
= NULL
);
70 Expression
*callCpCtor(Scope
*sc
, Expression
*e
);
72 Expression
*resolve(Loc loc
, Scope
*sc
, Dsymbol
*s
, bool hasOverloads
);
73 Expression
*resolveUFCSProperties(Scope
*sc
, Expression
*e1
, Expression
*e2
= NULL
);
74 Expression
*resolvePropertiesX(Scope
*sc
, Expression
*e1
, Expression
*e2
= NULL
);
75 Expression
*trySemantic(Expression
*e
, Scope
*sc
);
76 Expression
*unaSemantic(UnaExp
*e
, Scope
*sc
);
77 Expression
*binSemantic(BinExp
*e
, Scope
*sc
);
78 Expression
*binSemanticProp(BinExp
*e
, Scope
*sc
);
79 Expression
*semantic(Expression
*e
, Scope
*sc
);
80 Expression
*semanticY(DotIdExp
*exp
, Scope
*sc
, int flag
);
81 Expression
*semanticY(DotTemplateInstanceExp
*exp
, Scope
*sc
, int flag
);
83 /****************************************
84 * Preprocess arguments to function.
86 * exps[] tuples expanded, properties resolved, rewritten in place
88 * true a semantic error occurred
91 static bool preFunctionParameters(Scope
*sc
, Expressions
*exps
)
98 for (size_t i
= 0; i
< exps
->dim
; i
++)
100 Expression
*arg
= (*exps
)[i
];
102 arg
= resolveProperties(sc
, arg
);
103 if (arg
->op
== TOKtype
)
105 arg
->error("cannot pass type %s as a function argument", arg
->toChars());
106 arg
= new ErrorExp();
109 else if (checkNonAssignmentArrayOp(arg
))
111 arg
= new ErrorExp();
120 class ExpressionSemanticVisitor
: public Visitor
126 ExpressionSemanticVisitor(Scope
*sc
)
135 result
= new ErrorExp();
138 /*********************
139 * Mark the operand as will never be dereferenced,
140 * which is useful info for @safe checks.
141 * Do before semantic() on operands rewrites them.
143 static void setNoderefOperand(UnaExp
*e
)
145 if (e
->e1
->op
== TOKdotid
)
146 ((DotIdExp
*)e
->e1
)->noderef
= true;
149 /*********************
150 * Mark the operands as will never be dereferenced,
151 * which is useful info for @safe checks.
152 * Do before semantic() on operands rewrites them.
154 static void setNoderefOperands(BinExp
*e
)
156 if (e
->e1
->op
== TOKdotid
)
157 ((DotIdExp
*)e
->e1
)->noderef
= true;
158 if (e
->e2
->op
== TOKdotid
)
159 ((DotIdExp
*)e
->e2
)->noderef
= true;
162 static FuncDeclaration
*resolveOverloadSet(Loc loc
, Scope
*sc
,
163 OverloadSet
*os
, Objects
* tiargs
, Type
*tthis
, Expressions
*arguments
)
165 FuncDeclaration
*f
= NULL
;
166 for (size_t i
= 0; i
< os
->a
.dim
; i
++)
168 Dsymbol
*s
= os
->a
[i
];
169 if (tiargs
&& s
->isFuncDeclaration())
171 if (FuncDeclaration
*f2
= resolveFuncCall(loc
, sc
, s
, tiargs
, tthis
, arguments
, 1))
177 /* Error if match in more than one overload set,
178 * even if one is a 'better' match than the other.
180 ScopeDsymbol::multiplyDefined(loc
, f
, f2
);
187 ::error(loc
, "no overload matches for %s", os
->toChars());
193 /****************************************************
194 * Determine if `exp`, which takes the address of `v`, can do so safely.
197 * exp = expression that takes the address of `v`
198 * v = the variable getting its address taken
200 * `true` if ok, `false` for error
202 static bool checkAddressVar(Scope
*sc
, UnaExp
*e
, VarDeclaration
*v
)
206 if (!v
->canTakeAddressOf())
208 e
->error("cannot take address of %s", e
->e1
->toChars());
211 if (sc
->func
&& !sc
->intypeof
&& !v
->isDataseg())
213 const char *p
= v
->isParameter() ? "parameter" : "local";
214 if (global
.params
.vsafe
)
216 // Taking the address of v means it cannot be set to 'scope' later
217 v
->storage_class
&= ~STCmaybescope
;
218 v
->doNotInferScope
= true;
219 if (v
->storage_class
& STCscope
&& sc
->func
->setUnsafe())
221 e
->error("cannot take address of scope %s %s in @safe function %s", p
, v
->toChars(), sc
->func
->toChars());
225 else if (sc
->func
->setUnsafe())
227 e
->error("cannot take address of %s %s in @safe function %s", p
, v
->toChars(), sc
->func
->toChars());
235 static bool checkVectorElem(Expression
*e
, Expression
*elem
)
237 if (elem
->isConst() == 1)
240 e
->error("constant expression expected, not %s", elem
->toChars());
245 void visit(Expression
*e
)
248 e
->type
= e
->type
->semantic(e
->loc
, sc
);
250 e
->type
= Type::tvoid
;
254 void visit(IntegerExp
*e
)
257 if (e
->type
->ty
== Terror
)
259 assert(e
->type
->deco
);
264 void visit(RealExp
*e
)
267 e
->type
= Type::tfloat64
;
269 e
->type
= e
->type
->semantic(e
->loc
, sc
);
273 void visit(ComplexExp
*e
)
276 e
->type
= Type::tcomplex80
;
278 e
->type
= e
->type
->semantic(e
->loc
, sc
);
282 void visit(IdentifierExp
*exp
)
284 if (exp
->type
) // This is used as the dummy expression
291 Dsymbol
*s
= sc
->search(exp
->loc
, exp
->ident
, &scopesym
);
299 /* See if the symbol was a member of an enclosing 'with'
301 WithScopeSymbol
*withsym
= scopesym
->isWithScopeSymbol();
302 if (withsym
&& withsym
->withstate
->wthis
)
304 /* Disallow shadowing
306 // First find the scope of the with
308 while (scwith
->scopesym
!= scopesym
)
310 scwith
= scwith
->enclosing
;
313 // Look at enclosing scopes for symbols with the same name,
314 // in the same function
315 for (Scope
*scx
= scwith
; scx
&& scx
->func
== scwith
->func
; scx
= scx
->enclosing
)
318 if (scx
->scopesym
&& scx
->scopesym
->symtab
&&
319 (s2
= scx
->scopesym
->symtab
->lookup(s
->ident
)) != NULL
&&
322 exp
->error("with symbol %s is shadowing local symbol %s", s
->toPrettyChars(), s2
->toPrettyChars());
328 // Same as wthis.ident
329 // TODO: DotIdExp.semantic will find 'ident' from 'wthis' again.
330 // The redudancy should be removed.
331 e
= new VarExp(exp
->loc
, withsym
->withstate
->wthis
);
332 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
339 Declaration
*d
= s
->isDeclaration();
341 checkAccess(exp
->loc
, sc
, NULL
, d
);
344 /* If f is really a function template,
345 * then replace f with the function template declaration.
347 FuncDeclaration
*f
= s
->isFuncDeclaration();
350 TemplateDeclaration
*td
= getFuncTemplateDecl(f
);
353 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
354 td
= td
->overroot
; // then get the start
355 e
= new TemplateExp(exp
->loc
, td
, f
);
361 // Haven't done overload resolution yet, so pass 1
362 e
= resolve(exp
->loc
, sc
, s
, true);
370 AggregateDeclaration
*ad
= sc
->getStructClassScope();
371 if (ad
&& ad
->aliasthis
)
374 e
= new IdentifierExp(exp
->loc
, Id::This
);
375 e
= new DotIdExp(exp
->loc
, e
, ad
->aliasthis
->ident
);
376 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
377 e
= trySemantic(e
, sc
);
386 if (exp
->ident
== Id::ctfe
)
388 if (sc
->flags
& SCOPEctfe
)
390 exp
->error("variable __ctfe cannot be read at compile time");
394 // Create the magic __ctfe bool variable
395 VarDeclaration
*vd
= new VarDeclaration(exp
->loc
, Type::tbool
, Id::ctfe
, NULL
);
396 vd
->storage_class
|= STCtemp
;
397 Expression
*e
= new VarExp(exp
->loc
, vd
);
403 // If we've reached this point and are inside a with() scope then we may
404 // try one last attempt by checking whether the 'wthis' object supports
405 // dynamic dispatching via opDispatch.
406 // This is done by rewriting this expression as wthis.ident.
407 for (Scope
*sc2
= sc
; sc2
; sc2
= sc2
->enclosing
)
412 if (WithScopeSymbol
*ss
= sc2
->scopesym
->isWithScopeSymbol())
414 if (ss
->withstate
->wthis
)
417 e
= new VarExp(exp
->loc
, ss
->withstate
->wthis
);
418 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
419 e
= trySemantic(e
, sc
);
430 /* Look for what user might have meant
432 if (const char *n
= importHint(exp
->ident
->toChars()))
433 exp
->error("`%s` is not defined, perhaps `import %s;` is needed?", exp
->ident
->toChars(), n
);
434 else if (Dsymbol
*s2
= sc
->search_correct(exp
->ident
))
435 exp
->error("undefined identifier `%s`, did you mean %s `%s`?", exp
->ident
->toChars(), s2
->kind(), s2
->toChars());
436 else if (const char *p
= Scope::search_correct_C(exp
->ident
))
437 exp
->error("undefined identifier `%s`, did you mean `%s`?", exp
->ident
->toChars(), p
);
439 exp
->error("undefined identifier `%s`", exp
->ident
->toChars());
443 void visit(DsymbolExp
*e
)
445 result
= resolve(e
->loc
, sc
, e
->s
, e
->hasOverloads
);
448 void visit(ThisExp
*e
)
456 FuncDeclaration
*fd
= hasThis(sc
); // fd is the uplevel function with the 'this' variable
458 /* Special case for typeof(this) and typeof(super) since both
459 * should work even if they are not inside a non-static member function
461 if (!fd
&& sc
->intypeof
== 1)
463 // Find enclosing struct or class
464 for (Dsymbol
*s
= sc
->getStructClassScope(); 1; s
= s
->parent
)
468 e
->error("%s is not in a class or struct scope", e
->toChars());
471 ClassDeclaration
*cd
= s
->isClassDeclaration();
478 StructDeclaration
*sd
= s
->isStructDeclaration();
492 assert(e
->var
->parent
);
493 e
->type
= e
->var
->type
;
494 if (e
->var
->checkNestedReference(sc
, e
->loc
))
497 sc
->callSuper
|= CSXthis
;
502 e
->error("'this' is only defined in non-static member functions, not %s", sc
->parent
->toChars());
506 void visit(SuperExp
*e
)
514 FuncDeclaration
*fd
= hasThis(sc
);
515 ClassDeclaration
*cd
;
518 /* Special case for typeof(this) and typeof(super) since both
519 * should work even if they are not inside a non-static member function
521 if (!fd
&& sc
->intypeof
== 1)
523 // Find enclosing class
524 for (s
= sc
->getStructClassScope(); 1; s
= s
->parent
)
528 e
->error("%s is not in a class scope", e
->toChars());
531 cd
= s
->isClassDeclaration();
537 e
->error("class %s has no 'super'", s
->toChars());
550 assert(e
->var
&& e
->var
->parent
);
553 while (s
&& s
->isTemplateInstance())
555 if (s
->isTemplateDeclaration()) // allow inside template constraint
558 cd
= s
->isClassDeclaration();
559 //printf("parent is %s %s\n", fd->toParent()->kind(), fd->toParent()->toChars());
564 e
->error("no base class for %s", cd
->toChars());
565 e
->type
= e
->var
->type
;
569 e
->type
= cd
->baseClass
->type
;
570 e
->type
= e
->type
->castMod(e
->var
->type
->mod
);
573 if (e
->var
->checkNestedReference(sc
, e
->loc
))
577 sc
->callSuper
|= CSXsuper
;
582 e
->error("'super' is only allowed in non-static class member functions");
586 void visit(NullExp
*e
)
588 // NULL is the same as (void *)0
594 e
->type
= Type::tnull
;
598 void visit(StringExp
*e
)
615 for (u
= 0; u
< e
->len
;)
617 p
= utf_decodeChar((utf8_t
*)e
->string
, e
->len
, &u
, &c
);
630 e
->string
= buffer
.extractData();
633 e
->type
= new TypeDArray(Type::tdchar
->immutableOf());
638 for (u
= 0; u
< e
->len
;)
640 p
= utf_decodeChar((utf8_t
*)e
->string
, e
->len
, &u
, &c
);
648 buffer
.writeUTF16(c
);
654 buffer
.writeUTF16(0);
655 e
->string
= buffer
.extractData();
658 e
->type
= new TypeDArray(Type::twchar
->immutableOf());
667 e
->type
= new TypeDArray(Type::tchar
->immutableOf());
670 e
->type
= e
->type
->semantic(e
->loc
, sc
);
671 //e->type = e->type->immutableOf();
672 //printf("type = %s\n", e->type->toChars());
677 void visit(ArrayLiteralExp
*e
)
685 /* Perhaps an empty array literal [ ] should be rewritten as null?
689 e
->basis
= semantic(e
->basis
, sc
);
690 if (arrayExpressionSemantic(e
->elements
, sc
) || (e
->basis
&& e
->basis
->op
== TOKerror
))
692 expandTuples(e
->elements
);
696 e
->elements
->push(e
->basis
);
697 bool err
= arrayExpressionToCommonType(sc
, e
->elements
, &t0
);
703 e
->type
= t0
->arrayOf();
704 e
->type
= e
->type
->semantic(e
->loc
, sc
);
706 /* Disallow array literals of type void being used.
708 if (e
->elements
->dim
> 0 && t0
->ty
== Tvoid
)
710 e
->error("%s of type %s has no value", e
->toChars(), e
->type
->toChars());
714 semanticTypeInfo(sc
, e
->type
);
719 void visit(AssocArrayLiteralExp
*e
)
727 // Run semantic() on each element
728 bool err_keys
= arrayExpressionSemantic(e
->keys
, sc
);
729 bool err_vals
= arrayExpressionSemantic(e
->values
, sc
);
730 if (err_keys
|| err_vals
)
732 expandTuples(e
->keys
);
733 expandTuples(e
->values
);
734 if (e
->keys
->dim
!= e
->values
->dim
)
736 e
->error("number of keys is %u, must match number of values %u", e
->keys
->dim
, e
->values
->dim
);
742 err_keys
= arrayExpressionToCommonType(sc
, e
->keys
, &tkey
);
743 err_vals
= arrayExpressionToCommonType(sc
, e
->values
, &tvalue
);
744 if (err_keys
|| err_vals
)
747 if (tkey
== Type::terror
|| tvalue
== Type::terror
)
750 e
->type
= new TypeAArray(tvalue
, tkey
);
751 e
->type
= e
->type
->semantic(e
->loc
, sc
);
753 semanticTypeInfo(sc
, e
->type
);
758 void visit(StructLiteralExp
*e
)
767 if (e
->sd
->sizeok
!= SIZEOKdone
)
770 if (arrayExpressionSemantic(e
->elements
, sc
)) // run semantic() on each element
772 expandTuples(e
->elements
);
774 /* Fit elements[] to the corresponding type of field[].
776 if (!e
->sd
->fit(e
->loc
, sc
, e
->elements
, e
->stype
))
779 /* Fill out remainder of elements[] with default initializers for fields[]
781 if (!e
->sd
->fill(e
->loc
, e
->elements
, false))
783 /* An error in the initializer needs to be recorded as an error
784 * in the enclosing function or template, since the initializer
785 * will be part of the stuct declaration.
787 global
.increaseErrorCount();
791 if (checkFrameAccess(e
->loc
, sc
, e
->sd
, e
->elements
->dim
))
794 e
->type
= e
->stype
? e
->stype
: e
->sd
->type
;
798 void visit(TypeExp
*exp
)
800 if (exp
->type
->ty
== Terror
)
803 //printf("TypeExp::semantic(%s)\n", exp->type->toChars());
808 exp
->type
->resolve(exp
->loc
, sc
, &e
, &t
, &s
, true);
811 //printf("e = %s %s\n", Token::toChars(e->op), e->toChars());
816 //printf("t = %d %s\n", t->ty, t->toChars());
817 exp
->type
= t
->semantic(exp
->loc
, sc
);
822 //printf("s = %s %s\n", s->kind(), s->toChars());
823 e
= resolve(exp
->loc
, sc
, s
, true);
828 if (global
.params
.vcomplex
)
829 exp
->type
->checkComplexTransition(exp
->loc
);
834 void visit(ScopeExp
*exp
)
842 ScopeDsymbol
*sds2
= exp
->sds
;
843 TemplateInstance
*ti
= sds2
->isTemplateInstance();
846 WithScopeSymbol
*withsym
;
847 if (!ti
->findTempDecl(sc
, &withsym
) ||
848 !ti
->semanticTiargs(sc
))
850 if (withsym
&& withsym
->withstate
->wthis
)
852 Expression
*e
= new VarExp(exp
->loc
, withsym
->withstate
->wthis
);
853 e
= new DotTemplateInstanceExp(exp
->loc
, e
, ti
);
854 result
= semantic(e
, sc
);
857 if (ti
->needsTypeInference(sc
))
859 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
861 Dsymbol
*p
= td
->toParent2();
862 FuncDeclaration
*fdthis
= hasThis(sc
);
863 AggregateDeclaration
*ad
= p
? p
->isAggregateDeclaration() : NULL
;
864 if (fdthis
&& ad
&& isAggregate(fdthis
->vthis
->type
) == ad
&&
865 (td
->_scope
->stc
& STCstatic
) == 0)
867 Expression
*e
= new DotTemplateInstanceExp(exp
->loc
, new ThisExp(exp
->loc
), ti
->name
, ti
->tiargs
);
868 result
= semantic(e
, sc
);
872 else if (OverloadSet
*os
= ti
->tempdecl
->isOverloadSet())
874 FuncDeclaration
*fdthis
= hasThis(sc
);
875 AggregateDeclaration
*ad
= os
->parent
->isAggregateDeclaration();
876 if (fdthis
&& ad
&& isAggregate(fdthis
->vthis
->type
) == ad
)
878 Expression
*e
= new DotTemplateInstanceExp(exp
->loc
, new ThisExp(exp
->loc
), ti
->name
, ti
->tiargs
);
879 result
= semantic(e
, sc
);
883 // ti is an instance which requires IFTI.
885 exp
->type
= Type::tvoid
;
890 if (!ti
->inst
|| ti
->errors
)
893 Dsymbol
*s
= ti
->toAlias();
897 exp
->type
= Type::tvoid
;
901 sds2
= s
->isScopeDsymbol();
904 ti
= sds2
->isTemplateInstance();
905 //printf("+ sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
909 if (VarDeclaration
*v
= s
->isVarDeclaration())
913 exp
->error("forward reference of %s %s", v
->kind(), v
->toChars());
916 if ((v
->storage_class
& STCmanifest
) && v
->_init
)
918 /* When an instance that will be converted to a constant exists,
919 * the instance representation "foo!tiargs" is treated like a
920 * variable name, and its recursive appearance check (note that
921 * it's equivalent with a recursive instantiation of foo) is done
922 * separately from the circular initialization check for the
923 * eponymous enum variable declaration.
926 * enum bool foo = foo; // recursive definition check (v.inuse)
929 * enum bool bar = bar!T; // recursive instantiation check (ti.inuse)
934 exp
->error("recursive expansion of %s '%s'", ti
->kind(), ti
->toPrettyChars());
938 Expression
*e
= v
->expandInitializer(exp
->loc
);
947 //printf("s = %s, '%s'\n", s->kind(), s->toChars());
948 Expression
*e
= resolve(exp
->loc
, sc
, s
, true);
949 //printf("-1ScopeExp::semantic()\n");
954 //printf("sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
955 //printf("\tparent = '%s'\n", sds2->parent->toChars());
958 if (Type
*t
= sds2
->getType()) // (Aggregate|Enum)Declaration
960 Expression
*ex
= new TypeExp(exp
->loc
, t
);
961 result
= semantic(ex
, sc
);
965 if (TemplateDeclaration
*td
= sds2
->isTemplateDeclaration())
967 result
= semantic(new TemplateExp(exp
->loc
, td
), sc
);
972 exp
->type
= Type::tvoid
;
973 //printf("-2ScopeExp::semantic() %s\n", exp->toChars());
977 void visit(NewExp
*exp
)
979 if (exp
->type
) // if semantic() already run
985 // Bugzilla 11581: With the syntax `new T[edim]` or `thisexp.new T[edim]`,
986 // T should be analyzed first and edim should go into arguments iff it's
988 Expression
*edim
= NULL
;
989 if (!exp
->arguments
&& exp
->newtype
->ty
== Tsarray
)
991 edim
= ((TypeSArray
*)exp
->newtype
)->dim
;
992 exp
->newtype
= ((TypeNext
*)exp
->newtype
)->next
;
995 ClassDeclaration
*cdthis
= NULL
;
998 exp
->thisexp
= semantic(exp
->thisexp
, sc
);
999 if (exp
->thisexp
->op
== TOKerror
)
1001 cdthis
= exp
->thisexp
->type
->isClassHandle();
1004 exp
->error("'this' for nested class must be a class type, not %s", exp
->thisexp
->type
->toChars());
1008 sc
= sc
->push(cdthis
);
1009 exp
->type
= exp
->newtype
->semantic(exp
->loc
, sc
);
1014 exp
->type
= exp
->newtype
->semantic(exp
->loc
, sc
);
1016 if (exp
->type
->ty
== Terror
)
1021 if (exp
->type
->toBasetype()->ty
== Ttuple
)
1024 exp
->type
= new TypeSArray(exp
->type
, edim
);
1025 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1026 if (exp
->type
->ty
== Terror
)
1031 // --> new T[](edim)
1032 exp
->arguments
= new Expressions();
1033 exp
->arguments
->push(edim
);
1034 exp
->type
= exp
->type
->arrayOf();
1038 exp
->newtype
= exp
->type
; // in case type gets cast to something else
1039 Type
*tb
= exp
->type
->toBasetype();
1040 //printf("tb: %s, deco = %s\n", tb->toChars(), tb->deco);
1042 if (arrayExpressionSemantic(exp
->newargs
, sc
) ||
1043 preFunctionParameters(sc
, exp
->newargs
))
1047 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
1048 preFunctionParameters(sc
, exp
->arguments
))
1053 if (exp
->thisexp
&& tb
->ty
!= Tclass
)
1055 exp
->error("e.new is only for allocating nested classes, not %s", tb
->toChars());
1059 size_t nargs
= exp
->arguments
? exp
->arguments
->dim
: 0;
1060 Expression
*newprefix
= NULL
;
1062 if (tb
->ty
== Tclass
)
1064 ClassDeclaration
*cd
= ((TypeClass
*)tb
)->sym
;
1066 if (cd
->sizeok
!= SIZEOKdone
)
1069 cd
->ctor
= cd
->searchCtor();
1070 if (cd
->noDefaultCtor
&& !nargs
&& !cd
->defaultCtor
)
1072 exp
->error("default construction is disabled for type %s", cd
->type
->toChars());
1076 if (cd
->isInterfaceDeclaration())
1078 exp
->error("cannot create instance of interface %s", cd
->toChars());
1081 if (cd
->isAbstract())
1083 exp
->error("cannot create instance of abstract class %s", cd
->toChars());
1084 for (size_t i
= 0; i
< cd
->vtbl
.dim
; i
++)
1086 FuncDeclaration
*fd
= cd
->vtbl
[i
]->isFuncDeclaration();
1087 if (fd
&& fd
->isAbstract())
1088 errorSupplemental(exp
->loc
, "function '%s' is not implemented", fd
->toFullSignature());
1092 // checkDeprecated() is already done in newtype->semantic().
1096 /* We need a 'this' pointer for the nested class.
1097 * Ensure we have the right one.
1099 Dsymbol
*s
= cd
->toParent2();
1100 //printf("cd isNested, parent = %s '%s'\n", s->kind(), s->toPrettyChars());
1101 if (ClassDeclaration
*cdn
= s
->isClassDeclaration())
1105 // Supply an implicit 'this' and try again
1106 exp
->thisexp
= new ThisExp(exp
->loc
);
1107 for (Dsymbol
*sp
= sc
->parent
; 1; sp
= sp
->parent
)
1111 exp
->error("outer class %s 'this' needed to 'new' nested class %s", cdn
->toChars(), cd
->toChars());
1114 ClassDeclaration
*cdp
= sp
->isClassDeclaration();
1117 if (cdp
== cdn
|| cdn
->isBaseOf(cdp
, NULL
))
1119 // Add a '.outer' and try again
1120 exp
->thisexp
= new DotIdExp(exp
->loc
, exp
->thisexp
, Id::outer
);
1122 exp
->thisexp
= semantic(exp
->thisexp
, sc
);
1123 if (exp
->thisexp
->op
== TOKerror
)
1125 cdthis
= exp
->thisexp
->type
->isClassHandle();
1127 if (cdthis
!= cdn
&& !cdn
->isBaseOf(cdthis
, NULL
))
1129 //printf("cdthis = %s\n", cdthis->toChars());
1130 exp
->error("'this' for nested class must be of type %s, not %s",
1131 cdn
->toChars(), exp
->thisexp
->type
->toChars());
1134 if (!MODimplicitConv(exp
->thisexp
->type
->mod
, exp
->newtype
->mod
))
1136 exp
->error("nested type %s should have the same or weaker constancy as enclosing type %s",
1137 exp
->newtype
->toChars(), exp
->thisexp
->type
->toChars());
1141 else if (exp
->thisexp
)
1143 exp
->error("e.new is only for allocating nested classes");
1146 else if (FuncDeclaration
*fdn
= s
->isFuncDeclaration())
1148 // make sure the parent context fdn of cd is reachable from sc
1149 if (checkNestedRef(sc
->parent
, fdn
))
1151 exp
->error("outer function context of %s is needed to 'new' nested class %s",
1152 fdn
->toPrettyChars(), cd
->toPrettyChars());
1159 else if (exp
->thisexp
)
1161 exp
->error("e.new is only for allocating nested classes");
1167 // Prepend the size argument to newargs[]
1168 Expression
*e
= new IntegerExp(exp
->loc
, cd
->size(exp
->loc
), Type::tsize_t
);
1170 exp
->newargs
= new Expressions();
1171 exp
->newargs
->shift(e
);
1173 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, cd
->aggNew
, NULL
, tb
, exp
->newargs
);
1174 if (!f
|| f
->errors
)
1176 exp
->checkDeprecated(sc
, f
);
1177 exp
->checkPurity(sc
, f
);
1178 exp
->checkSafety(sc
, f
);
1179 exp
->checkNogc(sc
, f
);
1180 checkAccess(cd
, exp
->loc
, sc
, f
);
1182 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1184 if (functionParameters(exp
->loc
, sc
, tf
, NULL
, exp
->newargs
, f
, &rettype
, &newprefix
))
1187 exp
->allocator
= f
->isNewDeclaration();
1188 assert(exp
->allocator
);
1192 if (exp
->newargs
&& exp
->newargs
->dim
)
1194 exp
->error("no allocator for %s", cd
->toChars());
1201 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, cd
->ctor
, NULL
, tb
, exp
->arguments
, 0);
1202 if (!f
|| f
->errors
)
1204 exp
->checkDeprecated(sc
, f
);
1205 exp
->checkPurity(sc
, f
);
1206 exp
->checkSafety(sc
, f
);
1207 exp
->checkNogc(sc
, f
);
1208 checkAccess(cd
, exp
->loc
, sc
, f
);
1210 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1211 if (!exp
->arguments
)
1212 exp
->arguments
= new Expressions();
1213 if (functionParameters(exp
->loc
, sc
, tf
, exp
->type
, exp
->arguments
, f
, &exp
->type
, &exp
->argprefix
))
1216 exp
->member
= f
->isCtorDeclaration();
1217 assert(exp
->member
);
1223 exp
->error("no constructor for %s", cd
->toChars());
1228 else if (tb
->ty
== Tstruct
)
1230 StructDeclaration
*sd
= ((TypeStruct
*)tb
)->sym
;
1232 if (sd
->sizeok
!= SIZEOKdone
)
1235 sd
->ctor
= sd
->searchCtor();
1236 if (sd
->noDefaultCtor
&& !nargs
)
1238 exp
->error("default construction is disabled for type %s", sd
->type
->toChars());
1241 // checkDeprecated() is already done in newtype->semantic().
1245 // Prepend the uint size argument to newargs[]
1246 Expression
*e
= new IntegerExp(exp
->loc
, sd
->size(exp
->loc
), Type::tsize_t
);
1248 exp
->newargs
= new Expressions();
1249 exp
->newargs
->shift(e
);
1251 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, sd
->aggNew
, NULL
, tb
, exp
->newargs
);
1252 if (!f
|| f
->errors
)
1254 exp
->checkDeprecated(sc
, f
);
1255 exp
->checkPurity(sc
, f
);
1256 exp
->checkSafety(sc
, f
);
1257 exp
->checkNogc(sc
, f
);
1258 checkAccess(sd
, exp
->loc
, sc
, f
);
1260 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1262 if (functionParameters(exp
->loc
, sc
, tf
, NULL
, exp
->newargs
, f
, &rettype
, &newprefix
))
1265 exp
->allocator
= f
->isNewDeclaration();
1266 assert(exp
->allocator
);
1270 if (exp
->newargs
&& exp
->newargs
->dim
)
1272 exp
->error("no allocator for %s", sd
->toChars());
1277 if (sd
->ctor
&& nargs
)
1279 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, sd
->ctor
, NULL
, tb
, exp
->arguments
, 0);
1280 if (!f
|| f
->errors
)
1282 exp
->checkDeprecated(sc
, f
);
1283 exp
->checkPurity(sc
, f
);
1284 exp
->checkSafety(sc
, f
);
1285 exp
->checkNogc(sc
, f
);
1286 checkAccess(sd
, exp
->loc
, sc
, f
);
1288 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1289 if (!exp
->arguments
)
1290 exp
->arguments
= new Expressions();
1291 if (functionParameters(exp
->loc
, sc
, tf
, exp
->type
, exp
->arguments
, f
, &exp
->type
, &exp
->argprefix
))
1294 exp
->member
= f
->isCtorDeclaration();
1295 assert(exp
->member
);
1297 if (checkFrameAccess(exp
->loc
, sc
, sd
, sd
->fields
.dim
))
1302 if (!exp
->arguments
)
1303 exp
->arguments
= new Expressions();
1305 if (!sd
->fit(exp
->loc
, sc
, exp
->arguments
, tb
))
1307 if (!sd
->fill(exp
->loc
, exp
->arguments
, false))
1309 if (checkFrameAccess(exp
->loc
, sc
, sd
, exp
->arguments
? exp
->arguments
->dim
: 0))
1313 exp
->type
= exp
->type
->pointerTo();
1315 else if (tb
->ty
== Tarray
&& nargs
)
1317 Type
*tn
= tb
->nextOf()->baseElemOf();
1318 Dsymbol
*s
= tn
->toDsymbol(sc
);
1319 AggregateDeclaration
*ad
= s
? s
->isAggregateDeclaration() : NULL
;
1320 if (ad
&& ad
->noDefaultCtor
)
1322 exp
->error("default construction is disabled for type %s", tb
->nextOf()->toChars());
1325 for (size_t i
= 0; i
< nargs
; i
++)
1327 if (tb
->ty
!= Tarray
)
1329 exp
->error("too many arguments for array");
1333 Expression
*arg
= (*exp
->arguments
)[i
];
1334 arg
= resolveProperties(sc
, arg
);
1335 arg
= arg
->implicitCastTo(sc
, Type::tsize_t
);
1336 arg
= arg
->optimize(WANTvalue
);
1337 if (arg
->op
== TOKint64
&& (sinteger_t
)arg
->toInteger() < 0)
1339 exp
->error("negative array index %s", arg
->toChars());
1342 (*exp
->arguments
)[i
] = arg
;
1343 tb
= ((TypeDArray
*)tb
)->next
->toBasetype();
1346 else if (tb
->isscalar())
1351 else if (nargs
== 1)
1353 Expression
*e
= (*exp
->arguments
)[0];
1354 e
= e
->implicitCastTo(sc
, tb
);
1355 (*exp
->arguments
)[0] = e
;
1359 exp
->error("more than one argument for construction of %s", exp
->type
->toChars());
1363 exp
->type
= exp
->type
->pointerTo();
1367 exp
->error("new can only create structs, dynamic arrays or class objects, not %s's", exp
->type
->toChars());
1371 //printf("NewExp: '%s'\n", toChars());
1372 //printf("NewExp:type '%s'\n", exp->type->toChars());
1373 semanticTypeInfo(sc
, exp
->type
);
1377 result
= Expression::combine(newprefix
, exp
);
1383 void visit(NewAnonClassExp
*e
)
1385 Expression
*d
= new DeclarationExp(e
->loc
, e
->cd
);
1386 sc
= sc
->push(); // just create new scope
1387 sc
->flags
&= ~SCOPEctfe
; // temporary stop CTFE
1388 d
= semantic(d
, sc
);
1391 if (!e
->cd
->errors
&& sc
->intypeof
&& !sc
->parent
->inNonRoot())
1393 ScopeDsymbol
*sds
= sc
->tinst
? (ScopeDsymbol
*)sc
->tinst
: sc
->_module
;
1394 sds
->members
->push(e
->cd
);
1397 Expression
*n
= new NewExp(e
->loc
, e
->thisexp
, e
->newargs
, e
->cd
->type
, e
->arguments
);
1399 Expression
*c
= new CommaExp(e
->loc
, d
, n
);
1400 result
= semantic(c
, sc
);
1403 void visit(SymOffExp
*e
)
1405 //var->semantic(sc);
1407 e
->type
= e
->var
->type
->pointerTo();
1408 if (VarDeclaration
*v
= e
->var
->isVarDeclaration())
1410 if (v
->checkNestedReference(sc
, e
->loc
))
1413 else if (FuncDeclaration
*f
= e
->var
->isFuncDeclaration())
1415 if (f
->checkNestedReference(sc
, e
->loc
))
1421 void visit(VarExp
*e
)
1423 if (FuncDeclaration
*fd
= e
->var
->isFuncDeclaration())
1425 //printf("L%d fd = %s\n", __LINE__, f->toChars());
1426 if (!fd
->functionSemantic())
1431 e
->type
= e
->var
->type
;
1433 if (e
->type
&& !e
->type
->deco
)
1434 e
->type
= e
->type
->semantic(e
->loc
, sc
);
1436 /* Fix for 1161 doesn't work because it causes protection
1437 * problems when instantiating imported templates passing private
1438 * variables as alias template parameters.
1440 //checkAccess(e->loc, sc, NULL, e->var);
1442 if (VarDeclaration
*vd
= e
->var
->isVarDeclaration())
1444 if (vd
->checkNestedReference(sc
, e
->loc
))
1446 // Bugzilla 12025: If the variable is not actually used in runtime code,
1447 // the purity violation error is redundant.
1448 //checkPurity(sc, vd);
1450 else if (FuncDeclaration
*fd
= e
->var
->isFuncDeclaration())
1452 // TODO: If fd isn't yet resolved its overload, the checkNestedReference
1453 // call would cause incorrect validation.
1454 // Maybe here should be moved in CallExp, or AddrExp for functions.
1455 if (fd
->checkNestedReference(sc
, e
->loc
))
1458 else if (e
->var
->isOverDeclaration())
1460 e
->type
= Type::tvoid
; // ambiguous type?
1466 void visit(TupleExp
*exp
)
1475 exp
->e0
= semantic(exp
->e0
, sc
);
1477 // Run semantic() on each argument
1479 for (size_t i
= 0; i
< exp
->exps
->dim
; i
++)
1481 Expression
*e
= (*exp
->exps
)[i
];
1482 e
= semantic(e
, sc
);
1485 exp
->error("%s has no value", e
->toChars());
1488 else if (e
->op
== TOKerror
)
1491 (*exp
->exps
)[i
] = e
;
1496 expandTuples(exp
->exps
);
1497 exp
->type
= new TypeTuple(exp
->exps
);
1498 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1499 //printf("-TupleExp::semantic(%s)\n", exp->toChars());
1503 void visit(FuncExp
*exp
)
1505 Expression
*e
= exp
;
1507 sc
= sc
->push(); // just create new scope
1508 sc
->flags
&= ~SCOPEctfe
; // temporary stop CTFE
1509 sc
->protection
= Prot(PROTpublic
); // Bugzilla 12506
1511 if (!exp
->type
|| exp
->type
== Type::tvoid
)
1513 /* fd->treq might be incomplete type,
1514 * so should not semantic it.
1515 * void foo(T)(T delegate(int) dg){}
1516 * foo(a=>a); // in IFTI, treq == T delegate(int)
1518 //if (exp->fd->treq)
1519 // exp->fd->treq = exp->fd->treq->semantic(exp->loc, sc);
1523 // Set target of return type inference
1524 if (exp
->fd
->treq
&& !exp
->fd
->type
->nextOf())
1526 TypeFunction
*tfv
= NULL
;
1527 if (exp
->fd
->treq
->ty
== Tdelegate
||
1528 (exp
->fd
->treq
->ty
== Tpointer
&& exp
->fd
->treq
->nextOf()->ty
== Tfunction
))
1529 tfv
= (TypeFunction
*)exp
->fd
->treq
->nextOf();
1532 TypeFunction
*tfl
= (TypeFunction
*)exp
->fd
->type
;
1533 tfl
->next
= tfv
->nextOf();
1537 //printf("td = %p, treq = %p\n", exp->td, exp->fd->treq);
1540 assert(exp
->td
->parameters
&& exp
->td
->parameters
->dim
);
1541 exp
->td
->semantic(sc
);
1542 exp
->type
= Type::tvoid
; // temporary type
1544 if (exp
->fd
->treq
) // defer type determination
1547 if (exp
->matchType(exp
->fd
->treq
, sc
, &fe
) > MATCHnomatch
)
1555 unsigned olderrors
= global
.errors
;
1556 exp
->fd
->semantic(sc
);
1557 if (olderrors
== global
.errors
)
1559 exp
->fd
->semantic2(sc
);
1560 if (olderrors
== global
.errors
)
1561 exp
->fd
->semantic3(sc
);
1563 if (olderrors
!= global
.errors
)
1565 if (exp
->fd
->type
&& exp
->fd
->type
->ty
== Tfunction
&& !exp
->fd
->type
->nextOf())
1566 ((TypeFunction
*)exp
->fd
->type
)->next
= Type::terror
;
1571 // Type is a "delegate to" or "pointer to" the function literal
1572 if ((exp
->fd
->isNested() && exp
->fd
->tok
== TOKdelegate
) ||
1573 (exp
->tok
== TOKreserved
&& exp
->fd
->treq
&& exp
->fd
->treq
->ty
== Tdelegate
))
1575 exp
->type
= new TypeDelegate(exp
->fd
->type
);
1576 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1578 exp
->fd
->tok
= TOKdelegate
;
1582 exp
->type
= new TypePointer(exp
->fd
->type
);
1583 exp
->type
= exp
->type
->semantic(exp
->loc
, sc
);
1584 //exp->type = exp->fd->type->pointerTo();
1586 /* A lambda expression deduced to function pointer might become
1587 * to a delegate literal implicitly.
1589 * auto foo(void function() fp) { return 1; }
1590 * assert(foo({}) == 1);
1592 * So, should keep fd->tok == TOKreserve if fd->treq == NULL.
1594 if (exp
->fd
->treq
&& exp
->fd
->treq
->ty
== Tpointer
)
1596 // change to non-nested
1597 exp
->fd
->tok
= TOKfunction
;
1598 exp
->fd
->vthis
= NULL
;
1601 exp
->fd
->tookAddressOf
++;
1608 // used from CallExp::semantic()
1609 Expression
*callExpSemantic(FuncExp
*exp
, Scope
*sc
, Expressions
*arguments
)
1611 if ((!exp
->type
|| exp
->type
== Type::tvoid
) && exp
->td
&& arguments
&& arguments
->dim
)
1613 for (size_t k
= 0; k
< arguments
->dim
; k
++)
1614 { Expression
*checkarg
= (*arguments
)[k
];
1615 if (checkarg
->op
== TOKerror
)
1621 assert(exp
->td
->parameters
&& exp
->td
->parameters
->dim
);
1622 exp
->td
->semantic(sc
);
1624 TypeFunction
*tfl
= (TypeFunction
*)exp
->fd
->type
;
1625 size_t dim
= Parameter::dim(tfl
->parameters
);
1626 if (arguments
->dim
< dim
)
1627 { // Default arguments are always typed, so they don't need inference.
1628 Parameter
*p
= Parameter::getNth(tfl
->parameters
, arguments
->dim
);
1630 dim
= arguments
->dim
;
1633 if ((!tfl
->varargs
&& arguments
->dim
== dim
) ||
1634 ( tfl
->varargs
&& arguments
->dim
>= dim
))
1636 Objects
*tiargs
= new Objects();
1637 tiargs
->reserve(exp
->td
->parameters
->dim
);
1639 for (size_t i
= 0; i
< exp
->td
->parameters
->dim
; i
++)
1641 TemplateParameter
*tp
= (*exp
->td
->parameters
)[i
];
1642 for (size_t u
= 0; u
< dim
; u
++)
1643 { Parameter
*p
= Parameter::getNth(tfl
->parameters
, u
);
1644 if (p
->type
->ty
== Tident
&&
1645 ((TypeIdentifier
*)p
->type
)->ident
== tp
->ident
)
1646 { Expression
*e
= (*arguments
)[u
];
1647 tiargs
->push(e
->type
);
1648 u
= dim
; // break inner loop
1653 TemplateInstance
*ti
= new TemplateInstance(exp
->loc
, exp
->td
, tiargs
);
1654 Expression
*se
= new ScopeExp(exp
->loc
, ti
);
1655 return semantic(se
, sc
);
1657 exp
->error("cannot infer function literal type");
1658 return new ErrorExp();
1660 return semantic(exp
, sc
);
1663 void visit(DeclarationExp
*e
)
1671 unsigned olderrors
= global
.errors
;
1673 /* This is here to support extern(linkage) declaration,
1674 * where the extern(linkage) winds up being an AttribDeclaration
1677 Dsymbol
*s
= e
->declaration
;
1681 AttribDeclaration
*ad
= s
->isAttribDeclaration();
1684 if (ad
->decl
&& ad
->decl
->dim
== 1)
1693 VarDeclaration
*v
= s
->isVarDeclaration();
1696 // Do semantic() on initializer first, so:
1699 e
->declaration
->semantic(sc
);
1700 s
->parent
= sc
->parent
;
1703 //printf("inserting '%s' %p into sc = %p\n", s->toChars(), s, sc);
1704 // Insert into both local scope and function scope.
1705 // Must be unique in both.
1710 e
->error("declaration %s is already defined", s
->toPrettyChars());
1715 // Bugzilla 11720 - include Dataseg variables
1716 if ((s
->isFuncDeclaration() ||
1717 s
->isAggregateDeclaration() ||
1718 s
->isEnumDeclaration() ||
1719 (v
&& v
->isDataseg())) &&
1720 !sc
->func
->localsymtab
->insert(s
))
1722 e
->error("declaration %s is already defined in another scope in %s",
1723 s
->toPrettyChars(), sc
->func
->toChars());
1728 // Disallow shadowing
1729 for (Scope
*scx
= sc
->enclosing
; scx
&& scx
->func
== sc
->func
; scx
= scx
->enclosing
)
1732 if (scx
->scopesym
&& scx
->scopesym
->symtab
&&
1733 (s2
= scx
->scopesym
->symtab
->lookup(s
->ident
)) != NULL
&&
1736 e
->error("%s %s is shadowing %s %s", s
->kind(), s
->ident
->toChars(), s2
->kind(), s2
->toPrettyChars());
1743 if (!s
->isVarDeclaration())
1746 if (sc2
->stc
& (STCpure
| STCnothrow
| STCnogc
))
1748 sc2
->stc
&= ~(STCpure
| STCnothrow
| STCnogc
);
1749 e
->declaration
->semantic(sc2
);
1752 s
->parent
= sc
->parent
;
1754 if (global
.errors
== olderrors
)
1756 e
->declaration
->semantic2(sc
);
1757 if (global
.errors
== olderrors
)
1759 e
->declaration
->semantic3(sc
);
1762 // todo: error in declaration should be propagated.
1764 e
->type
= Type::tvoid
;
1768 void visit(TypeidExp
*exp
)
1770 Type
*ta
= isType(exp
->obj
);
1771 Expression
*ea
= isExpression(exp
->obj
);
1772 Dsymbol
*sa
= isDsymbol(exp
->obj
);
1774 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1778 ta
->resolve(exp
->loc
, sc
, &ea
, &ta
, &sa
, true);
1783 if (Dsymbol
*sym
= getDsymbol(ea
))
1784 ea
= resolve(exp
->loc
, sc
, sym
, false);
1786 ea
= semantic(ea
, sc
);
1787 ea
= resolveProperties(sc
, ea
);
1789 if (ea
->op
== TOKtype
)
1795 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1796 exp
->error("no type for typeid(%s)", ea
? ea
->toChars() : (sa
? sa
->toChars() : ""));
1800 if (global
.params
.vcomplex
)
1801 ta
->checkComplexTransition(exp
->loc
);
1804 if (ea
&& ta
->toBasetype()->ty
== Tclass
)
1806 /* Get the dynamic type, which is .classinfo
1808 ea
= semantic(ea
, sc
);
1809 e
= new TypeidExp(ea
->loc
, ea
);
1810 e
->type
= Type::typeinfoclass
->type
;
1812 else if (ta
->ty
== Terror
)
1818 // Handle this in the glue layer
1819 e
= new TypeidExp(exp
->loc
, ta
);
1820 e
->type
= getTypeInfoType(ta
, sc
);
1822 semanticTypeInfo(sc
, ta
);
1826 e
= new CommaExp(exp
->loc
, ea
, e
); // execute ea
1827 e
= semantic(e
, sc
);
1833 void visit(TraitsExp
*e
)
1835 result
= semanticTraits(e
, sc
);
1838 void visit(HaltExp
*e
)
1840 e
->type
= Type::tvoid
;
1844 void visit(IsExp
*e
)
1846 /* is(targ id tok tspec)
1847 * is(targ id : tok2)
1848 * is(targ id == tok2)
1851 //printf("IsExp::semantic(%s)\n", toChars());
1852 if (e
->id
&& !(sc
->flags
& SCOPEcondition
))
1854 e
->error("can only declare type aliases within static if conditionals or static asserts");
1859 Scope
*sc2
= sc
->copy(); // keep sc->flags
1862 sc2
->flags
|= SCOPEfullinst
;
1863 Type
*t
= e
->targ
->trySemantic(e
->loc
, sc2
);
1866 goto Lno
; // errors, so condition is false
1868 if (e
->tok2
!= TOKreserved
)
1873 if (e
->targ
->ty
!= Tstruct
)
1875 if (((TypeStruct
*)e
->targ
)->sym
->isUnionDeclaration())
1881 if (e
->targ
->ty
!= Tstruct
)
1883 if (!((TypeStruct
*)e
->targ
)->sym
->isUnionDeclaration())
1889 if (e
->targ
->ty
!= Tclass
)
1891 if (((TypeClass
*)e
->targ
)->sym
->isInterfaceDeclaration())
1897 if (e
->targ
->ty
!= Tclass
)
1899 if (!((TypeClass
*)e
->targ
)->sym
->isInterfaceDeclaration())
1904 if (!e
->targ
->isConst())
1910 if (!e
->targ
->isImmutable())
1916 if (!e
->targ
->isShared())
1922 if (!e
->targ
->isWild())
1928 // If class or interface, get the base class and interfaces
1929 if (e
->targ
->ty
!= Tclass
)
1933 ClassDeclaration
*cd
= ((TypeClass
*)e
->targ
)->sym
;
1934 Parameters
*args
= new Parameters
;
1935 args
->reserve(cd
->baseclasses
->dim
);
1936 if (cd
->_scope
&& !cd
->symtab
)
1937 cd
->semantic(cd
->_scope
);
1938 for (size_t i
= 0; i
< cd
->baseclasses
->dim
; i
++)
1940 BaseClass
*b
= (*cd
->baseclasses
)[i
];
1941 args
->push(new Parameter(STCin
, b
->type
, NULL
, NULL
));
1943 tded
= new TypeTuple(args
);
1948 if (e
->targ
->ty
!= Tenum
)
1951 tded
= ((TypeEnum
*)e
->targ
)->sym
->getMemtype(e
->loc
);
1954 if (tded
->ty
== Terror
)
1959 if (e
->targ
->ty
!= Tdelegate
)
1961 tded
= ((TypeDelegate
*)e
->targ
)->next
; // the underlying function type
1967 if (e
->targ
->ty
!= Tfunction
)
1971 /* Generate tuple from function parameter types.
1973 assert(tded
->ty
== Tfunction
);
1974 Parameters
*params
= ((TypeFunction
*)tded
)->parameters
;
1975 size_t dim
= Parameter::dim(params
);
1976 Parameters
*args
= new Parameters
;
1978 for (size_t i
= 0; i
< dim
; i
++)
1980 Parameter
*arg
= Parameter::getNth(params
, i
);
1981 assert(arg
&& arg
->type
);
1982 /* If one of the default arguments was an error,
1983 don't return an invalid tuple
1985 if (e
->tok2
== TOKparameters
&& arg
->defaultArg
&&
1986 arg
->defaultArg
->op
== TOKerror
)
1988 args
->push(new Parameter(arg
->storageClass
, arg
->type
,
1989 (e
->tok2
== TOKparameters
) ? arg
->ident
: NULL
,
1990 (e
->tok2
== TOKparameters
) ? arg
->defaultArg
: NULL
));
1992 tded
= new TypeTuple(args
);
1996 /* Get the 'return type' for the function,
1997 * delegate, or pointer to function.
1999 if (e
->targ
->ty
== Tfunction
)
2000 tded
= ((TypeFunction
*)e
->targ
)->next
;
2001 else if (e
->targ
->ty
== Tdelegate
)
2003 tded
= ((TypeDelegate
*)e
->targ
)->next
;
2004 tded
= ((TypeFunction
*)tded
)->next
;
2006 else if (e
->targ
->ty
== Tpointer
&&
2007 ((TypePointer
*)e
->targ
)->next
->ty
== Tfunction
)
2009 tded
= ((TypePointer
*)e
->targ
)->next
;
2010 tded
= ((TypeFunction
*)tded
)->next
;
2017 /* Generate a type tuple of the equivalent types used to determine if a
2018 * function argument of this type can be passed in registers.
2019 * The results of this are highly platform dependent, and intended
2020 * primarly for use in implementing va_arg().
2022 tded
= toArgTypes(e
->targ
);
2024 goto Lno
; // not valid for a parameter
2028 if (e
->targ
->ty
!= Tvector
)
2030 tded
= ((TypeVector
*)e
->targ
)->basetype
;
2038 else if (e
->tspec
&& !e
->id
&& !(e
->parameters
&& e
->parameters
->dim
))
2040 /* Evaluate to true if targ matches tspec
2044 e
->tspec
= e
->tspec
->semantic(e
->loc
, sc
);
2045 //printf("targ = %s, %s\n", e->targ->toChars(), e->targ->deco);
2046 //printf("tspec = %s, %s\n", e->tspec->toChars(), e->tspec->deco);
2047 if (e
->tok
== TOKcolon
)
2049 if (e
->targ
->implicitConvTo(e
->tspec
))
2056 if (e
->targ
->equals(e
->tspec
))
2064 /* Evaluate to true if targ matches tspec.
2065 * If true, declare id as an alias for the specialized type.
2066 * is(targ == tspec, tpl)
2067 * is(targ : tspec, tpl)
2068 * is(targ id == tspec)
2069 * is(targ id : tspec)
2070 * is(targ id == tspec, tpl)
2071 * is(targ id : tspec, tpl)
2074 Identifier
*tid
= e
->id
? e
->id
: Identifier::generateId("__isexp_id");
2075 e
->parameters
->insert(0, new TemplateTypeParameter(e
->loc
, tid
, NULL
, NULL
));
2078 dedtypes
.setDim(e
->parameters
->dim
);
2081 MATCH m
= deduceType(e
->targ
, sc
, e
->tspec
, e
->parameters
, &dedtypes
);
2082 //printf("targ: %s\n", e->targ->toChars());
2083 //printf("tspec: %s\n", e->tspec->toChars());
2084 if (m
<= MATCHnomatch
||
2085 (m
!= MATCHexact
&& e
->tok
== TOKequal
))
2091 tded
= (Type
*)dedtypes
[0];
2096 tiargs
[0] = e
->targ
;
2098 /* Declare trailing parameters
2100 for (size_t i
= 1; i
< e
->parameters
->dim
; i
++)
2102 TemplateParameter
*tp
= (*e
->parameters
)[i
];
2103 Declaration
*s
= NULL
;
2105 m
= tp
->matchArg(e
->loc
, sc
, &tiargs
, i
, e
->parameters
, &dedtypes
, &s
);
2106 if (m
<= MATCHnomatch
)
2110 s
->addMember(sc
, sc
->sds
);
2111 else if (!sc
->insert(s
))
2112 e
->error("declaration %s is already defined", s
->toChars());
2114 unSpeculative(sc
, s
);
2121 /* Declare id as an alias for type targ. Evaluate to true
2132 Tuple
*tup
= isTuple(tded
);
2134 s
= new TupleDeclaration(e
->loc
, e
->id
, &(tup
->objects
));
2136 s
= new AliasDeclaration(e
->loc
, e
->id
, tded
);
2138 /* The reason for the !tup is unclear. It fails Phobos unittests if it is not there.
2139 * More investigation is needed.
2141 if (!tup
&& !sc
->insert(s
))
2142 e
->error("declaration %s is already defined", s
->toChars());
2144 s
->addMember(sc
, sc
->sds
);
2146 unSpeculative(sc
, s
);
2149 result
= new IntegerExp(e
->loc
, 1, Type::tbool
);
2154 result
= new IntegerExp(e
->loc
, 0, Type::tbool
);
2157 void visit(BinAssignExp
*exp
)
2165 Expression
*e
= exp
->op_overload(sc
);
2172 if (exp
->e1
->checkReadModifyWrite(exp
->op
, exp
->e2
))
2175 if (exp
->e1
->op
== TOKarraylength
)
2177 // arr.length op= e2;
2178 e
= ArrayLengthExp::rewriteOpAssign(exp
);
2179 e
= semantic(e
, sc
);
2183 if (exp
->e1
->op
== TOKslice
|| exp
->e1
->type
->ty
== Tarray
|| exp
->e1
->type
->ty
== Tsarray
)
2185 if (exp
->e1
->op
== TOKslice
)
2186 ((SliceExp
*)exp
->e1
)->arrayop
= true;
2189 if (exp
->e2
->implicitConvTo(exp
->e1
->type
->nextOf()))
2192 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
->nextOf());
2194 else if (Expression
*ex
= typeCombine(exp
, sc
))
2199 exp
->type
= exp
->e1
->type
;
2200 result
= arrayOp(exp
, sc
);
2204 exp
->e1
= semantic(exp
->e1
, sc
);
2205 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
2206 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
2207 exp
->type
= exp
->e1
->type
;
2208 if (exp
->checkScalar())
2211 int arith
= (exp
->op
== TOKaddass
|| exp
->op
== TOKminass
|| exp
->op
== TOKmulass
||
2212 exp
->op
== TOKdivass
|| exp
->op
== TOKmodass
|| exp
->op
== TOKpowass
);
2213 int bitwise
= (exp
->op
== TOKandass
|| exp
->op
== TOKorass
|| exp
->op
== TOKxorass
);
2214 int shift
= (exp
->op
== TOKshlass
|| exp
->op
== TOKshrass
|| exp
->op
== TOKushrass
);
2216 if (bitwise
&& exp
->type
->toBasetype()->ty
== Tbool
)
2217 exp
->e2
= exp
->e2
->implicitCastTo(sc
, exp
->type
);
2218 else if (exp
->checkNoBool())
2221 if ((exp
->op
== TOKaddass
|| exp
->op
== TOKminass
) &&
2222 exp
->e1
->type
->toBasetype()->ty
== Tpointer
&&
2223 exp
->e2
->type
->toBasetype()->isintegral())
2225 result
= scaleFactor(exp
, sc
);
2229 if (Expression
*ex
= typeCombine(exp
, sc
))
2235 if (arith
&& exp
->checkArithmeticBin())
2237 if ((bitwise
|| shift
) && exp
->checkIntegralBin())
2241 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
2242 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
2245 if (!Target::isVectorOpSupported(exp
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
2247 result
= exp
->incompatibleTypes();
2251 if (exp
->e1
->op
== TOKerror
|| exp
->e2
->op
== TOKerror
)
2254 e
= exp
->checkOpAssignTypes(sc
);
2255 if (e
->op
== TOKerror
)
2261 assert(e
->op
== TOKassign
|| e
== exp
);
2262 result
= ((BinExp
*)e
)->reorderSettingAAElem(sc
);
2265 void visit(CompileExp
*exp
)
2267 sc
= sc
->startCTFE();
2268 exp
->e1
= semantic(exp
->e1
, sc
);
2269 exp
->e1
= resolveProperties(sc
, exp
->e1
);
2271 if (exp
->e1
->op
== TOKerror
)
2276 if (!exp
->e1
->type
->isString())
2278 exp
->error("argument to mixin must be a string type, not %s", exp
->e1
->type
->toChars());
2281 exp
->e1
= exp
->e1
->ctfeInterpret();
2282 StringExp
*se
= exp
->e1
->toStringExp();
2285 exp
->error("argument to mixin must be a string, not (%s)", exp
->e1
->toChars());
2288 se
= se
->toUTF8(sc
);
2289 unsigned errors
= global
.errors
;
2290 Parser
p(exp
->loc
, sc
->_module
, (utf8_t
*)se
->string
, se
->len
, 0);
2292 //printf("p.loc.linnum = %d\n", p.loc.linnum);
2293 Expression
*e
= p
.parseExpression();
2296 assert(global
.errors
!= errors
); // should have caught all these cases
2299 if (p
.token
.value
!= TOKeof
)
2301 exp
->error("incomplete mixin expression (%s)", se
->toChars());
2304 result
= semantic(e
, sc
);
2307 void visit(ImportExp
*e
)
2312 sc
= sc
->startCTFE();
2313 e
->e1
= semantic(e
->e1
, sc
);
2314 e
->e1
= resolveProperties(sc
, e
->e1
);
2316 e
->e1
= e
->e1
->ctfeInterpret();
2317 if (e
->e1
->op
!= TOKstring
)
2319 e
->error("file name argument must be a string, not (%s)", e
->e1
->toChars());
2322 se
= (StringExp
*)e
->e1
;
2323 se
= se
->toUTF8(sc
);
2324 name
= (char *)se
->string
;
2326 if (!global
.params
.fileImppath
)
2328 e
->error("need -Jpath switch to import text file %s", name
);
2332 /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory
2333 * ('Path Traversal') attacks.
2334 * http://cwe.mitre.org/data/definitions/22.html
2337 name
= FileName::safeSearchPath(global
.filePath
, name
);
2340 e
->error("file %s cannot be found or not in a path specified with -J", se
->toChars());
2344 if (global
.params
.verbose
)
2345 message("file %.*s\t(%s)", (int)se
->len
, (char *)se
->string
, name
);
2346 if (global
.params
.moduleDeps
!= NULL
)
2348 OutBuffer
*ob
= global
.params
.moduleDeps
;
2349 Module
* imod
= sc
->instantiatingModule();
2351 if (!global
.params
.moduleDepsFile
)
2352 ob
->writestring("depsFile ");
2353 ob
->writestring(imod
->toPrettyChars());
2354 ob
->writestring(" (");
2355 escapePath(ob
, imod
->srcfile
->toChars());
2356 ob
->writestring(") : ");
2357 if (global
.params
.moduleDepsFile
)
2358 ob
->writestring("string : ");
2359 ob
->writestring((char *) se
->string
);
2360 ob
->writestring(" (");
2361 escapePath(ob
, name
);
2362 ob
->writestring(")");
2370 e
->error("cannot read file %s", f
.toChars());
2376 se
= new StringExp(e
->loc
, f
.buffer
, f
.len
);
2379 result
= semantic(se
, sc
);
2386 void visit(AssertExp
*exp
)
2388 if (Expression
*ex
= unaSemantic(exp
, sc
))
2393 exp
->e1
= resolveProperties(sc
, exp
->e1
);
2394 // BUG: see if we can do compile time elimination of the Assert
2395 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
2396 exp
->e1
= exp
->e1
->toBoolean(sc
);
2399 exp
->msg
= semantic(exp
->msg
, sc
);
2400 exp
->msg
= resolveProperties(sc
, exp
->msg
);
2401 exp
->msg
= exp
->msg
->implicitCastTo(sc
, Type::tchar
->constOf()->arrayOf());
2402 exp
->msg
= exp
->msg
->optimize(WANTvalue
);
2405 if (exp
->e1
->op
== TOKerror
)
2410 if (exp
->msg
&& exp
->msg
->op
== TOKerror
)
2416 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
2417 bool f2
= exp
->msg
&& checkNonAssignmentArrayOp(exp
->msg
);
2421 if (exp
->e1
->isBool(false))
2423 FuncDeclaration
*fd
= sc
->parent
->isFuncDeclaration();
2425 fd
->hasReturnExp
|= 4;
2426 sc
->callSuper
|= CSXhalt
;
2429 for (size_t i
= 0; i
< sc
->fieldinit_dim
; i
++)
2430 sc
->fieldinit
[i
] |= CSXhalt
;
2433 if (!global
.params
.useAssert
)
2435 Expression
*e
= new HaltExp(exp
->loc
);
2436 e
= semantic(e
, sc
);
2441 exp
->type
= Type::tvoid
;
2445 void visit(DotIdExp
*exp
)
2447 Expression
*e
= semanticY(exp
, sc
, 1);
2448 if (e
&& isDotOpDispatch(e
))
2450 unsigned errors
= global
.startGagging();
2451 e
= resolvePropertiesX(sc
, e
);
2452 if (global
.endGagging(errors
))
2453 e
= NULL
; /* fall down to UFCS */
2460 if (!e
) // if failed to find the property
2462 /* If ident is not a valid property, rewrite:
2467 e
= resolveUFCSProperties(sc
, exp
);
2472 void visit(DotTemplateExp
*e
)
2474 if (Expression
*ex
= unaSemantic(e
, sc
))
2482 void visit(DotVarExp
*exp
)
2490 exp
->var
= exp
->var
->toAlias()->isDeclaration();
2492 exp
->e1
= semantic(exp
->e1
, sc
);
2494 if (TupleDeclaration
*tup
= exp
->var
->isTupleDeclaration())
2499 * tuple(e1.a, e1.b, e1.c)
2501 Expression
*e0
= NULL
;
2502 Expression
*ev
= sc
->func
? extractSideEffect(sc
, "__tup", &e0
, exp
->e1
) : exp
->e1
;
2504 Expressions
*exps
= new Expressions
;
2505 exps
->reserve(tup
->objects
->dim
);
2506 for (size_t i
= 0; i
< tup
->objects
->dim
; i
++)
2508 RootObject
*o
= (*tup
->objects
)[i
];
2510 if (o
->dyncast() == DYNCAST_EXPRESSION
)
2512 e
= (Expression
*)o
;
2513 if (e
->op
== TOKdsymbol
)
2515 Dsymbol
*s
= ((DsymbolExp
*)e
)->s
;
2516 e
= new DotVarExp(exp
->loc
, ev
, s
->isDeclaration());
2519 else if (o
->dyncast() == DYNCAST_DSYMBOL
)
2521 e
= new DsymbolExp(exp
->loc
, (Dsymbol
*)o
);
2523 else if (o
->dyncast() == DYNCAST_TYPE
)
2525 e
= new TypeExp(exp
->loc
, (Type
*)o
);
2529 exp
->error("%s is not an expression", o
->toChars());
2535 Expression
*e
= new TupleExp(exp
->loc
, e0
, exps
);
2536 e
= semantic(e
, sc
);
2541 exp
->e1
= exp
->e1
->addDtorHook(sc
);
2543 Type
*t1
= exp
->e1
->type
;
2545 if (FuncDeclaration
*fd
= exp
->var
->isFuncDeclaration())
2547 // for functions, do checks after overload resolution
2548 if (!fd
->functionSemantic())
2551 /* Bugzilla 13843: If fd obviously has no overloads, we should
2552 * normalize AST, and it will give a chance to wrap fd with FuncExp.
2554 if (fd
->isNested() || fd
->isFuncLiteralDeclaration())
2557 Expression
*e
= resolve(exp
->loc
, sc
, fd
, false);
2558 result
= Expression::combine(exp
->e1
, e
);
2562 exp
->type
= fd
->type
;
2565 else if (exp
->var
->isOverDeclaration())
2567 exp
->type
= Type::tvoid
; // ambiguous type?
2571 exp
->type
= exp
->var
->type
;
2572 if (!exp
->type
&& global
.errors
)
2574 // var is goofed up, just return 0
2579 if (t1
->ty
== Tpointer
)
2582 exp
->type
= exp
->type
->addMod(t1
->mod
);
2584 Dsymbol
*vparent
= exp
->var
->toParent();
2585 AggregateDeclaration
*ad
= vparent
? vparent
->isAggregateDeclaration() : NULL
;
2587 if (Expression
*e1x
= getRightThis(exp
->loc
, sc
, ad
, exp
->e1
, exp
->var
, 1))
2591 /* Later checkRightThis will report correct error for invalid field variable access.
2593 Expression
*e
= new VarExp(exp
->loc
, exp
->var
);
2594 e
= semantic(e
, sc
);
2598 checkAccess(exp
->loc
, sc
, exp
->e1
, exp
->var
);
2600 VarDeclaration
*v
= exp
->var
->isVarDeclaration();
2601 if (v
&& (v
->isDataseg() || (v
->storage_class
& STCmanifest
)))
2603 Expression
*e
= expandVar(WANTvalue
, v
);
2611 if (v
&& v
->isDataseg()) // fix bugzilla 8238
2614 checkAccess(exp
->loc
, sc
, exp
->e1
, v
);
2615 Expression
*e
= new VarExp(exp
->loc
, v
);
2616 e
= new CommaExp(exp
->loc
, exp
->e1
, e
);
2617 e
= semantic(e
, sc
);
2623 //printf("-DotVarExp::semantic('%s')\n", exp->toChars());
2627 void visit(DotTemplateInstanceExp
*exp
)
2629 // Indicate we need to resolve by UFCS.
2630 Expression
*e
= semanticY(exp
, sc
, 1);
2632 e
= resolveUFCSProperties(sc
, exp
);
2636 void visit(DelegateExp
*e
)
2644 e
->e1
= semantic(e
->e1
, sc
);
2645 e
->type
= new TypeDelegate(e
->func
->type
);
2646 e
->type
= e
->type
->semantic(e
->loc
, sc
);
2647 FuncDeclaration
*f
= e
->func
->toAliasFunc();
2648 AggregateDeclaration
*ad
= f
->toParent()->isAggregateDeclaration();
2650 e
->e1
= getRightThis(e
->loc
, sc
, ad
, e
->e1
, f
);
2651 if (f
->type
->ty
== Tfunction
)
2653 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
2654 if (!MODmethodConv(e
->e1
->type
->mod
, f
->type
->mod
))
2656 OutBuffer thisBuf
, funcBuf
;
2657 MODMatchToBuffer(&thisBuf
, e
->e1
->type
->mod
, tf
->mod
);
2658 MODMatchToBuffer(&funcBuf
, tf
->mod
, e
->e1
->type
->mod
);
2659 e
->error("%smethod %s is not callable using a %s%s",
2660 funcBuf
.peekString(), f
->toPrettyChars(), thisBuf
.peekString(), e
->e1
->toChars());
2664 if (ad
&& ad
->isClassDeclaration() && ad
->type
!= e
->e1
->type
)
2666 // A downcast is required for interfaces, see Bugzilla 3706
2667 e
->e1
= new CastExp(e
->loc
, e
->e1
, ad
->type
);
2668 e
->e1
= semantic(e
->e1
, sc
);
2673 void visit(DotTypeExp
*exp
)
2681 if (Expression
*e
= unaSemantic(exp
, sc
))
2687 exp
->type
= exp
->sym
->getType()->addMod(exp
->e1
->type
->mod
);
2691 void visit(CallExp
*exp
)
2695 result
= exp
; // semantic() already run
2700 Objects
*tiargs
= NULL
; // initial list of template arguments
2701 Expression
*ethis
= NULL
;
2703 Expression
*e1org
= exp
->e1
;
2705 if (exp
->e1
->op
== TOKcomma
)
2707 /* Rewrite (a,b)(args) as (a,(b(args)))
2709 CommaExp
*ce
= (CommaExp
*)exp
->e1
;
2712 result
= semantic(ce
, sc
);
2716 if (exp
->e1
->op
== TOKdelegate
)
2718 DelegateExp
*de
= (DelegateExp
*)exp
->e1
;
2719 exp
->e1
= new DotVarExp(de
->loc
, de
->e1
, de
->func
, de
->hasOverloads
);
2720 result
= semantic(exp
, sc
);
2724 if (exp
->e1
->op
== TOKfunction
)
2726 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
2727 preFunctionParameters(sc
, exp
->arguments
))
2732 // Run e1 semantic even if arguments have any errors
2733 FuncExp
*fe
= (FuncExp
*)exp
->e1
;
2734 exp
->e1
= callExpSemantic(fe
, sc
, exp
->arguments
);
2735 if (exp
->e1
->op
== TOKerror
)
2742 if (Expression
*ex
= resolveUFCS(sc
, exp
))
2749 * foo!(tiargs)(funcargs)
2751 if (exp
->e1
->op
== TOKscope
)
2753 ScopeExp
*se
= (ScopeExp
*)exp
->e1
;
2754 TemplateInstance
*ti
= se
->sds
->isTemplateInstance();
2757 /* Attempt to instantiate ti. If that works, go with it.
2758 * If not, go with partial explicit specialization.
2760 WithScopeSymbol
*withsym
;
2761 if (!ti
->findTempDecl(sc
, &withsym
) ||
2762 !ti
->semanticTiargs(sc
))
2766 if (withsym
&& withsym
->withstate
->wthis
)
2768 exp
->e1
= new VarExp(exp
->e1
->loc
, withsym
->withstate
->wthis
);
2769 exp
->e1
= new DotTemplateInstanceExp(exp
->e1
->loc
, exp
->e1
, ti
);
2772 if (ti
->needsTypeInference(sc
, 1))
2774 /* Go with partial explicit specialization
2776 tiargs
= ti
->tiargs
;
2777 assert(ti
->tempdecl
);
2778 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
2779 exp
->e1
= new TemplateExp(exp
->loc
, td
);
2780 else if (OverDeclaration
*od
= ti
->tempdecl
->isOverDeclaration())
2781 exp
->e1
= new VarExp(exp
->loc
, od
);
2783 exp
->e1
= new OverExp(exp
->loc
, ti
->tempdecl
->isOverloadSet());
2787 Expression
*e1x
= semantic(exp
->e1
, sc
);
2788 if (e1x
->op
== TOKerror
)
2799 * expr.foo!(tiargs)(funcargs)
2802 if (exp
->e1
->op
== TOKdotti
&& !exp
->e1
->type
)
2804 DotTemplateInstanceExp
*se
= (DotTemplateInstanceExp
*)exp
->e1
;
2805 TemplateInstance
*ti
= se
->ti
;
2807 /* Attempt to instantiate ti. If that works, go with it.
2808 * If not, go with partial explicit specialization.
2810 if (!se
->findTempDecl(sc
) ||
2811 !ti
->semanticTiargs(sc
))
2815 if (ti
->needsTypeInference(sc
, 1))
2817 /* Go with partial explicit specialization
2819 tiargs
= ti
->tiargs
;
2820 assert(ti
->tempdecl
);
2821 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
2822 exp
->e1
= new DotTemplateExp(exp
->loc
, se
->e1
, td
);
2823 else if (OverDeclaration
*od
= ti
->tempdecl
->isOverDeclaration())
2825 exp
->e1
= new DotVarExp(exp
->loc
, se
->e1
, od
, true);
2828 exp
->e1
= new DotExp(exp
->loc
, se
->e1
, new OverExp(exp
->loc
, ti
->tempdecl
->isOverloadSet()));
2832 Expression
*e1x
= semantic(exp
->e1
, sc
);
2833 if (e1x
->op
== TOKerror
)
2844 //printf("Lagain: %s\n", exp->toChars());
2846 if (exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
)
2848 // semantic() run later for these
2852 if (exp
->e1
->op
== TOKdotid
)
2854 DotIdExp
*die
= (DotIdExp
*)exp
->e1
;
2855 exp
->e1
= semantic(die
, sc
);
2856 /* Look for e1 having been rewritten to expr.opDispatch!(string)
2857 * We handle such earlier, so go back.
2858 * Note that in the rewrite, we carefully did not run semantic() on e1
2860 if (exp
->e1
->op
== TOKdotti
&& !exp
->e1
->type
)
2870 exp
->error("recursive evaluation of %s", exp
->toChars());
2874 Expression
*ex
= unaSemantic(exp
, sc
);
2883 /* Look for e1 being a lazy parameter
2885 if (exp
->e1
->op
== TOKvar
)
2887 VarExp
*ve
= (VarExp
*)exp
->e1
;
2888 if (ve
->var
->storage_class
& STClazy
)
2890 // lazy paramaters can be called without violating purity and safety
2891 Type
*tw
= ve
->var
->type
;
2892 Type
*tc
= ve
->var
->type
->substWildTo(MODconst
);
2893 TypeFunction
*tf
= new TypeFunction(NULL
, tc
, 0, LINKd
, STCsafe
| STCpure
);
2894 (tf
= (TypeFunction
*)tf
->semantic(exp
->loc
, sc
))->next
= tw
; // hack for bug7757
2895 TypeDelegate
*t
= new TypeDelegate(tf
);
2896 ve
->type
= t
->semantic(exp
->loc
, sc
);
2898 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
2899 if (v
&& ve
->checkPurity(sc
, v
))
2903 if (exp
->e1
->op
== TOKsymoff
&& ((SymOffExp
*)exp
->e1
)->hasOverloads
)
2905 SymOffExp
*se
= (SymOffExp
*)exp
->e1
;
2906 exp
->e1
= new VarExp(se
->loc
, se
->var
, true);
2907 exp
->e1
= semantic(exp
->e1
, sc
);
2909 else if (exp
->e1
->op
== TOKdot
)
2911 DotExp
*de
= (DotExp
*) exp
->e1
;
2913 if (de
->e2
->op
== TOKoverloadset
)
2916 tthis
= de
->e1
->type
;
2920 else if (exp
->e1
->op
== TOKstar
&& exp
->e1
->type
->ty
== Tfunction
)
2922 // Rewrite (*fp)(arguments) to fp(arguments)
2923 exp
->e1
= ((PtrExp
*)exp
->e1
)->e1
;
2927 t1
= exp
->e1
->type
? exp
->e1
->type
->toBasetype() : NULL
;
2929 if (exp
->e1
->op
== TOKerror
)
2934 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
2935 preFunctionParameters(sc
, exp
->arguments
))
2940 // Check for call operator overload
2943 if (t1
->ty
== Tstruct
)
2945 StructDeclaration
*sd
= ((TypeStruct
*)t1
)->sym
;
2946 sd
->size(exp
->loc
); // Resolve forward references to construct object
2947 if (sd
->sizeok
!= SIZEOKdone
)
2950 sd
->ctor
= sd
->searchCtor();
2952 // First look for constructor
2953 if (exp
->e1
->op
== TOKtype
&& sd
->ctor
)
2955 if (!sd
->noDefaultCtor
&& !(exp
->arguments
&& exp
->arguments
->dim
))
2958 StructLiteralExp
*sle
= new StructLiteralExp(exp
->loc
, sd
, NULL
, exp
->e1
->type
);
2959 if (!sd
->fill(exp
->loc
, sle
->elements
, true))
2961 if (checkFrameAccess(exp
->loc
, sc
, sd
, sle
->elements
->dim
))
2963 // Bugzilla 14556: Set concrete type to avoid further redundant semantic().
2964 sle
->type
= exp
->e1
->type
;
2966 /* Constructor takes a mutable object, so don't use
2967 * the immutable initializer symbol.
2969 sle
->useStaticInit
= false;
2971 Expression
*e
= sle
;
2972 if (CtorDeclaration
*cf
= sd
->ctor
->isCtorDeclaration())
2974 e
= new DotVarExp(exp
->loc
, e
, cf
, true);
2976 else if (TemplateDeclaration
*td
= sd
->ctor
->isTemplateDeclaration())
2978 e
= new DotTemplateExp(exp
->loc
, e
, td
);
2980 else if (OverloadSet
*os
= sd
->ctor
->isOverloadSet())
2982 e
= new DotExp(exp
->loc
, e
, new OverExp(exp
->loc
, os
));
2986 e
= new CallExp(exp
->loc
, e
, exp
->arguments
);
2987 result
= semantic(e
, sc
);
2990 // No constructor, look for overload of opCall
2991 if (search_function(sd
, Id::call
))
2992 goto L1
; // overload of opCall, therefore it's a call
2994 if (exp
->e1
->op
!= TOKtype
)
2996 if (sd
->aliasthis
&& exp
->e1
->type
!= exp
->att1
)
2998 if (!exp
->att1
&& exp
->e1
->type
->checkAliasThisRec())
2999 exp
->att1
= exp
->e1
->type
;
3000 exp
->e1
= resolveAliasThis(sc
, exp
->e1
);
3003 exp
->error("%s %s does not overload ()", sd
->kind(), sd
->toChars());
3007 /* It's a struct literal
3010 Expression
*e
= new StructLiteralExp(exp
->loc
, sd
, exp
->arguments
, exp
->e1
->type
);
3011 result
= semantic(e
, sc
);
3014 else if (t1
->ty
== Tclass
)
3017 // Rewrite as e1.call(arguments)
3018 Expression
*e
= new DotIdExp(exp
->loc
, exp
->e1
, Id::call
);
3019 e
= new CallExp(exp
->loc
, e
, exp
->arguments
);
3020 result
= semantic(e
, sc
);
3023 else if (exp
->e1
->op
== TOKtype
&& t1
->isscalar())
3027 // Make sure to use the the enum type itself rather than its
3028 // base type (see bugzilla 16346)
3029 if (exp
->e1
->type
->ty
== Tenum
)
3034 if (!exp
->arguments
|| exp
->arguments
->dim
== 0)
3036 e
= t1
->defaultInitLiteral(exp
->loc
);
3038 else if (exp
->arguments
->dim
== 1)
3040 e
= (*exp
->arguments
)[0];
3041 e
= e
->implicitCastTo(sc
, t1
);
3042 e
= new CastExp(exp
->loc
, e
, t1
);
3046 exp
->error("more than one argument for construction of %s", t1
->toChars());
3049 result
= semantic(e
, sc
);
3054 if ((exp
->e1
->op
== TOKdotvar
&& t1
->ty
== Tfunction
) ||
3055 exp
->e1
->op
== TOKdottd
)
3057 UnaExp
*ue
= (UnaExp
*)(exp
->e1
);
3059 Expression
*ue1
= ue
->e1
;
3060 Expression
*ue1old
= ue1
; // need for 'right this' check
3062 if (ue1
->op
== TOKvar
&&
3063 (v
= ((VarExp
*)ue1
)->var
->isVarDeclaration()) != NULL
&&
3066 ue
->e1
= new TypeExp(ue1
->loc
, ue1
->type
);
3071 DotTemplateExp
*dte
;
3073 if (exp
->e1
->op
== TOKdotvar
)
3075 dve
= (DotVarExp
*)(exp
->e1
);
3083 dte
= (DotTemplateExp
*)(exp
->e1
);
3087 // Do overload resolution
3088 exp
->f
= resolveFuncCall(exp
->loc
, sc
, s
, tiargs
, ue1
? ue1
->type
: NULL
, exp
->arguments
);
3089 if (!exp
->f
|| exp
->f
->errors
|| exp
->f
->type
->ty
== Terror
)
3091 if (exp
->f
->interfaceVirtual
)
3093 /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent
3095 BaseClass
*b
= exp
->f
->interfaceVirtual
;
3096 ClassDeclaration
*ad2
= b
->sym
;
3097 ue
->e1
= ue
->e1
->castTo(sc
, ad2
->type
->addMod(ue
->e1
->type
->mod
));
3098 ue
->e1
= semantic(ue
->e1
, sc
);
3100 int vi
= exp
->f
->findVtblIndex((Dsymbols
*)&ad2
->vtbl
, (int)ad2
->vtbl
.dim
);
3102 exp
->f
= ad2
->vtbl
[vi
]->isFuncDeclaration();
3105 if (exp
->f
->needThis())
3107 AggregateDeclaration
*ad
= exp
->f
->toParent2()->isAggregateDeclaration();
3108 ue
->e1
= getRightThis(exp
->loc
, sc
, ad
, ue
->e1
, exp
->f
);
3109 if (ue
->e1
->op
== TOKerror
)
3115 tthis
= ue
->e1
->type
;
3116 if (!(exp
->f
->type
->ty
== Tfunction
&& ((TypeFunction
*)exp
->f
->type
)->isscope
))
3118 if (global
.params
.vsafe
&& checkParamArgumentEscape(sc
, exp
->f
, Id::This
, ethis
, false))
3123 /* Cannot call public functions from inside invariant
3124 * (because then the invariant would have infinite recursion)
3126 if (sc
->func
&& sc
->func
->isInvariantDeclaration() &&
3127 ue
->e1
->op
== TOKthis
&&
3128 exp
->f
->addPostInvariant()
3131 exp
->error("cannot call public/export function %s from invariant", exp
->f
->toChars());
3135 exp
->checkDeprecated(sc
, exp
->f
);
3136 exp
->checkPurity(sc
, exp
->f
);
3137 exp
->checkSafety(sc
, exp
->f
);
3138 exp
->checkNogc(sc
, exp
->f
);
3139 checkAccess(exp
->loc
, sc
, ue
->e1
, exp
->f
);
3140 if (!exp
->f
->needThis())
3142 exp
->e1
= Expression::combine(ue
->e1
, new VarExp(exp
->loc
, exp
->f
, false));
3146 if (ue1old
->checkRightThis(sc
))
3148 if (exp
->e1
->op
== TOKdotvar
)
3151 exp
->e1
->type
= exp
->f
->type
;
3155 exp
->e1
= new DotVarExp(exp
->loc
, dte
->e1
, exp
->f
, false);
3156 exp
->e1
= semantic(exp
->e1
, sc
);
3157 if (exp
->e1
->op
== TOKerror
)
3159 ue
= (UnaExp
*)exp
->e1
;
3162 // See if we need to adjust the 'this' pointer
3163 AggregateDeclaration
*ad
= exp
->f
->isThis();
3164 ClassDeclaration
*cd
= ue
->e1
->type
->isClassHandle();
3165 if (ad
&& cd
&& ad
->isClassDeclaration())
3167 if (ue
->e1
->op
== TOKdottype
)
3169 ue
->e1
= ((DotTypeExp
*)ue
->e1
)->e1
;
3170 exp
->directcall
= true;
3172 else if (ue
->e1
->op
== TOKsuper
)
3173 exp
->directcall
= true;
3174 else if ((cd
->storage_class
& STCfinal
) != 0) // Bugzilla 14211
3175 exp
->directcall
= true;
3179 ue
->e1
= ue
->e1
->castTo(sc
, ad
->type
->addMod(ue
->e1
->type
->mod
));
3180 ue
->e1
= semantic(ue
->e1
, sc
);
3184 // If we've got a pointer to a function then deference it
3185 // https://issues.dlang.org/show_bug.cgi?id=16483
3186 if (exp
->e1
->type
->ty
== Tpointer
&& exp
->e1
->type
->nextOf()->ty
== Tfunction
)
3188 Expression
*e
= new PtrExp(exp
->loc
, exp
->e1
);
3189 e
->type
= exp
->e1
->type
->nextOf();
3194 else if (exp
->e1
->op
== TOKsuper
)
3196 // Base class constructor call
3197 AggregateDeclaration
*ad
= sc
->func
? sc
->func
->isThis() : NULL
;
3198 ClassDeclaration
*cd
= ad
? ad
->isClassDeclaration() : NULL
;
3199 if (!cd
|| !cd
->baseClass
|| !sc
->func
->isCtorDeclaration())
3201 exp
->error("super class constructor call must be in a constructor");
3204 if (!cd
->baseClass
->ctor
)
3206 exp
->error("no super class constructor for %s", cd
->baseClass
->toChars());
3210 if (!sc
->intypeof
&& !(sc
->callSuper
& CSXhalt
))
3212 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
3213 exp
->error("constructor calls not allowed in loops or after labels");
3214 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
3215 exp
->error("multiple constructor calls");
3216 if ((sc
->callSuper
& CSXreturn
) && !(sc
->callSuper
& CSXany_ctor
))
3217 exp
->error("an earlier return statement skips constructor");
3218 sc
->callSuper
|= CSXany_ctor
| CSXsuper_ctor
;
3221 tthis
= cd
->type
->addMod(sc
->func
->type
->mod
);
3222 if (OverloadSet
*os
= cd
->baseClass
->ctor
->isOverloadSet())
3223 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, NULL
, tthis
, exp
->arguments
);
3225 exp
->f
= resolveFuncCall(exp
->loc
, sc
, cd
->baseClass
->ctor
, NULL
, tthis
, exp
->arguments
, 0);
3226 if (!exp
->f
|| exp
->f
->errors
)
3228 exp
->checkDeprecated(sc
, exp
->f
);
3229 exp
->checkPurity(sc
, exp
->f
);
3230 exp
->checkSafety(sc
, exp
->f
);
3231 exp
->checkNogc(sc
, exp
->f
);
3232 checkAccess(exp
->loc
, sc
, NULL
, exp
->f
);
3234 exp
->e1
= new DotVarExp(exp
->e1
->loc
, exp
->e1
, exp
->f
, false);
3235 exp
->e1
= semantic(exp
->e1
, sc
);
3238 else if (exp
->e1
->op
== TOKthis
)
3240 // same class constructor call
3241 AggregateDeclaration
*ad
= sc
->func
? sc
->func
->isThis() : NULL
;
3242 if (!ad
|| !sc
->func
->isCtorDeclaration())
3244 exp
->error("constructor call must be in a constructor");
3248 if (!sc
->intypeof
&& !(sc
->callSuper
& CSXhalt
))
3250 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
3251 exp
->error("constructor calls not allowed in loops or after labels");
3252 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
3253 exp
->error("multiple constructor calls");
3254 if ((sc
->callSuper
& CSXreturn
) && !(sc
->callSuper
& CSXany_ctor
))
3255 exp
->error("an earlier return statement skips constructor");
3256 sc
->callSuper
|= CSXany_ctor
| CSXthis_ctor
;
3259 tthis
= ad
->type
->addMod(sc
->func
->type
->mod
);
3260 if (OverloadSet
*os
= ad
->ctor
->isOverloadSet())
3261 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, NULL
, tthis
, exp
->arguments
);
3263 exp
->f
= resolveFuncCall(exp
->loc
, sc
, ad
->ctor
, NULL
, tthis
, exp
->arguments
, 0);
3264 if (!exp
->f
|| exp
->f
->errors
)
3266 exp
->checkDeprecated(sc
, exp
->f
);
3267 exp
->checkPurity(sc
, exp
->f
);
3268 exp
->checkSafety(sc
, exp
->f
);
3269 exp
->checkNogc(sc
, exp
->f
);
3270 //checkAccess(exp->loc, sc, NULL, exp->f); // necessary?
3272 exp
->e1
= new DotVarExp(exp
->e1
->loc
, exp
->e1
, exp
->f
, false);
3273 exp
->e1
= semantic(exp
->e1
, sc
);
3276 // BUG: this should really be done by checking the static
3278 if (exp
->f
== sc
->func
)
3280 exp
->error("cyclic constructor call");
3284 else if (exp
->e1
->op
== TOKoverloadset
)
3286 OverloadSet
*os
= ((OverExp
*)exp
->e1
)->vars
;
3287 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, tiargs
, tthis
, exp
->arguments
);
3291 exp
->e1
= new DotVarExp(exp
->loc
, ethis
, exp
->f
, false);
3293 exp
->e1
= new VarExp(exp
->loc
, exp
->f
, false);
3298 exp
->error("function expected before (), not '%s'", exp
->e1
->toChars());
3301 else if (t1
->ty
== Terror
)
3305 else if (t1
->ty
!= Tfunction
)
3311 if (exp
->e1
->op
== TOKfunction
)
3313 // function literal that direct called is always inferred.
3314 assert(((FuncExp
*)exp
->e1
)->fd
);
3315 exp
->f
= ((FuncExp
*)exp
->e1
)->fd
;
3316 tf
= (TypeFunction
*)exp
->f
->type
;
3317 p
= "function literal";
3319 else if (t1
->ty
== Tdelegate
)
3321 TypeDelegate
*td
= (TypeDelegate
*)t1
;
3322 assert(td
->next
->ty
== Tfunction
);
3323 tf
= (TypeFunction
*)(td
->next
);
3326 else if (t1
->ty
== Tpointer
&& ((TypePointer
*)t1
)->next
->ty
== Tfunction
)
3328 tf
= (TypeFunction
*)(((TypePointer
*)t1
)->next
);
3329 p
= "function pointer";
3331 else if (exp
->e1
->op
== TOKdotvar
&&
3332 ((DotVarExp
*)exp
->e1
)->var
->isOverDeclaration())
3334 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
3335 exp
->f
= resolveFuncCall(exp
->loc
, sc
, dve
->var
, tiargs
, dve
->e1
->type
, exp
->arguments
, 2);
3338 if (exp
->f
->needThis())
3341 dve
->type
= exp
->f
->type
;
3342 dve
->hasOverloads
= false;
3345 exp
->e1
= new VarExp(dve
->loc
, exp
->f
, false);
3346 Expression
*e
= new CommaExp(exp
->loc
, dve
->e1
, exp
);
3347 result
= semantic(e
, sc
);
3350 else if (exp
->e1
->op
== TOKvar
&&
3351 ((VarExp
*)exp
->e1
)->var
->isOverDeclaration())
3353 s
= ((VarExp
*)exp
->e1
)->var
;
3356 else if (exp
->e1
->op
== TOKtemplate
)
3358 s
= ((TemplateExp
*)exp
->e1
)->td
;
3360 exp
->f
= resolveFuncCall(exp
->loc
, sc
, s
, tiargs
, NULL
, exp
->arguments
);
3361 if (!exp
->f
|| exp
->f
->errors
)
3363 if (exp
->f
->needThis())
3367 // Supply an implicit 'this', as in
3369 Expression
*ex
= new ThisExp(exp
->loc
);
3370 ex
= semantic(ex
, sc
);
3371 exp
->e1
= new DotVarExp(exp
->loc
, ex
, exp
->f
, false);
3374 else if (isNeedThisScope(sc
, exp
->f
))
3376 exp
->error("need 'this' for '%s' of type '%s'", exp
->f
->toChars(), exp
->f
->type
->toChars());
3380 exp
->e1
= new VarExp(exp
->e1
->loc
, exp
->f
, false);
3385 exp
->error("function expected before (), not %s of type %s", exp
->e1
->toChars(), exp
->e1
->type
->toChars());
3389 if (!tf
->callMatch(NULL
, exp
->arguments
))
3394 argExpTypesToCBuffer(&buf
, exp
->arguments
);
3397 tthis
->modToBuffer(&buf
);
3399 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3400 ::error(exp
->loc
, "%s %s %s is not callable using argument types %s",
3401 p
, exp
->e1
->toChars(), parametersTypeToChars(tf
->parameters
, tf
->varargs
),
3407 // Purity and safety check should run after testing arguments matching
3410 exp
->checkPurity(sc
, exp
->f
);
3411 exp
->checkSafety(sc
, exp
->f
);
3412 exp
->checkNogc(sc
, exp
->f
);
3413 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3416 else if (sc
->func
&& sc
->intypeof
!= 1 && !(sc
->flags
& SCOPEctfe
))
3419 if (!tf
->purity
&& !(sc
->flags
& SCOPEdebug
) && sc
->func
->setImpure())
3421 exp
->error("pure %s '%s' cannot call impure %s '%s'",
3422 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3425 if (!tf
->isnogc
&& sc
->func
->setGC())
3427 exp
->error("@nogc %s '%s' cannot call non-@nogc %s '%s'",
3428 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3431 if (tf
->trust
<= TRUSTsystem
&& sc
->func
->setUnsafe())
3433 exp
->error("@safe %s '%s' cannot call @system %s '%s'",
3434 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3441 if (t1
->ty
== Tpointer
)
3443 Expression
*e
= new PtrExp(exp
->loc
, exp
->e1
);
3449 else if (exp
->e1
->op
== TOKvar
)
3451 // Do overload resolution
3452 VarExp
*ve
= (VarExp
*)exp
->e1
;
3454 exp
->f
= ve
->var
->isFuncDeclaration();
3458 if (ve
->hasOverloads
)
3459 exp
->f
= resolveFuncCall(exp
->loc
, sc
, exp
->f
, tiargs
, NULL
, exp
->arguments
, 2);
3462 exp
->f
= exp
->f
->toAliasFunc();
3463 TypeFunction
*tf
= (TypeFunction
*)exp
->f
->type
;
3464 if (!tf
->callMatch(NULL
, exp
->arguments
))
3469 argExpTypesToCBuffer(&buf
, exp
->arguments
);
3472 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3473 ::error(exp
->loc
, "%s %s is not callable using argument types %s",
3474 exp
->e1
->toChars(), parametersTypeToChars(tf
->parameters
, tf
->varargs
),
3480 if (!exp
->f
|| exp
->f
->errors
)
3483 if (exp
->f
->needThis())
3485 // Change the ancestor lambdas to delegate before hasThis(sc) call.
3486 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3491 // Supply an implicit 'this', as in
3494 Expression
*ex
= new ThisExp(exp
->loc
);
3495 ex
= semantic(ex
, sc
);
3496 exp
->e1
= new DotVarExp(exp
->loc
, ex
, ve
->var
);
3497 // Note: we cannot use f directly, because further overload resolution
3498 // through the supplied 'this' may cause different result.
3501 else if (isNeedThisScope(sc
, exp
->f
))
3503 exp
->error("need 'this' for '%s' of type '%s'", exp
->f
->toChars(), exp
->f
->type
->toChars());
3508 exp
->checkDeprecated(sc
, exp
->f
);
3509 exp
->checkPurity(sc
, exp
->f
);
3510 exp
->checkSafety(sc
, exp
->f
);
3511 exp
->checkNogc(sc
, exp
->f
);
3512 checkAccess(exp
->loc
, sc
, NULL
, exp
->f
);
3513 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3519 if (ve
->hasOverloads
)
3521 exp
->e1
= new VarExp(ve
->loc
, exp
->f
, false);
3522 exp
->e1
->type
= exp
->f
->type
;
3526 assert(t1
->ty
== Tfunction
);
3528 Expression
*argprefix
;
3529 if (!exp
->arguments
)
3530 exp
->arguments
= new Expressions();
3531 if (functionParameters(exp
->loc
, sc
, (TypeFunction
*)(t1
), tthis
, exp
->arguments
, exp
->f
, &exp
->type
, &argprefix
))
3536 exp
->e1
= e1org
; // Bugzilla 10922, avoid recursive expression printing
3537 exp
->error("forward reference to inferred return type of function call '%s'", exp
->toChars());
3541 if (exp
->f
&& exp
->f
->tintro
)
3543 Type
*t
= exp
->type
;
3545 TypeFunction
*tf
= (TypeFunction
*)exp
->f
->tintro
;
3547 if (tf
->next
->isBaseOf(t
, &offset
) && offset
)
3549 exp
->type
= tf
->next
;
3550 result
= Expression::combine(argprefix
, exp
->castTo(sc
, t
));
3555 // Handle the case of a direct lambda call
3556 if (exp
->f
&& exp
->f
->isFuncLiteralDeclaration() &&
3557 sc
->func
&& !sc
->intypeof
)
3559 exp
->f
->tookAddressOf
= 0;
3562 result
= Expression::combine(argprefix
, exp
);
3565 void visit(AddrExp
*exp
)
3573 if (Expression
*ex
= unaSemantic(exp
, sc
))
3578 int wasCond
= exp
->e1
->op
== TOKquestion
;
3579 if (exp
->e1
->op
== TOKdotti
)
3581 DotTemplateInstanceExp
* dti
= (DotTemplateInstanceExp
*)exp
->e1
;
3582 TemplateInstance
*ti
= dti
->ti
;
3584 //assert(ti->needsTypeInference(sc));
3586 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
3588 Dsymbol
*s
= ti
->toAlias();
3589 FuncDeclaration
*f
= s
->isFuncDeclaration();
3592 exp
->e1
= new DotVarExp(exp
->e1
->loc
, dti
->e1
, f
);
3593 exp
->e1
= semantic(exp
->e1
, sc
);
3597 else if (exp
->e1
->op
== TOKscope
)
3599 TemplateInstance
*ti
= ((ScopeExp
*)exp
->e1
)->sds
->isTemplateInstance();
3602 //assert(ti->needsTypeInference(sc));
3604 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
3606 Dsymbol
*s
= ti
->toAlias();
3607 FuncDeclaration
*f
= s
->isFuncDeclaration();
3610 exp
->e1
= new VarExp(exp
->e1
->loc
, f
);
3611 exp
->e1
= semantic(exp
->e1
, sc
);
3615 exp
->e1
= exp
->e1
->toLvalue(sc
, NULL
);
3616 if (exp
->e1
->op
== TOKerror
)
3621 if (checkNonAssignmentArrayOp(exp
->e1
))
3626 exp
->error("cannot take address of %s", exp
->e1
->toChars());
3630 bool hasOverloads
= false;
3631 if (FuncDeclaration
*f
= isFuncAddress(exp
, &hasOverloads
))
3633 if (!hasOverloads
&& f
->checkForwardRef(exp
->loc
))
3636 else if (!exp
->e1
->type
->deco
)
3638 if (exp
->e1
->op
== TOKvar
)
3640 VarExp
*ve
= (VarExp
*)exp
->e1
;
3641 Declaration
*d
= ve
->var
;
3642 exp
->error("forward reference to %s %s", d
->kind(), d
->toChars());
3645 exp
->error("forward reference to %s", exp
->e1
->toChars());
3649 exp
->type
= exp
->e1
->type
->pointerTo();
3651 // See if this should really be a delegate
3652 if (exp
->e1
->op
== TOKdotvar
)
3654 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
3655 FuncDeclaration
*f
= dve
->var
->isFuncDeclaration();
3658 f
= f
->toAliasFunc(); // FIXME, should see overloads - Bugzilla 1983
3659 if (!dve
->hasOverloads
)
3664 e
= new DelegateExp(exp
->loc
, dve
->e1
, f
, dve
->hasOverloads
);
3665 else // It is a function pointer. Convert &v.f() --> (v, &V.f())
3666 e
= new CommaExp(exp
->loc
, dve
->e1
, new AddrExp(exp
->loc
, new VarExp(exp
->loc
, f
, dve
->hasOverloads
)));
3667 e
= semantic(e
, sc
);
3672 // Look for misaligned pointer in @safe mode
3673 if (checkUnsafeAccess(sc
, dve
, !exp
->type
->isMutable(), true))
3676 if (dve
->e1
->op
== TOKvar
&& global
.params
.vsafe
)
3678 VarExp
*ve
= (VarExp
*)dve
->e1
;
3679 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3682 if (!checkAddressVar(sc
, exp
, v
))
3686 else if ((dve
->e1
->op
== TOKthis
|| dve
->e1
->op
== TOKsuper
) && global
.params
.vsafe
)
3688 ThisExp
*ve
= (ThisExp
*)dve
->e1
;
3689 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3690 if (v
&& v
->storage_class
& STCref
)
3692 if (!checkAddressVar(sc
, exp
, v
))
3697 else if (exp
->e1
->op
== TOKvar
)
3699 VarExp
*ve
= (VarExp
*)exp
->e1
;
3701 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3704 if (!checkAddressVar(sc
, exp
, v
))
3707 ve
->checkPurity(sc
, v
);
3710 FuncDeclaration
*f
= ve
->var
->isFuncDeclaration();
3713 /* Because nested functions cannot be overloaded,
3714 * mark here that we took its address because castTo()
3715 * may not be called with an exact match.
3717 if (!ve
->hasOverloads
|| f
->isNested())
3721 if (f
->isFuncLiteralDeclaration())
3723 if (!f
->FuncDeclaration::isNested())
3725 /* Supply a 'null' for a this pointer if no this is available
3727 Expression
*e
= new DelegateExp(exp
->loc
, new NullExp(exp
->loc
, Type::tnull
), f
, ve
->hasOverloads
);
3728 e
= semantic(e
, sc
);
3733 Expression
*e
= new DelegateExp(exp
->loc
, exp
->e1
, f
, ve
->hasOverloads
);
3734 e
= semantic(e
, sc
);
3742 /* Should probably supply 'this' after overload resolution,
3745 Expression
*ethis
= new ThisExp(exp
->loc
);
3746 Expression
*e
= new DelegateExp(exp
->loc
, ethis
, f
, ve
->hasOverloads
);
3747 e
= semantic(e
, sc
);
3751 if (sc
->func
&& !sc
->intypeof
)
3753 if (sc
->func
->setUnsafe())
3755 exp
->error("'this' reference necessary to take address of member %s in @safe function %s",
3756 f
->toChars(), sc
->func
->toChars());
3762 else if ((exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
) && global
.params
.vsafe
)
3764 ThisExp
*ve
= (ThisExp
*)exp
->e1
;
3765 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3768 if (!checkAddressVar(sc
, exp
, v
))
3772 else if (exp
->e1
->op
== TOKcall
)
3774 CallExp
*ce
= (CallExp
*)exp
->e1
;
3775 if (ce
->e1
->type
->ty
== Tfunction
)
3777 TypeFunction
*tf
= (TypeFunction
*)ce
->e1
->type
;
3778 if (tf
->isref
&& sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
3780 exp
->error("cannot take address of ref return of %s() in @safe function %s",
3781 ce
->e1
->toChars(), sc
->func
->toChars());
3785 else if (exp
->e1
->op
== TOKindex
)
3790 * check 'a' the same as for a regular variable
3792 IndexExp
*ei
= (IndexExp
*)exp
->e1
;
3793 Type
*tyi
= ei
->e1
->type
->toBasetype();
3794 if (tyi
->ty
== Tsarray
&& ei
->e1
->op
== TOKvar
)
3796 VarExp
*ve
= (VarExp
*)ei
->e1
;
3797 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3800 if (!checkAddressVar(sc
, exp
, v
))
3803 ve
->checkPurity(sc
, v
);
3809 /* a ? b : c was transformed to *(a ? &b : &c), but we still
3810 * need to do safety checks
3812 assert(exp
->e1
->op
== TOKstar
);
3813 PtrExp
*pe
= (PtrExp
*)exp
->e1
;
3814 assert(pe
->e1
->op
== TOKquestion
);
3815 CondExp
*ce
= (CondExp
*)pe
->e1
;
3816 assert(ce
->e1
->op
== TOKaddress
);
3817 assert(ce
->e2
->op
== TOKaddress
);
3819 // Re-run semantic on the address expressions only
3820 ce
->e1
->type
= NULL
;
3821 ce
->e1
= semantic(ce
->e1
, sc
);
3822 ce
->e2
->type
= NULL
;
3823 ce
->e2
= semantic(ce
->e2
, sc
);
3826 result
= exp
->optimize(WANTvalue
);
3829 void visit(PtrExp
*exp
)
3837 Expression
*e
= exp
->op_overload(sc
);
3844 Type
*tb
= exp
->e1
->type
->toBasetype();
3848 exp
->type
= ((TypePointer
*)tb
)->next
;
3853 exp
->error("using * on an array is no longer supported; use *(%s).ptr instead", exp
->e1
->toChars());
3854 exp
->type
= ((TypeArray
*)tb
)->next
;
3855 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
->pointerTo());
3859 exp
->error("can only * a pointer, not a '%s'", exp
->e1
->type
->toChars());
3865 if (exp
->checkValue())
3871 void visit(NegExp
*exp
)
3879 Expression
*e
= exp
->op_overload(sc
);
3886 exp
->type
= exp
->e1
->type
;
3887 Type
*tb
= exp
->type
->toBasetype();
3888 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
3890 if (!isArrayOpValid(exp
->e1
))
3892 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
3899 if (!Target::isVectorOpSupported(tb
, exp
->op
))
3901 result
= exp
->incompatibleTypes();
3904 if (exp
->e1
->checkNoBool())
3906 if (exp
->e1
->checkArithmetic())
3912 void visit(UAddExp
*exp
)
3916 Expression
*e
= exp
->op_overload(sc
);
3923 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
))
3925 result
= exp
->incompatibleTypes();
3928 if (exp
->e1
->checkNoBool())
3930 if (exp
->e1
->checkArithmetic())
3936 void visit(ComExp
*exp
)
3944 Expression
*e
= exp
->op_overload(sc
);
3951 exp
->type
= exp
->e1
->type
;
3952 Type
*tb
= exp
->type
->toBasetype();
3953 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
3955 if (!isArrayOpValid(exp
->e1
))
3957 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
3964 if (!Target::isVectorOpSupported(tb
, exp
->op
))
3966 result
= exp
->incompatibleTypes();
3969 if (exp
->e1
->checkNoBool())
3971 if (exp
->e1
->checkIntegral())
3977 void visit(NotExp
*e
)
3985 setNoderefOperand(e
);
3987 // Note there is no operator overload
3988 if (Expression
*ex
= unaSemantic(e
, sc
))
3994 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
3995 if (e
->e1
->op
== TOKtype
)
3996 e
->e1
= resolveAliasThis(sc
, e
->e1
);
3998 e
->e1
= resolveProperties(sc
, e
->e1
);
3999 e
->e1
= e
->e1
->toBoolean(sc
);
4000 if (e
->e1
->type
== Type::terror
)
4006 if (!Target::isVectorOpSupported(e
->e1
->type
->toBasetype(), e
->op
))
4008 result
= e
->incompatibleTypes();
4011 // Bugzilla 13910: Today NotExp can take an array as its operand.
4012 if (checkNonAssignmentArrayOp(e
->e1
))
4015 e
->type
= Type::tbool
;
4019 void visit(DeleteExp
*exp
)
4021 if (Expression
*ex
= unaSemantic(exp
, sc
))
4026 exp
->e1
= resolveProperties(sc
, exp
->e1
);
4027 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, NULL
);
4028 if (exp
->e1
->op
== TOKerror
)
4033 exp
->type
= Type::tvoid
;
4035 AggregateDeclaration
*ad
= NULL
;
4036 Type
*tb
= exp
->e1
->type
->toBasetype();
4040 ClassDeclaration
*cd
= ((TypeClass
*)tb
)->sym
;
4042 if (cd
->isCOMinterface())
4043 { /* Because COM classes are deleted by IUnknown.Release()
4045 exp
->error("cannot delete instance of COM interface %s", cd
->toChars());
4053 tb
= ((TypePointer
*)tb
)->next
->toBasetype();
4054 if (tb
->ty
== Tstruct
)
4056 ad
= ((TypeStruct
*)tb
)->sym
;
4057 FuncDeclaration
*f
= ad
->aggDelete
;
4058 FuncDeclaration
*fd
= ad
->dtor
;
4062 semanticTypeInfo(sc
, tb
);
4067 * ea = copy e1 to a tmp to do side effects only once
4068 * eb = call destructor
4069 * ec = call deallocator
4071 Expression
*ea
= NULL
;
4072 Expression
*eb
= NULL
;
4073 Expression
*ec
= NULL
;
4074 VarDeclaration
*v
= NULL
;
4078 v
= copyToTemp(0, "__tmpea", exp
->e1
);
4080 ea
= new DeclarationExp(exp
->loc
, v
);
4086 Expression
*e
= ea
? new VarExp(exp
->loc
, v
) : exp
->e1
;
4087 e
= new DotVarExp(Loc(), e
, fd
, false);
4088 eb
= new CallExp(exp
->loc
, e
);
4089 eb
= semantic(eb
, sc
);
4094 Type
*tpv
= Type::tvoid
->pointerTo();
4095 Expression
*e
= ea
? new VarExp(exp
->loc
, v
) : exp
->e1
->castTo(sc
, tpv
);
4096 e
= new CallExp(exp
->loc
, new VarExp(exp
->loc
, f
, false), e
);
4097 ec
= semantic(e
, sc
);
4099 ea
= Expression::combine(ea
, eb
);
4100 ea
= Expression::combine(ea
, ec
);
4109 Type
*tv
= tb
->nextOf()->baseElemOf();
4110 if (tv
->ty
== Tstruct
)
4112 ad
= ((TypeStruct
*)tv
)->sym
;
4114 semanticTypeInfo(sc
, ad
->type
);
4119 exp
->error("cannot delete type %s", exp
->e1
->type
->toChars());
4128 err
|= exp
->checkPurity(sc
, ad
->dtor
);
4129 err
|= exp
->checkSafety(sc
, ad
->dtor
);
4130 err
|= exp
->checkNogc(sc
, ad
->dtor
);
4132 if (ad
->aggDelete
&& tb
->ty
!= Tarray
)
4134 err
|= exp
->checkPurity(sc
, ad
->aggDelete
);
4135 err
|= exp
->checkSafety(sc
, ad
->aggDelete
);
4136 err
|= exp
->checkNogc(sc
, ad
->aggDelete
);
4142 if (!sc
->intypeof
&& sc
->func
&&
4144 sc
->func
->setUnsafe())
4146 exp
->error("%s is not @safe but is used in @safe function %s", exp
->toChars(), sc
->func
->toChars());
4155 void visit(CastExp
*exp
)
4157 //static int x; assert(++x < 10);
4166 exp
->to
= exp
->to
->semantic(exp
->loc
, sc
);
4167 if (exp
->to
== Type::terror
)
4170 if (!exp
->to
->hasPointers())
4171 setNoderefOperand(exp
);
4173 // When e1 is a template lambda, this cast may instantiate it with
4175 exp
->e1
= inferType(exp
->e1
, exp
->to
);
4178 if (Expression
*ex
= unaSemantic(exp
, sc
))
4183 Expression
*e1x
= resolveProperties(sc
, exp
->e1
);
4184 if (e1x
->op
== TOKerror
)
4189 if (e1x
->checkType())
4195 exp
->error("cannot cast %s", exp
->e1
->toChars());
4199 if (!exp
->to
) // Handle cast(const) and cast(immutable), etc.
4201 exp
->to
= exp
->e1
->type
->castMod(exp
->mod
);
4202 exp
->to
= exp
->to
->semantic(exp
->loc
, sc
);
4203 if (exp
->to
== Type::terror
)
4207 if (exp
->to
->ty
== Ttuple
)
4209 exp
->error("cannot cast %s to tuple type %s", exp
->e1
->toChars(), exp
->to
->toChars());
4212 if (exp
->e1
->type
->ty
!= Tvoid
||
4213 (exp
->e1
->op
== TOKfunction
&& exp
->to
->ty
== Tvoid
) ||
4214 exp
->e1
->op
== TOKtype
||
4215 exp
->e1
->op
== TOKtemplate
)
4217 if (exp
->e1
->checkValue())
4221 // cast(void) is used to mark e1 as unused, so it is safe
4222 if (exp
->to
->ty
== Tvoid
)
4224 exp
->type
= exp
->to
;
4229 if (!exp
->to
->equals(exp
->e1
->type
) && exp
->mod
== (unsigned char)~0)
4231 if (Expression
*e
= exp
->op_overload(sc
))
4233 result
= e
->implicitCastTo(sc
, exp
->to
);
4238 Type
*t1b
= exp
->e1
->type
->toBasetype();
4239 Type
*tob
= exp
->to
->toBasetype();
4241 if (tob
->ty
== Tstruct
&& !tob
->equals(t1b
))
4249 // Rewrite as to.call(e1)
4250 Expression
*e
= new TypeExp(exp
->loc
, exp
->to
);
4251 e
= new CallExp(exp
->loc
, e
, exp
->e1
);
4252 e
= trySemantic(e
, sc
);
4260 if (!t1b
->equals(tob
) && (t1b
->ty
== Tarray
|| t1b
->ty
== Tsarray
))
4262 if (checkNonAssignmentArrayOp(exp
->e1
))
4266 // Look for casting to a vector type
4267 if (tob
->ty
== Tvector
&& t1b
->ty
!= Tvector
)
4269 result
= new VectorExp(exp
->loc
, exp
->e1
, exp
->to
);
4273 Expression
*ex
= exp
->e1
->castTo(sc
, exp
->to
);
4274 if (ex
->op
== TOKerror
)
4280 // Check for unsafe casts
4281 if (sc
->func
&& !sc
->intypeof
&&
4282 !isSafeCast(ex
, t1b
, tob
) &&
4283 sc
->func
->setUnsafe())
4285 exp
->error("cast from %s to %s not allowed in safe code", exp
->e1
->type
->toChars(), exp
->to
->toChars());
4292 void visit(VectorExp
*exp
)
4300 exp
->e1
= semantic(exp
->e1
, sc
);
4301 exp
->type
= exp
->to
->semantic(exp
->loc
, sc
);
4302 if (exp
->e1
->op
== TOKerror
|| exp
->type
->ty
== Terror
)
4308 Type
*tb
= exp
->type
->toBasetype();
4309 assert(tb
->ty
== Tvector
);
4310 TypeVector
*tv
= (TypeVector
*)tb
;
4311 Type
*te
= tv
->elementType();
4312 exp
->dim
= (int)(tv
->size(exp
->loc
) / te
->size(exp
->loc
));
4314 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
4316 if (exp
->e1
->op
== TOKarrayliteral
)
4318 for (size_t i
= 0; i
< exp
->dim
; i
++)
4320 // Do not stop on first error - check all AST nodes even if error found
4321 res
|= checkVectorElem(exp
, ((ArrayLiteralExp
*)exp
->e1
)->getElement(i
));
4324 else if (exp
->e1
->type
->ty
== Tvoid
)
4325 res
= checkVectorElem(exp
, exp
->e1
);
4327 Expression
*e
= exp
;
4333 void visit(SliceExp
*exp
)
4341 // operator overloading should be handled in ArrayExp already.
4343 if (Expression
*ex
= unaSemantic(exp
, sc
))
4348 exp
->e1
= resolveProperties(sc
, exp
->e1
);
4349 if (exp
->e1
->op
== TOKtype
&& exp
->e1
->type
->ty
!= Ttuple
)
4351 if (exp
->lwr
|| exp
->upr
)
4353 exp
->error("cannot slice type '%s'", exp
->e1
->toChars());
4356 Expression
*e
= new TypeExp(exp
->loc
, exp
->e1
->type
->arrayOf());
4357 result
= semantic(e
, sc
);
4360 if (!exp
->lwr
&& !exp
->upr
)
4362 if (exp
->e1
->op
== TOKarrayliteral
)
4364 // Convert [a,b,c][] to [a,b,c]
4365 Type
*t1b
= exp
->e1
->type
->toBasetype();
4366 Expression
*e
= exp
->e1
;
4367 if (t1b
->ty
== Tsarray
)
4370 e
->type
= t1b
->nextOf()->arrayOf();
4375 if (exp
->e1
->op
== TOKslice
)
4377 // Convert e[][] to e[]
4378 SliceExp
*se
= (SliceExp
*)exp
->e1
;
4379 if (!se
->lwr
&& !se
->upr
)
4385 if (isArrayOpOperand(exp
->e1
))
4387 // Convert (a[]+b[])[] to a[]+b[]
4392 if (exp
->e1
->op
== TOKerror
)
4397 if (exp
->e1
->type
->ty
== Terror
)
4400 Type
*t1b
= exp
->e1
->type
->toBasetype();
4401 if (t1b
->ty
== Tpointer
)
4403 if (((TypePointer
*)t1b
)->next
->ty
== Tfunction
)
4405 exp
->error("cannot slice function pointer %s", exp
->e1
->toChars());
4408 if (!exp
->lwr
|| !exp
->upr
)
4410 exp
->error("need upper and lower bound to slice pointer");
4413 if (sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
4415 exp
->error("pointer slicing not allowed in safe functions");
4419 else if (t1b
->ty
== Tarray
)
4422 else if (t1b
->ty
== Tsarray
)
4424 if (!exp
->arrayop
&& global
.params
.vsafe
)
4426 /* Slicing a static array is like taking the address of it.
4427 * Perform checks as if e[] was &e
4429 VarDeclaration
*v
= NULL
;
4430 if (exp
->e1
->op
== TOKdotvar
)
4432 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
4433 if (dve
->e1
->op
== TOKvar
)
4435 VarExp
*ve
= (VarExp
*)dve
->e1
;
4436 v
= ve
->var
->isVarDeclaration();
4438 else if (dve
->e1
->op
== TOKthis
|| dve
->e1
->op
== TOKsuper
)
4440 ThisExp
*ve
= (ThisExp
*)dve
->e1
;
4441 v
= ve
->var
->isVarDeclaration();
4442 if (v
&& !(v
->storage_class
& STCref
))
4446 else if (exp
->e1
->op
== TOKvar
)
4448 VarExp
*ve
= (VarExp
*)exp
->e1
;
4449 v
= ve
->var
->isVarDeclaration();
4451 else if (exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
)
4453 ThisExp
*ve
= (ThisExp
*)exp
->e1
;
4454 v
= ve
->var
->isVarDeclaration();
4459 if (!checkAddressVar(sc
, exp
, v
))
4464 else if (t1b
->ty
== Ttuple
)
4466 if (!exp
->lwr
&& !exp
->upr
)
4471 if (!exp
->lwr
|| !exp
->upr
)
4473 exp
->error("need upper and lower bound to slice tuple");
4477 else if (t1b
->ty
== Tvector
)
4479 // Convert e1 to corresponding static array
4480 TypeVector
*tv1
= (TypeVector
*)t1b
;
4481 t1b
= tv1
->basetype
;
4482 t1b
= t1b
->castMod(tv1
->mod
);
4483 exp
->e1
->type
= t1b
;
4487 exp
->error("%s cannot be sliced with []",
4488 t1b
->ty
== Tvoid
? exp
->e1
->toChars() : t1b
->toChars());
4492 /* Run semantic on lwr and upr.
4495 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
|| t1b
->ty
== Ttuple
)
4497 // Create scope for 'length' variable
4498 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, exp
);
4499 sym
->loc
= exp
->loc
;
4500 sym
->parent
= sc
->scopesym
;
4505 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4506 exp
->lwr
= semantic(exp
->lwr
, sc
);
4507 exp
->lwr
= resolveProperties(sc
, exp
->lwr
);
4508 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4509 exp
->lwr
= exp
->lwr
->implicitCastTo(sc
, Type::tsize_t
);
4513 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4514 exp
->upr
= semantic(exp
->upr
, sc
);
4515 exp
->upr
= resolveProperties(sc
, exp
->upr
);
4516 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4517 exp
->upr
= exp
->upr
->implicitCastTo(sc
, Type::tsize_t
);
4521 if ((exp
->lwr
&& exp
->lwr
->type
== Type::terror
) ||
4522 (exp
->upr
&& exp
->upr
->type
== Type::terror
))
4527 if (t1b
->ty
== Ttuple
)
4529 exp
->lwr
= exp
->lwr
->ctfeInterpret();
4530 exp
->upr
= exp
->upr
->ctfeInterpret();
4531 uinteger_t i1
= exp
->lwr
->toUInteger();
4532 uinteger_t i2
= exp
->upr
->toUInteger();
4537 if (exp
->e1
->op
== TOKtuple
) // slicing an expression tuple
4539 te
= (TupleExp
*)exp
->e1
;
4541 length
= te
->exps
->dim
;
4543 else if (exp
->e1
->op
== TOKtype
) // slicing a type tuple
4546 tup
= (TypeTuple
*)t1b
;
4547 length
= Parameter::dim(tup
->arguments
);
4552 if (i2
< i1
|| length
< i2
)
4554 exp
->error("string slice [%llu .. %llu] is out of bounds", i1
, i2
);
4558 size_t j1
= (size_t) i1
;
4559 size_t j2
= (size_t) i2
;
4561 if (exp
->e1
->op
== TOKtuple
)
4563 Expressions
*exps
= new Expressions
;
4564 exps
->setDim(j2
- j1
);
4565 for (size_t i
= 0; i
< j2
- j1
; i
++)
4567 (*exps
)[i
] = (*te
->exps
)[j1
+ i
];
4569 e
= new TupleExp(exp
->loc
, te
->e0
, exps
);
4573 Parameters
*args
= new Parameters
;
4574 args
->reserve(j2
- j1
);
4575 for (size_t i
= j1
; i
< j2
; i
++)
4577 Parameter
*arg
= Parameter::getNth(tup
->arguments
, i
);
4580 e
= new TypeExp(exp
->e1
->loc
, new TypeTuple(args
));
4582 e
= semantic(e
, sc
);
4587 exp
->type
= t1b
->nextOf()->arrayOf();
4588 // Allow typedef[] -> typedef[]
4589 if (exp
->type
->equals(t1b
))
4590 exp
->type
= exp
->e1
->type
;
4592 if (exp
->lwr
&& exp
->upr
)
4594 exp
->lwr
= exp
->lwr
->optimize(WANTvalue
);
4595 exp
->upr
= exp
->upr
->optimize(WANTvalue
);
4597 IntRange lwrRange
= getIntRange(exp
->lwr
);
4598 IntRange uprRange
= getIntRange(exp
->upr
);
4600 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
)
4602 Expression
*el
= new ArrayLengthExp(exp
->loc
, exp
->e1
);
4603 el
= semantic(el
, sc
);
4604 el
= el
->optimize(WANTvalue
);
4605 if (el
->op
== TOKint64
)
4607 dinteger_t length
= el
->toInteger();
4608 IntRange
bounds(SignExtendedNumber(0), SignExtendedNumber(length
));
4609 exp
->upperIsInBounds
= bounds
.contains(uprRange
);
4612 else if (t1b
->ty
== Tpointer
)
4614 exp
->upperIsInBounds
= true;
4619 exp
->lowerIsLessThanUpper
= (lwrRange
.imax
<= uprRange
.imin
);
4621 //printf("upperIsInBounds = %d lowerIsLessThanUpper = %d\n", upperIsInBounds, lowerIsLessThanUpper);
4627 void visit(ArrayLengthExp
*e
)
4635 if (Expression
*ex
= unaSemantic(e
, sc
))
4640 e
->e1
= resolveProperties(sc
, e
->e1
);
4642 e
->type
= Type::tsize_t
;
4646 void visit(IntervalExp
*e
)
4654 Expression
*le
= e
->lwr
;
4655 le
= semantic(le
, sc
);
4656 le
= resolveProperties(sc
, le
);
4658 Expression
*ue
= e
->upr
;
4659 ue
= semantic(ue
, sc
);
4660 ue
= resolveProperties(sc
, ue
);
4662 if (le
->op
== TOKerror
)
4667 if (ue
->op
== TOKerror
)
4676 e
->type
= Type::tvoid
;
4680 void visit(DelegatePtrExp
*e
)
4685 e
->e1
= resolveProperties(sc
, e
->e1
);
4687 if (e
->e1
->op
== TOKerror
)
4692 e
->type
= Type::tvoidptr
;
4697 void visit(DelegateFuncptrExp
*e
)
4702 e
->e1
= resolveProperties(sc
, e
->e1
);
4704 if (e
->e1
->op
== TOKerror
)
4709 e
->type
= e
->e1
->type
->nextOf()->pointerTo();
4714 void visit(ArrayExp
*exp
)
4718 Expression
*e
= exp
->op_overload(sc
);
4725 if (isAggregate(exp
->e1
->type
))
4726 exp
->error("no [] operator overload for type %s", exp
->e1
->type
->toChars());
4728 exp
->error("only one index allowed to index %s", exp
->e1
->type
->toChars());
4732 void visit(DotExp
*exp
)
4734 exp
->e1
= semantic(exp
->e1
, sc
);
4735 exp
->e2
= semantic(exp
->e2
, sc
);
4737 if (exp
->e1
->op
== TOKtype
)
4742 if (exp
->e2
->op
== TOKtype
)
4747 if (exp
->e2
->op
== TOKtemplate
)
4749 TemplateDeclaration
*td
= ((TemplateExp
*)exp
->e2
)->td
;
4750 Expression
*e
= new DotTemplateExp(exp
->loc
, exp
->e1
, td
);
4751 result
= semantic(e
, sc
);
4755 exp
->type
= exp
->e2
->type
;
4759 void visit(CommaExp
*e
)
4767 // Allow `((a,b),(x,y))`
4768 if (e
->allowCommaExp
)
4770 if (e
->e1
&& e
->e1
->op
== TOKcomma
)
4771 ((CommaExp
*)e
->e1
)->allowCommaExp
= true;
4772 if (e
->e2
&& e
->e2
->op
== TOKcomma
)
4773 ((CommaExp
*)e
->e2
)->allowCommaExp
= true;
4776 if (Expression
*ex
= binSemanticProp(e
, sc
))
4781 e
->e1
= e
->e1
->addDtorHook(sc
);
4783 if (checkNonAssignmentArrayOp(e
->e1
))
4786 e
->type
= e
->e2
->type
;
4787 if (e
->type
!= Type::tvoid
&& !e
->allowCommaExp
&& !e
->isGenerated
)
4788 e
->deprecation("Using the result of a comma expression is deprecated");
4792 void visit(IndexExp
*exp
)
4800 // operator overloading should be handled in ArrayExp already.
4803 exp
->e1
= semantic(exp
->e1
, sc
);
4804 assert(exp
->e1
->type
); // semantic() should already be run on it
4805 if (exp
->e1
->op
== TOKtype
&& exp
->e1
->type
->ty
!= Ttuple
)
4807 exp
->e2
= semantic(exp
->e2
, sc
);
4808 exp
->e2
= resolveProperties(sc
, exp
->e2
);
4810 if (exp
->e2
->op
== TOKtype
)
4811 nt
= new TypeAArray(exp
->e1
->type
, exp
->e2
->type
);
4813 nt
= new TypeSArray(exp
->e1
->type
, exp
->e2
);
4814 Expression
*e
= new TypeExp(exp
->loc
, nt
);
4815 result
= semantic(e
, sc
);
4818 if (exp
->e1
->op
== TOKerror
)
4823 if (exp
->e1
->type
->ty
== Terror
)
4826 // Note that unlike C we do not implement the int[ptr]
4828 Type
*t1b
= exp
->e1
->type
->toBasetype();
4830 if (t1b
->ty
== Tvector
)
4832 // Convert e1 to corresponding static array
4833 TypeVector
*tv1
= (TypeVector
*)t1b
;
4834 t1b
= tv1
->basetype
;
4835 t1b
= t1b
->castMod(tv1
->mod
);
4836 exp
->e1
->type
= t1b
;
4839 /* Run semantic on e2
4842 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
|| t1b
->ty
== Ttuple
)
4844 // Create scope for 'length' variable
4845 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, exp
);
4846 sym
->loc
= exp
->loc
;
4847 sym
->parent
= sc
->scopesym
;
4850 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4851 exp
->e2
= semantic(exp
->e2
, sc
);
4852 exp
->e2
= resolveProperties(sc
, exp
->e2
);
4853 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4854 if (exp
->e2
->op
== TOKtuple
)
4856 TupleExp
*te
= (TupleExp
*)exp
->e2
;
4857 if (te
->exps
&& te
->exps
->dim
== 1)
4858 exp
->e2
= Expression::combine(te
->e0
, (*te
->exps
)[0]); // bug 4444 fix
4862 if (exp
->e2
->type
== Type::terror
)
4865 if (checkNonAssignmentArrayOp(exp
->e1
))
4871 if (((TypePointer
*)t1b
)->next
->ty
== Tfunction
)
4873 exp
->error("cannot index function pointer %s", exp
->e1
->toChars());
4876 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4877 if (exp
->e2
->type
== Type::terror
)
4879 exp
->e2
= exp
->e2
->optimize(WANTvalue
);
4880 if (exp
->e2
->op
== TOKint64
&& exp
->e2
->toInteger() == 0)
4882 else if (sc
->func
&& sc
->func
->setUnsafe())
4884 exp
->error("safe function '%s' cannot index pointer '%s'",
4885 sc
->func
->toPrettyChars(), exp
->e1
->toChars());
4888 exp
->type
= ((TypeNext
*)t1b
)->next
;
4892 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4893 if (exp
->e2
->type
== Type::terror
)
4895 exp
->type
= ((TypeNext
*)t1b
)->next
;
4900 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4901 if (exp
->e2
->type
== Type::terror
)
4903 exp
->type
= t1b
->nextOf();
4909 TypeAArray
*taa
= (TypeAArray
*)t1b
;
4910 /* We can skip the implicit conversion if they differ only by
4911 * constness (Bugzilla 2684, see also bug 2954b)
4913 if (!arrayTypeCompatibleWithoutCasting(exp
->e2
->type
, taa
->index
))
4915 exp
->e2
= exp
->e2
->implicitCastTo(sc
, taa
->index
); // type checking
4916 if (exp
->e2
->type
== Type::terror
)
4920 semanticTypeInfo(sc
, taa
);
4922 exp
->type
= taa
->next
;
4928 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4929 if (exp
->e2
->type
== Type::terror
)
4931 exp
->e2
= exp
->e2
->ctfeInterpret();
4932 uinteger_t index
= exp
->e2
->toUInteger();
4937 if (exp
->e1
->op
== TOKtuple
)
4939 te
= (TupleExp
*)exp
->e1
;
4941 length
= te
->exps
->dim
;
4943 else if (exp
->e1
->op
== TOKtype
)
4946 tup
= (TypeTuple
*)t1b
;
4947 length
= Parameter::dim(tup
->arguments
);
4952 if (length
<= index
)
4954 exp
->error("array index [%llu] is outside array bounds [0 .. %llu]",
4955 index
, (ulonglong
)length
);
4960 if (exp
->e1
->op
== TOKtuple
)
4962 e
= (*te
->exps
)[(size_t)index
];
4963 e
= Expression::combine(te
->e0
, e
);
4966 e
= new TypeExp(exp
->e1
->loc
, Parameter::getNth(tup
->arguments
, (size_t)index
)->type
);
4972 exp
->error("%s must be an array or pointer type, not %s",
4973 exp
->e1
->toChars(), exp
->e1
->type
->toChars());
4977 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
)
4979 Expression
*el
= new ArrayLengthExp(exp
->loc
, exp
->e1
);
4980 el
= semantic(el
, sc
);
4981 el
= el
->optimize(WANTvalue
);
4982 if (el
->op
== TOKint64
)
4984 exp
->e2
= exp
->e2
->optimize(WANTvalue
);
4985 dinteger_t length
= el
->toInteger();
4988 IntRange
bounds(SignExtendedNumber(0), SignExtendedNumber(length
- 1));
4989 exp
->indexIsInBounds
= bounds
.contains(getIntRange(exp
->e2
));
4997 void visit(PostExp
*exp
)
5005 if (Expression
*ex
= binSemantic(exp
, sc
))
5010 Expression
*e1x
= resolveProperties(sc
, exp
->e1
);
5011 if (e1x
->op
== TOKerror
)
5018 Expression
*e
= exp
->op_overload(sc
);
5025 if (exp
->e1
->checkReadModifyWrite(exp
->op
))
5027 if (exp
->e1
->op
== TOKslice
)
5029 const char *s
= exp
->op
== TOKplusplus
? "increment" : "decrement";
5030 exp
->error("cannot post-%s array slice '%s', use pre-%s instead", s
, exp
->e1
->toChars(), s
);
5034 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
5036 Type
*t1
= exp
->e1
->type
->toBasetype();
5037 if (t1
->ty
== Tclass
|| t1
->ty
== Tstruct
|| exp
->e1
->op
== TOKarraylength
)
5039 /* Check for operator overloading,
5040 * but rewrite in terms of ++e instead of e++
5043 /* If e1 is not trivial, take a reference to it
5045 Expression
*de
= NULL
;
5046 if (exp
->e1
->op
!= TOKvar
&& exp
->e1
->op
!= TOKarraylength
)
5049 VarDeclaration
*v
= copyToTemp(STCref
, "__postref", exp
->e1
);
5050 de
= new DeclarationExp(exp
->loc
, v
);
5051 exp
->e1
= new VarExp(exp
->e1
->loc
, v
);
5055 * auto tmp = e1; ++e1; tmp
5057 VarDeclaration
*tmp
= copyToTemp(0, "__pitmp", exp
->e1
);
5058 Expression
*ea
= new DeclarationExp(exp
->loc
, tmp
);
5060 Expression
*eb
= exp
->e1
->syntaxCopy();
5061 eb
= new PreExp(exp
->op
== TOKplusplus
? TOKpreplusplus
: TOKpreminusminus
, exp
->loc
, eb
);
5063 Expression
*ec
= new VarExp(exp
->loc
, tmp
);
5065 // Combine de,ea,eb,ec
5067 ea
= new CommaExp(exp
->loc
, de
, ea
);
5068 e
= new CommaExp(exp
->loc
, ea
, eb
);
5069 e
= new CommaExp(exp
->loc
, e
, ec
);
5070 e
= semantic(e
, sc
);
5075 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
5078 if (exp
->e1
->checkScalar())
5080 if (exp
->e1
->checkNoBool())
5083 if (exp
->e1
->type
->ty
== Tpointer
)
5084 e
= scaleFactor(exp
, sc
);
5086 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
5087 e
->type
= exp
->e1
->type
;
5091 void visit(PreExp
*exp
)
5093 Expression
*e
= exp
->op_overload(sc
);
5094 // printf("PreExp::semantic('%s')\n", exp->toChars());
5102 // Rewrite as e1+=1 or e1-=1
5103 if (exp
->op
== TOKpreplusplus
)
5104 e
= new AddAssignExp(exp
->loc
, exp
->e1
, new IntegerExp(exp
->loc
, 1, Type::tint32
));
5106 e
= new MinAssignExp(exp
->loc
, exp
->e1
, new IntegerExp(exp
->loc
, 1, Type::tint32
));
5107 result
= semantic(e
, sc
);
5110 void visit(AssignExp
*exp
)
5112 //printf("e1->op = %d, '%s'\n", exp->e1->op, Token::toChars(exp->e1->op));
5113 //printf("e2->op = %d, '%s'\n", exp->e2->op, Token::toChars(exp->e2->op));
5120 Expression
*e1old
= exp
->e1
;
5122 if (exp
->e2
->op
== TOKcomma
)
5124 /* Rewrite to get rid of the comma from rvalue
5126 if (!((CommaExp
*)exp
->e2
)->isGenerated
)
5127 exp
->deprecation("Using the result of a comma expression is deprecated");
5129 exp
->e2
= Expression::extractLast(exp
->e2
, &e0
);
5130 Expression
*e
= Expression::combine(e0
, exp
);
5131 result
= semantic(e
, sc
);
5135 /* Look for operator overloading of a[arguments] = e2.
5136 * Do it before e1->semantic() otherwise the ArrayExp will have been
5137 * converted to unary operator overloading already.
5139 if (exp
->e1
->op
== TOKarray
)
5143 ArrayExp
*ae
= (ArrayExp
*)exp
->e1
;
5144 ae
->e1
= semantic(ae
->e1
, sc
);
5145 ae
->e1
= resolveProperties(sc
, ae
->e1
);
5146 Expression
*ae1old
= ae
->e1
;
5148 const bool maybeSlice
=
5149 (ae
->arguments
->dim
== 0 ||
5150 (ae
->arguments
->dim
== 1 && (*ae
->arguments
)[0]->op
== TOKinterval
));
5151 IntervalExp
*ie
= NULL
;
5152 if (maybeSlice
&& ae
->arguments
->dim
)
5154 assert((*ae
->arguments
)[0]->op
== TOKinterval
);
5155 ie
= (IntervalExp
*)(*ae
->arguments
)[0];
5160 if (ae
->e1
->op
== TOKerror
)
5165 Expression
*e0
= NULL
;
5166 Expression
*ae1save
= ae
->e1
;
5167 ae
->lengthVar
= NULL
;
5169 Type
*t1b
= ae
->e1
->type
->toBasetype();
5170 AggregateDeclaration
*ad
= isAggregate(t1b
);
5173 if (search_function(ad
, Id::indexass
))
5176 res
= resolveOpDollar(sc
, ae
, &e0
);
5177 if (!res
) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)
5179 if (res
->op
== TOKerror
)
5185 res
= semantic(exp
->e2
, sc
);
5186 if (res
->op
== TOKerror
)
5193 /* Rewrite (a[arguments] = e2) as:
5194 * a.opIndexAssign(e2, arguments)
5196 Expressions
*a
= (Expressions
*)ae
->arguments
->copy();
5197 a
->insert(0, exp
->e2
);
5198 res
= new DotIdExp(exp
->loc
, ae
->e1
, Id::indexass
);
5199 res
= new CallExp(exp
->loc
, res
, a
);
5200 if (maybeSlice
) // a[] = e2 might be: a.opSliceAssign(e2)
5201 res
= trySemantic(res
, sc
);
5203 res
= semantic(res
, sc
);
5206 res
= Expression::combine(e0
, res
);
5212 if (maybeSlice
&& search_function(ad
, Id::sliceass
))
5215 res
= resolveOpDollar(sc
, ae
, ie
, &e0
);
5216 if (res
->op
== TOKerror
)
5222 res
= semantic(exp
->e2
, sc
);
5223 if (res
->op
== TOKerror
)
5230 /* Rewrite (a[i..j] = e2) as:
5231 * a.opSliceAssign(e2, i, j)
5233 Expressions
*a
= new Expressions();
5240 res
= new DotIdExp(exp
->loc
, ae
->e1
, Id::sliceass
);
5241 res
= new CallExp(exp
->loc
, res
, a
);
5242 res
= semantic(res
, sc
);
5243 res
= Expression::combine(e0
, res
);
5248 // No operator overloading member function found yet, but
5249 // there might be an alias this to try.
5250 if (ad
->aliasthis
&& t1b
!= ae
->att1
)
5252 if (!ae
->att1
&& t1b
->checkAliasThisRec())
5255 /* Rewrite (a[arguments] op e2) as:
5256 * a.aliasthis[arguments] op e2
5258 ae
->e1
= resolveAliasThis(sc
, ae1save
, true);
5264 ae
->e1
= ae1old
; // recovery
5265 ae
->lengthVar
= NULL
;
5268 /* Run exp->e1 semantic.
5271 Expression
*e1x
= exp
->e1
;
5273 /* With UFCS, e.f = value
5279 if (e1x
->op
== TOKdotti
)
5281 DotTemplateInstanceExp
*dti
= (DotTemplateInstanceExp
*)e1x
;
5282 Expression
*e
= semanticY(dti
, sc
, 1);
5285 result
= resolveUFCSProperties(sc
, e1x
, exp
->e2
);
5290 else if (e1x
->op
== TOKdotid
)
5292 DotIdExp
*die
= (DotIdExp
*)e1x
;
5293 Expression
*e
= semanticY(die
, sc
, 1);
5294 if (e
&& isDotOpDispatch(e
))
5296 unsigned errors
= global
.startGagging();
5297 e
= resolvePropertiesX(sc
, e
, exp
->e2
);
5298 if (global
.endGagging(errors
))
5299 e
= NULL
; /* fall down to UFCS */
5308 result
= resolveUFCSProperties(sc
, e1x
, exp
->e2
);
5315 if (e1x
->op
== TOKslice
)
5316 ((SliceExp
*)e1x
)->arrayop
= true;
5318 e1x
= semantic(e1x
, sc
);
5321 /* We have f = value.
5327 if (Expression
*e
= resolvePropertiesX(sc
, e1x
, exp
->e2
))
5332 if (e1x
->checkRightThis(sc
))
5335 assert(exp
->e1
->type
);
5337 Type
*t1
= exp
->e1
->type
->toBasetype();
5339 /* Run exp->e2 semantic.
5340 * Different from other binary expressions, the analysis of e2
5341 * depends on the result of e1 in assignments.
5344 Expression
*e2x
= inferType(exp
->e2
, t1
->baseElemOf());
5346 e2x
= semantic(e2x
, sc
);
5347 e2x
= resolveProperties(sc
, e2x
);
5349 if (e2x
->op
== TOKtype
)
5350 e2x
= resolveAliasThis(sc
, e2x
); //https://issues.dlang.org/show_bug.cgi?id=17684
5351 if (e2x
->op
== TOKerror
)
5356 if (e2x
->checkValue())
5361 /* Rewrite tuple assignment as a tuple of assignments.
5364 Expression
*e2x
= exp
->e2
;
5367 if (exp
->e1
->op
== TOKtuple
&& e2x
->op
== TOKtuple
)
5369 TupleExp
*tup1
= (TupleExp
*)exp
->e1
;
5370 TupleExp
*tup2
= (TupleExp
*)e2x
;
5371 size_t dim
= tup1
->exps
->dim
;
5372 Expression
*e
= NULL
;
5373 if (dim
!= tup2
->exps
->dim
)
5375 exp
->error("mismatched tuple lengths, %d and %d", (int)dim
, (int)tup2
->exps
->dim
);
5380 e
= new IntegerExp(exp
->loc
, 0, Type::tint32
);
5381 e
= new CastExp(exp
->loc
, e
, Type::tvoid
); // avoid "has no effect" error
5382 e
= Expression::combine(Expression::combine(tup1
->e0
, tup2
->e0
), e
);
5386 Expressions
*exps
= new Expressions
;
5388 for (size_t i
= 0; i
< dim
; i
++)
5390 Expression
*ex1
= (*tup1
->exps
)[i
];
5391 Expression
*ex2
= (*tup2
->exps
)[i
];
5392 (*exps
)[i
] = new AssignExp(exp
->loc
, ex1
, ex2
);
5394 e
= new TupleExp(exp
->loc
, Expression::combine(tup1
->e0
, tup2
->e0
), exps
);
5396 result
= semantic(e
, sc
);
5400 /* Look for form: e1 = e2->aliasthis.
5402 if (exp
->e1
->op
== TOKtuple
)
5404 TupleDeclaration
*td
= isAliasThisTuple(e2x
);
5408 assert(exp
->e1
->type
->ty
== Ttuple
);
5409 TypeTuple
*tt
= (TypeTuple
*)exp
->e1
->type
;
5411 Expression
*e0
= NULL
;
5412 Expression
*ev
= extractSideEffect(sc
, "__tup", &e0
, e2x
);
5414 Expressions
*iexps
= new Expressions();
5417 for (size_t u
= 0; u
< iexps
->dim
; u
++)
5420 Expression
*e
= (*iexps
)[u
];
5422 Parameter
*arg
= Parameter::getNth(tt
->arguments
, u
);
5423 //printf("[%d] iexps->dim = %d, ", u, iexps->dim);
5424 //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars());
5425 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars());
5427 if (!arg
|| !e
->type
->implicitConvTo(arg
->type
))
5429 // expand initializer to tuple
5430 if (expandAliasThisTuples(iexps
, u
) != -1)
5432 if (iexps
->dim
<= u
)
5439 e2x
= new TupleExp(e2x
->loc
, e0
, iexps
);
5440 e2x
= semantic(e2x
, sc
);
5441 if (e2x
->op
== TOKerror
)
5446 // Do not need to overwrite exp->e2
5453 /* Inside constructor, if this is the first assignment of object field,
5454 * rewrite this to initializing the field.
5456 if (exp
->op
== TOKassign
&& exp
->e1
->checkModifiable(sc
) == 2)
5458 //printf("[%s] change to init - %s\n", exp->loc.toChars(), toChars());
5459 exp
->op
= TOKconstruct
;
5461 // Bugzilla 13515: set Index::modifiable flag for complex AA element initialization
5462 if (exp
->e1
->op
== TOKindex
)
5464 Expression
*e1x
= ((IndexExp
*)exp
->e1
)->markSettingAAElem();
5465 if (e1x
->op
== TOKerror
)
5472 else if (exp
->op
== TOKconstruct
&& exp
->e1
->op
== TOKvar
&&
5473 ((VarExp
*)exp
->e1
)->var
->storage_class
& (STCout
| STCref
))
5475 exp
->memset
|= referenceInit
;
5478 /* If it is an assignment from a 'foreign' type,
5479 * check for operator overloading.
5481 if (exp
->memset
& referenceInit
)
5483 // If this is an initialization of a reference,
5486 else if (t1
->ty
== Tstruct
)
5488 Expression
*e1x
= exp
->e1
;
5489 Expression
*e2x
= exp
->e2
;
5490 StructDeclaration
*sd
= ((TypeStruct
*)t1
)->sym
;
5492 if (exp
->op
== TOKconstruct
)
5494 Type
*t2
= e2x
->type
->toBasetype();
5495 if (t2
->ty
== Tstruct
&& sd
== ((TypeStruct
*)t2
)->sym
)
5498 if (sd
->sizeok
!= SIZEOKdone
)
5501 sd
->ctor
= sd
->searchCtor();
5503 // Bugzilla 15661: Look for the form from last of comma chain.
5504 Expression
*e2y
= e2x
;
5505 while (e2y
->op
== TOKcomma
)
5506 e2y
= ((CommaExp
*)e2y
)->e2
;
5508 CallExp
*ce
= (e2y
->op
== TOKcall
) ? (CallExp
*)e2y
: NULL
;
5509 DotVarExp
*dve
= (ce
&& ce
->e1
->op
== TOKdotvar
)
5510 ? (DotVarExp
*)ce
->e1
: NULL
;
5511 if (sd
->ctor
&& ce
&& dve
&& dve
->var
->isCtorDeclaration() &&
5512 e2y
->type
->implicitConvTo(t1
))
5514 /* Look for form of constructor call which is:
5515 * __ctmp.ctor(arguments...)
5518 /* Before calling the constructor, initialize
5519 * variable with a bit copy of the default
5522 AssignExp
*ae
= exp
;
5523 if (sd
->zeroInit
== 1 && !sd
->isNested())
5525 // Bugzilla 14606: Always use BlitExp for the special expression: (struct = 0)
5526 ae
= new BlitExp(ae
->loc
, ae
->e1
, new IntegerExp(exp
->loc
, 0, Type::tint32
));
5530 // Keep ae->op == TOKconstruct
5531 ae
->e2
= sd
->isNested() ? t1
->defaultInitLiteral(exp
->loc
) : t1
->defaultInit(exp
->loc
);
5533 ae
->type
= e1x
->type
;
5535 /* Replace __ctmp being constructed with e1.
5536 * We need to copy constructor call expression,
5537 * because it may be used in other place.
5539 DotVarExp
*dvx
= (DotVarExp
*)dve
->copy();
5541 CallExp
*cx
= (CallExp
*)ce
->copy();
5545 Expression::extractLast(e2x
, &e0
);
5547 Expression
*e
= Expression::combine(ae
, cx
);
5548 e
= Expression::combine(e0
, e
);
5549 e
= semantic(e
, sc
);
5555 /* We have a copy constructor for this
5557 if (e2x
->op
== TOKquestion
)
5560 * a ? e1 = b : e1 = c;
5562 CondExp
*econd
= (CondExp
*)e2x
;
5563 Expression
*ea1
= new ConstructExp(econd
->e1
->loc
, e1x
, econd
->e1
);
5564 Expression
*ea2
= new ConstructExp(econd
->e1
->loc
, e1x
, econd
->e2
);
5565 Expression
*e
= new CondExp(exp
->loc
, econd
->econd
, ea1
, ea2
);
5566 result
= semantic(e
, sc
);
5570 if (e2x
->isLvalue())
5572 if (!e2x
->type
->implicitConvTo(e1x
->type
))
5574 exp
->error("conversion error from %s to %s", e2x
->type
->toChars(), e1x
->type
->toChars());
5579 * (e1 = e2).postblit();
5581 * Blit assignment e1 = e2 returns a reference to the original e1,
5582 * then call the postblit on it.
5584 Expression
*e
= e1x
->copy();
5585 e
->type
= e
->type
->mutableOf();
5586 e
= new BlitExp(exp
->loc
, e
, e2x
);
5587 e
= new DotVarExp(exp
->loc
, e
, sd
->postblit
, false);
5588 e
= new CallExp(exp
->loc
, e
);
5589 result
= semantic(e
, sc
);
5594 /* The struct value returned from the function is transferred
5595 * so should not call the destructor on it.
5597 e2x
= valueNoDtor(e2x
);
5601 else if (!e2x
->implicitConvTo(t1
))
5604 if (sd
->sizeok
!= SIZEOKdone
)
5607 sd
->ctor
= sd
->searchCtor();
5611 /* Look for implicit constructor call
5613 * e1 = init, e1.ctor(e2)
5616 einit
= new BlitExp(exp
->loc
, e1x
, e1x
->type
->defaultInit(exp
->loc
));
5617 einit
->type
= e1x
->type
;
5620 e
= new DotIdExp(exp
->loc
, e1x
, Id::ctor
);
5621 e
= new CallExp(exp
->loc
, e
, e2x
);
5622 e
= new CommaExp(exp
->loc
, einit
, e
);
5623 e
= semantic(e
, sc
);
5627 if (search_function(sd
, Id::call
))
5629 /* Look for static opCall
5630 * (See bugzilla 2702 for more discussion)
5632 * e1 = typeof(e1).opCall(arguments)
5634 e2x
= typeDotIdExp(e2x
->loc
, e1x
->type
, Id::call
);
5635 e2x
= new CallExp(exp
->loc
, e2x
, exp
->e2
);
5637 e2x
= semantic(e2x
, sc
);
5638 e2x
= resolveProperties(sc
, e2x
);
5639 if (e2x
->op
== TOKerror
)
5644 if (e2x
->checkValue())
5648 else // Bugzilla 11355
5650 AggregateDeclaration
*ad2
= isAggregate(e2x
->type
);
5651 if (ad2
&& ad2
->aliasthis
&& !(exp
->att2
&& e2x
->type
== exp
->att2
))
5653 if (!exp
->att2
&& exp
->e2
->type
->checkAliasThisRec())
5654 exp
->att2
= exp
->e2
->type
;
5656 /* Rewrite (e1 op e2) as:
5657 * (e1 op e2.aliasthis)
5659 exp
->e2
= new DotIdExp(exp
->e2
->loc
, exp
->e2
, ad2
->aliasthis
->ident
);
5660 result
= semantic(exp
, sc
);
5665 else if (exp
->op
== TOKassign
)
5667 if (e1x
->op
== TOKindex
&&
5668 ((IndexExp
*)e1x
)->e1
->type
->toBasetype()->ty
== Taarray
)
5675 * ref __aakey = key;
5677 * (__aakey in __aatmp
5678 * ? __aatmp[__aakey].opAssign(__aaval)
5679 * : ConstructExp(__aatmp[__aakey], __aaval));
5681 IndexExp
*ie
= (IndexExp
*)e1x
;
5682 Type
*t2
= e2x
->type
->toBasetype();
5684 Expression
*e0
= NULL
;
5685 Expression
*ea
= extractSideEffect(sc
, "__aatmp", &e0
, ie
->e1
);
5686 Expression
*ek
= extractSideEffect(sc
, "__aakey", &e0
, ie
->e2
);
5687 Expression
*ev
= extractSideEffect(sc
, "__aaval", &e0
, e2x
);
5689 AssignExp
*ae
= (AssignExp
*)exp
->copy();
5690 ae
->e1
= new IndexExp(exp
->loc
, ea
, ek
);
5691 ae
->e1
= semantic(ae
->e1
, sc
);
5692 ae
->e1
= ae
->e1
->optimize(WANTvalue
);
5694 Expression
*e
= ae
->op_overload(sc
);
5697 Expression
*ey
= NULL
;
5698 if (t2
->ty
== Tstruct
&& sd
== t2
->toDsymbol(sc
))
5702 else if (!ev
->implicitConvTo(ie
->type
) && sd
->ctor
)
5704 // Look for implicit constructor call
5705 // Rewrite as S().ctor(e2)
5706 ey
= new StructLiteralExp(exp
->loc
, sd
, NULL
);
5707 ey
= new DotIdExp(exp
->loc
, ey
, Id::ctor
);
5708 ey
= new CallExp(exp
->loc
, ey
, ev
);
5709 ey
= trySemantic(ey
, sc
);
5714 ex
= new IndexExp(exp
->loc
, ea
, ek
);
5715 ex
= semantic(ex
, sc
);
5716 ex
= ex
->optimize(WANTvalue
);
5717 ex
= ex
->modifiableLvalue(sc
, ex
); // allocate new slot
5718 ey
= new ConstructExp(exp
->loc
, ex
, ey
);
5719 ey
= semantic(ey
, sc
);
5720 if (ey
->op
== TOKerror
)
5727 // Bugzilla 14144: The whole expression should have the common type
5728 // of opAssign() return and assigned AA entry.
5729 // Even if there's no common type, expression should be typed as void.
5731 if (!typeMerge(sc
, TOKquestion
, &t
, &ex
, &ey
))
5733 ex
= new CastExp(ex
->loc
, ex
, Type::tvoid
);
5734 ey
= new CastExp(ey
->loc
, ey
, Type::tvoid
);
5736 e
= new CondExp(exp
->loc
, new InExp(exp
->loc
, ek
, ea
), ex
, ey
);
5738 e
= Expression::combine(e0
, e
);
5739 e
= semantic(e
, sc
);
5746 Expression
*e
= exp
->op_overload(sc
);
5755 assert(exp
->op
== TOKblit
);
5760 else if (t1
->ty
== Tclass
)
5762 // Disallow assignment operator overloads for same type
5763 if (exp
->op
== TOKassign
&& !exp
->e2
->implicitConvTo(exp
->e1
->type
))
5765 Expression
*e
= exp
->op_overload(sc
);
5773 else if (t1
->ty
== Tsarray
)
5775 // SliceExp cannot have static array type without context inference.
5776 assert(exp
->e1
->op
!= TOKslice
);
5778 Expression
*e1x
= exp
->e1
;
5779 Expression
*e2x
= exp
->e2
;
5781 if (e2x
->implicitConvTo(e1x
->type
))
5783 if (exp
->op
!= TOKblit
&&
5784 ((e2x
->op
== TOKslice
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5785 (e2x
->op
== TOKcast
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5786 (e2x
->op
!= TOKslice
&& e2x
->isLvalue())))
5788 if (e1x
->checkPostblit(sc
, t1
))
5792 // e2 matches to t1 because of the implicit length match, so
5793 if (isUnaArrayOp(e2x
->op
) || isBinArrayOp(e2x
->op
))
5795 // convert e1 to e1[]
5796 // e.g. e1[] = a[] + b[];
5797 SliceExp
*sle
= new SliceExp(e1x
->loc
, e1x
, NULL
, NULL
);
5798 sle
->arrayop
= true;
5799 e1x
= semantic(sle
, sc
);
5803 // convert e2 to t1 later
5804 // e.g. e1 = [1, 2, 3];
5809 if (e2x
->implicitConvTo(t1
->nextOf()->arrayOf()) > MATCHnomatch
)
5811 uinteger_t dim1
= ((TypeSArray
*)t1
)->dim
->toInteger();
5812 uinteger_t dim2
= dim1
;
5813 if (e2x
->op
== TOKarrayliteral
)
5815 ArrayLiteralExp
*ale
= (ArrayLiteralExp
*)e2x
;
5816 dim2
= ale
->elements
? ale
->elements
->dim
: 0;
5818 else if (e2x
->op
== TOKslice
)
5820 Type
*tx
= toStaticArrayType((SliceExp
*)e2x
);
5822 dim2
= ((TypeSArray
*)tx
)->dim
->toInteger();
5826 exp
->error("mismatched array lengths, %d and %d", (int)dim1
, (int)dim2
);
5831 // May be block or element-wise assignment, so
5832 // convert e1 to e1[]
5833 if (exp
->op
!= TOKassign
)
5835 // If multidimensional static array, treat as one large array
5836 dinteger_t dim
= ((TypeSArray
*)t1
)->dim
->toInteger();
5840 t
= t
->nextOf()->toBasetype();
5841 if (t
->ty
!= Tsarray
)
5843 dim
*= ((TypeSArray
*)t
)->dim
->toInteger();
5844 e1x
->type
= t
->nextOf()->sarrayOf(dim
);
5847 SliceExp
*sle
= new SliceExp(e1x
->loc
, e1x
, NULL
, NULL
);
5848 sle
->arrayop
= true;
5849 e1x
= semantic(sle
, sc
);
5851 if (e1x
->op
== TOKerror
)
5856 if (e2x
->op
== TOKerror
)
5864 t1
= e1x
->type
->toBasetype();
5867 /* Check the mutability of e1.
5869 if (exp
->e1
->op
== TOKarraylength
)
5871 // e1 is not an lvalue, but we let code generator handle it
5872 ArrayLengthExp
*ale
= (ArrayLengthExp
*)exp
->e1
;
5874 Expression
*ale1x
= ale
->e1
;
5875 ale1x
= ale1x
->modifiableLvalue(sc
, exp
->e1
);
5876 if (ale1x
->op
== TOKerror
)
5883 Type
*tn
= ale
->e1
->type
->toBasetype()->nextOf();
5884 checkDefCtor(ale
->loc
, tn
);
5885 semanticTypeInfo(sc
, tn
);
5887 else if (exp
->e1
->op
== TOKslice
)
5889 Type
*tn
= exp
->e1
->type
->nextOf();
5890 if (exp
->op
== TOKassign
&& !tn
->isMutable())
5892 exp
->error("slice %s is not mutable", exp
->e1
->toChars());
5896 // For conditional operator, both branches need conversion.
5897 SliceExp
*se
= (SliceExp
*)exp
->e1
;
5898 while (se
->e1
->op
== TOKslice
)
5899 se
= (SliceExp
*)se
->e1
;
5900 if (se
->e1
->op
== TOKquestion
&&
5901 se
->e1
->type
->toBasetype()->ty
== Tsarray
)
5903 se
->e1
= se
->e1
->modifiableLvalue(sc
, exp
->e1
);
5904 if (se
->e1
->op
== TOKerror
)
5913 Expression
*e1x
= exp
->e1
;
5915 // Try to do a decent error message with the expression
5916 // before it got constant folded
5917 if (e1x
->op
!= TOKvar
)
5918 e1x
= e1x
->optimize(WANTvalue
);
5920 if (exp
->op
== TOKassign
)
5921 e1x
= e1x
->modifiableLvalue(sc
, e1old
);
5923 if (e1x
->op
== TOKerror
)
5931 /* Tweak e2 based on the type of e1.
5933 Expression
*e2x
= exp
->e2
;
5934 Type
*t2
= e2x
->type
->toBasetype();
5936 // If it is a array, get the element type. Note that it may be
5937 // multi-dimensional.
5939 while (telem
->ty
== Tarray
)
5940 telem
= telem
->nextOf();
5942 if (exp
->e1
->op
== TOKslice
&&
5943 t1
->nextOf() && (telem
->ty
!= Tvoid
|| e2x
->op
== TOKnull
) &&
5944 e2x
->implicitConvTo(t1
->nextOf())
5947 // Check for block assignment. If it is of type void[], void[][], etc,
5948 // '= null' is the only allowable block assignment (Bug 7493)
5950 exp
->memset
|= blockAssign
; // make it easy for back end to tell what this is
5951 e2x
= e2x
->implicitCastTo(sc
, t1
->nextOf());
5952 if (exp
->op
!= TOKblit
&& e2x
->isLvalue() &&
5953 exp
->e1
->checkPostblit(sc
, t1
->nextOf()))
5956 else if (exp
->e1
->op
== TOKslice
&&
5957 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
) &&
5958 t2
->nextOf()->implicitConvTo(t1
->nextOf()))
5960 // Check element-wise assignment.
5962 /* If assigned elements number is known at compile time,
5963 * check the mismatch.
5965 SliceExp
*se1
= (SliceExp
*)exp
->e1
;
5966 TypeSArray
*tsa1
= (TypeSArray
*)toStaticArrayType(se1
);
5967 TypeSArray
*tsa2
= NULL
;
5968 if (e2x
->op
== TOKarrayliteral
)
5969 tsa2
= (TypeSArray
*)t2
->nextOf()->sarrayOf(((ArrayLiteralExp
*)e2x
)->elements
->dim
);
5970 else if (e2x
->op
== TOKslice
)
5971 tsa2
= (TypeSArray
*)toStaticArrayType((SliceExp
*)e2x
);
5972 else if (t2
->ty
== Tsarray
)
5973 tsa2
= (TypeSArray
*)t2
;
5976 uinteger_t dim1
= tsa1
->dim
->toInteger();
5977 uinteger_t dim2
= tsa2
->dim
->toInteger();
5980 exp
->error("mismatched array lengths, %d and %d", (int)dim1
, (int)dim2
);
5985 if (exp
->op
!= TOKblit
&&
5986 ((e2x
->op
== TOKslice
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5987 (e2x
->op
== TOKcast
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5988 (e2x
->op
!= TOKslice
&& e2x
->isLvalue())))
5990 if (exp
->e1
->checkPostblit(sc
, t1
->nextOf()))
5994 if (0 && global
.params
.warnings
!= DIAGNOSTICoff
&& !global
.gag
&& exp
->op
== TOKassign
&&
5995 e2x
->op
!= TOKslice
&& e2x
->op
!= TOKassign
&&
5996 e2x
->op
!= TOKarrayliteral
&& e2x
->op
!= TOKstring
&&
5997 !(e2x
->op
== TOKadd
|| e2x
->op
== TOKmin
||
5998 e2x
->op
== TOKmul
|| e2x
->op
== TOKdiv
||
5999 e2x
->op
== TOKmod
|| e2x
->op
== TOKxor
||
6000 e2x
->op
== TOKand
|| e2x
->op
== TOKor
||
6001 e2x
->op
== TOKpow
||
6002 e2x
->op
== TOKtilde
|| e2x
->op
== TOKneg
))
6004 const char* e1str
= exp
->e1
->toChars();
6005 const char* e2str
= e2x
->toChars();
6006 exp
->warning("explicit element-wise assignment %s = (%s)[] is better than %s = %s",
6007 e1str
, e2str
, e1str
, e2str
);
6010 Type
*t2n
= t2
->nextOf();
6011 Type
*t1n
= t1
->nextOf();
6013 if (t2n
->equivalent(t1n
) ||
6014 (t1n
->isBaseOf(t2n
, &offset
) && offset
== 0))
6016 /* Allow copy of distinct qualifier elements.
6018 * char[] dst; const(char)[] src;
6021 * class C {} class D : C {}
6025 if (isArrayOpValid(e2x
))
6027 // Don't add CastExp to keep AST for array operations
6029 e2x
->type
= exp
->e1
->type
->constOf();
6032 e2x
= e2x
->castTo(sc
, exp
->e1
->type
->constOf());
6036 /* Bugzilla 15778: A string literal has an array type of immutable
6037 * elements by default, and normally it cannot be convertible to
6038 * array type of mutable elements. But for element-wise assignment,
6039 * elements need to be const at best. So we should give a chance
6040 * to change code unit size for polysemous string literal.
6042 if (e2x
->op
== TOKstring
)
6043 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
->constOf());
6045 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
);
6047 if (t1n
->toBasetype()->ty
== Tvoid
&& t2n
->toBasetype()->ty
== Tvoid
)
6049 if (!sc
->intypeof
&& sc
->func
&& sc
->func
->setUnsafe())
6051 exp
->error("cannot copy void[] to void[] in @safe code");
6058 if (0 && global
.params
.warnings
!= DIAGNOSTICoff
&& !global
.gag
&& exp
->op
== TOKassign
&&
6059 t1
->ty
== Tarray
&& t2
->ty
== Tsarray
&&
6060 e2x
->op
!= TOKslice
&&
6061 t2
->implicitConvTo(t1
))
6062 { // Disallow ar[] = sa (Converted to ar[] = sa[])
6063 // Disallow da = sa (Converted to da = sa[])
6064 const char* e1str
= exp
->e1
->toChars();
6065 const char* e2str
= e2x
->toChars();
6066 const char* atypestr
= exp
->e1
->op
== TOKslice
? "element-wise" : "slice";
6067 exp
->warning("explicit %s assignment %s = (%s)[] is better than %s = %s",
6068 atypestr
, e1str
, e2str
, e1str
, e2str
);
6070 if (exp
->op
== TOKblit
)
6071 e2x
= e2x
->castTo(sc
, exp
->e1
->type
);
6073 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
);
6075 if (e2x
->op
== TOKerror
)
6081 t2
= exp
->e2
->type
->toBasetype();
6083 /* Look for array operations
6085 if ((t2
->ty
== Tarray
|| t2
->ty
== Tsarray
) && isArrayOpValid(exp
->e2
))
6087 // Look for valid array operations
6088 if (!(exp
->memset
& blockAssign
) && exp
->e1
->op
== TOKslice
&&
6089 (isUnaArrayOp(exp
->e2
->op
) || isBinArrayOp(exp
->e2
->op
)))
6091 exp
->type
= exp
->e1
->type
;
6092 if (exp
->op
== TOKconstruct
) // Bugzilla 10282: tweak mutability of e1 element
6093 exp
->e1
->type
= exp
->e1
->type
->nextOf()->mutableOf()->arrayOf();
6094 result
= arrayOp(exp
, sc
);
6098 // Drop invalid array operations in e2
6099 // d = a[] + b[], d = (a[] + b[])[0..2], etc
6100 if (checkNonAssignmentArrayOp(exp
->e2
, !(exp
->memset
& blockAssign
) && exp
->op
== TOKassign
))
6103 // Remains valid array assignments
6104 // d = d[], d = [1,2,3], etc
6107 /* Don't allow assignment to classes that were allocated on the stack with:
6108 * scope Class c = new Class();
6111 if (exp
->e1
->op
== TOKvar
&& exp
->op
== TOKassign
)
6113 VarExp
*ve
= (VarExp
*)exp
->e1
;
6114 VarDeclaration
*vd
= ve
->var
->isVarDeclaration();
6115 if (vd
&& (vd
->onstack
|| vd
->mynew
))
6117 assert(t1
->ty
== Tclass
);
6118 exp
->error("cannot rebind scope variables");
6121 if (exp
->e1
->op
== TOKvar
&& ((VarExp
*)exp
->e1
)->var
->ident
== Id::ctfe
)
6123 exp
->error("cannot modify compiler-generated variable __ctfe");
6126 exp
->type
= exp
->e1
->type
;
6128 Expression
*res
= exp
->op
== TOKassign
? exp
->reorderSettingAAElem(sc
) : exp
;
6129 checkAssignEscape(sc
, res
, false);
6133 void visit(CatAssignExp
*exp
)
6141 //printf("CatAssignExp::semantic() %s\n", toChars());
6142 Expression
*e
= exp
->op_overload(sc
);
6149 if (exp
->e1
->op
== TOKslice
)
6151 SliceExp
*se
= (SliceExp
*)exp
->e1
;
6152 if (se
->e1
->type
->toBasetype()->ty
== Tsarray
)
6154 exp
->error("cannot append to static array %s", se
->e1
->type
->toChars());
6159 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
6160 if (exp
->e1
->op
== TOKerror
)
6165 if (exp
->e2
->op
== TOKerror
)
6171 if (checkNonAssignmentArrayOp(exp
->e2
))
6174 Type
*tb1
= exp
->e1
->type
->toBasetype();
6175 Type
*tb1next
= tb1
->nextOf();
6176 Type
*tb2
= exp
->e2
->type
->toBasetype();
6178 if ((tb1
->ty
== Tarray
) &&
6179 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
6180 (exp
->e2
->implicitConvTo(exp
->e1
->type
)
6181 || (tb2
->nextOf()->implicitConvTo(tb1next
) &&
6182 (tb2
->nextOf()->size(Loc()) == tb1next
->size(Loc())))
6187 if (exp
->e1
->checkPostblit(sc
, tb1next
))
6189 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
6191 else if ((tb1
->ty
== Tarray
) &&
6192 exp
->e2
->implicitConvTo(tb1next
)
6196 if (exp
->e2
->checkPostblit(sc
, tb2
))
6198 exp
->e2
= exp
->e2
->castTo(sc
, tb1next
);
6199 exp
->e2
= doCopyOrMove(sc
, exp
->e2
);
6201 else if (tb1
->ty
== Tarray
&&
6202 (tb1next
->ty
== Tchar
|| tb1next
->ty
== Twchar
) &&
6203 exp
->e2
->type
->ty
!= tb1next
->ty
&&
6204 exp
->e2
->implicitConvTo(Type::tdchar
)
6206 { // Append dchar to char[] or wchar[]
6207 exp
->e2
= exp
->e2
->castTo(sc
, Type::tdchar
);
6209 /* Do not allow appending wchar to char[] because if wchar happens
6210 * to be a surrogate pair, nothing good can result.
6215 exp
->error("cannot append type %s to type %s", tb2
->toChars(), tb1
->toChars());
6218 if (exp
->e2
->checkValue())
6221 exp
->type
= exp
->e1
->type
;
6222 result
= exp
->reorderSettingAAElem(sc
);
6225 void visit(PowAssignExp
*exp
)
6233 Expression
*e
= exp
->op_overload(sc
);
6240 if (exp
->e1
->checkReadModifyWrite(exp
->op
, exp
->e2
))
6243 assert(exp
->e1
->type
&& exp
->e2
->type
);
6244 if (exp
->e1
->op
== TOKslice
|| exp
->e1
->type
->ty
== Tarray
|| exp
->e1
->type
->ty
== Tsarray
)
6247 if (exp
->e2
->implicitConvTo(exp
->e1
->type
->nextOf()))
6250 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
->nextOf());
6252 else if (Expression
*ex
= typeCombine(exp
, sc
))
6258 // Check element types are arithmetic
6259 Type
*tb1
= exp
->e1
->type
->nextOf()->toBasetype();
6260 Type
*tb2
= exp
->e2
->type
->toBasetype();
6261 if (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
6262 tb2
= tb2
->nextOf()->toBasetype();
6264 if ( (tb1
->isintegral() || tb1
->isfloating()) &&
6265 (tb2
->isintegral() || tb2
->isfloating()))
6267 exp
->type
= exp
->e1
->type
;
6268 result
= arrayOp(exp
, sc
);
6274 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
6277 if ((exp
->e1
->type
->isintegral() || exp
->e1
->type
->isfloating()) &&
6278 (exp
->e2
->type
->isintegral() || exp
->e2
->type
->isfloating()))
6280 Expression
*e0
= NULL
;
6281 e
= exp
->reorderSettingAAElem(sc
);
6282 e
= Expression::extractLast(e
, &e0
);
6285 if (exp
->e1
->op
== TOKvar
)
6287 // Rewrite: e1 = e1 ^^ e2
6288 e
= new PowExp(exp
->loc
, exp
->e1
->syntaxCopy(), exp
->e2
);
6289 e
= new AssignExp(exp
->loc
, exp
->e1
, e
);
6293 // Rewrite: ref tmp = e1; tmp = tmp ^^ e2
6294 VarDeclaration
*v
= copyToTemp(STCref
, "__powtmp", exp
->e1
);
6295 Expression
*de
= new DeclarationExp(exp
->e1
->loc
, v
);
6296 VarExp
*ve
= new VarExp(exp
->e1
->loc
, v
);
6297 e
= new PowExp(exp
->loc
, ve
, exp
->e2
);
6298 e
= new AssignExp(exp
->loc
, new VarExp(exp
->e1
->loc
, v
), e
);
6299 e
= new CommaExp(exp
->loc
, de
, e
);
6301 e
= Expression::combine(e0
, e
);
6302 e
= semantic(e
, sc
);
6306 result
= exp
->incompatibleTypes();
6309 void visit(AddExp
*exp
)
6317 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6322 Expression
*e
= exp
->op_overload(sc
);
6329 Type
*tb1
= exp
->e1
->type
->toBasetype();
6330 Type
*tb2
= exp
->e2
->type
->toBasetype();
6333 if (tb1
->ty
== Tdelegate
||
6334 (tb1
->ty
== Tpointer
&& tb1
->nextOf()->ty
== Tfunction
))
6336 err
|= exp
->e1
->checkArithmetic();
6338 if (tb2
->ty
== Tdelegate
||
6339 (tb2
->ty
== Tpointer
&& tb2
->nextOf()->ty
== Tfunction
))
6341 err
|= exp
->e2
->checkArithmetic();
6346 if ((tb1
->ty
== Tpointer
&& exp
->e2
->type
->isintegral()) ||
6347 (tb2
->ty
== Tpointer
&& exp
->e1
->type
->isintegral()))
6349 result
= scaleFactor(exp
, sc
);
6353 if (tb1
->ty
== Tpointer
&& tb2
->ty
== Tpointer
)
6355 result
= exp
->incompatibleTypes();
6359 if (Expression
*ex
= typeCombine(exp
, sc
))
6365 Type
*tb
= exp
->type
->toBasetype();
6366 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6368 if (!isArrayOpValid(exp
))
6370 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6377 tb1
= exp
->e1
->type
->toBasetype();
6378 if (!Target::isVectorOpSupported(tb1
, exp
->op
, tb2
))
6380 result
= exp
->incompatibleTypes();
6383 if ((tb1
->isreal() && exp
->e2
->type
->isimaginary()) ||
6384 (tb1
->isimaginary() && exp
->e2
->type
->isreal()))
6386 switch (exp
->type
->toBasetype()->ty
)
6390 exp
->type
= Type::tcomplex32
;
6395 exp
->type
= Type::tcomplex64
;
6400 exp
->type
= Type::tcomplex80
;
6410 void visit(MinExp
*exp
)
6418 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6423 Expression
*e
= exp
->op_overload(sc
);
6430 Type
*t1
= exp
->e1
->type
->toBasetype();
6431 Type
*t2
= exp
->e2
->type
->toBasetype();
6434 if (t1
->ty
== Tdelegate
||
6435 (t1
->ty
== Tpointer
&& t1
->nextOf()->ty
== Tfunction
))
6437 err
|= exp
->e1
->checkArithmetic();
6439 if (t2
->ty
== Tdelegate
||
6440 (t2
->ty
== Tpointer
&& t2
->nextOf()->ty
== Tfunction
))
6442 err
|= exp
->e2
->checkArithmetic();
6447 if (t1
->ty
== Tpointer
)
6449 if (t2
->ty
== Tpointer
)
6451 // Need to divide the result by the stride
6452 // Replace (ptr - ptr) with (ptr - ptr) / stride
6455 // make sure pointer types are compatible
6456 if (Expression
*ex
= typeCombine(exp
, sc
))
6462 exp
->type
= Type::tptrdiff_t
;
6463 stride
= t2
->nextOf()->size();
6466 e
= new IntegerExp(exp
->loc
, 0, Type::tptrdiff_t
);
6470 e
= new DivExp(exp
->loc
, exp
, new IntegerExp(Loc(), stride
, Type::tptrdiff_t
));
6471 e
->type
= Type::tptrdiff_t
;
6474 else if (t2
->isintegral())
6475 e
= scaleFactor(exp
, sc
);
6478 exp
->error("can't subtract %s from pointer", t2
->toChars());
6484 if (t2
->ty
== Tpointer
)
6486 exp
->type
= exp
->e2
->type
;
6487 exp
->error("can't subtract pointer from %s", exp
->e1
->type
->toChars());
6491 if (Expression
*ex
= typeCombine(exp
, sc
))
6497 Type
*tb
= exp
->type
->toBasetype();
6498 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6500 if (!isArrayOpValid(exp
))
6502 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6509 t1
= exp
->e1
->type
->toBasetype();
6510 t2
= exp
->e2
->type
->toBasetype();
6511 if (!Target::isVectorOpSupported(t1
, exp
->op
, t2
))
6513 result
= exp
->incompatibleTypes();
6516 if ((t1
->isreal() && t2
->isimaginary()) ||
6517 (t1
->isimaginary() && t2
->isreal()))
6519 switch (exp
->type
->ty
)
6523 exp
->type
= Type::tcomplex32
;
6528 exp
->type
= Type::tcomplex64
;
6533 exp
->type
= Type::tcomplex80
;
6543 void visit(CatExp
*exp
)
6545 //printf("CatExp::semantic() %s\n", exp->toChars());
6552 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6557 Expression
*e
= exp
->op_overload(sc
);
6564 Type
*tb1
= exp
->e1
->type
->toBasetype();
6565 Type
*tb2
= exp
->e2
->type
->toBasetype();
6567 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
6568 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
6572 /* BUG: Should handle things like:
6577 Type
*tb1next
= tb1
->nextOf();
6578 Type
*tb2next
= tb2
->nextOf();
6580 // Check for: array ~ array
6581 if (tb1next
&& tb2next
&&
6582 (tb1next
->implicitConvTo(tb2next
) >= MATCHconst
||
6583 tb2next
->implicitConvTo(tb1next
) >= MATCHconst
||
6584 (exp
->e1
->op
== TOKarrayliteral
&& exp
->e1
->implicitConvTo(tb2
)) ||
6585 (exp
->e2
->op
== TOKarrayliteral
&& exp
->e2
->implicitConvTo(tb1
))
6589 /* Bugzilla 9248: Here to avoid the case of:
6590 * void*[] a = [cast(void*)1];
6591 * void*[] b = [cast(void*)2];
6594 * a ~ [cast(void*)b];
6597 /* Bugzilla 14682: Also to avoid the case of:
6601 * a ~ cast(int[])[];
6606 // Check for: array ~ element
6607 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
) && tb2
->ty
!= Tvoid
)
6609 if (exp
->e1
->op
== TOKarrayliteral
)
6611 exp
->e2
= exp
->e2
->isLvalue() ? callCpCtor(sc
, exp
->e2
) : valueNoDtor(exp
->e2
);
6612 // Bugzilla 14686: Postblit call appears in AST, and this is
6613 // finally translated to an ArrayLiteralExp in below otpimize().
6615 else if (exp
->e1
->op
== TOKstring
)
6617 // No postblit call exists on character (integer) value.
6621 if (exp
->e2
->checkPostblit(sc
, tb2
))
6623 // Postblit call will be done in runtime helper function
6626 if (exp
->e1
->op
== TOKarrayliteral
&& exp
->e1
->implicitConvTo(tb2
->arrayOf()))
6628 exp
->e1
= exp
->e1
->implicitCastTo(sc
, tb2
->arrayOf());
6629 exp
->type
= tb2
->arrayOf();
6632 if (exp
->e2
->implicitConvTo(tb1next
) >= MATCHconvert
)
6634 exp
->e2
= exp
->e2
->implicitCastTo(sc
, tb1next
);
6635 exp
->type
= tb1next
->arrayOf();
6637 if (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
6639 // Make e2 into [e2]
6640 exp
->e2
= new ArrayLiteralExp(exp
->e2
->loc
, exp
->e2
);
6641 exp
->e2
->type
= exp
->type
;
6643 result
= exp
->optimize(WANTvalue
);
6647 // Check for: element ~ array
6648 if ((tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
) && tb1
->ty
!= Tvoid
)
6650 if (exp
->e2
->op
== TOKarrayliteral
)
6652 exp
->e1
= exp
->e1
->isLvalue() ? callCpCtor(sc
, exp
->e1
) : valueNoDtor(exp
->e1
);
6654 else if (exp
->e2
->op
== TOKstring
)
6659 if (exp
->e1
->checkPostblit(sc
, tb1
))
6663 if (exp
->e2
->op
== TOKarrayliteral
&& exp
->e2
->implicitConvTo(tb1
->arrayOf()))
6665 exp
->e2
= exp
->e2
->implicitCastTo(sc
, tb1
->arrayOf());
6666 exp
->type
= tb1
->arrayOf();
6669 if (exp
->e1
->implicitConvTo(tb2next
) >= MATCHconvert
)
6671 exp
->e1
= exp
->e1
->implicitCastTo(sc
, tb2next
);
6672 exp
->type
= tb2next
->arrayOf();
6674 if (tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
)
6676 // Make e1 into [e1]
6677 exp
->e1
= new ArrayLiteralExp(exp
->e1
->loc
, exp
->e1
);
6678 exp
->e1
->type
= exp
->type
;
6680 result
= exp
->optimize(WANTvalue
);
6686 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
) &&
6687 (tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
) &&
6688 (tb1next
->mod
|| tb2next
->mod
) &&
6689 (tb1next
->mod
!= tb2next
->mod
)
6692 Type
*t1
= tb1next
->mutableOf()->constOf()->arrayOf();
6693 Type
*t2
= tb2next
->mutableOf()->constOf()->arrayOf();
6694 if (exp
->e1
->op
== TOKstring
&& !((StringExp
*)exp
->e1
)->committed
)
6697 exp
->e1
= exp
->e1
->castTo(sc
, t1
);
6698 if (exp
->e2
->op
== TOKstring
&& !((StringExp
*)exp
->e2
)->committed
)
6701 exp
->e2
= exp
->e2
->castTo(sc
, t2
);
6704 if (Expression
*ex
= typeCombine(exp
, sc
))
6709 exp
->type
= exp
->type
->toHeadMutable();
6711 Type
*tb
= exp
->type
->toBasetype();
6712 if (tb
->ty
== Tsarray
)
6713 exp
->type
= tb
->nextOf()->arrayOf();
6714 if (exp
->type
->ty
== Tarray
&& tb1next
&& tb2next
&&
6715 tb1next
->mod
!= tb2next
->mod
)
6717 exp
->type
= exp
->type
->nextOf()->toHeadMutable()->arrayOf();
6719 if (Type
*tbn
= tb
->nextOf())
6721 if (exp
->checkPostblit(sc
, tbn
))
6724 Type
*t1
= exp
->e1
->type
->toBasetype();
6725 Type
*t2
= exp
->e2
->type
->toBasetype();
6726 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
6727 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
6729 // Normalize to ArrayLiteralExp or StringExp as far as possible
6730 e
= exp
->optimize(WANTvalue
);
6734 //printf("(%s) ~ (%s)\n", exp->e1->toChars(), exp->e2->toChars());
6735 result
= exp
->incompatibleTypes();
6741 void visit(MulExp
*exp
)
6749 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6754 Expression
*e
= exp
->op_overload(sc
);
6761 if (Expression
*ex
= typeCombine(exp
, sc
))
6767 Type
*tb
= exp
->type
->toBasetype();
6768 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6770 if (!isArrayOpValid(exp
))
6772 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6779 if (exp
->checkArithmeticBin())
6782 if (exp
->type
->isfloating())
6784 Type
*t1
= exp
->e1
->type
;
6785 Type
*t2
= exp
->e2
->type
;
6791 else if (t2
->isreal())
6795 else if (t1
->isimaginary())
6797 if (t2
->isimaginary())
6800 switch (t1
->toBasetype()->ty
)
6803 exp
->type
= Type::tfloat32
;
6807 exp
->type
= Type::tfloat64
;
6811 exp
->type
= Type::tfloat80
;
6819 exp
->e1
->type
= exp
->type
;
6820 exp
->e2
->type
= exp
->type
;
6821 e
= new NegExp(exp
->loc
, exp
);
6822 e
= semantic(e
, sc
);
6827 exp
->type
= t2
; // t2 is complex
6829 else if (t2
->isimaginary())
6831 exp
->type
= t1
; // t1 is complex
6834 else if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
6836 result
= exp
->incompatibleTypes();
6842 void visit(DivExp
*exp
)
6850 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6854 Expression
*e
= exp
->op_overload(sc
);
6861 if (Expression
*ex
= typeCombine(exp
, sc
))
6867 Type
*tb
= exp
->type
->toBasetype();
6868 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6870 if (!isArrayOpValid(exp
))
6872 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6879 if (exp
->checkArithmeticBin())
6882 if (exp
->type
->isfloating())
6884 Type
*t1
= exp
->e1
->type
;
6885 Type
*t2
= exp
->e2
->type
;
6890 if (t2
->isimaginary())
6894 e
= new NegExp(exp
->loc
, exp
);
6895 e
= semantic(e
, sc
);
6900 else if (t2
->isreal())
6904 else if (t1
->isimaginary())
6906 if (t2
->isimaginary())
6908 switch (t1
->toBasetype()->ty
)
6911 exp
->type
= Type::tfloat32
;
6915 exp
->type
= Type::tfloat64
;
6919 exp
->type
= Type::tfloat80
;
6927 exp
->type
= t2
; // t2 is complex
6929 else if (t2
->isimaginary())
6931 exp
->type
= t1
; // t1 is complex
6934 else if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
6936 result
= exp
->incompatibleTypes();
6942 void visit(ModExp
*exp
)
6950 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6955 Expression
*e
= exp
->op_overload(sc
);
6962 if (Expression
*ex
= typeCombine(exp
, sc
))
6968 Type
*tb
= exp
->type
->toBasetype();
6969 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6971 if (!isArrayOpValid(exp
))
6973 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6979 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
6981 result
= exp
->incompatibleTypes();
6985 if (exp
->checkArithmeticBin())
6988 if (exp
->type
->isfloating())
6990 exp
->type
= exp
->e1
->type
;
6991 if (exp
->e2
->type
->iscomplex())
6993 exp
->error("cannot perform modulo complex arithmetic");
7000 Module
*loadStdMath()
7002 static Import
*impStdMath
= NULL
;
7005 Identifiers
*a
= new Identifiers();
7007 Import
*s
= new Import(Loc(), a
, Id::math
, NULL
, false);
7011 s
->mod
->importAll(NULL
);
7012 s
->mod
->semantic(NULL
);
7016 return impStdMath
->mod
;
7019 void visit(PowExp
*exp
)
7027 //printf("PowExp::semantic() %s\n", exp->toChars());
7028 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7033 Expression
*e
= exp
->op_overload(sc
);
7040 if (Expression
*ex
= typeCombine(exp
, sc
))
7046 Type
*tb
= exp
->type
->toBasetype();
7047 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7049 if (!isArrayOpValid(exp
))
7051 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7058 if (exp
->checkArithmeticBin())
7061 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7063 result
= exp
->incompatibleTypes();
7067 // For built-in numeric types, there are several cases.
7068 // TODO: backend support, especially for e1 ^^ 2.
7070 // First, attempt to fold the expression.
7071 e
= exp
->optimize(WANTvalue
);
7072 if (e
->op
!= TOKpow
)
7074 e
= semantic(e
, sc
);
7079 // Determine if we're raising to an integer power.
7080 sinteger_t intpow
= 0;
7081 if (exp
->e2
->op
== TOKint64
&& ((sinteger_t
)exp
->e2
->toInteger() == 2 || (sinteger_t
)exp
->e2
->toInteger() == 3))
7082 intpow
= exp
->e2
->toInteger();
7083 else if (exp
->e2
->op
== TOKfloat64
&& (exp
->e2
->toReal() == ldouble((sinteger_t
)exp
->e2
->toReal())))
7084 intpow
= (sinteger_t
)(exp
->e2
->toReal());
7086 // Deal with x^^2, x^^3 immediately, since they are of practical importance.
7087 if (intpow
== 2 || intpow
== 3)
7089 // Replace x^^2 with (tmp = x, tmp*tmp)
7090 // Replace x^^3 with (tmp = x, tmp*tmp*tmp)
7091 VarDeclaration
*tmp
= copyToTemp(0, "__powtmp", exp
->e1
);
7092 Expression
*de
= new DeclarationExp(exp
->loc
, tmp
);
7093 Expression
*ve
= new VarExp(exp
->loc
, tmp
);
7095 /* Note that we're reusing ve. This should be ok.
7097 Expression
*me
= new MulExp(exp
->loc
, ve
, ve
);
7099 me
= new MulExp(exp
->loc
, me
, ve
);
7100 e
= new CommaExp(exp
->loc
, de
, me
);
7101 e
= semantic(e
, sc
);
7106 Module
*mmath
= loadStdMath();
7109 //exp->error("requires std.math for ^^ operators");
7112 // Leave handling of PowExp to the backend, or throw
7113 // an error gracefully if no backend support exists.
7114 if (Expression
*ex
= typeCombine(exp
, sc
))
7122 e
= new ScopeExp(exp
->loc
, mmath
);
7124 if (exp
->e2
->op
== TOKfloat64
&& exp
->e2
->toReal() == CTFloat::half
)
7126 // Replace e1 ^^ 0.5 with .std.math.sqrt(x)
7127 e
= new CallExp(exp
->loc
, new DotIdExp(exp
->loc
, e
, Id::_sqrt
), exp
->e1
);
7131 // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
7132 e
= new CallExp(exp
->loc
, new DotIdExp(exp
->loc
, e
, Id::_pow
), exp
->e1
, exp
->e2
);
7134 e
= semantic(e
, sc
);
7138 void visit(ShlExp
*exp
)
7140 //printf("ShlExp::semantic(), type = %p\n", exp->type);
7147 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7152 Expression
*e
= exp
->op_overload(sc
);
7159 if (exp
->checkIntegralBin())
7161 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7163 result
= exp
->incompatibleTypes();
7166 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7167 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7168 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7170 exp
->type
= exp
->e1
->type
;
7174 void visit(ShrExp
*exp
)
7182 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7187 Expression
*e
= exp
->op_overload(sc
);
7194 if (exp
->checkIntegralBin())
7196 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7198 result
= exp
->incompatibleTypes();
7201 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7202 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7203 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7205 exp
->type
= exp
->e1
->type
;
7209 void visit(UshrExp
*exp
)
7217 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7222 Expression
*e
= exp
->op_overload(sc
);
7229 if (exp
->checkIntegralBin())
7231 if (!Target::isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7233 result
= exp
->incompatibleTypes();
7236 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7237 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7238 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7240 exp
->type
= exp
->e1
->type
;
7244 void visit(AndExp
*exp
)
7252 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7257 Expression
*e
= exp
->op_overload(sc
);
7264 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7265 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7267 exp
->type
= exp
->e1
->type
;
7272 if (Expression
*ex
= typeCombine(exp
, sc
))
7278 Type
*tb
= exp
->type
->toBasetype();
7279 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7281 if (!isArrayOpValid(exp
))
7283 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7290 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7292 result
= exp
->incompatibleTypes();
7295 if (exp
->checkIntegralBin())
7301 void visit(OrExp
*exp
)
7309 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7314 Expression
*e
= exp
->op_overload(sc
);
7321 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7322 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7324 exp
->type
= exp
->e1
->type
;
7329 if (Expression
*ex
= typeCombine(exp
, sc
))
7335 Type
*tb
= exp
->type
->toBasetype();
7336 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7338 if (!isArrayOpValid(exp
))
7340 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7347 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7349 result
= exp
->incompatibleTypes();
7352 if (exp
->checkIntegralBin())
7358 void visit(XorExp
*exp
)
7366 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7371 Expression
*e
= exp
->op_overload(sc
);
7378 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7379 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7381 exp
->type
= exp
->e1
->type
;
7386 if (Expression
*ex
= typeCombine(exp
, sc
))
7392 Type
*tb
= exp
->type
->toBasetype();
7393 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7395 if (!isArrayOpValid(exp
))
7397 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7404 if (!Target::isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7406 result
= exp
->incompatibleTypes();
7409 if (exp
->checkIntegralBin())
7415 void visit(OrOrExp
*exp
)
7423 setNoderefOperands(exp
);
7425 // same as for AndAnd
7426 Expression
*e1x
= semantic(exp
->e1
, sc
);
7428 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7429 if (e1x
->op
== TOKtype
)
7430 e1x
= resolveAliasThis(sc
, e1x
);
7432 e1x
= resolveProperties(sc
, e1x
);
7433 e1x
= e1x
->toBoolean(sc
);
7434 unsigned cs1
= sc
->callSuper
;
7436 if (sc
->flags
& SCOPEcondition
)
7438 /* If in static if, don't evaluate e2 if we don't have to.
7440 e1x
= e1x
->optimize(WANTvalue
);
7441 if (e1x
->isBool(true))
7443 result
= new IntegerExp(exp
->loc
, 1, Type::tbool
);
7448 Expression
*e2x
= semantic(exp
->e2
, sc
);
7449 sc
->mergeCallSuper(exp
->loc
, cs1
);
7451 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7452 if (e2x
->op
== TOKtype
)
7453 e2x
= resolveAliasThis(sc
, e2x
);
7455 e2x
= resolveProperties(sc
, e2x
);
7457 bool f1
= checkNonAssignmentArrayOp(e1x
);
7458 bool f2
= checkNonAssignmentArrayOp(e2x
);
7462 // Unless the right operand is 'void', the expression is converted to 'bool'.
7463 if (e2x
->type
->ty
!= Tvoid
)
7464 e2x
= e2x
->toBoolean(sc
);
7466 if (e2x
->op
== TOKtype
|| e2x
->op
== TOKscope
)
7468 exp
->error("%s is not an expression", exp
->e2
->toChars());
7471 if (e1x
->op
== TOKerror
)
7476 if (e2x
->op
== TOKerror
)
7482 // The result type is 'bool', unless the right operand has type 'void'.
7483 if (e2x
->type
->ty
== Tvoid
)
7484 exp
->type
= Type::tvoid
;
7486 exp
->type
= Type::tbool
;
7493 void visit(AndAndExp
*exp
)
7501 setNoderefOperands(exp
);
7504 Expression
*e1x
= semantic(exp
->e1
, sc
);
7506 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7507 if (e1x
->op
== TOKtype
)
7508 e1x
= resolveAliasThis(sc
, e1x
);
7510 e1x
= resolveProperties(sc
, e1x
);
7511 e1x
= e1x
->toBoolean(sc
);
7512 unsigned cs1
= sc
->callSuper
;
7514 if (sc
->flags
& SCOPEcondition
)
7516 /* If in static if, don't evaluate e2 if we don't have to.
7518 e1x
= e1x
->optimize(WANTvalue
);
7519 if (e1x
->isBool(false))
7521 result
= new IntegerExp(exp
->loc
, 0, Type::tbool
);
7526 Expression
*e2x
= semantic(exp
->e2
, sc
);
7527 sc
->mergeCallSuper(exp
->loc
, cs1
);
7529 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7530 if (e2x
->op
== TOKtype
)
7531 e2x
= resolveAliasThis(sc
, e2x
);
7533 e2x
= resolveProperties(sc
, e2x
);
7535 bool f1
= checkNonAssignmentArrayOp(e1x
);
7536 bool f2
= checkNonAssignmentArrayOp(e2x
);
7540 // Unless the right operand is 'void', the expression is converted to 'bool'.
7541 if (e2x
->type
->ty
!= Tvoid
)
7542 e2x
= e2x
->toBoolean(sc
);
7544 if (e2x
->op
== TOKtype
|| e2x
->op
== TOKscope
)
7546 exp
->error("%s is not an expression", exp
->e2
->toChars());
7549 if (e1x
->op
== TOKerror
)
7554 if (e2x
->op
== TOKerror
)
7560 // The result type is 'bool', unless the right operand has type 'void'.
7561 if (e2x
->type
->ty
== Tvoid
)
7562 exp
->type
= Type::tvoid
;
7564 exp
->type
= Type::tbool
;
7571 void visit(InExp
*exp
)
7579 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7584 Expression
*e
= exp
->op_overload(sc
);
7591 Type
*t2b
= exp
->e2
->type
->toBasetype();
7596 TypeAArray
*ta
= (TypeAArray
*)t2b
;
7598 // Special handling for array keys
7599 if (!arrayTypeCompatible(exp
->e1
->loc
, exp
->e1
->type
, ta
->index
))
7601 // Convert key to type of key
7602 exp
->e1
= exp
->e1
->implicitCastTo(sc
, ta
->index
);
7605 semanticTypeInfo(sc
, ta
->index
);
7607 // Return type is pointer to value
7608 exp
->type
= ta
->nextOf()->pointerTo();
7613 result
= exp
->incompatibleTypes();
7622 void visit(RemoveExp
*e
)
7624 if (Expression
*ex
= binSemantic(e
, sc
))
7632 void visit(CmpExp
*exp
)
7640 setNoderefOperands(exp
);
7642 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7647 Type
*t1
= exp
->e1
->type
->toBasetype();
7648 Type
*t2
= exp
->e2
->type
->toBasetype();
7649 if ((t1
->ty
== Tclass
&& exp
->e2
->op
== TOKnull
) ||
7650 (t2
->ty
== Tclass
&& exp
->e1
->op
== TOKnull
))
7652 exp
->error("do not use null when comparing class types");
7656 Expression
*e
= exp
->op_overload(sc
);
7659 if (!e
->type
->isscalar() && e
->type
->equals(exp
->e1
->type
))
7661 exp
->error("recursive opCmp expansion");
7664 if (e
->op
== TOKcall
)
7666 e
= new CmpExp(exp
->op
, exp
->loc
, e
, new IntegerExp(exp
->loc
, 0, Type::tint32
));
7667 e
= semantic(e
, sc
);
7673 if (Expression
*ex
= typeCombine(exp
, sc
))
7679 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7680 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7684 exp
->type
= Type::tbool
;
7686 // Special handling for array comparisons
7687 t1
= exp
->e1
->type
->toBasetype();
7688 t2
= exp
->e2
->type
->toBasetype();
7689 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
|| t1
->ty
== Tpointer
) &&
7690 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
|| t2
->ty
== Tpointer
))
7692 Type
*t1next
= t1
->nextOf();
7693 Type
*t2next
= t2
->nextOf();
7694 if (t1next
->implicitConvTo(t2next
) < MATCHconst
&&
7695 t2next
->implicitConvTo(t1next
) < MATCHconst
&&
7696 (t1next
->ty
!= Tvoid
&& t2next
->ty
!= Tvoid
))
7698 exp
->error("array comparison type mismatch, %s vs %s", t1next
->toChars(), t2next
->toChars());
7701 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
7702 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
7704 semanticTypeInfo(sc
, t1
->nextOf());
7707 else if (t1
->ty
== Tstruct
|| t2
->ty
== Tstruct
||
7708 (t1
->ty
== Tclass
&& t2
->ty
== Tclass
))
7710 if (t2
->ty
== Tstruct
)
7711 exp
->error("need member function opCmp() for %s %s to compare", t2
->toDsymbol(sc
)->kind(), t2
->toChars());
7713 exp
->error("need member function opCmp() for %s %s to compare", t1
->toDsymbol(sc
)->kind(), t1
->toChars());
7716 else if (t1
->iscomplex() || t2
->iscomplex())
7718 exp
->error("compare not defined for complex operands");
7721 else if (t1
->ty
== Taarray
|| t2
->ty
== Taarray
)
7723 exp
->error("%s is not defined for associative arrays", Token::toChars(exp
->op
));
7726 else if (!Target::isVectorOpSupported(t1
, exp
->op
, t2
))
7728 result
= exp
->incompatibleTypes();
7733 bool r1
= exp
->e1
->checkValue();
7734 bool r2
= exp
->e2
->checkValue();
7742 // Refer rel_integral[] table
7743 case TOKunord
: altop
= TOKerror
; break;
7744 case TOKlg
: altop
= TOKnotequal
; break;
7745 case TOKleg
: altop
= TOKerror
; break;
7746 case TOKule
: altop
= TOKle
; break;
7747 case TOKul
: altop
= TOKlt
; break;
7748 case TOKuge
: altop
= TOKge
; break;
7749 case TOKug
: altop
= TOKgt
; break;
7750 case TOKue
: altop
= TOKequal
; break;
7751 default: altop
= TOKreserved
; break;
7753 if (altop
== TOKerror
&&
7754 (t1
->ty
== Tarray
|| t1
->ty
== Tsarray
||
7755 t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
7757 exp
->error("'%s' is not defined for array comparisons", Token::toChars(exp
->op
));
7760 if (altop
!= TOKreserved
)
7762 if (!t1
->isfloating())
7764 if (altop
== TOKerror
)
7766 const char *s
= exp
->op
== TOKunord
? "false" : "true";
7767 exp
->error("floating point operator '%s' always returns %s for non-floating comparisons",
7768 Token::toChars(exp
->op
), s
);
7772 exp
->error("use '%s' for non-floating comparisons rather than floating point operator '%s'",
7773 Token::toChars(altop
), Token::toChars(exp
->op
));
7778 exp
->error("use std.math.isNaN to deal with NaN operands rather than floating point operator '%s'",
7779 Token::toChars(exp
->op
));
7784 //printf("CmpExp: %s, type = %s\n", e->toChars(), e->type->toChars());
7788 void visit(EqualExp
*exp
)
7790 //printf("EqualExp::semantic('%s')\n", toChars());
7797 setNoderefOperands(exp
);
7799 if (Expression
*e
= binSemanticProp(exp
, sc
))
7804 if (exp
->e1
->op
== TOKtype
|| exp
->e2
->op
== TOKtype
)
7806 result
= exp
->incompatibleTypes();
7811 Type
*t1
= exp
->e1
->type
;
7812 Type
*t2
= exp
->e2
->type
;
7813 if (t1
->ty
== Tenum
&& t2
->ty
== Tenum
&& !t1
->equivalent(t2
))
7814 exp
->deprecation("Comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`",
7815 t1
->toChars(), t2
->toChars());
7818 /* Before checking for operator overloading, check to see if we're
7819 * comparing the addresses of two statics. If so, we can just see
7820 * if they are the same symbol.
7822 if (exp
->e1
->op
== TOKaddress
&& exp
->e2
->op
== TOKaddress
)
7824 AddrExp
*ae1
= (AddrExp
*)exp
->e1
;
7825 AddrExp
*ae2
= (AddrExp
*)exp
->e2
;
7826 if (ae1
->e1
->op
== TOKvar
&& ae2
->e1
->op
== TOKvar
)
7828 VarExp
*ve1
= (VarExp
*)ae1
->e1
;
7829 VarExp
*ve2
= (VarExp
*)ae2
->e1
;
7831 if (ve1
->var
== ve2
->var
)
7833 // They are the same, result is 'true' for ==, 'false' for !=
7834 result
= new IntegerExp(exp
->loc
, (exp
->op
== TOKequal
), Type::tbool
);
7840 if (Expression
*e
= exp
->op_overload(sc
))
7846 if (Expression
*e
= typeCombine(exp
, sc
))
7852 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7853 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7857 exp
->type
= Type::tbool
;
7859 // Special handling for array comparisons
7860 if (!arrayTypeCompatible(exp
->loc
, exp
->e1
->type
, exp
->e2
->type
))
7862 if (exp
->e1
->type
!= exp
->e2
->type
&& exp
->e1
->type
->isfloating() && exp
->e2
->type
->isfloating())
7864 // Cast both to complex
7865 exp
->e1
= exp
->e1
->castTo(sc
, Type::tcomplex80
);
7866 exp
->e2
= exp
->e2
->castTo(sc
, Type::tcomplex80
);
7869 if (exp
->e1
->type
->toBasetype()->ty
== Taarray
)
7870 semanticTypeInfo(sc
, exp
->e1
->type
->toBasetype());
7872 Type
*t1
= exp
->e1
->type
->toBasetype();
7873 Type
*t2
= exp
->e2
->type
->toBasetype();
7875 if (!Target::isVectorOpSupported(t1
, exp
->op
, t2
))
7877 result
= exp
->incompatibleTypes();
7884 void visit(IdentityExp
*exp
)
7892 setNoderefOperands(exp
);
7894 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7900 if (Expression
*ex
= typeCombine(exp
, sc
))
7906 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7907 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7911 exp
->type
= Type::tbool
;
7913 if (exp
->e1
->type
!= exp
->e2
->type
&& exp
->e1
->type
->isfloating() && exp
->e2
->type
->isfloating())
7915 // Cast both to complex
7916 exp
->e1
= exp
->e1
->castTo(sc
, Type::tcomplex80
);
7917 exp
->e2
= exp
->e2
->castTo(sc
, Type::tcomplex80
);
7920 Type
*tb1
= exp
->e1
->type
->toBasetype();
7921 Type
*tb2
= exp
->e2
->type
->toBasetype();
7922 if (!Target::isVectorOpSupported(tb1
, exp
->op
, tb2
))
7924 result
= exp
->incompatibleTypes();
7931 void visit(CondExp
*exp
)
7939 if (exp
->econd
->op
== TOKdotid
)
7940 ((DotIdExp
*)exp
->econd
)->noderef
= true;
7942 Expression
*ec
= semantic(exp
->econd
, sc
);
7943 ec
= resolveProperties(sc
, ec
);
7944 ec
= ec
->toBoolean(sc
);
7946 unsigned cs0
= sc
->callSuper
;
7947 unsigned *fi0
= sc
->saveFieldInit();
7948 Expression
*e1x
= semantic(exp
->e1
, sc
);
7949 e1x
= resolveProperties(sc
, e1x
);
7951 unsigned cs1
= sc
->callSuper
;
7952 unsigned *fi1
= sc
->fieldinit
;
7953 sc
->callSuper
= cs0
;
7954 sc
->fieldinit
= fi0
;
7955 Expression
*e2x
= semantic(exp
->e2
, sc
);
7956 e2x
= resolveProperties(sc
, e2x
);
7958 sc
->mergeCallSuper(exp
->loc
, cs1
);
7959 sc
->mergeFieldInit(exp
->loc
, fi1
);
7961 if (ec
->op
== TOKerror
)
7966 if (ec
->type
== Type::terror
)
7970 if (e1x
->op
== TOKerror
)
7975 if (e1x
->type
== Type::terror
)
7979 if (e2x
->op
== TOKerror
)
7984 if (e2x
->type
== Type::terror
)
7988 bool f0
= checkNonAssignmentArrayOp(exp
->econd
);
7989 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7990 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7994 Type
*t1
= exp
->e1
->type
;
7995 Type
*t2
= exp
->e2
->type
;
7996 // If either operand is void the result is void, we have to cast both
7997 // the expression to void so that we explicitly discard the expression
7998 // value if any (bugzilla 16598)
7999 if (t1
->ty
== Tvoid
|| t2
->ty
== Tvoid
)
8001 exp
->type
= Type::tvoid
;
8002 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
);
8003 exp
->e2
= exp
->e2
->castTo(sc
, exp
->type
);
8009 if (Expression
*ex
= typeCombine(exp
, sc
))
8014 switch (exp
->e1
->type
->toBasetype()->ty
)
8019 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
8022 switch (exp
->e2
->type
->toBasetype()->ty
)
8027 exp
->e1
= exp
->e1
->castTo(sc
, exp
->e2
->type
);
8030 if (exp
->type
->toBasetype()->ty
== Tarray
)
8032 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
);
8033 exp
->e2
= exp
->e2
->castTo(sc
, exp
->type
);
8036 exp
->type
= exp
->type
->merge2();
8038 /* Bugzilla 14696: If either e1 or e2 contain temporaries which need dtor,
8039 * make them conditional.
8041 * cond ? (__tmp1 = ..., __tmp1) : (__tmp2 = ..., __tmp2)
8043 * (auto __cond = cond) ? (... __tmp1) : (... __tmp2)
8044 * and replace edtors of __tmp1 and __tmp2 with:
8045 * __tmp1->edtor --> __cond && __tmp1.dtor()
8046 * __tmp2->edtor --> __cond || __tmp2.dtor()
8053 void visit(FileInitExp
*e
)
8055 //printf("FileInitExp::semantic()\n");
8056 e
->type
= Type::tstring
;
8060 void visit(LineInitExp
*e
)
8062 e
->type
= Type::tint32
;
8066 void visit(ModuleInitExp
*e
)
8068 //printf("ModuleInitExp::semantic()\n");
8069 e
->type
= Type::tstring
;
8073 void visit(FuncInitExp
*e
)
8075 //printf("FuncInitExp::semantic()\n");
8076 e
->type
= Type::tstring
;
8079 result
= e
->resolveLoc(Loc(), sc
);
8085 void visit(PrettyFuncInitExp
*e
)
8087 //printf("PrettyFuncInitExp::semantic()\n");
8088 e
->type
= Type::tstring
;
8091 result
= e
->resolveLoc(Loc(), sc
);
8098 /**********************************
8099 * Try to run semantic routines.
8100 * If they fail, return NULL.
8102 Expression
*trySemantic(Expression
*exp
, Scope
* sc
)
8104 //printf("+trySemantic(%s)\n", toChars());
8105 unsigned errors
= global
.startGagging();
8106 Expression
*e
= semantic(exp
, sc
);
8107 if (global
.endGagging(errors
))
8111 //printf("-trySemantic(%s)\n", toChars());
8115 /**************************
8116 * Helper function for easy error propagation.
8117 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8119 Expression
*unaSemantic(UnaExp
*e
, Scope
*sc
)
8121 Expression
*e1x
= semantic(e
->e1
, sc
);
8122 if (e1x
->op
== TOKerror
)
8128 /**************************
8129 * Helper function for easy error propagation.
8130 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8132 Expression
*binSemantic(BinExp
*e
, Scope
*sc
)
8134 Expression
*e1x
= semantic(e
->e1
, sc
);
8135 Expression
*e2x
= semantic(e
->e2
, sc
);
8137 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
8138 if (e1x
->op
== TOKtype
)
8139 e1x
= resolveAliasThis(sc
, e1x
);
8140 if (e2x
->op
== TOKtype
)
8141 e2x
= resolveAliasThis(sc
, e2x
);
8143 if (e1x
->op
== TOKerror
)
8145 if (e2x
->op
== TOKerror
)
8152 Expression
*binSemanticProp(BinExp
*e
, Scope
*sc
)
8154 if (Expression
*ex
= binSemantic(e
, sc
))
8156 Expression
*e1x
= resolveProperties(sc
, e
->e1
);
8157 Expression
*e2x
= resolveProperties(sc
, e
->e2
);
8158 if (e1x
->op
== TOKerror
)
8160 if (e2x
->op
== TOKerror
)
8167 // entrypoint for semantic ExpressionSemanticVisitor
8168 Expression
*semantic(Expression
*e
, Scope
*sc
)
8170 ExpressionSemanticVisitor v
= ExpressionSemanticVisitor(sc
);
8175 Expression
*semanticX(DotIdExp
*exp
, Scope
*sc
)
8177 //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
8178 if (Expression
*ex
= unaSemantic(exp
, sc
))
8181 if (exp
->ident
== Id::_mangleof
)
8185 switch (exp
->e1
->op
)
8188 ds
= ((ScopeExp
*)exp
->e1
)->sds
;
8191 ds
= ((VarExp
*)exp
->e1
)->var
;
8194 ds
= ((DotVarExp
*)exp
->e1
)->var
;
8196 case TOKoverloadset
:
8197 ds
= ((OverExp
*)exp
->e1
)->vars
;
8201 TemplateExp
*te
= (TemplateExp
*)exp
->e1
;
8202 ds
= te
->fd
? (Dsymbol
*)te
->fd
: te
->td
;
8207 if (FuncDeclaration
*f
= ds
->isFuncDeclaration())
8209 if (f
->checkForwardRef(exp
->loc
))
8210 return new ErrorExp();
8213 mangleToBuffer(ds
, &buf
);
8214 const char *s
= buf
.extractString();
8215 Expression
*e
= new StringExp(exp
->loc
, const_cast<char*>(s
), strlen(s
));
8216 e
= semantic(e
, sc
);
8224 if (exp
->e1
->op
== TOKvar
&& exp
->e1
->type
->toBasetype()->ty
== Tsarray
&& exp
->ident
== Id::length
)
8226 // bypass checkPurity
8227 return exp
->e1
->type
->dotExp(sc
, exp
->e1
, exp
->ident
, exp
->noderef
? 2 : 0);
8230 if (exp
->e1
->op
== TOKdot
)
8235 exp
->e1
= resolvePropertiesX(sc
, exp
->e1
);
8237 if (exp
->e1
->op
== TOKtuple
&& exp
->ident
== Id::offsetof
)
8239 /* 'distribute' the .offsetof to each of the tuple elements.
8241 TupleExp
*te
= (TupleExp
*)exp
->e1
;
8242 Expressions
*exps
= new Expressions();
8243 exps
->setDim(te
->exps
->dim
);
8244 for (size_t i
= 0; i
< exps
->dim
; i
++)
8246 Expression
*e
= (*te
->exps
)[i
];
8247 e
= semantic(e
, sc
);
8248 e
= new DotIdExp(e
->loc
, e
, Id::offsetof
);
8251 // Don't evaluate te->e0 in runtime
8252 Expression
*e
= new TupleExp(exp
->loc
, NULL
, exps
);
8253 e
= semantic(e
, sc
);
8256 if (exp
->e1
->op
== TOKtuple
&& exp
->ident
== Id::length
)
8258 TupleExp
*te
= (TupleExp
*)exp
->e1
;
8259 // Don't evaluate te->e0 in runtime
8260 Expression
*e
= new IntegerExp(exp
->loc
, te
->exps
->dim
, Type::tsize_t
);
8264 // Bugzilla 14416: Template has no built-in properties except for 'stringof'.
8265 if ((exp
->e1
->op
== TOKdottd
|| exp
->e1
->op
== TOKtemplate
) && exp
->ident
!= Id::stringof
)
8267 exp
->error("template %s does not have property '%s'", exp
->e1
->toChars(), exp
->ident
->toChars());
8268 return new ErrorExp();
8273 exp
->error("expression %s does not have property '%s'", exp
->e1
->toChars(), exp
->ident
->toChars());
8274 return new ErrorExp();
8280 // Resolve e1.ident without seeing UFCS.
8281 // If flag == 1, stop "not a property" error and return NULL.
8282 Expression
*semanticY(DotIdExp
*exp
, Scope
*sc
, int flag
)
8284 //printf("DotIdExp::semanticY(this = %p, '%s')\n", this, toChars());
8286 //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }
8288 /* Special case: rewrite this.id and super.id
8289 * to be classtype.id and baseclasstype.id
8290 * if we have no this pointer.
8292 if ((exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
) && !hasThis(sc
))
8294 if (AggregateDeclaration
*ad
= sc
->getStructClassScope())
8296 if (exp
->e1
->op
== TOKthis
)
8298 exp
->e1
= new TypeExp(exp
->e1
->loc
, ad
->type
);
8302 ClassDeclaration
*cd
= ad
->isClassDeclaration();
8303 if (cd
&& cd
->baseClass
)
8304 exp
->e1
= new TypeExp(exp
->e1
->loc
, cd
->baseClass
->type
);
8309 Expression
*e
= semanticX(exp
, sc
);
8315 if (exp
->e1
->op
== TOKdot
)
8317 DotExp
*de
= (DotExp
*)exp
->e1
;
8327 Type
*t1b
= exp
->e1
->type
->toBasetype();
8329 if (eright
->op
== TOKscope
) // also used for template alias's
8331 ScopeExp
*ie
= (ScopeExp
*)eright
;
8332 int flags
= SearchLocalsOnly
;
8334 /* Disable access to another module's private imports.
8335 * The check for 'is sds our current module' is because
8336 * the current module should have access to its own imports.
8338 if (ie
->sds
->isModule() && ie
->sds
!= sc
->_module
)
8339 flags
|= IgnorePrivateImports
;
8340 if (sc
->flags
& SCOPEignoresymbolvisibility
)
8341 flags
|= IgnoreSymbolVisibility
;
8342 Dsymbol
*s
= ie
->sds
->search(exp
->loc
, exp
->ident
, flags
);
8343 /* Check for visibility before resolving aliases because public
8344 * aliases to private symbols are public.
8346 if (s
&& !(sc
->flags
& SCOPEignoresymbolvisibility
) && !symbolIsVisible(sc
->_module
, s
))
8348 if (s
->isDeclaration())
8349 ::error(exp
->loc
, "%s is not visible from module %s", s
->toPrettyChars(), sc
->_module
->toChars());
8351 ::deprecation(exp
->loc
, "%s is not visible from module %s", s
->toPrettyChars(), sc
->_module
->toChars());
8356 if (Package
*p
= s
->isPackage())
8357 checkAccess(exp
->loc
, sc
, p
);
8359 // if 's' is a tuple variable, the tuple is returned.
8362 exp
->checkDeprecated(sc
, s
);
8364 EnumMember
*em
= s
->isEnumMember();
8367 return em
->getVarExp(exp
->loc
, sc
);
8370 VarDeclaration
*v
= s
->isVarDeclaration();
8373 //printf("DotIdExp:: Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
8375 (!v
->type
->deco
&& v
->inuse
))
8378 exp
->error("circular reference to %s '%s'", v
->kind(), v
->toPrettyChars());
8380 exp
->error("forward reference to %s '%s'", v
->kind(), v
->toPrettyChars());
8381 return new ErrorExp();
8383 if (v
->type
->ty
== Terror
)
8384 return new ErrorExp();
8386 if ((v
->storage_class
& STCmanifest
) && v
->_init
&& !exp
->wantsym
)
8388 /* Normally, the replacement of a symbol with its initializer is supposed to be in semantic2().
8389 * Introduced by https://github.com/dlang/dmd/pull/5588 which should probably
8390 * be reverted. `wantsym` is the hack to work around the problem.
8394 ::error(exp
->loc
, "circular initialization of %s '%s'", v
->kind(), v
->toPrettyChars());
8395 return new ErrorExp();
8397 e
= v
->expandInitializer(exp
->loc
);
8399 e
= semantic(e
, sc
);
8407 eleft
= new ThisExp(exp
->loc
);
8408 e
= new DotVarExp(exp
->loc
, eleft
, v
);
8409 e
= semantic(e
, sc
);
8413 e
= new VarExp(exp
->loc
, v
);
8415 { e
= new CommaExp(exp
->loc
, eleft
, e
);
8420 return semantic(e
, sc
);
8423 FuncDeclaration
*f
= s
->isFuncDeclaration();
8426 //printf("it's a function\n");
8427 if (!f
->functionSemantic())
8428 return new ErrorExp();
8432 eleft
= new ThisExp(exp
->loc
);
8433 e
= new DotVarExp(exp
->loc
, eleft
, f
, true);
8434 e
= semantic(e
, sc
);
8438 e
= new VarExp(exp
->loc
, f
, true);
8440 { e
= new CommaExp(exp
->loc
, eleft
, e
);
8446 if (TemplateDeclaration
*td
= s
->isTemplateDeclaration())
8449 e
= new DotTemplateExp(exp
->loc
, eleft
, td
);
8451 e
= new TemplateExp(exp
->loc
, td
);
8452 e
= semantic(e
, sc
);
8455 if (OverDeclaration
*od
= s
->isOverDeclaration())
8457 e
= new VarExp(exp
->loc
, od
, true);
8460 e
= new CommaExp(exp
->loc
, eleft
, e
);
8461 e
->type
= Type::tvoid
; // ambiguous type?
8465 OverloadSet
*o
= s
->isOverloadSet();
8467 { //printf("'%s' is an overload set\n", o->toChars());
8468 return new OverExp(exp
->loc
, o
);
8471 if (Type
*t
= s
->getType())
8473 return semantic(new TypeExp(exp
->loc
, t
), sc
);
8476 TupleDeclaration
*tup
= s
->isTupleDeclaration();
8481 e
= new DotVarExp(exp
->loc
, eleft
, tup
);
8482 e
= semantic(e
, sc
);
8485 e
= new TupleExp(exp
->loc
, tup
);
8486 e
= semantic(e
, sc
);
8490 ScopeDsymbol
*sds
= s
->isScopeDsymbol();
8493 //printf("it's a ScopeDsymbol %s\n", exp->ident->toChars());
8494 e
= new ScopeExp(exp
->loc
, sds
);
8495 e
= semantic(e
, sc
);
8497 e
= new DotExp(exp
->loc
, eleft
, e
);
8501 Import
*imp
= s
->isImport();
8504 ie
= new ScopeExp(exp
->loc
, imp
->pkg
);
8505 return semantic(ie
, sc
);
8508 // BUG: handle other cases like in IdentifierExp::semantic()
8511 else if (exp
->ident
== Id::stringof
)
8513 const char *p
= ie
->toChars();
8514 e
= new StringExp(exp
->loc
, const_cast<char *>(p
), strlen(p
));
8515 e
= semantic(e
, sc
);
8518 if (ie
->sds
->isPackage() ||
8519 ie
->sds
->isImport() ||
8520 ie
->sds
->isModule())
8526 s
= ie
->sds
->search_correct(exp
->ident
);
8528 exp
->error("undefined identifier '%s' in %s '%s', did you mean %s '%s'?",
8529 exp
->ident
->toChars(), ie
->sds
->kind(), ie
->sds
->toPrettyChars(), s
->kind(), s
->toChars());
8531 exp
->error("undefined identifier '%s' in %s '%s'",
8532 exp
->ident
->toChars(), ie
->sds
->kind(), ie
->sds
->toPrettyChars());
8533 return new ErrorExp();
8535 else if (t1b
->ty
== Tpointer
&& exp
->e1
->type
->ty
!= Tenum
&&
8536 exp
->ident
!= Id::_init
&& exp
->ident
!= Id::__sizeof
&&
8537 exp
->ident
!= Id::__xalignof
&& exp
->ident
!= Id::offsetof
&&
8538 exp
->ident
!= Id::_mangleof
&& exp
->ident
!= Id::stringof
)
8540 Type
*t1bn
= t1b
->nextOf();
8543 AggregateDeclaration
*ad
= isAggregate(t1bn
);
8544 if (ad
&& !ad
->members
) // Bugzilla 11312
8553 if (flag
&& t1bn
->ty
== Tvoid
)
8555 e
= new PtrExp(exp
->loc
, exp
->e1
);
8556 e
= semantic(e
, sc
);
8557 return e
->type
->dotExp(sc
, e
, exp
->ident
, flag
| (exp
->noderef
? 2 : 0));
8561 if (exp
->e1
->op
== TOKtype
|| exp
->e1
->op
== TOKtemplate
)
8563 e
= exp
->e1
->type
->dotExp(sc
, exp
->e1
, exp
->ident
, flag
| (exp
->noderef
? 2 : 0));
8565 e
= semantic(e
, sc
);
8570 // Resolve e1.ident!tiargs without seeing UFCS.
8571 // If flag == 1, stop "not a property" error and return NULL.
8572 Expression
*semanticY(DotTemplateInstanceExp
*exp
, Scope
*sc
, int flag
)
8574 DotIdExp
*die
= new DotIdExp(exp
->loc
, exp
->e1
, exp
->ti
->name
);
8576 Expression
*e
= semanticX(die
, sc
);
8579 exp
->e1
= die
->e1
; // take back
8581 Type
*t1b
= exp
->e1
->type
->toBasetype();
8582 if (t1b
->ty
== Tarray
|| t1b
->ty
== Tsarray
|| t1b
->ty
== Taarray
||
8583 t1b
->ty
== Tnull
|| (t1b
->isTypeBasic() && t1b
->ty
!= Tvoid
))
8585 /* No built-in type has templatized properties, so do shortcut.
8586 * It is necessary in: 1024.max!"a < b"
8591 e
= semanticY(die
, sc
, flag
);
8592 if (flag
&& e
&& isDotOpDispatch(e
))
8594 /* opDispatch!tiargs would be a function template that needs IFTI,
8595 * so it's not a template
8597 e
= NULL
; /* fall down to UFCS */
8604 if (e
->op
== TOKerror
)
8606 if (e
->op
== TOKdotvar
)
8608 DotVarExp
*dve
= (DotVarExp
*)e
;
8609 if (FuncDeclaration
*fd
= dve
->var
->isFuncDeclaration())
8611 TemplateDeclaration
*td
= fd
->findTemplateDeclRoot();
8614 e
= new DotTemplateExp(dve
->loc
, dve
->e1
, td
);
8615 e
= semantic(e
, sc
);
8618 else if (dve
->var
->isOverDeclaration())
8620 exp
->e1
= dve
->e1
; // pull semantic() result
8621 if (!exp
->findTempDecl(sc
))
8623 if (exp
->ti
->needsTypeInference(sc
))
8625 exp
->ti
->semantic(sc
);
8626 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8627 return new ErrorExp();
8628 Dsymbol
*s
= exp
->ti
->toAlias();
8629 Declaration
*v
= s
->isDeclaration();
8632 if (v
->type
&& !v
->type
->deco
)
8633 v
->type
= v
->type
->semantic(v
->loc
, sc
);
8634 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8635 e
= semantic(e
, sc
);
8638 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8639 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8640 e
= semantic(e
, sc
);
8644 else if (e
->op
== TOKvar
)
8646 VarExp
*ve
= (VarExp
*)e
;
8647 if (FuncDeclaration
*fd
= ve
->var
->isFuncDeclaration())
8649 TemplateDeclaration
*td
= fd
->findTemplateDeclRoot();
8652 e
= new TemplateExp(ve
->loc
, td
);
8653 e
= semantic(e
, sc
);
8656 else if (OverDeclaration
*od
= ve
->var
->isOverDeclaration())
8658 exp
->ti
->tempdecl
= od
;
8659 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8660 e
= semantic(e
, sc
);
8664 if (e
->op
== TOKdottd
)
8666 DotTemplateExp
*dte
= (DotTemplateExp
*)e
;
8667 exp
->e1
= dte
->e1
; // pull semantic() result
8669 exp
->ti
->tempdecl
= dte
->td
;
8670 if (!exp
->ti
->semanticTiargs(sc
))
8671 return new ErrorExp();
8672 if (exp
->ti
->needsTypeInference(sc
))
8674 exp
->ti
->semantic(sc
);
8675 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8676 return new ErrorExp();
8677 Dsymbol
*s
= exp
->ti
->toAlias();
8678 Declaration
*v
= s
->isDeclaration();
8679 if (v
&& (v
->isFuncDeclaration() || v
->isVarDeclaration()))
8681 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8682 e
= semantic(e
, sc
);
8685 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8686 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8687 e
= semantic(e
, sc
);
8690 else if (e
->op
== TOKtemplate
)
8692 exp
->ti
->tempdecl
= ((TemplateExp
*)e
)->td
;
8693 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8694 e
= semantic(e
, sc
);
8697 else if (e
->op
== TOKdot
)
8699 DotExp
*de
= (DotExp
*)e
;
8701 if (de
->e2
->op
== TOKoverloadset
)
8703 if (!exp
->findTempDecl(sc
) ||
8704 !exp
->ti
->semanticTiargs(sc
))
8706 return new ErrorExp();
8708 if (exp
->ti
->needsTypeInference(sc
))
8710 exp
->ti
->semantic(sc
);
8711 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8712 return new ErrorExp();
8713 Dsymbol
*s
= exp
->ti
->toAlias();
8714 Declaration
*v
= s
->isDeclaration();
8717 if (v
->type
&& !v
->type
->deco
)
8718 v
->type
= v
->type
->semantic(v
->loc
, sc
);
8719 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8720 e
= semantic(e
, sc
);
8723 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8724 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8725 e
= semantic(e
, sc
);
8729 else if (e
->op
== TOKoverloadset
)
8731 OverExp
*oe
= (OverExp
*)e
;
8732 exp
->ti
->tempdecl
= oe
->vars
;
8733 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8734 e
= semantic(e
, sc
);
8738 e
->error("%s isn't a template", e
->toChars());
8739 return new ErrorExp();