string checkPragmaRHSUnionControl (const Rose_STL_Container< SgNode * >unionFields, const Rose_STL_Container< SgNode * >classFields, const string pragmaRHS, const string controlPrefix) { string returnString = ""; cout << "BEFORE checkPragmaRHSUnionControl" << endl; const string leftCondition = "("; const string rightCondition = ")"; string controlVariable = ""; string condition = ""; string substring = pragmaRHS; string subConditionToCheck; int leftBorder = 0; int rightBorder = 0; while (substring.find (leftCondition) != string::npos) { string tempString = ""; leftBorder = substring.find (leftCondition); rightBorder = substring.find (rightCondition); subConditionToCheck = substring.substr (leftBorder + 1, rightBorder - 1); if (subConditionToCheck.find ("==") != string::npos) { string controlVariableName = subConditionToCheck.substr (0, subConditionToCheck.find ("==")); string condition = subConditionToCheck.substr (subConditionToCheck.find ("==") + 2, subConditionToCheck.length ()); controlVariableName= trim(controlVariableName); condition = trim(condition); //AS(040904) Ugly fix of bug. At a later point find the bug which // makes is so that there a paranthesis is inside the // condition string when there are multiple conditions. if(condition.find(")") != string::npos) condition=condition.substr(0,condition.length()-1); ROSE_ASSERT( condition.find(")") == string::npos ); ROSE_ASSERT( condition.find("(") == string::npos ); //See if this control variable name is redefined as another name in the //parent class if((classFields.empty() != true) & (controlVariableName.length()>0)){ SgNodePtrVector parentScopes = findScopes (isSgNode(*classFields.begin())); for(SgNodePtrVector::iterator scope = parentScopes.begin() ; scope != parentScopes.end(); scope++ ){ if(isSgClassDefinition(*scope)!=NULL){ SgClassDefinition* classDefinition = isSgClassDefinition(*scope); //in some parts of the program a class containing a union which is used in //many calsses can replace the standard control variable name with another. //See if the parent class defines such an exception. Rose_STL_Container<ControlStructureContainer*> pragmaExceptionList = queryFindCommentsInScope("//pragma", "GenUnionControlException_", classDefinition); for (Rose_STL_Container< ControlStructureContainer * >::iterator i = pragmaExceptionList.begin (); i != pragmaExceptionList.end (); ++i) { ControlStructureContainer *controlStructure = *i; ROSE_ASSERT (controlStructure != NULL); //get the variable which corresponds to the variable name in the control structure string exceptionName = parsePragmaStringRHS (controlStructure->getPragmaString (), "GenUnionControlException_", controlVariableName); if(exceptionName.length() > 0 ){ controlVariableName = trim(exceptionName); } //if the control variable exist set the name variableControl to that name } }/* End if(isSgClassDefiniton()!=NULL) */ } /*End for(SgNodePtrVecto::iterator ... ) */ } //check to see if a a variable exist in the parent scope of the union with the name controlVariableName Rose_STL_Container< SgNode * >variableDeclaration = NodeQuery::queryNodeList (classFields, new SgName (controlVariableName. c_str ()), NodeQuery::VariableDeclarationFromName); cout << "control variable name \"" << controlVariableName << "\"" << endl; if(unionFields.empty() == true) cout << "Union has no fieds" << endl; if(classFields.empty() == true) cout << "Parent class has no fields" << endl; else if(variableDeclaration.empty() == true){ }/* End if(variableDeclaration.empty() == true */ ROSE_ASSERT (variableDeclaration.empty () == false); tempString = " ("+ controlPrefix + controlVariableName + "==" + condition + ") "; } else if (subConditionToCheck.find ("!=") != string::npos) { string controlVariableName = subConditionToCheck.substr (0, subConditionToCheck.find ("!=")); string condition = subConditionToCheck.substr (subConditionToCheck.find ("!=") + 2, subConditionToCheck.length ()); if((classFields.empty()!=true)&(controlVariableName.length() > 0)){ SgNodePtrVector parentScopes = findScopes (isSgNode(*classFields.begin())); for(SgNodePtrVector::iterator scope = parentScopes.begin() ; scope != parentScopes.end(); scope++ ){ if(isSgClassDefinition(*scope)!=NULL){ SgClassDefinition* classDefinition = isSgClassDefinition(*scope); //in some parts of the program a class containing a union which is used in //many calsses can replace the standard control variable name with another. //See if the parent class defines such an exception. Rose_STL_Container<ControlStructureContainer*> pragmaExceptionList = queryFindCommentsInScope("//pragma", "GenUnionControlException_", classDefinition); for (Rose_STL_Container< ControlStructureContainer * >::iterator i = pragmaExceptionList.begin (); i != pragmaExceptionList.end (); ++i) { ControlStructureContainer *controlStructure = *i; ROSE_ASSERT (controlStructure != NULL); //get the variable which corresponds to the variable name in the control structure string exceptionName = parsePragmaStringRHS (controlStructure->getPragmaString (), "GenUnionControlException_", controlVariableName); if(exceptionName.length() > 0 ){ controlVariableName = trim(exceptionName); } //if the control variable exist set the name variableControl to that name } }/* End if(isSgClassDefiniton()!=NULL) */ } /*End for(SgNodePtrVecto::iterator ... ) */ } //check to see if a a variable exist in the parent scope of the union with the name controlVariableName Rose_STL_Container< SgNode * >variableDeclaration = NodeQuery::queryNodeList (classFields, new SgName (controlVariableName. c_str ()), NodeQuery::VariableDeclarationFromName); ROSE_ASSERT (variableDeclaration.empty () == false); tempString = " ("+ controlPrefix + controlVariableName + "!=" + condition + ") "; } else { cerr << "Case not implemented yet in (controlVariableName??condition). Terminating.\n"; cout << pragmaRHS << "\n"; exit (1); } //check to see if there exist any more control variables substring = substring.substr (rightBorder + 1, substring.length ()); if (substring.find (leftCondition) != string::npos) { if (substring.find ("&") != string::npos) { returnString = returnString + tempString + " & "; substring = substring.substr (substring.find ("&") + 1, substring.length ()); } else if (substring.find ("|") != string::npos) { returnString = returnString + tempString + " | "; substring = substring.substr (substring.find ("|") + 1, substring.length ()); } else { cerr << "Case not implemented yet in (--)?(--). Terminating\n"; cout << "Pragma RHS:" << pragmaRHS << "\n Substring:\"\n" << substring << "\"\n"; cout << substring. find (leftCondition) << "::" << string::npos << "\n"; exit (1); } } else returnString = returnString + tempString; } /* end while */ cout << "AFTER checkPragmaRHSUnionControl" << endl; return "if(" + returnString + ")"; }; /* End function: checkPragmaRHSUnionControl() */
void generateModFile(SgFile *sfile) { ROSE_ASSERT(sfile != NULL); // file name, with full path. string originalModuleFilenameWithPath = sfile->get_file_info()->get_filenameString(); #if 0 // DQ (10/24/2010): This is overly restrictive...we still want to generate the rmod file. // It does not matter is we compile or not compile any generated file. This premature // exit will cause F03 code to fail to be processed by ROSE since any mod file required // will not generated. // FMZ (10/28/2009): don't generate the .rmod for the readin .rmod file if (sfile->get_skipfinalCompileStep() == true) { if (SgProject::get_verbose() > 0) printf ("Skipping generation of rmod file: %s \n",originalModuleFilenameWithPath.c_str()); return; } #endif // Cause the output of a message with verbose level is turned on. if (SgProject::get_verbose() > 0) { printf ("In generateModFile(): Generating a Fortran 90 specific module (*.rmod file) for file = %s \n",originalModuleFilenameWithPath.c_str()); } // Get the list of SgModuleStatement objects for the current AST. Rose_STL_Container<SgNode*> moduleDeclarationList = NodeQuery::querySubTree (sfile,V_SgModuleStatement); #if 0 // DQ: I think this case is not required since the loop (below) would be empty. if (moduleDeclarationList.empty()) { // no module in the file return; } #endif for (Rose_STL_Container<SgNode*>::iterator i = moduleDeclarationList.begin(); i != moduleDeclarationList.end(); i++) { // For a module named "xx" generate a file "xx.rose_mod" which contains // all the variable definitions and function declarations SgModuleStatement* module_stmt = isSgModuleStatement(*i); ROSE_ASSERT(module_stmt != NULL); string outputDir = get_rmod_dir(sfile); string outputFilename; if (outputDir !="") outputFilename =outputDir + module_stmt->get_name() + MOD_FILE_SUFFIX; else outputFilename = module_stmt->get_name() + MOD_FILE_SUFFIX; string lowerCaseOutputFilename = StringUtility::convertToLowerCase(outputFilename); // Cause the output of a message with verbose level is turned on. if (SgProject::get_verbose() > 0) { printf ("In generateModFile() (loop over module declarations): Generating a Fortran 90 specific module file %s for module = %s \n",lowerCaseOutputFilename.c_str(),outputFilename.c_str()); } // Use a lower case generate filename for the generated ROSE mod (or rmod) file. // fstream Module_OutputFile(outputFilename.c_str(),ios::out); fstream Module_OutputFile(lowerCaseOutputFilename.c_str(),ios::out); if (!Module_OutputFile) { cout << "Error detected in opening file " << lowerCaseOutputFilename.c_str() << "for output" << endl; ROSE_ASSERT(false); } // Output header at the top of the generate *.rmod file. Module_OutputFile << endl << "! =================================================================================== \n" << "! <<Automatically generated for Rose Fortran Separate Compilation, DO NOT MODIFY IT>> \n" << "! =================================================================================== \n" << endl; SgUnparse_Info ninfo; ninfo.set_current_scope((SgScopeStatement*)module_stmt); ninfo.set_SkipFormatting(); // set the flag bit "outputFortranModFile" ninfo.set_outputFortranModFile(); ostringstream outputString; Unparser_Opt options(false, false,false,false,true,false,false,false,false,false); // This is a confusing use of originalModuleFilename vs. outputFilename (Oh, the first one has the full path!). // The originalModuleFilename will be used to build a FortranCodeGeneration_locatedNode using // the originalModuleFilename as a basis. // printf ("originalModuleFilenameWithPath = %s outputFilename = %s \n",originalModuleFilenameWithPath.c_str(),outputFilename.c_str()); Unparser unp(&Module_OutputFile, originalModuleFilenameWithPath,options,NULL,NULL); unp.currentFile = sfile; // The outputFilename is the name that will be matched against in the selection of statements to unparse. // However, that its suffix is ".rmod" will cause UnparseLanguageIndependentConstructs::statementFromFile() // to always return true. So use of outputFilename should map to the file from the file constructed. FortranCodeGeneration_locatedNode myunp(&unp, outputFilename); // This calls the unparser for just the module declaration. myunp.unparseClassDeclStmt_module((SgStatement*)module_stmt,(SgUnparse_Info&)ninfo); Module_OutputFile.flush(); Module_OutputFile.close(); } }