diff options
author | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-01-04 19:05:38 +0100 |
---|---|---|
committer | Iain Buclaw <ibuclaw@gdcproject.org> | 2021-01-05 22:09:10 +0100 |
commit | c5e94699efa816444c0ae49ad55d0e01a48203df (patch) | |
tree | f527fd1748c2f034d74ca1b268d4f56fc36cf050 /gcc/d/dmd/expressionsem.c | |
parent | ae1ada95fee1ee4fac0dec0486076d9787988a03 (diff) | |
download | gcc-c5e94699efa816444c0ae49ad55d0e01a48203df.zip gcc-c5e94699efa816444c0ae49ad55d0e01a48203df.tar.gz gcc-c5e94699efa816444c0ae49ad55d0e01a48203df.tar.bz2 |
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.
Diffstat (limited to 'gcc/d/dmd/expressionsem.c')
-rw-r--r-- | gcc/d/dmd/expressionsem.c | 67 |
1 files changed, 58 insertions, 9 deletions
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) |