diff --git a/decl.cpp b/decl.cpp index ae7e78a5..5ec58462 100644 --- a/decl.cpp +++ b/decl.cpp @@ -535,8 +535,6 @@ Declaration::GetVariableDeclarations() const { std::vector vars; for (unsigned int i = 0; i < declarators.size(); ++i) { - if (declarators[i] == NULL) - continue; Declarator *decl = declarators[i]; if (decl == NULL) // Ignore earlier errors @@ -545,11 +543,7 @@ Declaration::GetVariableDeclarations() const { Symbol *sym = decl->GetSymbol(); sym->type = sym->type->ResolveUnboundVariability(Type::Varying); - if (dynamic_cast(sym->type) != NULL) { - // function declaration - m->symbolTable->AddFunction(sym); - } - else { + if (dynamic_cast(sym->type) == NULL) { m->symbolTable->AddVariable(sym); vars.push_back(VariableDeclaration(sym, decl->initExpr)); } @@ -558,6 +552,28 @@ Declaration::GetVariableDeclarations() const { } +void +Declaration::DeclareFunctions() { + Assert(declSpecs->storageClass != SC_TYPEDEF); + + for (unsigned int i = 0; i < declarators.size(); ++i) { + Declarator *decl = declarators[i]; + if (decl == NULL) + // Ignore earlier errors + continue; + + Symbol *sym = decl->GetSymbol(); + sym->type = sym->type->ResolveUnboundVariability(Type::Varying); + + if (dynamic_cast(sym->type) == NULL) + continue; + + bool isInline = (declSpecs->typeQualifiers & TYPEQUAL_INLINE); + m->AddFunctionDeclaration(sym, isInline); + } +} + + void Declaration::Print(int indent) const { printf("%*cDeclaration: specs [", indent, ' '); diff --git a/decl.h b/decl.h index 272ccea2..2d7e662b 100644 --- a/decl.h +++ b/decl.h @@ -210,6 +210,10 @@ public: Declarator representation.) */ std::vector GetVariableDeclarations() const; + /** For any function declarations in the Declaration, add the + declaration to the module. */ + void DeclareFunctions(); + DeclSpecs *declSpecs; std::vector declarators; }; diff --git a/parse.yy b/parse.yy index 97cc6eff..07575948 100644 --- a/parse.yy +++ b/parse.yy @@ -494,6 +494,7 @@ declaration_statement $$ = NULL; } else { + $1->DeclareFunctions(); std::vector vars = $1->GetVariableDeclarations(); $$ = new DeclStmt(vars, @1); } diff --git a/sym.cpp b/sym.cpp index b33e8cbe..0647a5b4 100644 --- a/sym.cpp +++ b/sym.cpp @@ -72,8 +72,7 @@ SymbolTable::SymbolTable() { SymbolTable::~SymbolTable() { // Otherwise we have mismatched push/pop scopes - Assert(variables.size() == 1 && functions.size() == 1 && - types.size() == 1); + Assert(variables.size() == 1 && types.size() == 1); PopScope(); } @@ -81,7 +80,6 @@ SymbolTable::~SymbolTable() { void SymbolTable::PushScope() { variables.push_back(new SymbolMapType); - functions.push_back(new FunctionMapType); types.push_back(new TypeMapType); } @@ -92,10 +90,6 @@ SymbolTable::PopScope() { delete variables.back(); variables.pop_back(); - Assert(functions.size() > 1); - delete functions.back(); - functions.pop_back(); - Assert(types.size() > 1); delete types.back(); types.pop_back(); @@ -160,7 +154,7 @@ SymbolTable::AddFunction(Symbol *symbol) { // the symbol table return false; - std::vector &funOverloads = (*functions.back())[symbol->name]; + std::vector &funOverloads = functions[symbol->name]; funOverloads.push_back(symbol); return true; } @@ -168,17 +162,14 @@ SymbolTable::AddFunction(Symbol *symbol) { bool SymbolTable::LookupFunction(const char *name, std::vector *matches) { - for (int i = (int)functions.size() - 1; i >= 0; --i) { - FunctionMapType &fm = *(functions[i]); - FunctionMapType::iterator iter = fm.find(name); - if (iter != fm.end()) { - if (matches == NULL) - return true; - else { - const std::vector &funcs = iter->second; - for (int j = 0; j < (int)funcs.size(); ++j) - matches->push_back(funcs[j]); - } + FunctionMapType::iterator iter = functions.find(name); + if (iter != functions.end()) { + if (matches == NULL) + return true; + else { + const std::vector &funcs = iter->second; + for (int j = 0; j < (int)funcs.size(); ++j) + matches->push_back(funcs[j]); } } return matches ? (matches->size() > 0) : false; @@ -187,15 +178,12 @@ SymbolTable::LookupFunction(const char *name, std::vector *matches) { Symbol * SymbolTable::LookupFunction(const char *name, const FunctionType *type) { - for (int i = (int)functions.size() - 1; i >= 0; --i) { - FunctionMapType &fm = *(functions[i]); - FunctionMapType::iterator iter = fm.find(name); - if (iter != fm.end()) { - std::vector funcs = iter->second; - for (int j = 0; j < (int)funcs.size(); ++j) { - if (Type::Equal(funcs[j]->type, type)) - return funcs[j]; - } + FunctionMapType::iterator iter = functions.find(name); + if (iter != functions.end()) { + std::vector funcs = iter->second; + for (int j = 0; j < (int)funcs.size(); ++j) { + if (Type::Equal(funcs[j]->type, type)) + return funcs[j]; } } return NULL; @@ -261,14 +249,11 @@ SymbolTable::ClosestVariableOrFunctionMatch(const char *str) const { } } - for (int i = 0; i < (int)functions.size(); ++i) { - const FunctionMapType &fm = *(functions[i]); - FunctionMapType::const_iterator iter; - for (iter = fm.begin(); iter != fm.end(); ++iter) { - int dist = StringEditDistance(str, iter->first, maxDelta+1); - if (dist <= maxDelta) - matches[dist].push_back(iter->first); - } + FunctionMapType::const_iterator iter; + for (iter = functions.begin(); iter != functions.end(); ++iter) { + int dist = StringEditDistance(str, iter->first, maxDelta+1); + if (dist <= maxDelta) + matches[dist].push_back(iter->first); } // Now, return the first entry of matches[] that is non-empty, if any. @@ -346,15 +331,13 @@ SymbolTable::Print() { } fprintf(stderr, "Functions:\n----------------\n"); - for (int i = 0; i < (int)functions.size(); ++i) { - FunctionMapType::iterator fiter = functions[i]->begin(); - while (fiter != functions[i]->end()) { - fprintf(stderr, "%s\n", fiter->first.c_str()); - std::vector &syms = fiter->second; - for (unsigned int j = 0; j < syms.size(); ++j) - fprintf(stderr, " %s\n", syms[j]->type->GetString().c_str()); - ++fiter; - } + FunctionMapType::iterator fiter = functions.begin(); + while (fiter != functions.end()) { + fprintf(stderr, "%s\n", fiter->first.c_str()); + std::vector &syms = fiter->second; + for (unsigned int j = 0; j < syms.size(); ++j) + fprintf(stderr, " %s\n", syms[j]->type->GetString().c_str()); + ++fiter; } depth = 0; diff --git a/sym.h b/sym.h index 97f5efd7..aff0553c 100644 --- a/sym.h +++ b/sym.h @@ -257,12 +257,13 @@ private: typedef std::map SymbolMapType; std::vector variables; - /** Function declarations are also scoped., A STL \c vector is used to - store the function symbols for a given name since, due to function - overloading, a name can have multiple function symbols associated - with it. */ + /** Function declarations are *not* scoped. (C99, for example, allows + an implementation to maintain function declarations in a single + namespace.) A STL \c vector is used to store the function symbols + for a given name since, due to function overloading, a name can + have multiple function symbols associated with it. */ typedef std::map > FunctionMapType; - std::vector functions; + FunctionMapType functions; /** Type definitions can also be scoped. A new \c TypeMapType is added to the back of the \c types \c vector each time a new scope @@ -278,15 +279,12 @@ SymbolTable::GetMatchingFunctions(Predicate pred, std::vector *matches) const { // Iterate through all function symbols and apply the given predicate. // If it returns true, add the Symbol * to the provided vector. - for (unsigned int i = 0; i < functions.size(); ++i) { - FunctionMapType &fm = *(functions[i]); - FunctionMapType::const_iterator iter; - for (iter = fm.begin(); iter != fm.end(); ++iter) { - const std::vector &syms = iter->second; - for (unsigned int j = 0; j < syms.size(); ++j) { - if (pred(syms[j])) - matches->push_back(syms[j]); - } + FunctionMapType::const_iterator iter; + for (iter = functions.begin(); iter != functions.end(); ++iter) { + const std::vector &syms = iter->second; + for (unsigned int j = 0; j < syms.size(); ++j) { + if (pred(syms[j])) + matches->push_back(syms[j]); } } }