virtual void visit(SgNode* node) { if (isSgBasicBlock(node)) { SgBasicBlock* c = isSgBasicBlock(node); SgStatementPtrList newStatements; for (SgStatementPtrList::const_iterator i = c->get_statements().begin(); i != c->get_statements().end(); ++i) { if (isSgBasicBlock(*i)) { SgBasicBlock* c2 = isSgBasicBlock(*i); const SgStatementPtrList& c2Stmts = c2->get_statements(); // We need to prevent a declaration from immediately following a label, as that is illegal if (!newStatements.empty() && isSgLabelStatement(newStatements.back()) && !c2Stmts.empty() && isSgVariableDeclaration(c2Stmts.front())) { newStatements.push_back(SageBuilder::buildExprStatement(SageBuilder::buildNullExpression())); } newStatements.insert(newStatements.end(), isSgBasicBlock(*i)->get_statements().begin(), isSgBasicBlock(*i)->get_statements().end()); } else { if (!newStatements.empty() && isSgLabelStatement(newStatements.back()) && isSgVariableDeclaration(*i)) { newStatements.push_back(SageBuilder::buildExprStatement(SageBuilder::buildNullExpression())); } newStatements.push_back(*i); } } if (!newStatements.empty() && isSgLabelStatement(newStatements.back())) { // Prevent block from ending with a label newStatements.push_back(SageBuilder::buildExprStatement(SageBuilder::buildNullExpression())); } for (SgStatementPtrList::const_iterator i = newStatements.begin(); i != newStatements.end(); ++i) { (*i)->set_parent(c); } c->get_statements() = newStatements; c->get_symbol_table()->get_table()->clear(); SageInterface::rebuildSymbolTable(c); } }
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
void TransformationSupport::getTransformationOptions ( SgNode* astNode, list<OptionDeclaration> & generatedList, string identifingTypeName ) { // This function searches for variables of type ScopeBasedTransformationOptimization. Variables // of type ScopeBasedTransformationOptimization are used to communicate optimizations from the // application to the preprocessor. If called from a project or file object it traverses down to // the global scope of the file and searches only the global scope, if called from and other // location within the AST it searches the current scope and then traverses the parent nodes to // find all enclosing scopes until in reaches the global scope. At each scope it searches for // variables of type ScopeBasedTransformationOptimization. // printf ("######################### START OF TRANSFORMATION OPTION QUERY ######################## \n"); ROSE_ASSERT (astNode != NULL); ROSE_ASSERT (identifingTypeName.c_str() != NULL); #if 0 printf ("In getTransformationOptions(): astNode->sage_class_name() = %s generatedList.size() = %d \n", astNode->sage_class_name(),generatedList.size()); SgLocatedNode* locatedNode = isSgLocatedNode(astNode); if (locatedNode != NULL) { printf (" locatedNode->get_file_info()->get_filename() = %s \n",locatedNode->get_file_info()->get_filename()); printf (" locatedNode->get_file_info()->get_line() = %d \n",locatedNode->get_file_info()->get_line()); } #endif switch (astNode->variant()) { case ProjectTag: { SgProject* project = isSgProject(astNode); ROSE_ASSERT (project != NULL); //! Loop through all the files in the project and call the mainTransform function for each file int i = 0; for (i=0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); // printf ("Calling Query::traverse(SgFile,QueryFunctionType,QueryAssemblyFunctionType) \n"); getTransformationOptions ( file, generatedList, identifingTypeName ); } break; } case SourceFileTag: { SgSourceFile* file = isSgSourceFile(astNode); ROSE_ASSERT (file != NULL); SgGlobal* globalScope = file->get_globalScope(); ROSE_ASSERT (globalScope != NULL); ROSE_ASSERT (isSgGlobal(globalScope) != NULL); getTransformationOptions ( globalScope, generatedList, identifingTypeName ); break; } // Global Scope case GLOBAL_STMT: { SgGlobal* globalScope = isSgGlobal(astNode); ROSE_ASSERT (globalScope != NULL); SgSymbolTable* symbolTable = globalScope->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // printf ("Processed global scope, exiting .. \n"); // ROSE_ABORT(); break; } case SymbolTableTag: { // List the variable in each scope // printf ("List all the variables in this symbol table! \n"); SgSymbolTable* symbolTable = isSgSymbolTable(astNode); ROSE_ASSERT (symbolTable != NULL); bool foundTransformationOptimizationSpecifier = false; // printf ("Now print out the information in the symbol table for this scope: \n"); // symbolTable->print(); #if 0 // I don't know when a SymbolTable is given a name! printf ("SymbolTable has a name = %s \n", (symbolTable->get_no_name()) ? "NO: it has no name" : "YES: it does have a name"); if (!symbolTable->get_no_name()) printf ("SymbolTable name = %s \n",symbolTable->get_name().str()); else ROSE_ASSERT (symbolTable->get_name().str() == NULL); #endif if (symbolTable->get_table() != NULL) { SgSymbolTable::hash_iterator i = symbolTable->get_table()->begin(); int counter = 0; while (i != symbolTable->get_table()->end()) { ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); // printf ("Initial info: number: %d pair.first (SgName) = %s pair.second (SgSymbol) sage_class_name() = %s \n", // counter,(*i).first.str(),(*i).second->sage_class_name()); SgSymbol* symbol = isSgSymbol((*i).second); ROSE_ASSERT ( symbol != NULL ); SgType* type = symbol->get_type(); ROSE_ASSERT ( type != NULL ); SgNamedType* namedType = isSgNamedType(type); string typeName; if (namedType != NULL) { SgName n = namedType->get_name(); typeName = namedType->get_name().str(); // char* nameString = namedType->get_name().str(); // printf ("Type is: (named type) = %s \n",nameString); ROSE_ASSERT (identifingTypeName.c_str() != NULL); // ROSE_ASSERT (typeName != NULL); // printf ("In getTransformationOptions(): typeName = %s identifingTypeName = %s \n",typeName.c_str(),identifingTypeName.c_str()); // if ( (typeName != NULL) && ( typeName == identifingTypeName) ) if ( typeName == identifingTypeName ) { // Now look at the parameter list to the constructor and save the // values into the list. // printf ("Now save the constructor arguments! \n"); SgVariableSymbol* variableSymbol = isSgVariableSymbol(symbol); if ( variableSymbol != NULL ) { SgInitializedName* initializedNameDeclaration = variableSymbol->get_declaration(); ROSE_ASSERT (initializedNameDeclaration != NULL); SgDeclarationStatement* declarationStatement = initializedNameDeclaration->get_declaration(); ROSE_ASSERT (declarationStatement != NULL); SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(declarationStatement); ROSE_ASSERT (variableDeclaration != NULL); getTransformationOptionsFromVariableDeclarationConstructorArguments(variableDeclaration,generatedList); foundTransformationOptimizationSpecifier = true; // printf ("Exiting after saving the constructor arguments! \n"); // ROSE_ABORT(); } else { #if 0 printf ("Not a SgVariableSymbol: symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif } } else { #if 0 printf ("typeName != identifingTypeName : symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif #if 0 // I don't think this should ever be NULL (but it is sometimes) if (typeName != NULL) printf ("typeName == NULL \n"); #endif } } else { typeName = (char *)type->sage_class_name(); } // printf ("In while loop at the base: counter = %d \n",counter); i++; counter++; } } else { // printf ("Pointer to symbol table is NULL \n"); } // printf ("foundTransformationOptimizationSpecifier = %s \n",foundTransformationOptimizationSpecifier ? "true" : "false"); // SgSymbolTable objects don't have a parent node (specifically they lack a get_parent // member function in the interface)! break; } case BASIC_BLOCK_STMT: { // List the variable in each scope // printf ("List all the variables in this scope! \n"); SgBasicBlock* basicBlock = isSgBasicBlock(astNode); ROSE_ASSERT (basicBlock != NULL); SgSymbolTable* symbolTable = basicBlock->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // Next go (fall through this case) to the default case so that we traverse the parent // of the SgBasicBlock. // break; } default: // Most cases will be the default (this is by design) // printf ("default in switch found in globalQueryGetListOperandStringFunction() (sage_class_name = %s) \n",astNode->sage_class_name()); // Need to recursively backtrack through the parents until we reach the SgGlobal (global scope) SgStatement* statement = isSgStatement(astNode); if (statement != NULL) { SgNode* parentNode = statement->get_parent(); ROSE_ASSERT (parentNode != NULL); // printf ("parent = %p parentNode->sage_class_name() = %s \n",parentNode,parentNode->sage_class_name()); SgStatement* parentStatement = isSgStatement(parentNode); if (parentStatement == NULL) { printf ("parentStatement == NULL: statement (%p) is a %s \n",statement,statement->sage_class_name()); printf ("parentStatement == NULL: statement->get_file_info()->get_filename() = %s \n",statement->get_file_info()->get_filename()); printf ("parentStatement == NULL: statement->get_file_info()->get_line() = %d \n",statement->get_file_info()->get_line()); } ROSE_ASSERT (parentStatement != NULL); // Call this function recursively (directly rather than through the query mechanism) getTransformationOptions ( parentStatement, generatedList, identifingTypeName ); } else { // printf ("astNode is not a SgStatement! \n"); } break; } #if 0 printf ("At BASE of getTransformationOptions(): astNode->sage_class_name() = %s size of generatedList = %d \n", astNode->sage_class_name(),generatedList.size()); #endif // printf ("######################### END OF TRANSFORMATION OPTION QUERY ######################## \n"); }