void MyTraversal::visit ( SgNode* astNode ) { SgBasicBlock* bb = isSgBasicBlock(astNode); SgGlobal *sg=isSgGlobal(astNode); string symbol_id="foo"; string incstr="#include \"newadinc.h\""; if (bb!=NULL) { // insert declaration double foo; // on top of this block Sg_File_Info * finfo=new Sg_File_Info(bb->getFileName(), 1,1); SgName sgnm(symbol_id.c_str()); SgType * ptype = new SgTypeDouble(); SgVariableDeclaration *sgdecl=new SgVariableDeclaration(finfo,sgnm, ptype); bb->prepend_statement(sgdecl); // MiddleLevelRewrite::insert(bb, sgdecl->unparseToString(),MidLevelCollectionTypedefs::TopOfCurrentScope); } else { if(sg!=NULL) { MiddleLevelRewrite::insert(sg,incstr, MidLevelCollectionTypedefs::TopOfCurrentScope); } } }
void RtedTransformation::insertVariableCreateInitForParams( SgFunctionDefinition& fndef) { SgBasicBlock* body = fndef.get_body(); ROSE_ASSERT( body); SgInitializedNamePtrList names = fndef.get_declaration()->get_parameterList()->get_args(); BOOST_FOREACH( SgInitializedName* param, names) { SgType* initType = param->get_type(); // nov2010 code: // reference variables don't allocate new memory // if we call createVariable the RTS will think it's a double // allocation fault // \pp we skip array types because they will be handled elsewhere // \todo not sure if this is correct here, b/c arrays would decay // to pointers anyway. However, this decay is not represented // in the nov2010 code, thus we skip these initializations // here. if ( isSgReferenceType(initType) || isSgArrayType(skip_ModifierType(initType)) ) continue; SgFunctionDeclaration* fndecl = fndef.get_declaration(); std::cerr << ">>> " << fndecl->get_name() << std::endl; ROSE_ASSERT(isSgFunctionDefinition(param->get_scope())); body->prepend_statement( buildVariableCreateCallStmt(param, true) ); }
ClastToSage::ClastToSage(SgScopeStatement* scopScope, clast_stmt* root, scoplib_scop_p scoplibScop, PolyRoseOptions& options) { //SgScopeStatement* scope = isSgScopeStatement((SgNode*) scoplibScop->usr); _polyoptions = options; SgScopeStatement* scope = scopScope; ROSE_ASSERT(scope); m_scopRoot = NULL; /// OLD: m_scope = scope; m_scoplib_scop = scoplibScop; m_verbose = _polyoptions.isVerbose(); // 0- Retrive meta information stored as an annotation of the // SageAST root. SgStatement* scopRoot = isSgStatement((SgNode*)(scoplibScop->usr)); ScopRootAnnotation* annot = (ScopRootAnnotation*)(scopRoot->getAttribute("ScopRoot")); ROSE_ASSERT(annot); _fakeSymbolMap = annot->fakeSymbolMap; // 1- Collect all iterators in the clast. They are of the from 'cXX' // where XX is an integer. _scoplibIterators = collectAllIterators(root); // 2- Map clast iterator to new variables that does not conflict // with existing names, and register the symbols in the symbol // table. _sageIterators = createNewIterators(_scoplibIterators, scope); // 3- Create the basic block containing the transformed scop. SgBasicBlock* bb = buildBasicBlock(root); // 4- Update the variable scope with the new bb, and insert the // declaration statement in the AST. std::map<const char*, SgVariableDeclaration*>::iterator iter; Rose_STL_Container<SgNode*> varRefs = NodeQuery::querySubTree(bb,V_SgVarRefExp); for(iter = _sageIterators.begin(); iter != _sageIterators.end(); ++iter) { // Deal with the symbol tables. SgInitializedNamePtrList& l = iter->second->get_variables(); for (SgInitializedNamePtrList::iterator i = l.begin(); i != l.end(); i++) { (*i)->set_scope(bb); SgVariableSymbol* sym = new SgVariableSymbol(*i); bb->insert_symbol((*i)->get_name(), sym); // Ugly hack: replace the old symbol with the new entry in // the symbol table. for (Rose_STL_Container<SgNode *>::iterator j = varRefs.begin(); j != varRefs.end(); j++) { SgVarRefExp *vRef = isSgVarRefExp((*j)); if (vRef->get_symbol()->get_name() == (*i)->get_name()) vRef->set_symbol(sym); } } // Insert the declaration statement in the BB. bb->prepend_statement(iter->second); } // Post-process for pragma insertion. if (options.getGeneratePragmas()) insertPragmas(bb); m_scopRoot = bb; }
void SgNode::insertSourceCode ( SgProject & project, const char* sourceCodeString, const char* localDeclaration, const char* globalDeclaration, bool locateNewCodeAtTop, bool isADeclaration ) { // If this function is useful only for SgBasicBlock then it should be put into that class directly. // This function is used to insert code into AST object for which insertion make sense: // (specifically any BASIC_BLOCK_STMT) if (variant() != BASIC_BLOCK_STMT) { printf ("ERROR: insert only make since for BASIC_BLOCK_STMT statements (variant() == variant()) \n"); ROSE_ABORT(); } SgBasicBlock* currentBlock = isSgBasicBlock(this); ROSE_ASSERT (currentBlock != NULL); // printf ("##### Calling SgNode::generateAST() \n"); #if 0 printf ("In insertSourceCode(): globalDeclaration = \n%s\n",globalDeclaration); printf ("In insertSourceCode(): localDeclaration = \n%s\n",localDeclaration); printf ("In insertSourceCode(): sourceCodeString = \n%s\n",sourceCodeString); #endif // SgNode* newTransformationAST = generateAST (project,sourceCodeString,globalDeclaration); // ROSE_ASSERT (newTransformationAST != NULL); SgStatementPtrList* newTransformationStatementListPtr = generateAST (project,sourceCodeString,localDeclaration,globalDeclaration,isADeclaration); ROSE_ASSERT (newTransformationStatementListPtr != NULL); ROSE_ASSERT (newTransformationStatementListPtr->size() > 0); // printf ("##### DONE: Calling SgNode::generateAST() \n"); // get a reference to the statement list out of the basic block SgStatementPtrList & currentStatementList = currentBlock->get_statements(); if (locateNewCodeAtTop == true) { // Insert at top of list (pull the elements off the bottom of the new statement list to get the order correct // printf ("Insert new statements (new statement list size = %d) at the top of the block (in reverse order to preset the order in the final block) \n",newTransformationStatementListPtr->size()); SgStatementPtrList::reverse_iterator transformationStatementIterator; for (transformationStatementIterator = newTransformationStatementListPtr->rbegin(); transformationStatementIterator != newTransformationStatementListPtr->rend(); transformationStatementIterator++) { // Modify where a statement is inserted to avoid dependent variables from being inserted // before they are declared. // Get a list of the variables // Generate the list of types used within the target subtree of the AST list<string> typeNameStringList = NameQuery::getTypeNamesQuery ( *transformationStatementIterator ); int statementCounter = 0; int previousStatementCounter = 0; // Declaration furthest in source sequence of all variables referenced in code to be inserted (last in source sequence order) // SgStatementPtrList::iterator furthestDeclarationInSourceSequence = NULL; SgStatementPtrList::iterator furthestDeclarationInSourceSequence; #if 0 string unparsedDeclarationCodeString = (*transformationStatementIterator)->unparseToString(); ROSE_ASSERT (unparsedDeclarationCodeString.c_str() != NULL); printf ("unparsedDeclarationCodeString = %s \n",unparsedDeclarationCodeString.c_str()); #endif if ( typeNameStringList.size() > 0 ) { // There should be at least one type in the statement ROSE_ASSERT (typeNameStringList.size() > 0); // printf ("typeNameStringList.size() = %d \n",typeNameStringList.size()); // printf ("This statement has a dependence upon a variable of some type \n"); // Loop over all the types and get list of variables of each type // (so they can be declared properly when the transformation is compiled) list<string>::iterator typeListStringElementIterator; for (typeListStringElementIterator = typeNameStringList.begin(); typeListStringElementIterator != typeNameStringList.end(); typeListStringElementIterator++) { // printf ("Type = %s \n",(*typeListStringElementIterator).c_str()); // Find a list of names of variable of type (*listStringElementIterator) list<string> operandNameStringList = NameQuery::getVariableNamesWithTypeNameQuery ( *transformationStatementIterator, *typeListStringElementIterator ); // There should be at least one variable of that type in the statement ROSE_ASSERT (operandNameStringList.size() > 0); // printf ("operandNameStringList.size() = %d \n",operandNameStringList.size()); // Loop over all the types and get list of variable of each type list<string>::iterator variableListStringElementIterator; for (variableListStringElementIterator = operandNameStringList.begin(); variableListStringElementIterator != operandNameStringList.end(); variableListStringElementIterator++) { #if 0 printf ("Type = %s Variable = %s \n", (*typeListStringElementIterator).c_str(), (*variableListStringElementIterator).c_str()); #endif string variableName = *variableListStringElementIterator; string typeName = *typeListStringElementIterator; SgName name = variableName.c_str(); SgVariableSymbol* symbol = currentBlock->lookup_var_symbol(name); if ( symbol != NULL ) { // found a variable with name -- make sure that the declarations // represented by *transformationStatementIterator are inserted // after their declaration. #if 0 printf ("Found a valid symbol corresponding to Type = %s Variable = %s (must be defined in the local scope) \n", (*typeListStringElementIterator).c_str(), (*variableListStringElementIterator).c_str()); #endif ROSE_ASSERT (symbol != NULL); SgInitializedName* declarationInitializedName = symbol->get_declaration(); ROSE_ASSERT (declarationInitializedName != NULL); SgDeclarationStatement* declarationStatement = declarationInitializedName->get_declaration(); ROSE_ASSERT (declarationStatement != NULL); #if 0 printf ("declarationStatementString located at line = %d of file = %s \n", rose::getLineNumber(declarationStatement), rose::getFileName(declarationStatement)); string declarationStatementString = declarationStatement->unparseToString(); printf ("declarationStatementString = %s \n",declarationStatementString.c_str()); #endif statementCounter = 1; SgStatementPtrList::iterator i = currentStatementList.begin(); bool declarationFound = false; while ( ( i != currentStatementList.end() ) && ( declarationFound == false ) ) { // searching for the declarationStatement #if 0 printf ("statementCounter = %d previousStatementCounter = %d \n", statementCounter,previousStatementCounter); string currentStatementString = (*i)->unparseToString(); printf ("currentStatementString = %s \n",currentStatementString.c_str()); #endif if ( (*i == declarationStatement) && (statementCounter > previousStatementCounter) ) { // printf ("Found the declarationStatement at position (statementCounter = %d previousStatementCounter = %d) \n",statementCounter,previousStatementCounter); declarationFound = true; } else { // printf ("Not the declaration we are looking for! \n"); i++; statementCounter++; } } // Save a reference to the variable declaration that is furthest in // the source sequence so that we can append the new statement just // after it (so that variables referenced in the new statement will // be defined). if ( (statementCounter > previousStatementCounter) && ( declarationFound == true ) ) { previousStatementCounter = statementCounter; furthestDeclarationInSourceSequence = i; } #if 0 printf ("AFTER LOOP OVER STATEMENTS: previousStatementCounter = %d \n",previousStatementCounter); string lastStatementString = (*furthestDeclarationInSourceSequence)->unparseToString(); printf ("lastStatementString = %s \n",lastStatementString.c_str()); #endif } else { // If the variable is not found then insert the new statement at the front of the list #if 0 printf ("Can NOT find a valid symbol corresponding to Type = %s Variable = %s (so it is not declared in the local scope) \n", (*typeListStringElementIterator).c_str(), (*variableListStringElementIterator).c_str()); #endif // currentStatementList.push_front(*transformationStatementIterator); } #if 0 printf ("BOTTOM OF LOOP OVER VARIABLES: previousStatementCounter = %d \n",previousStatementCounter); #endif } if (statementCounter > previousStatementCounter) previousStatementCounter = statementCounter; #if 0 printf ("BOTTOM OF LOOP OVER TYPES: previousStatementCounter = %d \n",previousStatementCounter); #endif #if 0 printf ("Exiting in insertSourceCode(): transformationStatementIterator loop (type = %s) ... \n",(*typeListStringElementIterator).c_str()); ROSE_ABORT(); #endif } #if 0 printf ("Exiting in loop insertSourceCode (type = %s) ... \n",(*typeListStringElementIterator).c_str()); ROSE_ABORT(); #endif // Now append the new statement AFTER the declaration that we have found // currentStatementList.insert(*targetDeclarationStatementIterator,*transformationStatementIterator); // currentStatementList.insert(lastStatementIterator,*transformationStatementIterator); #if 1 // printf ("BEFORE ADDING NEW STATEMENT: previousStatementCounter = %d \n",previousStatementCounter); if (previousStatementCounter == 0) { printf ("##### Prepend new statement to the top of the local scope \n"); // currentStatementList.push_front(*transformationStatementIterator); currentBlock->prepend_statement (*transformationStatementIterator); } else { // printf ("##### Append the new statement after the last position where a dependent variable is declared in the local scope \n"); // Use new function added to append/prepend at a specified location in the list of statements currentBlock->append_statement (furthestDeclarationInSourceSequence,*transformationStatementIterator); } #else SgStatementPtrList::iterator tempIterator = furthestDeclarationInSourceSequence; tempIterator++; // Handle the case of appending at the end of the list if ( tempIterator == currentStatementList.end() ) { currentBlock->append_statement (*transformationStatementIterator); } else { currentBlock->insert_statement (tempIterator,*transformationStatementIterator); } #endif } else { // This statement has no type information (so it has no dependence upon any non-primative type) // "int x;" would be an example of a statement that would not generate a type (though perhaps it should?) // printf ("This statement has no type information (so it has no dependence upon any non-primative type) \n"); // So this statment can be places at the front of the list of statements in this block // *** Note that we can't use the STL function directly since it does not set the parent information *** // currentStatementList.push_front(*transformationStatementIterator); currentBlock->insert_statement (currentStatementList.begin(),*transformationStatementIterator); } #if 0 string bottomUnparsedDeclarationCodeString = (*transformationStatementIterator)->unparseToString(); ROSE_ASSERT (bottomUnparsedDeclarationCodeString.c_str() != NULL); printf ("bottomUnparsedDeclarationCodeString = %s \n",bottomUnparsedDeclarationCodeString.c_str()); #endif } #if 0 printf ("Exiting in insertSourceCode(): case of locateNewCodeAtTop == true ... \n"); ROSE_ABORT(); #endif } else { // Put the new statements at the end of the list (traverse the new statements from first to last) // But put it before any return statement! So find the last statement! SgStatementPtrList::iterator lastStatement = currentStatementList.begin(); bool foundEndOfList = false; while ( (foundEndOfList == false) && (lastStatement != currentStatementList.end()) ) { SgStatementPtrList::iterator tempStatement = lastStatement; tempStatement++; if (tempStatement == currentStatementList.end()) foundEndOfList = true; else lastStatement++; } ROSE_ASSERT ( *lastStatement != NULL ); // printf ("(*lastStatement)->sage_class_name() = %s \n",(*lastStatement)->sage_class_name()); // printf ("Insert new statements at the bottom of the block \n"); SgStatementPtrList::iterator transformationStatementIterator; for (transformationStatementIterator = newTransformationStatementListPtr->begin(); transformationStatementIterator != newTransformationStatementListPtr->end(); transformationStatementIterator++) { // If there is a RETURN_STMT in the block then insert the new statement just before the // existing RETURN_STMT if ( (*lastStatement)->variant() == RETURN_STMT) { // printf ("Backing away from the end of the list to find the last non-return statement \n"); // lastStatement--; currentBlock->insert_statement(lastStatement,*transformationStatementIterator); } else { currentStatementList.push_back(*transformationStatementIterator); } } } // printf ("$CLASSNAME::insertSourceCode taking (SgProject,char*,char*) not implemented yet! \n"); // ROSE_ABORT(); }