コード例 #1
0
SgClassDeclaration*
buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope)
   {
  // This function builds a class declaration and definition 
  // (both the defining and nondefining declarations as required).

  // Build a file info object marked as a transformation
     Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode();
     assert(fileInfo != NULL);

  // This is the class definition (the fileInfo is the position of the opening brace)
     SgClassDefinition* classDefinition   = new SgClassDefinition(fileInfo);
     assert(classDefinition != NULL);

  // Set the end of construct explictly (where not a transformation this is the location of the closing brace)
     classDefinition->set_endOfConstruct(fileInfo);

  // This is the defining declaration for the class (with a reference to the class definition)
     SgClassDeclaration* classDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition);
     assert(classDeclaration != NULL);

  // Set the defining declaration in the defining declaration!
     classDeclaration->set_definingDeclaration(classDeclaration);

  // Set the non defining declaration in the defining declaration (both are required)
     SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL);
     assert(classDeclaration != NULL);
     nondefiningClassDeclaration->set_scope(scope);
     nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration));

  // Set the internal reference to the non-defining declaration
     classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     classDeclaration->set_type(nondefiningClassDeclaration->get_type());

  // Set the defining and no-defining declarations in the non-defining class declaration!
     nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     nondefiningClassDeclaration->set_definingDeclaration(classDeclaration);

  // Set the nondefining declaration as a forward declaration!
     nondefiningClassDeclaration->setForward();

  // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)!
     classDefinition->set_declaration(classDeclaration);

  // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!)
     classDeclaration->set_scope(scope);

  // some error checking
     assert(classDeclaration->get_definingDeclaration() != NULL);
     assert(classDeclaration->get_firstNondefiningDeclaration() != NULL);
     assert(classDeclaration->get_definition() != NULL);

  // DQ (9/8/2007): Need to add function symbol to global scope!
     printf ("Fixing up the symbol table in scope = %p = %s for class = %p = %s \n",scope,scope->class_name().c_str(),classDeclaration,classDeclaration->get_name().str());
     SgClassSymbol* classSymbol = new SgClassSymbol(classDeclaration);
     scope->insert_symbol(classDeclaration->get_name(),classSymbol);
     ROSE_ASSERT(scope->lookup_class_symbol(classDeclaration->get_name()) != NULL);

     return classDeclaration;
   }
コード例 #2
0
ファイル: addStruct.C プロジェクト: billhoffman/rose-develop
SgVariableDeclaration*
buildStructVariable ( SgScopeStatement* scope,
              vector<SgType*> memberTypes, vector<string> memberNames,
              string structName = "", string varName = "", SgAggregateInitializer *initializer = NULL )
   {
     ROSE_ASSERT(memberTypes.size() == memberNames.size());
     SgClassDeclaration* classDeclaration = buildClassDeclarationAndDefinition(structName,scope);
     vector<SgType*>::iterator typeIterator       = memberTypes.begin();
     vector<string>::iterator  memberNameIterator = memberNames.begin();
     while (typeIterator != memberTypes.end())
        {
       // printf ("Adding data member type = %s variable name = %s \n",(*typeIterator)->unparseToString().c_str(),memberNameIterator->c_str());
          SgVariableDeclaration* memberDeclaration = new SgVariableDeclaration(SOURCE_POSITION,*memberNameIterator,*typeIterator,NULL);
          memberDeclaration->set_endOfConstruct(SOURCE_POSITION);

          classDeclaration->get_definition()->append_member(memberDeclaration);

          memberDeclaration->set_parent(classDeclaration->get_definition());
        // Liao (2/13/2008) scope and symbols for member variables
          SgInitializedName* initializedName = *(memberDeclaration->get_variables().begin());
          initializedName->set_file_info(SOURCE_POSITION);
          initializedName->set_scope(classDeclaration->get_definition());

        // set nondefning declaration pointer
         memberDeclaration->set_firstNondefiningDeclaration(memberDeclaration);

         SgVariableSymbol* variableSymbol = new SgVariableSymbol(initializedName);
         classDeclaration->get_definition()->insert_symbol(*memberNameIterator,variableSymbol);

          typeIterator++;
          memberNameIterator++;
        }

     SgClassType* classType = new SgClassType(classDeclaration->get_firstNondefiningDeclaration());
     SgVariableDeclaration* variableDeclaration = new SgVariableDeclaration(SOURCE_POSITION,varName,classType,initializer);
     variableDeclaration->set_endOfConstruct(SOURCE_POSITION);

   //Liao (2/13/2008) scope and symbols for struct variable
     SgInitializedName* initializedName = *(variableDeclaration->get_variables().begin());
     initializedName->set_file_info(SOURCE_POSITION);
     initializedName->set_scope(scope);

     SgVariableSymbol* variableSymbol = new SgVariableSymbol(initializedName);
     scope->insert_symbol(varName,variableSymbol);

  //set nondefining declaration 
    variableDeclaration->set_firstNondefiningDeclaration(variableDeclaration);

  // This is required, since it is not set in the SgVariableDeclaration constructor
     initializer->set_parent(variableDeclaration);

     variableDeclaration->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true);
     variableDeclaration->set_baseTypeDefiningDeclaration(classDeclaration->get_definingDeclaration());

     classDeclaration->set_parent(variableDeclaration);

     return variableDeclaration;
   }
コード例 #3
0
ファイル: abiStuff.C プロジェクト: brushington/rose-develop
StructLayoutInfo NonpackedTypeLayoutGenerator::layoutType(SgType* t) const {
  switch (t->variantT()) {
    case V_SgClassType: { // Also covers structs and unions
      SgClassDeclaration* decl = isSgClassDeclaration(isSgClassType(t)->get_declaration());
      ROSE_ASSERT (decl);
      decl = isSgClassDeclaration(decl->get_definingDeclaration());
      ROSE_ASSERT (decl);
      SgClassDefinition* def = decl->get_definition();
      ROSE_ASSERT (def);
      StructLayoutInfo layout;
      size_t currentOffset = 0;
      const SgBaseClassPtrList& bases = def->get_inheritances();
      for (SgBaseClassPtrList::const_iterator i = bases.begin();
           i != bases.end(); ++i) {
        SgBaseClass* base = *i;
        SgClassDeclaration* basecls = base->get_base_class();
        layoutOneField(basecls->get_type(), base, false, currentOffset, layout);
      }
      const SgDeclarationStatementPtrList& body = def->get_members();
      bool isUnion = (decl->get_class_type() == SgClassDeclaration::e_union);
      for (SgDeclarationStatementPtrList::const_iterator i = body.begin();
           i != body.end(); ++i) {
        SgDeclarationStatement* mem = *i;
        SgVariableDeclaration* vardecl = isSgVariableDeclaration(mem);
        SgClassDeclaration* classdecl = isSgClassDeclaration(mem);
        bool isUnnamedUnion = classdecl ? classdecl->get_isUnNamed() : false;
        if (vardecl) {
          if (!vardecl->get_declarationModifier().isDefault()) continue; // Static fields and friends
          ROSE_ASSERT (!vardecl->get_bitfield());
          const SgInitializedNamePtrList& vars = isSgVariableDeclaration(mem)->get_variables();
          for (SgInitializedNamePtrList::const_iterator j = vars.begin();
               j != vars.end(); ++j) {
            SgInitializedName* var = *j;
            layoutOneField(var->get_type(), var, isUnion, currentOffset, layout);
          }
        } else if (isUnnamedUnion) {
          layoutOneField(classdecl->get_type(), classdecl, isUnion, currentOffset, layout);
        } // else continue;
      }
      if (layout.alignment != 0 && layout.size % layout.alignment != 0) {
        size_t paddingNeeded = layout.alignment - (layout.size % layout.alignment);
        if (!isUnion) {
          layout.fields.push_back(StructLayoutEntry(NULL, layout.size, paddingNeeded));
        }
        layout.size += paddingNeeded;
      }
      return layout;
    }
    case V_SgArrayType: {
      StructLayoutInfo layout = this->beginning->layoutType(isSgArrayType(t)->get_base_type());
      layout.fields.clear();
      SgExpression* numElements = isSgArrayType(t)->get_index();

      //Adjustment for UPC array like a[100*THREADS],treat it as a[100]
      // Liao, 8/7/2008
      if (isUpcArrayWithThreads(isSgArrayType(t)))
      {
        SgMultiplyOp* multiply = isSgMultiplyOp(isSgArrayType(t)->get_index());
        ROSE_ASSERT(multiply);

     // DQ (9/26/2011): Do constant folding if required.
     // SageInterface::constantFolding(multiply);

        numElements = multiply->get_lhs_operand();
      }  
      if (!isSgValueExp(numElements)) {
        cerr << "Error: trying to compute static size of an array with non-constant size" << endl;
        abort();
      }
      layout.size *= SageInterface::getIntegerConstantValue(isSgValueExp(numElements));
      return layout;
    }
    case V_SgTypeComplex: {
    //"Each complex type has the same representation and alignment requirements as 
    //an array type containing exactly two elements of the corresponding real type"
      StructLayoutInfo layout = this->beginning->layoutType(isSgTypeComplex(t)->get_base_type());
      layout.size *= 2;
      return layout;
    }
    case V_SgTypeImaginary: {
      StructLayoutInfo layout = this->beginning->layoutType(isSgTypeImaginary(t)->get_base_type());
      return layout;
    }

    default: return ChainableTypeLayoutGenerator::layoutType(t);
  }
}
コード例 #4
0
ファイル: buildReplacementMap.C プロジェクト: KurSh/rose
bool
ReplacementMapTraversal::verifyODR( SgNode* node, SgNode* duplicateNodeFromOriginalAST )
   {
     bool passesODR = false;
  // printf ("Verify that node = %p is equivalent to duplicateNodeFromOriginalAST = %p = %s \n",node,duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str());

  // Verify that these strings match
     ROSE_ASSERT (duplicateNodeFromOriginalAST->variantT() == node->variantT());
     ROSE_ASSERT (duplicateNodeFromOriginalAST->class_name() == node->class_name());
  // ROSE_ASSERT (generateUniqueName(duplicateNodeFromOriginalAST) == generateUniqueName(node));

     string nodeString;
     string duplicateNodeFromOriginalASTstring;

#if 0
  // DQ (2/3/2007): This is a test to debug the ODR checking.
  // I think that the unparser has some state specific to the output of access protections.
  // if the unparsing changes the state then the access permission (public, protected, private) 
  // is output and this cause a falue trigger to the ODR string match.  This is a temp fix to
  // absorbe any change of state, but we need a mechanism to clear the state in the unparser.
     string absorbeUnparserStateChange_A = node->unparseToString();
     string absorbeUnparserStateChange_B = duplicateNodeFromOriginalAST->unparseToString();
#endif
#if 0
  // DQ (2/3/2007): Make sure that there are close to being related. It appears that if these are
     if (node->get_parent()->variantT() == duplicateNodeFromOriginalAST->get_parent()->variantT())
        {
          nodeString                         = node->unparseToString();
          duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString();
        }
#endif

     bool skip_ODR_test = false;

     bool nodeIsCompilerGenerated = 
          (node->get_file_info() != NULL) ? node->get_file_info()->isCompilerGenerated() : false;
     bool duplicateNodeFromOriginalASTIsCompilerGenerated = 
          (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isCompilerGenerated() : false;

     bool nodeIsFrontendSpecific = 
          (node->get_file_info() != NULL) ? node->get_file_info()->isFrontendSpecific() : false;
     bool duplicateNodeFromOriginalASTIsFrontendSpecific = 
          (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isFrontendSpecific() : false;

  // If this is a template declaration for a function then it might have been a part of another template declaration 
  // for the template class and thus might not exist explicitly in the AST (and thus not have enough information from 
  // which to generate a meaningful mangled name).  Skip ODR testing of these cases.
     bool isTemplateMemberFunctionInTemplatedClass = false;
     SgTemplateDeclaration* templateDeclaration = isSgTemplateDeclaration(node);
     if (templateDeclaration != NULL)
        {
          SgTemplateDeclaration* dup_templateDeclaration = isSgTemplateDeclaration(duplicateNodeFromOriginalAST);
          ROSE_ASSERT(dup_templateDeclaration != NULL);
          if ( templateDeclaration->get_string().is_null() && dup_templateDeclaration->get_string().is_null() )
             {
               isTemplateMemberFunctionInTemplatedClass = true;
             }
        }

     if (isTemplateMemberFunctionInTemplatedClass == true)
        {
          printf ("ODR not tested isTemplateMemberFunctionInTemplatedClass == true. \n");
          skip_ODR_test = true;
        }

     if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true || nodeIsCompilerGenerated == true || duplicateNodeFromOriginalASTIsCompilerGenerated == true)
        {
       // printf ("ODR not tested for frontend specific compiler generated code. \n");
          skip_ODR_test = true;
        }

  // DQ (1/20/2007): The unparse will not generate a string if the code is frontend specific or compiler generated (I forget which).
  // if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true)
     if (skip_ODR_test == true)
        {
       // printf ("ODR not tested for frontend specific compiler generated code. \n");
          passesODR = true;
        }
       else
        {
          SgUnparse_Info info_a;
          SgUnparse_Info info_b;

       // DQ (2/6/2007): Force qualified names to be used uniformally (note that info.set_requiresGlobalNameQualification() 
       // causes an error) info.set_requiresGlobalNameQualification();
          info_a.set_forceQualifiedNames();
          info_b.set_forceQualifiedNames();

          nodeString                         = node->unparseToString(&info_a);

       // DQ (2/6/2007): The SgUnparse_Info object carries state which controls the use of access qualification and the 
       // first call to unparseToString might have set the access (e.g. to "public") and the second call would drop the 
       // access qualification.  We unset the access qualification state in the SgUnparse_Info object so that both will 
       // be unparsed the same (we could have alternatively used two separate SgUnparse_Info objects.
       // info.set_isUnsetAccess();

          duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString(&info_b);

          passesODR = (nodeString == duplicateNodeFromOriginalASTstring);
        }

  // Don't count the cases where the unparse fails to to invalid parent in redundant SgClassDeclaration (fix these later)
     if (passesODR == false && nodeString.empty() == false && duplicateNodeFromOriginalASTstring.empty() == false)
        {
#if 1
          if (SgProject::get_verbose() > 0)
               printf ("##### In ReplacementMapTraversal::verifyODR() is false: node = %p = %s duplicateNodeFromOriginalAST = %p = %s \n",
                    node,node->class_name().c_str(),duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str());

       // printf ("##### passesODR = %s \n",passesODR ? "true" : "false");
       // printf ("duplicateNodeFromOriginalASTstring = \n---> %s\n",duplicateNodeFromOriginalASTstring.c_str());
       // printf ("nodeString                         = \n---> %s\n",nodeString.c_str());
          if (node->get_file_info() != NULL && duplicateNodeFromOriginalAST->get_file_info() != NULL)
             {
               if (SgProject::get_verbose() > 0)
                  {
                    SgNode* parent_node = node->get_parent();

                 // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code.
                    ROSE_ASSERT(parent_node != NULL);

                    printf ("parent_node = %p = %s = %s \n",parent_node,parent_node->class_name().c_str(),SageInterface::get_name(parent_node).c_str());
                    SgNode* parent_dup = duplicateNodeFromOriginalAST->get_parent();

                 // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code.
                    ROSE_ASSERT(parent_dup != NULL);

                    printf ("parent_dup = %p = %s = %s \n",parent_dup,parent_dup->class_name().c_str(),SageInterface::get_name(parent_dup).c_str());

                    printf ("\nPosition of error: \n");
                    node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug");
                    duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug");
                    printf ("\nPosition of error: \n");

                    printf ("\nPosition of error (parent IR node): \n");
                    parent_node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_node) is false: debug");
                    parent_dup->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_dup) is false: debug");
                    printf ("\nPosition of error (parent IR node): \n");
                  }
             }
            else
             {
               SgClassType* classType = isSgClassType(node);
               SgClassType* duplicateNodeFromOriginalAST_classType = isSgClassType(duplicateNodeFromOriginalAST);
               if (classType != NULL)
                  {
                    if (SgProject::get_verbose() > 0)
                       {
                         SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration());
                         ROSE_ASSERT(classDeclaration != NULL);
                         classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (classType)");
                         printf ("classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n",
                              classDeclaration,
                              classDeclaration->get_definingDeclaration(),
                              classDeclaration->get_firstNondefiningDeclaration());

                         ROSE_ASSERT(duplicateNodeFromOriginalAST_classType != NULL);
                         SgClassDeclaration* duplicateNodeFromOriginalAST_classDeclaration = isSgClassDeclaration(duplicateNodeFromOriginalAST_classType->get_declaration());
                         ROSE_ASSERT(duplicateNodeFromOriginalAST_classDeclaration != NULL);
                         duplicateNodeFromOriginalAST_classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (duplicateNodeFromOriginalAST_classType)");
                         printf ("duplicateNodeFromOriginalAST_classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n",
                              duplicateNodeFromOriginalAST_classDeclaration,
                              duplicateNodeFromOriginalAST_classDeclaration->get_definingDeclaration(),
                              duplicateNodeFromOriginalAST_classDeclaration->get_firstNondefiningDeclaration());
                       }
                  }
             }
#endif
          odrViolations.push_back(pair<SgNode*,SgNode*>(node,duplicateNodeFromOriginalAST));
        }
#if 0
     printf ("duplicateNodeFromOriginalASTstring = %p = %s \n---> %s\n",
          duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),duplicateNodeFromOriginalASTstring.c_str());
     printf ("nodeString                         = %p = %s \n---> %s\n",
          node,node->class_name().c_str(),nodeString.c_str());
#endif
#if 0
     SgClassType* original = isSgClassType(duplicateNodeFromOriginalAST);
     SgClassType* target   = isSgClassType(node);
     if (original != NULL && target != NULL)
        {
          printf ("original declaration = %p \n",original->get_declaration());
          printf ("target declaration   = %p \n",target->get_declaration());
        }
#endif
#if 1
     if (passesODR == false)
        {
          if (SgProject::get_verbose() > 0)
             {
               string node_generatedName         = SageInterface::generateUniqueName(node,false);
               string originalNode_generatedName = SageInterface::generateUniqueName(duplicateNodeFromOriginalAST,false);

               printf ("ODR Violation Source code: nodeString                         = \n%s\n \n",nodeString.c_str());
               printf ("ODR Violation Source code: duplicateNodeFromOriginalASTstring = \n%s\n \n",duplicateNodeFromOriginalASTstring.c_str());
               printf ("nodeString = %s \n",nodeString.c_str());
               printf ("node_generatedName         = %s \n",node_generatedName.c_str());
               printf ("originalNode_generatedName = %s \n",originalNode_generatedName.c_str());

               printf ("node                         = %p = %s = %s \n",node,node->class_name().c_str(),SageInterface::get_name(node).c_str());
               printf ("duplicateNodeFromOriginalAST = %p = %s = %s \n",duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),SageInterface::get_name(duplicateNodeFromOriginalAST).c_str());

               printf ("node (unique string)                         = %s \n",generateUniqueName(node,true).c_str());
               printf ("duplicateNodeFromOriginalAST (unique string) = %s \n",generateUniqueName(duplicateNodeFromOriginalAST,true).c_str());

               SgDeclarationStatement* declarationStatement = isSgDeclarationStatement(node);
               if (declarationStatement != NULL)
                  {
                    printf ("declarationStatement->get_definingDeclaration()         = %p \n",declarationStatement->get_definingDeclaration());
                    printf ("declarationStatement->get_firstNondefiningDeclaration() = %p \n",declarationStatement->get_firstNondefiningDeclaration());
                  }

               SgDeclarationStatement* declarationStatement2 = isSgDeclarationStatement(duplicateNodeFromOriginalAST);
               if (declarationStatement2 != NULL)
                  {
                    printf ("declarationStatement2->get_definingDeclaration()         = %p \n",declarationStatement2->get_definingDeclaration());
                    printf ("declarationStatement2->get_firstNondefiningDeclaration() = %p \n",declarationStatement2->get_firstNondefiningDeclaration());
                  }

               printf ("Source code positions of ORD violation: \n");
               node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug");
               duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug");
             }
        }
#endif
  // ROSE_ASSERT(nodeString == duplicateNodeFromOriginalASTstring);
     ROSE_ASSERT(passesODR == true);

     return passesODR;
   }
コード例 #5
0
ファイル: typechecking.C プロジェクト: matzke1/rose-develop
  void instr(SgProject* project, Rose_STL_Container<SgType*> types)
  {
    SgGlobal* global = SI::getFirstGlobalScope(project);
    std::string prefix("rtc_ti_"); //struct prefix
    std::string ti_type_str("struct rtc_typeinfo*");
    SgType* ti_type = SB::buildOpaqueType(ti_type_str,global);

    //Insert declarations from the typechecking library.

    //void minalloc_check(unsigned long long addr)
    SgFunctionDeclaration* minalloc_check_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("minalloc_check"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("addr",SB::buildUnsignedLongLongType())),
          global,NULL);
    SI::prependStatement(minalloc_check_decl,global);

    //void typetracker_add(unsigned long long addr, struct rtc_typeinfo* ti);
    SgFunctionDeclaration* typetracker_add_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("typetracker_add"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("addr",SB::buildUnsignedLongLongType()),
            SB::buildInitializedName("ti",ti_type)),
          global,NULL);
    SI::prependStatement(typetracker_add_decl,global);

    //void setBaseType(rtc_typeinfo* ti, rtc_typeinfo* base)
    SgFunctionDeclaration* setBaseType_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("setBaseType"),
          SgTypeVoid::createType(),
          SB::buildFunctionParameterList(
            SB::buildInitializedName("ti",ti_type),
            SB::buildInitializedName("base",ti_type)),
          global,NULL);
    SI::prependStatement(setBaseType_decl,global);

    //struct rtc_typeinfo* ti_init(const char* a, size_t sz, int c)
    SgFunctionDeclaration* ti_init_decl = SB::buildNondefiningFunctionDeclaration(
                                            SgName("ti_init"),
                                            ti_type,
                                            SB::buildFunctionParameterList(
//    SB::buildInitializedName("a",SB::buildPointerType(SB::buildConstType(SB::buildCharType()))),
                                                SB::buildInitializedName("a",SB::buildPointerType(SB::buildCharType())),
//    SB::buildInitializedName("sz", SB::buildOpaqueType("size_t",global)),
                                                SB::buildInitializedName("sz", SB::buildLongLongType()),
                                                SB::buildInitializedName("c", SB::buildIntType())),
                                            global,NULL);
    SI::prependStatement(ti_init_decl,global);

    //void traverseAndPrint()
    SgFunctionDeclaration* traverseAndPrint_decl = SB::buildNondefiningFunctionDeclaration(
          SgName("traverseAndPrint"),SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL);
    SI::prependStatement(traverseAndPrint_decl,global);

    //non-defining declaration of rtc_init_typeinfo
    SgName init_name("rtc_init_typeinfo");
    SgFunctionDeclaration* init_nondef = SB::buildNondefiningFunctionDeclaration(init_name,SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL);
    SI::prependStatement(init_nondef,global);

    //call to rtc_init_typeinfo placed in main function.
    SgFunctionDeclaration* maindecl = SI::findMain(project);
    SgExprStatement* initcall = SB::buildFunctionCallStmt(init_name,SgTypeVoid::createType(),NULL,maindecl->get_definition());
    maindecl->get_definition()->prepend_statement(initcall);

    //defining declaration of rtc_init_typeinfo
    SgFunctionDeclaration* init_definingDecl = new SgFunctionDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_name,init_nondef->get_type(),NULL);
    init_definingDecl->set_firstNondefiningDeclaration(init_nondef);
    SgFunctionDefinition* init_definition = new SgFunctionDefinition(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_definingDecl,SB::buildBasicBlock());
    init_definingDecl->set_definition(init_definition);
    SI::appendStatement(init_definingDecl,global);

    std::vector<std::string> lst;
    for(unsigned int index = 0; index < types.size(); index++)
    {
      SgType* ptr = types[index];

      ptr = ptr->stripTypedefsAndModifiers();
      if(!shouldInstrumentType(ptr))
        continue;
      std::string nameStr = prefix + Util::getNameForType(ptr).getString();
      if(!contains(lst,nameStr))
      {
        SgVariableDeclaration* decl = SB::buildVariableDeclaration(nameStr,ti_type,NULL,global);
        SI::prependStatement(decl,global);
        lst.push_back(nameStr);
      }
    }

    for(unsigned int index = 0; index < types.size(); index++)
    {
      SgType* ptr = types[index];
      ptr = ptr->stripTypedefsAndModifiers();
      if(!shouldInstrumentType(ptr))
        continue;
      std::string typeNameStr = Util::getNameForType(ptr).getString();
      std::string structNameStr = prefix + Util::getNameForType(ptr).getString();

      if(contains(lst,structNameStr))
      {
        SgExpression* lhs;
        SgExpression* rhs;

        //In case of an anonymous struct or union, we create a local, named version of the declaration so we can know its size.
        SgClassDeclaration* altDecl = NULL;
        if(isSgNamedType(ptr) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration())->get_isUnNamed())
        {
          SgClassDeclaration* originalDecl = isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()->get_definingDeclaration());
          SgName altDecl_name(typeNameStr + "_def");
          altDecl = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type());

          SgClassDefinition* altDecl_definition = SB::buildClassDefinition(altDecl);

          SgDeclarationStatementPtrList originalMembers = originalDecl->get_definition()->get_members();
          for(SgDeclarationStatementPtrList::iterator it = originalMembers.begin(); it != originalMembers.end(); it++)
          {
            SgDeclarationStatement* member = *it;
            SgDeclarationStatement* membercpy = isSgDeclarationStatement(SI::copyStatement(member));
            altDecl_definition->append_member(membercpy);
          }


          SgClassDeclaration* altDecl_nondef = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type());

          altDecl_nondef->set_scope(global);
          altDecl->set_scope(global);

          altDecl->set_firstNondefiningDeclaration(altDecl_nondef);
          altDecl_nondef->set_firstNondefiningDeclaration(altDecl_nondef);
          altDecl->set_definingDeclaration(altDecl);
          altDecl_nondef->set_definingDeclaration(altDecl);


          SgClassType* altDecl_ct = SgClassType::createType(altDecl_nondef);
          altDecl->set_type(altDecl_ct);
          altDecl_nondef->set_type(altDecl_ct);

          altDecl->set_isUnNamed(false);
          altDecl_nondef->set_isUnNamed(false);

          altDecl_nondef->set_forward(true);

          SgSymbol* sym = new SgClassSymbol(altDecl_nondef);
          global->insert_symbol(altDecl_name, sym);

          altDecl->set_linkage("C");
          altDecl_nondef->set_linkage("C");

          ROSE_ASSERT(sym && sym->get_symbol_basis() == altDecl_nondef);
          ROSE_ASSERT(altDecl->get_definingDeclaration() == altDecl);
          ROSE_ASSERT(altDecl->get_firstNondefiningDeclaration() == altDecl_nondef);
          ROSE_ASSERT(altDecl->search_for_symbol_from_symbol_table() == sym);
          ROSE_ASSERT(altDecl->get_definition() == altDecl_definition);
          ROSE_ASSERT(altDecl->get_scope() == global && altDecl->get_scope() == altDecl_nondef->get_scope());
          ROSE_ASSERT(altDecl_ct->get_declaration() == altDecl_nondef);

          //For some reason, this is not working...

          //global->append_statement(altDecl);
          //global->prepend_statement(altDecl_nondef);

          //SI::setOneSourcePositionForTransformation(altDecl);
          //SI::setOneSourcePositionForTransformation(altDecl_nondef);
        }

        SgType* baseType;
        if(isSgPointerType(ptr))
          baseType = ptr->dereference();
        else
          baseType = ptr->findBaseType();

        baseType = baseType->stripTypedefsAndModifiers();
        if(baseType == NULL || baseType == ptr)
        {
          //In this case, there is no base type.
          rhs = SB::buildFunctionCallExp(SgName("ti_init"),SgTypeVoid::createType(),SB::buildExprListExp(
                                           SB::buildStringVal(ptr->unparseToString()),
                                           ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)),
                                           SB::buildIntVal(getClassification(ptr))
                                         ),init_definition);
        }
        else
        {
          //The type has a base type.
          std::string baseStructNameStr = prefix + Util::getNameForType(baseType).getString();
          rhs = SB::buildFunctionCallExp(SgName("ti_init"),ti_type,SB::buildExprListExp(
                                           SB::buildStringVal(ptr->unparseToString()),
                                           ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)),
                                           SB::buildIntVal(getClassification(ptr))
                                         ),init_definition);

          SgExprStatement* set_BT = SB::buildFunctionCallStmt(SgName("setBaseType"),ti_type,SB::buildExprListExp(
                                      SB::buildVarRefExp(structNameStr),
                                      SB::buildVarRefExp(baseStructNameStr)),
                                    init_definition);
          init_definition->append_statement(set_BT);
        }
        lhs = SB::buildVarRefExp(structNameStr);


        SgExprStatement* assignstmt = SB::buildAssignStatement(lhs,rhs);
        init_definition->prepend_statement(assignstmt);
        std::remove(lst.begin(),lst.end(),structNameStr);

      }



    }
  }
コード例 #6
0
bool isDeclaredVirtualWithinClassAncestry(SgFunctionDeclaration *functionDeclaration, SgClassDefinition *classDefinition)
{
  SgType *functionType =
    functionDeclaration->get_type();
  ROSE_ASSERT(functionType != NULL);

  // Look in each of the class' parent classes.
  SgBaseClassPtrList & baseClassList = classDefinition->get_inheritances(); 
  for (SgBaseClassPtrList::iterator i = baseClassList.begin(); 
       i != baseClassList.end(); ++i) {
 
    SgBaseClass *baseClass = *i;
    ROSE_ASSERT(baseClass != NULL);

    SgClassDeclaration *classDeclaration = baseClass->get_base_class(); 
    ROSE_ASSERT(classDeclaration != NULL);

    SgDeclarationStatement *definingDecl =
      classDeclaration->get_definingDeclaration();
    if ( definingDecl == NULL )
      continue;
    
    SgClassDeclaration *definingClassDeclaration =
      isSgClassDeclaration(definingDecl);
    ROSE_ASSERT(classDeclaration != NULL);

    SgClassDefinition *parentClassDefinition =
      definingClassDeclaration->get_definition();

    if ( parentClassDefinition == NULL )
      continue;

    // Visit all methods in the parent class.
    SgDeclarationStatementPtrList &members = 
      parentClassDefinition->get_members(); 

    bool isDeclaredVirtual = false;

    for (SgDeclarationStatementPtrList::iterator it = members.begin(); 
	 it != members.end(); ++it) { 
    
      SgDeclarationStatement *declarationStatement = *it; 
      ROSE_ASSERT(declarationStatement != NULL);
      
      switch(declarationStatement->variantT()) {
      
      case V_SgMemberFunctionDeclaration:
	{
	  SgMemberFunctionDeclaration *memberFunctionDeclaration =  
	    isSgMemberFunctionDeclaration(declarationStatement); 

	  if ( isVirtual(memberFunctionDeclaration) ) {

	    SgType *parentMemberFunctionType =
	      memberFunctionDeclaration->get_type();
	    ROSE_ASSERT(parentMemberFunctionType != NULL);

	    if ( parentMemberFunctionType == functionType ) {
	      return true;
	    }

	  }
	  break;

	}
      default:
	{
	  break;
	}

      }

    }

    if ( isDeclaredVirtualWithinClassAncestry(functionDeclaration, 
					      parentClassDefinition) ) {
      return true;
    }

  }

  return false;
}
void
FixupAstSymbolTablesToSupportAliasedSymbols::visit ( SgNode* node )
   {
  // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST.
#if ALIAS_SYMBOL_DEBUGGING
     printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit() (preorder AST traversal) node = %p = %s \n",node,node->class_name().c_str());
#endif

#if 0
  // DQ (7/23/2011): New support for linking namespaces sharing the same name (mangled name).
  // std::map<SgName,std::vector<SgNamespaceDefinition*> > namespaceMap;
     SgNamespaceDefinitionStatement* namespaceDefinition = isSgNamespaceDefinitionStatement(node);
     if (namespaceDefinition != NULL)
        {
       // DQ (7/23/2011): Assemble namespaces with the same name into vectors defined in the map 
       // accessed using the name of the namespace as a key.

#error "DEAD CODE"

          SgName name = namespaceDefinition->get_namespaceDeclaration()->get_name();
#if ALIAS_SYMBOL_DEBUGGING
          printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: namespace definition found for name = %s #symbols = %d \n",name.str(),namespaceDefinition->get_symbol_table()->size());
#endif
       // It is important to use mangled names to define unique names when namespaces are nested.
          SgName mangledNamespaceName = namespaceDefinition->get_namespaceDeclaration()->get_mangled_name();
#if ALIAS_SYMBOL_DEBUGGING
          printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: namespace definition associated mangled name = %s \n",mangledNamespaceName.str());
#endif
       // DQ (7/23/2011): Fixup the name we use as a key in the map to relect that some namespaces don't have a name.
          if (name == "")
             {
            // Modify the mangled name to reflect the unnamed namespace...

#if ALIAS_SYMBOL_DEBUGGING
               printf ("Warning in FixupAstSymbolTablesToSupportAliasedSymbols::visit(): Unnamed namespaces shuld be mangled to reflect the lack of a name \n");
#endif
               mangledNamespaceName += "_unnamed_namespace";
             }

#if ALIAS_SYMBOL_DEBUGGING
          printf ("namespace definition associated mangled name = %s \n",mangledNamespaceName.str());
#endif
#if ALIAS_SYMBOL_DEBUGGING
          printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: associated mangled name = %s namespaceMap size = %" PRIuPTR " \n",mangledNamespaceName.str(),namespaceMap.size());
#endif
          std::map<SgName,std::vector<SgNamespaceDefinitionStatement*> >::iterator i = namespaceMap.find(mangledNamespaceName);
          if (i != namespaceMap.end())
             {
               std::vector<SgNamespaceDefinitionStatement*> & namespaceVector = i->second;
#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: (found an entry): Namespace vector size = %" PRIuPTR " \n",namespaceVector.size());
#endif
            // Testing each entry...
               for (size_t j = 0; j < namespaceVector.size(); j++)
                  {
                    ROSE_ASSERT(namespaceVector[j] != NULL);
                    SgName existingNamespaceName = namespaceVector[j]->get_namespaceDeclaration()->get_name();
#if ALIAS_SYMBOL_DEBUGGING
                    printf ("Existing namespace (SgNamespaceDefinitionStatement) %p = %s \n",namespaceVector[j],existingNamespaceName.str());
#endif
                    if (j > 0)
                       {
                         ROSE_ASSERT(namespaceVector[j]->get_previousNamespaceDefinition() != NULL);
                       }

                    if (namespaceVector.size() > 1 && j < namespaceVector.size() - 2)
                       {
                         ROSE_ASSERT(namespaceVector[j]->get_nextNamespaceDefinition() != NULL);
                       }
                  }

#error "DEAD CODE"

               size_t namespaceListSize = namespaceVector.size();
               if (namespaceListSize > 0)
                  {
                    size_t lastNamespaceIndex = namespaceListSize - 1;

                 // DQ (5/9/2013): Before setting these, I think they should be unset (to NULL values).
                 // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL);
                 // ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL);
                 // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL);

                 // namespaceVector[lastNamespaceIndex]->set_nextNamespaceDefinition(namespaceDefinition);
#if 1
                    printf ("namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() = %p \n",namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition());
#endif
                    if (namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL)
                       {
                         namespaceVector[lastNamespaceIndex]->set_nextNamespaceDefinition(namespaceDefinition);
                       }
                      else
                       {
                      // DQ (5/9/2013): If this is already set then make sure it was set to the correct value.
                         ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == namespaceDefinition);
                       }

#error "DEAD CODE"

                 // DQ (5/9/2013): If this is already set then make sure it was set to the correct value.
                 // namespaceDefinition->set_previousNamespaceDefinition(namespaceVector[lastNamespaceIndex]);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == namespaceVector[lastNamespaceIndex]);

                 // DQ (5/9/2013): I think I can assert this.
                    ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_namespaceDeclaration()->get_name() == namespaceDefinition->get_namespaceDeclaration()->get_name());
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL);
#if 1
                    printf ("namespaceDefinition = %p namespaceDefinition->get_nextNamespaceDefinition() = %p \n",namespaceDefinition,namespaceDefinition->get_nextNamespaceDefinition());
#endif
                 // ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition()     == NULL);
                 // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL);
                  }

            // Add the namespace matching a previous name to the list.
               namespaceVector.push_back(namespaceDefinition);

#error "DEAD CODE"

            // Setup scopes as sources and distinations of alias symbols.
               SgNamespaceDefinitionStatement* referencedScope = namespaceDefinition->get_previousNamespaceDefinition();
               ROSE_ASSERT(referencedScope != NULL);
               SgNamespaceDefinitionStatement* currentScope = namespaceDefinition;
               ROSE_ASSERT(currentScope != NULL);

#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: Suppress injection of symbols from one namespace to the other for each reintrant namespace \n");
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: referencedScope #symbols = %d currentScope #symbols = %d \n",referencedScope->get_symbol_table()->size(),currentScope->get_symbol_table()->size());
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: referencedScope = %p currentScope = %p \n",referencedScope,currentScope);
#endif
#if 1
            // Generate the alias symbols from the referencedScope and inject into the currentScope.
               injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,currentScope,SgAccessModifier::e_default);
#endif
             }
            else
             {
#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: (entry NOT found): Insert namespace %p for name = %s into the namespaceMap \n",namespaceDefinition,mangledNamespaceName.str());
#endif
               std::vector<SgNamespaceDefinitionStatement*> list(1);
               ROSE_ASSERT(list.size() == 1);

#error "DEAD CODE"

               list[0] = namespaceDefinition;
#if 0
            // DQ (3/11/2012): New code, but maybe we should instead put the implicit "std" namespace into the global scope more directly.
               if (mangledNamespaceName == "std" && false)
                  {
                 // This case has to be handled special since the implicit "std" namespace primary declaration was 
                 // constructed but not added to the global scope.  But maybe it should be.
                  }
                 else
                  {
                 // DQ (7/24/2011): get_nextNamespaceDefinition() == NULL is false in the case of the AST copy tests 
                 // (see tests/nonsmoke/functional/CompileTests/copyAST_tests/copytest2007_30.C). Only  get_nextNamespaceDefinition() 
                 // appears to sometimes be non-null, so we reset them both to NULL just to make sure.
                    namespaceDefinition->set_nextNamespaceDefinition(NULL);
                    namespaceDefinition->set_previousNamespaceDefinition(NULL);

                    ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition()     == NULL);
                    ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL);
                  }
#else
            // DQ (7/24/2011): get_nextNamespaceDefinition() == NULL is false in the case of the AST copy tests 
            // (see tests/nonsmoke/functional/CompileTests/copyAST_tests/copytest2007_30.C). Only  get_nextNamespaceDefinition() 
            // appears to sometimes be non-null, so we reset them both to NULL just to make sure.
               namespaceDefinition->set_nextNamespaceDefinition(NULL);
               namespaceDefinition->set_previousNamespaceDefinition(NULL);

               ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition()     == NULL);
               ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL);
#endif
               namespaceMap.insert(std::pair<SgName,std::vector<SgNamespaceDefinitionStatement*> >(mangledNamespaceName,list));

#error "DEAD CODE"

#if ALIAS_SYMBOL_DEBUGGING
               printf ("namespaceMap.size() = %" PRIuPTR " \n",namespaceMap.size());
#endif
             }
        }

#error "DEAD CODE"

#else
  // DQ (5/23/2013): Commented out since we now have a newer and better namespace support for symbol handling.
  // printf ("NOTE:: COMMENTED OUT old support for namespace declarations in FixupAstSymbolTablesToSupportAliasedSymbols traversal \n");
#endif

     SgUseStatement* useDeclaration = isSgUseStatement(node);
     if (useDeclaration != NULL)
        {
       // This must be done in the Fortran AST construction since aliased symbols must be inserted
       // before they are looked up as part of name resolution of variable, functions, and types.
       // For C++ we can be more flexible and support the construction of symbol aliases within 
       // post-processing.
        }

  // DQ (4/14/2010): Added this C++ specific support.
  // In the future we may want to support the injection of alias symbols for C++ "using" directives and "using" declarations.
     SgUsingDeclarationStatement* usingDeclarationStatement = isSgUsingDeclarationStatement(node);
     if (usingDeclarationStatement != NULL)
        {
#if ALIAS_SYMBOL_DEBUGGING
          printf ("Found the SgUsingDeclarationStatement \n");
#endif
          SgScopeStatement* currentScope = usingDeclarationStatement->get_scope();
          ROSE_ASSERT(currentScope != NULL);

          SgDeclarationStatement* declaration     = usingDeclarationStatement->get_declaration();
          SgInitializedName*      initializedName = usingDeclarationStatement->get_initializedName();

       // Only one of these can be non-null.
          ROSE_ASSERT(initializedName != NULL || declaration != NULL);
          ROSE_ASSERT( (initializedName != NULL && declaration != NULL) == false);

          if (declaration != NULL)
             {
#if ALIAS_SYMBOL_DEBUGGING
               printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): declaration = %p = %s \n",declaration,declaration->class_name().c_str());
#endif
             }
            else
             {
               if (initializedName != NULL)
                  {
#if ALIAS_SYMBOL_DEBUGGING
                    printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): initializedName = %s \n",initializedName->get_name().str());
#endif
                  }
                 else
                  {
                    printf ("Error: both declaration and initializedName in SgUsingDeclarationStatement are NULL \n");
                    ROSE_ASSERT(false);
                  }
             }

#if 0
          printf ("Exiting at the base of FixupAstSymbolTablesToSupportAliasedSymbols::visit() \n");
          ROSE_ASSERT(false);
#endif
        }

     SgUsingDirectiveStatement* usingDirectiveStatement = isSgUsingDirectiveStatement(node);
     if (usingDirectiveStatement != NULL)
        {
#if ALIAS_SYMBOL_DEBUGGING
          printf ("Found the SgUsingDirectiveStatement \n");
#endif
          SgNamespaceDeclarationStatement* namespaceDeclaration = usingDirectiveStatement->get_namespaceDeclaration();
          ROSE_ASSERT(namespaceDeclaration != NULL);

          SgScopeStatement* currentScope    = usingDirectiveStatement->get_scope();

       // To be more specific this is really a SgNamespaceDefinitionStatement
          SgScopeStatement* referencedScope = namespaceDeclaration->get_definition();

          if (referencedScope == NULL)
             {
            // DQ (5/21/2010): Handle case of using "std" (predefined namespace in C++), but it not having been explicitly defined (see test2005_57.C).
               if (namespaceDeclaration->get_name() != "std")
                  {
                    printf ("ERROR: namespaceDeclaration has no valid definition \n");
                    namespaceDeclaration->get_startOfConstruct()->display("ERROR: namespaceDeclaration has no valid definition");

                 // DQ (5/20/2010): Added assertion to trap this case.
                    printf ("Exiting because referencedScope could not be identified.\n");
                    ROSE_ASSERT(false);
                  }
             }

       // Note that "std", as a predefined namespace, can have a null definition, so we can't 
       // insist that we inject all symbols in namespaces that we can't see explicitly.
          if (referencedScope != NULL)
             {
               ROSE_ASSERT(referencedScope != NULL);
               ROSE_ASSERT(currentScope != NULL);
#if 0
               printf ("Calling injectSymbolsFromReferencedScopeIntoCurrentScope() for usingDirectiveStatement = %p = %s \n",node,node->class_name().c_str());
#endif
               injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,currentScope,usingDirectiveStatement,SgAccessModifier::e_default);
             }

#if 0
          printf ("Exiting at the base of FixupAstSymbolTablesToSupportAliasedSymbols::visit() \n");
          ROSE_ASSERT(false);
#endif
        }

  // DQ (5/6/2011): Added support to build SgAliasSymbols in derived class scopes that reference the symbols of the base classes associated with protected and public declarations.
     SgClassDefinition* classDefinition = isSgClassDefinition(node);
     if (classDefinition != NULL)
        {
       // Handle any derived classes.
          SgBaseClassPtrList & baseClassList = classDefinition->get_inheritances();
          SgBaseClassPtrList::iterator i = baseClassList.begin();
          for ( ; i != baseClassList.end(); ++i)
             {
            // Check each base class.
               SgBaseClass* baseClass = *i;
               ROSE_ASSERT(baseClass != NULL);

               /* skip processing for SgExpBaseClasses (which don't have to define p_base_class) */
               if (baseClass->variantT() == V_SgExpBaseClass) {
                   continue;
               }

            // printf ("baseClass->get_baseClassModifier().displayString()                      = %s \n",baseClass->get_baseClassModifier().displayString().c_str());
            // printf ("baseClass->get_baseClassModifier().get_accessModifier().displayString() = %s \n",baseClass->get_baseClassModifier().get_accessModifier().displayString().c_str());

            // if (baseClass->get_modifier() == SgBaseClass::e_virtual)
               if (baseClass->get_baseClassModifier().get_modifier() == SgBaseClassModifier::e_virtual)
                  {
                 // Not clear if virtual as a modifier effects the handling of alias symbols.
                 // printf ("Not clear if virtual as a modifier effects the handling of alias symbols. \n");
                  }

            // DQ (6/22/2011): Define the access level for alias symbol's declarations to be included.
               SgAccessModifier::access_modifier_enum accessLevel = baseClass->get_baseClassModifier().get_accessModifier().get_modifier();

               SgClassDeclaration* tmpClassDeclaration    = baseClass->get_base_class();
               ROSE_ASSERT(tmpClassDeclaration != NULL);
#if 0
            // ROSE_ASSERT(tmpClassDeclaration->get_definingDeclaration() != NULL);
               SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(tmpClassDeclaration->get_definingDeclaration());
               ROSE_ASSERT(targetClassDeclaration != NULL);
               SgScopeStatement*   referencedScope  = targetClassDeclaration->get_definition();
            // We need this function to restrict it's injection of symbol to just those that are associated with public and protected declarations.
               injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,classDefinition,accessLevel);
#else
            // DQ (2/25/2012) We only want to inject the symbol where we have identified the defining scope.
               if (tmpClassDeclaration->get_definingDeclaration() != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(tmpClassDeclaration->get_definingDeclaration());
                    ROSE_ASSERT(targetClassDeclaration != NULL);
                    SgScopeStatement*   referencedScope  = targetClassDeclaration->get_definition();
#if 0
                    printf ("Calling injectSymbolsFromReferencedScopeIntoCurrentScope() for classDefinition = %p = %s baseClass = %p accessLevel = %d \n",
                         node,node->class_name().c_str(),baseClass,accessLevel);
#endif
                 // DQ (7/12/2014): Use the SgBaseClass as the causal node that has triggered the insertion of the SgAliasSymbols.
                 // We need this function to restrict it's injection of symbol to just those that are associated with public and protected declarations.
                    injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,classDefinition,baseClass,accessLevel);
                  }
                 else
                  {
                 // DQ (2/25/2012): Print a warning message when this happens (so far only test2012_08.C).
                    if (SgProject::get_verbose() > 0)
                       {
                         mprintf ("WARNING: In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): Not really clear how to handle this case where tmpClassDeclaration->get_definingDeclaration() == NULL! \n");
                       }
                  }
#endif
             }
        }


     SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(node);
     if (functionDeclaration != NULL)
        {
#if ALIAS_SYMBOL_DEBUGGING
          printf ("Found a the SgFunctionDeclaration \n");
#endif
       // SgScopeStatement*  functionScope   = functionDeclaration->get_scope();
          SgScopeStatement*  currentScope    = isSgScopeStatement(functionDeclaration->get_parent());
          SgClassDefinition* classDefinition = isSgClassDefinition(currentScope);

          if (classDefinition != NULL)
             {
            // This is a function declared in a class definition, test of friend (forget why it is important to test for isOperator().
               if (functionDeclaration->get_declarationModifier().isFriend() == true || functionDeclaration->get_specialFunctionModifier().isOperator() == true)
                  {
                 // printf ("Process all friend function with a SgAliasSymbol to where they are declared in another scope (usually global scope) \n");
#if 0
                    SgName name = functionDeclaration->get_name();

                    SgSymbol* symbol = functionDeclaration->search_for_symbol_from_symbol_table();
                    ROSE_ASSERT ( symbol != NULL );

                    SgAliasSymbol* aliasSymbol = new SgAliasSymbol (symbol);

                 // Use the current name and the alias to the symbol
                    currentScope->insert_symbol(name,aliasSymbol);
#endif
#if 0
                    printf ("Error: friend functions not processed yet! \n");
                    ROSE_ASSERT(false);
#endif
                  }
             }
        }

#if ALIAS_SYMBOL_DEBUGGING
     printf ("Leaving FixupAstSymbolTablesToSupportAliasedSymbols::visit() (preorder AST traversal) node = %p = %s \n",node,node->class_name().c_str());
#endif
   }
コード例 #8
0
ファイル: addStruct.C プロジェクト: billhoffman/rose-develop
SgClassDeclaration*
buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope)
   {
  // This function builds a class declaration and definition 
  // (both the defining and nondefining declarations as required).

  // This is the class definition (the fileInfo is the position of the opening brace)
     SgClassDefinition* classDefinition   = new SgClassDefinition(SOURCE_POSITION);
     assert(classDefinition != NULL);

  // Set the end of construct explictly (where not a transformation this is the location of the closing brace)
     classDefinition->set_endOfConstruct(SOURCE_POSITION);

  // This is the defining declaration for the class (with a reference to the class definition)
     SgClassDeclaration* classDeclaration = new SgClassDeclaration(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition);
     assert(classDeclaration != NULL);
     classDeclaration->set_endOfConstruct(SOURCE_POSITION);

  // Set the defining declaration in the defining declaration!
     classDeclaration->set_definingDeclaration(classDeclaration);

  // Set the non defining declaration in the defining declaration (both are required)
     SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL);
     assert(classDeclaration != NULL);
     nondefiningClassDeclaration->set_endOfConstruct(SOURCE_POSITION);
     nondefiningClassDeclaration->set_scope(scope); // scope is needed for createType()
     nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration));

  // Set the internal reference to the non-defining declaration
     classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     classDeclaration->set_type (nondefiningClassDeclaration->get_type());

  // Set the defining and no-defining declarations in the non-defining class declaration!
     nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration);
     nondefiningClassDeclaration->set_definingDeclaration(classDeclaration);

  // Set the nondefining declaration as a forward declaration!
     nondefiningClassDeclaration->setForward();

  // Liao (2/13/2008), symbol for the declaration
     SgClassSymbol* mysymbol = new SgClassSymbol(nondefiningClassDeclaration);
     scope->insert_symbol(name, mysymbol);

  // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)!
     classDefinition->set_declaration(classDeclaration);

  // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!)
     classDeclaration->set_scope(scope);

  //set parent
     classDeclaration->set_parent(scope);
     nondefiningClassDeclaration->set_parent(scope);

  // some error checking
     assert(classDeclaration->get_definingDeclaration() != NULL);
     assert(classDeclaration->get_firstNondefiningDeclaration() != NULL);
     assert(classDeclaration->get_definition() != NULL);

     ROSE_ASSERT(classDeclaration->get_definition()->get_parent() != NULL);

     return classDeclaration;
   }