//-----------------------------------------------------------------------------------
//  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();
}
Exemple #3
0
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;
}