Skip to content

Commit ca27778

Browse files
committed
Push implicit this argument when calling methods from methods.
1 parent 9953d0d commit ca27778

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
@@ -1256,7 +1256,8 @@ ASTtype_constructor::childname (size_t i) const
12561256

12571257

12581258
ASTfunction_call::ASTfunction_call (OSLCompilerImpl *comp, ustring name,
1259-
ASTNode *args, FunctionSymbol *funcsym)
1259+
ASTNode *args, FunctionSymbol *funcsym,
1260+
ASTNode* implicit_this)
12601261
: ASTnamed_symbol (function_call_node, comp, name, args),
12611262
m_poly(funcsym), // Default - resolved symbol or null
12621263
m_argread(~1), // Default - all args are read except the first
@@ -1272,14 +1273,29 @@ ASTfunction_call::ASTfunction_call (OSLCompilerImpl *comp, ustring name,
12721273
m_sym = nullptr;
12731274
return;
12741275
}
1276+
if (implicit_this && m_sym->node()) {
1277+
int advance;
1278+
const char* form = static_cast<FunctionSymbol*>(m_sym)->argcodes().c_str();
1279+
/*TypeSpec rval = */ comp->type_from_code(form, &advance);
1280+
form += advance;
1281+
if (*form && comp->type_from_code(form) == implicit_this->typespec()) {
1282+
method_from_function(new ASTvariable_ref(m_compiler,
1283+
ustring("this"), true));
1284+
}
1285+
}
12751286
}
12761287

12771288

12781289

12791290
void
12801291
ASTfunction_call::method_from_function (ASTNode* thisRef)
12811292
{
1282-
ASSERT (m_method == false);
1293+
// Only do this once!
1294+
if (m_method) {
1295+
delete thisRef;
1296+
return;
1297+
}
1298+
12831299
ASSERT (m_children.size() == 1);
12841300
m_method = true;
12851301
if (m_children[0])

src/liboslcomp/ast.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,8 @@ class ASTfunction_call : public ASTnamed_symbol
934934
{
935935
public:
936936
ASTfunction_call (OSLCompilerImpl *comp, ustring name, ASTNode *args,
937-
FunctionSymbol *funcsym = nullptr);
937+
FunctionSymbol *funcsym = nullptr,
938+
ASTNode* implicit_this = nullptr);
938939
const char *nodetypename () const { return "function_call"; }
939940
const char *childname (size_t i) const;
940941
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

@@ -343,22 +343,21 @@ function_declaration
343343
'(' formal_params_opt ')' metadata_block_opt
344344
{
345345
if (StructSpec *s = oslcompiler->symtab().current_struct()) {
346-
allowthis = true;
347346
TypeSpec t(s->name().c_str(), 0);
348-
auto* args = new ASTvariable_declaration(oslcompiler, t,
349-
$5);
350-
$<n>$ = args;
347+
implicit_this = new ASTvariable_declaration(oslcompiler, t,
348+
$5);
349+
$<n>$ = implicit_this.get();
351350
} else
352351
$<n>$ = $5;
353352
}
354353
function_body_or_just_decl
355354
{
356-
allowthis = false;
357355
oslcompiler->symtab().pop (); // restore scope
358356
ASTfunction_declaration *f;
359357
f = new ASTfunction_declaration (oslcompiler,
360358
typespec_stack.top(),
361359
ustring($2), $<n>8, $9, $7);
360+
implicit_this = nullptr;
362361
oslcompiler->remember_function_decl (f);
363362
typespec_stack.pop ();
364363
$$ = f;
@@ -790,7 +789,7 @@ variable_lvalue
790789
id_or_field
791790
: IDENTIFIER
792791
{
793-
$$ = new ASTvariable_ref (oslcompiler, ustring($1), allowthis);
792+
$$ = new ASTvariable_ref (oslcompiler, ustring($1), implicit_this);
794793
}
795794
| variable_lvalue '.' IDENTIFIER
796795
{
@@ -945,7 +944,8 @@ type_constructor
945944
function_call
946945
: IDENTIFIER '(' function_args_opt ')'
947946
{
948-
$$ = new ASTfunction_call (oslcompiler, ustring($1), $3);
947+
$$ = new ASTfunction_call (oslcompiler, ustring($1), $3,
948+
nullptr, implicit_this.get());
949949
}
950950
;
951951

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)