aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd/expressionsem.c
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2021-01-04 19:05:38 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2021-01-05 22:09:10 +0100
commitc5e94699efa816444c0ae49ad55d0e01a48203df (patch)
treef527fd1748c2f034d74ca1b268d4f56fc36cf050 /gcc/d/dmd/expressionsem.c
parentae1ada95fee1ee4fac0dec0486076d9787988a03 (diff)
downloadgcc-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.c67
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)