//----------------------------------------------------------------------------------- // int UnparseOrigFormat::cases_of_printSpecifier // // Calculates the length of any keywords to subtract from the total number of // spaces to indent. Unparser::printSpecifier prints out any keywords // necessary for the declaration and this function subtracts the length of keywords // printed. Read the comments for the function special_cases to find out why this // is needed. However, the keywords are sometimes generated automatically by Sage, // such as "auto." If the original file did not contain "auto," but the option to // print "auto" is true, then this function will erroneously add to subcol. Yet if // the original file did include "auto" and the option is true, then we would be // correctly adding to subcol. This discrepancy is impossible for the unparser to // distinguish. //----------------------------------------------------------------------------------- int UnparseOrigFormat::cases_of_printSpecifier(SgLocatedNode* node, SgUnparse_Info& info) { int subcol = 0; // if (decl_stmt->isExtern() && decl_stmt->get_linkage()) { // (*os) << "extern \"" << decl_stmt->get_linkage() << "\" "; // if (decl_stmt->isExternBrace()) (*os) << "{ "; // } SgDeclarationStatement* decl_stmt = isSgDeclarationStatement(node); if (decl_stmt != NULL) { // DQ (4/25/2004): Moved to function decalration case below // if (decl_stmt->isVirtual()) subcol += 8; if (decl_stmt->get_declarationModifier().isFriend()) subcol += 7; // DQ (4/25/2004): Moved to function decalration case below // if (decl_stmt->isInline()) subcol += 7; // DQ (4/25/2004): Removed CC++ support // if (decl_stmt->.isAtomic() && !info.SkipAtomic()) subcol += 7; if (decl_stmt->get_declarationModifier().get_storageModifier().isStatic()) subcol += 7; if ( decl_stmt->get_declarationModifier().get_storageModifier().isExtern() && !decl_stmt->get_linkage() ) subcol += 7; // DQ (4/25/2004): Removed CC++ support // if (decl_stmt->isGlobalClass() && !info.SkipGlobal() ) subcol += 7; // checks option status before adding to subcol // if (opt.get_auto_opt()) // if (decl_stmt->isAuto()) subcol += 5; if (decl_stmt->get_declarationModifier().get_storageModifier().isRegister()) subcol += 9; } SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(node); if (functionDeclaration != NULL) { if (functionDeclaration->get_functionModifier().isInline()) subcol += 7; if (functionDeclaration->get_functionModifier().isVirtual()) subcol += 8; } return subcol; }
/** \brief Returns true if method is a pure virtual method. * \param functionDeclaration A method declaration. * \returns Boolean indicating whether method is a pure virtual * method. */ bool isPureVirtual(SgFunctionDeclaration *functionDeclaration) { if ( functionDeclaration == NULL ) return false; if ( functionDeclaration->get_functionModifier().isPureVirtual() ) return true; SgDeclarationStatement *firstNondefiningDeclaration = functionDeclaration->get_firstNondefiningDeclaration(); if ( firstNondefiningDeclaration == NULL ) return false; SgFunctionDeclaration *firstNondefiningFuncDeclaration = isSgFunctionDeclaration(firstNondefiningDeclaration); ROSE_ASSERT(firstNondefiningFuncDeclaration != NULL); return firstNondefiningFuncDeclaration->get_functionModifier().isPureVirtual(); }
SgFunctionDeclaration * CudaOutliner::generateFunction ( SgBasicBlock* s, const string& func_name_str, ASTtools::VarSymSet_t& syms, MintHostSymToDevInitMap_t hostToDevVars, const ASTtools::VarSymSet_t& pdSyms, const ASTtools::VarSymSet_t& psyms, SgScopeStatement* scope) { //Create a function named 'func_name_str', with a parameter list from 'syms' //pdSyms specifies symbols which must use pointer dereferencing if replaced during outlining, //only used when -rose:outline:temp_variable is used //psyms are the symbols for OpenMP private variables, or dead variables (not live-in, not live-out) ROSE_ASSERT ( s && scope); ROSE_ASSERT(isSgGlobal(scope)); // step 1: perform necessary liveness and side effect analysis, if requested. // --------------------------------------------------------- std::set< SgInitializedName *> liveIns, liveOuts; // Collect read-only variables of the outlining target std::set<SgInitializedName*> readOnlyVars; if (Outliner::temp_variable||Outliner::enable_classic) { SgStatement* firstStmt = (s->get_statements())[0]; if (isSgForStatement(firstStmt)&& Outliner::enable_liveness) { LivenessAnalysis * liv = SageInterface::call_liveness_analysis (SageInterface::getProject()); SageInterface::getLiveVariables(liv, isSgForStatement(firstStmt), liveIns, liveOuts); } SageInterface::collectReadOnlyVariables(s,readOnlyVars); if (0)//Outliner::enable_debug) { cout<<" INFO:Mint: CudaOutliner::generateFunction()---Found "<<readOnlyVars.size()<<" read only variables..:"; for (std::set<SgInitializedName*>::const_iterator iter = readOnlyVars.begin(); iter!=readOnlyVars.end(); iter++) cout<<" "<<(*iter)->get_name().getString()<<" "; cout<<endl; cout<<"CudaOutliner::generateFunction() -----Found "<<liveOuts.size()<<" live out variables..:"; for (std::set<SgInitializedName*>::const_iterator iter = liveOuts.begin(); iter!=liveOuts.end(); iter++) cout<<" "<<(*iter)->get_name().getString()<<" "; cout<<endl; } } //step 2. Create function skeleton, 'func'. // ----------------------------------------- SgName func_name (func_name_str); SgFunctionParameterList *parameterList = buildFunctionParameterList(); SgType* func_Type = SgTypeVoid::createType (); SgFunctionDeclaration* func = createFuncSkeleton (func_name, func_Type ,parameterList, scope); //adds __global__ keyword func->get_functionModifier().setCudaKernel(); ROSE_ASSERT (func); // Liao, 4/15/2009 , enforce C-bindings for C++ outlined code // enable C code to call this outlined function // Only apply to C++ , pure C has trouble in recognizing extern "C" // Another way is to attach the function with preprocessing info: // #if __cplusplus // extern "C" // #endif // We don't choose it since the language linkage information is not explicit in AST if ( SageInterface::is_Cxx_language() || is_mixed_C_and_Cxx_language() \ || is_mixed_Fortran_and_Cxx_language() || is_mixed_Fortran_and_C_and_Cxx_language() ) { // Make function 'extern "C"' func->get_declarationModifier().get_storageModifier().setExtern(); func->set_linkage ("C"); } //step 3. Create the function body // ----------------------------------------- // Generate the function body by deep-copying 's'. SgBasicBlock* func_body = func->get_definition()->get_body(); ROSE_ASSERT (func_body != NULL); // This does a copy of the statements in "s" to the function body of the outlined function. ROSE_ASSERT(func_body->get_statements().empty() == true); // This calls AST copy on each statement in the SgBasicBlock, but not on the block, so the // symbol table is setup by AST copy mechanism and it is setup properly SageInterface::moveStatementsBetweenBlocks (s, func_body); if (Outliner::useNewFile) ASTtools::setSourcePositionAtRootAndAllChildrenAsTransformation(func_body); //step 4: variable handling, including: // ----------------------------------------- // create parameters of the outlined functions // add statements to unwrap the parameters if wrapping is requested // add repacking statements if necessary // replace variables to access to parameters, directly or indirectly // do not wrap parameters Outliner::enable_classic = true; functionParameterHandling(syms, hostToDevVars, pdSyms, psyms, readOnlyVars, liveOuts, func); ROSE_ASSERT (func != NULL); // Retest this... // Copied the similar fix from the rose outliner // Liao 2/6/2013. It is essential to rebuild function type after the parameter list is finalized. // The original function type was build using empty parameter list. SgType* stale_func_type = func->get_type(); func->set_type(buildFunctionType(func->get_type()->get_return_type(), buildFunctionParameterTypeList(func->get_parameterList()))); SgFunctionDeclaration* non_def_func = isSgFunctionDeclaration(func->get_firstNondefiningDeclaration ()) ; ROSE_ASSERT (non_def_func != NULL); ROSE_ASSERT (stale_func_type == non_def_func->get_type()); non_def_func->set_type(func->get_type()); ROSE_ASSERT(func->get_definition()->get_body()->get_parent() == func->get_definition()); ROSE_ASSERT(scope->lookup_function_symbol(func->get_name())); return func; }