Loading libacc/acc.cpp +105 −34 Original line number Diff line number Diff line Loading @@ -1312,6 +1312,12 @@ class Compiler : public ErrorSink { } } String& operator=(const String& other) { clear(); appendBytes(other.getUnwrapped(), other.len()); return *this; } inline char* getUnwrapped() const { return mpBase; } Loading Loading @@ -1439,6 +1445,12 @@ class Compiler : public ErrorSink { return result; } void forEach(bool (*callback)(String* key, V* value, void* context), void* context) { hashmapForEach(mpMap, (bool (*)(void*, void*, void*)) callback, context); } protected: void init(size_t initialCapacity) { Loading Loading @@ -1670,11 +1682,21 @@ class Compiler : public ErrorSink { return addImp(0, pName); } void forEachGlobal( bool (*callback)(String* key, VariableInfo* value, void* context), void* context) { mStack.get(0).pTable->forEach(callback, context); } private: VariableInfo* addImp(int entryIndex, String* pName) { Entry e = mStack.get(entryIndex); SymbolTable* pTable = e.pTable; if (pTable->contains(pName)) { return NULL; } VariableInfo* v = new VariableInfo(); delete pTable->put(pName, v); #if 0 fprintf(stderr, "Add \"%s\" %08x level %d\n", pName->getUnwrapped(), v, e.level); Loading Loading @@ -2044,6 +2066,7 @@ class Compiler : public ErrorSink { void unary(intptr_t l) { intptr_t n, t, a; int c; String tString; t = 0; n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */ Loading @@ -2063,6 +2086,7 @@ class Compiler : public ErrorSink { c = tokl; a = tokc; t = tok; tString = mTokenString; next(); if (t == TOK_NUM) { pGen->li(a); Loading Loading @@ -2112,14 +2136,15 @@ class Compiler : public ErrorSink { } else { if (t == TOK_UNDEFINED_SYMBOL) { t = (intptr_t) mSymbolTable.addGlobal( new String(mTokenString)); new String(tString)); } n = *(int *) t; n = (intptr_t) ((VariableInfo*) t)->pAddress; /* forward reference: try dlsym */ if (!n) { n = (intptr_t) dlsym(RTLD_DEFAULT, mTokenString.getUnwrapped()); tString.getUnwrapped()); ((VariableInfo*) t)->pAddress = (void*) n; } if ((tok == '=') & l) { /* assignment */ Loading @@ -2128,6 +2153,9 @@ class Compiler : public ErrorSink { pGen->storeR0(n); } else if (tok != '(') { /* variable */ if (!n) { error("Undefined variable %s", tString.getUnwrapped()); } pGen->loadR0(n, tokl == 11, tokc); if (tokl == 11) { next(); Loading Loading @@ -2216,7 +2244,7 @@ class Compiler : public ErrorSink { return pGen->gtst(0, 0); } void block(intptr_t l) { void block(intptr_t l, bool outermostFunctionBlock) { intptr_t a, n, t; if (tok == TOK_IF) { Loading @@ -2224,12 +2252,12 @@ class Compiler : public ErrorSink { skip('('); a = test_expr(); skip(')'); block(l); block(l, false); if (tok == TOK_ELSE) { next(); n = pGen->gjmp(0); /* jmp */ pGen->gsym(a); block(l); block(l, false); pGen->gsym(n); /* patch else jmp */ } else { pGen->gsym(a); /* patch if test */ Loading Loading @@ -2259,18 +2287,22 @@ class Compiler : public ErrorSink { } } skip(')'); block((intptr_t) &a); block((intptr_t) &a, false); pGen->gjmp(n - codeBuf.getPC() - pGen->jumpOffset()); /* jmp */ pGen->gsym(a); } else if (tok == '{') { if (! outermostFunctionBlock) { mSymbolTable.pushLevel(); } next(); /* declarations */ localDeclarations(); while (tok != '}' && tok != EOF) block(l); block(l, false); skip('}'); if (! outermostFunctionBlock) { mSymbolTable.popLevel(); } } else { if (tok == TOK_RETURN) { next(); Loading Loading @@ -2350,18 +2382,22 @@ class Compiler : public ErrorSink { } } void defineGlobalSymbol() { if (tok == TOK_UNDEFINED_SYMBOL) { // TODO: don't allow multiple definitions at same level. void addGlobalSymbol() { tok = (intptr_t) mSymbolTable.addGlobal( new String(mTokenString)); reportIfDuplicate(); } void reportIfDuplicate() { if (!tok) { error("Duplicate definition of %s", mTokenString.getUnwrapped()); } } void defineLocalSymbol() { // TODO: don't allow multiple definitions at same level. void addLocalSymbol() { tok = (intptr_t) mSymbolTable.addLocal( new String(mTokenString)); reportIfDuplicate(); } void localDeclarations() { Loading @@ -2371,10 +2407,11 @@ class Compiler : public ErrorSink { while (acceptType(base)) { while (tok != ';') { Type t = acceptPointerDeclaration(t); defineLocalSymbol(); addLocalSymbol(); if (tok) { loc = loc + 4; *(int *) tok = -loc; } next(); if (tok == ',') next(); Loading @@ -2388,29 +2425,39 @@ class Compiler : public ErrorSink { Type base; expectType(base); Type t = acceptPointerDeclaration(t); defineGlobalSymbol(); if (tok == TOK_UNDEFINED_SYMBOL) { addGlobalSymbol(); } VariableInfo* name = (VariableInfo*) tok; if (name && name->pAddress) { error("Already defined global %s", mTokenString.getUnwrapped()); } next(); if (tok == ',' || tok == ';') { // it's a variable declaration for(;;) { if (name) { name->pAddress = (int*) allocGlobalSpace(4); } if (tok != ',') { break; } skip(','); t = acceptPointerDeclaration(t); defineGlobalSymbol(); addGlobalSymbol(); name = (VariableInfo*) tok; next(); } skip(';'); } else { if (name) { /* patch forward references (XXX: does not work for function pointers) */ pGen->gsym((int) name->pForward); /* put function address */ name->pAddress = (void*) codeBuf.getPC(); } skip('('); mSymbolTable.pushLevel(); intptr_t a = 8; Loading @@ -2419,10 +2466,12 @@ class Compiler : public ErrorSink { Type aType; expectType(aType); aType = acceptPointerDeclaration(aType); defineLocalSymbol(); addLocalSymbol(); if (tok) { /* read param name and compute offset */ *(int *) tok = a; a = a + 4; } next(); if (tok == ',') next(); Loading @@ -2431,7 +2480,7 @@ class Compiler : public ErrorSink { skip(')'); rsym = loc = 0; a = pGen->functionEntry(argCount); block(0); block(0, true); pGen->gsym(rsym); pGen->functionExit(argCount, a, loc); mSymbolTable.popLevel(); Loading Loading @@ -2551,6 +2600,7 @@ public: inp(); next(); globalDeclarations(); checkForUndefinedForwardReferences(); result = pGen->finishCompile(); if (result == 0) { if (mErrorBuf.len()) { Loading @@ -2560,6 +2610,27 @@ public: return result; } void checkForUndefinedForwardReferences() { mSymbolTable.forEachGlobal(static_ufrcFn, this); } static bool static_ufrcFn(String* key, VariableInfo* value, void* context) { Compiler* pCompiler = (Compiler*) context; return pCompiler->undefinedForwardReferenceCheck(key, value); } bool undefinedForwardReferenceCheck(String* key, VariableInfo* value) { #if 0 fprintf(stderr, "%s 0x%8x 0x%08x\n", key->getUnwrapped(), value->pAddress, value->pForward); #endif if (!value->pAddress && value->pForward) { error("Undefined forward reference: %s", key->getUnwrapped()); } return true; } int dump(FILE* out) { fwrite(codeBuf.getBase(), 1, codeBuf.getSize(), out); return 0; Loading libacc/tests/data/locals.c +8 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,9 @@ int a; int f() { int a; printf("f 0: a = %d b = %d\n", a, b); // Undefined variable b // printf("f 0: a = %d b = %d\n", a, b); printf("f 0: a = %d\n", a); a = 2; printf("f 1: a = %d\n", a); } Loading @@ -14,19 +16,23 @@ int g(int a) { } int h(int a) { int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol // int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol printf("h 0: a = %d\n", a); a = 4; printf("h 1: a = %d\n", a); } // Already defined global // int h() {} int globCheck() { fprintf(stdout, "globCheck()\n"); } int fwdCheck() { b(); // Undefined forward reference // c(); } int b() { Loading Loading
libacc/acc.cpp +105 −34 Original line number Diff line number Diff line Loading @@ -1312,6 +1312,12 @@ class Compiler : public ErrorSink { } } String& operator=(const String& other) { clear(); appendBytes(other.getUnwrapped(), other.len()); return *this; } inline char* getUnwrapped() const { return mpBase; } Loading Loading @@ -1439,6 +1445,12 @@ class Compiler : public ErrorSink { return result; } void forEach(bool (*callback)(String* key, V* value, void* context), void* context) { hashmapForEach(mpMap, (bool (*)(void*, void*, void*)) callback, context); } protected: void init(size_t initialCapacity) { Loading Loading @@ -1670,11 +1682,21 @@ class Compiler : public ErrorSink { return addImp(0, pName); } void forEachGlobal( bool (*callback)(String* key, VariableInfo* value, void* context), void* context) { mStack.get(0).pTable->forEach(callback, context); } private: VariableInfo* addImp(int entryIndex, String* pName) { Entry e = mStack.get(entryIndex); SymbolTable* pTable = e.pTable; if (pTable->contains(pName)) { return NULL; } VariableInfo* v = new VariableInfo(); delete pTable->put(pName, v); #if 0 fprintf(stderr, "Add \"%s\" %08x level %d\n", pName->getUnwrapped(), v, e.level); Loading Loading @@ -2044,6 +2066,7 @@ class Compiler : public ErrorSink { void unary(intptr_t l) { intptr_t n, t, a; int c; String tString; t = 0; n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */ Loading @@ -2063,6 +2086,7 @@ class Compiler : public ErrorSink { c = tokl; a = tokc; t = tok; tString = mTokenString; next(); if (t == TOK_NUM) { pGen->li(a); Loading Loading @@ -2112,14 +2136,15 @@ class Compiler : public ErrorSink { } else { if (t == TOK_UNDEFINED_SYMBOL) { t = (intptr_t) mSymbolTable.addGlobal( new String(mTokenString)); new String(tString)); } n = *(int *) t; n = (intptr_t) ((VariableInfo*) t)->pAddress; /* forward reference: try dlsym */ if (!n) { n = (intptr_t) dlsym(RTLD_DEFAULT, mTokenString.getUnwrapped()); tString.getUnwrapped()); ((VariableInfo*) t)->pAddress = (void*) n; } if ((tok == '=') & l) { /* assignment */ Loading @@ -2128,6 +2153,9 @@ class Compiler : public ErrorSink { pGen->storeR0(n); } else if (tok != '(') { /* variable */ if (!n) { error("Undefined variable %s", tString.getUnwrapped()); } pGen->loadR0(n, tokl == 11, tokc); if (tokl == 11) { next(); Loading Loading @@ -2216,7 +2244,7 @@ class Compiler : public ErrorSink { return pGen->gtst(0, 0); } void block(intptr_t l) { void block(intptr_t l, bool outermostFunctionBlock) { intptr_t a, n, t; if (tok == TOK_IF) { Loading @@ -2224,12 +2252,12 @@ class Compiler : public ErrorSink { skip('('); a = test_expr(); skip(')'); block(l); block(l, false); if (tok == TOK_ELSE) { next(); n = pGen->gjmp(0); /* jmp */ pGen->gsym(a); block(l); block(l, false); pGen->gsym(n); /* patch else jmp */ } else { pGen->gsym(a); /* patch if test */ Loading Loading @@ -2259,18 +2287,22 @@ class Compiler : public ErrorSink { } } skip(')'); block((intptr_t) &a); block((intptr_t) &a, false); pGen->gjmp(n - codeBuf.getPC() - pGen->jumpOffset()); /* jmp */ pGen->gsym(a); } else if (tok == '{') { if (! outermostFunctionBlock) { mSymbolTable.pushLevel(); } next(); /* declarations */ localDeclarations(); while (tok != '}' && tok != EOF) block(l); block(l, false); skip('}'); if (! outermostFunctionBlock) { mSymbolTable.popLevel(); } } else { if (tok == TOK_RETURN) { next(); Loading Loading @@ -2350,18 +2382,22 @@ class Compiler : public ErrorSink { } } void defineGlobalSymbol() { if (tok == TOK_UNDEFINED_SYMBOL) { // TODO: don't allow multiple definitions at same level. void addGlobalSymbol() { tok = (intptr_t) mSymbolTable.addGlobal( new String(mTokenString)); reportIfDuplicate(); } void reportIfDuplicate() { if (!tok) { error("Duplicate definition of %s", mTokenString.getUnwrapped()); } } void defineLocalSymbol() { // TODO: don't allow multiple definitions at same level. void addLocalSymbol() { tok = (intptr_t) mSymbolTable.addLocal( new String(mTokenString)); reportIfDuplicate(); } void localDeclarations() { Loading @@ -2371,10 +2407,11 @@ class Compiler : public ErrorSink { while (acceptType(base)) { while (tok != ';') { Type t = acceptPointerDeclaration(t); defineLocalSymbol(); addLocalSymbol(); if (tok) { loc = loc + 4; *(int *) tok = -loc; } next(); if (tok == ',') next(); Loading @@ -2388,29 +2425,39 @@ class Compiler : public ErrorSink { Type base; expectType(base); Type t = acceptPointerDeclaration(t); defineGlobalSymbol(); if (tok == TOK_UNDEFINED_SYMBOL) { addGlobalSymbol(); } VariableInfo* name = (VariableInfo*) tok; if (name && name->pAddress) { error("Already defined global %s", mTokenString.getUnwrapped()); } next(); if (tok == ',' || tok == ';') { // it's a variable declaration for(;;) { if (name) { name->pAddress = (int*) allocGlobalSpace(4); } if (tok != ',') { break; } skip(','); t = acceptPointerDeclaration(t); defineGlobalSymbol(); addGlobalSymbol(); name = (VariableInfo*) tok; next(); } skip(';'); } else { if (name) { /* patch forward references (XXX: does not work for function pointers) */ pGen->gsym((int) name->pForward); /* put function address */ name->pAddress = (void*) codeBuf.getPC(); } skip('('); mSymbolTable.pushLevel(); intptr_t a = 8; Loading @@ -2419,10 +2466,12 @@ class Compiler : public ErrorSink { Type aType; expectType(aType); aType = acceptPointerDeclaration(aType); defineLocalSymbol(); addLocalSymbol(); if (tok) { /* read param name and compute offset */ *(int *) tok = a; a = a + 4; } next(); if (tok == ',') next(); Loading @@ -2431,7 +2480,7 @@ class Compiler : public ErrorSink { skip(')'); rsym = loc = 0; a = pGen->functionEntry(argCount); block(0); block(0, true); pGen->gsym(rsym); pGen->functionExit(argCount, a, loc); mSymbolTable.popLevel(); Loading Loading @@ -2551,6 +2600,7 @@ public: inp(); next(); globalDeclarations(); checkForUndefinedForwardReferences(); result = pGen->finishCompile(); if (result == 0) { if (mErrorBuf.len()) { Loading @@ -2560,6 +2610,27 @@ public: return result; } void checkForUndefinedForwardReferences() { mSymbolTable.forEachGlobal(static_ufrcFn, this); } static bool static_ufrcFn(String* key, VariableInfo* value, void* context) { Compiler* pCompiler = (Compiler*) context; return pCompiler->undefinedForwardReferenceCheck(key, value); } bool undefinedForwardReferenceCheck(String* key, VariableInfo* value) { #if 0 fprintf(stderr, "%s 0x%8x 0x%08x\n", key->getUnwrapped(), value->pAddress, value->pForward); #endif if (!value->pAddress && value->pForward) { error("Undefined forward reference: %s", key->getUnwrapped()); } return true; } int dump(FILE* out) { fwrite(codeBuf.getBase(), 1, codeBuf.getSize(), out); return 0; Loading
libacc/tests/data/locals.c +8 −2 Original line number Diff line number Diff line Loading @@ -2,7 +2,9 @@ int a; int f() { int a; printf("f 0: a = %d b = %d\n", a, b); // Undefined variable b // printf("f 0: a = %d b = %d\n", a, b); printf("f 0: a = %d\n", a); a = 2; printf("f 1: a = %d\n", a); } Loading @@ -14,19 +16,23 @@ int g(int a) { } int h(int a) { int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol // int a; // gcc 4.3 says error: 'a' redeclared as different kind of symbol printf("h 0: a = %d\n", a); a = 4; printf("h 1: a = %d\n", a); } // Already defined global // int h() {} int globCheck() { fprintf(stdout, "globCheck()\n"); } int fwdCheck() { b(); // Undefined forward reference // c(); } int b() { Loading