From dddea6d4d81cac76ff64cde178e2d5f7fe09fb55 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Thu, 7 Jan 2021 18:03:33 +0100 Subject: d: Merge upstream dmd 9038e64c5. Adds support for using user-defined attributes on function arguments and single-parameter alias declarations. These attributes behave analogous to existing UDAs. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 9038e64c5. * d-builtins.cc (build_frontend_type): Update call to Parameter::create. --- .../gdc.test/compilable/extra-files/header1.d | 18 ++ .../gdc.test/compilable/testheaderudamodule.d | 2 + .../gdc.test/fail_compilation/fail10207.d | 2 +- gcc/testsuite/gdc.test/runnable/uda.d | 194 +++++++++++++++++++++ 4 files changed, 215 insertions(+), 1 deletion(-) (limited to 'gcc/testsuite/gdc.test') diff --git a/gcc/testsuite/gdc.test/compilable/extra-files/header1.d b/gcc/testsuite/gdc.test/compilable/extra-files/header1.d index a746a2aac06..d8221eb882a 100644 --- a/gcc/testsuite/gdc.test/compilable/extra-files/header1.d +++ b/gcc/testsuite/gdc.test/compilable/extra-files/header1.d @@ -519,3 +519,21 @@ struct Foo3A(T) @disable this(this); @disable this(); } + +void test13x(@(10) int a, @(20) int, @(30) @(40) int[] arr...) {} + +enum Test14UDA1; +struct Test14UDA2 +{ + string str; +} + +Test14UDA2 test14uda3(string name) +{ + return Test14UDA2(name); +} +struct Test14UDA4(string v){} + +void test14x(@Test14UDA1 int, @Test14UDA2("1") int, @test14uda3("2") int, @Test14UDA4!"3" int) {} + +void test15x(@(20) void delegate(int) @safe dg){} diff --git a/gcc/testsuite/gdc.test/compilable/testheaderudamodule.d b/gcc/testsuite/gdc.test/compilable/testheaderudamodule.d index 1a7d6506669..5ee94868993 100644 --- a/gcc/testsuite/gdc.test/compilable/testheaderudamodule.d +++ b/gcc/testsuite/gdc.test/compilable/testheaderudamodule.d @@ -11,3 +11,5 @@ struct UDA } void main() {} + +void foo(@(1) int bar, @UDA(2) string bebe); diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10207.d b/gcc/testsuite/gdc.test/fail_compilation/fail10207.d index ac8b4eef11a..3f09a27541a 100644 --- a/gcc/testsuite/gdc.test/fail_compilation/fail10207.d +++ b/gcc/testsuite/gdc.test/fail_compilation/fail10207.d @@ -1,7 +1,7 @@ /* TEST_OUTPUT: --- -fail_compilation/fail10207.d(7): Error: user defined attributes not allowed for `alias` declarations +fail_compilation/fail10207.d(7): Error: user-defined attributes not allowed for `alias` declarations --- */ alias @Safe int __externC; diff --git a/gcc/testsuite/gdc.test/runnable/uda.d b/gcc/testsuite/gdc.test/runnable/uda.d index c1782c90a7b..38f84e5971d 100644 --- a/gcc/testsuite/gdc.test/runnable/uda.d +++ b/gcc/testsuite/gdc.test/runnable/uda.d @@ -467,6 +467,193 @@ static assert(__traits(getAttributes, FileData11844.member)[0](new FileData11844 /************************************************/ +template AliasSeq(T...) +{ + alias AliasSeq = T; +} + +template ParameterUDA(size_t p_num, func...) +if (func.length == 1 && is(typeof(func[0]) PT == __parameters) && PT.length > p_num) +{ + static if (is(typeof(func[0]) PT == __parameters)) + { + template Get(size_t i) + { + static if (//!isFunctionPointer!func && !isDelegate!func + // Parameters without UDA may yield CT error. + /*&&*/ is(typeof(__traits(getAttributes, PT[i..i+1]))x)) + { + alias Get = AliasSeq!(__traits(getAttributes, PT[i..i+1])); + } + else + { + alias Get = AliasSeq!(); + } + } + } + else + { + static assert(0, func[0].stringof ~ "is not a function"); + + // Define dummy entities to avoid pointless errors + template Get(size_t i) { alias Get = AliasSeq!(); } + alias PT = AliasSeq!(); + } + + alias ParameterUDA = Get!p_num; +} + +void test13x(@(10) int a, @(20) int, @(30) @(40) int[] arr...) {} + +void test13() +{ + static assert([ParameterUDA!(0, test13x)] == [10]); + static assert([ParameterUDA!(1, test13x)] == [20]); + static assert([ParameterUDA!(2, test13x)] == [30, 40]); +} + +template Test13t(F) +{ + static assert(!__traits(compiles, ParameterUDA!(0, F))); + static assert(!__traits(compiles, ParameterUDA!(1, F))); + static assert(!__traits(compiles, ParameterUDA!(2, F))); + enum Test13t = true; +} + +alias test13t = Test13t!(typeof(test13x)); + +enum Test14UDA1; + +struct Test14UDA2 +{ + string str; +} + +Test14UDA2 test14uda3(string name) +{ + return Test14UDA2(name); +} + +struct Test14UDA4(string v) +{ +} + +void test14x(@Test14UDA1 int, @Test14UDA2("1") int, @test14uda3("2") int, @Test14UDA4!"3" int) {} +void test14() +{ + static assert(is(ParameterUDA!(0, test14x)[0] == Test14UDA1)); + static assert(ParameterUDA!(1, test14x)[0] == Test14UDA2("1")); + static assert(ParameterUDA!(2, test14x)[0] == test14uda3("2")); + static assert(is(ParameterUDA!(3, test14x)[0] == Test14UDA4!"3")); +} + +void test15x(@(20) void delegate(int) @safe dg) +{ + static assert([__traits(getAttributes, dg)] == [20]); + static assert(is(typeof(dg) == void delegate(int) @safe)); +} + +template MinimalFunctionTypeOf(func...) +if (func.length == 1) +{ + static if (is(func[0] T) || is(typeof(func[0]) T) && is(T Fdlg == delegate)) + alias MinimalFunctionTypeOf = Fdlg; // HIT: delegate + else + static assert(0); +} + +template Parameters(func...) +if (func.length == 1) +{ + static if (is(MinimalFunctionTypeOf!func P == function)) + alias Parameters = P; + else + static assert(0, "argument has no parameters"); +} + +void test15y(@(20) void delegate(@Test14UDA2("2") @("test15yUDA") int) @safe dg) +{ + static assert([__traits(getAttributes, dg)] == [20]); + static assert(is(typeof(dg) == void delegate(int) @safe)); + auto foo = (@("myUDA") int x){ + static assert([__traits(getAttributes, x)] == ["myUDA"]); + }; + static assert(__traits(getAttributes, Parameters!dg)[0] == Test14UDA2("2")); + static assert(__traits(getAttributes, Parameters!dg)[1] == "test15yUDA"); +} + +void test15z() +{ + test15y((@(15) @(16) int x){ + static assert([__traits(getAttributes, x)] == [15, 16]); + }); +} + +void test16x(A)(@(22) A a) +{ + static assert([__traits(getAttributes, a)] == [22]); +} + +void test16() +{ + static assert([ParameterUDA!(0, test16x!int)] == [22]); +} + +void test17() +{ + void test17x(A)(@(23) A a) + { + static assert([__traits(getAttributes, a)] == [23]); + } + static assert([ParameterUDA!(0, test17x!int)] == [23]); +} + +void test18() +{ + void test18a(@(Tuple!(18, "a")) int a) + { + static assert(__traits(getAttributes, a) == Tuple!(18, "a")); + } + void test18b(@Tuple!(18, "b") int a) + { + static assert(__traits(getAttributes, a) == Tuple!(18, "b")); + } + + static assert(ParameterUDA!(0, test18a) == Tuple!(18, "a")); + static assert(ParameterUDA!(0, test18b) == Tuple!(18, "b")); +} + +// Lambdas with parentheses: +void test19() +{ + // lambdas without parentheses + alias test19a = @(3) b => 1 + 2; + alias test19b = @(3) @(4) b => 1 + 2; + + alias test19c = (@(3) c, @(5) d) => 1 + 2; + alias test19d = (@(3) @(4) c, @(5) d) => 1 + 2; + auto test19e = (@(3) int c, @(5) int d) => 1 + 2; + + // still allow alias function declarations + alias FuncType = @safe void function(); + alias FuncType2 = @safe nothrow void function(); + alias FuncType3 = nothrow void function(); + alias FuncType4 = nothrow @safe void function(); +} + +void test20() +{ + // Using a delegate with inferred parameter type + void test20a(int delegate(int) t){ t(1); } + test20a((@(19) a) { + static assert([__traits(getAttributes, a)] == [19]); + return a + 2; + }); +} + +/************************************************/ + + int main() { test1(); @@ -482,6 +669,13 @@ int main() test11(); test12(); test9178(); + test13(); + test14(); + test16(); + test17(); + test18(); + test19(); + test20(); printf("Success\n"); return 0; -- cgit v1.2.3