/* Compiler implementation of the D programming language
- * Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved
+ * Copyright (C) 1999-2024 by The D Language Foundation, All Rights Reserved
* written by Walter Bright
* https://www.digitalmars.com
* Distributed under the Boost Software License, Version 1.0.
class ClassDeclaration;
class OverloadSet;
class StringExp;
+class InterpExp;
class LoweredAssignExp;
-struct UnionExp;
#ifdef IN_GCC
typedef union tree_node Symbol;
#else
struct Symbol; // back end symbol
#endif
-void expandTuples(Expressions *exps, Identifiers *names = nullptr);
-bool isTrivialExp(Expression *e);
-bool hasSideEffect(Expression *e, bool assumeImpureCalls = false);
+namespace dmd
+{
+ // in expressionsem.d
+ Expression *expressionSemantic(Expression *e, Scope *sc);
+ // in typesem.d
+ Expression *defaultInit(Type *mt, const Loc &loc, const bool isCfile = false);
-enum BE : int32_t;
-BE canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
+ // Entry point for CTFE.
+ // A compile-time result is required. Give an error if not possible
+ Expression *ctfeInterpret(Expression *e);
+ void expandTuples(Expressions *exps, Identifiers *names = nullptr);
+ Expression *optimize(Expression *exp, int result, bool keepLvalue = false);
+}
typedef unsigned char OwnedBy;
enum
Type *type; // !=NULL means that semantic() has been run
Loc loc; // file location
EXP op; // to minimize use of dynamic_cast
+ d_bool parens; // if this is a parenthesized expression
size_t size() const;
static void _init();
- Expression *copy();
virtual Expression *syntaxCopy();
// kludge for template.isExpression()
DYNCAST dyncast() const override final { return DYNCAST_EXPRESSION; }
const char *toChars() const override;
- void error(const char *format, ...) const;
- void warning(const char *format, ...) const;
- void deprecation(const char *format, ...) const;
virtual dinteger_t toInteger();
virtual uinteger_t toUInteger();
virtual complex_t toComplex();
virtual StringExp *toStringExp();
virtual bool isLvalue();
- virtual Expression *toLvalue(Scope *sc, Expression *e);
- virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
- Expression *implicitCastTo(Scope *sc, Type *t);
- MATCH implicitConvTo(Type *t);
- Expression *castTo(Scope *sc, Type *t);
- virtual Expression *resolveLoc(const Loc &loc, Scope *sc);
virtual bool checkType();
virtual bool checkValue();
- bool checkDeprecated(Scope *sc, Dsymbol *s);
- virtual Expression *addDtorHook(Scope *sc);
Expression *addressOf();
Expression *deref();
- Expression *optimize(int result, bool keepLvalue = false);
-
- // Entry point for CTFE.
- // A compile-time result is required. Give an error if not possible
- Expression *ctfeInterpret();
int isConst();
virtual bool isIdentical(const Expression *e) const;
virtual Optional<bool> toBool();
SuperExp* isSuperExp();
NullExp* isNullExp();
StringExp* isStringExp();
+ InterpExp* isInterpExp();
TupleExp* isTupleExp();
ArrayLiteralExp* isArrayLiteralExp();
AssocArrayLiteralExp* isAssocArrayLiteralExp();
dinteger_t value;
static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type);
- static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type);
bool equals(const RootObject * const o) const override;
dinteger_t toInteger() override;
real_t toReal() override;
real_t toImaginary() override;
complex_t toComplex() override;
Optional<bool> toBool() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
dinteger_t getInteger() { return value; }
- void setInteger(dinteger_t value);
template<int v>
static IntegerExp literal();
};
class ErrorExp final : public Expression
{
public:
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
static ErrorExp *errorexp; // handy shared value
real_t value;
static RealExp *create(const Loc &loc, real_t value, Type *type);
- static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type);
bool equals(const RootObject * const o) const override;
bool isIdentical(const Expression *e) const override;
dinteger_t toInteger() override;
complex_t value;
static ComplexExp *create(const Loc &loc, complex_t value, Type *type);
- static void emplace(UnionExp *pue, const Loc &loc, complex_t value, Type *type);
bool equals(const RootObject * const o) const override;
bool isIdentical(const Expression *e) const override;
dinteger_t toInteger() override;
{
public:
Identifier *ident;
- d_bool parens;
static IdentifierExp *create(const Loc &loc, Identifier *ident);
bool isLvalue() override final;
- Expression *toLvalue(Scope *sc, Expression *e) override final;
void accept(Visitor *v) override { v->visit(this); }
};
DsymbolExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
ThisExp *syntaxCopy() override;
Optional<bool> toBool() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
class SuperExp final : public ThisExp
{
public:
- bool isLvalue() override;
- Expression* toLvalue(Scope* sc, Expression* e) final override;
void accept(Visitor *v) override { v->visit(this); }
};
public:
utf8_t postfix; // 'c', 'w', 'd'
OwnedBy ownedByCtfe;
- void *string; // char, wchar, or dchar data
+ void *string; // char, wchar, dchar, or long data
size_t len; // number of chars, wchars, or dchars
unsigned char sz; // 1: char, 2: wchar, 4: dchar
- bool committed; // if type is committed
+ d_bool committed; // if type is committed
+ d_bool hexString; // if string is parsed from a hex string literal
static StringExp *create(const Loc &loc, const char *s);
static StringExp *create(const Loc &loc, const void *s, d_size_t len);
- static void emplace(UnionExp *pue, const Loc &loc, const char *s);
bool equals(const RootObject * const o) const override;
char32_t getCodeUnit(d_size_t i) const;
- void setCodeUnit(d_size_t i, char32_t c);
+ dinteger_t getIndex(d_size_t i) const;
StringExp *toStringExp() override;
- StringExp *toUTF8(Scope *sc);
Optional<bool> toBool() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
size_t numberOfCodeUnits(int tynto = 0) const;
void writeTo(void* dest, bool zero, int tyto = 0) const;
};
+class InterpExp final : public Expression
+{
+public:
+ utf8_t postfix; // 'c', 'w', 'd'
+ OwnedBy ownedByCtfe;
+ void* interpolatedSet;
+
+ void accept(Visitor* v) override { v->visit(this); }
+};
+
// Tuple
class TupleExp final : public Expression
Expressions *elements;
static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
- static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
ArrayLiteralExp *syntaxCopy() override;
bool equals(const RootObject * const o) const override;
- Expression *getElement(d_size_t i); // use opIndex instead
- Expression *opIndex(d_size_t i);
+ Expression *getElement(d_size_t i);
Optional<bool> toBool() override;
StringExp *toStringExp() override;
OwnedBy ownedByCtfe;
Expressions *keys;
Expressions *values;
+ Expression* lowering;
bool equals(const RootObject * const o) const override;
AssocArrayLiteralExp *syntaxCopy() override;
union
{
- Symbol *sym; // back end symbol to initialize with literal
+ Symbol *sym; // back end symbol to initialize with literal (used as a Symbol*)
// those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
StructLiteralExp *inlinecopy;
static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
bool equals(const RootObject * const o) const override;
StructLiteralExp *syntaxCopy() override;
- Expression *getField(Type *type, unsigned offset);
- int getFieldIndex(Type *type, unsigned offset);
- Expression *addDtorHook(Scope *sc) override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
FuncDeclaration *fd;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
bool checkType() override;
bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
bool equals(const RootObject * const o) const override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
OverloadSet *vars;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
Expression *e1;
UnaExp *syntaxCopy() override;
- Expression *incompatibleTypes();
- Expression *resolveLoc(const Loc &loc, Scope *sc) override final;
void accept(Visitor *v) override { v->visit(this); }
};
Type *att2; // Save alias this type to detect recursion
BinExp *syntaxCopy() override;
- Expression *incompatibleTypes();
-
- Expression *reorderSettingAAElem(Scope *sc);
void accept(Visitor *v) override { v->visit(this); }
};
{
public:
bool isLvalue() override final;
- Expression *toLvalue(Scope *sc, Expression *ex) override final;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override final;
void accept(Visitor *v) override { v->visit(this); }
};
d_bool hasOverloads;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
TemplateInstance *ti;
DotTemplateInstanceExp *syntaxCopy() override;
- bool findTempDecl(Scope *sc);
bool checkType() override;
bool checkValue() override;
void accept(Visitor *v) override { v->visit(this); }
CallExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *addDtorHook(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
CastExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
OwnedBy ownedByCtfe;
static VectorExp *create(const Loc &loc, Expression *e, Type *t);
- static void emplace(UnionExp *pue, const Loc &loc, Expression *e, Type *t);
VectorExp *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
};
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
private:
uint8_t bitFields;
+public:
SliceExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
Optional<bool> toBool() override;
void accept(Visitor *v) override { v->visit(this); }
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
{
public:
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
ArrayExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
d_bool isGenerated;
d_bool allowCommaExp;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
Optional<bool> toBool() override;
- Expression *addDtorHook(Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
IndexExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
void accept(Visitor *v) override { v->visit(this); }
};
MemorySet memset;
bool isLvalue() override final;
- Expression *toLvalue(Scope *sc, Expression *ex) override final;
void accept(Visitor *v) override { v->visit(this); }
};
class CatAssignExp : public BinAssignExp
{
public:
+ Expression *lowering; // lowered druntime hook `_d_arrayappend{cTX,T}`
+
void accept(Visitor *v) override { v->visit(this); }
};
CondExp *syntaxCopy() override;
bool isLvalue() override;
- Expression *toLvalue(Scope *sc, Expression *e) override;
- Expression *modifiableLvalue(Scope *sc, Expression *e) override;
- void hookDtors(Scope *sc);
void accept(Visitor *v) override { v->visit(this); }
};
class FileInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class LineInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class ModuleInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class FuncInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
class PrettyFuncInitExp final : public DefaultInitExp
{
public:
- Expression *resolveLoc(const Loc &loc, Scope *sc) override;
void accept(Visitor *v) override { v->visit(this); }
};
/****************************************************************/
-/* A type meant as a union of all the Expression types,
- * to serve essentially as a Variant that will sit on the stack
- * during CTFE to reduce memory consumption.
- */
-struct UnionExp
-{
- UnionExp() { } // yes, default constructor does nothing
-
- UnionExp(Expression *e)
- {
- memcpy(this, (void *)e, e->size());
- }
-
- /* Extract pointer to Expression
- */
- Expression *exp() { return (Expression *)&u; }
-
- /* Convert to an allocated Expression
- */
- Expression *copy();
-
-private:
- // Ensure that the union is suitably aligned.
-#if defined(__GNUC__) || defined(__clang__)
- __attribute__((aligned(8)))
-#elif defined(_MSC_VER)
- __declspec(align(8))
-#elif defined(__DMC__)
- #pragma pack(8)
-#endif
- union
- {
- char exp [sizeof(Expression)];
- char integerexp[sizeof(IntegerExp)];
- char errorexp [sizeof(ErrorExp)];
- char realexp [sizeof(RealExp)];
- char complexexp[sizeof(ComplexExp)];
- char symoffexp [sizeof(SymOffExp)];
- char stringexp [sizeof(StringExp)];
- char arrayliteralexp [sizeof(ArrayLiteralExp)];
- char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
- char structliteralexp [sizeof(StructLiteralExp)];
- char nullexp [sizeof(NullExp)];
- char dotvarexp [sizeof(DotVarExp)];
- char addrexp [sizeof(AddrExp)];
- char indexexp [sizeof(IndexExp)];
- char sliceexp [sizeof(SliceExp)];
- char vectorexp [sizeof(VectorExp)];
- } u;
-#if defined(__DMC__)
- #pragma pack()
-#endif
-};
-
-/****************************************************************/
-
class ObjcClassReferenceExp final : public Expression
{
public: