void Jovial_to_C::translateProgramHeaderStatement(SgProgramHeaderStatement* programHeaderStatement) { // Get scopeStatement from SgProgramHeaderStatement SgScopeStatement* scopeStatement = programHeaderStatement->get_scope(); ROSE_ASSERT(scopeStatement); // Get ParameterList and DecoratorList SgFunctionParameterList* functionParameterList = buildFunctionParameterList(); SgExprListExp* decoratorList = deepCopy(programHeaderStatement->get_decoratorList()); // Reuse FunctionDefinition from Fortran programHeaderStatement SgFunctionDefinition* functionDefinition = programHeaderStatement->get_definition(); // Get basicBlock from SgProgramHeaderStatement SgBasicBlock* basicBlock = functionDefinition->get_body(); ROSE_ASSERT(basicBlock); SgSymbolTable* symbolTable = basicBlock->get_symbol_table(); ROSE_ASSERT(symbolTable); // The main function return type is int SgType* mainType = SgTypeInt::createType(); // Remove original function symbol. Keep the new function symbol with name of "main" SgFunctionSymbol* functionSymbol = isSgFunctionSymbol(scopeStatement->lookup_symbol(programHeaderStatement->get_name())); SgSymbolTable* globalSymbolTable = isSgSymbolTable(functionSymbol->get_parent()); globalSymbolTable->remove(functionSymbol); functionSymbol->set_parent(NULL); delete(functionSymbol); // Create SgFunctionDeclaration for C main function. Name must be "main". SgFunctionDeclaration* cFunctionDeclaration = buildDefiningFunctionDeclaration("main", mainType, functionParameterList, scopeStatement); // Setup the C function declaration. removeList.push_back(cFunctionDeclaration->get_definition()); functionDefinition->set_parent(cFunctionDeclaration); cFunctionDeclaration->set_definition(functionDefinition); programHeaderStatement->set_definition(NULL); // Replace the SgProgramHeaderStatement with SgFunctionDeclaration. replaceStatement(programHeaderStatement,cFunctionDeclaration,true); cFunctionDeclaration->set_decoratorList(decoratorList); // cFunctionDeclaration->set_startOfConstruct(functionDefinition->get_startOfConstruct()); // cFunctionDeclaration->set_endOfConstruct(functionDefinition->get_endOfConstruct()); // cFunctionDeclaration->get_file_info()->set_physical_filename(cFunctionDeclaration->get_file_info()->get_filenameString()); programHeaderStatement->set_parent(NULL); } // End of Jovial_to_C::translateProgramHeaderStatement
virtual void visit(SgNode* n) { SgLabelStatement* l = isSgLabelStatement(n); if (l) { SgName name = l->get_label(); // The label is in some inner scope, and needs to be moved to the // enclosing function definition SgSymbolTable* st = l->get_scope()->get_symbol_table(); ROSE_ASSERT (st); ROSE_ASSERT (st->find_label(name)); st->remove(st->find_label(name)); name << "__" << ++labelRenameCounter; // cout << "Found label " << l->get_label().getString() << " to rename to " << name.getString() << endl; l->set_label(name); l->set_scope(newScope); SgLabelSymbol* lSym = new SgLabelSymbol(l); lSym->set_parent(symtab); symtab->insert(name, lSym); } }
virtual void visit(SgNode* n) { if (isSgFunctionDefinition(n)) { renameLabels(isSgFunctionDefinition(n), isSgFunctionDefinition(n)); } else if (isSgInitializedName(n)) { SgInitializedName* n2 = isSgInitializedName(n); ROSE_ASSERT(n2->get_file_info() != NULL); if (isMemberVariable(*n2)) return; // JW (7/16/2004): Added patch if (isSgVariableDeclaration(n2->get_parent())) { SgVariableDeclaration* decl = isSgVariableDeclaration(n2->get_parent()); if (isSgGlobal(decl->get_parent())) return; if (isSgNamespaceDefinitionStatement(decl->get_parent())) return; } if (isSgCtorInitializerList(n2->get_parent())) return; if (n2->get_name().getString() == "") return; SgName name(n2->get_name()); SgSymbolTable* symtab = n2->get_scope()->get_symbol_table(); SgSymbol* sym = symtab->find(n2); if (sym) { symtab->remove(sym); } name << "__" << counter++; n2->set_name(name); SgVariableSymbol* n2symbol = new SgVariableSymbol(n2); n2symbol->set_parent(symtab); symtab->insert(name, n2symbol); // printf ("RenameVariablesVisitor(): name = %s scope = %p = %s \n",name.str(),savedScope,savedScope->class_name().c_str()); ROSE_ASSERT(n2->get_parent() != NULL); ROSE_ASSERT(n2->get_file_info() != NULL); } }
void FixupAstSymbolTables::visit ( SgNode* node ) { // DQ (6/27/2005): Output the local symbol table from each scope. // printf ("node = %s \n",node->sage_class_name()); SgScopeStatement* scope = isSgScopeStatement(node); if (scope != NULL) { #if 0 printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str()); #endif SgSymbolTable* symbolTable = scope->get_symbol_table(); if (symbolTable == NULL) { #if 0 printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str()); scope->get_file_info()->display("Symbol Table Location"); #endif SgSymbolTable* tempSymbolTable = new SgSymbolTable(); ROSE_ASSERT(tempSymbolTable != NULL); // name this table as compiler generated! The name is a static member used to store // state for the next_symbol() functions. It is meaningless to set these. // tempSymbolTable->set_name("compiler-generated symbol table"); scope->set_symbol_table(tempSymbolTable); // reset the symbolTable using the get_symbol_table() member function symbolTable = scope->get_symbol_table(); ROSE_ASSERT(symbolTable != NULL); // DQ (2/16/2006): Set this parent directly (now tested) symbolTable->set_parent(scope); ROSE_ASSERT(symbolTable->get_parent() != NULL); } ROSE_ASSERT(symbolTable != NULL); if (symbolTable->get_parent() == NULL) { printf ("Warning: Fixing up symbolTable, calling symbolTable->set_parent() (parent not previously set) \n"); symbolTable->set_parent(scope); } ROSE_ASSERT(symbolTable->get_parent() != NULL); // Make sure that the internal hash table used in the symbol table is also present! if (symbolTable->get_table() == NULL) { // DQ (6/27/2005): There are a lot of these built, perhaps more than we really need! #if 0 printf ("AST Fixup: Building internal Symbol Table hash table (rose_hash_multimap) for %p = %s at: \n", scope,scope->sage_class_name()); scope->get_file_info()->display("Symbol Table Location"); #endif rose_hash_multimap* internalHashTable = new rose_hash_multimap(); ROSE_ASSERT(internalHashTable != NULL); symbolTable->set_table(internalHashTable); } ROSE_ASSERT(symbolTable->get_table() != NULL); SgSymbolTable::BaseHashType* internalTable = symbolTable->get_table(); ROSE_ASSERT(internalTable != NULL); // DQ (6/23/2011): Note: Declarations that reference types that have not been seen yet may be placed into the // wronge scope, then later when we see the correct scope we have a symbol in two or more symbol tables. The // code below detects and fixes this problem. // DQ (6/16/2011): List of symbols we need to remove from symbol tables where they are multibily represented. std::vector<SgSymbol*> listOfSymbolsToRemove; // DQ (6/12/2011): Fixup symbol table by removing symbols that are not associated with a declaration in the current scope. int idx = 0; SgSymbolTable::hash_iterator i = internalTable->begin(); while (i != internalTable->end()) { // DQ: removed SgName casting operator to char* // cout << "[" << idx << "] " << (*i).first.str(); ROSE_ASSERT ( (*i).first.str() != NULL ); ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); // printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) sage_class_name() = %s \n", // idx,(*i).first.str(),(*i).second->sage_class_name()); SgSymbol* symbol = isSgSymbol((*i).second); ROSE_ASSERT ( symbol != NULL ); // We have to look at each type of symbol separately! This is because there is no virtual function, // the reason for this is that each get_declaration() function returns a different type! // ROSE_ASSERT ( symbol->get_declaration() != NULL ); switch(symbol->variantT()) { case V_SgClassSymbol: { SgClassSymbol* classSymbol = isSgClassSymbol(symbol); ROSE_ASSERT(classSymbol != NULL); ROSE_ASSERT(classSymbol->get_declaration() != NULL); SgDeclarationStatement* declarationToFindInScope = NULL; // Search for the declaration in the associated scope. declarationToFindInScope = classSymbol->get_declaration(); ROSE_ASSERT(declarationToFindInScope != NULL); SgClassDeclaration* classDeclaration = isSgClassDeclaration(declarationToFindInScope); ROSE_ASSERT(classDeclaration != NULL); SgName name = classDeclaration->get_name(); // SgType* declarationType = declarationToFindInScope->get_type(); SgType* declarationType = classDeclaration->get_type(); ROSE_ASSERT(declarationType != NULL); if (declarationToFindInScope->get_definingDeclaration() != NULL) { declarationToFindInScope = declarationToFindInScope->get_definingDeclaration(); SgClassDeclaration* definingClassDeclaration = isSgClassDeclaration(declarationToFindInScope); ROSE_ASSERT(definingClassDeclaration != NULL); // SgType* definingDeclarationType = declarationToFindInScope->get_type(); SgType* definingDeclarationType = definingClassDeclaration->get_type(); ROSE_ASSERT(definingDeclarationType != NULL); // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C // A simple rule that all declarations should follow (now that we have proper global type tables). // ROSE_ASSERT(definingDeclarationType == declarationType); if (definingDeclarationType != declarationType) { printf ("In fixupSymbolTables.C: Note that definingDeclarationType != declarationType \n"); } } SgNamedType* namedType = isSgNamedType(declarationType); ROSE_ASSERT(namedType != NULL); SgDeclarationStatement* declarationAssociatedToType = namedType->get_declaration(); ROSE_ASSERT(declarationAssociatedToType != NULL); #if 0 printf ("Found a symbol without a matching declaration in the current scope (declList): declarationToFindInScope = %p = %s \n",declarationToFindInScope,declarationToFindInScope->class_name().c_str()); printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) class_name() = %s \n",idx,(*i).first.str(),(*i).second->class_name().c_str()); #endif SgScopeStatement* scopeOfDeclarationToFindInScope = declarationToFindInScope->get_scope(); SgScopeStatement* scopeOfDeclarationAssociatedWithType = declarationAssociatedToType->get_scope(); #if 0 printf ("declarationToFindInScope = %p declarationToFindInScope->get_scope() = %p = %s \n",declarationToFindInScope,declarationToFindInScope->get_scope(),declarationToFindInScope->get_scope()->class_name().c_str()); printf ("declarationAssociatedToType = %p declarationAssociatedToType->get_scope() = %p = %s \n",declarationAssociatedToType,declarationAssociatedToType->get_scope(),declarationAssociatedToType->get_scope()->class_name().c_str()); #endif if (scopeOfDeclarationToFindInScope != scopeOfDeclarationAssociatedWithType) { // DQ (6/12/2011): Houston, we have a problem! The trick is to fix it... // A symbol has been placed into a scope when we could not be certain which scope it should be placed. // We have a default of placing such symbols into the global scope, but it might be better to just have // a special scope where such symbols could be placed so that we could have them separate from the global // scope and then fix them up more clearly. // Note that test2011_80.C still fails but the AST is at least correct (I think). SgGlobal* scopeOfDeclarationToFindInScope_GlobalScope = isSgGlobal(scopeOfDeclarationToFindInScope); // SgGlobal* scopeOfDeclarationAssociatedWithType_GlobalScope = isSgGlobal(scopeOfDeclarationAssociatedWithType); if (scopeOfDeclarationToFindInScope_GlobalScope != NULL) { // In general which ever scope is the global scope is where the error is...??? // This is because when we don't know where to put a symbol (e.g. from a declaration of a pointer) we put it into global scope. // There is even an agrument that this is correct as a default for C/C++, but only if it must exist (see test2011_80.C). // Remove the symbol from the symbol table of the global scope. printf ("Remove the associated symbol in the current symbol table \n"); // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope()); if (declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope()) printf ("In fixupSymbolTables.C: Note that declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope() \n"); } else { listOfSymbolsToRemove.push_back(classSymbol); } } // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope()); break; } default: { // It night be there are are no other types of symbols to consider... // printf ("Ignoring non SgClassSymbols (fixupSymbolTables.C) symbol = %s \n",symbol->class_name().c_str()); // ROSE_ASSERT(false); } } // Increment iterator! i++; // Increment counter! idx++; } // DQ (6/18/2011): Now that we are through with the symbol table we can support removal of any // identified problematic symbol without worrying about STL iterator invalidation. for (size_t j = 0; j < listOfSymbolsToRemove.size(); j++) { // Remove these symbols. SgSymbol* removeSymbol = listOfSymbolsToRemove[j]; ROSE_ASSERT(removeSymbol != NULL); SgSymbolTable* associatedSymbolTable = isSgSymbolTable(removeSymbol->get_parent()); ROSE_ASSERT(associatedSymbolTable != NULL); ROSE_ASSERT(associatedSymbolTable == symbolTable); associatedSymbolTable->remove(removeSymbol); printf ("Redundant symbol removed...from symbol table \n"); // ROSE_ASSERT(false); } #if 0 // debugging symbolTable->print("In FixupAstSymbolTables::visit(): printing out the symbol tables"); #endif } }