Skip to content

Commit 5dca01a

Browse files
committed
Push implicit this argument when calling methods from methods.
1 parent 0379496 commit 5dca01a

File tree

5 files changed

+60
-15
lines changed

5 files changed

+60
-15
lines changed

src/liboslcomp/ast.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,7 +1183,8 @@ ASTtype_constructor::childname (size_t i) const
11831183

11841184

11851185
ASTfunction_call::ASTfunction_call (OSLCompilerImpl *comp, ustring name,
1186-
ASTNode *args, FunctionSymbol *funcsym)
1186+
ASTNode *args, FunctionSymbol *funcsym,
1187+
ASTNode* implicit_this)
11871188
: ASTnamed_symbol (function_call_node, comp, name, args),
11881189
m_poly(funcsym), // Default - resolved symbol or null
11891190
m_argread(~1), // Default - all args are read except the first
@@ -1199,14 +1200,29 @@ ASTfunction_call::ASTfunction_call (OSLCompilerImpl *comp, ustring name,
11991200
m_sym = nullptr;
12001201
return;
12011202
}
1203+
if (implicit_this && m_sym->node()) {
1204+
int advance;
1205+
const char* form = static_cast<FunctionSymbol*>(m_sym)->argcodes().c_str();
1206+
/*TypeSpec rval = */ comp->type_from_code(form, &advance);
1207+
form += advance;
1208+
if (*form && comp->type_from_code(form) == implicit_this->typespec()) {
1209+
method_from_function(new ASTvariable_ref(m_compiler,
1210+
ustring("this"), true));
1211+
}
1212+
}
12021213
}
12031214

12041215

12051216

12061217
void
12071218
ASTfunction_call::method_from_function (ASTNode* thisRef)
12081219
{
1209-
ASSERT (m_method == false);
1220+
// Only do this once!
1221+
if (m_method) {
1222+
delete thisRef;
1223+
return;
1224+
}
1225+
12101226
ASSERT (m_children.size() == 1);
12111227
m_method = true;
12121228
if (m_children[0])

src/liboslcomp/ast.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,8 @@ class ASTfunction_call : public ASTnamed_symbol
910910
{
911911
public:
912912
ASTfunction_call (OSLCompilerImpl *comp, ustring name, ASTNode *args,
913-
FunctionSymbol *funcsym = nullptr);
913+
FunctionSymbol *funcsym = nullptr,
914+
ASTNode* implicit_this = nullptr);
914915
const char *nodetypename () const { return "function_call"; }
915916
const char *childname (size_t i) const;
916917
const char *opname () const;

src/liboslcomp/oslgram.y

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ TypeDesc osllextype (int lex);
6464
OSL_NAMESPACE_EXIT
6565

6666
static std::stack<TypeSpec> typespec_stack; // just for function_declaration
67-
bool allowthis;
67+
static ASTNode::ref implicit_this;
6868

6969
%}
7070

@@ -340,22 +340,21 @@ function_declaration
340340
'(' formal_params_opt ')' metadata_block_opt
341341
{
342342
if (StructSpec *s = oslcompiler->symtab().current_struct()) {
343-
allowthis = true;
344343
TypeSpec t(s->name().c_str(), 0);
345-
auto* args = new ASTvariable_declaration(oslcompiler, t,
346-
$5);
347-
$<n>$ = args;
344+
implicit_this = new ASTvariable_declaration(oslcompiler, t,
345+
$5);
346+
$<n>$ = implicit_this.get();
348347
} else
349348
$<n>$ = $5;
350349
}
351350
function_body_or_just_decl
352351
{
353-
allowthis = false;
354352
oslcompiler->symtab().pop (); // restore scope
355353
ASTfunction_declaration *f;
356354
f = new ASTfunction_declaration (oslcompiler,
357355
typespec_stack.top(),
358356
ustring($2), $<n>8, $9, $7);
357+
implicit_this = nullptr;
359358
oslcompiler->remember_function_decl (f);
360359
typespec_stack.pop ();
361360
$$ = f;
@@ -781,7 +780,7 @@ variable_lvalue
781780
id_or_field
782781
: IDENTIFIER
783782
{
784-
$$ = new ASTvariable_ref (oslcompiler, ustring($1), allowthis);
783+
$$ = new ASTvariable_ref (oslcompiler, ustring($1), implicit_this);
785784
}
786785
| variable_lvalue '.' IDENTIFIER
787786
{
@@ -936,7 +935,8 @@ type_constructor
936935
function_call
937936
: IDENTIFIER '(' function_args_opt ')'
938937
{
939-
$$ = new ASTfunction_call (oslcompiler, ustring($1), $3);
938+
$$ = new ASTfunction_call (oslcompiler, ustring($1), $3,
939+
nullptr, implicit_this.get());
940940
}
941941
;
942942

testsuite/function-method/ref/out.txt

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,16 @@
1-
test.osl:12: warning: argument "f" shadows a field with the same name
1+
test.osl:16: warning: argument "f" shadows a field with the same name
2+
test.osl:22: warning: argument "f" shadows a field with the same name
3+
test.osl:27: warning: "f" shadows a field with the same name
24
Compiled test.osl -> test.oso
35
emethod::test: (42) (2)
46
emethod::test: (42) (46)
5-
emethod::testchain: 40
6-
emethod::testchain: 36
77
emethod::testchain: 28
8-
emethod::testchain: 12
8+
emethod::testchain: 24
9+
emethod::testchain: 16
10+
emethod::testchain: 0
11+
emethod::shadowed: (40) (3.14)
12+
emethod::shadowed2: 40 22.4 6.28
13+
emethod::shadowed: (40) (6.28)
14+
unshadowed 5
15+
unshadowed *
916

testsuite/function-method/test.osl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
void unshadowed(int i) { printf("unshadowed %d\n", i); }
2+
void unshadowed() { printf("unshadowed *\n"); }
3+
14
struct emethod {
25
float f;
36

@@ -15,12 +18,30 @@ struct emethod {
1518
printf("emethod::testchain: %g\n", this.f);
1619
return this;
1720
}
21+
22+
void shadowed(float f) {
23+
printf("emethod::shadowed: (%g) (%g)\n", this.f, f);
24+
}
25+
26+
float shadowed2(float ff) {
27+
float f = 32.4;
28+
f -= 10;
29+
printf("emethod::shadowed2: %g %g %g\n", this.f, f, ff);
30+
shadowed(ff);
31+
unshadowed(5);
32+
unshadowed();
33+
return f;
34+
}
1835
};
1936

37+
2038
shader test ()
2139
{
2240
emethod e = { 42 };
2341
e.test(2);
2442
e.test2(2);
2543
emethod(2+4+8+16).testchain(2).testchain(4).testchain(8).testchain(16);
44+
e.f -= 2;
45+
e.shadowed(3.14);
46+
e.shadowed2(6.28);
2647
}

0 commit comments

Comments
 (0)