2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * http://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * http://www.boost.org/LICENSE_1_0.txt
10 #include "root/dsystem.h"
11 #include "root/rmem.h"
12 #include "root/root.h"
18 #include "expression.h"
23 #include "statement.h"
24 #include "declaration.h"
25 #include "aggregate.h"
37 bool typeMerge(Scope
*sc
, TOK op
, Type
**pt
, Expression
**pe1
, Expression
**pe2
);
38 bool isArrayOpValid(Expression
*e
);
39 Expression
*expandVar(int result
, VarDeclaration
*v
);
40 bool checkAssignEscape(Scope
*sc
, Expression
*e
, bool gag
);
41 bool checkParamArgumentEscape(Scope
*sc
, FuncDeclaration
*fdc
, Identifier
*par
, Expression
*arg
, bool gag
);
42 bool checkAccess(AggregateDeclaration
*ad
, Loc loc
, Scope
*sc
, Dsymbol
*smember
);
43 bool checkNestedRef(Dsymbol
*s
, Dsymbol
*p
);
44 bool checkFrameAccess(Loc loc
, Scope
*sc
, AggregateDeclaration
*ad
, size_t istart
= 0);
45 bool symbolIsVisible(Module
*mod
, Dsymbol
*s
);
46 bool symbolIsVisible(Scope
*sc
, Dsymbol
*s
);
47 VarDeclaration
*copyToTemp(StorageClass stc
, const char *name
, Expression
*e
);
48 Expression
*extractSideEffect(Scope
*sc
, const char *name
, Expression
**e0
, Expression
*e
, bool alwaysCopy
= false);
49 Type
*getTypeInfoType(Loc loc
, Type
*t
, Scope
*sc
);
50 bool MODimplicitConv(MOD modfrom
, MOD modto
);
51 MATCH
MODmethodConv(MOD modfrom
, MOD modto
);
52 void MODMatchToBuffer(OutBuffer
*buf
, unsigned char lhsMod
, unsigned char rhsMod
);
54 void unSpeculative(Scope
*sc
, RootObject
*o
);
55 bool arrayExpressionToCommonType(Scope
*sc
, Expressions
*exps
, Type
**pt
);
56 bool checkDefCtor(Loc loc
, Type
*t
);
57 bool isDotOpDispatch(Expression
*e
);
58 bool functionParameters(Loc loc
, Scope
*sc
, TypeFunction
*tf
, Type
*tthis
, Expressions
*arguments
, FuncDeclaration
*fd
, Type
**prettype
, Expression
**peprefix
);
59 Expression
*getRightThis(Loc loc
, Scope
*sc
, AggregateDeclaration
*ad
, Expression
*e1
, Declaration
*var
, int flag
= 0);
60 bool isNeedThisScope(Scope
*sc
, Declaration
*d
);
61 Expression
*resolveUFCS(Scope
*sc
, CallExp
*ce
);
62 bool checkUnsafeAccess(Scope
*sc
, Expression
*e
, bool readonly
, bool printmsg
);
63 bool isSafeCast(Expression
*e
, Type
*tfrom
, Type
*tto
);
64 FuncDeclaration
*isFuncAddress(Expression
*e
, bool *hasOverloads
= NULL
);
65 Expression
*callCpCtor(Scope
*sc
, Expression
*e
);
67 Expression
*resolve(Loc loc
, Scope
*sc
, Dsymbol
*s
, bool hasOverloads
);
68 Expression
*resolveUFCSProperties(Scope
*sc
, Expression
*e1
, Expression
*e2
= NULL
);
69 Expression
*resolvePropertiesX(Scope
*sc
, Expression
*e1
, Expression
*e2
= NULL
);
71 /****************************************
72 * Preprocess arguments to function.
74 * exps[] tuples expanded, properties resolved, rewritten in place
76 * true a semantic error occurred
79 static bool preFunctionParameters(Scope
*sc
, Expressions
*exps
)
86 for (size_t i
= 0; i
< exps
->length
; i
++)
88 Expression
*arg
= (*exps
)[i
];
90 arg
= resolveProperties(sc
, arg
);
91 if (arg
->op
== TOKtype
)
93 arg
->error("cannot pass type %s as a function argument", arg
->toChars());
97 else if (arg
->type
->toBasetype()->ty
== Tfunction
)
99 arg
->error("cannot pass type %s as a function argument", arg
->toChars());
100 arg
= new ErrorExp();
103 else if (checkNonAssignmentArrayOp(arg
))
105 arg
= new ErrorExp();
115 * Determines whether a symbol represents a module or package
116 * (Used as a helper for is(type == module) and is(type == package))
119 * sym = the symbol to be checked
122 * the symbol which `sym` represents (or `null` if it doesn't represent a `Package`)
124 Package
*resolveIsPackage(Dsymbol
*sym
)
127 if (Import
*imp
= sym
->isImport())
129 if (imp
->pkg
== NULL
)
131 error(sym
->loc
, "Internal Compiler Error: unable to process forward-referenced import `%s`",
138 pkg
= sym
->isPackage();
140 pkg
->resolvePKGunknown();
144 class ExpressionSemanticVisitor
: public Visitor
150 ExpressionSemanticVisitor(Scope
*sc
)
159 result
= new ErrorExp();
162 /*********************
163 * Mark the operand as will never be dereferenced,
164 * which is useful info for @safe checks.
165 * Do before semantic() on operands rewrites them.
167 static void setNoderefOperand(UnaExp
*e
)
169 if (e
->e1
->op
== TOKdotid
)
170 ((DotIdExp
*)e
->e1
)->noderef
= true;
173 /*********************
174 * Mark the operands as will never be dereferenced,
175 * which is useful info for @safe checks.
176 * Do before semantic() on operands rewrites them.
178 static void setNoderefOperands(BinExp
*e
)
180 if (e
->e1
->op
== TOKdotid
)
181 ((DotIdExp
*)e
->e1
)->noderef
= true;
182 if (e
->e2
->op
== TOKdotid
)
183 ((DotIdExp
*)e
->e2
)->noderef
= true;
186 static FuncDeclaration
*resolveOverloadSet(Loc loc
, Scope
*sc
,
187 OverloadSet
*os
, Objects
* tiargs
, Type
*tthis
, Expressions
*arguments
)
189 FuncDeclaration
*f
= NULL
;
190 for (size_t i
= 0; i
< os
->a
.length
; i
++)
192 Dsymbol
*s
= os
->a
[i
];
193 if (tiargs
&& s
->isFuncDeclaration())
195 if (FuncDeclaration
*f2
= resolveFuncCall(loc
, sc
, s
, tiargs
, tthis
, arguments
, 1))
201 /* Error if match in more than one overload set,
202 * even if one is a 'better' match than the other.
204 ScopeDsymbol::multiplyDefined(loc
, f
, f2
);
211 ::error(loc
, "no overload matches for %s", os
->toChars());
217 /****************************************************
218 * Determine if `exp`, which takes the address of `v`, can do so safely.
221 * exp = expression that takes the address of `v`
222 * v = the variable getting its address taken
224 * `true` if ok, `false` for error
226 static bool checkAddressVar(Scope
*sc
, UnaExp
*e
, VarDeclaration
*v
)
230 if (!v
->canTakeAddressOf())
232 e
->error("cannot take address of %s", e
->e1
->toChars());
235 if (sc
->func
&& !sc
->intypeof
&& !v
->isDataseg())
237 const char *p
= v
->isParameter() ? "parameter" : "local";
238 if (global
.params
.vsafe
)
240 // Taking the address of v means it cannot be set to 'scope' later
241 v
->storage_class
&= ~STCmaybescope
;
242 v
->doNotInferScope
= true;
243 if (v
->storage_class
& STCscope
&& sc
->func
->setUnsafe())
245 e
->error("cannot take address of scope %s %s in @safe function %s", p
, v
->toChars(), sc
->func
->toChars());
249 else if (sc
->func
->setUnsafe())
251 e
->error("cannot take address of %s %s in @safe function %s", p
, v
->toChars(), sc
->func
->toChars());
259 static bool checkVectorElem(Expression
*e
, Expression
*elem
)
261 if (elem
->isConst() == 1)
264 e
->error("constant expression expected, not %s", elem
->toChars());
269 void visit(Expression
*e
)
272 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
274 e
->type
= Type::tvoid
;
278 void visit(IntegerExp
*e
)
281 if (e
->type
->ty
== Terror
)
283 assert(e
->type
->deco
);
288 void visit(RealExp
*e
)
291 e
->type
= Type::tfloat64
;
293 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
297 void visit(ComplexExp
*e
)
300 e
->type
= Type::tcomplex80
;
302 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
306 void visit(IdentifierExp
*exp
)
308 if (exp
->type
) // This is used as the dummy expression
315 Dsymbol
*s
= sc
->search(exp
->loc
, exp
->ident
, &scopesym
);
323 /* See if the symbol was a member of an enclosing 'with'
325 WithScopeSymbol
*withsym
= scopesym
->isWithScopeSymbol();
326 if (withsym
&& withsym
->withstate
->wthis
&& symbolIsVisible(sc
, s
))
328 /* Disallow shadowing
330 // First find the scope of the with
332 while (scwith
->scopesym
!= scopesym
)
334 scwith
= scwith
->enclosing
;
337 // Look at enclosing scopes for symbols with the same name,
338 // in the same function
339 for (Scope
*scx
= scwith
; scx
&& scx
->func
== scwith
->func
; scx
= scx
->enclosing
)
342 if (scx
->scopesym
&& scx
->scopesym
->symtab
&&
343 (s2
= scx
->scopesym
->symtab
->lookup(s
->ident
)) != NULL
&&
346 exp
->error("with symbol %s is shadowing local symbol %s", s
->toPrettyChars(), s2
->toPrettyChars());
352 // Same as wthis.ident
353 // TODO: DotIdExp.semantic will find 'ident' from 'wthis' again.
354 // The redudancy should be removed.
355 e
= new VarExp(exp
->loc
, withsym
->withstate
->wthis
);
356 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
357 e
= expressionSemantic(e
, sc
);
363 if (withsym
->withstate
->exp
->type
->ty
!= Tvoid
)
365 // with (exp)' is a type expression
366 // or 's' is not visible there (for error message)
367 e
= new TypeExp(exp
->loc
, withsym
->withstate
->exp
->type
);
371 // 'with (exp)' is a Package/Module
372 e
= withsym
->withstate
->exp
;
374 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
375 result
= expressionSemantic(e
, sc
);
379 /* If f is really a function template,
380 * then replace f with the function template declaration.
382 FuncDeclaration
*f
= s
->isFuncDeclaration();
385 TemplateDeclaration
*td
= getFuncTemplateDecl(f
);
388 if (td
->overroot
) // if not start of overloaded list of TemplateDeclaration's
389 td
= td
->overroot
; // then get the start
390 e
= new TemplateExp(exp
->loc
, td
, f
);
391 e
= expressionSemantic(e
, sc
);
396 // Haven't done overload resolution yet, so pass 1
397 e
= resolve(exp
->loc
, sc
, s
, true);
405 AggregateDeclaration
*ad
= sc
->getStructClassScope();
406 if (ad
&& ad
->aliasthis
)
409 e
= new IdentifierExp(exp
->loc
, Id::This
);
410 e
= new DotIdExp(exp
->loc
, e
, ad
->aliasthis
->ident
);
411 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
412 e
= trySemantic(e
, sc
);
421 if (exp
->ident
== Id::ctfe
)
423 if (sc
->flags
& SCOPEctfe
)
425 exp
->error("variable __ctfe cannot be read at compile time");
429 // Create the magic __ctfe bool variable
430 VarDeclaration
*vd
= new VarDeclaration(exp
->loc
, Type::tbool
, Id::ctfe
, NULL
);
431 vd
->storage_class
|= STCtemp
;
432 vd
->semanticRun
= PASSsemanticdone
;
433 Expression
*e
= new VarExp(exp
->loc
, vd
);
434 e
= expressionSemantic(e
, sc
);
439 // If we've reached this point and are inside a with() scope then we may
440 // try one last attempt by checking whether the 'wthis' object supports
441 // dynamic dispatching via opDispatch.
442 // This is done by rewriting this expression as wthis.ident.
443 for (Scope
*sc2
= sc
; sc2
; sc2
= sc2
->enclosing
)
448 if (WithScopeSymbol
*ss
= sc2
->scopesym
->isWithScopeSymbol())
450 if (ss
->withstate
->wthis
)
453 e
= new VarExp(exp
->loc
, ss
->withstate
->wthis
);
454 e
= new DotIdExp(exp
->loc
, e
, exp
->ident
);
455 e
= trySemantic(e
, sc
);
466 /* Look for what user might have meant
468 if (const char *n
= importHint(exp
->ident
->toChars()))
469 exp
->error("`%s` is not defined, perhaps `import %s;` is needed?", exp
->ident
->toChars(), n
);
470 else if (Dsymbol
*s2
= sc
->search_correct(exp
->ident
))
471 exp
->error("undefined identifier `%s`, did you mean %s `%s`?", exp
->ident
->toChars(), s2
->kind(), s2
->toChars());
472 else if (const char *p
= Scope::search_correct_C(exp
->ident
))
473 exp
->error("undefined identifier `%s`, did you mean `%s`?", exp
->ident
->toChars(), p
);
475 exp
->error("undefined identifier `%s`", exp
->ident
->toChars());
479 void visit(DsymbolExp
*e
)
481 result
= resolve(e
->loc
, sc
, e
->s
, e
->hasOverloads
);
484 void visit(ThisExp
*e
)
492 FuncDeclaration
*fd
= hasThis(sc
); // fd is the uplevel function with the 'this' variable
494 /* Special case for typeof(this) and typeof(super) since both
495 * should work even if they are not inside a non-static member function
497 if (!fd
&& sc
->intypeof
== 1)
499 // Find enclosing struct or class
500 for (Dsymbol
*s
= sc
->getStructClassScope(); 1; s
= s
->parent
)
504 e
->error("%s is not in a class or struct scope", e
->toChars());
507 ClassDeclaration
*cd
= s
->isClassDeclaration();
514 StructDeclaration
*sd
= s
->isStructDeclaration();
528 assert(e
->var
->parent
);
529 e
->type
= e
->var
->type
;
530 if (e
->var
->checkNestedReference(sc
, e
->loc
))
533 sc
->callSuper
|= CSXthis
;
538 e
->error("`this` is only defined in non-static member functions, not %s", sc
->parent
->toChars());
542 void visit(SuperExp
*e
)
550 FuncDeclaration
*fd
= hasThis(sc
);
551 ClassDeclaration
*cd
;
554 /* Special case for typeof(this) and typeof(super) since both
555 * should work even if they are not inside a non-static member function
557 if (!fd
&& sc
->intypeof
== 1)
559 // Find enclosing class
560 for (s
= sc
->getStructClassScope(); 1; s
= s
->parent
)
564 e
->error("%s is not in a class scope", e
->toChars());
567 cd
= s
->isClassDeclaration();
573 e
->error("class %s has no `super`", s
->toChars());
586 assert(e
->var
&& e
->var
->parent
);
589 while (s
&& s
->isTemplateInstance())
591 if (s
->isTemplateDeclaration()) // allow inside template constraint
594 cd
= s
->isClassDeclaration();
595 //printf("parent is %s %s\n", fd->toParent()->kind(), fd->toParent()->toChars());
600 e
->error("no base class for %s", cd
->toChars());
601 e
->type
= e
->var
->type
;
605 e
->type
= cd
->baseClass
->type
;
606 e
->type
= e
->type
->castMod(e
->var
->type
->mod
);
609 if (e
->var
->checkNestedReference(sc
, e
->loc
))
613 sc
->callSuper
|= CSXsuper
;
618 e
->error("`super` is only allowed in non-static class member functions");
622 void visit(NullExp
*e
)
624 // NULL is the same as (void *)0
630 e
->type
= Type::tnull
;
634 void visit(StringExp
*e
)
651 for (u
= 0; u
< e
->len
;)
653 p
= utf_decodeChar((utf8_t
*)e
->string
, e
->len
, &u
, &c
);
666 e
->string
= buffer
.extractData();
669 e
->type
= new TypeDArray(Type::tdchar
->immutableOf());
674 for (u
= 0; u
< e
->len
;)
676 p
= utf_decodeChar((utf8_t
*)e
->string
, e
->len
, &u
, &c
);
684 buffer
.writeUTF16(c
);
690 buffer
.writeUTF16(0);
691 e
->string
= buffer
.extractData();
694 e
->type
= new TypeDArray(Type::twchar
->immutableOf());
703 e
->type
= new TypeDArray(Type::tchar
->immutableOf());
706 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
707 //e->type = e->type->immutableOf();
708 //printf("type = %s\n", e->type->toChars());
713 void visit(ArrayLiteralExp
*e
)
721 /* Perhaps an empty array literal [ ] should be rewritten as null?
725 e
->basis
= expressionSemantic(e
->basis
, sc
);
726 if (arrayExpressionSemantic(e
->elements
, sc
) || (e
->basis
&& e
->basis
->op
== TOKerror
))
728 expandTuples(e
->elements
);
732 e
->elements
->push(e
->basis
);
733 bool err
= arrayExpressionToCommonType(sc
, e
->elements
, &t0
);
739 e
->type
= t0
->arrayOf();
740 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
742 /* Disallow array literals of type void being used.
744 if (e
->elements
->length
> 0 && t0
->ty
== Tvoid
)
746 e
->error("%s of type %s has no value", e
->toChars(), e
->type
->toChars());
750 if (global
.params
.useTypeInfo
&& Type::dtypeinfo
)
751 semanticTypeInfo(sc
, e
->type
);
756 void visit(AssocArrayLiteralExp
*e
)
764 // Run semantic() on each element
765 bool err_keys
= arrayExpressionSemantic(e
->keys
, sc
);
766 bool err_vals
= arrayExpressionSemantic(e
->values
, sc
);
767 if (err_keys
|| err_vals
)
769 expandTuples(e
->keys
);
770 expandTuples(e
->values
);
771 if (e
->keys
->length
!= e
->values
->length
)
773 e
->error("number of keys is %u, must match number of values %u", e
->keys
->length
, e
->values
->length
);
779 err_keys
= arrayExpressionToCommonType(sc
, e
->keys
, &tkey
);
780 err_vals
= arrayExpressionToCommonType(sc
, e
->values
, &tvalue
);
781 if (err_keys
|| err_vals
)
784 if (tkey
== Type::terror
|| tvalue
== Type::terror
)
787 e
->type
= new TypeAArray(tvalue
, tkey
);
788 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
790 semanticTypeInfo(sc
, e
->type
);
795 void visit(StructLiteralExp
*e
)
804 if (e
->sd
->sizeok
!= SIZEOKdone
)
807 if (arrayExpressionSemantic(e
->elements
, sc
)) // run semantic() on each element
809 expandTuples(e
->elements
);
811 /* Fit elements[] to the corresponding type of field[].
813 if (!e
->sd
->fit(e
->loc
, sc
, e
->elements
, e
->stype
))
816 /* Fill out remainder of elements[] with default initializers for fields[]
818 if (!e
->sd
->fill(e
->loc
, e
->elements
, false))
820 /* An error in the initializer needs to be recorded as an error
821 * in the enclosing function or template, since the initializer
822 * will be part of the stuct declaration.
824 global
.increaseErrorCount();
828 if (checkFrameAccess(e
->loc
, sc
, e
->sd
, e
->elements
->length
))
831 e
->type
= e
->stype
? e
->stype
: e
->sd
->type
;
835 void visit(TypeExp
*exp
)
837 if (exp
->type
->ty
== Terror
)
840 //printf("TypeExp::semantic(%s)\n", exp->type->toChars());
845 exp
->type
->resolve(exp
->loc
, sc
, &e
, &t
, &s
, true);
848 // `(Type)` is actually `(var)` so if `(var)` is a member requiring `this`
849 // then rewrite as `(this.var)` in case it would be followed by a DotVar
850 // to fix https://issues.dlang.org/show_bug.cgi?id=9490
851 VarExp
*ve
= e
->isVarExp();
852 if (ve
&& ve
->var
&& exp
->parens
&& !ve
->var
->isStatic() && !(sc
->stc
& STCstatic
) &&
853 sc
->func
&& sc
->func
->needThis() && ve
->var
->toParent2()->isAggregateDeclaration())
855 // printf("apply fix for issue 9490: add `this.` to `%s`...\n", e->toChars());
856 e
= new DotVarExp(exp
->loc
, new ThisExp(exp
->loc
), ve
->var
, false);
858 //printf("e = %s %s\n", Token::toChars(e->op), e->toChars());
859 e
= expressionSemantic(e
, sc
);
863 //printf("t = %d %s\n", t->ty, t->toChars());
864 exp
->type
= typeSemantic(t
, exp
->loc
, sc
);
869 //printf("s = %s %s\n", s->kind(), s->toChars());
870 e
= resolve(exp
->loc
, sc
, s
, true);
875 if (global
.params
.vcomplex
)
876 exp
->type
->checkComplexTransition(exp
->loc
);
881 void visit(ScopeExp
*exp
)
889 ScopeDsymbol
*sds2
= exp
->sds
;
890 TemplateInstance
*ti
= sds2
->isTemplateInstance();
893 WithScopeSymbol
*withsym
;
894 if (!ti
->findTempDecl(sc
, &withsym
) ||
895 !ti
->semanticTiargs(sc
))
897 if (withsym
&& withsym
->withstate
->wthis
)
899 Expression
*e
= new VarExp(exp
->loc
, withsym
->withstate
->wthis
);
900 e
= new DotTemplateInstanceExp(exp
->loc
, e
, ti
);
901 result
= expressionSemantic(e
, sc
);
904 if (ti
->needsTypeInference(sc
))
906 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
908 Dsymbol
*p
= td
->toParent2();
909 FuncDeclaration
*fdthis
= hasThis(sc
);
910 AggregateDeclaration
*ad
= p
? p
->isAggregateDeclaration() : NULL
;
911 if (fdthis
&& ad
&& isAggregate(fdthis
->vthis
->type
) == ad
&&
912 (td
->_scope
->stc
& STCstatic
) == 0)
914 Expression
*e
= new DotTemplateInstanceExp(exp
->loc
, new ThisExp(exp
->loc
), ti
->name
, ti
->tiargs
);
915 result
= expressionSemantic(e
, sc
);
919 else if (OverloadSet
*os
= ti
->tempdecl
->isOverloadSet())
921 FuncDeclaration
*fdthis
= hasThis(sc
);
922 AggregateDeclaration
*ad
= os
->parent
->isAggregateDeclaration();
923 if (fdthis
&& ad
&& isAggregate(fdthis
->vthis
->type
) == ad
)
925 Expression
*e
= new DotTemplateInstanceExp(exp
->loc
, new ThisExp(exp
->loc
), ti
->name
, ti
->tiargs
);
926 result
= expressionSemantic(e
, sc
);
930 // ti is an instance which requires IFTI.
932 exp
->type
= Type::tvoid
;
936 dsymbolSemantic(ti
, sc
);
937 if (!ti
->inst
|| ti
->errors
)
940 Dsymbol
*s
= ti
->toAlias();
944 exp
->type
= Type::tvoid
;
948 sds2
= s
->isScopeDsymbol();
951 ti
= sds2
->isTemplateInstance();
952 //printf("+ sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
956 if (VarDeclaration
*v
= s
->isVarDeclaration())
960 exp
->error("forward reference of %s %s", v
->kind(), v
->toChars());
963 if ((v
->storage_class
& STCmanifest
) && v
->_init
)
965 /* When an instance that will be converted to a constant exists,
966 * the instance representation "foo!tiargs" is treated like a
967 * variable name, and its recursive appearance check (note that
968 * it's equivalent with a recursive instantiation of foo) is done
969 * separately from the circular initialization check for the
970 * eponymous enum variable declaration.
973 * enum bool foo = foo; // recursive definition check (v.inuse)
976 * enum bool bar = bar!T; // recursive instantiation check (ti.inuse)
981 exp
->error("recursive expansion of %s `%s`", ti
->kind(), ti
->toPrettyChars());
985 Expression
*e
= v
->expandInitializer(exp
->loc
);
987 e
= expressionSemantic(e
, sc
);
994 //printf("s = %s, '%s'\n", s->kind(), s->toChars());
995 Expression
*e
= resolve(exp
->loc
, sc
, s
, true);
996 //printf("-1ScopeExp::semantic()\n");
1001 //printf("sds2 = %s, '%s'\n", sds2->kind(), sds2->toChars());
1002 //printf("\tparent = '%s'\n", sds2->parent->toChars());
1003 dsymbolSemantic(sds2
, sc
);
1005 if (Type
*t
= sds2
->getType()) // (Aggregate|Enum)Declaration
1007 Expression
*ex
= new TypeExp(exp
->loc
, t
);
1008 result
= expressionSemantic(ex
, sc
);
1012 if (TemplateDeclaration
*td
= sds2
->isTemplateDeclaration())
1014 result
= expressionSemantic(new TemplateExp(exp
->loc
, td
), sc
);
1019 exp
->type
= Type::tvoid
;
1020 //printf("-2ScopeExp::semantic() %s\n", exp->toChars());
1024 void visit(NewExp
*exp
)
1026 if (exp
->type
) // if semantic() already run
1032 // Bugzilla 11581: With the syntax `new T[edim]` or `thisexp.new T[edim]`,
1033 // T should be analyzed first and edim should go into arguments iff it's
1035 Expression
*edim
= NULL
;
1036 if (!exp
->arguments
&& exp
->newtype
->ty
== Tsarray
)
1038 edim
= ((TypeSArray
*)exp
->newtype
)->dim
;
1039 exp
->newtype
= ((TypeNext
*)exp
->newtype
)->next
;
1042 ClassDeclaration
*cdthis
= NULL
;
1045 exp
->thisexp
= expressionSemantic(exp
->thisexp
, sc
);
1046 if (exp
->thisexp
->op
== TOKerror
)
1048 cdthis
= exp
->thisexp
->type
->isClassHandle();
1051 exp
->error("`this` for nested class must be a class type, not %s", exp
->thisexp
->type
->toChars());
1055 sc
= sc
->push(cdthis
);
1056 exp
->type
= typeSemantic(exp
->newtype
, exp
->loc
, sc
);
1061 exp
->type
= typeSemantic(exp
->newtype
, exp
->loc
, sc
);
1063 if (exp
->type
->ty
== Terror
)
1068 if (exp
->type
->toBasetype()->ty
== Ttuple
)
1071 exp
->type
= new TypeSArray(exp
->type
, edim
);
1072 exp
->type
= typeSemantic(exp
->type
, exp
->loc
, sc
);
1073 if (exp
->type
->ty
== Terror
)
1078 // --> new T[](edim)
1079 exp
->arguments
= new Expressions();
1080 exp
->arguments
->push(edim
);
1081 exp
->type
= exp
->type
->arrayOf();
1085 exp
->newtype
= exp
->type
; // in case type gets cast to something else
1086 Type
*tb
= exp
->type
->toBasetype();
1087 //printf("tb: %s, deco = %s\n", tb->toChars(), tb->deco);
1089 if (arrayExpressionSemantic(exp
->newargs
, sc
) ||
1090 preFunctionParameters(sc
, exp
->newargs
))
1094 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
1095 preFunctionParameters(sc
, exp
->arguments
))
1100 if (exp
->thisexp
&& tb
->ty
!= Tclass
)
1102 exp
->error("e.new is only for allocating nested classes, not %s", tb
->toChars());
1106 size_t nargs
= exp
->arguments
? exp
->arguments
->length
: 0;
1107 Expression
*newprefix
= NULL
;
1109 if (tb
->ty
== Tclass
)
1111 ClassDeclaration
*cd
= ((TypeClass
*)tb
)->sym
;
1113 if (cd
->sizeok
!= SIZEOKdone
)
1116 cd
->ctor
= cd
->searchCtor();
1117 if (cd
->noDefaultCtor
&& !nargs
&& !cd
->defaultCtor
)
1119 exp
->error("default construction is disabled for type %s", cd
->type
->toChars());
1123 if (cd
->isInterfaceDeclaration())
1125 exp
->error("cannot create instance of interface %s", cd
->toChars());
1128 if (cd
->isAbstract())
1130 exp
->error("cannot create instance of abstract class %s", cd
->toChars());
1131 for (size_t i
= 0; i
< cd
->vtbl
.length
; i
++)
1133 FuncDeclaration
*fd
= cd
->vtbl
[i
]->isFuncDeclaration();
1134 if (fd
&& fd
->isAbstract())
1135 errorSupplemental(exp
->loc
, "function `%s` is not implemented", fd
->toFullSignature());
1139 // checkDeprecated() is already done in newtype->semantic().
1143 /* We need a 'this' pointer for the nested class.
1144 * Ensure we have the right one.
1146 Dsymbol
*s
= cd
->toParent2();
1147 //printf("cd isNested, parent = %s '%s'\n", s->kind(), s->toPrettyChars());
1148 if (ClassDeclaration
*cdn
= s
->isClassDeclaration())
1152 // Supply an implicit 'this' and try again
1153 exp
->thisexp
= new ThisExp(exp
->loc
);
1154 for (Dsymbol
*sp
= sc
->parent
; 1; sp
= sp
->parent
)
1158 exp
->error("outer class %s `this` needed to `new` nested class %s", cdn
->toChars(), cd
->toChars());
1161 ClassDeclaration
*cdp
= sp
->isClassDeclaration();
1164 if (cdp
== cdn
|| cdn
->isBaseOf(cdp
, NULL
))
1166 // Add a '.outer' and try again
1167 exp
->thisexp
= new DotIdExp(exp
->loc
, exp
->thisexp
, Id::outer
);
1169 exp
->thisexp
= expressionSemantic(exp
->thisexp
, sc
);
1170 if (exp
->thisexp
->op
== TOKerror
)
1172 cdthis
= exp
->thisexp
->type
->isClassHandle();
1174 if (cdthis
!= cdn
&& !cdn
->isBaseOf(cdthis
, NULL
))
1176 //printf("cdthis = %s\n", cdthis->toChars());
1177 exp
->error("`this` for nested class must be of type %s, not %s",
1178 cdn
->toChars(), exp
->thisexp
->type
->toChars());
1181 if (!MODimplicitConv(exp
->thisexp
->type
->mod
, exp
->newtype
->mod
))
1183 exp
->error("nested type %s should have the same or weaker constancy as enclosing type %s",
1184 exp
->newtype
->toChars(), exp
->thisexp
->type
->toChars());
1188 else if (exp
->thisexp
)
1190 exp
->error("e.new is only for allocating nested classes");
1193 else if (FuncDeclaration
*fdn
= s
->isFuncDeclaration())
1195 // make sure the parent context fdn of cd is reachable from sc
1196 if (checkNestedRef(sc
->parent
, fdn
))
1198 exp
->error("outer function context of %s is needed to `new` nested class %s",
1199 fdn
->toPrettyChars(), cd
->toPrettyChars());
1206 else if (exp
->thisexp
)
1208 exp
->error("e.new is only for allocating nested classes");
1214 // Prepend the size argument to newargs[]
1215 Expression
*e
= new IntegerExp(exp
->loc
, cd
->size(exp
->loc
), Type::tsize_t
);
1217 exp
->newargs
= new Expressions();
1218 exp
->newargs
->shift(e
);
1220 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, cd
->aggNew
, NULL
, tb
, exp
->newargs
);
1221 if (!f
|| f
->errors
)
1223 exp
->checkDeprecated(sc
, f
);
1224 exp
->checkDisabled(sc
, f
);
1225 exp
->checkPurity(sc
, f
);
1226 exp
->checkSafety(sc
, f
);
1227 exp
->checkNogc(sc
, f
);
1228 checkAccess(cd
, exp
->loc
, sc
, f
);
1230 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1232 if (functionParameters(exp
->loc
, sc
, tf
, NULL
, exp
->newargs
, f
, &rettype
, &newprefix
))
1235 exp
->allocator
= f
->isNewDeclaration();
1236 assert(exp
->allocator
);
1240 if (exp
->newargs
&& exp
->newargs
->length
)
1242 exp
->error("no allocator for %s", cd
->toChars());
1249 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, cd
->ctor
, NULL
, tb
, exp
->arguments
, 0);
1250 if (!f
|| f
->errors
)
1252 exp
->checkDeprecated(sc
, f
);
1253 exp
->checkDisabled(sc
, f
);
1254 exp
->checkPurity(sc
, f
);
1255 exp
->checkSafety(sc
, f
);
1256 exp
->checkNogc(sc
, f
);
1257 checkAccess(cd
, exp
->loc
, sc
, f
);
1259 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1260 if (!exp
->arguments
)
1261 exp
->arguments
= new Expressions();
1262 if (functionParameters(exp
->loc
, sc
, tf
, exp
->type
, exp
->arguments
, f
, &exp
->type
, &exp
->argprefix
))
1265 exp
->member
= f
->isCtorDeclaration();
1266 assert(exp
->member
);
1272 exp
->error("no constructor for %s", cd
->toChars());
1276 // https://issues.dlang.org/show_bug.cgi?id=19941
1277 // Run semantic on all field initializers to resolve any forward
1278 // references. This is the same as done for structs in sd->fill().
1279 for (ClassDeclaration
*c
= cd
; c
; c
= c
->baseClass
)
1281 for (size_t i
= 0; i
< c
->fields
.length
; i
++)
1283 VarDeclaration
*v
= c
->fields
[i
];
1284 if (v
->inuse
|| v
->_scope
== NULL
|| v
->_init
== NULL
||
1285 v
->_init
->isVoidInitializer())
1288 v
->_init
= initializerSemantic(v
->_init
, v
->_scope
, v
->type
, INITinterpret
);
1294 else if (tb
->ty
== Tstruct
)
1296 StructDeclaration
*sd
= ((TypeStruct
*)tb
)->sym
;
1298 if (sd
->sizeok
!= SIZEOKdone
)
1301 sd
->ctor
= sd
->searchCtor();
1302 if (sd
->noDefaultCtor
&& !nargs
)
1304 exp
->error("default construction is disabled for type %s", sd
->type
->toChars());
1307 // checkDeprecated() is already done in newtype->semantic().
1311 // Prepend the uint size argument to newargs[]
1312 Expression
*e
= new IntegerExp(exp
->loc
, sd
->size(exp
->loc
), Type::tsize_t
);
1314 exp
->newargs
= new Expressions();
1315 exp
->newargs
->shift(e
);
1317 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, sd
->aggNew
, NULL
, tb
, exp
->newargs
);
1318 if (!f
|| f
->errors
)
1320 exp
->checkDeprecated(sc
, f
);
1321 exp
->checkDisabled(sc
, f
);
1322 exp
->checkPurity(sc
, f
);
1323 exp
->checkSafety(sc
, f
);
1324 exp
->checkNogc(sc
, f
);
1325 checkAccess(sd
, exp
->loc
, sc
, f
);
1327 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1329 if (functionParameters(exp
->loc
, sc
, tf
, NULL
, exp
->newargs
, f
, &rettype
, &newprefix
))
1332 exp
->allocator
= f
->isNewDeclaration();
1333 assert(exp
->allocator
);
1337 if (exp
->newargs
&& exp
->newargs
->length
)
1339 exp
->error("no allocator for %s", sd
->toChars());
1344 if (sd
->ctor
&& nargs
)
1346 FuncDeclaration
*f
= resolveFuncCall(exp
->loc
, sc
, sd
->ctor
, NULL
, tb
, exp
->arguments
, 0);
1347 if (!f
|| f
->errors
)
1349 exp
->checkDeprecated(sc
, f
);
1350 exp
->checkDisabled(sc
, f
);
1351 exp
->checkPurity(sc
, f
);
1352 exp
->checkSafety(sc
, f
);
1353 exp
->checkNogc(sc
, f
);
1354 checkAccess(sd
, exp
->loc
, sc
, f
);
1356 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
1357 if (!exp
->arguments
)
1358 exp
->arguments
= new Expressions();
1359 if (functionParameters(exp
->loc
, sc
, tf
, exp
->type
, exp
->arguments
, f
, &exp
->type
, &exp
->argprefix
))
1362 exp
->member
= f
->isCtorDeclaration();
1363 assert(exp
->member
);
1365 if (checkFrameAccess(exp
->loc
, sc
, sd
, sd
->fields
.length
))
1370 if (!exp
->arguments
)
1371 exp
->arguments
= new Expressions();
1373 if (!sd
->fit(exp
->loc
, sc
, exp
->arguments
, tb
))
1375 if (!sd
->fill(exp
->loc
, exp
->arguments
, false))
1377 if (checkFrameAccess(exp
->loc
, sc
, sd
, exp
->arguments
? exp
->arguments
->length
: 0))
1381 exp
->type
= exp
->type
->pointerTo();
1383 else if (tb
->ty
== Tarray
&& nargs
)
1385 Type
*tn
= tb
->nextOf()->baseElemOf();
1386 Dsymbol
*s
= tn
->toDsymbol(sc
);
1387 AggregateDeclaration
*ad
= s
? s
->isAggregateDeclaration() : NULL
;
1388 if (ad
&& ad
->noDefaultCtor
)
1390 exp
->error("default construction is disabled for type %s", tb
->nextOf()->toChars());
1393 for (size_t i
= 0; i
< nargs
; i
++)
1395 if (tb
->ty
!= Tarray
)
1397 exp
->error("too many arguments for array");
1401 Expression
*arg
= (*exp
->arguments
)[i
];
1402 arg
= resolveProperties(sc
, arg
);
1403 arg
= arg
->implicitCastTo(sc
, Type::tsize_t
);
1404 arg
= arg
->optimize(WANTvalue
);
1405 if (arg
->op
== TOKint64
&& (sinteger_t
)arg
->toInteger() < 0)
1407 exp
->error("negative array index %s", arg
->toChars());
1410 (*exp
->arguments
)[i
] = arg
;
1411 tb
= ((TypeDArray
*)tb
)->next
->toBasetype();
1414 else if (tb
->isscalar())
1419 else if (nargs
== 1)
1421 Expression
*e
= (*exp
->arguments
)[0];
1422 e
= e
->implicitCastTo(sc
, tb
);
1423 (*exp
->arguments
)[0] = e
;
1427 exp
->error("more than one argument for construction of %s", exp
->type
->toChars());
1431 exp
->type
= exp
->type
->pointerTo();
1435 exp
->error("new can only create structs, dynamic arrays or class objects, not %s's", exp
->type
->toChars());
1439 //printf("NewExp: '%s'\n", toChars());
1440 //printf("NewExp:type '%s'\n", exp->type->toChars());
1441 semanticTypeInfo(sc
, exp
->type
);
1445 result
= Expression::combine(newprefix
, exp
);
1451 void visit(NewAnonClassExp
*e
)
1453 Expression
*d
= new DeclarationExp(e
->loc
, e
->cd
);
1454 sc
= sc
->push(); // just create new scope
1455 sc
->flags
&= ~SCOPEctfe
; // temporary stop CTFE
1456 d
= expressionSemantic(d
, sc
);
1459 if (!e
->cd
->errors
&& sc
->intypeof
&& !sc
->parent
->inNonRoot())
1461 ScopeDsymbol
*sds
= sc
->tinst
? (ScopeDsymbol
*)sc
->tinst
: sc
->_module
;
1462 sds
->members
->push(e
->cd
);
1465 Expression
*n
= new NewExp(e
->loc
, e
->thisexp
, e
->newargs
, e
->cd
->type
, e
->arguments
);
1467 Expression
*c
= new CommaExp(e
->loc
, d
, n
);
1468 result
= expressionSemantic(c
, sc
);
1471 void visit(SymOffExp
*e
)
1473 //dsymbolSemantic(var, sc);
1475 e
->type
= e
->var
->type
->pointerTo();
1476 if (VarDeclaration
*v
= e
->var
->isVarDeclaration())
1478 if (v
->checkNestedReference(sc
, e
->loc
))
1481 else if (FuncDeclaration
*f
= e
->var
->isFuncDeclaration())
1483 if (f
->checkNestedReference(sc
, e
->loc
))
1489 void visit(VarExp
*e
)
1491 VarDeclaration
*vd
= e
->var
->isVarDeclaration();
1492 FuncDeclaration
*fd
= e
->var
->isFuncDeclaration();
1496 //printf("L%d fd = %s\n", __LINE__, f->toChars());
1497 if (!fd
->functionSemantic())
1502 e
->type
= e
->var
->type
;
1504 if (e
->type
&& !e
->type
->deco
)
1506 Declaration
*decl
= e
->var
->isDeclaration();
1509 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
1514 /* Fix for 1161 doesn't work because it causes protection
1515 * problems when instantiating imported templates passing private
1516 * variables as alias template parameters.
1518 //checkAccess(e->loc, sc, NULL, e->var);
1522 if (vd
->checkNestedReference(sc
, e
->loc
))
1524 // Bugzilla 12025: If the variable is not actually used in runtime code,
1525 // the purity violation error is redundant.
1526 //checkPurity(sc, vd);
1530 // TODO: If fd isn't yet resolved its overload, the checkNestedReference
1531 // call would cause incorrect validation.
1532 // Maybe here should be moved in CallExp, or AddrExp for functions.
1533 if (fd
->checkNestedReference(sc
, e
->loc
))
1536 else if (e
->var
->isOverDeclaration())
1538 e
->type
= Type::tvoid
; // ambiguous type?
1544 void visit(TupleExp
*exp
)
1553 exp
->e0
= expressionSemantic(exp
->e0
, sc
);
1555 // Run semantic() on each argument
1557 for (size_t i
= 0; i
< exp
->exps
->length
; i
++)
1559 Expression
*e
= (*exp
->exps
)[i
];
1560 e
= expressionSemantic(e
, sc
);
1563 exp
->error("%s has no value", e
->toChars());
1566 else if (e
->op
== TOKerror
)
1569 (*exp
->exps
)[i
] = e
;
1574 expandTuples(exp
->exps
);
1575 exp
->type
= new TypeTuple(exp
->exps
);
1576 exp
->type
= typeSemantic(exp
->type
, exp
->loc
, sc
);
1577 //printf("-TupleExp::semantic(%s)\n", exp->toChars());
1581 void visit(FuncExp
*exp
)
1583 Expression
*e
= exp
;
1585 sc
= sc
->push(); // just create new scope
1586 sc
->flags
&= ~SCOPEctfe
; // temporary stop CTFE
1587 sc
->protection
= Prot(Prot::public_
); // Bugzilla 12506
1589 if (!exp
->type
|| exp
->type
== Type::tvoid
)
1591 /* fd->treq might be incomplete type,
1592 * so should not semantic it.
1593 * void foo(T)(T delegate(int) dg){}
1594 * foo(a=>a); // in IFTI, treq == T delegate(int)
1596 //if (exp->fd->treq)
1597 // exp->fd->treq = typeSemantic(exp->fd->treq, exp->loc, sc);
1601 // Set target of return type inference
1602 if (exp
->fd
->treq
&& !exp
->fd
->type
->nextOf())
1604 TypeFunction
*tfv
= NULL
;
1605 if (exp
->fd
->treq
->ty
== Tdelegate
||
1606 (exp
->fd
->treq
->ty
== Tpointer
&& exp
->fd
->treq
->nextOf()->ty
== Tfunction
))
1607 tfv
= (TypeFunction
*)exp
->fd
->treq
->nextOf();
1610 TypeFunction
*tfl
= (TypeFunction
*)exp
->fd
->type
;
1611 tfl
->next
= tfv
->nextOf();
1615 //printf("td = %p, treq = %p\n", exp->td, exp->fd->treq);
1618 assert(exp
->td
->parameters
&& exp
->td
->parameters
->length
);
1619 dsymbolSemantic(exp
->td
, sc
);
1620 exp
->type
= Type::tvoid
; // temporary type
1622 if (exp
->fd
->treq
) // defer type determination
1625 if (exp
->matchType(exp
->fd
->treq
, sc
, &fe
) > MATCHnomatch
)
1633 unsigned olderrors
= global
.errors
;
1634 dsymbolSemantic(exp
->fd
, sc
);
1635 if (olderrors
== global
.errors
)
1637 semantic2(exp
->fd
, sc
);
1638 if (olderrors
== global
.errors
)
1639 semantic3(exp
->fd
, sc
);
1641 if (olderrors
!= global
.errors
)
1643 if (exp
->fd
->type
&& exp
->fd
->type
->ty
== Tfunction
&& !exp
->fd
->type
->nextOf())
1644 ((TypeFunction
*)exp
->fd
->type
)->next
= Type::terror
;
1649 // Type is a "delegate to" or "pointer to" the function literal
1650 if ((exp
->fd
->isNested() && exp
->fd
->tok
== TOKdelegate
) ||
1651 (exp
->tok
== TOKreserved
&& exp
->fd
->treq
&& exp
->fd
->treq
->ty
== Tdelegate
))
1653 exp
->type
= new TypeDelegate(exp
->fd
->type
);
1654 exp
->type
= typeSemantic(exp
->type
, exp
->loc
, sc
);
1656 exp
->fd
->tok
= TOKdelegate
;
1660 exp
->type
= new TypePointer(exp
->fd
->type
);
1661 exp
->type
= typeSemantic(exp
->type
, exp
->loc
, sc
);
1662 //exp->type = exp->fd->type->pointerTo();
1664 /* A lambda expression deduced to function pointer might become
1665 * to a delegate literal implicitly.
1667 * auto foo(void function() fp) { return 1; }
1668 * assert(foo({}) == 1);
1670 * So, should keep fd->tok == TOKreserve if fd->treq == NULL.
1672 if (exp
->fd
->treq
&& exp
->fd
->treq
->ty
== Tpointer
)
1674 // change to non-nested
1675 exp
->fd
->tok
= TOKfunction
;
1676 exp
->fd
->vthis
= NULL
;
1679 exp
->fd
->tookAddressOf
++;
1686 // used from CallExp::semantic()
1687 Expression
*callExpSemantic(FuncExp
*exp
, Scope
*sc
, Expressions
*arguments
)
1689 if ((!exp
->type
|| exp
->type
== Type::tvoid
) && exp
->td
&& arguments
&& arguments
->length
)
1691 for (size_t k
= 0; k
< arguments
->length
; k
++)
1692 { Expression
*checkarg
= (*arguments
)[k
];
1693 if (checkarg
->op
== TOKerror
)
1699 assert(exp
->td
->parameters
&& exp
->td
->parameters
->length
);
1700 dsymbolSemantic(exp
->td
, sc
);
1702 TypeFunction
*tfl
= (TypeFunction
*)exp
->fd
->type
;
1703 size_t dim
= tfl
->parameterList
.length();
1704 if (arguments
->length
< dim
)
1705 { // Default arguments are always typed, so they don't need inference.
1706 Parameter
*p
= tfl
->parameterList
[arguments
->length
];
1708 dim
= arguments
->length
;
1711 if ((tfl
->parameterList
.varargs
== VARARGnone
&& arguments
->length
== dim
) ||
1712 (tfl
->parameterList
.varargs
!= VARARGnone
&& arguments
->length
>= dim
))
1714 Objects
*tiargs
= new Objects();
1715 tiargs
->reserve(exp
->td
->parameters
->length
);
1717 for (size_t i
= 0; i
< exp
->td
->parameters
->length
; i
++)
1719 TemplateParameter
*tp
= (*exp
->td
->parameters
)[i
];
1720 for (size_t u
= 0; u
< dim
; u
++)
1721 { Parameter
*p
= tfl
->parameterList
[u
];
1722 if (p
->type
->ty
== Tident
&&
1723 ((TypeIdentifier
*)p
->type
)->ident
== tp
->ident
)
1724 { Expression
*e
= (*arguments
)[u
];
1725 tiargs
->push(e
->type
);
1726 u
= dim
; // break inner loop
1731 TemplateInstance
*ti
= new TemplateInstance(exp
->loc
, exp
->td
, tiargs
);
1732 Expression
*se
= new ScopeExp(exp
->loc
, ti
);
1733 return expressionSemantic(se
, sc
);
1735 exp
->error("cannot infer function literal type");
1736 return new ErrorExp();
1738 return expressionSemantic(exp
, sc
);
1741 void visit(DeclarationExp
*e
)
1749 unsigned olderrors
= global
.errors
;
1751 /* This is here to support extern(linkage) declaration,
1752 * where the extern(linkage) winds up being an AttribDeclaration
1755 Dsymbol
*s
= e
->declaration
;
1759 AttribDeclaration
*ad
= s
->isAttribDeclaration();
1762 if (ad
->decl
&& ad
->decl
->length
== 1)
1771 VarDeclaration
*v
= s
->isVarDeclaration();
1774 // Do semantic() on initializer first, so:
1777 dsymbolSemantic(e
->declaration
, sc
);
1778 s
->parent
= sc
->parent
;
1781 //printf("inserting '%s' %p into sc = %p\n", s->toChars(), s, sc);
1782 // Insert into both local scope and function scope.
1783 // Must be unique in both.
1788 e
->error("declaration %s is already defined", s
->toPrettyChars());
1793 // Bugzilla 11720 - include Dataseg variables
1794 if ((s
->isFuncDeclaration() ||
1795 s
->isAggregateDeclaration() ||
1796 s
->isEnumDeclaration() ||
1797 (v
&& v
->isDataseg())) &&
1798 !sc
->func
->localsymtab
->insert(s
))
1800 e
->error("declaration %s is already defined in another scope in %s",
1801 s
->toPrettyChars(), sc
->func
->toChars());
1806 // Disallow shadowing
1807 for (Scope
*scx
= sc
->enclosing
; scx
&& (scx
->func
== sc
->func
|| (scx
->func
&& sc
->func
->fes
)); scx
= scx
->enclosing
)
1810 if (scx
->scopesym
&& scx
->scopesym
->symtab
&&
1811 (s2
= scx
->scopesym
->symtab
->lookup(s
->ident
)) != NULL
&&
1814 // allow STClocal symbols to be shadowed
1815 // TODO: not reallly an optimal design
1816 Declaration
*decl
= s2
->isDeclaration();
1817 if (!decl
|| !(decl
->storage_class
& STClocal
))
1821 e
->deprecation("%s `%s` is shadowing %s `%s`. Rename the `foreach` variable.",
1822 s
->kind(), s
->ident
->toChars(), s2
->kind(), s2
->toPrettyChars());
1826 e
->error("%s %s is shadowing %s %s",
1827 s
->kind(), s
->ident
->toChars(), s2
->kind(), s2
->toPrettyChars());
1836 if (!s
->isVarDeclaration())
1839 if (sc2
->stc
& (STCpure
| STCnothrow
| STCnogc
))
1841 sc2
->stc
&= ~(STCpure
| STCnothrow
| STCnogc
);
1842 dsymbolSemantic(e
->declaration
, sc2
);
1845 s
->parent
= sc
->parent
;
1847 if (global
.errors
== olderrors
)
1849 semantic2(e
->declaration
, sc
);
1850 if (global
.errors
== olderrors
)
1852 semantic3(e
->declaration
, sc
);
1855 // todo: error in declaration should be propagated.
1857 e
->type
= Type::tvoid
;
1861 void visit(TypeidExp
*exp
)
1863 Type
*ta
= isType(exp
->obj
);
1864 Expression
*ea
= isExpression(exp
->obj
);
1865 Dsymbol
*sa
= isDsymbol(exp
->obj
);
1867 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1871 ta
->resolve(exp
->loc
, sc
, &ea
, &ta
, &sa
, true);
1876 if (Dsymbol
*sym
= getDsymbol(ea
))
1877 ea
= resolve(exp
->loc
, sc
, sym
, false);
1879 ea
= expressionSemantic(ea
, sc
);
1880 ea
= resolveProperties(sc
, ea
);
1882 if (ea
->op
== TOKtype
)
1888 //printf("ta %p ea %p sa %p\n", ta, ea, sa);
1889 exp
->error("no type for typeid(%s)", ea
? ea
->toChars() : (sa
? sa
->toChars() : ""));
1893 if (global
.params
.vcomplex
)
1894 ta
->checkComplexTransition(exp
->loc
);
1897 if (ea
&& ta
->toBasetype()->ty
== Tclass
)
1899 if (!Type::typeinfoclass
)
1901 error(exp
->loc
, "`object.TypeInfo_Class` could not be found, but is implicitly used");
1906 /* Get the dynamic type, which is .classinfo
1908 ea
= expressionSemantic(ea
, sc
);
1909 e
= new TypeidExp(ea
->loc
, ea
);
1910 e
->type
= Type::typeinfoclass
->type
;
1913 else if (ta
->ty
== Terror
)
1919 // Handle this in the glue layer
1920 e
= new TypeidExp(exp
->loc
, ta
);
1921 e
->type
= getTypeInfoType(exp
->loc
, ta
, sc
);
1923 semanticTypeInfo(sc
, ta
);
1927 e
= new CommaExp(exp
->loc
, ea
, e
); // execute ea
1928 e
= expressionSemantic(e
, sc
);
1934 void visit(TraitsExp
*e
)
1936 result
= semanticTraits(e
, sc
);
1939 void visit(HaltExp
*e
)
1941 e
->type
= Type::tvoid
;
1945 void visit(IsExp
*e
)
1947 /* is(targ id tok tspec)
1948 * is(targ id : tok2)
1949 * is(targ id == tok2)
1952 //printf("IsExp::semantic(%s)\n", toChars());
1953 if (e
->id
&& !(sc
->flags
& SCOPEcondition
))
1955 e
->error("can only declare type aliases within static if conditionals or static asserts");
1960 if (e
->tok2
== TOKpackage
|| e
->tok2
== TOKmodule
) // These is() expressions are special because they can work on modules, not just types.
1962 Dsymbol
*sym
= e
->targ
->toDsymbol(sc
);
1965 Package
*p
= resolveIsPackage(sym
);
1968 if (e
->tok2
== TOKpackage
&& p
->isModule()) // Note that isModule() will return null for package modules because they're not actually instances of Module.
1970 else if(e
->tok2
== TOKmodule
&& !(p
->isModule() || p
->isPackageMod()))
1977 Scope
*sc2
= sc
->copy(); // keep sc->flags
1980 sc2
->flags
|= SCOPEfullinst
;
1981 Type
*t
= e
->targ
->trySemantic(e
->loc
, sc2
);
1983 if (!t
) // errors, so condition is false
1988 if (e
->tok2
!= TOKreserved
)
1993 if (e
->targ
->ty
!= Tstruct
)
1995 if (((TypeStruct
*)e
->targ
)->sym
->isUnionDeclaration())
2001 if (e
->targ
->ty
!= Tstruct
)
2003 if (!((TypeStruct
*)e
->targ
)->sym
->isUnionDeclaration())
2009 if (e
->targ
->ty
!= Tclass
)
2011 if (((TypeClass
*)e
->targ
)->sym
->isInterfaceDeclaration())
2017 if (e
->targ
->ty
!= Tclass
)
2019 if (!((TypeClass
*)e
->targ
)->sym
->isInterfaceDeclaration())
2024 if (!e
->targ
->isConst())
2030 if (!e
->targ
->isImmutable())
2036 if (!e
->targ
->isShared())
2042 if (!e
->targ
->isWild())
2048 // If class or interface, get the base class and interfaces
2049 if (e
->targ
->ty
!= Tclass
)
2053 ClassDeclaration
*cd
= ((TypeClass
*)e
->targ
)->sym
;
2054 Parameters
*args
= new Parameters
;
2055 args
->reserve(cd
->baseclasses
->length
);
2056 if (cd
->semanticRun
< PASSsemanticdone
)
2057 dsymbolSemantic(cd
, NULL
);
2058 for (size_t i
= 0; i
< cd
->baseclasses
->length
; i
++)
2060 BaseClass
*b
= (*cd
->baseclasses
)[i
];
2061 args
->push(new Parameter(STCin
, b
->type
, NULL
, NULL
, NULL
));
2063 tded
= new TypeTuple(args
);
2068 if (e
->targ
->ty
!= Tenum
)
2071 tded
= ((TypeEnum
*)e
->targ
)->sym
->getMemtype(e
->loc
);
2074 if (tded
->ty
== Terror
)
2079 if (e
->targ
->ty
!= Tdelegate
)
2081 tded
= ((TypeDelegate
*)e
->targ
)->next
; // the underlying function type
2087 if (e
->targ
->ty
!= Tfunction
)
2091 /* Generate tuple from function parameter types.
2093 assert(tded
->ty
== Tfunction
);
2094 TypeFunction
*tdedf
= (TypeFunction
*)tded
;
2095 size_t dim
= tdedf
->parameterList
.length();
2096 Parameters
*args
= new Parameters
;
2098 for (size_t i
= 0; i
< dim
; i
++)
2100 Parameter
*arg
= tdedf
->parameterList
[i
];
2101 assert(arg
&& arg
->type
);
2102 /* If one of the default arguments was an error,
2103 don't return an invalid tuple
2105 if (e
->tok2
== TOKparameters
&& arg
->defaultArg
&&
2106 arg
->defaultArg
->op
== TOKerror
)
2108 args
->push(new Parameter(arg
->storageClass
, arg
->type
,
2109 (e
->tok2
== TOKparameters
) ? arg
->ident
: NULL
,
2110 (e
->tok2
== TOKparameters
) ? arg
->defaultArg
: NULL
,
2111 arg
->userAttribDecl
));
2113 tded
= new TypeTuple(args
);
2117 /* Get the 'return type' for the function,
2118 * delegate, or pointer to function.
2120 if (e
->targ
->ty
== Tfunction
)
2121 tded
= ((TypeFunction
*)e
->targ
)->next
;
2122 else if (e
->targ
->ty
== Tdelegate
)
2124 tded
= ((TypeDelegate
*)e
->targ
)->next
;
2125 tded
= ((TypeFunction
*)tded
)->next
;
2127 else if (e
->targ
->ty
== Tpointer
&&
2128 ((TypePointer
*)e
->targ
)->next
->ty
== Tfunction
)
2130 tded
= ((TypePointer
*)e
->targ
)->next
;
2131 tded
= ((TypeFunction
*)tded
)->next
;
2138 /* Generate a type tuple of the equivalent types used to determine if a
2139 * function argument of this type can be passed in registers.
2140 * The results of this are highly platform dependent, and intended
2141 * primarly for use in implementing va_arg().
2143 tded
= target
.toArgTypes(e
->targ
);
2145 goto Lno
; // not valid for a parameter
2149 if (e
->targ
->ty
!= Tvector
)
2151 tded
= ((TypeVector
*)e
->targ
)->basetype
;
2159 else if (e
->tspec
&& !e
->id
&& !(e
->parameters
&& e
->parameters
->length
))
2161 /* Evaluate to true if targ matches tspec
2165 e
->tspec
= typeSemantic(e
->tspec
, e
->loc
, sc
);
2166 //printf("targ = %s, %s\n", e->targ->toChars(), e->targ->deco);
2167 //printf("tspec = %s, %s\n", e->tspec->toChars(), e->tspec->deco);
2168 if (e
->tok
== TOKcolon
)
2170 if (e
->targ
->implicitConvTo(e
->tspec
))
2177 if (e
->targ
->equals(e
->tspec
))
2185 /* Evaluate to true if targ matches tspec.
2186 * If true, declare id as an alias for the specialized type.
2187 * is(targ == tspec, tpl)
2188 * is(targ : tspec, tpl)
2189 * is(targ id == tspec)
2190 * is(targ id : tspec)
2191 * is(targ id == tspec, tpl)
2192 * is(targ id : tspec, tpl)
2195 Identifier
*tid
= e
->id
? e
->id
: Identifier::generateId("__isexp_id");
2196 e
->parameters
->insert(0, new TemplateTypeParameter(e
->loc
, tid
, NULL
, NULL
));
2199 dedtypes
.setDim(e
->parameters
->length
);
2202 MATCH m
= deduceType(e
->targ
, sc
, e
->tspec
, e
->parameters
, &dedtypes
);
2203 //printf("targ: %s\n", e->targ->toChars());
2204 //printf("tspec: %s\n", e->tspec->toChars());
2205 if (m
<= MATCHnomatch
||
2206 (m
!= MATCHexact
&& e
->tok
== TOKequal
))
2212 tded
= (Type
*)dedtypes
[0];
2217 tiargs
[0] = e
->targ
;
2219 /* Declare trailing parameters
2221 for (size_t i
= 1; i
< e
->parameters
->length
; i
++)
2223 TemplateParameter
*tp
= (*e
->parameters
)[i
];
2224 Declaration
*s
= NULL
;
2226 m
= tp
->matchArg(e
->loc
, sc
, &tiargs
, i
, e
->parameters
, &dedtypes
, &s
);
2227 if (m
<= MATCHnomatch
)
2229 dsymbolSemantic(s
, sc
);
2231 e
->error("declaration %s is already defined", s
->toChars());
2233 unSpeculative(sc
, s
);
2240 /* Declare id as an alias for type targ. Evaluate to true
2251 Tuple
*tup
= isTuple(tded
);
2253 s
= new TupleDeclaration(e
->loc
, e
->id
, &(tup
->objects
));
2255 s
= new AliasDeclaration(e
->loc
, e
->id
, tded
);
2256 dsymbolSemantic(s
, sc
);
2257 /* The reason for the !tup is unclear. It fails Phobos unittests if it is not there.
2258 * More investigation is needed.
2260 if (!tup
&& !sc
->insert(s
))
2261 e
->error("declaration %s is already defined", s
->toChars());
2263 unSpeculative(sc
, s
);
2266 result
= new IntegerExp(e
->loc
, 1, Type::tbool
);
2271 result
= new IntegerExp(e
->loc
, 0, Type::tbool
);
2274 void visit(BinAssignExp
*exp
)
2282 Expression
*e
= exp
->op_overload(sc
);
2289 if (exp
->e1
->checkReadModifyWrite(exp
->op
, exp
->e2
))
2292 if (exp
->e1
->op
== TOKarraylength
)
2294 // arr.length op= e2;
2295 e
= ArrayLengthExp::rewriteOpAssign(exp
);
2296 e
= expressionSemantic(e
, sc
);
2300 if (exp
->e1
->op
== TOKslice
|| exp
->e1
->type
->ty
== Tarray
|| exp
->e1
->type
->ty
== Tsarray
)
2302 if (checkNonAssignmentArrayOp(exp
->e1
))
2305 if (exp
->e1
->op
== TOKslice
)
2306 ((SliceExp
*)exp
->e1
)->arrayop
= true;
2309 if (exp
->e2
->implicitConvTo(exp
->e1
->type
->nextOf()))
2312 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
->nextOf());
2314 else if (Expression
*ex
= typeCombine(exp
, sc
))
2319 exp
->type
= exp
->e1
->type
;
2320 result
= arrayOp(exp
, sc
);
2324 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
2325 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
2326 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
2327 exp
->type
= exp
->e1
->type
;
2328 if (exp
->checkScalar())
2331 int arith
= (exp
->op
== TOKaddass
|| exp
->op
== TOKminass
|| exp
->op
== TOKmulass
||
2332 exp
->op
== TOKdivass
|| exp
->op
== TOKmodass
|| exp
->op
== TOKpowass
);
2333 int bitwise
= (exp
->op
== TOKandass
|| exp
->op
== TOKorass
|| exp
->op
== TOKxorass
);
2334 int shift
= (exp
->op
== TOKshlass
|| exp
->op
== TOKshrass
|| exp
->op
== TOKushrass
);
2336 if (bitwise
&& exp
->type
->toBasetype()->ty
== Tbool
)
2337 exp
->e2
= exp
->e2
->implicitCastTo(sc
, exp
->type
);
2338 else if (exp
->checkNoBool())
2341 if ((exp
->op
== TOKaddass
|| exp
->op
== TOKminass
) &&
2342 exp
->e1
->type
->toBasetype()->ty
== Tpointer
&&
2343 exp
->e2
->type
->toBasetype()->isintegral())
2345 result
= scaleFactor(exp
, sc
);
2349 if (Expression
*ex
= typeCombine(exp
, sc
))
2355 if (arith
&& exp
->checkArithmeticBin())
2357 if ((bitwise
|| shift
) && exp
->checkIntegralBin())
2361 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
2362 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
2365 if (!target
.isVectorOpSupported(exp
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
2367 result
= exp
->incompatibleTypes();
2371 if (exp
->e1
->op
== TOKerror
|| exp
->e2
->op
== TOKerror
)
2374 e
= exp
->checkOpAssignTypes(sc
);
2375 if (e
->op
== TOKerror
)
2381 assert(e
->op
== TOKassign
|| e
== exp
);
2382 result
= ((BinExp
*)e
)->reorderSettingAAElem(sc
);
2385 void visit(CompileExp
*exp
)
2387 StringExp
*se
= semanticString(sc
, exp
->e1
, "argument to mixin");
2390 se
= se
->toUTF8(sc
);
2391 unsigned errors
= global
.errors
;
2392 Parser
p(exp
->loc
, sc
->_module
, (utf8_t
*)se
->string
, se
->len
, 0);
2394 //printf("p.loc.linnum = %d\n", p.loc.linnum);
2395 Expression
*e
= p
.parseExpression();
2398 assert(global
.errors
!= errors
); // should have caught all these cases
2401 if (p
.token
.value
!= TOKeof
)
2403 exp
->error("incomplete mixin expression (%s)", se
->toChars());
2406 result
= expressionSemantic(e
, sc
);
2409 void visit(ImportExp
*e
)
2411 StringExp
*se
= semanticString(sc
, e
->e1
, "file name argument");
2414 se
= se
->toUTF8(sc
);
2416 const char *name
= (char *)se
->string
;
2417 if (!global
.params
.fileImppath
)
2419 e
->error("need -Jpath switch to import text file %s", name
);
2423 /* Be wary of CWE-22: Improper Limitation of a Pathname to a Restricted Directory
2424 * ('Path Traversal') attacks.
2425 * http://cwe.mitre.org/data/definitions/22.html
2428 name
= FileName::safeSearchPath(global
.filePath
, name
);
2431 e
->error("file %s cannot be found or not in a path specified with -J", se
->toChars());
2435 sc
->_module
->contentImportedFiles
.push(name
);
2436 if (global
.params
.verbose
)
2437 message("file %.*s\t(%s)", (int)se
->len
, (char *)se
->string
, name
);
2438 if (global
.params
.moduleDeps
!= NULL
)
2440 OutBuffer
*ob
= global
.params
.moduleDeps
;
2441 Module
* imod
= sc
->instantiatingModule();
2443 if (!global
.params
.moduleDepsFile
.length
)
2444 ob
->writestring("depsFile ");
2445 ob
->writestring(imod
->toPrettyChars());
2446 ob
->writestring(" (");
2447 escapePath(ob
, imod
->srcfile
->toChars());
2448 ob
->writestring(") : ");
2449 if (global
.params
.moduleDepsFile
.length
)
2450 ob
->writestring("string : ");
2451 ob
->writestring((char *) se
->string
);
2452 ob
->writestring(" (");
2453 escapePath(ob
, name
);
2454 ob
->writestring(")");
2462 e
->error("cannot read file %s", f
.toChars());
2468 se
= new StringExp(e
->loc
, f
.buffer
, f
.len
);
2471 result
= expressionSemantic(se
, sc
);
2474 void visit(AssertExp
*exp
)
2476 if (Expression
*ex
= unaSemantic(exp
, sc
))
2481 exp
->e1
= resolveProperties(sc
, exp
->e1
);
2482 // BUG: see if we can do compile time elimination of the Assert
2483 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
2484 exp
->e1
= exp
->e1
->toBoolean(sc
);
2487 exp
->msg
= expressionSemantic(exp
->msg
, sc
);
2488 exp
->msg
= resolveProperties(sc
, exp
->msg
);
2489 exp
->msg
= exp
->msg
->implicitCastTo(sc
, Type::tchar
->constOf()->arrayOf());
2490 exp
->msg
= exp
->msg
->optimize(WANTvalue
);
2493 if (exp
->e1
->op
== TOKerror
)
2498 if (exp
->msg
&& exp
->msg
->op
== TOKerror
)
2504 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
2505 bool f2
= exp
->msg
&& checkNonAssignmentArrayOp(exp
->msg
);
2509 if (exp
->e1
->isBool(false))
2511 FuncDeclaration
*fd
= sc
->parent
->isFuncDeclaration();
2513 fd
->hasReturnExp
|= 4;
2514 sc
->callSuper
|= CSXhalt
;
2517 for (size_t i
= 0; i
< sc
->fieldinit_dim
; i
++)
2518 sc
->fieldinit
[i
] |= CSXhalt
;
2521 if (global
.params
.useAssert
== CHECKENABLEoff
)
2523 Expression
*e
= new HaltExp(exp
->loc
);
2524 e
= expressionSemantic(e
, sc
);
2529 exp
->type
= Type::tvoid
;
2533 void visit(DotIdExp
*exp
)
2535 Expression
*e
= semanticY(exp
, sc
, 1);
2536 if (e
&& isDotOpDispatch(e
))
2538 unsigned errors
= global
.startGagging();
2539 e
= resolvePropertiesX(sc
, e
);
2540 if (global
.endGagging(errors
))
2541 e
= NULL
; /* fall down to UFCS */
2548 if (!e
) // if failed to find the property
2550 /* If ident is not a valid property, rewrite:
2555 e
= resolveUFCSProperties(sc
, exp
);
2560 void visit(DotTemplateExp
*e
)
2562 if (Expression
*ex
= unaSemantic(e
, sc
))
2570 void visit(DotVarExp
*exp
)
2578 exp
->var
= exp
->var
->toAlias()->isDeclaration();
2580 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
2582 if (TupleDeclaration
*tup
= exp
->var
->isTupleDeclaration())
2587 * tuple(e1.a, e1.b, e1.c)
2589 Expression
*e0
= NULL
;
2590 Expression
*ev
= sc
->func
? extractSideEffect(sc
, "__tup", &e0
, exp
->e1
) : exp
->e1
;
2592 Expressions
*exps
= new Expressions
;
2593 exps
->reserve(tup
->objects
->length
);
2594 for (size_t i
= 0; i
< tup
->objects
->length
; i
++)
2596 RootObject
*o
= (*tup
->objects
)[i
];
2598 if (o
->dyncast() == DYNCAST_EXPRESSION
)
2600 e
= (Expression
*)o
;
2601 if (e
->op
== TOKdsymbol
)
2603 Dsymbol
*s
= ((DsymbolExp
*)e
)->s
;
2604 e
= new DotVarExp(exp
->loc
, ev
, s
->isDeclaration());
2607 else if (o
->dyncast() == DYNCAST_DSYMBOL
)
2609 e
= new DsymbolExp(exp
->loc
, (Dsymbol
*)o
);
2611 else if (o
->dyncast() == DYNCAST_TYPE
)
2613 e
= new TypeExp(exp
->loc
, (Type
*)o
);
2617 exp
->error("%s is not an expression", o
->toChars());
2623 Expression
*e
= new TupleExp(exp
->loc
, e0
, exps
);
2624 e
= expressionSemantic(e
, sc
);
2629 exp
->e1
= exp
->e1
->addDtorHook(sc
);
2631 Type
*t1
= exp
->e1
->type
;
2633 if (FuncDeclaration
*fd
= exp
->var
->isFuncDeclaration())
2635 // for functions, do checks after overload resolution
2636 if (!fd
->functionSemantic())
2639 /* Bugzilla 13843: If fd obviously has no overloads, we should
2640 * normalize AST, and it will give a chance to wrap fd with FuncExp.
2642 if (fd
->isNested() || fd
->isFuncLiteralDeclaration())
2645 Expression
*e
= resolve(exp
->loc
, sc
, fd
, false);
2646 result
= Expression::combine(exp
->e1
, e
);
2650 exp
->type
= fd
->type
;
2653 else if (exp
->var
->isOverDeclaration())
2655 exp
->type
= Type::tvoid
; // ambiguous type?
2659 exp
->type
= exp
->var
->type
;
2660 if (!exp
->type
&& global
.errors
)
2662 // var is goofed up, just return 0
2667 if (t1
->ty
== Tpointer
)
2670 exp
->type
= exp
->type
->addMod(t1
->mod
);
2672 Dsymbol
*vparent
= exp
->var
->toParent();
2673 AggregateDeclaration
*ad
= vparent
? vparent
->isAggregateDeclaration() : NULL
;
2675 if (Expression
*e1x
= getRightThis(exp
->loc
, sc
, ad
, exp
->e1
, exp
->var
, 1))
2679 /* Later checkRightThis will report correct error for invalid field variable access.
2681 Expression
*e
= new VarExp(exp
->loc
, exp
->var
);
2682 e
= expressionSemantic(e
, sc
);
2686 checkAccess(exp
->loc
, sc
, exp
->e1
, exp
->var
);
2688 VarDeclaration
*v
= exp
->var
->isVarDeclaration();
2689 if (v
&& (v
->isDataseg() || (v
->storage_class
& STCmanifest
)))
2691 Expression
*e
= expandVar(WANTvalue
, v
);
2699 if (v
&& v
->isDataseg()) // fix bugzilla 8238
2702 checkAccess(exp
->loc
, sc
, exp
->e1
, v
);
2703 Expression
*e
= new VarExp(exp
->loc
, v
);
2704 e
= new CommaExp(exp
->loc
, exp
->e1
, e
);
2705 e
= expressionSemantic(e
, sc
);
2711 //printf("-DotVarExp::semantic('%s')\n", exp->toChars());
2715 void visit(DotTemplateInstanceExp
*exp
)
2717 // Indicate we need to resolve by UFCS.
2718 Expression
*e
= semanticY(exp
, sc
, 1);
2720 e
= resolveUFCSProperties(sc
, exp
);
2724 void visit(DelegateExp
*e
)
2732 e
->e1
= expressionSemantic(e
->e1
, sc
);
2733 e
->type
= new TypeDelegate(e
->func
->type
);
2734 e
->type
= typeSemantic(e
->type
, e
->loc
, sc
);
2735 FuncDeclaration
*f
= e
->func
->toAliasFunc();
2736 AggregateDeclaration
*ad
= f
->toParent()->isAggregateDeclaration();
2738 e
->e1
= getRightThis(e
->loc
, sc
, ad
, e
->e1
, f
);
2739 if (f
->type
->ty
== Tfunction
)
2741 TypeFunction
*tf
= (TypeFunction
*)f
->type
;
2742 if (!MODmethodConv(e
->e1
->type
->mod
, f
->type
->mod
))
2744 OutBuffer thisBuf
, funcBuf
;
2745 MODMatchToBuffer(&thisBuf
, e
->e1
->type
->mod
, tf
->mod
);
2746 MODMatchToBuffer(&funcBuf
, tf
->mod
, e
->e1
->type
->mod
);
2747 e
->error("%smethod %s is not callable using a %s%s",
2748 funcBuf
.peekChars(), f
->toPrettyChars(), thisBuf
.peekChars(), e
->e1
->toChars());
2752 if (ad
&& ad
->isClassDeclaration() && ad
->type
!= e
->e1
->type
)
2754 // A downcast is required for interfaces, see Bugzilla 3706
2755 e
->e1
= new CastExp(e
->loc
, e
->e1
, ad
->type
);
2756 e
->e1
= expressionSemantic(e
->e1
, sc
);
2761 void visit(DotTypeExp
*exp
)
2769 if (Expression
*e
= unaSemantic(exp
, sc
))
2775 exp
->type
= exp
->sym
->getType()->addMod(exp
->e1
->type
->mod
);
2779 void visit(CallExp
*exp
)
2783 result
= exp
; // semantic() already run
2788 Objects
*tiargs
= NULL
; // initial list of template arguments
2789 Expression
*ethis
= NULL
;
2791 Expression
*e1org
= exp
->e1
;
2793 if (exp
->e1
->op
== TOKcomma
)
2795 /* Rewrite (a,b)(args) as (a,(b(args)))
2797 CommaExp
*ce
= (CommaExp
*)exp
->e1
;
2800 result
= expressionSemantic(ce
, sc
);
2804 if (exp
->e1
->op
== TOKdelegate
)
2806 DelegateExp
*de
= (DelegateExp
*)exp
->e1
;
2807 exp
->e1
= new DotVarExp(de
->loc
, de
->e1
, de
->func
, de
->hasOverloads
);
2808 result
= expressionSemantic(exp
, sc
);
2812 if (exp
->e1
->op
== TOKfunction
)
2814 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
2815 preFunctionParameters(sc
, exp
->arguments
))
2820 // Run e1 semantic even if arguments have any errors
2821 FuncExp
*fe
= (FuncExp
*)exp
->e1
;
2822 exp
->e1
= callExpSemantic(fe
, sc
, exp
->arguments
);
2823 if (exp
->e1
->op
== TOKerror
)
2830 if (Expression
*ex
= resolveUFCS(sc
, exp
))
2837 * foo!(tiargs)(funcargs)
2839 if (exp
->e1
->op
== TOKscope
)
2841 ScopeExp
*se
= (ScopeExp
*)exp
->e1
;
2842 TemplateInstance
*ti
= se
->sds
->isTemplateInstance();
2845 /* Attempt to instantiate ti. If that works, go with it.
2846 * If not, go with partial explicit specialization.
2848 WithScopeSymbol
*withsym
;
2849 if (!ti
->findTempDecl(sc
, &withsym
) ||
2850 !ti
->semanticTiargs(sc
))
2854 if (withsym
&& withsym
->withstate
->wthis
)
2856 exp
->e1
= new VarExp(exp
->e1
->loc
, withsym
->withstate
->wthis
);
2857 exp
->e1
= new DotTemplateInstanceExp(exp
->e1
->loc
, exp
->e1
, ti
);
2860 if (ti
->needsTypeInference(sc
, 1))
2862 /* Go with partial explicit specialization
2864 tiargs
= ti
->tiargs
;
2865 assert(ti
->tempdecl
);
2866 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
2867 exp
->e1
= new TemplateExp(exp
->loc
, td
);
2868 else if (OverDeclaration
*od
= ti
->tempdecl
->isOverDeclaration())
2869 exp
->e1
= new VarExp(exp
->loc
, od
);
2871 exp
->e1
= new OverExp(exp
->loc
, ti
->tempdecl
->isOverloadSet());
2875 Expression
*e1x
= expressionSemantic(exp
->e1
, sc
);
2876 if (e1x
->op
== TOKerror
)
2887 * expr.foo!(tiargs)(funcargs)
2890 if (exp
->e1
->op
== TOKdotti
&& !exp
->e1
->type
)
2892 DotTemplateInstanceExp
*se
= (DotTemplateInstanceExp
*)exp
->e1
;
2893 TemplateInstance
*ti
= se
->ti
;
2895 /* Attempt to instantiate ti. If that works, go with it.
2896 * If not, go with partial explicit specialization.
2898 if (!se
->findTempDecl(sc
) ||
2899 !ti
->semanticTiargs(sc
))
2903 if (ti
->needsTypeInference(sc
, 1))
2905 /* Go with partial explicit specialization
2907 tiargs
= ti
->tiargs
;
2908 assert(ti
->tempdecl
);
2909 if (TemplateDeclaration
*td
= ti
->tempdecl
->isTemplateDeclaration())
2910 exp
->e1
= new DotTemplateExp(exp
->loc
, se
->e1
, td
);
2911 else if (OverDeclaration
*od
= ti
->tempdecl
->isOverDeclaration())
2913 exp
->e1
= new DotVarExp(exp
->loc
, se
->e1
, od
, true);
2916 exp
->e1
= new DotExp(exp
->loc
, se
->e1
, new OverExp(exp
->loc
, ti
->tempdecl
->isOverloadSet()));
2920 Expression
*e1x
= expressionSemantic(exp
->e1
, sc
);
2921 if (e1x
->op
== TOKerror
)
2932 //printf("Lagain: %s\n", exp->toChars());
2934 if (exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
)
2936 // semantic() run later for these
2940 if (exp
->e1
->op
== TOKdotid
)
2942 DotIdExp
*die
= (DotIdExp
*)exp
->e1
;
2943 exp
->e1
= expressionSemantic(die
, sc
);
2944 /* Look for e1 having been rewritten to expr.opDispatch!(string)
2945 * We handle such earlier, so go back.
2946 * Note that in the rewrite, we carefully did not run semantic() on e1
2948 if (exp
->e1
->op
== TOKdotti
&& !exp
->e1
->type
)
2956 if (++nest
> global
.recursionLimit
)
2958 exp
->error("recursive evaluation of %s", exp
->toChars());
2962 Expression
*ex
= unaSemantic(exp
, sc
);
2971 /* Look for e1 being a lazy parameter
2973 if (exp
->e1
->op
== TOKvar
)
2975 VarExp
*ve
= (VarExp
*)exp
->e1
;
2976 if (ve
->var
->storage_class
& STClazy
)
2978 // lazy paramaters can be called without violating purity and safety
2979 Type
*tw
= ve
->var
->type
;
2980 Type
*tc
= ve
->var
->type
->substWildTo(MODconst
);
2981 TypeFunction
*tf
= new TypeFunction(ParameterList(), tc
, LINKd
, STCsafe
| STCpure
);
2982 (tf
= (TypeFunction
*)typeSemantic(tf
, exp
->loc
, sc
))->next
= tw
; // hack for bug7757
2983 TypeDelegate
*t
= new TypeDelegate(tf
);
2984 ve
->type
= typeSemantic(t
, exp
->loc
, sc
);
2986 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
2987 if (v
&& ve
->checkPurity(sc
, v
))
2991 if (exp
->e1
->op
== TOKsymoff
&& ((SymOffExp
*)exp
->e1
)->hasOverloads
)
2993 SymOffExp
*se
= (SymOffExp
*)exp
->e1
;
2994 exp
->e1
= new VarExp(se
->loc
, se
->var
, true);
2995 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
2997 else if (exp
->e1
->op
== TOKdot
)
2999 DotExp
*de
= (DotExp
*) exp
->e1
;
3001 if (de
->e2
->op
== TOKoverloadset
)
3004 tthis
= de
->e1
->type
;
3008 else if (exp
->e1
->op
== TOKstar
&& exp
->e1
->type
->ty
== Tfunction
)
3010 // Rewrite (*fp)(arguments) to fp(arguments)
3011 exp
->e1
= ((PtrExp
*)exp
->e1
)->e1
;
3015 t1
= exp
->e1
->type
? exp
->e1
->type
->toBasetype() : NULL
;
3017 if (exp
->e1
->op
== TOKerror
)
3022 if (arrayExpressionSemantic(exp
->arguments
, sc
) ||
3023 preFunctionParameters(sc
, exp
->arguments
))
3028 // Check for call operator overload
3031 if (t1
->ty
== Tstruct
)
3033 StructDeclaration
*sd
= ((TypeStruct
*)t1
)->sym
;
3034 sd
->size(exp
->loc
); // Resolve forward references to construct object
3035 if (sd
->sizeok
!= SIZEOKdone
)
3038 sd
->ctor
= sd
->searchCtor();
3040 // First look for constructor
3041 if (exp
->e1
->op
== TOKtype
&& sd
->ctor
)
3043 if (!sd
->noDefaultCtor
&& !(exp
->arguments
&& exp
->arguments
->length
))
3046 StructLiteralExp
*sle
= new StructLiteralExp(exp
->loc
, sd
, NULL
, exp
->e1
->type
);
3047 if (!sd
->fill(exp
->loc
, sle
->elements
, true))
3049 if (checkFrameAccess(exp
->loc
, sc
, sd
, sle
->elements
->length
))
3051 // Bugzilla 14556: Set concrete type to avoid further redundant semantic().
3052 sle
->type
= exp
->e1
->type
;
3054 /* Constructor takes a mutable object, so don't use
3055 * the immutable initializer symbol.
3057 sle
->useStaticInit
= false;
3059 Expression
*e
= sle
;
3060 if (CtorDeclaration
*cf
= sd
->ctor
->isCtorDeclaration())
3062 e
= new DotVarExp(exp
->loc
, e
, cf
, true);
3064 else if (TemplateDeclaration
*td
= sd
->ctor
->isTemplateDeclaration())
3066 e
= new DotTemplateExp(exp
->loc
, e
, td
);
3068 else if (OverloadSet
*os
= sd
->ctor
->isOverloadSet())
3070 e
= new DotExp(exp
->loc
, e
, new OverExp(exp
->loc
, os
));
3074 e
= new CallExp(exp
->loc
, e
, exp
->arguments
);
3075 result
= expressionSemantic(e
, sc
);
3078 // No constructor, look for overload of opCall
3079 if (search_function(sd
, Id::call
))
3080 goto L1
; // overload of opCall, therefore it's a call
3082 if (exp
->e1
->op
!= TOKtype
)
3084 if (sd
->aliasthis
&& exp
->e1
->type
!= exp
->att1
)
3086 if (!exp
->att1
&& exp
->e1
->type
->checkAliasThisRec())
3087 exp
->att1
= exp
->e1
->type
;
3088 exp
->e1
= resolveAliasThis(sc
, exp
->e1
);
3091 exp
->error("%s %s does not overload ()", sd
->kind(), sd
->toChars());
3095 /* It's a struct literal
3098 Expression
*e
= new StructLiteralExp(exp
->loc
, sd
, exp
->arguments
, exp
->e1
->type
);
3099 result
= expressionSemantic(e
, sc
);
3102 else if (t1
->ty
== Tclass
)
3105 // Rewrite as e1.call(arguments)
3106 Expression
*e
= new DotIdExp(exp
->loc
, exp
->e1
, Id::call
);
3107 e
= new CallExp(exp
->loc
, e
, exp
->arguments
);
3108 result
= expressionSemantic(e
, sc
);
3111 else if (exp
->e1
->op
== TOKtype
&& t1
->isscalar())
3115 // Make sure to use the the enum type itself rather than its
3116 // base type (see bugzilla 16346)
3117 if (exp
->e1
->type
->ty
== Tenum
)
3122 if (!exp
->arguments
|| exp
->arguments
->length
== 0)
3124 e
= t1
->defaultInitLiteral(exp
->loc
);
3126 else if (exp
->arguments
->length
== 1)
3128 e
= (*exp
->arguments
)[0];
3129 e
= e
->implicitCastTo(sc
, t1
);
3130 e
= new CastExp(exp
->loc
, e
, t1
);
3134 exp
->error("more than one argument for construction of %s", t1
->toChars());
3137 result
= expressionSemantic(e
, sc
);
3142 if ((exp
->e1
->op
== TOKdotvar
&& t1
->ty
== Tfunction
) ||
3143 exp
->e1
->op
== TOKdottd
)
3145 UnaExp
*ue
= (UnaExp
*)(exp
->e1
);
3147 Expression
*ue1
= ue
->e1
;
3148 Expression
*ue1old
= ue1
; // need for 'right this' check
3150 if (ue1
->op
== TOKvar
&&
3151 (v
= ((VarExp
*)ue1
)->var
->isVarDeclaration()) != NULL
&&
3154 ue
->e1
= new TypeExp(ue1
->loc
, ue1
->type
);
3159 DotTemplateExp
*dte
;
3161 if (exp
->e1
->op
== TOKdotvar
)
3163 dve
= (DotVarExp
*)(exp
->e1
);
3171 dte
= (DotTemplateExp
*)(exp
->e1
);
3175 // Do overload resolution
3176 exp
->f
= resolveFuncCall(exp
->loc
, sc
, s
, tiargs
, ue1
? ue1
->type
: NULL
, exp
->arguments
);
3177 if (!exp
->f
|| exp
->f
->errors
|| exp
->f
->type
->ty
== Terror
)
3179 if (exp
->f
->interfaceVirtual
)
3181 /* Cast 'this' to the type of the interface, and replace f with the interface's equivalent
3183 BaseClass
*b
= exp
->f
->interfaceVirtual
;
3184 ClassDeclaration
*ad2
= b
->sym
;
3185 ue
->e1
= ue
->e1
->castTo(sc
, ad2
->type
->addMod(ue
->e1
->type
->mod
));
3186 ue
->e1
= expressionSemantic(ue
->e1
, sc
);
3188 int vi
= exp
->f
->findVtblIndex((Dsymbols
*)&ad2
->vtbl
, (int)ad2
->vtbl
.length
);
3190 exp
->f
= ad2
->vtbl
[vi
]->isFuncDeclaration();
3193 if (exp
->f
->needThis())
3195 AggregateDeclaration
*ad
= exp
->f
->toParent2()->isAggregateDeclaration();
3196 ue
->e1
= getRightThis(exp
->loc
, sc
, ad
, ue
->e1
, exp
->f
);
3197 if (ue
->e1
->op
== TOKerror
)
3203 tthis
= ue
->e1
->type
;
3204 if (!(exp
->f
->type
->ty
== Tfunction
&& ((TypeFunction
*)exp
->f
->type
)->isscope
))
3206 if (global
.params
.vsafe
&& checkParamArgumentEscape(sc
, exp
->f
, Id::This
, ethis
, false))
3211 /* Cannot call public functions from inside invariant
3212 * (because then the invariant would have infinite recursion)
3214 if (sc
->func
&& sc
->func
->isInvariantDeclaration() &&
3215 ue
->e1
->op
== TOKthis
&&
3216 exp
->f
->addPostInvariant()
3219 exp
->error("cannot call public/export function %s from invariant", exp
->f
->toChars());
3223 exp
->checkDeprecated(sc
, exp
->f
);
3224 exp
->checkDisabled(sc
, exp
->f
);
3225 exp
->checkPurity(sc
, exp
->f
);
3226 exp
->checkSafety(sc
, exp
->f
);
3227 exp
->checkNogc(sc
, exp
->f
);
3228 checkAccess(exp
->loc
, sc
, ue
->e1
, exp
->f
);
3229 if (!exp
->f
->needThis())
3231 exp
->e1
= Expression::combine(ue
->e1
, new VarExp(exp
->loc
, exp
->f
, false));
3235 if (ue1old
->checkRightThis(sc
))
3237 if (exp
->e1
->op
== TOKdotvar
)
3240 exp
->e1
->type
= exp
->f
->type
;
3244 exp
->e1
= new DotVarExp(exp
->loc
, dte
->e1
, exp
->f
, false);
3245 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
3246 if (exp
->e1
->op
== TOKerror
)
3248 ue
= (UnaExp
*)exp
->e1
;
3251 // See if we need to adjust the 'this' pointer
3252 AggregateDeclaration
*ad
= exp
->f
->isThis();
3253 ClassDeclaration
*cd
= ue
->e1
->type
->isClassHandle();
3254 if (ad
&& cd
&& ad
->isClassDeclaration())
3256 if (ue
->e1
->op
== TOKdottype
)
3258 ue
->e1
= ((DotTypeExp
*)ue
->e1
)->e1
;
3259 exp
->directcall
= true;
3261 else if (ue
->e1
->op
== TOKsuper
)
3262 exp
->directcall
= true;
3263 else if ((cd
->storage_class
& STCfinal
) != 0) // Bugzilla 14211
3264 exp
->directcall
= true;
3268 ue
->e1
= ue
->e1
->castTo(sc
, ad
->type
->addMod(ue
->e1
->type
->mod
));
3269 ue
->e1
= expressionSemantic(ue
->e1
, sc
);
3273 // If we've got a pointer to a function then deference it
3274 // https://issues.dlang.org/show_bug.cgi?id=16483
3275 if (exp
->e1
->type
->ty
== Tpointer
&& exp
->e1
->type
->nextOf()->ty
== Tfunction
)
3277 Expression
*e
= new PtrExp(exp
->loc
, exp
->e1
);
3278 e
->type
= exp
->e1
->type
->nextOf();
3283 else if (exp
->e1
->op
== TOKsuper
)
3285 // Base class constructor call
3286 AggregateDeclaration
*ad
= sc
->func
? sc
->func
->isThis() : NULL
;
3287 ClassDeclaration
*cd
= ad
? ad
->isClassDeclaration() : NULL
;
3288 if (!cd
|| !cd
->baseClass
|| !sc
->func
->isCtorDeclaration())
3290 exp
->error("super class constructor call must be in a constructor");
3293 if (!cd
->baseClass
->ctor
)
3295 exp
->error("no super class constructor for %s", cd
->baseClass
->toChars());
3299 if (!sc
->intypeof
&& !(sc
->callSuper
& CSXhalt
))
3301 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
3302 exp
->error("constructor calls not allowed in loops or after labels");
3303 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
3304 exp
->error("multiple constructor calls");
3305 if ((sc
->callSuper
& CSXreturn
) && !(sc
->callSuper
& CSXany_ctor
))
3306 exp
->error("an earlier return statement skips constructor");
3307 sc
->callSuper
|= CSXany_ctor
| CSXsuper_ctor
;
3310 tthis
= cd
->type
->addMod(sc
->func
->type
->mod
);
3311 if (OverloadSet
*os
= cd
->baseClass
->ctor
->isOverloadSet())
3312 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, NULL
, tthis
, exp
->arguments
);
3314 exp
->f
= resolveFuncCall(exp
->loc
, sc
, cd
->baseClass
->ctor
, NULL
, tthis
, exp
->arguments
, 0);
3315 if (!exp
->f
|| exp
->f
->errors
)
3317 exp
->checkDeprecated(sc
, exp
->f
);
3318 exp
->checkDisabled(sc
, exp
->f
);
3319 exp
->checkPurity(sc
, exp
->f
);
3320 exp
->checkSafety(sc
, exp
->f
);
3321 exp
->checkNogc(sc
, exp
->f
);
3322 checkAccess(exp
->loc
, sc
, NULL
, exp
->f
);
3324 exp
->e1
= new DotVarExp(exp
->e1
->loc
, exp
->e1
, exp
->f
, false);
3325 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
3328 else if (exp
->e1
->op
== TOKthis
)
3330 // same class constructor call
3331 AggregateDeclaration
*ad
= sc
->func
? sc
->func
->isThis() : NULL
;
3332 if (!ad
|| !sc
->func
->isCtorDeclaration())
3334 exp
->error("constructor call must be in a constructor");
3338 // https://issues.dlang.org/show_bug.cgi?id=18719
3339 // If `exp` is a call expression to another constructor
3340 // then it means that all struct/class fields will be
3341 // initialized after this call.
3342 for (size_t i
= 0; i
< sc
->fieldinit_dim
; i
++)
3343 sc
->fieldinit
[i
] |= CSXthis_ctor
;
3345 if (!sc
->intypeof
&& !(sc
->callSuper
& CSXhalt
))
3347 if (sc
->noctor
|| sc
->callSuper
& CSXlabel
)
3348 exp
->error("constructor calls not allowed in loops or after labels");
3349 if (sc
->callSuper
& (CSXsuper_ctor
| CSXthis_ctor
))
3350 exp
->error("multiple constructor calls");
3351 if ((sc
->callSuper
& CSXreturn
) && !(sc
->callSuper
& CSXany_ctor
))
3352 exp
->error("an earlier return statement skips constructor");
3353 sc
->callSuper
|= CSXany_ctor
| CSXthis_ctor
;
3356 tthis
= ad
->type
->addMod(sc
->func
->type
->mod
);
3357 if (OverloadSet
*os
= ad
->ctor
->isOverloadSet())
3358 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, NULL
, tthis
, exp
->arguments
);
3360 exp
->f
= resolveFuncCall(exp
->loc
, sc
, ad
->ctor
, NULL
, tthis
, exp
->arguments
, 0);
3361 if (!exp
->f
|| exp
->f
->errors
)
3363 exp
->checkDeprecated(sc
, exp
->f
);
3364 exp
->checkDisabled(sc
, exp
->f
);
3365 exp
->checkPurity(sc
, exp
->f
);
3366 exp
->checkSafety(sc
, exp
->f
);
3367 exp
->checkNogc(sc
, exp
->f
);
3368 //checkAccess(exp->loc, sc, NULL, exp->f); // necessary?
3370 exp
->e1
= new DotVarExp(exp
->e1
->loc
, exp
->e1
, exp
->f
, false);
3371 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
3374 // BUG: this should really be done by checking the static
3376 if (exp
->f
== sc
->func
)
3378 exp
->error("cyclic constructor call");
3382 else if (exp
->e1
->op
== TOKoverloadset
)
3384 OverloadSet
*os
= ((OverExp
*)exp
->e1
)->vars
;
3385 exp
->f
= resolveOverloadSet(exp
->loc
, sc
, os
, tiargs
, tthis
, exp
->arguments
);
3389 exp
->e1
= new DotVarExp(exp
->loc
, ethis
, exp
->f
, false);
3391 exp
->e1
= new VarExp(exp
->loc
, exp
->f
, false);
3396 exp
->error("function expected before (), not `%s`", exp
->e1
->toChars());
3399 else if (t1
->ty
== Terror
)
3403 else if (t1
->ty
!= Tfunction
)
3409 if (exp
->e1
->op
== TOKfunction
)
3411 // function literal that direct called is always inferred.
3412 assert(((FuncExp
*)exp
->e1
)->fd
);
3413 exp
->f
= ((FuncExp
*)exp
->e1
)->fd
;
3414 tf
= (TypeFunction
*)exp
->f
->type
;
3415 p
= "function literal";
3417 else if (t1
->ty
== Tdelegate
)
3419 TypeDelegate
*td
= (TypeDelegate
*)t1
;
3420 assert(td
->next
->ty
== Tfunction
);
3421 tf
= (TypeFunction
*)(td
->next
);
3424 else if (t1
->ty
== Tpointer
&& ((TypePointer
*)t1
)->next
->ty
== Tfunction
)
3426 tf
= (TypeFunction
*)(((TypePointer
*)t1
)->next
);
3427 p
= "function pointer";
3429 else if (exp
->e1
->op
== TOKdotvar
&&
3430 ((DotVarExp
*)exp
->e1
)->var
->isOverDeclaration())
3432 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
3433 exp
->f
= resolveFuncCall(exp
->loc
, sc
, dve
->var
, tiargs
, dve
->e1
->type
, exp
->arguments
, 2);
3436 if (exp
->f
->needThis())
3439 dve
->type
= exp
->f
->type
;
3440 dve
->hasOverloads
= false;
3443 exp
->e1
= new VarExp(dve
->loc
, exp
->f
, false);
3444 Expression
*e
= new CommaExp(exp
->loc
, dve
->e1
, exp
);
3445 result
= expressionSemantic(e
, sc
);
3448 else if (exp
->e1
->op
== TOKvar
&&
3449 ((VarExp
*)exp
->e1
)->var
->isOverDeclaration())
3451 s
= ((VarExp
*)exp
->e1
)->var
;
3454 else if (exp
->e1
->op
== TOKtemplate
)
3456 s
= ((TemplateExp
*)exp
->e1
)->td
;
3458 exp
->f
= resolveFuncCall(exp
->loc
, sc
, s
, tiargs
, NULL
, exp
->arguments
);
3459 if (!exp
->f
|| exp
->f
->errors
)
3461 if (exp
->f
->needThis())
3465 // Supply an implicit 'this', as in
3467 Expression
*ex
= new ThisExp(exp
->loc
);
3468 ex
= expressionSemantic(ex
, sc
);
3469 exp
->e1
= new DotVarExp(exp
->loc
, ex
, exp
->f
, false);
3472 else if (isNeedThisScope(sc
, exp
->f
))
3474 exp
->error("need `this` for `%s` of type `%s`", exp
->f
->toChars(), exp
->f
->type
->toChars());
3478 exp
->e1
= new VarExp(exp
->e1
->loc
, exp
->f
, false);
3483 exp
->error("function expected before (), not %s of type %s", exp
->e1
->toChars(), exp
->e1
->type
->toChars());
3487 if (!tf
->callMatch(NULL
, exp
->arguments
))
3492 argExpTypesToCBuffer(&buf
, exp
->arguments
);
3495 tthis
->modToBuffer(&buf
);
3497 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3498 ::error(exp
->loc
, "%s %s %s is not callable using argument types %s",
3499 p
, exp
->e1
->toChars(), parametersTypeToChars(tf
->parameterList
),
3505 // Purity and safety check should run after testing arguments matching
3508 exp
->checkPurity(sc
, exp
->f
);
3509 exp
->checkSafety(sc
, exp
->f
);
3510 exp
->checkNogc(sc
, exp
->f
);
3511 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3514 else if (sc
->func
&& sc
->intypeof
!= 1 && !(sc
->flags
& SCOPEctfe
))
3517 if (!tf
->purity
&& !(sc
->flags
& SCOPEdebug
) && sc
->func
->setImpure())
3519 exp
->error("pure %s `%s` cannot call impure %s `%s`",
3520 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3523 if (!tf
->isnogc
&& sc
->func
->setGC())
3525 exp
->error("@nogc %s `%s` cannot call non-@nogc %s `%s`",
3526 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3529 if (tf
->trust
<= TRUSTsystem
&& sc
->func
->setUnsafe())
3531 exp
->error("@safe %s `%s` cannot call @system %s `%s`",
3532 sc
->func
->kind(), sc
->func
->toPrettyChars(), p
, exp
->e1
->toChars());
3539 if (t1
->ty
== Tpointer
)
3541 Expression
*e
= new PtrExp(exp
->loc
, exp
->e1
);
3547 else if (exp
->e1
->op
== TOKvar
)
3549 // Do overload resolution
3550 VarExp
*ve
= (VarExp
*)exp
->e1
;
3552 exp
->f
= ve
->var
->isFuncDeclaration();
3556 if (ve
->hasOverloads
)
3557 exp
->f
= resolveFuncCall(exp
->loc
, sc
, exp
->f
, tiargs
, NULL
, exp
->arguments
, 2);
3560 exp
->f
= exp
->f
->toAliasFunc();
3561 TypeFunction
*tf
= (TypeFunction
*)exp
->f
->type
;
3562 if (!tf
->callMatch(NULL
, exp
->arguments
))
3567 argExpTypesToCBuffer(&buf
, exp
->arguments
);
3570 //printf("tf = %s, args = %s\n", tf->deco, (*exp->arguments)[0]->type->deco);
3571 ::error(exp
->loc
, "%s %s is not callable using argument types %s",
3572 exp
->e1
->toChars(), parametersTypeToChars(tf
->parameterList
),
3578 if (!exp
->f
|| exp
->f
->errors
)
3581 if (exp
->f
->needThis())
3583 // Change the ancestor lambdas to delegate before hasThis(sc) call.
3584 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3589 // Supply an implicit 'this', as in
3592 Expression
*ex
= new ThisExp(exp
->loc
);
3593 ex
= expressionSemantic(ex
, sc
);
3594 exp
->e1
= new DotVarExp(exp
->loc
, ex
, ve
->var
);
3595 // Note: we cannot use f directly, because further overload resolution
3596 // through the supplied 'this' may cause different result.
3599 else if (isNeedThisScope(sc
, exp
->f
))
3601 exp
->error("need `this` for `%s` of type `%s`", exp
->f
->toChars(), exp
->f
->type
->toChars());
3606 exp
->checkDeprecated(sc
, exp
->f
);
3607 exp
->checkDisabled(sc
, exp
->f
);
3608 exp
->checkPurity(sc
, exp
->f
);
3609 exp
->checkSafety(sc
, exp
->f
);
3610 exp
->checkNogc(sc
, exp
->f
);
3611 checkAccess(exp
->loc
, sc
, NULL
, exp
->f
);
3612 if (exp
->f
->checkNestedReference(sc
, exp
->loc
))
3618 if (ve
->hasOverloads
)
3620 exp
->e1
= new VarExp(ve
->loc
, exp
->f
, false);
3621 exp
->e1
->type
= exp
->f
->type
;
3625 assert(t1
->ty
== Tfunction
);
3627 Expression
*argprefix
;
3628 if (!exp
->arguments
)
3629 exp
->arguments
= new Expressions();
3630 if (functionParameters(exp
->loc
, sc
, (TypeFunction
*)(t1
), tthis
, exp
->arguments
, exp
->f
, &exp
->type
, &argprefix
))
3635 exp
->e1
= e1org
; // Bugzilla 10922, avoid recursive expression printing
3636 exp
->error("forward reference to inferred return type of function call `%s`", exp
->toChars());
3640 if (exp
->f
&& exp
->f
->tintro
)
3642 Type
*t
= exp
->type
;
3644 TypeFunction
*tf
= (TypeFunction
*)exp
->f
->tintro
;
3646 if (tf
->next
->isBaseOf(t
, &offset
) && offset
)
3648 exp
->type
= tf
->next
;
3649 result
= Expression::combine(argprefix
, exp
->castTo(sc
, t
));
3654 // Handle the case of a direct lambda call
3655 if (exp
->f
&& exp
->f
->isFuncLiteralDeclaration() &&
3656 sc
->func
&& !sc
->intypeof
)
3658 exp
->f
->tookAddressOf
= 0;
3661 result
= Expression::combine(argprefix
, exp
);
3664 void visit(AddrExp
*exp
)
3672 if (Expression
*ex
= unaSemantic(exp
, sc
))
3677 int wasCond
= exp
->e1
->op
== TOKquestion
;
3678 if (exp
->e1
->op
== TOKdotti
)
3680 DotTemplateInstanceExp
* dti
= (DotTemplateInstanceExp
*)exp
->e1
;
3681 TemplateInstance
*ti
= dti
->ti
;
3683 //assert(ti->needsTypeInference(sc));
3684 dsymbolSemantic(ti
, sc
);
3685 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
3687 Dsymbol
*s
= ti
->toAlias();
3688 FuncDeclaration
*f
= s
->isFuncDeclaration();
3691 exp
->e1
= new DotVarExp(exp
->e1
->loc
, dti
->e1
, f
);
3692 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
3696 else if (exp
->e1
->op
== TOKscope
)
3698 TemplateInstance
*ti
= ((ScopeExp
*)exp
->e1
)->sds
->isTemplateInstance();
3701 //assert(ti->needsTypeInference(sc));
3702 dsymbolSemantic(ti
, sc
);
3703 if (!ti
->inst
|| ti
->errors
) // if template failed to expand
3705 Dsymbol
*s
= ti
->toAlias();
3706 FuncDeclaration
*f
= s
->isFuncDeclaration();
3709 exp
->e1
= new VarExp(exp
->e1
->loc
, f
);
3710 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
3714 exp
->e1
= exp
->e1
->toLvalue(sc
, NULL
);
3715 if (exp
->e1
->op
== TOKerror
)
3720 if (checkNonAssignmentArrayOp(exp
->e1
))
3725 exp
->error("cannot take address of %s", exp
->e1
->toChars());
3729 bool hasOverloads
= false;
3730 if (FuncDeclaration
*f
= isFuncAddress(exp
, &hasOverloads
))
3732 if (!hasOverloads
&& f
->checkForwardRef(exp
->loc
))
3735 else if (!exp
->e1
->type
->deco
)
3737 if (exp
->e1
->op
== TOKvar
)
3739 VarExp
*ve
= (VarExp
*)exp
->e1
;
3740 Declaration
*d
= ve
->var
;
3741 exp
->error("forward reference to %s %s", d
->kind(), d
->toChars());
3744 exp
->error("forward reference to %s", exp
->e1
->toChars());
3748 exp
->type
= exp
->e1
->type
->pointerTo();
3750 // See if this should really be a delegate
3751 if (exp
->e1
->op
== TOKdotvar
)
3753 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
3754 FuncDeclaration
*f
= dve
->var
->isFuncDeclaration();
3757 f
= f
->toAliasFunc(); // FIXME, should see overloads - Bugzilla 1983
3758 if (!dve
->hasOverloads
)
3763 e
= new DelegateExp(exp
->loc
, dve
->e1
, f
, dve
->hasOverloads
);
3764 else // It is a function pointer. Convert &v.f() --> (v, &V.f())
3765 e
= new CommaExp(exp
->loc
, dve
->e1
, new AddrExp(exp
->loc
, new VarExp(exp
->loc
, f
, dve
->hasOverloads
)));
3766 e
= expressionSemantic(e
, sc
);
3771 // Look for misaligned pointer in @safe mode
3772 if (checkUnsafeAccess(sc
, dve
, !exp
->type
->isMutable(), true))
3775 if (dve
->e1
->op
== TOKvar
&& global
.params
.vsafe
)
3777 VarExp
*ve
= (VarExp
*)dve
->e1
;
3778 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3781 if (!checkAddressVar(sc
, exp
, v
))
3785 else if ((dve
->e1
->op
== TOKthis
|| dve
->e1
->op
== TOKsuper
) && global
.params
.vsafe
)
3787 ThisExp
*ve
= (ThisExp
*)dve
->e1
;
3788 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3789 if (v
&& v
->storage_class
& STCref
)
3791 if (!checkAddressVar(sc
, exp
, v
))
3796 else if (exp
->e1
->op
== TOKvar
)
3798 VarExp
*ve
= (VarExp
*)exp
->e1
;
3800 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3803 if (!checkAddressVar(sc
, exp
, v
))
3806 ve
->checkPurity(sc
, v
);
3809 FuncDeclaration
*f
= ve
->var
->isFuncDeclaration();
3812 /* Because nested functions cannot be overloaded,
3813 * mark here that we took its address because castTo()
3814 * may not be called with an exact match.
3816 if (!ve
->hasOverloads
|| f
->isNested())
3820 if (f
->isFuncLiteralDeclaration())
3822 if (!f
->FuncDeclaration::isNested())
3824 /* Supply a 'null' for a this pointer if no this is available
3826 Expression
*e
= new DelegateExp(exp
->loc
, new NullExp(exp
->loc
, Type::tnull
), f
, ve
->hasOverloads
);
3827 e
= expressionSemantic(e
, sc
);
3832 Expression
*e
= new DelegateExp(exp
->loc
, exp
->e1
, f
, ve
->hasOverloads
);
3833 e
= expressionSemantic(e
, sc
);
3841 /* Should probably supply 'this' after overload resolution,
3844 Expression
*ethis
= new ThisExp(exp
->loc
);
3845 Expression
*e
= new DelegateExp(exp
->loc
, ethis
, f
, ve
->hasOverloads
);
3846 e
= expressionSemantic(e
, sc
);
3850 if (sc
->func
&& !sc
->intypeof
)
3852 if (sc
->func
->setUnsafe())
3854 exp
->error("`this` reference necessary to take address of member %s in @safe function %s",
3855 f
->toChars(), sc
->func
->toChars());
3861 else if ((exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
) && global
.params
.vsafe
)
3863 ThisExp
*ve
= (ThisExp
*)exp
->e1
;
3864 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3867 if (!checkAddressVar(sc
, exp
, v
))
3871 else if (exp
->e1
->op
== TOKcall
)
3873 CallExp
*ce
= (CallExp
*)exp
->e1
;
3874 if (ce
->e1
->type
->ty
== Tfunction
)
3876 TypeFunction
*tf
= (TypeFunction
*)ce
->e1
->type
;
3877 if (tf
->isref
&& sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
3879 exp
->error("cannot take address of ref return of %s() in @safe function %s",
3880 ce
->e1
->toChars(), sc
->func
->toChars());
3884 else if (exp
->e1
->op
== TOKindex
)
3889 * check 'a' the same as for a regular variable
3891 IndexExp
*ei
= (IndexExp
*)exp
->e1
;
3892 Type
*tyi
= ei
->e1
->type
->toBasetype();
3893 if (tyi
->ty
== Tsarray
&& ei
->e1
->op
== TOKvar
)
3895 VarExp
*ve
= (VarExp
*)ei
->e1
;
3896 VarDeclaration
*v
= ve
->var
->isVarDeclaration();
3899 if (!checkAddressVar(sc
, exp
, v
))
3902 ve
->checkPurity(sc
, v
);
3908 /* a ? b : c was transformed to *(a ? &b : &c), but we still
3909 * need to do safety checks
3911 assert(exp
->e1
->op
== TOKstar
);
3912 PtrExp
*pe
= (PtrExp
*)exp
->e1
;
3913 assert(pe
->e1
->op
== TOKquestion
);
3914 CondExp
*ce
= (CondExp
*)pe
->e1
;
3915 assert(ce
->e1
->op
== TOKaddress
);
3916 assert(ce
->e2
->op
== TOKaddress
);
3918 // Re-run semantic on the address expressions only
3919 ce
->e1
->type
= NULL
;
3920 ce
->e1
= expressionSemantic(ce
->e1
, sc
);
3921 ce
->e2
->type
= NULL
;
3922 ce
->e2
= expressionSemantic(ce
->e2
, sc
);
3925 result
= exp
->optimize(WANTvalue
);
3928 void visit(PtrExp
*exp
)
3936 Expression
*e
= exp
->op_overload(sc
);
3943 Type
*tb
= exp
->e1
->type
->toBasetype();
3947 exp
->type
= ((TypePointer
*)tb
)->next
;
3952 exp
->error("using * on an array is no longer supported; use *(%s).ptr instead", exp
->e1
->toChars());
3953 exp
->type
= ((TypeArray
*)tb
)->next
;
3954 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
->pointerTo());
3958 exp
->error("can only * a pointer, not a `%s`", exp
->e1
->type
->toChars());
3964 if (exp
->checkValue())
3970 void visit(NegExp
*exp
)
3978 Expression
*e
= exp
->op_overload(sc
);
3985 exp
->type
= exp
->e1
->type
;
3986 Type
*tb
= exp
->type
->toBasetype();
3987 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
3989 if (!isArrayOpValid(exp
->e1
))
3991 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
3998 if (!target
.isVectorOpSupported(tb
, exp
->op
))
4000 result
= exp
->incompatibleTypes();
4003 if (exp
->e1
->checkNoBool())
4005 if (exp
->e1
->checkArithmetic())
4011 void visit(UAddExp
*exp
)
4015 Expression
*e
= exp
->op_overload(sc
);
4022 if (!target
.isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
))
4024 result
= exp
->incompatibleTypes();
4027 if (exp
->e1
->checkNoBool())
4029 if (exp
->e1
->checkArithmetic())
4035 void visit(ComExp
*exp
)
4043 Expression
*e
= exp
->op_overload(sc
);
4050 exp
->type
= exp
->e1
->type
;
4051 Type
*tb
= exp
->type
->toBasetype();
4052 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
4054 if (!isArrayOpValid(exp
->e1
))
4056 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
4063 if (!target
.isVectorOpSupported(tb
, exp
->op
))
4065 result
= exp
->incompatibleTypes();
4068 if (exp
->e1
->checkNoBool())
4070 if (exp
->e1
->checkIntegral())
4076 void visit(NotExp
*e
)
4084 setNoderefOperand(e
);
4086 // Note there is no operator overload
4087 if (Expression
*ex
= unaSemantic(e
, sc
))
4093 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
4094 if (e
->e1
->op
== TOKtype
)
4095 e
->e1
= resolveAliasThis(sc
, e
->e1
);
4097 e
->e1
= resolveProperties(sc
, e
->e1
);
4098 e
->e1
= e
->e1
->toBoolean(sc
);
4099 if (e
->e1
->type
== Type::terror
)
4105 if (!target
.isVectorOpSupported(e
->e1
->type
->toBasetype(), e
->op
))
4107 result
= e
->incompatibleTypes();
4110 // Bugzilla 13910: Today NotExp can take an array as its operand.
4111 if (checkNonAssignmentArrayOp(e
->e1
))
4114 e
->type
= Type::tbool
;
4118 void visit(DeleteExp
*exp
)
4120 if (Expression
*ex
= unaSemantic(exp
, sc
))
4125 exp
->e1
= resolveProperties(sc
, exp
->e1
);
4126 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, NULL
);
4127 if (exp
->e1
->op
== TOKerror
)
4132 exp
->type
= Type::tvoid
;
4134 AggregateDeclaration
*ad
= NULL
;
4135 Type
*tb
= exp
->e1
->type
->toBasetype();
4139 ClassDeclaration
*cd
= ((TypeClass
*)tb
)->sym
;
4141 if (cd
->isCOMinterface())
4142 { /* Because COM classes are deleted by IUnknown.Release()
4144 exp
->error("cannot delete instance of COM interface %s", cd
->toChars());
4152 tb
= ((TypePointer
*)tb
)->next
->toBasetype();
4153 if (tb
->ty
== Tstruct
)
4155 ad
= ((TypeStruct
*)tb
)->sym
;
4156 FuncDeclaration
*f
= ad
->aggDelete
;
4157 FuncDeclaration
*fd
= ad
->dtor
;
4161 semanticTypeInfo(sc
, tb
);
4166 * ea = copy e1 to a tmp to do side effects only once
4167 * eb = call destructor
4168 * ec = call deallocator
4170 Expression
*ea
= NULL
;
4171 Expression
*eb
= NULL
;
4172 Expression
*ec
= NULL
;
4173 VarDeclaration
*v
= NULL
;
4177 v
= copyToTemp(0, "__tmpea", exp
->e1
);
4178 dsymbolSemantic(v
, sc
);
4179 ea
= new DeclarationExp(exp
->loc
, v
);
4185 Expression
*e
= ea
? new VarExp(exp
->loc
, v
) : exp
->e1
;
4186 e
= new DotVarExp(Loc(), e
, fd
, false);
4187 eb
= new CallExp(exp
->loc
, e
);
4188 eb
= expressionSemantic(eb
, sc
);
4193 Type
*tpv
= Type::tvoid
->pointerTo();
4194 Expression
*e
= ea
? new VarExp(exp
->loc
, v
) : exp
->e1
->castTo(sc
, tpv
);
4195 e
= new CallExp(exp
->loc
, new VarExp(exp
->loc
, f
, false), e
);
4196 ec
= expressionSemantic(e
, sc
);
4198 ea
= Expression::combine(ea
, eb
);
4199 ea
= Expression::combine(ea
, ec
);
4208 Type
*tv
= tb
->nextOf()->baseElemOf();
4209 if (tv
->ty
== Tstruct
)
4211 ad
= ((TypeStruct
*)tv
)->sym
;
4213 semanticTypeInfo(sc
, ad
->type
);
4218 exp
->error("cannot delete type %s", exp
->e1
->type
->toChars());
4227 err
|= exp
->checkPurity(sc
, ad
->dtor
);
4228 err
|= exp
->checkSafety(sc
, ad
->dtor
);
4229 err
|= exp
->checkNogc(sc
, ad
->dtor
);
4231 if (ad
->aggDelete
&& tb
->ty
!= Tarray
)
4233 err
|= exp
->checkPurity(sc
, ad
->aggDelete
);
4234 err
|= exp
->checkSafety(sc
, ad
->aggDelete
);
4235 err
|= exp
->checkNogc(sc
, ad
->aggDelete
);
4241 if (!sc
->intypeof
&& sc
->func
&&
4243 sc
->func
->setUnsafe())
4245 exp
->error("%s is not @safe but is used in @safe function %s", exp
->toChars(), sc
->func
->toChars());
4254 void visit(CastExp
*exp
)
4256 //static int x; assert(++x < 10);
4265 exp
->to
= typeSemantic(exp
->to
, exp
->loc
, sc
);
4266 if (exp
->to
== Type::terror
)
4269 if (!exp
->to
->hasPointers())
4270 setNoderefOperand(exp
);
4272 // When e1 is a template lambda, this cast may instantiate it with
4274 exp
->e1
= inferType(exp
->e1
, exp
->to
);
4277 if (Expression
*ex
= unaSemantic(exp
, sc
))
4282 Expression
*e1x
= resolveProperties(sc
, exp
->e1
);
4283 if (e1x
->op
== TOKerror
)
4288 if (e1x
->checkType())
4294 exp
->error("cannot cast %s", exp
->e1
->toChars());
4298 if (!exp
->to
) // Handle cast(const) and cast(immutable), etc.
4300 exp
->to
= exp
->e1
->type
->castMod(exp
->mod
);
4301 exp
->to
= typeSemantic(exp
->to
, exp
->loc
, sc
);
4302 if (exp
->to
== Type::terror
)
4306 if (exp
->to
->ty
== Ttuple
)
4308 exp
->error("cannot cast %s to tuple type %s", exp
->e1
->toChars(), exp
->to
->toChars());
4311 if (exp
->e1
->type
->ty
!= Tvoid
||
4312 (exp
->e1
->op
== TOKfunction
&& exp
->to
->ty
== Tvoid
) ||
4313 exp
->e1
->op
== TOKtype
||
4314 exp
->e1
->op
== TOKtemplate
)
4316 if (exp
->e1
->checkValue())
4320 // cast(void) is used to mark e1 as unused, so it is safe
4321 if (exp
->to
->ty
== Tvoid
)
4323 exp
->type
= exp
->to
;
4328 if (!exp
->to
->equals(exp
->e1
->type
) && exp
->mod
== (unsigned char)~0)
4330 if (Expression
*e
= exp
->op_overload(sc
))
4332 result
= e
->implicitCastTo(sc
, exp
->to
);
4337 Type
*t1b
= exp
->e1
->type
->toBasetype();
4338 Type
*tob
= exp
->to
->toBasetype();
4340 if (tob
->ty
== Tstruct
&& !tob
->equals(t1b
))
4348 // Rewrite as to.call(e1)
4349 Expression
*e
= new TypeExp(exp
->loc
, exp
->to
);
4350 e
= new CallExp(exp
->loc
, e
, exp
->e1
);
4351 e
= trySemantic(e
, sc
);
4359 if (!t1b
->equals(tob
) && (t1b
->ty
== Tarray
|| t1b
->ty
== Tsarray
))
4361 if (checkNonAssignmentArrayOp(exp
->e1
))
4365 // Look for casting to a vector type
4366 if (tob
->ty
== Tvector
&& t1b
->ty
!= Tvector
)
4368 result
= new VectorExp(exp
->loc
, exp
->e1
, exp
->to
);
4372 Expression
*ex
= exp
->e1
->castTo(sc
, exp
->to
);
4373 if (ex
->op
== TOKerror
)
4379 // Check for unsafe casts
4380 if (sc
->func
&& !sc
->intypeof
&&
4381 !isSafeCast(ex
, t1b
, tob
) &&
4382 sc
->func
->setUnsafe())
4384 exp
->error("cast from %s to %s not allowed in safe code", exp
->e1
->type
->toChars(), exp
->to
->toChars());
4391 void visit(VectorExp
*exp
)
4399 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
4400 exp
->type
= typeSemantic(exp
->to
, exp
->loc
, sc
);
4401 if (exp
->e1
->op
== TOKerror
|| exp
->type
->ty
== Terror
)
4407 Type
*tb
= exp
->type
->toBasetype();
4408 assert(tb
->ty
== Tvector
);
4409 TypeVector
*tv
= (TypeVector
*)tb
;
4410 Type
*te
= tv
->elementType();
4411 exp
->dim
= (int)(tv
->size(exp
->loc
) / te
->size(exp
->loc
));
4413 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
4415 if (exp
->e1
->op
== TOKarrayliteral
)
4417 for (size_t i
= 0; i
< exp
->dim
; i
++)
4419 // Do not stop on first error - check all AST nodes even if error found
4420 res
|= checkVectorElem(exp
, ((ArrayLiteralExp
*)exp
->e1
)->getElement(i
));
4423 else if (exp
->e1
->type
->ty
== Tvoid
)
4424 res
= checkVectorElem(exp
, exp
->e1
);
4426 Expression
*e
= exp
;
4432 void visit(VectorArrayExp
*e
)
4437 e
->e1
= resolveProperties(sc
, e
->e1
);
4439 if (e
->e1
->op
== TOKerror
)
4444 assert(e
->e1
->type
->ty
== Tvector
);
4445 TypeVector
*tv
= (TypeVector
*)e
->e1
->type
;
4446 e
->type
= tv
->basetype
;
4451 void visit(SliceExp
*exp
)
4459 // operator overloading should be handled in ArrayExp already.
4461 if (Expression
*ex
= unaSemantic(exp
, sc
))
4466 exp
->e1
= resolveProperties(sc
, exp
->e1
);
4467 if (exp
->e1
->op
== TOKtype
&& exp
->e1
->type
->ty
!= Ttuple
)
4469 if (exp
->lwr
|| exp
->upr
)
4471 exp
->error("cannot slice type `%s`", exp
->e1
->toChars());
4474 Expression
*e
= new TypeExp(exp
->loc
, exp
->e1
->type
->arrayOf());
4475 result
= expressionSemantic(e
, sc
);
4478 if (!exp
->lwr
&& !exp
->upr
)
4480 if (exp
->e1
->op
== TOKarrayliteral
)
4482 // Convert [a,b,c][] to [a,b,c]
4483 Type
*t1b
= exp
->e1
->type
->toBasetype();
4484 Expression
*e
= exp
->e1
;
4485 if (t1b
->ty
== Tsarray
)
4488 e
->type
= t1b
->nextOf()->arrayOf();
4493 if (exp
->e1
->op
== TOKslice
)
4495 // Convert e[][] to e[]
4496 SliceExp
*se
= (SliceExp
*)exp
->e1
;
4497 if (!se
->lwr
&& !se
->upr
)
4503 if (isArrayOpOperand(exp
->e1
))
4505 // Convert (a[]+b[])[] to a[]+b[]
4510 if (exp
->e1
->op
== TOKerror
)
4515 if (exp
->e1
->type
->ty
== Terror
)
4518 Type
*t1b
= exp
->e1
->type
->toBasetype();
4519 if (t1b
->ty
== Tpointer
)
4521 if (((TypePointer
*)t1b
)->next
->ty
== Tfunction
)
4523 exp
->error("cannot slice function pointer %s", exp
->e1
->toChars());
4526 if (!exp
->lwr
|| !exp
->upr
)
4528 exp
->error("need upper and lower bound to slice pointer");
4531 if (sc
->func
&& !sc
->intypeof
&& sc
->func
->setUnsafe())
4533 exp
->error("pointer slicing not allowed in safe functions");
4537 else if (t1b
->ty
== Tarray
)
4540 else if (t1b
->ty
== Tsarray
)
4542 if (!exp
->arrayop
&& global
.params
.vsafe
)
4544 /* Slicing a static array is like taking the address of it.
4545 * Perform checks as if e[] was &e
4547 VarDeclaration
*v
= NULL
;
4548 if (exp
->e1
->op
== TOKdotvar
)
4550 DotVarExp
*dve
= (DotVarExp
*)exp
->e1
;
4551 if (dve
->e1
->op
== TOKvar
)
4553 VarExp
*ve
= (VarExp
*)dve
->e1
;
4554 v
= ve
->var
->isVarDeclaration();
4556 else if (dve
->e1
->op
== TOKthis
|| dve
->e1
->op
== TOKsuper
)
4558 ThisExp
*ve
= (ThisExp
*)dve
->e1
;
4559 v
= ve
->var
->isVarDeclaration();
4560 if (v
&& !(v
->storage_class
& STCref
))
4564 else if (exp
->e1
->op
== TOKvar
)
4566 VarExp
*ve
= (VarExp
*)exp
->e1
;
4567 v
= ve
->var
->isVarDeclaration();
4569 else if (exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
)
4571 ThisExp
*ve
= (ThisExp
*)exp
->e1
;
4572 v
= ve
->var
->isVarDeclaration();
4577 if (!checkAddressVar(sc
, exp
, v
))
4582 else if (t1b
->ty
== Ttuple
)
4584 if (!exp
->lwr
&& !exp
->upr
)
4589 if (!exp
->lwr
|| !exp
->upr
)
4591 exp
->error("need upper and lower bound to slice tuple");
4595 else if (t1b
->ty
== Tvector
)
4597 // Convert e1 to corresponding static array
4598 TypeVector
*tv1
= (TypeVector
*)t1b
;
4599 t1b
= tv1
->basetype
;
4600 t1b
= t1b
->castMod(tv1
->mod
);
4601 exp
->e1
->type
= t1b
;
4605 exp
->error("%s cannot be sliced with []",
4606 t1b
->ty
== Tvoid
? exp
->e1
->toChars() : t1b
->toChars());
4610 /* Run semantic on lwr and upr.
4613 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
|| t1b
->ty
== Ttuple
)
4615 // Create scope for 'length' variable
4616 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, exp
);
4617 sym
->loc
= exp
->loc
;
4618 sym
->parent
= sc
->scopesym
;
4623 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4624 exp
->lwr
= expressionSemantic(exp
->lwr
, sc
);
4625 exp
->lwr
= resolveProperties(sc
, exp
->lwr
);
4626 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4627 exp
->lwr
= exp
->lwr
->implicitCastTo(sc
, Type::tsize_t
);
4631 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4632 exp
->upr
= expressionSemantic(exp
->upr
, sc
);
4633 exp
->upr
= resolveProperties(sc
, exp
->upr
);
4634 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4635 exp
->upr
= exp
->upr
->implicitCastTo(sc
, Type::tsize_t
);
4639 if ((exp
->lwr
&& exp
->lwr
->type
== Type::terror
) ||
4640 (exp
->upr
&& exp
->upr
->type
== Type::terror
))
4645 if (t1b
->ty
== Ttuple
)
4647 exp
->lwr
= exp
->lwr
->ctfeInterpret();
4648 exp
->upr
= exp
->upr
->ctfeInterpret();
4649 uinteger_t i1
= exp
->lwr
->toUInteger();
4650 uinteger_t i2
= exp
->upr
->toUInteger();
4655 if (exp
->e1
->op
== TOKtuple
) // slicing an expression tuple
4657 te
= (TupleExp
*)exp
->e1
;
4659 length
= te
->exps
->length
;
4661 else if (exp
->e1
->op
== TOKtype
) // slicing a type tuple
4664 tup
= (TypeTuple
*)t1b
;
4665 length
= Parameter::dim(tup
->arguments
);
4670 if (i2
< i1
|| length
< i2
)
4672 exp
->error("string slice [%llu .. %llu] is out of bounds", i1
, i2
);
4676 size_t j1
= (size_t) i1
;
4677 size_t j2
= (size_t) i2
;
4679 if (exp
->e1
->op
== TOKtuple
)
4681 Expressions
*exps
= new Expressions
;
4682 exps
->setDim(j2
- j1
);
4683 for (size_t i
= 0; i
< j2
- j1
; i
++)
4685 (*exps
)[i
] = (*te
->exps
)[j1
+ i
];
4687 e
= new TupleExp(exp
->loc
, te
->e0
, exps
);
4691 Parameters
*args
= new Parameters
;
4692 args
->reserve(j2
- j1
);
4693 for (size_t i
= j1
; i
< j2
; i
++)
4695 Parameter
*arg
= Parameter::getNth(tup
->arguments
, i
);
4698 e
= new TypeExp(exp
->e1
->loc
, new TypeTuple(args
));
4700 e
= expressionSemantic(e
, sc
);
4705 exp
->type
= t1b
->nextOf()->arrayOf();
4706 // Allow typedef[] -> typedef[]
4707 if (exp
->type
->equals(t1b
))
4708 exp
->type
= exp
->e1
->type
;
4710 if (exp
->lwr
&& exp
->upr
)
4712 exp
->lwr
= exp
->lwr
->optimize(WANTvalue
);
4713 exp
->upr
= exp
->upr
->optimize(WANTvalue
);
4715 IntRange lwrRange
= getIntRange(exp
->lwr
);
4716 IntRange uprRange
= getIntRange(exp
->upr
);
4718 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
)
4720 Expression
*el
= new ArrayLengthExp(exp
->loc
, exp
->e1
);
4721 el
= expressionSemantic(el
, sc
);
4722 el
= el
->optimize(WANTvalue
);
4723 if (el
->op
== TOKint64
)
4725 dinteger_t length
= el
->toInteger();
4726 IntRange
bounds(SignExtendedNumber(0), SignExtendedNumber(length
));
4727 exp
->upperIsInBounds
= bounds
.contains(uprRange
);
4730 else if (t1b
->ty
== Tpointer
)
4732 exp
->upperIsInBounds
= true;
4737 exp
->lowerIsLessThanUpper
= (lwrRange
.imax
<= uprRange
.imin
);
4739 //printf("upperIsInBounds = %d lowerIsLessThanUpper = %d\n", upperIsInBounds, lowerIsLessThanUpper);
4745 void visit(ArrayLengthExp
*e
)
4753 if (Expression
*ex
= unaSemantic(e
, sc
))
4758 e
->e1
= resolveProperties(sc
, e
->e1
);
4760 e
->type
= Type::tsize_t
;
4764 void visit(IntervalExp
*e
)
4772 Expression
*le
= e
->lwr
;
4773 le
= expressionSemantic(le
, sc
);
4774 le
= resolveProperties(sc
, le
);
4776 Expression
*ue
= e
->upr
;
4777 ue
= expressionSemantic(ue
, sc
);
4778 ue
= resolveProperties(sc
, ue
);
4780 if (le
->op
== TOKerror
)
4785 if (ue
->op
== TOKerror
)
4794 e
->type
= Type::tvoid
;
4798 void visit(DelegatePtrExp
*e
)
4803 e
->e1
= resolveProperties(sc
, e
->e1
);
4805 if (e
->e1
->op
== TOKerror
)
4810 e
->type
= Type::tvoidptr
;
4815 void visit(DelegateFuncptrExp
*e
)
4820 e
->e1
= resolveProperties(sc
, e
->e1
);
4822 if (e
->e1
->op
== TOKerror
)
4827 e
->type
= e
->e1
->type
->nextOf()->pointerTo();
4832 void visit(ArrayExp
*exp
)
4836 Expression
*e
= exp
->op_overload(sc
);
4843 if (isAggregate(exp
->e1
->type
))
4844 exp
->error("no [] operator overload for type %s", exp
->e1
->type
->toChars());
4846 exp
->error("only one index allowed to index %s", exp
->e1
->type
->toChars());
4850 void visit(DotExp
*exp
)
4852 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
4853 exp
->e2
= expressionSemantic(exp
->e2
, sc
);
4855 if (exp
->e1
->op
== TOKtype
)
4860 if (exp
->e2
->op
== TOKtype
)
4865 if (exp
->e2
->op
== TOKtemplate
)
4867 TemplateDeclaration
*td
= ((TemplateExp
*)exp
->e2
)->td
;
4868 Expression
*e
= new DotTemplateExp(exp
->loc
, exp
->e1
, td
);
4869 result
= expressionSemantic(e
, sc
);
4873 exp
->type
= exp
->e2
->type
;
4877 void visit(CommaExp
*e
)
4885 // Allow `((a,b),(x,y))`
4886 if (e
->allowCommaExp
)
4888 if (e
->e1
&& e
->e1
->op
== TOKcomma
)
4889 ((CommaExp
*)e
->e1
)->allowCommaExp
= true;
4890 if (e
->e2
&& e
->e2
->op
== TOKcomma
)
4891 ((CommaExp
*)e
->e2
)->allowCommaExp
= true;
4894 if (Expression
*ex
= binSemanticProp(e
, sc
))
4899 e
->e1
= e
->e1
->addDtorHook(sc
);
4901 if (checkNonAssignmentArrayOp(e
->e1
))
4904 e
->type
= e
->e2
->type
;
4905 if (e
->type
!= Type::tvoid
&& !e
->allowCommaExp
&& !e
->isGenerated
)
4906 e
->deprecation("Using the result of a comma expression is deprecated");
4910 void visit(IndexExp
*exp
)
4918 // operator overloading should be handled in ArrayExp already.
4921 exp
->e1
= expressionSemantic(exp
->e1
, sc
);
4922 assert(exp
->e1
->type
); // semantic() should already be run on it
4923 if (exp
->e1
->op
== TOKtype
&& exp
->e1
->type
->ty
!= Ttuple
)
4925 exp
->e2
= expressionSemantic(exp
->e2
, sc
);
4926 exp
->e2
= resolveProperties(sc
, exp
->e2
);
4928 if (exp
->e2
->op
== TOKtype
)
4929 nt
= new TypeAArray(exp
->e1
->type
, exp
->e2
->type
);
4931 nt
= new TypeSArray(exp
->e1
->type
, exp
->e2
);
4932 Expression
*e
= new TypeExp(exp
->loc
, nt
);
4933 result
= expressionSemantic(e
, sc
);
4936 if (exp
->e1
->op
== TOKerror
)
4941 if (exp
->e1
->type
->ty
== Terror
)
4944 // Note that unlike C we do not implement the int[ptr]
4946 Type
*t1b
= exp
->e1
->type
->toBasetype();
4948 if (t1b
->ty
== Tvector
)
4950 // Convert e1 to corresponding static array
4951 TypeVector
*tv1
= (TypeVector
*)t1b
;
4952 t1b
= tv1
->basetype
;
4953 t1b
= t1b
->castMod(tv1
->mod
);
4954 exp
->e1
->type
= t1b
;
4957 /* Run semantic on e2
4960 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
|| t1b
->ty
== Ttuple
)
4962 // Create scope for 'length' variable
4963 ScopeDsymbol
*sym
= new ArrayScopeSymbol(sc
, exp
);
4964 sym
->loc
= exp
->loc
;
4965 sym
->parent
= sc
->scopesym
;
4968 if (t1b
->ty
== Ttuple
) sc
= sc
->startCTFE();
4969 exp
->e2
= expressionSemantic(exp
->e2
, sc
);
4970 exp
->e2
= resolveProperties(sc
, exp
->e2
);
4971 if (t1b
->ty
== Ttuple
) sc
= sc
->endCTFE();
4972 if (exp
->e2
->op
== TOKtuple
)
4974 TupleExp
*te
= (TupleExp
*)exp
->e2
;
4975 if (te
->exps
&& te
->exps
->length
== 1)
4976 exp
->e2
= Expression::combine(te
->e0
, (*te
->exps
)[0]); // bug 4444 fix
4980 if (exp
->e2
->type
== Type::terror
)
4983 if (checkNonAssignmentArrayOp(exp
->e1
))
4989 if (((TypePointer
*)t1b
)->next
->ty
== Tfunction
)
4991 exp
->error("cannot index function pointer %s", exp
->e1
->toChars());
4994 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
4995 if (exp
->e2
->type
== Type::terror
)
4997 exp
->e2
= exp
->e2
->optimize(WANTvalue
);
4998 if (exp
->e2
->op
== TOKint64
&& exp
->e2
->toInteger() == 0)
5000 else if (sc
->func
&& sc
->func
->setUnsafe())
5002 exp
->error("safe function `%s` cannot index pointer `%s`",
5003 sc
->func
->toPrettyChars(), exp
->e1
->toChars());
5006 exp
->type
= ((TypeNext
*)t1b
)->next
;
5010 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
5011 if (exp
->e2
->type
== Type::terror
)
5013 exp
->type
= ((TypeNext
*)t1b
)->next
;
5018 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
5019 if (exp
->e2
->type
== Type::terror
)
5021 exp
->type
= t1b
->nextOf();
5027 TypeAArray
*taa
= (TypeAArray
*)t1b
;
5028 /* We can skip the implicit conversion if they differ only by
5029 * constness (Bugzilla 2684, see also bug 2954b)
5031 if (!arrayTypeCompatibleWithoutCasting(exp
->e2
->type
, taa
->index
))
5033 exp
->e2
= exp
->e2
->implicitCastTo(sc
, taa
->index
); // type checking
5034 if (exp
->e2
->type
== Type::terror
)
5038 semanticTypeInfo(sc
, taa
);
5040 exp
->type
= taa
->next
;
5046 exp
->e2
= exp
->e2
->implicitCastTo(sc
, Type::tsize_t
);
5047 if (exp
->e2
->type
== Type::terror
)
5049 exp
->e2
= exp
->e2
->ctfeInterpret();
5050 uinteger_t index
= exp
->e2
->toUInteger();
5055 if (exp
->e1
->op
== TOKtuple
)
5057 te
= (TupleExp
*)exp
->e1
;
5059 length
= te
->exps
->length
;
5061 else if (exp
->e1
->op
== TOKtype
)
5064 tup
= (TypeTuple
*)t1b
;
5065 length
= Parameter::dim(tup
->arguments
);
5070 if (length
<= index
)
5072 exp
->error("array index [%llu] is outside array bounds [0 .. %llu]",
5073 index
, (ulonglong
)length
);
5078 if (exp
->e1
->op
== TOKtuple
)
5080 e
= (*te
->exps
)[(size_t)index
];
5081 e
= Expression::combine(te
->e0
, e
);
5084 e
= new TypeExp(exp
->e1
->loc
, Parameter::getNth(tup
->arguments
, (size_t)index
)->type
);
5090 exp
->error("%s must be an array or pointer type, not %s",
5091 exp
->e1
->toChars(), exp
->e1
->type
->toChars());
5095 if (t1b
->ty
== Tsarray
|| t1b
->ty
== Tarray
)
5097 Expression
*el
= new ArrayLengthExp(exp
->loc
, exp
->e1
);
5098 el
= expressionSemantic(el
, sc
);
5099 el
= el
->optimize(WANTvalue
);
5100 if (el
->op
== TOKint64
)
5102 exp
->e2
= exp
->e2
->optimize(WANTvalue
);
5103 dinteger_t length
= el
->toInteger();
5106 IntRange
bounds(SignExtendedNumber(0), SignExtendedNumber(length
- 1));
5107 exp
->indexIsInBounds
= bounds
.contains(getIntRange(exp
->e2
));
5115 void visit(PostExp
*exp
)
5123 if (Expression
*ex
= binSemantic(exp
, sc
))
5128 Expression
*e1x
= resolveProperties(sc
, exp
->e1
);
5129 if (e1x
->op
== TOKerror
)
5136 Expression
*e
= exp
->op_overload(sc
);
5143 if (exp
->e1
->checkReadModifyWrite(exp
->op
))
5145 if (exp
->e1
->op
== TOKslice
)
5147 const char *s
= exp
->op
== TOKplusplus
? "increment" : "decrement";
5148 exp
->error("cannot post-%s array slice `%s`, use pre-%s instead", s
, exp
->e1
->toChars(), s
);
5152 exp
->e1
= exp
->e1
->optimize(WANTvalue
);
5154 Type
*t1
= exp
->e1
->type
->toBasetype();
5155 if (t1
->ty
== Tclass
|| t1
->ty
== Tstruct
|| exp
->e1
->op
== TOKarraylength
)
5157 /* Check for operator overloading,
5158 * but rewrite in terms of ++e instead of e++
5161 /* If e1 is not trivial, take a reference to it
5163 Expression
*de
= NULL
;
5164 if (exp
->e1
->op
!= TOKvar
&& exp
->e1
->op
!= TOKarraylength
)
5167 VarDeclaration
*v
= copyToTemp(STCref
, "__postref", exp
->e1
);
5168 de
= new DeclarationExp(exp
->loc
, v
);
5169 exp
->e1
= new VarExp(exp
->e1
->loc
, v
);
5173 * auto tmp = e1; ++e1; tmp
5175 VarDeclaration
*tmp
= copyToTemp(0, "__pitmp", exp
->e1
);
5176 Expression
*ea
= new DeclarationExp(exp
->loc
, tmp
);
5178 Expression
*eb
= exp
->e1
->syntaxCopy();
5179 eb
= new PreExp(exp
->op
== TOKplusplus
? TOKpreplusplus
: TOKpreminusminus
, exp
->loc
, eb
);
5181 Expression
*ec
= new VarExp(exp
->loc
, tmp
);
5183 // Combine de,ea,eb,ec
5185 ea
= new CommaExp(exp
->loc
, de
, ea
);
5186 e
= new CommaExp(exp
->loc
, ea
, eb
);
5187 e
= new CommaExp(exp
->loc
, e
, ec
);
5188 e
= expressionSemantic(e
, sc
);
5193 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
5196 if (exp
->e1
->checkScalar())
5198 if (exp
->e1
->checkNoBool())
5201 if (exp
->e1
->type
->ty
== Tpointer
)
5202 e
= scaleFactor(exp
, sc
);
5204 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
5205 e
->type
= exp
->e1
->type
;
5209 void visit(PreExp
*exp
)
5211 Expression
*e
= exp
->op_overload(sc
);
5212 // printf("PreExp::semantic('%s')\n", exp->toChars());
5220 // Rewrite as e1+=1 or e1-=1
5221 if (exp
->op
== TOKpreplusplus
)
5222 e
= new AddAssignExp(exp
->loc
, exp
->e1
, new IntegerExp(exp
->loc
, 1, Type::tint32
));
5224 e
= new MinAssignExp(exp
->loc
, exp
->e1
, new IntegerExp(exp
->loc
, 1, Type::tint32
));
5225 result
= expressionSemantic(e
, sc
);
5228 void visit(AssignExp
*exp
)
5230 //printf("e1->op = %d, '%s'\n", exp->e1->op, Token::toChars(exp->e1->op));
5231 //printf("e2->op = %d, '%s'\n", exp->e2->op, Token::toChars(exp->e2->op));
5238 Expression
*e1old
= exp
->e1
;
5240 if (exp
->e2
->op
== TOKcomma
)
5242 /* Rewrite to get rid of the comma from rvalue
5244 if (!((CommaExp
*)exp
->e2
)->isGenerated
)
5245 exp
->deprecation("Using the result of a comma expression is deprecated");
5247 exp
->e2
= Expression::extractLast(exp
->e2
, &e0
);
5248 Expression
*e
= Expression::combine(e0
, exp
);
5249 result
= expressionSemantic(e
, sc
);
5253 /* Look for operator overloading of a[arguments] = e2.
5254 * Do it before e1->semantic() otherwise the ArrayExp will have been
5255 * converted to unary operator overloading already.
5257 if (exp
->e1
->op
== TOKarray
)
5261 ArrayExp
*ae
= (ArrayExp
*)exp
->e1
;
5262 ae
->e1
= expressionSemantic(ae
->e1
, sc
);
5263 ae
->e1
= resolveProperties(sc
, ae
->e1
);
5264 Expression
*ae1old
= ae
->e1
;
5266 const bool maybeSlice
=
5267 (ae
->arguments
->length
== 0 ||
5268 (ae
->arguments
->length
== 1 && (*ae
->arguments
)[0]->op
== TOKinterval
));
5269 IntervalExp
*ie
= NULL
;
5270 if (maybeSlice
&& ae
->arguments
->length
)
5272 assert((*ae
->arguments
)[0]->op
== TOKinterval
);
5273 ie
= (IntervalExp
*)(*ae
->arguments
)[0];
5278 if (ae
->e1
->op
== TOKerror
)
5283 Expression
*e0
= NULL
;
5284 Expression
*ae1save
= ae
->e1
;
5285 ae
->lengthVar
= NULL
;
5287 Type
*t1b
= ae
->e1
->type
->toBasetype();
5288 AggregateDeclaration
*ad
= isAggregate(t1b
);
5291 if (search_function(ad
, Id::indexass
))
5294 res
= resolveOpDollar(sc
, ae
, &e0
);
5295 if (!res
) // a[i..j] = e2 might be: a.opSliceAssign(e2, i, j)
5297 if (res
->op
== TOKerror
)
5303 res
= expressionSemantic(exp
->e2
, sc
);
5304 if (res
->op
== TOKerror
)
5311 /* Rewrite (a[arguments] = e2) as:
5312 * a.opIndexAssign(e2, arguments)
5314 Expressions
*a
= (Expressions
*)ae
->arguments
->copy();
5315 a
->insert(0, exp
->e2
);
5316 res
= new DotIdExp(exp
->loc
, ae
->e1
, Id::indexass
);
5317 res
= new CallExp(exp
->loc
, res
, a
);
5318 if (maybeSlice
) // a[] = e2 might be: a.opSliceAssign(e2)
5319 res
= trySemantic(res
, sc
);
5321 res
= expressionSemantic(res
, sc
);
5324 res
= Expression::combine(e0
, res
);
5330 if (maybeSlice
&& search_function(ad
, Id::sliceass
))
5333 res
= resolveOpDollar(sc
, ae
, ie
, &e0
);
5334 if (res
->op
== TOKerror
)
5340 res
= expressionSemantic(exp
->e2
, sc
);
5341 if (res
->op
== TOKerror
)
5348 /* Rewrite (a[i..j] = e2) as:
5349 * a.opSliceAssign(e2, i, j)
5351 Expressions
*a
= new Expressions();
5358 res
= new DotIdExp(exp
->loc
, ae
->e1
, Id::sliceass
);
5359 res
= new CallExp(exp
->loc
, res
, a
);
5360 res
= expressionSemantic(res
, sc
);
5361 res
= Expression::combine(e0
, res
);
5366 // No operator overloading member function found yet, but
5367 // there might be an alias this to try.
5368 if (ad
->aliasthis
&& t1b
!= ae
->att1
)
5370 if (!ae
->att1
&& t1b
->checkAliasThisRec())
5373 /* Rewrite (a[arguments] op e2) as:
5374 * a.aliasthis[arguments] op e2
5376 ae
->e1
= resolveAliasThis(sc
, ae1save
, true);
5382 ae
->e1
= ae1old
; // recovery
5383 ae
->lengthVar
= NULL
;
5386 /* Run exp->e1 semantic.
5389 Expression
*e1x
= exp
->e1
;
5391 /* With UFCS, e.f = value
5397 if (e1x
->op
== TOKdotti
)
5399 DotTemplateInstanceExp
*dti
= (DotTemplateInstanceExp
*)e1x
;
5400 Expression
*e
= semanticY(dti
, sc
, 1);
5403 result
= resolveUFCSProperties(sc
, e1x
, exp
->e2
);
5408 else if (e1x
->op
== TOKdotid
)
5410 DotIdExp
*die
= (DotIdExp
*)e1x
;
5411 Expression
*e
= semanticY(die
, sc
, 1);
5412 if (e
&& isDotOpDispatch(e
))
5414 unsigned errors
= global
.startGagging();
5415 e
= resolvePropertiesX(sc
, e
, exp
->e2
);
5416 if (global
.endGagging(errors
))
5417 e
= NULL
; /* fall down to UFCS */
5426 result
= resolveUFCSProperties(sc
, e1x
, exp
->e2
);
5433 if (e1x
->op
== TOKslice
)
5434 ((SliceExp
*)e1x
)->arrayop
= true;
5436 e1x
= expressionSemantic(e1x
, sc
);
5439 /* We have f = value.
5445 if (Expression
*e
= resolvePropertiesX(sc
, e1x
, exp
->e2
))
5450 if (e1x
->checkRightThis(sc
))
5453 assert(exp
->e1
->type
);
5455 Type
*t1
= exp
->e1
->type
->toBasetype();
5457 /* Run exp->e2 semantic.
5458 * Different from other binary expressions, the analysis of e2
5459 * depends on the result of e1 in assignments.
5462 Expression
*e2x
= inferType(exp
->e2
, t1
->baseElemOf());
5464 e2x
= expressionSemantic(e2x
, sc
);
5465 e2x
= resolveProperties(sc
, e2x
);
5467 if (e2x
->op
== TOKtype
)
5468 e2x
= resolveAliasThis(sc
, e2x
); //https://issues.dlang.org/show_bug.cgi?id=17684
5469 if (e2x
->op
== TOKerror
)
5474 if (e2x
->checkValue())
5479 /* Rewrite tuple assignment as a tuple of assignments.
5482 Expression
*e2x
= exp
->e2
;
5485 if (exp
->e1
->op
== TOKtuple
&& e2x
->op
== TOKtuple
)
5487 TupleExp
*tup1
= (TupleExp
*)exp
->e1
;
5488 TupleExp
*tup2
= (TupleExp
*)e2x
;
5489 size_t dim
= tup1
->exps
->length
;
5490 Expression
*e
= NULL
;
5491 if (dim
!= tup2
->exps
->length
)
5493 exp
->error("mismatched tuple lengths, %d and %d", (int)dim
, (int)tup2
->exps
->length
);
5498 e
= new IntegerExp(exp
->loc
, 0, Type::tint32
);
5499 e
= new CastExp(exp
->loc
, e
, Type::tvoid
); // avoid "has no effect" error
5500 e
= Expression::combine(Expression::combine(tup1
->e0
, tup2
->e0
), e
);
5504 Expressions
*exps
= new Expressions
;
5506 for (size_t i
= 0; i
< dim
; i
++)
5508 Expression
*ex1
= (*tup1
->exps
)[i
];
5509 Expression
*ex2
= (*tup2
->exps
)[i
];
5510 (*exps
)[i
] = new AssignExp(exp
->loc
, ex1
, ex2
);
5512 e
= new TupleExp(exp
->loc
, Expression::combine(tup1
->e0
, tup2
->e0
), exps
);
5514 result
= expressionSemantic(e
, sc
);
5518 /* Look for form: e1 = e2->aliasthis.
5520 if (exp
->e1
->op
== TOKtuple
)
5522 TupleDeclaration
*td
= isAliasThisTuple(e2x
);
5526 assert(exp
->e1
->type
->ty
== Ttuple
);
5527 TypeTuple
*tt
= (TypeTuple
*)exp
->e1
->type
;
5529 Expression
*e0
= NULL
;
5530 Expression
*ev
= extractSideEffect(sc
, "__tup", &e0
, e2x
);
5532 Expressions
*iexps
= new Expressions();
5535 for (size_t u
= 0; u
< iexps
->length
; u
++)
5538 Expression
*e
= (*iexps
)[u
];
5540 Parameter
*arg
= Parameter::getNth(tt
->arguments
, u
);
5541 //printf("[%d] iexps->length = %d, ", u, iexps->length);
5542 //printf("e = (%s %s, %s), ", Token::tochars[e->op], e->toChars(), e->type->toChars());
5543 //printf("arg = (%s, %s)\n", arg->toChars(), arg->type->toChars());
5545 if (!arg
|| !e
->type
->implicitConvTo(arg
->type
))
5547 // expand initializer to tuple
5548 if (expandAliasThisTuples(iexps
, u
) != -1)
5550 if (iexps
->length
<= u
)
5557 e2x
= new TupleExp(e2x
->loc
, e0
, iexps
);
5558 e2x
= expressionSemantic(e2x
, sc
);
5559 if (e2x
->op
== TOKerror
)
5564 // Do not need to overwrite exp->e2
5571 /* Inside constructor, if this is the first assignment of object field,
5572 * rewrite this to initializing the field.
5574 if (exp
->op
== TOKassign
&& exp
->e1
->checkModifiable(sc
) == 2)
5576 //printf("[%s] change to init - %s\n", exp->loc.toChars(), toChars());
5577 exp
->op
= TOKconstruct
;
5579 // Bugzilla 13515: set Index::modifiable flag for complex AA element initialization
5580 if (exp
->e1
->op
== TOKindex
)
5582 Expression
*e1x
= ((IndexExp
*)exp
->e1
)->markSettingAAElem();
5583 if (e1x
->op
== TOKerror
)
5590 else if (exp
->op
== TOKconstruct
&& exp
->e1
->op
== TOKvar
&&
5591 ((VarExp
*)exp
->e1
)->var
->storage_class
& (STCout
| STCref
))
5593 exp
->memset
|= referenceInit
;
5596 /* If it is an assignment from a 'foreign' type,
5597 * check for operator overloading.
5599 if (exp
->memset
& referenceInit
)
5601 // If this is an initialization of a reference,
5604 else if (t1
->ty
== Tstruct
)
5606 Expression
*e1x
= exp
->e1
;
5607 Expression
*e2x
= exp
->e2
;
5608 StructDeclaration
*sd
= ((TypeStruct
*)t1
)->sym
;
5610 if (exp
->op
== TOKconstruct
)
5612 Type
*t2
= e2x
->type
->toBasetype();
5613 if (t2
->ty
== Tstruct
&& sd
== ((TypeStruct
*)t2
)->sym
)
5616 if (sd
->sizeok
!= SIZEOKdone
)
5619 sd
->ctor
= sd
->searchCtor();
5621 // Bugzilla 15661: Look for the form from last of comma chain.
5622 Expression
*e2y
= e2x
;
5623 while (e2y
->op
== TOKcomma
)
5624 e2y
= ((CommaExp
*)e2y
)->e2
;
5626 CallExp
*ce
= (e2y
->op
== TOKcall
) ? (CallExp
*)e2y
: NULL
;
5627 DotVarExp
*dve
= (ce
&& ce
->e1
->op
== TOKdotvar
)
5628 ? (DotVarExp
*)ce
->e1
: NULL
;
5629 if (sd
->ctor
&& ce
&& dve
&& dve
->var
->isCtorDeclaration() &&
5630 e2y
->type
->implicitConvTo(t1
))
5632 /* Look for form of constructor call which is:
5633 * __ctmp.ctor(arguments...)
5636 /* Before calling the constructor, initialize
5637 * variable with a bit copy of the default
5640 AssignExp
*ae
= exp
;
5641 if (sd
->zeroInit
== 1 && !sd
->isNested())
5643 // Bugzilla 14606: Always use BlitExp for the special expression: (struct = 0)
5644 ae
= new BlitExp(ae
->loc
, ae
->e1
, new IntegerExp(exp
->loc
, 0, Type::tint32
));
5648 // Keep ae->op == TOKconstruct
5649 ae
->e2
= sd
->isNested() ? t1
->defaultInitLiteral(exp
->loc
) : t1
->defaultInit(exp
->loc
);
5651 ae
->type
= e1x
->type
;
5653 /* Replace __ctmp being constructed with e1.
5654 * We need to copy constructor call expression,
5655 * because it may be used in other place.
5657 DotVarExp
*dvx
= (DotVarExp
*)dve
->copy();
5659 CallExp
*cx
= (CallExp
*)ce
->copy();
5663 Expression::extractLast(e2x
, &e0
);
5665 Expression
*e
= Expression::combine(ae
, cx
);
5666 e
= Expression::combine(e0
, e
);
5667 e
= expressionSemantic(e
, sc
);
5673 /* We have a copy constructor for this
5675 if (e2x
->op
== TOKquestion
)
5678 * a ? e1 = b : e1 = c;
5680 CondExp
*econd
= (CondExp
*)e2x
;
5681 Expression
*ea1
= new ConstructExp(econd
->e1
->loc
, e1x
, econd
->e1
);
5682 Expression
*ea2
= new ConstructExp(econd
->e1
->loc
, e1x
, econd
->e2
);
5683 Expression
*e
= new CondExp(exp
->loc
, econd
->econd
, ea1
, ea2
);
5684 result
= expressionSemantic(e
, sc
);
5688 if (e2x
->isLvalue())
5690 if (!e2x
->type
->implicitConvTo(e1x
->type
))
5692 exp
->error("conversion error from %s to %s", e2x
->type
->toChars(), e1x
->type
->toChars());
5697 * (e1 = e2).postblit();
5699 * Blit assignment e1 = e2 returns a reference to the original e1,
5700 * then call the postblit on it.
5702 Expression
*e
= e1x
->copy();
5703 e
->type
= e
->type
->mutableOf();
5704 e
= new BlitExp(exp
->loc
, e
, e2x
);
5705 e
= new DotVarExp(exp
->loc
, e
, sd
->postblit
, false);
5706 e
= new CallExp(exp
->loc
, e
);
5707 result
= expressionSemantic(e
, sc
);
5712 /* The struct value returned from the function is transferred
5713 * so should not call the destructor on it.
5715 e2x
= valueNoDtor(e2x
);
5719 else if (!e2x
->implicitConvTo(t1
))
5722 if (sd
->sizeok
!= SIZEOKdone
)
5725 sd
->ctor
= sd
->searchCtor();
5729 /* Look for implicit constructor call
5731 * e1 = init, e1.ctor(e2)
5734 einit
= new BlitExp(exp
->loc
, e1x
, e1x
->type
->defaultInit(exp
->loc
));
5735 einit
->type
= e1x
->type
;
5738 e
= new DotIdExp(exp
->loc
, e1x
, Id::ctor
);
5739 e
= new CallExp(exp
->loc
, e
, e2x
);
5740 e
= new CommaExp(exp
->loc
, einit
, e
);
5741 e
= expressionSemantic(e
, sc
);
5745 if (search_function(sd
, Id::call
))
5747 /* Look for static opCall
5748 * (See bugzilla 2702 for more discussion)
5750 * e1 = typeof(e1).opCall(arguments)
5752 e2x
= typeDotIdExp(e2x
->loc
, e1x
->type
, Id::call
);
5753 e2x
= new CallExp(exp
->loc
, e2x
, exp
->e2
);
5755 e2x
= expressionSemantic(e2x
, sc
);
5756 e2x
= resolveProperties(sc
, e2x
);
5757 if (e2x
->op
== TOKerror
)
5762 if (e2x
->checkValue())
5766 else // Bugzilla 11355
5768 AggregateDeclaration
*ad2
= isAggregate(e2x
->type
);
5769 if (ad2
&& ad2
->aliasthis
&& !(exp
->att2
&& e2x
->type
== exp
->att2
))
5771 if (!exp
->att2
&& exp
->e2
->type
->checkAliasThisRec())
5772 exp
->att2
= exp
->e2
->type
;
5774 /* Rewrite (e1 op e2) as:
5775 * (e1 op e2.aliasthis)
5777 exp
->e2
= new DotIdExp(exp
->e2
->loc
, exp
->e2
, ad2
->aliasthis
->ident
);
5778 result
= expressionSemantic(exp
, sc
);
5783 else if (exp
->op
== TOKassign
)
5785 if (e1x
->op
== TOKindex
&&
5786 ((IndexExp
*)e1x
)->e1
->type
->toBasetype()->ty
== Taarray
)
5793 * ref __aakey = key;
5795 * (__aakey in __aatmp
5796 * ? __aatmp[__aakey].opAssign(__aaval)
5797 * : ConstructExp(__aatmp[__aakey], __aaval));
5799 IndexExp
*ie
= (IndexExp
*)e1x
;
5800 Type
*t2
= e2x
->type
->toBasetype();
5802 Expression
*e0
= NULL
;
5803 Expression
*ea
= extractSideEffect(sc
, "__aatmp", &e0
, ie
->e1
);
5804 Expression
*ek
= extractSideEffect(sc
, "__aakey", &e0
, ie
->e2
);
5805 Expression
*ev
= extractSideEffect(sc
, "__aaval", &e0
, e2x
);
5807 AssignExp
*ae
= (AssignExp
*)exp
->copy();
5808 ae
->e1
= new IndexExp(exp
->loc
, ea
, ek
);
5809 ae
->e1
= expressionSemantic(ae
->e1
, sc
);
5810 ae
->e1
= ae
->e1
->optimize(WANTvalue
);
5812 Expression
*e
= ae
->op_overload(sc
);
5815 Expression
*ey
= NULL
;
5816 if (t2
->ty
== Tstruct
&& sd
== t2
->toDsymbol(sc
))
5820 else if (!ev
->implicitConvTo(ie
->type
) && sd
->ctor
)
5822 // Look for implicit constructor call
5823 // Rewrite as S().ctor(e2)
5824 ey
= new StructLiteralExp(exp
->loc
, sd
, NULL
);
5825 ey
= new DotIdExp(exp
->loc
, ey
, Id::ctor
);
5826 ey
= new CallExp(exp
->loc
, ey
, ev
);
5827 ey
= trySemantic(ey
, sc
);
5832 ex
= new IndexExp(exp
->loc
, ea
, ek
);
5833 ex
= expressionSemantic(ex
, sc
);
5834 ex
= ex
->optimize(WANTvalue
);
5835 ex
= ex
->modifiableLvalue(sc
, ex
); // allocate new slot
5836 ey
= new ConstructExp(exp
->loc
, ex
, ey
);
5837 ey
= expressionSemantic(ey
, sc
);
5838 if (ey
->op
== TOKerror
)
5845 // Bugzilla 14144: The whole expression should have the common type
5846 // of opAssign() return and assigned AA entry.
5847 // Even if there's no common type, expression should be typed as void.
5849 if (!typeMerge(sc
, TOKquestion
, &t
, &ex
, &ey
))
5851 ex
= new CastExp(ex
->loc
, ex
, Type::tvoid
);
5852 ey
= new CastExp(ey
->loc
, ey
, Type::tvoid
);
5854 e
= new CondExp(exp
->loc
, new InExp(exp
->loc
, ek
, ea
), ex
, ey
);
5856 e
= Expression::combine(e0
, e
);
5857 e
= expressionSemantic(e
, sc
);
5864 Expression
*e
= exp
->op_overload(sc
);
5873 assert(exp
->op
== TOKblit
);
5878 else if (t1
->ty
== Tclass
)
5880 // Disallow assignment operator overloads for same type
5881 if (exp
->op
== TOKassign
&& !exp
->e2
->implicitConvTo(exp
->e1
->type
))
5883 Expression
*e
= exp
->op_overload(sc
);
5891 else if (t1
->ty
== Tsarray
)
5893 // SliceExp cannot have static array type without context inference.
5894 assert(exp
->e1
->op
!= TOKslice
);
5896 Expression
*e1x
= exp
->e1
;
5897 Expression
*e2x
= exp
->e2
;
5899 if (e2x
->implicitConvTo(e1x
->type
))
5901 if (exp
->op
!= TOKblit
&&
5902 ((e2x
->op
== TOKslice
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5903 (e2x
->op
== TOKcast
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
5904 (e2x
->op
!= TOKslice
&& e2x
->isLvalue())))
5906 if (e1x
->checkPostblit(sc
, t1
))
5910 // e2 matches to t1 because of the implicit length match, so
5911 if (isUnaArrayOp(e2x
->op
) || isBinArrayOp(e2x
->op
))
5913 // convert e1 to e1[]
5914 // e.g. e1[] = a[] + b[];
5915 SliceExp
*sle
= new SliceExp(e1x
->loc
, e1x
, NULL
, NULL
);
5916 sle
->arrayop
= true;
5917 e1x
= expressionSemantic(sle
, sc
);
5921 // convert e2 to t1 later
5922 // e.g. e1 = [1, 2, 3];
5927 if (e2x
->implicitConvTo(t1
->nextOf()->arrayOf()) > MATCHnomatch
)
5929 uinteger_t dim1
= ((TypeSArray
*)t1
)->dim
->toInteger();
5930 uinteger_t dim2
= dim1
;
5931 if (e2x
->op
== TOKarrayliteral
)
5933 ArrayLiteralExp
*ale
= (ArrayLiteralExp
*)e2x
;
5934 dim2
= ale
->elements
? ale
->elements
->length
: 0;
5936 else if (e2x
->op
== TOKslice
)
5938 Type
*tx
= toStaticArrayType((SliceExp
*)e2x
);
5940 dim2
= ((TypeSArray
*)tx
)->dim
->toInteger();
5944 exp
->error("mismatched array lengths, %d and %d", (int)dim1
, (int)dim2
);
5949 // May be block or element-wise assignment, so
5950 // convert e1 to e1[]
5951 if (exp
->op
!= TOKassign
)
5953 // If multidimensional static array, treat as one large array
5954 dinteger_t dim
= t1
->numberOfElems(exp
->loc
);
5955 e1x
->type
= t1
->baseElemOf()->sarrayOf(dim
);
5957 SliceExp
*sle
= new SliceExp(e1x
->loc
, e1x
, NULL
, NULL
);
5958 sle
->arrayop
= true;
5959 e1x
= expressionSemantic(sle
, sc
);
5961 if (e1x
->op
== TOKerror
)
5966 if (e2x
->op
== TOKerror
)
5974 t1
= e1x
->type
->toBasetype();
5977 /* Check the mutability of e1.
5979 if (exp
->e1
->op
== TOKarraylength
)
5981 // e1 is not an lvalue, but we let code generator handle it
5982 ArrayLengthExp
*ale
= (ArrayLengthExp
*)exp
->e1
;
5984 Expression
*ale1x
= ale
->e1
;
5985 ale1x
= ale1x
->modifiableLvalue(sc
, exp
->e1
);
5986 if (ale1x
->op
== TOKerror
)
5993 Type
*tn
= ale
->e1
->type
->toBasetype()->nextOf();
5994 checkDefCtor(ale
->loc
, tn
);
5995 semanticTypeInfo(sc
, tn
);
5997 else if (exp
->e1
->op
== TOKslice
)
5999 Type
*tn
= exp
->e1
->type
->nextOf();
6000 if (exp
->op
== TOKassign
&& !tn
->isMutable())
6002 exp
->error("slice %s is not mutable", exp
->e1
->toChars());
6006 // For conditional operator, both branches need conversion.
6007 SliceExp
*se
= (SliceExp
*)exp
->e1
;
6008 while (se
->e1
->op
== TOKslice
)
6009 se
= (SliceExp
*)se
->e1
;
6010 if (se
->e1
->op
== TOKquestion
&&
6011 se
->e1
->type
->toBasetype()->ty
== Tsarray
)
6013 se
->e1
= se
->e1
->modifiableLvalue(sc
, exp
->e1
);
6014 if (se
->e1
->op
== TOKerror
)
6023 Expression
*e1x
= exp
->e1
;
6025 // Try to do a decent error message with the expression
6026 // before it got constant folded
6027 if (e1x
->op
!= TOKvar
)
6028 e1x
= e1x
->optimize(WANTvalue
);
6030 if (exp
->op
== TOKassign
)
6031 e1x
= e1x
->modifiableLvalue(sc
, e1old
);
6033 if (e1x
->op
== TOKerror
)
6041 /* Tweak e2 based on the type of e1.
6043 Expression
*e2x
= exp
->e2
;
6044 Type
*t2
= e2x
->type
->toBasetype();
6046 // If it is a array, get the element type. Note that it may be
6047 // multi-dimensional.
6049 while (telem
->ty
== Tarray
)
6050 telem
= telem
->nextOf();
6052 if (exp
->e1
->op
== TOKslice
&&
6053 t1
->nextOf() && (telem
->ty
!= Tvoid
|| e2x
->op
== TOKnull
) &&
6054 e2x
->implicitConvTo(t1
->nextOf())
6057 // Check for block assignment. If it is of type void[], void[][], etc,
6058 // '= null' is the only allowable block assignment (Bug 7493)
6060 exp
->memset
|= blockAssign
; // make it easy for back end to tell what this is
6061 e2x
= e2x
->implicitCastTo(sc
, t1
->nextOf());
6062 if (exp
->op
!= TOKblit
&& e2x
->isLvalue() &&
6063 exp
->e1
->checkPostblit(sc
, t1
->nextOf()))
6066 else if (exp
->e1
->op
== TOKslice
&&
6067 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
) &&
6068 t2
->nextOf()->implicitConvTo(t1
->nextOf()))
6070 // Check element-wise assignment.
6072 /* If assigned elements number is known at compile time,
6073 * check the mismatch.
6075 SliceExp
*se1
= (SliceExp
*)exp
->e1
;
6076 TypeSArray
*tsa1
= (TypeSArray
*)toStaticArrayType(se1
);
6077 TypeSArray
*tsa2
= NULL
;
6078 if (e2x
->op
== TOKarrayliteral
)
6079 tsa2
= (TypeSArray
*)t2
->nextOf()->sarrayOf(((ArrayLiteralExp
*)e2x
)->elements
->length
);
6080 else if (e2x
->op
== TOKslice
)
6081 tsa2
= (TypeSArray
*)toStaticArrayType((SliceExp
*)e2x
);
6082 else if (t2
->ty
== Tsarray
)
6083 tsa2
= (TypeSArray
*)t2
;
6086 uinteger_t dim1
= tsa1
->dim
->toInteger();
6087 uinteger_t dim2
= tsa2
->dim
->toInteger();
6090 exp
->error("mismatched array lengths, %d and %d", (int)dim1
, (int)dim2
);
6095 if (exp
->op
!= TOKblit
&&
6096 ((e2x
->op
== TOKslice
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
6097 (e2x
->op
== TOKcast
&& ((UnaExp
*)e2x
)->e1
->isLvalue()) ||
6098 (e2x
->op
!= TOKslice
&& e2x
->isLvalue())))
6100 if (exp
->e1
->checkPostblit(sc
, t1
->nextOf()))
6104 if (0 && global
.params
.warnings
!= DIAGNOSTICoff
&& !global
.gag
&& exp
->op
== TOKassign
&&
6105 e2x
->op
!= TOKslice
&& e2x
->op
!= TOKassign
&&
6106 e2x
->op
!= TOKarrayliteral
&& e2x
->op
!= TOKstring
&&
6107 !(e2x
->op
== TOKadd
|| e2x
->op
== TOKmin
||
6108 e2x
->op
== TOKmul
|| e2x
->op
== TOKdiv
||
6109 e2x
->op
== TOKmod
|| e2x
->op
== TOKxor
||
6110 e2x
->op
== TOKand
|| e2x
->op
== TOKor
||
6111 e2x
->op
== TOKpow
||
6112 e2x
->op
== TOKtilde
|| e2x
->op
== TOKneg
))
6114 const char* e1str
= exp
->e1
->toChars();
6115 const char* e2str
= e2x
->toChars();
6116 exp
->warning("explicit element-wise assignment %s = (%s)[] is better than %s = %s",
6117 e1str
, e2str
, e1str
, e2str
);
6120 Type
*t2n
= t2
->nextOf();
6121 Type
*t1n
= t1
->nextOf();
6123 if (t2n
->equivalent(t1n
) ||
6124 (t1n
->isBaseOf(t2n
, &offset
) && offset
== 0))
6126 /* Allow copy of distinct qualifier elements.
6128 * char[] dst; const(char)[] src;
6131 * class C {} class D : C {}
6135 if (isArrayOpValid(e2x
))
6137 // Don't add CastExp to keep AST for array operations
6139 e2x
->type
= exp
->e1
->type
->constOf();
6142 e2x
= e2x
->castTo(sc
, exp
->e1
->type
->constOf());
6146 /* Bugzilla 15778: A string literal has an array type of immutable
6147 * elements by default, and normally it cannot be convertible to
6148 * array type of mutable elements. But for element-wise assignment,
6149 * elements need to be const at best. So we should give a chance
6150 * to change code unit size for polysemous string literal.
6152 if (e2x
->op
== TOKstring
)
6153 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
->constOf());
6155 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
);
6157 if (t1n
->toBasetype()->ty
== Tvoid
&& t2n
->toBasetype()->ty
== Tvoid
)
6159 if (!sc
->intypeof
&& sc
->func
&& sc
->func
->setUnsafe())
6161 exp
->error("cannot copy void[] to void[] in @safe code");
6168 if (0 && global
.params
.warnings
!= DIAGNOSTICoff
&& !global
.gag
&& exp
->op
== TOKassign
&&
6169 t1
->ty
== Tarray
&& t2
->ty
== Tsarray
&&
6170 e2x
->op
!= TOKslice
&&
6171 t2
->implicitConvTo(t1
))
6172 { // Disallow ar[] = sa (Converted to ar[] = sa[])
6173 // Disallow da = sa (Converted to da = sa[])
6174 const char* e1str
= exp
->e1
->toChars();
6175 const char* e2str
= e2x
->toChars();
6176 const char* atypestr
= exp
->e1
->op
== TOKslice
? "element-wise" : "slice";
6177 exp
->warning("explicit %s assignment %s = (%s)[] is better than %s = %s",
6178 atypestr
, e1str
, e2str
, e1str
, e2str
);
6180 if (exp
->op
== TOKblit
)
6181 e2x
= e2x
->castTo(sc
, exp
->e1
->type
);
6183 e2x
= e2x
->implicitCastTo(sc
, exp
->e1
->type
);
6185 if (e2x
->op
== TOKerror
)
6191 t2
= exp
->e2
->type
->toBasetype();
6193 /* Look for array operations
6195 if ((t2
->ty
== Tarray
|| t2
->ty
== Tsarray
) && isArrayOpValid(exp
->e2
))
6197 // Look for valid array operations
6198 if (!(exp
->memset
& blockAssign
) && exp
->e1
->op
== TOKslice
&&
6199 (isUnaArrayOp(exp
->e2
->op
) || isBinArrayOp(exp
->e2
->op
)))
6201 exp
->type
= exp
->e1
->type
;
6202 if (exp
->op
== TOKconstruct
) // Bugzilla 10282: tweak mutability of e1 element
6203 exp
->e1
->type
= exp
->e1
->type
->nextOf()->mutableOf()->arrayOf();
6204 result
= arrayOp(exp
, sc
);
6208 // Drop invalid array operations in e2
6209 // d = a[] + b[], d = (a[] + b[])[0..2], etc
6210 if (checkNonAssignmentArrayOp(exp
->e2
, !(exp
->memset
& blockAssign
) && exp
->op
== TOKassign
))
6213 // Remains valid array assignments
6214 // d = d[], d = [1,2,3], etc
6217 /* Don't allow assignment to classes that were allocated on the stack with:
6218 * scope Class c = new Class();
6221 if (exp
->e1
->op
== TOKvar
&& exp
->op
== TOKassign
)
6223 VarExp
*ve
= (VarExp
*)exp
->e1
;
6224 VarDeclaration
*vd
= ve
->var
->isVarDeclaration();
6225 if (vd
&& (vd
->onstack
|| vd
->mynew
))
6227 assert(t1
->ty
== Tclass
);
6228 exp
->error("cannot rebind scope variables");
6231 if (exp
->e1
->op
== TOKvar
&& ((VarExp
*)exp
->e1
)->var
->ident
== Id::ctfe
)
6233 exp
->error("cannot modify compiler-generated variable __ctfe");
6236 exp
->type
= exp
->e1
->type
;
6238 Expression
*res
= exp
->op
== TOKassign
? exp
->reorderSettingAAElem(sc
) : exp
;
6239 checkAssignEscape(sc
, res
, false);
6243 void visit(CatAssignExp
*exp
)
6251 //printf("CatAssignExp::semantic() %s\n", toChars());
6252 Expression
*e
= exp
->op_overload(sc
);
6259 if (exp
->e1
->op
== TOKslice
)
6261 SliceExp
*se
= (SliceExp
*)exp
->e1
;
6262 if (se
->e1
->type
->toBasetype()->ty
== Tsarray
)
6264 exp
->error("cannot append to static array %s", se
->e1
->type
->toChars());
6269 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
6270 if (exp
->e1
->op
== TOKerror
)
6275 if (exp
->e2
->op
== TOKerror
)
6281 if (checkNonAssignmentArrayOp(exp
->e2
))
6284 Type
*tb1
= exp
->e1
->type
->toBasetype();
6285 Type
*tb1next
= tb1
->nextOf();
6286 Type
*tb2
= exp
->e2
->type
->toBasetype();
6288 if ((tb1
->ty
== Tarray
) &&
6289 (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
) &&
6290 (exp
->e2
->implicitConvTo(exp
->e1
->type
)
6291 || (tb2
->nextOf()->implicitConvTo(tb1next
) &&
6292 (tb2
->nextOf()->size(Loc()) == tb1next
->size(Loc())))
6297 if (exp
->e1
->checkPostblit(sc
, tb1next
))
6299 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
6301 else if ((tb1
->ty
== Tarray
) &&
6302 exp
->e2
->implicitConvTo(tb1next
)
6306 if (exp
->e2
->checkPostblit(sc
, tb2
))
6308 exp
->e2
= exp
->e2
->castTo(sc
, tb1next
);
6309 exp
->e2
= doCopyOrMove(sc
, exp
->e2
);
6311 else if (tb1
->ty
== Tarray
&&
6312 (tb1next
->ty
== Tchar
|| tb1next
->ty
== Twchar
) &&
6313 exp
->e2
->type
->ty
!= tb1next
->ty
&&
6314 exp
->e2
->implicitConvTo(Type::tdchar
)
6316 { // Append dchar to char[] or wchar[]
6317 exp
->e2
= exp
->e2
->castTo(sc
, Type::tdchar
);
6319 /* Do not allow appending wchar to char[] because if wchar happens
6320 * to be a surrogate pair, nothing good can result.
6325 exp
->error("cannot append type %s to type %s", tb2
->toChars(), tb1
->toChars());
6328 if (exp
->e2
->checkValue())
6331 exp
->type
= exp
->e1
->type
;
6332 result
= exp
->reorderSettingAAElem(sc
);
6335 void visit(PowAssignExp
*exp
)
6343 Expression
*e
= exp
->op_overload(sc
);
6350 if (exp
->e1
->checkReadModifyWrite(exp
->op
, exp
->e2
))
6353 assert(exp
->e1
->type
&& exp
->e2
->type
);
6354 if (exp
->e1
->op
== TOKslice
|| exp
->e1
->type
->ty
== Tarray
|| exp
->e1
->type
->ty
== Tsarray
)
6356 if (checkNonAssignmentArrayOp(exp
->e1
))
6360 if (exp
->e2
->implicitConvTo(exp
->e1
->type
->nextOf()))
6363 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
->nextOf());
6365 else if (Expression
*ex
= typeCombine(exp
, sc
))
6371 // Check element types are arithmetic
6372 Type
*tb1
= exp
->e1
->type
->nextOf()->toBasetype();
6373 Type
*tb2
= exp
->e2
->type
->toBasetype();
6374 if (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
6375 tb2
= tb2
->nextOf()->toBasetype();
6377 if ( (tb1
->isintegral() || tb1
->isfloating()) &&
6378 (tb2
->isintegral() || tb2
->isfloating()))
6380 exp
->type
= exp
->e1
->type
;
6381 result
= arrayOp(exp
, sc
);
6387 exp
->e1
= exp
->e1
->modifiableLvalue(sc
, exp
->e1
);
6390 if ((exp
->e1
->type
->isintegral() || exp
->e1
->type
->isfloating()) &&
6391 (exp
->e2
->type
->isintegral() || exp
->e2
->type
->isfloating()))
6393 Expression
*e0
= NULL
;
6394 e
= exp
->reorderSettingAAElem(sc
);
6395 e
= Expression::extractLast(e
, &e0
);
6398 if (exp
->e1
->op
== TOKvar
)
6400 // Rewrite: e1 = e1 ^^ e2
6401 e
= new PowExp(exp
->loc
, exp
->e1
->syntaxCopy(), exp
->e2
);
6402 e
= new AssignExp(exp
->loc
, exp
->e1
, e
);
6406 // Rewrite: ref tmp = e1; tmp = tmp ^^ e2
6407 VarDeclaration
*v
= copyToTemp(STCref
, "__powtmp", exp
->e1
);
6408 Expression
*de
= new DeclarationExp(exp
->e1
->loc
, v
);
6409 VarExp
*ve
= new VarExp(exp
->e1
->loc
, v
);
6410 e
= new PowExp(exp
->loc
, ve
, exp
->e2
);
6411 e
= new AssignExp(exp
->loc
, new VarExp(exp
->e1
->loc
, v
), e
);
6412 e
= new CommaExp(exp
->loc
, de
, e
);
6414 e
= Expression::combine(e0
, e
);
6415 e
= expressionSemantic(e
, sc
);
6419 result
= exp
->incompatibleTypes();
6422 void visit(AddExp
*exp
)
6430 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6435 Expression
*e
= exp
->op_overload(sc
);
6442 Type
*tb1
= exp
->e1
->type
->toBasetype();
6443 Type
*tb2
= exp
->e2
->type
->toBasetype();
6446 if (tb1
->ty
== Tdelegate
||
6447 (tb1
->ty
== Tpointer
&& tb1
->nextOf()->ty
== Tfunction
))
6449 err
|= exp
->e1
->checkArithmetic();
6451 if (tb2
->ty
== Tdelegate
||
6452 (tb2
->ty
== Tpointer
&& tb2
->nextOf()->ty
== Tfunction
))
6454 err
|= exp
->e2
->checkArithmetic();
6459 if ((tb1
->ty
== Tpointer
&& exp
->e2
->type
->isintegral()) ||
6460 (tb2
->ty
== Tpointer
&& exp
->e1
->type
->isintegral()))
6462 result
= scaleFactor(exp
, sc
);
6466 if (tb1
->ty
== Tpointer
&& tb2
->ty
== Tpointer
)
6468 result
= exp
->incompatibleTypes();
6472 if (Expression
*ex
= typeCombine(exp
, sc
))
6478 Type
*tb
= exp
->type
->toBasetype();
6479 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6481 if (!isArrayOpValid(exp
))
6483 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6490 tb1
= exp
->e1
->type
->toBasetype();
6491 if (!target
.isVectorOpSupported(tb1
, exp
->op
, tb2
))
6493 result
= exp
->incompatibleTypes();
6496 if ((tb1
->isreal() && exp
->e2
->type
->isimaginary()) ||
6497 (tb1
->isimaginary() && exp
->e2
->type
->isreal()))
6499 switch (exp
->type
->toBasetype()->ty
)
6503 exp
->type
= Type::tcomplex32
;
6508 exp
->type
= Type::tcomplex64
;
6513 exp
->type
= Type::tcomplex80
;
6523 void visit(MinExp
*exp
)
6531 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6536 Expression
*e
= exp
->op_overload(sc
);
6543 Type
*t1
= exp
->e1
->type
->toBasetype();
6544 Type
*t2
= exp
->e2
->type
->toBasetype();
6547 if (t1
->ty
== Tdelegate
||
6548 (t1
->ty
== Tpointer
&& t1
->nextOf()->ty
== Tfunction
))
6550 err
|= exp
->e1
->checkArithmetic();
6552 if (t2
->ty
== Tdelegate
||
6553 (t2
->ty
== Tpointer
&& t2
->nextOf()->ty
== Tfunction
))
6555 err
|= exp
->e2
->checkArithmetic();
6560 if (t1
->ty
== Tpointer
)
6562 if (t2
->ty
== Tpointer
)
6564 // Need to divide the result by the stride
6565 // Replace (ptr - ptr) with (ptr - ptr) / stride
6568 // make sure pointer types are compatible
6569 if (Expression
*ex
= typeCombine(exp
, sc
))
6575 exp
->type
= Type::tptrdiff_t
;
6576 stride
= t2
->nextOf()->size();
6579 e
= new IntegerExp(exp
->loc
, 0, Type::tptrdiff_t
);
6583 e
= new DivExp(exp
->loc
, exp
, new IntegerExp(Loc(), stride
, Type::tptrdiff_t
));
6584 e
->type
= Type::tptrdiff_t
;
6587 else if (t2
->isintegral())
6588 e
= scaleFactor(exp
, sc
);
6591 exp
->error("can't subtract %s from pointer", t2
->toChars());
6597 if (t2
->ty
== Tpointer
)
6599 exp
->type
= exp
->e2
->type
;
6600 exp
->error("can't subtract pointer from %s", exp
->e1
->type
->toChars());
6604 if (Expression
*ex
= typeCombine(exp
, sc
))
6610 Type
*tb
= exp
->type
->toBasetype();
6611 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6613 if (!isArrayOpValid(exp
))
6615 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6622 t1
= exp
->e1
->type
->toBasetype();
6623 t2
= exp
->e2
->type
->toBasetype();
6624 if (!target
.isVectorOpSupported(t1
, exp
->op
, t2
))
6626 result
= exp
->incompatibleTypes();
6629 if ((t1
->isreal() && t2
->isimaginary()) ||
6630 (t1
->isimaginary() && t2
->isreal()))
6632 switch (exp
->type
->ty
)
6636 exp
->type
= Type::tcomplex32
;
6641 exp
->type
= Type::tcomplex64
;
6646 exp
->type
= Type::tcomplex80
;
6656 void visit(CatExp
*exp
)
6658 //printf("CatExp::semantic() %s\n", exp->toChars());
6665 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6670 Expression
*e
= exp
->op_overload(sc
);
6677 Type
*tb1
= exp
->e1
->type
->toBasetype();
6678 Type
*tb2
= exp
->e2
->type
->toBasetype();
6680 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
6681 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
6685 /* BUG: Should handle things like:
6690 Type
*tb1next
= tb1
->nextOf();
6691 Type
*tb2next
= tb2
->nextOf();
6693 // Check for: array ~ array
6694 if (tb1next
&& tb2next
&&
6695 (tb1next
->implicitConvTo(tb2next
) >= MATCHconst
||
6696 tb2next
->implicitConvTo(tb1next
) >= MATCHconst
||
6697 (exp
->e1
->op
== TOKarrayliteral
&& exp
->e1
->implicitConvTo(tb2
)) ||
6698 (exp
->e2
->op
== TOKarrayliteral
&& exp
->e2
->implicitConvTo(tb1
))
6702 /* Bugzilla 9248: Here to avoid the case of:
6703 * void*[] a = [cast(void*)1];
6704 * void*[] b = [cast(void*)2];
6707 * a ~ [cast(void*)b];
6710 /* Bugzilla 14682: Also to avoid the case of:
6714 * a ~ cast(int[])[];
6719 // Check for: array ~ element
6720 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
) && tb2
->ty
!= Tvoid
)
6722 if (exp
->e1
->op
== TOKarrayliteral
)
6724 exp
->e2
= exp
->e2
->isLvalue() ? callCpCtor(sc
, exp
->e2
) : valueNoDtor(exp
->e2
);
6725 // Bugzilla 14686: Postblit call appears in AST, and this is
6726 // finally translated to an ArrayLiteralExp in below otpimize().
6728 else if (exp
->e1
->op
== TOKstring
)
6730 // No postblit call exists on character (integer) value.
6734 if (exp
->e2
->checkPostblit(sc
, tb2
))
6736 // Postblit call will be done in runtime helper function
6739 if (exp
->e1
->op
== TOKarrayliteral
&& exp
->e1
->implicitConvTo(tb2
->arrayOf()))
6741 exp
->e1
= exp
->e1
->implicitCastTo(sc
, tb2
->arrayOf());
6742 exp
->type
= tb2
->arrayOf();
6745 if (exp
->e2
->implicitConvTo(tb1next
) >= MATCHconvert
)
6747 exp
->e2
= exp
->e2
->implicitCastTo(sc
, tb1next
);
6748 exp
->type
= tb1next
->arrayOf();
6750 if (tb2
->ty
== Tarray
|| tb2
->ty
== Tsarray
)
6752 // Make e2 into [e2]
6753 exp
->e2
= new ArrayLiteralExp(exp
->e2
->loc
, exp
->type
, exp
->e2
);
6755 result
= exp
->optimize(WANTvalue
);
6759 // Check for: element ~ array
6760 if ((tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
) && tb1
->ty
!= Tvoid
)
6762 if (exp
->e2
->op
== TOKarrayliteral
)
6764 exp
->e1
= exp
->e1
->isLvalue() ? callCpCtor(sc
, exp
->e1
) : valueNoDtor(exp
->e1
);
6766 else if (exp
->e2
->op
== TOKstring
)
6771 if (exp
->e1
->checkPostblit(sc
, tb1
))
6775 if (exp
->e2
->op
== TOKarrayliteral
&& exp
->e2
->implicitConvTo(tb1
->arrayOf()))
6777 exp
->e2
= exp
->e2
->implicitCastTo(sc
, tb1
->arrayOf());
6778 exp
->type
= tb1
->arrayOf();
6781 if (exp
->e1
->implicitConvTo(tb2next
) >= MATCHconvert
)
6783 exp
->e1
= exp
->e1
->implicitCastTo(sc
, tb2next
);
6784 exp
->type
= tb2next
->arrayOf();
6786 if (tb1
->ty
== Tarray
|| tb1
->ty
== Tsarray
)
6788 // Make e1 into [e1]
6789 exp
->e1
= new ArrayLiteralExp(exp
->e1
->loc
, exp
->type
, exp
->e1
);
6791 result
= exp
->optimize(WANTvalue
);
6797 if ((tb1
->ty
== Tsarray
|| tb1
->ty
== Tarray
) &&
6798 (tb2
->ty
== Tsarray
|| tb2
->ty
== Tarray
) &&
6799 (tb1next
->mod
|| tb2next
->mod
) &&
6800 (tb1next
->mod
!= tb2next
->mod
)
6803 Type
*t1
= tb1next
->mutableOf()->constOf()->arrayOf();
6804 Type
*t2
= tb2next
->mutableOf()->constOf()->arrayOf();
6805 if (exp
->e1
->op
== TOKstring
&& !((StringExp
*)exp
->e1
)->committed
)
6808 exp
->e1
= exp
->e1
->castTo(sc
, t1
);
6809 if (exp
->e2
->op
== TOKstring
&& !((StringExp
*)exp
->e2
)->committed
)
6812 exp
->e2
= exp
->e2
->castTo(sc
, t2
);
6815 if (Expression
*ex
= typeCombine(exp
, sc
))
6820 exp
->type
= exp
->type
->toHeadMutable();
6822 Type
*tb
= exp
->type
->toBasetype();
6823 if (tb
->ty
== Tsarray
)
6824 exp
->type
= tb
->nextOf()->arrayOf();
6825 if (exp
->type
->ty
== Tarray
&& tb1next
&& tb2next
&&
6826 tb1next
->mod
!= tb2next
->mod
)
6828 exp
->type
= exp
->type
->nextOf()->toHeadMutable()->arrayOf();
6830 if (Type
*tbn
= tb
->nextOf())
6832 if (exp
->checkPostblit(sc
, tbn
))
6835 Type
*t1
= exp
->e1
->type
->toBasetype();
6836 Type
*t2
= exp
->e2
->type
->toBasetype();
6837 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
6838 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
6840 // Normalize to ArrayLiteralExp or StringExp as far as possible
6841 e
= exp
->optimize(WANTvalue
);
6845 //printf("(%s) ~ (%s)\n", exp->e1->toChars(), exp->e2->toChars());
6846 result
= exp
->incompatibleTypes();
6852 void visit(MulExp
*exp
)
6860 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6865 Expression
*e
= exp
->op_overload(sc
);
6872 if (Expression
*ex
= typeCombine(exp
, sc
))
6878 Type
*tb
= exp
->type
->toBasetype();
6879 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6881 if (!isArrayOpValid(exp
))
6883 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6890 if (exp
->checkArithmeticBin())
6893 if (exp
->type
->isfloating())
6895 Type
*t1
= exp
->e1
->type
;
6896 Type
*t2
= exp
->e2
->type
;
6902 else if (t2
->isreal())
6906 else if (t1
->isimaginary())
6908 if (t2
->isimaginary())
6911 switch (t1
->toBasetype()->ty
)
6914 exp
->type
= Type::tfloat32
;
6918 exp
->type
= Type::tfloat64
;
6922 exp
->type
= Type::tfloat80
;
6930 exp
->e1
->type
= exp
->type
;
6931 exp
->e2
->type
= exp
->type
;
6932 e
= new NegExp(exp
->loc
, exp
);
6933 e
= expressionSemantic(e
, sc
);
6938 exp
->type
= t2
; // t2 is complex
6940 else if (t2
->isimaginary())
6942 exp
->type
= t1
; // t1 is complex
6945 else if (!target
.isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
6947 result
= exp
->incompatibleTypes();
6953 void visit(DivExp
*exp
)
6961 if (Expression
*ex
= binSemanticProp(exp
, sc
))
6966 Expression
*e
= exp
->op_overload(sc
);
6973 if (Expression
*ex
= typeCombine(exp
, sc
))
6979 Type
*tb
= exp
->type
->toBasetype();
6980 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
6982 if (!isArrayOpValid(exp
))
6984 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
6991 if (exp
->checkArithmeticBin())
6994 if (exp
->type
->isfloating())
6996 Type
*t1
= exp
->e1
->type
;
6997 Type
*t2
= exp
->e2
->type
;
7002 if (t2
->isimaginary())
7006 e
= new NegExp(exp
->loc
, exp
);
7007 e
= expressionSemantic(e
, sc
);
7012 else if (t2
->isreal())
7016 else if (t1
->isimaginary())
7018 if (t2
->isimaginary())
7020 switch (t1
->toBasetype()->ty
)
7023 exp
->type
= Type::tfloat32
;
7027 exp
->type
= Type::tfloat64
;
7031 exp
->type
= Type::tfloat80
;
7039 exp
->type
= t2
; // t2 is complex
7041 else if (t2
->isimaginary())
7043 exp
->type
= t1
; // t1 is complex
7046 else if (!target
.isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7048 result
= exp
->incompatibleTypes();
7054 void visit(ModExp
*exp
)
7062 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7067 Expression
*e
= exp
->op_overload(sc
);
7074 if (Expression
*ex
= typeCombine(exp
, sc
))
7080 Type
*tb
= exp
->type
->toBasetype();
7081 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7083 if (!isArrayOpValid(exp
))
7085 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7091 if (!target
.isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7093 result
= exp
->incompatibleTypes();
7097 if (exp
->checkArithmeticBin())
7100 if (exp
->type
->isfloating())
7102 exp
->type
= exp
->e1
->type
;
7103 if (exp
->e2
->type
->iscomplex())
7105 exp
->error("cannot perform modulo complex arithmetic");
7112 Module
*loadStdMath()
7114 static Import
*impStdMath
= NULL
;
7117 Identifiers
*a
= new Identifiers();
7119 Import
*s
= new Import(Loc(), a
, Id::math
, NULL
, false);
7123 s
->mod
->importAll(NULL
);
7124 dsymbolSemantic(s
->mod
, NULL
);
7128 return impStdMath
->mod
;
7131 void visit(PowExp
*exp
)
7139 //printf("PowExp::semantic() %s\n", exp->toChars());
7140 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7145 Expression
*e
= exp
->op_overload(sc
);
7152 if (Expression
*ex
= typeCombine(exp
, sc
))
7158 Type
*tb
= exp
->type
->toBasetype();
7159 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7161 if (!isArrayOpValid(exp
))
7163 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7170 if (exp
->checkArithmeticBin())
7173 if (!target
.isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7175 result
= exp
->incompatibleTypes();
7179 // For built-in numeric types, there are several cases.
7180 // TODO: backend support, especially for e1 ^^ 2.
7182 // First, attempt to fold the expression.
7183 e
= exp
->optimize(WANTvalue
);
7184 if (e
->op
!= TOKpow
)
7186 e
= expressionSemantic(e
, sc
);
7191 // Determine if we're raising to an integer power.
7192 sinteger_t intpow
= 0;
7193 if (exp
->e2
->op
== TOKint64
&& ((sinteger_t
)exp
->e2
->toInteger() == 2 || (sinteger_t
)exp
->e2
->toInteger() == 3))
7194 intpow
= exp
->e2
->toInteger();
7195 else if (exp
->e2
->op
== TOKfloat64
&& (exp
->e2
->toReal() == ldouble((sinteger_t
)exp
->e2
->toReal())))
7196 intpow
= (sinteger_t
)(exp
->e2
->toReal());
7198 // Deal with x^^2, x^^3 immediately, since they are of practical importance.
7199 if (intpow
== 2 || intpow
== 3)
7201 // Replace x^^2 with (tmp = x, tmp*tmp)
7202 // Replace x^^3 with (tmp = x, tmp*tmp*tmp)
7203 VarDeclaration
*tmp
= copyToTemp(0, "__powtmp", exp
->e1
);
7204 Expression
*de
= new DeclarationExp(exp
->loc
, tmp
);
7205 Expression
*ve
= new VarExp(exp
->loc
, tmp
);
7207 /* Note that we're reusing ve. This should be ok.
7209 Expression
*me
= new MulExp(exp
->loc
, ve
, ve
);
7211 me
= new MulExp(exp
->loc
, me
, ve
);
7212 e
= new CommaExp(exp
->loc
, de
, me
);
7213 e
= expressionSemantic(e
, sc
);
7218 Module
*mmath
= loadStdMath();
7221 //exp->error("requires std.math for ^^ operators");
7224 // Leave handling of PowExp to the backend, or throw
7225 // an error gracefully if no backend support exists.
7226 if (Expression
*ex
= typeCombine(exp
, sc
))
7234 e
= new ScopeExp(exp
->loc
, mmath
);
7236 if (exp
->e2
->op
== TOKfloat64
&& exp
->e2
->toReal() == CTFloat::half
)
7238 // Replace e1 ^^ 0.5 with .std.math.sqrt(x)
7239 e
= new CallExp(exp
->loc
, new DotIdExp(exp
->loc
, e
, Id::_sqrt
), exp
->e1
);
7243 // Replace e1 ^^ e2 with .std.math.pow(e1, e2)
7244 e
= new CallExp(exp
->loc
, new DotIdExp(exp
->loc
, e
, Id::_pow
), exp
->e1
, exp
->e2
);
7246 e
= expressionSemantic(e
, sc
);
7250 void visit(ShlExp
*exp
)
7252 //printf("ShlExp::semantic(), type = %p\n", exp->type);
7259 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7264 Expression
*e
= exp
->op_overload(sc
);
7271 if (exp
->checkIntegralBin())
7273 if (!target
.isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7275 result
= exp
->incompatibleTypes();
7278 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7279 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7280 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7282 exp
->type
= exp
->e1
->type
;
7286 void visit(ShrExp
*exp
)
7294 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7299 Expression
*e
= exp
->op_overload(sc
);
7306 if (exp
->checkIntegralBin())
7308 if (!target
.isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7310 result
= exp
->incompatibleTypes();
7313 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7314 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7315 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7317 exp
->type
= exp
->e1
->type
;
7321 void visit(UshrExp
*exp
)
7329 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7334 Expression
*e
= exp
->op_overload(sc
);
7341 if (exp
->checkIntegralBin())
7343 if (!target
.isVectorOpSupported(exp
->e1
->type
->toBasetype(), exp
->op
, exp
->e2
->type
->toBasetype()))
7345 result
= exp
->incompatibleTypes();
7348 exp
->e1
= integralPromotions(exp
->e1
, sc
);
7349 if (exp
->e2
->type
->toBasetype()->ty
!= Tvector
)
7350 exp
->e2
= exp
->e2
->castTo(sc
, Type::tshiftcnt
);
7352 exp
->type
= exp
->e1
->type
;
7356 void visit(AndExp
*exp
)
7364 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7369 Expression
*e
= exp
->op_overload(sc
);
7376 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7377 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7379 exp
->type
= exp
->e1
->type
;
7384 if (Expression
*ex
= typeCombine(exp
, sc
))
7390 Type
*tb
= exp
->type
->toBasetype();
7391 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7393 if (!isArrayOpValid(exp
))
7395 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7402 if (!target
.isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7404 result
= exp
->incompatibleTypes();
7407 if (exp
->checkIntegralBin())
7413 void visit(OrExp
*exp
)
7421 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7426 Expression
*e
= exp
->op_overload(sc
);
7433 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7434 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7436 exp
->type
= exp
->e1
->type
;
7441 if (Expression
*ex
= typeCombine(exp
, sc
))
7447 Type
*tb
= exp
->type
->toBasetype();
7448 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7450 if (!isArrayOpValid(exp
))
7452 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7459 if (!target
.isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7461 result
= exp
->incompatibleTypes();
7464 if (exp
->checkIntegralBin())
7470 void visit(XorExp
*exp
)
7478 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7483 Expression
*e
= exp
->op_overload(sc
);
7490 if (exp
->e1
->type
->toBasetype()->ty
== Tbool
&&
7491 exp
->e2
->type
->toBasetype()->ty
== Tbool
)
7493 exp
->type
= exp
->e1
->type
;
7498 if (Expression
*ex
= typeCombine(exp
, sc
))
7504 Type
*tb
= exp
->type
->toBasetype();
7505 if (tb
->ty
== Tarray
|| tb
->ty
== Tsarray
)
7507 if (!isArrayOpValid(exp
))
7509 exp
->error("invalid array operation %s (possible missing [])", exp
->toChars());
7516 if (!target
.isVectorOpSupported(tb
, exp
->op
, exp
->e2
->type
->toBasetype()))
7518 result
= exp
->incompatibleTypes();
7521 if (exp
->checkIntegralBin())
7527 void visit(LogicalExp
*exp
)
7535 setNoderefOperands(exp
);
7537 Expression
*e1x
= expressionSemantic(exp
->e1
, sc
);
7539 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7540 if (e1x
->op
== TOKtype
)
7541 e1x
= resolveAliasThis(sc
, e1x
);
7543 e1x
= resolveProperties(sc
, e1x
);
7544 e1x
= e1x
->toBoolean(sc
);
7545 unsigned cs1
= sc
->callSuper
;
7547 if (sc
->flags
& SCOPEcondition
)
7549 /* If in static if, don't evaluate e2 if we don't have to.
7551 e1x
= e1x
->optimize(WANTvalue
);
7552 if (e1x
->isBool(exp
->op
== TOKoror
))
7554 result
= new IntegerExp(exp
->loc
, exp
->op
== TOKoror
, Type::tbool
);
7559 Expression
*e2x
= expressionSemantic(exp
->e2
, sc
);
7560 sc
->mergeCallSuper(exp
->loc
, cs1
);
7562 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
7563 if (e2x
->op
== TOKtype
)
7564 e2x
= resolveAliasThis(sc
, e2x
);
7566 e2x
= resolveProperties(sc
, e2x
);
7568 bool f1
= checkNonAssignmentArrayOp(e1x
);
7569 bool f2
= checkNonAssignmentArrayOp(e2x
);
7573 // Unless the right operand is 'void', the expression is converted to 'bool'.
7574 if (e2x
->type
->ty
!= Tvoid
)
7575 e2x
= e2x
->toBoolean(sc
);
7577 if (e2x
->op
== TOKtype
|| e2x
->op
== TOKscope
)
7579 exp
->error("%s is not an expression", exp
->e2
->toChars());
7582 if (e1x
->op
== TOKerror
)
7587 if (e2x
->op
== TOKerror
)
7593 // The result type is 'bool', unless the right operand has type 'void'.
7594 if (e2x
->type
->ty
== Tvoid
)
7595 exp
->type
= Type::tvoid
;
7597 exp
->type
= Type::tbool
;
7604 void visit(InExp
*exp
)
7612 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7617 Expression
*e
= exp
->op_overload(sc
);
7624 Type
*t2b
= exp
->e2
->type
->toBasetype();
7629 TypeAArray
*ta
= (TypeAArray
*)t2b
;
7631 // Special handling for array keys
7632 if (!arrayTypeCompatible(exp
->e1
->loc
, exp
->e1
->type
, ta
->index
))
7634 // Convert key to type of key
7635 exp
->e1
= exp
->e1
->implicitCastTo(sc
, ta
->index
);
7638 semanticTypeInfo(sc
, ta
->index
);
7640 // Return type is pointer to value
7641 exp
->type
= ta
->nextOf()->pointerTo();
7646 result
= exp
->incompatibleTypes();
7655 void visit(RemoveExp
*e
)
7657 if (Expression
*ex
= binSemantic(e
, sc
))
7665 void visit(CmpExp
*exp
)
7673 setNoderefOperands(exp
);
7675 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7680 Type
*t1
= exp
->e1
->type
->toBasetype();
7681 Type
*t2
= exp
->e2
->type
->toBasetype();
7682 if ((t1
->ty
== Tclass
&& exp
->e2
->op
== TOKnull
) ||
7683 (t2
->ty
== Tclass
&& exp
->e1
->op
== TOKnull
))
7685 exp
->error("do not use null when comparing class types");
7689 Expression
*e
= exp
->op_overload(sc
);
7692 if (!e
->type
->isscalar() && e
->type
->equals(exp
->e1
->type
))
7694 exp
->error("recursive opCmp expansion");
7697 if (e
->op
== TOKcall
)
7699 e
= new CmpExp(exp
->op
, exp
->loc
, e
, new IntegerExp(exp
->loc
, 0, Type::tint32
));
7700 e
= expressionSemantic(e
, sc
);
7706 if (Expression
*ex
= typeCombine(exp
, sc
))
7712 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7713 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7717 exp
->type
= Type::tbool
;
7719 // Special handling for array comparisons
7720 t1
= exp
->e1
->type
->toBasetype();
7721 t2
= exp
->e2
->type
->toBasetype();
7722 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
|| t1
->ty
== Tpointer
) &&
7723 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
|| t2
->ty
== Tpointer
))
7725 Type
*t1next
= t1
->nextOf();
7726 Type
*t2next
= t2
->nextOf();
7727 if (t1next
->implicitConvTo(t2next
) < MATCHconst
&&
7728 t2next
->implicitConvTo(t1next
) < MATCHconst
&&
7729 (t1next
->ty
!= Tvoid
&& t2next
->ty
!= Tvoid
))
7731 exp
->error("array comparison type mismatch, %s vs %s", t1next
->toChars(), t2next
->toChars());
7734 if ((t1
->ty
== Tarray
|| t1
->ty
== Tsarray
) &&
7735 (t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
7737 semanticTypeInfo(sc
, t1
->nextOf());
7740 else if (t1
->ty
== Tstruct
|| t2
->ty
== Tstruct
||
7741 (t1
->ty
== Tclass
&& t2
->ty
== Tclass
))
7743 if (t2
->ty
== Tstruct
)
7744 exp
->error("need member function opCmp() for %s %s to compare", t2
->toDsymbol(sc
)->kind(), t2
->toChars());
7746 exp
->error("need member function opCmp() for %s %s to compare", t1
->toDsymbol(sc
)->kind(), t1
->toChars());
7749 else if (t1
->iscomplex() || t2
->iscomplex())
7751 exp
->error("compare not defined for complex operands");
7754 else if (t1
->ty
== Taarray
|| t2
->ty
== Taarray
)
7756 exp
->error("%s is not defined for associative arrays", Token::toChars(exp
->op
));
7759 else if (!target
.isVectorOpSupported(t1
, exp
->op
, t2
))
7761 result
= exp
->incompatibleTypes();
7766 bool r1
= exp
->e1
->checkValue();
7767 bool r2
= exp
->e2
->checkValue();
7775 // Refer rel_integral[] table
7776 case TOKunord
: altop
= TOKerror
; break;
7777 case TOKlg
: altop
= TOKnotequal
; break;
7778 case TOKleg
: altop
= TOKerror
; break;
7779 case TOKule
: altop
= TOKle
; break;
7780 case TOKul
: altop
= TOKlt
; break;
7781 case TOKuge
: altop
= TOKge
; break;
7782 case TOKug
: altop
= TOKgt
; break;
7783 case TOKue
: altop
= TOKequal
; break;
7784 default: altop
= TOKreserved
; break;
7786 if (altop
== TOKerror
&&
7787 (t1
->ty
== Tarray
|| t1
->ty
== Tsarray
||
7788 t2
->ty
== Tarray
|| t2
->ty
== Tsarray
))
7790 exp
->error("`%s` is not defined for array comparisons", Token::toChars(exp
->op
));
7793 if (altop
!= TOKreserved
)
7795 if (!t1
->isfloating())
7797 if (altop
== TOKerror
)
7799 const char *s
= exp
->op
== TOKunord
? "false" : "true";
7800 exp
->error("floating point operator `%s` always returns %s for non-floating comparisons",
7801 Token::toChars(exp
->op
), s
);
7805 exp
->error("use `%s` for non-floating comparisons rather than floating point operator `%s`",
7806 Token::toChars(altop
), Token::toChars(exp
->op
));
7811 exp
->error("use std.math.isNaN to deal with NaN operands rather than floating point operator `%s`",
7812 Token::toChars(exp
->op
));
7817 //printf("CmpExp: %s, type = %s\n", e->toChars(), e->type->toChars());
7821 void visit(EqualExp
*exp
)
7823 //printf("EqualExp::semantic('%s')\n", toChars());
7830 setNoderefOperands(exp
);
7832 if (Expression
*e
= binSemanticProp(exp
, sc
))
7837 if (exp
->e1
->op
== TOKtype
|| exp
->e2
->op
== TOKtype
)
7839 result
= exp
->incompatibleTypes();
7844 Type
*t1
= exp
->e1
->type
;
7845 Type
*t2
= exp
->e2
->type
;
7846 if (t1
->ty
== Tenum
&& t2
->ty
== Tenum
&& !t1
->equivalent(t2
))
7847 exp
->deprecation("Comparison between different enumeration types `%s` and `%s`; If this behavior is intended consider using `std.conv.asOriginalType`",
7848 t1
->toChars(), t2
->toChars());
7851 /* Before checking for operator overloading, check to see if we're
7852 * comparing the addresses of two statics. If so, we can just see
7853 * if they are the same symbol.
7855 if (exp
->e1
->op
== TOKaddress
&& exp
->e2
->op
== TOKaddress
)
7857 AddrExp
*ae1
= (AddrExp
*)exp
->e1
;
7858 AddrExp
*ae2
= (AddrExp
*)exp
->e2
;
7859 if (ae1
->e1
->op
== TOKvar
&& ae2
->e1
->op
== TOKvar
)
7861 VarExp
*ve1
= (VarExp
*)ae1
->e1
;
7862 VarExp
*ve2
= (VarExp
*)ae2
->e1
;
7864 if (ve1
->var
== ve2
->var
)
7866 // They are the same, result is 'true' for ==, 'false' for !=
7867 result
= new IntegerExp(exp
->loc
, (exp
->op
== TOKequal
), Type::tbool
);
7873 if (Expression
*e
= exp
->op_overload(sc
))
7879 if (Expression
*e
= typeCombine(exp
, sc
))
7885 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7886 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7890 exp
->type
= Type::tbool
;
7892 // Special handling for array comparisons
7893 if (!arrayTypeCompatible(exp
->loc
, exp
->e1
->type
, exp
->e2
->type
))
7895 if (exp
->e1
->type
!= exp
->e2
->type
&& exp
->e1
->type
->isfloating() && exp
->e2
->type
->isfloating())
7897 // Cast both to complex
7898 exp
->e1
= exp
->e1
->castTo(sc
, Type::tcomplex80
);
7899 exp
->e2
= exp
->e2
->castTo(sc
, Type::tcomplex80
);
7902 if (exp
->e1
->type
->toBasetype()->ty
== Taarray
)
7903 semanticTypeInfo(sc
, exp
->e1
->type
->toBasetype());
7905 Type
*t1
= exp
->e1
->type
->toBasetype();
7906 Type
*t2
= exp
->e2
->type
->toBasetype();
7908 if (!target
.isVectorOpSupported(t1
, exp
->op
, t2
))
7910 result
= exp
->incompatibleTypes();
7917 void visit(IdentityExp
*exp
)
7925 setNoderefOperands(exp
);
7927 if (Expression
*ex
= binSemanticProp(exp
, sc
))
7933 if (Expression
*ex
= typeCombine(exp
, sc
))
7939 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
7940 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
7944 if (exp
->e1
->op
== TOKtype
|| exp
->e2
->op
== TOKtype
)
7946 result
= exp
->incompatibleTypes();
7950 exp
->type
= Type::tbool
;
7952 if (exp
->e1
->type
!= exp
->e2
->type
&& exp
->e1
->type
->isfloating() && exp
->e2
->type
->isfloating())
7954 // Cast both to complex
7955 exp
->e1
= exp
->e1
->castTo(sc
, Type::tcomplex80
);
7956 exp
->e2
= exp
->e2
->castTo(sc
, Type::tcomplex80
);
7959 Type
*tb1
= exp
->e1
->type
->toBasetype();
7960 Type
*tb2
= exp
->e2
->type
->toBasetype();
7961 if (!target
.isVectorOpSupported(tb1
, exp
->op
, tb2
))
7963 result
= exp
->incompatibleTypes();
7970 void visit(CondExp
*exp
)
7978 if (exp
->econd
->op
== TOKdotid
)
7979 ((DotIdExp
*)exp
->econd
)->noderef
= true;
7981 Expression
*ec
= expressionSemantic(exp
->econd
, sc
);
7982 ec
= resolveProperties(sc
, ec
);
7983 ec
= ec
->toBoolean(sc
);
7985 unsigned cs0
= sc
->callSuper
;
7986 unsigned *fi0
= sc
->saveFieldInit();
7987 Expression
*e1x
= expressionSemantic(exp
->e1
, sc
);
7988 e1x
= resolveProperties(sc
, e1x
);
7990 unsigned cs1
= sc
->callSuper
;
7991 unsigned *fi1
= sc
->fieldinit
;
7992 sc
->callSuper
= cs0
;
7993 sc
->fieldinit
= fi0
;
7994 Expression
*e2x
= expressionSemantic(exp
->e2
, sc
);
7995 e2x
= resolveProperties(sc
, e2x
);
7997 sc
->mergeCallSuper(exp
->loc
, cs1
);
7998 sc
->mergeFieldInit(exp
->loc
, fi1
);
8000 if (ec
->op
== TOKerror
)
8005 if (ec
->type
== Type::terror
)
8009 if (e1x
->op
== TOKerror
)
8014 if (e1x
->type
== Type::terror
)
8018 if (e2x
->op
== TOKerror
)
8023 if (e2x
->type
== Type::terror
)
8027 bool f0
= checkNonAssignmentArrayOp(exp
->econd
);
8028 bool f1
= checkNonAssignmentArrayOp(exp
->e1
);
8029 bool f2
= checkNonAssignmentArrayOp(exp
->e2
);
8033 Type
*t1
= exp
->e1
->type
;
8034 Type
*t2
= exp
->e2
->type
;
8035 // If either operand is void the result is void, we have to cast both
8036 // the expression to void so that we explicitly discard the expression
8037 // value if any (bugzilla 16598)
8038 if (t1
->ty
== Tvoid
|| t2
->ty
== Tvoid
)
8040 exp
->type
= Type::tvoid
;
8041 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
);
8042 exp
->e2
= exp
->e2
->castTo(sc
, exp
->type
);
8048 if (Expression
*ex
= typeCombine(exp
, sc
))
8053 switch (exp
->e1
->type
->toBasetype()->ty
)
8058 exp
->e2
= exp
->e2
->castTo(sc
, exp
->e1
->type
);
8061 switch (exp
->e2
->type
->toBasetype()->ty
)
8066 exp
->e1
= exp
->e1
->castTo(sc
, exp
->e2
->type
);
8069 if (exp
->type
->toBasetype()->ty
== Tarray
)
8071 exp
->e1
= exp
->e1
->castTo(sc
, exp
->type
);
8072 exp
->e2
= exp
->e2
->castTo(sc
, exp
->type
);
8075 exp
->type
= exp
->type
->merge2();
8077 /* Bugzilla 14696: If either e1 or e2 contain temporaries which need dtor,
8078 * make them conditional.
8080 * cond ? (__tmp1 = ..., __tmp1) : (__tmp2 = ..., __tmp2)
8082 * (auto __cond = cond) ? (... __tmp1) : (... __tmp2)
8083 * and replace edtors of __tmp1 and __tmp2 with:
8084 * __tmp1->edtor --> __cond && __tmp1.dtor()
8085 * __tmp2->edtor --> __cond || __tmp2.dtor()
8092 void visit(FileInitExp
*e
)
8094 //printf("FileInitExp::semantic()\n");
8095 e
->type
= Type::tstring
;
8099 void visit(LineInitExp
*e
)
8101 e
->type
= Type::tint32
;
8105 void visit(ModuleInitExp
*e
)
8107 //printf("ModuleInitExp::semantic()\n");
8108 e
->type
= Type::tstring
;
8112 void visit(FuncInitExp
*e
)
8114 //printf("FuncInitExp::semantic()\n");
8115 e
->type
= Type::tstring
;
8118 result
= e
->resolveLoc(Loc(), sc
);
8124 void visit(PrettyFuncInitExp
*e
)
8126 //printf("PrettyFuncInitExp::semantic()\n");
8127 e
->type
= Type::tstring
;
8130 result
= e
->resolveLoc(Loc(), sc
);
8137 /**********************************
8138 * Try to run semantic routines.
8139 * If they fail, return NULL.
8141 Expression
*trySemantic(Expression
*exp
, Scope
* sc
)
8143 //printf("+trySemantic(%s)\n", toChars());
8144 unsigned errors
= global
.startGagging();
8145 Expression
*e
= expressionSemantic(exp
, sc
);
8146 if (global
.endGagging(errors
))
8150 //printf("-trySemantic(%s)\n", toChars());
8154 /**************************
8155 * Helper function for easy error propagation.
8156 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8158 Expression
*unaSemantic(UnaExp
*e
, Scope
*sc
)
8160 Expression
*e1x
= expressionSemantic(e
->e1
, sc
);
8161 if (e1x
->op
== TOKerror
)
8167 /**************************
8168 * Helper function for easy error propagation.
8169 * If error occurs, returns ErrorExp. Otherwise returns NULL.
8171 Expression
*binSemantic(BinExp
*e
, Scope
*sc
)
8173 Expression
*e1x
= expressionSemantic(e
->e1
, sc
);
8174 Expression
*e2x
= expressionSemantic(e
->e2
, sc
);
8176 // for static alias this: https://issues.dlang.org/show_bug.cgi?id=17684
8177 if (e1x
->op
== TOKtype
)
8178 e1x
= resolveAliasThis(sc
, e1x
);
8179 if (e2x
->op
== TOKtype
)
8180 e2x
= resolveAliasThis(sc
, e2x
);
8182 if (e1x
->op
== TOKerror
)
8184 if (e2x
->op
== TOKerror
)
8191 Expression
*binSemanticProp(BinExp
*e
, Scope
*sc
)
8193 if (Expression
*ex
= binSemantic(e
, sc
))
8195 Expression
*e1x
= resolveProperties(sc
, e
->e1
);
8196 Expression
*e2x
= resolveProperties(sc
, e
->e2
);
8197 if (e1x
->op
== TOKerror
)
8199 if (e2x
->op
== TOKerror
)
8206 // entrypoint for semantic ExpressionSemanticVisitor
8207 Expression
*expressionSemantic(Expression
*e
, Scope
*sc
)
8209 ExpressionSemanticVisitor v
= ExpressionSemanticVisitor(sc
);
8214 Expression
*semanticX(DotIdExp
*exp
, Scope
*sc
)
8216 //printf("DotIdExp::semanticX(this = %p, '%s')\n", this, toChars());
8217 if (Expression
*ex
= unaSemantic(exp
, sc
))
8220 if (exp
->ident
== Id::_mangleof
)
8224 switch (exp
->e1
->op
)
8227 ds
= ((ScopeExp
*)exp
->e1
)->sds
;
8230 ds
= ((VarExp
*)exp
->e1
)->var
;
8233 ds
= ((DotVarExp
*)exp
->e1
)->var
;
8235 case TOKoverloadset
:
8236 ds
= ((OverExp
*)exp
->e1
)->vars
;
8240 TemplateExp
*te
= (TemplateExp
*)exp
->e1
;
8241 ds
= te
->fd
? (Dsymbol
*)te
->fd
: te
->td
;
8246 if (FuncDeclaration
*f
= ds
->isFuncDeclaration())
8248 if (f
->checkForwardRef(exp
->loc
))
8249 return new ErrorExp();
8252 mangleToBuffer(ds
, &buf
);
8253 const char *s
= buf
.extractChars();
8254 Expression
*e
= new StringExp(exp
->loc
, const_cast<char*>(s
), strlen(s
));
8255 e
= expressionSemantic(e
, sc
);
8263 if (exp
->e1
->op
== TOKvar
&& exp
->e1
->type
->toBasetype()->ty
== Tsarray
&& exp
->ident
== Id::length
)
8265 // bypass checkPurity
8266 return exp
->e1
->type
->dotExp(sc
, exp
->e1
, exp
->ident
, exp
->noderef
? 2 : 0);
8269 if (exp
->e1
->op
== TOKdot
)
8274 exp
->e1
= resolvePropertiesX(sc
, exp
->e1
);
8276 if (exp
->e1
->op
== TOKtuple
&& exp
->ident
== Id::offsetof
)
8278 /* 'distribute' the .offsetof to each of the tuple elements.
8280 TupleExp
*te
= (TupleExp
*)exp
->e1
;
8281 Expressions
*exps
= new Expressions();
8282 exps
->setDim(te
->exps
->length
);
8283 for (size_t i
= 0; i
< exps
->length
; i
++)
8285 Expression
*e
= (*te
->exps
)[i
];
8286 e
= expressionSemantic(e
, sc
);
8287 e
= new DotIdExp(e
->loc
, e
, Id::offsetof
);
8290 // Don't evaluate te->e0 in runtime
8291 Expression
*e
= new TupleExp(exp
->loc
, NULL
, exps
);
8292 e
= expressionSemantic(e
, sc
);
8295 if (exp
->e1
->op
== TOKtuple
&& exp
->ident
== Id::length
)
8297 TupleExp
*te
= (TupleExp
*)exp
->e1
;
8298 // Don't evaluate te->e0 in runtime
8299 Expression
*e
= new IntegerExp(exp
->loc
, te
->exps
->length
, Type::tsize_t
);
8303 // Bugzilla 14416: Template has no built-in properties except for 'stringof'.
8304 if ((exp
->e1
->op
== TOKdottd
|| exp
->e1
->op
== TOKtemplate
) && exp
->ident
!= Id::stringof
)
8306 exp
->error("template %s does not have property `%s`", exp
->e1
->toChars(), exp
->ident
->toChars());
8307 return new ErrorExp();
8312 exp
->error("expression %s does not have property `%s`", exp
->e1
->toChars(), exp
->ident
->toChars());
8313 return new ErrorExp();
8319 // Resolve e1.ident without seeing UFCS.
8320 // If flag == 1, stop "not a property" error and return NULL.
8321 Expression
*semanticY(DotIdExp
*exp
, Scope
*sc
, int flag
)
8323 //printf("DotIdExp::semanticY(this = %p, '%s')\n", this, toChars());
8325 //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; }
8327 /* Special case: rewrite this.id and super.id
8328 * to be classtype.id and baseclasstype.id
8329 * if we have no this pointer.
8331 if ((exp
->e1
->op
== TOKthis
|| exp
->e1
->op
== TOKsuper
) && !hasThis(sc
))
8333 if (AggregateDeclaration
*ad
= sc
->getStructClassScope())
8335 if (exp
->e1
->op
== TOKthis
)
8337 exp
->e1
= new TypeExp(exp
->e1
->loc
, ad
->type
);
8341 ClassDeclaration
*cd
= ad
->isClassDeclaration();
8342 if (cd
&& cd
->baseClass
)
8343 exp
->e1
= new TypeExp(exp
->e1
->loc
, cd
->baseClass
->type
);
8348 Expression
*e
= semanticX(exp
, sc
);
8354 if (exp
->e1
->op
== TOKdot
)
8356 DotExp
*de
= (DotExp
*)exp
->e1
;
8366 Type
*t1b
= exp
->e1
->type
->toBasetype();
8368 if (eright
->op
== TOKscope
) // also used for template alias's
8370 ScopeExp
*ie
= (ScopeExp
*)eright
;
8371 int flags
= SearchLocalsOnly
;
8373 /* Disable access to another module's private imports.
8374 * The check for 'is sds our current module' is because
8375 * the current module should have access to its own imports.
8377 if (ie
->sds
->isModule() && ie
->sds
!= sc
->_module
)
8378 flags
|= IgnorePrivateImports
;
8379 if (sc
->flags
& SCOPEignoresymbolvisibility
)
8380 flags
|= IgnoreSymbolVisibility
;
8381 Dsymbol
*s
= ie
->sds
->search(exp
->loc
, exp
->ident
, flags
);
8382 /* Check for visibility before resolving aliases because public
8383 * aliases to private symbols are public.
8385 if (s
&& !(sc
->flags
& SCOPEignoresymbolvisibility
) && !symbolIsVisible(sc
->_module
, s
))
8391 Package
*p
= s
->isPackage();
8392 if (p
&& checkAccess(sc
, p
))
8399 // if 's' is a tuple variable, the tuple is returned.
8402 exp
->checkDeprecated(sc
, s
);
8403 exp
->checkDisabled(sc
, s
);
8405 EnumMember
*em
= s
->isEnumMember();
8408 return em
->getVarExp(exp
->loc
, sc
);
8411 VarDeclaration
*v
= s
->isVarDeclaration();
8414 //printf("DotIdExp:: Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
8416 (!v
->type
->deco
&& v
->inuse
))
8419 exp
->error("circular reference to %s `%s`", v
->kind(), v
->toPrettyChars());
8421 exp
->error("forward reference to %s `%s`", v
->kind(), v
->toPrettyChars());
8422 return new ErrorExp();
8424 if (v
->type
->ty
== Terror
)
8425 return new ErrorExp();
8427 if ((v
->storage_class
& STCmanifest
) && v
->_init
&& !exp
->wantsym
)
8429 /* Normally, the replacement of a symbol with its initializer is supposed to be in semantic2().
8430 * Introduced by https://github.com/dlang/dmd/pull/5588 which should probably
8431 * be reverted. `wantsym` is the hack to work around the problem.
8435 ::error(exp
->loc
, "circular initialization of %s `%s`", v
->kind(), v
->toPrettyChars());
8436 return new ErrorExp();
8438 e
= v
->expandInitializer(exp
->loc
);
8440 e
= expressionSemantic(e
, sc
);
8448 eleft
= new ThisExp(exp
->loc
);
8449 e
= new DotVarExp(exp
->loc
, eleft
, v
);
8450 e
= expressionSemantic(e
, sc
);
8454 e
= new VarExp(exp
->loc
, v
);
8456 { e
= new CommaExp(exp
->loc
, eleft
, e
);
8461 return expressionSemantic(e
, sc
);
8464 FuncDeclaration
*f
= s
->isFuncDeclaration();
8467 //printf("it's a function\n");
8468 if (!f
->functionSemantic())
8469 return new ErrorExp();
8473 eleft
= new ThisExp(exp
->loc
);
8474 e
= new DotVarExp(exp
->loc
, eleft
, f
, true);
8475 e
= expressionSemantic(e
, sc
);
8479 e
= new VarExp(exp
->loc
, f
, true);
8481 { e
= new CommaExp(exp
->loc
, eleft
, e
);
8487 if (TemplateDeclaration
*td
= s
->isTemplateDeclaration())
8490 e
= new DotTemplateExp(exp
->loc
, eleft
, td
);
8492 e
= new TemplateExp(exp
->loc
, td
);
8493 e
= expressionSemantic(e
, sc
);
8496 if (OverDeclaration
*od
= s
->isOverDeclaration())
8498 e
= new VarExp(exp
->loc
, od
, true);
8501 e
= new CommaExp(exp
->loc
, eleft
, e
);
8502 e
->type
= Type::tvoid
; // ambiguous type?
8506 OverloadSet
*o
= s
->isOverloadSet();
8508 { //printf("'%s' is an overload set\n", o->toChars());
8509 return new OverExp(exp
->loc
, o
);
8512 if (Type
*t
= s
->getType())
8514 return expressionSemantic(new TypeExp(exp
->loc
, t
), sc
);
8517 TupleDeclaration
*tup
= s
->isTupleDeclaration();
8522 e
= new DotVarExp(exp
->loc
, eleft
, tup
);
8523 e
= expressionSemantic(e
, sc
);
8526 e
= new TupleExp(exp
->loc
, tup
);
8527 e
= expressionSemantic(e
, sc
);
8531 ScopeDsymbol
*sds
= s
->isScopeDsymbol();
8534 //printf("it's a ScopeDsymbol %s\n", exp->ident->toChars());
8535 e
= new ScopeExp(exp
->loc
, sds
);
8536 e
= expressionSemantic(e
, sc
);
8538 e
= new DotExp(exp
->loc
, eleft
, e
);
8542 Import
*imp
= s
->isImport();
8545 ie
= new ScopeExp(exp
->loc
, imp
->pkg
);
8546 return expressionSemantic(ie
, sc
);
8549 // BUG: handle other cases like in IdentifierExp::semantic()
8552 else if (exp
->ident
== Id::stringof
)
8554 const char *p
= ie
->toChars();
8555 e
= new StringExp(exp
->loc
, const_cast<char *>(p
), strlen(p
));
8556 e
= expressionSemantic(e
, sc
);
8559 if (ie
->sds
->isPackage() ||
8560 ie
->sds
->isImport() ||
8561 ie
->sds
->isModule())
8567 s
= ie
->sds
->search_correct(exp
->ident
);
8571 exp
->error("undefined identifier `%s` in %s `%s`, perhaps add `static import %s;`",
8572 exp
->ident
->toChars(), ie
->sds
->kind(), ie
->sds
->toPrettyChars(), s
->toPrettyChars());
8574 exp
->error("undefined identifier `%s` in %s `%s`, did you mean %s `%s`?",
8575 exp
->ident
->toChars(), ie
->sds
->kind(), ie
->sds
->toPrettyChars(), s
->kind(), s
->toChars());
8578 exp
->error("undefined identifier `%s` in %s `%s`",
8579 exp
->ident
->toChars(), ie
->sds
->kind(), ie
->sds
->toPrettyChars());
8580 return new ErrorExp();
8582 else if (t1b
->ty
== Tpointer
&& exp
->e1
->type
->ty
!= Tenum
&&
8583 exp
->ident
!= Id::_init
&& exp
->ident
!= Id::__sizeof
&&
8584 exp
->ident
!= Id::__xalignof
&& exp
->ident
!= Id::offsetof
&&
8585 exp
->ident
!= Id::_mangleof
&& exp
->ident
!= Id::stringof
)
8587 Type
*t1bn
= t1b
->nextOf();
8590 AggregateDeclaration
*ad
= isAggregate(t1bn
);
8591 if (ad
&& !ad
->members
) // Bugzilla 11312
8600 if (flag
&& t1bn
->ty
== Tvoid
)
8602 e
= new PtrExp(exp
->loc
, exp
->e1
);
8603 e
= expressionSemantic(e
, sc
);
8604 return e
->type
->dotExp(sc
, e
, exp
->ident
, flag
| (exp
->noderef
? 2 : 0));
8608 if (exp
->e1
->op
== TOKtype
|| exp
->e1
->op
== TOKtemplate
)
8610 e
= exp
->e1
->type
->dotExp(sc
, exp
->e1
, exp
->ident
, flag
| (exp
->noderef
? 2 : 0));
8612 e
= expressionSemantic(e
, sc
);
8617 // Resolve e1.ident!tiargs without seeing UFCS.
8618 // If flag == 1, stop "not a property" error and return NULL.
8619 Expression
*semanticY(DotTemplateInstanceExp
*exp
, Scope
*sc
, int flag
)
8621 DotIdExp
*die
= new DotIdExp(exp
->loc
, exp
->e1
, exp
->ti
->name
);
8623 Expression
*e
= semanticX(die
, sc
);
8626 exp
->e1
= die
->e1
; // take back
8628 Type
*t1b
= exp
->e1
->type
->toBasetype();
8629 if (t1b
->ty
== Tarray
|| t1b
->ty
== Tsarray
|| t1b
->ty
== Taarray
||
8630 t1b
->ty
== Tnull
|| (t1b
->isTypeBasic() && t1b
->ty
!= Tvoid
))
8632 /* No built-in type has templatized properties, so do shortcut.
8633 * It is necessary in: 1024.max!"a < b"
8638 e
= semanticY(die
, sc
, flag
);
8639 if (flag
&& e
&& isDotOpDispatch(e
))
8641 /* opDispatch!tiargs would be a function template that needs IFTI,
8642 * so it's not a template
8644 e
= NULL
; /* fall down to UFCS */
8651 if (e
->op
== TOKerror
)
8653 if (e
->op
== TOKdotvar
)
8655 DotVarExp
*dve
= (DotVarExp
*)e
;
8656 if (FuncDeclaration
*fd
= dve
->var
->isFuncDeclaration())
8658 TemplateDeclaration
*td
= fd
->findTemplateDeclRoot();
8661 e
= new DotTemplateExp(dve
->loc
, dve
->e1
, td
);
8662 e
= expressionSemantic(e
, sc
);
8665 else if (dve
->var
->isOverDeclaration())
8667 exp
->e1
= dve
->e1
; // pull semantic() result
8668 if (!exp
->findTempDecl(sc
))
8670 if (exp
->ti
->needsTypeInference(sc
))
8672 dsymbolSemantic(exp
->ti
, sc
);
8673 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8674 return new ErrorExp();
8675 Dsymbol
*s
= exp
->ti
->toAlias();
8676 Declaration
*v
= s
->isDeclaration();
8679 if (v
->type
&& !v
->type
->deco
)
8680 v
->type
= typeSemantic(v
->type
, v
->loc
, sc
);
8681 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8682 e
= expressionSemantic(e
, sc
);
8685 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8686 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8687 e
= expressionSemantic(e
, sc
);
8691 else if (e
->op
== TOKvar
)
8693 VarExp
*ve
= (VarExp
*)e
;
8694 if (FuncDeclaration
*fd
= ve
->var
->isFuncDeclaration())
8696 TemplateDeclaration
*td
= fd
->findTemplateDeclRoot();
8699 e
= new TemplateExp(ve
->loc
, td
);
8700 e
= expressionSemantic(e
, sc
);
8703 else if (OverDeclaration
*od
= ve
->var
->isOverDeclaration())
8705 exp
->ti
->tempdecl
= od
;
8706 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8707 e
= expressionSemantic(e
, sc
);
8711 if (e
->op
== TOKdottd
)
8713 DotTemplateExp
*dte
= (DotTemplateExp
*)e
;
8714 exp
->e1
= dte
->e1
; // pull semantic() result
8716 exp
->ti
->tempdecl
= dte
->td
;
8717 if (!exp
->ti
->semanticTiargs(sc
))
8718 return new ErrorExp();
8719 if (exp
->ti
->needsTypeInference(sc
))
8721 dsymbolSemantic(exp
->ti
, sc
);
8722 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8723 return new ErrorExp();
8724 Dsymbol
*s
= exp
->ti
->toAlias();
8725 Declaration
*v
= s
->isDeclaration();
8726 if (v
&& (v
->isFuncDeclaration() || v
->isVarDeclaration()))
8728 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8729 e
= expressionSemantic(e
, sc
);
8732 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8733 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8734 e
= expressionSemantic(e
, sc
);
8737 else if (e
->op
== TOKtemplate
)
8739 exp
->ti
->tempdecl
= ((TemplateExp
*)e
)->td
;
8740 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8741 e
= expressionSemantic(e
, sc
);
8744 else if (e
->op
== TOKdot
)
8746 DotExp
*de
= (DotExp
*)e
;
8748 if (de
->e2
->op
== TOKoverloadset
)
8750 if (!exp
->findTempDecl(sc
) ||
8751 !exp
->ti
->semanticTiargs(sc
))
8753 return new ErrorExp();
8755 if (exp
->ti
->needsTypeInference(sc
))
8757 dsymbolSemantic(exp
->ti
, sc
);
8758 if (!exp
->ti
->inst
|| exp
->ti
->errors
) // if template failed to expand
8759 return new ErrorExp();
8760 Dsymbol
*s
= exp
->ti
->toAlias();
8761 Declaration
*v
= s
->isDeclaration();
8764 if (v
->type
&& !v
->type
->deco
)
8765 v
->type
= typeSemantic(v
->type
, v
->loc
, sc
);
8766 e
= new DotVarExp(exp
->loc
, exp
->e1
, v
);
8767 e
= expressionSemantic(e
, sc
);
8770 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8771 e
= new DotExp(exp
->loc
, exp
->e1
, e
);
8772 e
= expressionSemantic(e
, sc
);
8776 else if (e
->op
== TOKoverloadset
)
8778 OverExp
*oe
= (OverExp
*)e
;
8779 exp
->ti
->tempdecl
= oe
->vars
;
8780 e
= new ScopeExp(exp
->loc
, exp
->ti
);
8781 e
= expressionSemantic(e
, sc
);
8785 e
->error("%s isn't a template", e
->toChars());
8786 return new ErrorExp();