Пример #1
0
  //! A default builder function handles all details: file use name, others use numbering  
  //  Algorithm:
  //   Go through all parent scopes until reach SgSourceFile. store them into a list
  //   iterate on the list to generate all abstract handles, with optional the parent handle information
  abstract_handle * buildAbstractHandle(SgNode* snode)
  {
    ROSE_ASSERT (snode != NULL);
    // simple nodes
    if  (isSgSourceFile (snode) || isSgProject(snode) ||isSgGlobal(snode))
      return buildSingleAbstractHandle (snode);

    // all other nodes, trace back to SgGlobal, store all intermediate scope nodes
    std::vector<SgNode*> scope_list; 
    SgScopeStatement* p_scope = SageInterface::getEnclosingScope(snode);
    while (!isSgGlobal(p_scope))
    {
      scope_list.push_back(p_scope);
      p_scope =  SageInterface::getEnclosingScope(p_scope);
    }
    
    ROSE_ASSERT (isSgGlobal(p_scope));
    abstract_handle * p_handle = buildSingleAbstractHandle (p_scope);
   
   // Now go through the list to generate numbering handles
    std::vector<SgNode*>::reverse_iterator riter;
    for (riter = scope_list.rbegin(); riter!= scope_list.rend(); riter++)
    {
      SgNode* c_node = *riter;
      p_handle = buildSingleAbstractHandle (c_node, p_handle);
    }
   
   ROSE_ASSERT (p_handle != NULL);

   return buildSingleAbstractHandle (snode, p_handle);
  }
Пример #2
0
 void instr(SgScopeStatement* scope) {
   if(isSgBasicBlock(scope)) {
     #ifdef LOCK_KEY_INSERT
     instr(isSgBasicBlock(scope));
     #endif
   }
   else if(isSgGlobal(scope)) {
     instr(isSgGlobal(scope));
   }
 }
Пример #3
0
void visitorTraversal::visit(SgNode* n)
   {
     SgGlobal* globalScope = isSgGlobal(n);
     if (globalScope != NULL)
        {
          printf ("Looking for \"x\" in the global symbol table ... \n");
          SgSymbol* symbol = globalScope->lookup_var_symbol("x");
          ROSE_ASSERT(symbol != NULL);

       // Iterate through the symbol table
          SgSymbolTable::BaseHashType* hashTable = globalScope->get_symbol_table()->get_table();
          SgSymbolTable::hash_iterator i = hashTable->begin();
          while (i != hashTable->end())
             {
               printf ("hash tabel entry: i->first = %s \n",i->first.str());
               i++;
             }
        }
#if 0
     SgScopeStatement* scope = isSgScopeStatement(n);
     if (scope != NULL)
        {
          printf ("Looking for \"x\" in the global symbol table ... \n");
          SgSymbol* symbol = globalScope->lookup_var_symbol("x");
          ROSE_ASSERT(symbol != NULL);
        }
#endif
   }
Пример #4
0
bool ClangToSageTranslator::VisitDecl(clang::Decl * decl, SgNode ** node) {
#if DEBUG_VISIT_DECL
    std::cerr << "ClangToSageTranslator::VisitDecl" << std::endl;
#endif    
    if (*node == NULL) {
        std::cerr << "Runtime error: No Sage node associated with the declaration..." << std::endl;
        return false;
    }

    if (!isSgGlobal(*node))
        applySourceRange(*node, decl->getSourceRange());

    // TODO attributes
/*
    std::cerr << "Attribute list for " << decl->getDeclKindName() << " (" << decl << "): ";
    clang::Decl::attr_iterator it;
    for (it = decl->attr_begin(); it != decl->attr_end(); it++) {
        std::cerr << (*it)->getKind() << ", ";
    }
    std::cerr << std::endl;

    if (clang::VarDecl::classof(decl)) {
        clang::VarDecl * var_decl = (clang::VarDecl *)decl;
        std::cerr << "Stoprage class for " << decl->getDeclKindName() << " (" << decl << "): " << var_decl->getStorageClass() << std::endl;
    }
*/
    return true;
}
Пример #5
0
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);
             }
        }
   }
Пример #6
0
SgFunctionDeclaration *CudaOutliner::createFuncSkeleton (const string& name, SgType* ret_type,
							 SgFunctionParameterList* params, SgScopeStatement* scope)
{
  ROSE_ASSERT(scope != NULL);
  ROSE_ASSERT(isSgGlobal(scope)!=NULL);
  SgFunctionDeclaration* func;
  SgProcedureHeaderStatement* fortranRoutine;
  if (SageInterface::is_Fortran_language())
    {
      fortranRoutine = SageBuilder::buildProcedureHeaderStatement(name.c_str(),ret_type, params, SgProcedureHeaderStatement::e_subroutine_subprogram_kind,scope);
      func = isSgFunctionDeclaration(fortranRoutine);
    }
  else
    {
      func = SageBuilder::buildDefiningFunctionDeclaration(name,ret_type,params,scope);
    }

  ROSE_ASSERT (func != NULL);
  SgFunctionSymbol* func_symbol = scope->lookup_function_symbol(func->get_name());
  ROSE_ASSERT(func_symbol != NULL);
  if (0)//Outliner::enable_debug)
    {
      printf("Found function symbol in %p for function:%s\n",scope,func->get_name().getString().c_str());
    }
  return func;
}
Пример #7
0
void StaticConstructorTraversal::visit(SgNode *n) {

  // Get declared variables
  SgInitializedName *vName = isSgInitializedName(n);

  if (vName && !isAcreIgnore(vName->get_declaration())) {
    Sg_File_Info *fInfo = vName->get_file_info();
    SgScopeStatement *scope = vName->get_scope();
    
    // Find global variables (variables in namespaces count, e.g. std)
    if (!fInfo->isCompilerGenerated() && (isSgGlobal(scope) || isSgNamespaceDefinitionStatement(scope))) {

      // Walk typedefs until reach pointer to base type  
      SgTypedefType *tdType = isSgTypedefType(vName->get_type());
      while (tdType && isSgTypedefType(tdType->get_base_type())) 
        tdType = isSgTypedefType(tdType->get_base_type());
      
      // Determine if type is a class (i.e. type with a constructor)
      SgClassType *cType = isSgClassType(vName->get_type());
      if (tdType)
        cType = isSgClassType(tdType->get_base_type());
      
      // Output location of globals with a static constructor
      if (cType) {
        *out << "Static Constructor Violation: " << fInfo->get_filename() << " @ " << fInfo->get_line() << "\n";
      }
    }
  }
}
Пример #8
0
  //! A helper function to build a single abstract handle item
  static abstract_handle * buildSingleAbstractHandle(SgNode* snode, abstract_handle * p_handle = NULL)
  {
    abstract_handle *  result = NULL; 
    ROSE_ASSERT (snode != NULL);
    abstract_node * anode = buildroseNode(snode);
    ROSE_ASSERT (anode != NULL);

    // look up first
    result = handle_map[anode];
    if (result != NULL)
      return result;

    //Create the single handle item 
    if (isSgSourceFile (snode) || isSgProject(snode) ||isSgGlobal(snode))
      result = new abstract_handle (anode); // default name or file location specifiers are used
    else 
    {
      // any other types of AST node, use numbering or name within the parent handle
      ROSE_ASSERT (p_handle != NULL);
      if (isSgFunctionDefinition(snode))
        result = new abstract_handle  (anode, e_name, p_handle);
      else  
        result = new abstract_handle  (anode, e_numbering, p_handle);
    }  

    ROSE_ASSERT (result != NULL);
    // cache the result
    handle_map[anode] = result;   

    return result;
  }
Пример #9
0
void
SgGlobal::fixupCopy_symbols(SgNode* copy, SgCopyHelp & help) const
   {
#if DEBUG_FIXUP_COPY
     printf ("Inside of SgGlobal::fixupCopy_symbols() for %p copy = %p \n",this,copy);
#endif

     SgGlobal* global_copy = isSgGlobal(copy);
     ROSE_ASSERT(global_copy != NULL);

     const SgDeclarationStatementPtrList & statementList_original = this->getDeclarationList();
     const SgDeclarationStatementPtrList & statementList_copy     = global_copy->getDeclarationList();

     SgDeclarationStatementPtrList::const_iterator i_original = statementList_original.begin();
     SgDeclarationStatementPtrList::const_iterator i_copy     = statementList_copy.begin();

  // Iterate over both lists to match up the correct pairs of SgStatement objects
     while ( (i_original != statementList_original.end()) && (i_copy != statementList_copy.end()) )
        {
          (*i_original)->fixupCopy_symbols(*i_copy,help);

          i_original++;
          i_copy++;
        }

  // Call the base class fixupCopy member function
     SgScopeStatement::fixupCopy_symbols(copy,help);

  // printf ("\nLeaving SgGlobal::fixupCopy_symbols() this = %p = %s  copy = %p \n",this,this->class_name().c_str(),copy);
   }
Пример #10
0
void SageUtils::addComment(const std::string & comment, SgScopeStatement * scope) {
    PreprocessingInfo::RelativePositionType pos;
    if(isSgGlobal(scope)) {
        pos = PreprocessingInfo::after;    
    } else {
        pos = PreprocessingInfo::inside;
    }
    SageInterface::attachComment(scope, comment, pos);
}
Пример #11
0
void
CompassAnalyses::StaticConstructorInitialization::Traversal::
visit(SgNode* node)
   { 
  // Test for static initialization of variables of type class, such initializations where they are 
  // static or appear in global scope can be called in an order dependent upon the compiler and this 
  // can lead to subtle bugs in large scale applications.

     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);

     if (variableDeclaration != NULL)
        {
          SgInitializedNamePtrList::iterator i = variableDeclaration->get_variables().begin();
          while (i != variableDeclaration->get_variables().end())
             {
               SgInitializedName* initializedName = *i;

            // Check the type and see if it is a class (check for typedefs too)
               SgType* variableType = initializedName->get_type();

               SgClassType *classType = isSgClassType(variableType);
               if (classType != NULL)
                  {
                 // Now check if this is a global or namespace variable or an static class member
                 // This might also have to be a test for other scopes as well.
                    SgScopeStatement* scope = variableDeclaration->get_scope();
                    if (isSgGlobal(scope) != NULL || isSgNamespaceDefinitionStatement(scope) != NULL)
                       {
                      // printf ("Found a global variable defining a class = %p \n",initializedName);
                      // variableDeclaration->get_file_info()->display("global variable defining a class");
                         output->addOutput(new CheckerOutput(initializedName));
                       }

                    if (isSgClassDefinition(scope) != NULL)
                       {
                      // Now check if it is a static data member
                         if (variableDeclaration->get_declarationModifier().get_storageModifier().isStatic() == true)
                            {
                           // printf ("Found a static data member defining a class = %p \n",initializedName);
                           // variableDeclaration->get_file_info()->display("static data member defining a class");
                              output->addOutput(new CheckerOutput(initializedName));
                            }
                       }
                  }

            // increment though the variables in the declaration (typically just one)
               i++;
             }
        }

   } //End of the visit function.
Пример #12
0
 void visit(SgNode *S) {
   switch (S->variantT()) {
   case V_SgFunctionDeclaration:
     visitSgFunctionDeclaration(dynamic_cast<SgFunctionDeclaration *>(S));
     break;
   case V_SgGlobal:
     if (debugHooks) {
       SageInterface::insertHeader("assert.h", PreprocessingInfo::after,
           true, isSgGlobal(S));
     }
     break;
   default:
     break;
   }
 }
Пример #13
0
void
Traversal::visit(SgNode* node)
   {
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(node);

  // Look for variable declarations appearing in global scope!
  // if (variableDeclaration != NULL && isSgGlobal(variableDeclaration->get_parent()) != NULL)
     if (variableDeclaration != NULL)
        {
          SgInitializedNamePtrList::iterator i = variableDeclaration->get_variables().begin();
          while (i != variableDeclaration->get_variables().end())
             {
               SgInitializedName* initializedName = *i;

            // Check the type and see if it is a class (check for typedefs too)
               SgType* variableType = initializedName->get_type();

               SgClassType *classType = isSgClassType(variableType);
               if (classType != NULL)
                  {
                 // Now check if this is a global variable or an static class member
                    SgScopeStatement* scope = variableDeclaration->get_scope();
                    if (isSgGlobal(scope) != NULL)
                       {
                         printf ("Found a global variable defining a class \n");
                      // variableDeclaration->get_file_info()->display("global variable defining a class");
                         outputPositionInformation(variableDeclaration);
                       }

                    if (isSgClassDefinition(scope) != NULL)
                       {
                      // Now check if it is a static data member
                         if (variableDeclaration->get_declarationModifier().get_storageModifier().isStatic() == true)
                            {
                              printf ("Found a static data member defining a class \n");
                           // variableDeclaration->get_file_info()->display("static data member defining a class");
                              outputPositionInformation(variableDeclaration);
                            }
                       }
                  }

            // increment though the variables in the declaration (typically just one)
               i++;
             }
        }
   }
Пример #14
0
Файл: DCL.C Проект: 8l/rose
/**
 * Do not reuse variable names in subscopes
 */
bool DCL01_C( const SgNode *node ) {
	const SgInitializedName *varInitName = isSgInitializedName(node);
	if (!varInitName)
		return false;
	const SgName varName = varInitName->get_name();
	const SgScopeStatement *varScope = varInitName->get_scope();
	assert(varScope);
	while(!isSgGlobal(varScope)) {
		varScope = varScope->get_scope();
		if(varScope->symbol_exists(varName)) {
			print_error(node, "DCL01-C", ("Do not reuse variable names in subscopes: " + varName.getString()).c_str(), true);
			return true;
		}
	}

	return false;
}
Пример #15
0
void ModelBuilder::add(Model::model_t & model, SgVariableSymbol * variable_symbol) {
  SgScopeStatement * scope = variable_symbol->get_scope();
  assert(scope != NULL);

  SgNamespaceDefinitionStatement * nsp_defn     = isSgNamespaceDefinitionStatement(scope);
  SgClassDefinition              * class_defn   = isSgClassDefinition(scope);
  SgGlobal                       * global_scope = isSgGlobal(scope);
  
  SgType * sg_type = variable_symbol->get_type();
  assert(sg_type != NULL);
  Model::type_t type = model.lookup_type(sg_type);
  if (type == NULL) {
    add(model, sg_type);
    type = model.lookup_type(sg_type);
  }
  assert(type != NULL);
  
  if (nsp_defn != NULL || global_scope != NULL) {
    Model::variable_t element = Model::build<Model::e_model_variable>();

    element->node->symbol = variable_symbol;
    element->node->type = type;
  
    setParentFromScope<Model::e_model_variable>(model, element, variable_symbol);

    model.variables.push_back(element);
  }
  else if (class_defn != NULL) {
    Model::field_t element = Model::build<Model::e_model_field>();

    element->node->symbol = variable_symbol;
    element->node->type = type;
  
    setParentFromScope<Model::e_model_field>(model, element, variable_symbol);

    model.fields.push_back(element);
  }
  else {
    /// \todo error printing
    assert(false);
  }
}
/*
 * The visit function is reimplemented from AstSimpleProcessing, and is called for every node
 * in the the AST. We are only really interested in looking at function calls to op_par_loop_3.
 */
void OPSource::visit(SgNode *n)
{ 
  SgFile *file = isSgFile(n);
  if(file!=NULL)
  {
  file->set_unparse_includes(false);
  }

  // We need to put the global scope on the scope stack so that we can look
  // up the oplus datatypes later on (in generateSpecial).
  SgGlobal *globalScope = isSgGlobal(n);
  if(globalScope!=NULL)
  {
    pushScopeStack(globalScope);
    
    // Add the global kernel header
    insertHeader("kernels.h", PreprocessingInfo::after, false, globalScope);
  }

  fixParLoops(n);
  fixOpStructs(n);
  fixOpFunctions(n);
}
Пример #17
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;
}  
Пример #18
0
void
FixupAstSymbolTables::visit ( SgNode* node )
   {
  // DQ (6/27/2005): Output the local symbol table from each scope.
  // printf ("node = %s \n",node->sage_class_name());

     SgScopeStatement* scope = isSgScopeStatement(node);
     if (scope != NULL)
        {
#if 0
          printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str());
#endif
          SgSymbolTable* symbolTable = scope->get_symbol_table();
          if (symbolTable == NULL)
             {
#if 0
               printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str());
               scope->get_file_info()->display("Symbol Table Location");
#endif
               SgSymbolTable* tempSymbolTable = new SgSymbolTable();
               ROSE_ASSERT(tempSymbolTable != NULL);

            // name this table as compiler generated! The name is a static member used to store 
            // state for the next_symbol() functions. It is meaningless to set these.
            // tempSymbolTable->set_name("compiler-generated symbol table");

               scope->set_symbol_table(tempSymbolTable);

            // reset the symbolTable using the get_symbol_table() member function
               symbolTable = scope->get_symbol_table();
               ROSE_ASSERT(symbolTable != NULL);

            // DQ (2/16/2006): Set this parent directly (now tested)
               symbolTable->set_parent(scope);
               ROSE_ASSERT(symbolTable->get_parent() != NULL);
             }
          ROSE_ASSERT(symbolTable != NULL);

          if (symbolTable->get_parent() == NULL)
             {
               printf ("Warning: Fixing up symbolTable, calling symbolTable->set_parent() (parent not previously set) \n");
               symbolTable->set_parent(scope);
             }
          ROSE_ASSERT(symbolTable->get_parent() != NULL);

       // Make sure that the internal hash table used in the symbol table is also present!
          if (symbolTable->get_table() == NULL)
             {
            // DQ (6/27/2005): There are a lot of these built, perhaps more than we really need!
#if 0
               printf ("AST Fixup: Building internal Symbol Table hash table (rose_hash_multimap) for %p = %s at: \n",
                    scope,scope->sage_class_name());
               scope->get_file_info()->display("Symbol Table Location");
#endif
               rose_hash_multimap* internalHashTable = new rose_hash_multimap();
               ROSE_ASSERT(internalHashTable != NULL);
               symbolTable->set_table(internalHashTable);
             }
          ROSE_ASSERT(symbolTable->get_table() != NULL);

          SgSymbolTable::BaseHashType* internalTable = symbolTable->get_table();
          ROSE_ASSERT(internalTable != NULL);


       // DQ (6/23/2011): Note: Declarations that reference types that have not been seen yet may be placed into the 
       // wronge scope, then later when we see the correct scope we have a symbol in two or more symbol tables.  The 
       // code below detects and fixes this problem.

       // DQ (6/16/2011): List of symbols we need to remove from symbol tables where they are multibily represented.
          std::vector<SgSymbol*> listOfSymbolsToRemove;

       // DQ (6/12/2011): Fixup symbol table by removing symbols that are not associated with a declaration in the current scope.
          int idx = 0;
          SgSymbolTable::hash_iterator i = internalTable->begin();
          while (i != internalTable->end())
             {
            // DQ: removed SgName casting operator to char*
            // cout << "[" << idx << "] " << (*i).first.str();
               ROSE_ASSERT ( (*i).first.str() != NULL );
               ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL );

            // printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) sage_class_name() = %s \n",
            //      idx,(*i).first.str(),(*i).second->sage_class_name());

               SgSymbol* symbol = isSgSymbol((*i).second);
               ROSE_ASSERT ( symbol != NULL );

            // We have to look at each type of symbol separately!  This is because there is no virtual function,
            // the reason for this is that each get_declaration() function returns a different type!
            // ROSE_ASSERT ( symbol->get_declaration() != NULL );
               switch(symbol->variantT())
                  {
                    case V_SgClassSymbol:
                       {
                         SgClassSymbol* classSymbol = isSgClassSymbol(symbol);
                         ROSE_ASSERT(classSymbol != NULL);
                         ROSE_ASSERT(classSymbol->get_declaration() != NULL);

                         SgDeclarationStatement* declarationToFindInScope = NULL;

                      // Search for the declaration in the associated scope.
                         declarationToFindInScope = classSymbol->get_declaration();
                         ROSE_ASSERT(declarationToFindInScope != NULL);

                         SgClassDeclaration* classDeclaration = isSgClassDeclaration(declarationToFindInScope);
                         ROSE_ASSERT(classDeclaration != NULL);

                         SgName name = classDeclaration->get_name();

                      // SgType* declarationType = declarationToFindInScope->get_type();
                         SgType* declarationType = classDeclaration->get_type();
                         ROSE_ASSERT(declarationType != NULL);

                         if (declarationToFindInScope->get_definingDeclaration() != NULL)
                            {
                              declarationToFindInScope = declarationToFindInScope->get_definingDeclaration();
                              SgClassDeclaration* definingClassDeclaration = isSgClassDeclaration(declarationToFindInScope);
                              ROSE_ASSERT(definingClassDeclaration != NULL);

                           // SgType* definingDeclarationType = declarationToFindInScope->get_type();
                              SgType* definingDeclarationType = definingClassDeclaration->get_type();
                              ROSE_ASSERT(definingDeclarationType != NULL);

                           // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C
                           // A simple rule that all declarations should follow (now that we have proper global type tables).
                           // ROSE_ASSERT(definingDeclarationType == declarationType);
                              if (definingDeclarationType != declarationType)
                                 {
                                   printf ("In fixupSymbolTables.C: Note that definingDeclarationType != declarationType \n");
                                 }
                            }

                         SgNamedType* namedType = isSgNamedType(declarationType);
                         ROSE_ASSERT(namedType != NULL);

                         SgDeclarationStatement* declarationAssociatedToType = namedType->get_declaration();
                         ROSE_ASSERT(declarationAssociatedToType != NULL);
#if 0
                         printf ("Found a symbol without a matching declaration in the current scope (declList): declarationToFindInScope = %p = %s \n",declarationToFindInScope,declarationToFindInScope->class_name().c_str());
                         printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) class_name() = %s \n",idx,(*i).first.str(),(*i).second->class_name().c_str());
#endif
                         SgScopeStatement* scopeOfDeclarationToFindInScope      = declarationToFindInScope->get_scope();
                         SgScopeStatement* scopeOfDeclarationAssociatedWithType = declarationAssociatedToType->get_scope();
#if 0
                         printf ("declarationToFindInScope = %p declarationToFindInScope->get_scope() = %p = %s \n",declarationToFindInScope,declarationToFindInScope->get_scope(),declarationToFindInScope->get_scope()->class_name().c_str());
                         printf ("declarationAssociatedToType = %p declarationAssociatedToType->get_scope() = %p = %s \n",declarationAssociatedToType,declarationAssociatedToType->get_scope(),declarationAssociatedToType->get_scope()->class_name().c_str());
#endif
                         if (scopeOfDeclarationToFindInScope != scopeOfDeclarationAssociatedWithType)
                            {
                           // DQ (6/12/2011): Houston, we have a problem!  The trick is to fix it...
                           // A symbol has been placed into a scope when we could not be certain which scope it should be placed.
                           // We have a default of placing such symbols into the global scope, but it might be better to just have 
                           // a special scope where such symbols could be placed so that we could have them separate from the global 
                           // scope and then fix them up more clearly.

                           // Note that test2011_80.C still fails but the AST is at least correct (I think).
                              SgGlobal* scopeOfDeclarationToFindInScope_GlobalScope      = isSgGlobal(scopeOfDeclarationToFindInScope);
                           // SgGlobal* scopeOfDeclarationAssociatedWithType_GlobalScope = isSgGlobal(scopeOfDeclarationAssociatedWithType);

                              if (scopeOfDeclarationToFindInScope_GlobalScope != NULL)
                                 {
                                // In general which ever scope is the global scope is where the error is...???
                                // This is because when we don't know where to put a symbol (e.g. from a declaration of a pointer) we put it into global scope.
                                // There is even an agrument that this is correct as a default for C/C++, but only if it must exist (see test2011_80.C).
                                // Remove the symbol from the symbol table of the global scope.

                                   printf ("Remove the associated symbol in the current symbol table \n");

                                // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C
                                // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope());
                                   if (declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope())
                                        printf ("In fixupSymbolTables.C: Note that declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope() \n");
                                 }
                                else
                                 {
                                   listOfSymbolsToRemove.push_back(classSymbol);
                                 }
                            }
                      // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope());

                         break;
                       }

                    default:
                       {
                      // It night be there are are no other types of symbols to consider...

                      // printf ("Ignoring non SgClassSymbols (fixupSymbolTables.C) symbol = %s \n",symbol->class_name().c_str());
                      // ROSE_ASSERT(false);
                       }
                  }

            // Increment iterator!
               i++;

            // Increment counter!
               idx++;
             }

       // DQ (6/18/2011): Now that we are through with the symbol table we can support removal of any 
       // identified problematic symbol without worrying about STL iterator invalidation.
          for (size_t j = 0; j < listOfSymbolsToRemove.size(); j++)
             {
            // Remove these symbols.
               SgSymbol* removeSymbol = listOfSymbolsToRemove[j];
               ROSE_ASSERT(removeSymbol != NULL);
               SgSymbolTable* associatedSymbolTable = isSgSymbolTable(removeSymbol->get_parent());
               ROSE_ASSERT(associatedSymbolTable != NULL);

               ROSE_ASSERT(associatedSymbolTable == symbolTable);

               associatedSymbolTable->remove(removeSymbol);

               printf ("Redundant symbol removed...from symbol table \n");
            // ROSE_ASSERT(false);
             }
#if 0
       // debugging
          symbolTable->print("In FixupAstSymbolTables::visit(): printing out the symbol tables");
#endif
        }
   }
Пример #19
0
void ModelBuilder::setParentFromScope(Model::model_t & model, Model::element_t<kind> * element, SgSymbol * symbol) {
  SgScopeStatement * scope = symbol->get_scope();
  assert(scope != NULL);

  SgNamespaceDefinitionStatement * nsp_defn     = isSgNamespaceDefinitionStatement(scope);
  SgClassDefinition              * class_defn   = isSgClassDefinition(scope);
  SgGlobal                       * global_scope = isSgGlobal(scope);

  if (nsp_defn != NULL) {
    // field and method cannot have namespace for scope
    assert(kind != Model::e_model_field && kind != Model::e_model_method);
  
    SgNamespaceDeclarationStatement * nsp_decl = nsp_defn->get_namespaceDeclaration();
    assert(nsp_decl != NULL);
    
    SgNamespaceSymbol * parent_symbol = isSgNamespaceSymbol(nsp_decl->get_symbol_from_symbol_table());
    assert(parent_symbol != NULL);
    
    Model::namespace_t parent_element = model.lookup_namespace(parent_symbol);
    if (parent_element == NULL) {
      add(model, parent_symbol);
      parent_element = model.lookup_namespace(parent_symbol);
    }
    assert(parent_element != NULL);
    
    switch (kind) {
      case Model::e_model_variable:  parent_element->scope->variable_children.push_back  ( (Model::variable_t)  element); break;
      case Model::e_model_function:  parent_element->scope->function_children.push_back  ( (Model::function_t)  element); break;
      case Model::e_model_type:      parent_element->scope->type_children.push_back      ( (Model::type_t)      element); break;
      case Model::e_model_class:     parent_element->scope->class_children.push_back     ( (Model::class_t)     element); break;
      case Model::e_model_namespace: parent_element->scope->namespace_children.push_back ( (Model::namespace_t) element); break;

      case Model::e_model_field:
      case Model::e_model_method:
        assert(false);
    }
    
    switch (kind) {
      case Model::e_model_variable:  ( (Model::variable_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_function:  ( (Model::function_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_namespace: ( (Model::namespace_t) element)->scope->parent = parent_element; break;

      case Model::e_model_type:  ( (Model::type_t)  element)->scope->parent.a_namespace = parent_element; break;
      case Model::e_model_class: ( (Model::class_t) element)->scope->parent.a_namespace = parent_element; break;

      case Model::e_model_field:
      case Model::e_model_method:
        assert(false);
    }
  }
  else if (class_defn != NULL) {
    // namespace, function, and variable cannot have class for scope
    assert(kind != Model::e_model_namespace && kind != Model::e_model_function && kind != Model::e_model_variable);
    
    SgClassDeclaration * class_decl = class_defn->get_declaration();
    assert(class_decl != NULL);
    
    SgClassSymbol * parent_symbol = isSgClassSymbol(class_decl->get_firstNondefiningDeclaration()->get_symbol_from_symbol_table());
    assert(parent_symbol != NULL);
    
    Model::class_t parent_element = model.lookup_class(parent_symbol);
    if (parent_element == NULL) {
      add(model, parent_symbol);
      parent_element = model.lookup_class(parent_symbol);
    }
    assert(parent_element != NULL);

    switch (kind) {
      case Model::e_model_field:  parent_element->scope->field_children.push_back  ( (Model::field_t)  element); break;
      case Model::e_model_method: parent_element->scope->method_children.push_back ( (Model::method_t) element); break;
      case Model::e_model_type:   parent_element->scope->type_children.push_back   ( (Model::type_t)   element); break;
      case Model::e_model_class:  parent_element->scope->class_children.push_back  ( (Model::class_t)  element); break;

      case Model::e_model_namespace:
      case Model::e_model_variable:
      case Model::e_model_function:
        assert(false);
    }

    switch (kind) {
      case Model::e_model_field:  ( (Model::field_t)  element)->scope->parent = parent_element; break;
      case Model::e_model_method: ( (Model::method_t) element)->scope->parent = parent_element; break;
      
      case Model::e_model_type:  ( (Model::type_t)  element)->scope->parent.a_class = parent_element; break;
      case Model::e_model_class: ( (Model::class_t) element)->scope->parent.a_class = parent_element; break;

      case Model::e_model_namespace:
      case Model::e_model_variable:
      case Model::e_model_function:
        assert(false);
    }
  }
  else if (global_scope != NULL) {
    /// \todo Should we have a root namespace to represent the global scope ???
  }
  else {
    /// \todo error printing
    assert(false);
  }
}
Пример #20
0
// GB (05/30/2007): This was completely rewritten from the old version to
// use much more efficient comparisons now available to us; it also never
// causes visits to included files, something that happened from time to
// time with the old version.
bool 
SgTreeTraversal_inFileToTraverse(SgNode* node, bool traversalConstraint, SgFile* fileToVisit)
   {
  // If traversing without constraint, just continue.
  // if (!traversalConstraint)
     if (traversalConstraint == false)
        {
          return true;
        }

#if 0
  // DQ (8/20/2018): Added debugging for support unparsing of header files.
     printf ("In SgTreeTraversal_inFileToTraverse(): fileToVisit = %p filename = %s \n",fileToVisit,fileToVisit->getFileName().c_str());
#endif

  // DQ (1/21/2008): Recently added SgAsmNodes for binaries also do not 
  // have a SgFileInfo object.
  // Of all the nodes to be traversed, only SgProject is allowed to have
  // a NULL file info; go ahead and try to traverse it (even though this
  // does not make sense since it is not within any file).
     if (node->get_file_info() == NULL)
        {
       // DQ (1/20/2008): This fails for binary files, why is this!
       // if (isSgProject(node) == NULL)
       //      printf ("What node is this: node = %p = %s \n",node,node->class_name().c_str()); // SageInterface::get_name(node).c_str());
       // ROSE_ASSERT(isSgProject(node) != NULL);

       // DQ (11/20/2013): Added SgJavaImportStatementList and SgJavaClassDeclarationList to the exception list since they don't have a source position field.
       // if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL)
          if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL && isSgJavaImportStatementList(node) == NULL && isSgJavaClassDeclarationList(node) == NULL)
          {
               printf ("Error: SgTreeTraversal_inFileToTraverse() --- node->get_file_info() == NULL: node = %p = %s \n",node,node->class_name().c_str());
               SageInterface::dumpInfo(node);
          }

#if 0
       // DQ (11/19/2013): Allow this to pass while we are evaluating the AST traversal for Java.
       // ROSE_ASSERT(isSgProject(node) != NULL || isSgAsmNode(node) != NULL);
       // if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL)
          if (isSgProject(node) == NULL && isSgAsmNode(node) == NULL && isSgJavaImportStatementList(node) == NULL && isSgJavaClassDeclarationList(node) == NULL)
             {
               printf ("WARNING: isSgProject(node) == NULL && isSgAsmNode(node) == NULL: this could be Java code using an incomplete AST: node = %p = %s \n",node,node->class_name().c_str());
             }
#endif

          return true;
        }

  // Traverse compiler generated code and code generated from
  // transformations, unless it is "frontend specific" like the stuff in
  // rose_edg_required_macros_and_functions.h.
     bool isFrontendSpecific = node->get_file_info()->isFrontendSpecific();
     bool isCompilerGeneratedOrPartOfTransformation;
     if (isFrontendSpecific)
        {
          isCompilerGeneratedOrPartOfTransformation = false;
        }
       else
        {
       // DQ (11/14/2008): Implicitly defined functions in Fortran are not marked as compiler generated 
       // (the function body is at least explicit in the source file), but the function declaration IR 
       // nodes is marked as coming from file == NULL_FILE and it is also marked as "outputInCodeGeneration"
       // So it should be traversed so that we can see the function body and so that it can be a proper 
       // part of the definition of the AST.
       // isCompilerGeneratedOrPartOfTransformation = node->get_file_info()->isCompilerGenerated() || node->get_file_info()->isTransformation();
          bool isOutputInCodeGeneration = node->get_file_info()->isOutputInCodeGeneration();
          isCompilerGeneratedOrPartOfTransformation = node->get_file_info()->isCompilerGenerated() || node->get_file_info()->isTransformation() || isOutputInCodeGeneration;
        }

  // Traverse this node if it is in the file we want to visit.
     bool isRightFile = node->get_file_info()->isSameFile(fileToVisit);

#if 0
     printf ("In SgTreeTraversal_inFileToTraverse(): node = %p = %s isRightFile = %s \n",node,node->class_name().c_str(),isRightFile ? "true" : "false");
#endif

  // This function is meant to traverse input files in the sense of not
  // visiting "header" files (a fuzzy concept). But not every #included file
  // is a header, "code" (another fuzzy concept) can also be #included; see
  // test2005_157.C for an example. We want to traverse such code, so we
  // cannot rely on just comparing files.
  // The following heuristic is therefore used: If a node is included from
  // global scope or from within a namespace definition, we guess that it is
  // a header and don't traverse it. Otherwise, we guess that it is "code"
  // and do traverse it.
     bool isCode = node->get_parent() != NULL
                   && !isSgGlobal(node->get_parent())
                   && !isSgNamespaceDefinitionStatement(node->get_parent());

     bool traverseNode;
     if (isCompilerGeneratedOrPartOfTransformation || isRightFile || isCode)
          traverseNode = true;
       else
          traverseNode = false;


#if 0
  // DQ (8/17/2018): Need to stop here and debug this function tomorrow.
     printf ("Exiting as a test! \n");
     ROSE_ASSERT(false);
#endif

     return traverseNode;
   }
Пример #21
0
Файл: DCL.C Проект: 8l/rose
/**
 * Const-qualify immutable objects
 *
 * \todo count assignments, if only one, report violation
 */
bool DCL00_C( const SgNode *node ) {
	const SgInitializedName *varName = isSgInitializedName(node);
	if (!varName)
		return false;

	/**
	 * Ignore variables generated by macros
	 */
	if ((varName->get_name().getString().substr(0,2) == "__")
	||  isCompilerGeneratedNode(node))
		return false;

	/**
	 * Ignore global variables
	 */
	if (isGlobalVar(varName))
		return false;

	/**
	 * Ignore variables that are already const, are function pointers, or are
	 * declared inside of a struct, enum, or as an argument to a function
	 */
	SgType *varType = varName->get_type();
	if (isConstType(varType)
	|| isConstType(varType->dereference())
	|| isConstType(varType->dereference()->dereference())
	|| isSgFunctionType(varType)
	|| isSgClassType(varType)
	|| findParentOfType(varName, SgCtorInitializerList)
	|| findParentOfType(varName, SgEnumDeclaration)
	|| findParentOfType(varName, SgClassDeclaration))
		return false;

	/**
	 * DCL13-C is a subset of this rule, figure out which rule we are dealing
	 * with here
	 */
	std::string ruleStr;
	std::string errStr;
	if (findParentOfType(varName, SgFunctionParameterList)) {
		/** ignore function prototypes, just worry about the definitions */
		const SgFunctionDeclaration *fnDecl = findParentOfType(varName, SgFunctionDeclaration);
		/**
		 * Disabling assertion due to C++ code
		 */
		if (!fnDecl)
			return false;
//		assert(fnDecl);
		if (!fnDecl->get_definition())
			return false;
		if (isSgPointerType(varName->get_type())
		||  isSgArrayType(varName->get_type())) {
			ruleStr = "DCL13-C";
			errStr = "Declare function parameters that are pointers to values not changed by the function as const: ";
		} else {
			return false;
		}
	} else {
		ruleStr = "DCL00-C";
		errStr = "Const-qualify immutable objects: ";
	}

	/**
	 * Ignore global variables or variables declared as extern
	 */
	const SgScopeStatement *varScope = varName->get_scope();
	if (isSgGlobal(varScope) || isExternVar(varName))
		return false;

	FOREACH_SUBNODE(varScope, nodes, i, V_SgVarRefExp) {
		const SgVarRefExp *iVar = isSgVarRefExp(*i);
		assert(iVar);
		if (getRefDecl(iVar) != varName)
			continue;

		const SgNode *parent = iVar->get_parent();
		while(isSgCastExp(parent)) {
			parent = parent->get_parent();
		}
		assert(parent);

		/**
		 * If the variable is written to or it's address is taken, we can no
		 * longer be sure it should be const, if it's a struct and gets
		 * dereferenced, who knows what's getting written there :/
		 */
		if (varWrittenTo(iVar)
		||  isSgArrowExp(parent)
		||  findParentOfType(iVar, SgAddressOfOp))
			return false;

		/**
		 * If the variable is a pointer or array, and we pass it to a function
		 * or as an argument to pointer arithmetic, or assign it's value
		 * somewhere, we can longer be sure it should be const
		 */
		if ((isSgPointerType(varType) || isSgArrayType(varType))
		&& (findParentOfType(iVar, SgFunctionCallExp)
			|| isSgAddOp(parent)
			|| isSgSubtractOp(parent)
			|| isSgAssignOp(parent)
			|| isSgPntrArrRefExp(parent)
			|| isSgPointerDerefExp(parent)
			|| isSgAssignInitializer(parent)))
			return false;
	}

	const std::string msg =  errStr + varName->get_name().getString();
	print_error(node, ruleStr.c_str(), msg.c_str(), true);
	return true;
}