From c5e94699efa816444c0ae49ad55d0e01a48203df Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Mon, 4 Jan 2021 19:05:38 +0100 Subject: d: Merge upstream dmd a5c86f5b9 Adds the following new `__traits' to the D language. - isDeprecated: used to detect if a function is deprecated. - isDisabled: used to detect if a function is marked with @disable. - isFuture: used to detect if a function is marked with @__future. - isModule: used to detect if a given symbol represents a module, this enhancement also adds support using `is(sym == module)'. - isPackage: used to detect if a given symbol represents a package, this enhancement also adds support using `is(sym == package)'. - child: takes two arguments. The first must be a symbol or expression and the second must be a symbol, such as an alias to a member of the first 'parent' argument. The result is the second 'member' argument interpreted with its 'this' context set to 'parent'. This is the inverse of `__traits(parent, member)'. - isReturnOnStack: determines if a function's return value is placed on the stack, or is returned via registers. - isZeroInit: used to detect if a type's default initializer has no non-zero bits. - getTargetInfo: used to query features of the target being compiled for, the back-end can expand this to register any key to handle the given argument, however a reliable subset exists which includes "cppRuntimeLibrary", "cppStd", "floatAbi", and "objectFormat". - getLocation: returns a tuple whose entries correspond to the filename, line number, and column number of where the argument was declared. - hasPostblit: used to detect if a type is a struct with a postblit. - isCopyable: used to detect if a type allows copying its value. - getVisibility: an alias for the getProtection trait. Reviewed-on: https://github.com/dlang/dmd/pull/12093 gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd a5c86f5b9. * d-builtins.cc (d_eval_constant_expression): Handle ADDR_EXPR trees created by build_string_literal. * d-frontend.cc (retStyle): Remove function. * d-target.cc (d_language_target_info): New variable. (d_target_info_table): Likewise. (Target::_init): Initialize d_target_info_table. (Target::isReturnOnStack): New function. (d_add_target_info_handlers): Likewise. (d_handle_target_cpp_std): Likewise. (d_handle_target_cpp_runtime_library): Likewise. (Target::getTargetInfo): Likewise. * d-target.h (struct d_target_info_spec): New type. (d_add_target_info_handlers): Declare. --- gcc/d/dmd/expressionsem.c | 67 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 9 deletions(-) (limited to 'gcc/d/dmd/expressionsem.c') diff --git a/gcc/d/dmd/expressionsem.c b/gcc/d/dmd/expressionsem.c index d251996..7dfe995 100644 --- a/gcc/d/dmd/expressionsem.c +++ b/gcc/d/dmd/expressionsem.c @@ -119,6 +119,36 @@ static bool preFunctionParameters(Scope *sc, Expressions *exps) return err; } +/** + * Determines whether a symbol represents a module or package + * (Used as a helper for is(type == module) and is(type == package)) + * + * Params: + * sym = the symbol to be checked + * + * Returns: + * the symbol which `sym` represents (or `null` if it doesn't represent a `Package`) + */ +Package *resolveIsPackage(Dsymbol *sym) +{ + Package *pkg; + if (Import *imp = sym->isImport()) + { + if (imp->pkg == NULL) + { + error(sym->loc, "Internal Compiler Error: unable to process forward-referenced import `%s`", + imp->toChars()); + assert(0); + } + pkg = imp->pkg; + } + else + pkg = sym->isPackage(); + if (pkg) + pkg->resolvePKGunknown(); + return pkg; +} + class ExpressionSemanticVisitor : public Visitor { public: @@ -1920,15 +1950,34 @@ public: } Type *tded = NULL; - Scope *sc2 = sc->copy(); // keep sc->flags - sc2->tinst = NULL; - sc2->minst = NULL; - sc2->flags |= SCOPEfullinst; - Type *t = e->targ->trySemantic(e->loc, sc2); - sc2->pop(); - if (!t) - goto Lno; // errors, so condition is false - e->targ = t; + if (e->tok2 == TOKpackage || e->tok2 == TOKmodule) // These is() expressions are special because they can work on modules, not just types. + { + Dsymbol *sym = e->targ->toDsymbol(sc); + if (sym == NULL) + goto Lno; + Package *p = resolveIsPackage(sym); + if (p == NULL) + goto Lno; + if (e->tok2 == TOKpackage && p->isModule()) // Note that isModule() will return null for package modules because they're not actually instances of Module. + goto Lno; + else if(e->tok2 == TOKmodule && !(p->isModule() || p->isPackageMod())) + goto Lno; + tded = e->targ; + goto Lyes; + } + + { + Scope *sc2 = sc->copy(); // keep sc->flags + sc2->tinst = NULL; + sc2->minst = NULL; + sc2->flags |= SCOPEfullinst; + Type *t = e->targ->trySemantic(e->loc, sc2); + sc2->pop(); + if (!t) // errors, so condition is false + goto Lno; + e->targ = t; + } + if (e->tok2 != TOKreserved) { switch (e->tok2) -- cgit v1.1