summaryrefslogtreecommitdiffstats
path: root/libacc
diff options
context:
space:
mode:
authorJack Palevich <jackpal@google.com>2009-09-04 15:24:23 -0700
committerJack Palevich <jackpal@google.com>2009-09-04 15:24:23 -0700
commit5fd66ae01e3b4a75307a65d839e4679327f10471 (patch)
tree66df86c480acb63990fb677417a304d43198d992 /libacc
parent91acb14877e7138879057f794a61ee2fd424a41d (diff)
downloadsystem_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.cpp18
-rw-r--r--libacc/tests/data/addressOf.c31
-rw-r--r--libacc/tests/test.py7
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()