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];
}
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 535361c..7e6dde6 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -4450,10 +4450,8 @@
                 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 @@
         }
     }
 
+    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 @@
 
     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 0000000..e7acde5
--- /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 a8575b1..c982d16 100644
--- a/libacc/tests/test.py
+++ b/libacc/tests/test.py
@@ -471,6 +471,13 @@
 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()