diff options
author | Jack Palevich <jackpal@google.com> | 2009-09-04 15:24:23 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-09-04 15:24:23 -0700 |
commit | 5fd66ae01e3b4a75307a65d839e4679327f10471 (patch) | |
tree | 66df86c480acb63990fb677417a304d43198d992 /libacc | |
parent | 91acb14877e7138879057f794a61ee2fd424a41d (diff) | |
download | system_core-5fd66ae01e3b4a75307a65d839e4679327f10471.tar.gz system_core-5fd66ae01e3b4a75307a65d839e4679327f10471.tar.bz2 system_core-5fd66ae01e3b4a75307a65d839e4679327f10471.zip |
Improve address operator (unary &).
Until now the address operator only worked with simple variables.
Now it works with arbitrary expressions (that are lvalues or function
names). So for example this now works:
struct S { int a[10]};
int f(struct S* p) {
return &p->a[3];
}
Diffstat (limited to 'libacc')
-rw-r--r-- | libacc/acc.cpp | 18 | ||||
-rw-r--r-- | libacc/tests/data/addressOf.c | 31 | ||||
-rw-r--r-- | libacc/tests/test.py | 7 |
3 files changed, 51 insertions, 5 deletions
diff --git a/libacc/acc.cpp b/libacc/acc.cpp index 535361c9b..7e6dde6a4 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -4450,10 +4450,8 @@ class Compiler : public ErrorSink { unary(); doPointer(); } else if (t == '&') { - VariableInfo* pVI = VI(tok); - pGen->leaR0((int) pVI->pAddress, createPtrType(pVI->pType), - ET_RVALUE); - next(); + unary(); + doAddressOf(); } else if (t == EOF ) { error("Unexpected EOF."); } else if (t == ';') { @@ -4656,6 +4654,16 @@ class Compiler : public ErrorSink { } } + void doAddressOf() { + Type* pR0 = pGen->getR0Type(); + bool isFuncPtr = pR0->tag == TY_POINTER && pR0->pHead->tag == TY_FUNC; + if ((! isFuncPtr) && pGen->getR0ExpressionType() != ET_LVALUE) { + error("Expected an lvalue"); + } + Type* pR0Type = pGen->getR0Type(); + pGen->setR0ExpressionType(ET_RVALUE); + } + /* Recursive descent parser for binary operations. */ void binaryOp(int level) { @@ -5293,7 +5301,7 @@ class Compiler : public ErrorSink { void checkLVal() { if (pGen->getR0ExpressionType() != ET_LVALUE) { - error("Expected an lval"); + error("Expected an lvalue"); } } diff --git a/libacc/tests/data/addressOf.c b/libacc/tests/data/addressOf.c new file mode 100644 index 000000000..e7acde53d --- /dev/null +++ b/libacc/tests/data/addressOf.c @@ -0,0 +1,31 @@ +void testStruct() { + struct str { + float x; + float y; + }; + + struct str base; + int index = 0; + + base.x = 10.0; + struct str *s = &base; + + float *v = &(*s).x; + float *v2 = &s[index].x; + printf("testStruct: %g %g %g\n",base.x, *v, *v2); +} + +void testArray() { + int a[2]; + a[0] = 1; + a[1] = 2; + int* p = &a[0]; + int* p2 = a; + printf("testArray: %d %d %d\n", a[0], *p, *p2); +} + +int main() { + testStruct(); + testArray(); + return 0; +} diff --git a/libacc/tests/test.py b/libacc/tests/test.py index a8575b13a..c982d16c3 100644 --- a/libacc/tests/test.py +++ b/libacc/tests/test.py @@ -471,6 +471,13 @@ testArgs: (6, 8, 10, 12) result: 6 ""","""""") + def testAddressOf(self): + self.compileCheck(["-R", "data/addressOf.c"], """Executing compiled code: +testStruct: 10 10 10 +testArray: 1 1 1 +result: 0 +""","""""") + def main(): checkEnvironment() parseArgv() |