Skip to content

Commit

Permalink
fix Issue 4018 - __FILE__ and __LINE__ as default template parameters…
Browse files Browse the repository at this point in the history
… not set to instantiation point per spec

Also fixes __MODULE__, __FUNCITON__, and __PRETTY_FUNCTION__
  • Loading branch information
9rnsr committed Oct 2, 2013
1 parent 9631c69 commit 7c4ef33
Show file tree
Hide file tree
Showing 7 changed files with 200 additions and 106 deletions.
2 changes: 1 addition & 1 deletion src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -6792,7 +6792,7 @@ Expression *IsExp::semantic(Scope *sc)
{ TemplateParameter *tp = (*parameters)[i];
Declaration *s = NULL;

m = tp->matchArg(sc, &tiargs, i, parameters, &dedtypes, &s);
m = tp->matchArg(loc, sc, &tiargs, i, parameters, &dedtypes, &s);
if (m == MATCHnomatch)
goto Lno;
s->semantic(sc);
Expand Down
14 changes: 8 additions & 6 deletions src/template.c
Original file line number Diff line number Diff line change
Expand Up @@ -844,12 +844,14 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
Scope *paramscope = scope->push(paramsym);
Module *mi = ti->instantiatingModule ? ti->instantiatingModule : sc->instantiatingModule;
paramscope->instantiatingModule = mi;
paramscope->callsc = sc;
paramscope->stc = 0;

// Attempt type deduction
m = MATCHexact;
for (size_t i = 0; i < dedtypes_dim; i++)
{ MATCH m2;
{
MATCH m2;
TemplateParameter *tp = (*parameters)[i];
Declaration *sparam;

Expand All @@ -861,7 +863,7 @@ MATCH TemplateDeclaration::matchWithInstance(Scope *sc, TemplateInstance *ti,
printf("\tparameter[%d] is %s : %s\n", i, tp->ident->toChars(), ttp->specType ? ttp->specType->toChars() : "");
#endif

m2 = tp->matchArg(paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
m2 = tp->matchArg(ti->loc, paramscope, ti->tiargs, i, parameters, dedtypes, &sparam);
//printf("\tm2 = %d\n", m2);

if (m2 == MATCHnomatch)
Expand Down Expand Up @@ -1184,7 +1186,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
MATCH m;
Declaration *sparam = NULL;

m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
m = tp->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, &sparam);
//printf("\tdeduceType m = %d\n", m);
if (m == MATCHnomatch)
goto Lnomatch;
Expand Down Expand Up @@ -1916,7 +1918,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(FuncDeclaration *f, Loc l
* the oded == oarg
*/
(*dedargs)[i] = oded;
MATCH m2 = tparam->matchArg(paramscope, dedargs, i, parameters, &dedtypes, NULL);
MATCH m2 = tparam->matchArg(loc, paramscope, dedargs, i, parameters, &dedtypes, NULL);
//printf("m2 = %d\n", m2);
if (!m2)
goto Lnomatch;
Expand Down Expand Up @@ -4088,7 +4090,7 @@ TemplateThisParameter *TemplateParameter::isTemplateThisParameter()
* *psparam set to symbol declared and initialized to dedtypes[i]
*/

MATCH TemplateParameter::matchArg(Scope *sc, Objects *tiargs,
MATCH TemplateParameter::matchArg(Loc loc, Scope *sc, Objects *tiargs,
size_t i, TemplateParameters *parameters, Objects *dedtypes,
Declaration **psparam)
{
Expand Down Expand Up @@ -4987,7 +4989,7 @@ int TemplateTupleParameter::overloadMatch(TemplateParameter *tp)
return 0;
}

MATCH TemplateTupleParameter::matchArg(Scope *sc, Objects *tiargs,
MATCH TemplateTupleParameter::matchArg(Loc loc, Scope *sc, Objects *tiargs,
size_t i, TemplateParameters *parameters, Objects *dedtypes,
Declaration **psparam)
{
Expand Down
4 changes: 2 additions & 2 deletions src/template.h
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ class TemplateParameter

/* Match actual argument against parameter.
*/
virtual MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
virtual MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
virtual MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam) = 0;

/* Create dummy argument based on parameter.
Expand Down Expand Up @@ -281,7 +281,7 @@ class TemplateTupleParameter : public TemplateParameter
RootObject *specialization();
RootObject *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
MATCH matchArg(Loc loc, Scope *sc, Objects *tiargs, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
MATCH matchArg(Scope *sc, RootObject *oarg, size_t i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
void *dummyArg();
};
Expand Down
84 changes: 0 additions & 84 deletions test/runnable/Fix5140.d

This file was deleted.

13 changes: 0 additions & 13 deletions test/runnable/imports/Fix5140a_file.d

This file was deleted.

37 changes: 37 additions & 0 deletions test/runnable/imports/testkwd_file.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module imports.testkwd;

/****************************************/

version(Windows) enum sep = "\\"; else enum sep = "/";

enum thatFile = "runnable"~sep~"imports"~sep~"testkwd_file.d";
enum thatMod = "imports.testkwd";
//enum thatLine;
enum thatFunc = "imports.testkwd.getCalleeFunc";
enum thatFunc2 = `string imports.testkwd.getCalleeFunc2(int x = 1, string s = "hello")`;

string getCalleeFile() { return __FILE__; }
ulong getCalleeLine() { return __LINE__; } enum thatLine = 14;
string getCalleeMod() { return __MODULE__; }
string getCalleeFunc() { return __FUNCTION__; }
string getCalleeFunc2(int x = 1, string s = "hello") { return __PRETTY_FUNCTION__; }

/****************************************/

string getFuncArgFile (string name = __FILE__ ) { return name; }
ulong getFuncArgLine (ulong lnum = __LINE__ ) { return lnum; }
string getFuncArgMod (string name = __MODULE__ ) { return name; }
string getFuncArgFunc (string name = __FUNCTION__ ) { return name; }
string getFuncArgFunc2(string name = __PRETTY_FUNCTION__) { return name; }

string getFuncTiargFile (string name = __FILE__ )() { return name; }
ulong getFuncTiargLine (ulong lnum = __LINE__ )() { return lnum; }
string getFuncTiargMod (string name = __MODULE__ )() { return name; }
string getFuncTiargFunc (string name = __FUNCTION__ )() { return name; }
string getFuncTiargFunc2(string name = __PRETTY_FUNCTION__)() { return name; }

template getInstTiargFile (string name = __FILE__ ) { enum getInstTiargFile = name; }
template getInstTiargLine (ulong lnum = __LINE__ ) { enum getInstTiargLine = lnum; }
template getInstTiargMod (string name = __MODULE__ ) { enum getInstTiargMod = name; }
template getInstTiargFunc (string name = __FUNCTION__ ) { enum getInstTiargFunc = name; }
template getInstTiargFunc2(string name = __PRETTY_FUNCTION__) { enum getInstTiargFunc2 = name; }
152 changes: 152 additions & 0 deletions test/runnable/testkeyword.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// PERMUTE_ARGS:
// EXTRA_SOURCES: imports/testkwd_file.d
module testkeyword;
import imports.testkwd;

/****************************************/
// calee test

static assert(getCalleeFile() == thatFile);
static assert(getCalleeLine() == thatLine);
static assert(getCalleeMod() == thatMod);
static assert(getCalleeFunc() == thatFunc);
static assert(getCalleeFunc2() == thatFunc2);

void testCallee()
{
static assert(getCalleeFile() == thatFile);
static assert(getCalleeLine() == thatLine);
static assert(getCalleeMod() == thatMod);
static assert(getCalleeFunc() == thatFunc);
static assert(getCalleeFunc2() == thatFunc2);
}

/****************************************/
// caller test

version(Windows) enum sep = "\\"; else enum sep = "/";

enum thisFile = "runnable"~sep~"testkeyword.d";
enum thisMod = "testkeyword";

static assert(getFuncArgFile() == thisFile);
static assert(getFuncArgLine() == 33);
static assert(getFuncArgMod() == thisMod);
static assert(getFuncArgFunc() == "");
static assert(getFuncArgFunc2() == "");

static assert(getFuncTiargFile() == thisFile);
static assert(getFuncTiargLine() == 39);
static assert(getFuncTiargMod() == thisMod);
static assert(getFuncTiargFunc() == "");
static assert(getFuncTiargFunc2() == "");

static assert(getInstTiargFile!() == thisFile);
static assert(getInstTiargLine!() == 45);
static assert(getInstTiargMod!() == thisMod);
static assert(getInstTiargFunc!() == "");
static assert(getInstTiargFunc2!() == "");

void main(string[] args) nothrow
{
enum thisFunc = "testkeyword.main";
enum thisFunc2 = "void testkeyword.main(string[] args) nothrow";

static assert(getFuncArgFile() == thisFile);
static assert(getFuncArgLine() == 56);
static assert(getFuncArgMod() == thisMod);
static assert(getFuncArgFunc() == thisFunc);
static assert(getFuncArgFunc2() == thisFunc2);

static assert(getFuncTiargFile() == thisFile);
static assert(getFuncTiargLine() == 62);
static assert(getFuncTiargMod() == thisMod);
static assert(getFuncTiargFunc() == thisFunc);
static assert(getFuncTiargFunc2() == thisFunc2);

static assert(getInstTiargFile!() == thisFile);
static assert(getInstTiargLine!() == 68);
static assert(getInstTiargMod!() == thisMod);
static assert(getInstTiargFunc!() == thisFunc);
static assert(getInstTiargFunc2!() == thisFunc2);

void nested(int x, float y) nothrow
{
enum thisFunc = "testkeyword.main.nested";
enum thisFunc2 = "void testkeyword.main.nested(int x, float y) nothrow";

static assert(getFuncArgFile() == thisFile);
static assert(getFuncArgLine() == 79);
static assert(getFuncArgMod() == thisMod);
static assert(getFuncArgFunc() == thisFunc);
static assert(getFuncArgFunc2() == thisFunc2);

static assert(getFuncTiargFile() == thisFile);
static assert(getFuncTiargLine() == 85);
static assert(getFuncTiargMod() == thisMod);
static assert(getFuncTiargFunc() == thisFunc);
static assert(getFuncTiargFunc2() == thisFunc2);

static assert(getInstTiargFile!() == thisFile);
static assert(getInstTiargLine!() == 91);
static assert(getInstTiargMod!() == thisMod);
static assert(getInstTiargFunc!() == thisFunc);
static assert(getInstTiargFunc2!() == thisFunc2);
}
nested(1, 1.0);

auto funcLiteral = (int x, int y)
{
enum thisFunc = "testkeyword.main.__lambda3";
enum thisFunc2 = "testkeyword.main.__lambda3(int x, int y)";

static assert(getFuncArgFile() == thisFile);
static assert(getFuncArgLine() == 104);
static assert(getFuncArgMod() == thisMod);
static assert(getFuncArgFunc() == thisFunc);
static assert(getFuncArgFunc2() == thisFunc2);

static assert(getFuncTiargFile() == thisFile);
static assert(getFuncTiargLine() == 110);
static assert(getFuncTiargMod() == thisMod);
static assert(getFuncTiargFunc() == thisFunc);
static assert(getFuncTiargFunc2() == thisFunc2);

static assert(getInstTiargFile!() == thisFile);
static assert(getInstTiargLine!() == 116);
static assert(getInstTiargMod!() == thisMod);
static assert(getInstTiargFunc!() == thisFunc);
static assert(getInstTiargFunc2!() == thisFunc2);
};
funcLiteral(1, 2);

static struct S
{
void func(string cs, T1, alias T2, T...)(int x) const
{
enum thisFunc = `testkeyword.main.S.func!("foo", int, symbol, int[], float[]).func`;
enum thisFunc2 = `void testkeyword.main.S.func!("foo", int, symbol, int[], float[]).func(int x) const`;

static assert(getFuncArgFile() == thisFile);
static assert(getFuncArgLine() == 131);
static assert(getFuncArgMod() == thisMod);
static assert(getFuncArgFunc() == thisFunc);
static assert(getFuncArgFunc2() == thisFunc2);

static assert(getFuncTiargFile() == thisFile);
static assert(getFuncTiargLine() == 137);
static assert(getFuncTiargMod() == thisMod);
static assert(getFuncTiargFunc() == thisFunc);
static assert(getFuncTiargFunc2() == thisFunc2);

static assert(getInstTiargFile!() == thisFile);
static assert(getInstTiargLine!() == 143);
static assert(getInstTiargMod!() == thisMod);
static assert(getInstTiargFunc!() == thisFunc);
static assert(getInstTiargFunc2!() == thisFunc2);
}
}
static int symbol;
S s;
s.func!("foo", int, symbol, int[], float[])(1);
}

0 comments on commit 7c4ef33

Please sign in to comment.