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;
   }
Beispiel #2
0
NodeQuerySynthesizedAttributeType NodeQuery::queryNodeClassDeclarationFromName(SgNode* node, SgNode* nameNode){
  NodeQuerySynthesizedAttributeType returnList;
  ROSE_ASSERT( nameNode != NULL );
  ROSE_ASSERT( node     != NULL );


  //finds the name which should be matched to 
  SgName* sageName = isSgName(nameNode);
  ROSE_ASSERT( sageName != NULL );
  std::string nameToMatch = sageName->str();
  ROSE_ASSERT( nameToMatch.length() > 0 );

  SgClassDeclaration *sageClassDeclaration = isSgClassDeclaration (node);

  if (sageClassDeclaration != NULL)
  {

    std::string name = sageClassDeclaration->get_name ().str ();

    if( name == nameToMatch )
      returnList.push_back(node);

  }

  return returnList;

} /* End function:queryNodeCLassDeclarationFromName() */
Beispiel #3
0
string
Doxygen::getDeclStmtName(SgDeclarationStatement *st)
{
    SgFunctionDeclaration *fn = isSgFunctionDeclaration(st);
    SgVariableDeclaration *vn = isSgVariableDeclaration(st);
    SgClassDeclaration *cn = isSgClassDeclaration(st);
    if (fn)
    {
        return fn->get_name().str();
    }
    else if (vn)
    {
        /* XXX The following is a bit dodgy since single
         * SgVariableDeclaration may declare multiple
         * variables.  But doxygen doesn't handle this case
         * properly.  A useful transform may split up the
         * SgVariableDeclaration for doxygen's sake */
        return (*(vn->get_variables().begin()))->get_name().str();
    }
    else if (cn)
    {
        return cn->get_name().str();
    }
    else
    {
        fprintf(stderr, "Cannot handle this case: %s\n", st->sage_class_name());
        abort();
    }
}
Beispiel #4
0
NameQuerySynthesizedAttributeType
NameQuery::queryNameStructNames (SgNode * astNode)
{

  ROSE_ASSERT (astNode != 0);

  NameQuerySynthesizedAttributeType returnNameList;

  SgClassDeclaration *sageClassDeclaration = isSgClassDeclaration (astNode);

  if (sageClassDeclaration != NULL)
    if (sageClassDeclaration->get_class_type () ==
        SgClassDeclaration::e_struct)
      {
        string name = sageClassDeclaration->get_name ().str ();

#if DEBUG_NAMEQUERY
        printf ("In case: CLASS_DECL_STMT name = %s \n", name.c_str ());
#endif

        returnNameList.push_back (name);
      }


  return returnNameList;

}                               /* End function queryNameStructNames() */
void
CompassAnalyses::VariableNameEqualsDatabaseName::Traversal::
visit(SgNode* node)
   { 
     if( isSgAssignInitializer(node) != NULL )
          assignExp = node;
  
     if( isSgAssignOp(node) != NULL )
          assignExp = node; 

     SgFunctionCallExp* funcCall = isSgFunctionCallExp(node);

  // See if we have a dot expression or arrow expression which
  // accesses the desired member function in the class we are looking for.
     if ( funcCall != NULL  )
        {
          SgExpression* funcExp = funcCall->get_function();

          if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) )
             {
               SgBinaryOp*     binOp = isSgBinaryOp(funcExp);
               SgExpression*   rhsOp = binOp->get_rhs_operand();
            // SgExpression*   lhsOp = binOp->get_lhs_operand();
               if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp)  )
                  {
                 // std::cout << "c1\n" ;

                    SgMemberFunctionSymbol*      funcSymbol = funcRef->get_symbol();
                    ROSE_ASSERT(funcSymbol->get_declaration() != NULL);

                 // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C)
                 // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL);
                    if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL)
                       {
                         SgMemberFunctionDeclaration* funcDecl   = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration());
                         ROSE_ASSERT( funcDecl != NULL );

                         SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope());
                         SgClassDeclaration*          clDecl     = isSgClassDeclaration(clDef->get_declaration());  

                      // SgClassDeclaration*          clDecl     = funcDecl->get_associatedClassDeclaration();

                         ROSE_ASSERT( clDecl != NULL );
                         std::string className    = clDecl->get_name().getString();

                         ROSE_ASSERT(funcDecl != NULL);
                         std::string functionName = funcDecl->get_name().getString();
 
                      // If the class is the class we are looking for see if the member function
                      // access is to the member function we are interested in.
                      // std::cout << "className = " << className << std::endl;
                      // std::cout << "functionName = " << functionName << std::endl;

                         if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) )
                            {
                              SgExprListExp*         actualArgs    = funcCall->get_args();
                              SgExpressionPtrList&   actualExpArgs = actualArgs->get_expressions ();

                              ROSE_ASSERT(actualExpArgs.size() == 1);
                              Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal);

                              ROSE_ASSERT( nodeLst.size() > 0);
                              SgStringVal* actualArg = isSgStringVal(*nodeLst.begin());
                              ROSE_ASSERT(actualArg != NULL);

                              std::string  stringArg = actualArg->get_value();

                              std::cout << "arg:" << stringArg << std::endl;

                              std::string varName;

                           // SgInitializedName* initName = NULL; 
                              if ( SgAssignInitializer* assignInit =  isSgAssignInitializer(assignExp) )
                                 {
                                   SgInitializedName* initName = isSgInitializedName(assignInit->get_parent());
                                   ROSE_ASSERT(initName != NULL);
                                 
                                   varName = initName->get_name().getString();
                                 }
                                else
                                 {
                                   if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) )
                                      {
                                        SgExpression*     lhsOp  = assignOp->get_lhs_operand();
                                        SgVarRefExp*      varRef = isSgVarRefExp(lhsOp);
                                        ROSE_ASSERT(varRef!=NULL);
                                        SgVariableSymbol* varSymbol = varRef->get_symbol();
                                        ROSE_ASSERT(varSymbol != NULL);
                                        SgInitializedName* initName = varSymbol->get_declaration();
                                        varName = initName->get_name().getString();
                                      }
                                 }
 
                              if (varName != "")
                                 {
                                // we are only interested in the part of the argument after the last ":"
                                // Database scopes in ALE3D are separated by ":"

                                   size_t posCol = stringArg.find_last_of(':');
                                 
                                   if (posCol != std::string::npos)
                                        stringArg = stringArg.substr(posCol+1);

                                 //Find violations to the rule
                                   if ( stringArg != varName)
                                      {
                                        output->addOutput(new CheckerOutput(assignExp));
                                        std::cout << "violation" << varName << std::endl;
                                      }
                                     else 
                                      {
                                        std::cout << "non=violation" << varName << std::endl;
                                      }
                                 }
                            }
                       }
                  }
             } 
        }
   } // End of the visit function.
Beispiel #6
0
void
FixupSelfReferentialMacrosInAST::visit ( SgNode* node )
   {
  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
  // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
     switch (node->variantT())
        {
          case V_SgInitializedName:
             {
               SgInitializedName* initializedName = isSgInitializedName(node);
               ROSE_ASSERT(initializedName != NULL);
               SgType* type = initializedName->get_type()->stripType();
               SgClassType* classType = isSgClassType(type);
               if (classType != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration());
                    SgName className = targetClassDeclaration->get_name();

                 // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str());

                 // For sudo_exec_pty.c also look for siginfo
                    if (className == "sigaction" || className == "siginfo")
                       {
                      // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n");

                      // Note we could also check that the declaration came from a known header file.
                         SgStatement* associatedStatement = isSgStatement(initializedName->get_parent());
                         if (associatedStatement != NULL)
                            {
                           // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro.
                           // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n");

                           // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos );

                              PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration;

                           // We are puting out all macros anytime we see either type.  This might be too much...

                           // From the sigaction.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef sa_handler\n",directiveType);
                              addMacro(associatedStatement,"#undef sa_sigaction\n",directiveType);

                           // From the siginfo.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef si_pid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_uid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_timerid\n",directiveType);
                              addMacro(associatedStatement,"#undef si_overrun\n",directiveType);
                              addMacro(associatedStatement,"#undef si_status\n", directiveType);
                              addMacro(associatedStatement,"#undef si_utime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_stime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_value\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_int\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_ptr\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_addr\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_band\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_fd\n",     directiveType);
                            }
                       }
                  }
             }

          default:
             {
            // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str());
             }
        }

   }
string
SIDL_TreeTraversal::generateSIDLFunctionDeclaration(SgFunctionDeclaration* functionDeclarationStatement )
{
    ROSE_ASSERT (functionDeclarationStatement != NULL);
    ROSE_ASSERT (functionDeclarationStatement->get_file_info() != NULL);
    const SgSpecialFunctionModifier &functionModifier = functionDeclarationStatement->get_specialFunctionModifier();

    string functionName = functionDeclarationStatement->get_name().str();
    string sidlFunctionName ;
    if (functionModifier.isConstructor()) {
        if (functionDeclarationStatement->get_args().size() == 0) return ""; // skip empty constructor
        sidlFunctionName = constructorName;
    }
    else {
        sidlFunctionName = functionName;
    }

    // We have to force the mangled name to be generated before we access it (else we just get "defaultName")
    string mangledFunctionName = functionDeclarationStatement->get_mangled_name().str();

    sidlFunctionName = stringifyOperatorWithoutSymbols(sidlFunctionName);

    // Get the class name
    SgClassDefinition* classDefinition   = isSgClassDefinition(functionDeclarationStatement->get_scope());

    // DQ (1/7/2004): Modified for make EDG version 3.3 work (member function declarations's normalized by EDG)
    if (classDefinition != NULL)
    {
        SgClassDeclaration* classDeclaration = classDefinition->get_declaration();

        string className = classDeclaration->get_name().str();

        overloadInformation info = isOverloaded(classDefinition,functionName,mangledFunctionName);
        int orderofOverloadedFunction = info.get_order();

        // If function is overloaded then append the number indicating the order of appearance in the
        // class declaration
        if (info.get_count() > 1)
        {
            vector<SgType*> types = info.get_types();

            // SgInitializedNamePtrList &args = functionDeclarationStatement->get_args ();
            int size = types.size();
            if(size > 0)
            {
                if(size < 3)
                {
                    sidlFunctionName += "[";
                    for(vector<SgType*>::iterator i = types.begin(); i!= types.end(); i++)
                    {
                        if(i != types.begin()) sidlFunctionName += "_";
                        if(isSgPointerType(*i) != NULL)	sidlFunctionName += "P";
                        sidlFunctionName += sidlOverloadExtension(TransformationSupport::getTypeName(*i));
                    }
                    sidlFunctionName += "]";
                }
                else
                    sidlFunctionName += "["+numberToOverloadString(orderofOverloadedFunction)+"]";
            }
        }
    }
    else
    {
        printf ("EDG version 3.3 can return a null pointer to the member function definition \n");
    }

    SgFunctionType* functionType = functionDeclarationStatement->get_type();
    ROSE_ASSERT(functionType != NULL);

    // SgType* returnType = functionType->get_return_type();
    // ROSE_ASSERT (returnType != NULL);
    // string returnTypeName = TransformationSupport::getTypeName(returnType);

    // printf ("function has_ellipses %s \n",(functionType->get_has_ellipses() != false) ? "true" : "false");
    // showSgFunctionType(cout, functionType, "Called from generateSIDLFunctionDeclaration", 0 );
    // printf ("Function return type = %s \n",returnTypeName.c_str());

#if 0
    SgTypePtrList & argumentTypeList = functionType->get_arguments();
    ROSE_ASSERT (argumentTypeList.size() >= 0);
    SgTypePtrList::iterator argumentIterator = argumentTypeList.begin();

    for (argumentIterator = argumentTypeList.begin(); argumentIterator != argumentTypeList.end(); argumentIterator++)
    {
        // showSgType(os,(*argumentIterator), label, depth+1);

        string argumentTypeName = TransformationSupport::getTypeName(*argumentIterator);
        printf ("-----> argument #%d  argumentTypeName = %s \n",argumentCounter++,argumentTypeName.c_str());
    }
#endif

    //Determine the SIDL parameter passing mechanism (in,out,inout)
    SgInitializedNamePtrList & argumentList = functionDeclarationStatement->get_args();
    string parameterTypesAndNames;
    SgInitializedNamePtrList::iterator i;

    unsigned int argumentCounter = 0;
    for (i = argumentList.begin(); i != argumentList.end(); i++)
    {
        SgType* type = (*i)->get_type();
        ROSE_ASSERT (type != NULL);

        string typeName = TransformationSupport::getTypeName(type);
        ROSE_ASSERT (typeName.c_str() != NULL);

        string sidlParameterPassingMechanim = "in";

        //it seems like the has_ellipses value is wrong, so we'll set it
        functionType->set_has_ellipses(false);
        if(type->variantT() == V_SgTypeEllipse)
        {
            sidlParameterPassingMechanim = "inout";
            functionType->set_has_ellipses(true);
        }
        //else if (type->variantT() == V_SgTypeVoid)
        /*else if (rose::stringDuplicate(type->sage_class_name()) == "SgTypeVoid")
        {
        	printf("found a void\n");
        	//void type is only viable for a pointer.  foo(void) will just become foo()
        	if(isSgPointerType(type) != NULL)
        	{
        		printf("found a void pointer\n");
        		sidlParameterPassingMechanim ="inout opaque";
        	}
        }*/
        else if (isSgReferenceType(type) != NULL)
        {
            sidlParameterPassingMechanim = "inout";
        }
        else if (isSgPointerType(type) != NULL)
        {
            sidlParameterPassingMechanim = "inout";
        }
        else if (isSgArrayType(type) != NULL)
        {
            SgArrayType array = isSgArrayType(type);
            sidlParameterPassingMechanim = "inout Array<";
            SgType* baseType = array.get_base_type();
            sidlParameterPassingMechanim += TransformationSupport::getTypeName(baseType);
            sidlParameterPassingMechanim += ",1>";
            //FIXME: I don't see a way to determine the dimention of the array
        }



        // Build the substring for each parameter

        parameterTypesAndNames += sidlParameterPassingMechanim;
        parameterTypesAndNames += " ";

        //if(type->variantT() != V_SgTypeGlobalVoid)
        //{
        if(type->variantT() == V_SgTypeEllipse)
        {
            parameterTypesAndNames += "Array<BabelBaseType,1> "; //FIXME: need to include a declaration for BaseType
            parameterTypesAndNames += "elips" +  argumentCounter; //this fails to actually append the counter, but I don't think it will matter: kmk
        }
        else
        {
            SgName name = (*i)->get_name();
            string nameString = name.str();
            string typeName = TransformationSupport::getTypeName(type);

            if(typeName == "void")
            {
                if(nameString!="")
                {
                    parameterTypesAndNames += "opaque ";
                    parameterTypesAndNames += nameString;
                }
            }
            else
            {
                parameterTypesAndNames += typeName;
                parameterTypesAndNames += " ";
                if(nameString != "") //will be empty if the function declaration doesn't provide a name
                    parameterTypesAndNames += nameString;
            }
        }

        // Add a "," to the string if there are more parameters in the list
        if ( argumentCounter < argumentList.size()-1 )
            parameterTypesAndNames += ",";
        //}else printf("avoiding the void\n");
        argumentCounter++;
    }

    SgType* returnType = functionType->get_return_type();
    ROSE_ASSERT (returnType != NULL);
    string returnTypeName = "void";
    if(returnType->variantT() != V_SgTypeVoid)
        returnTypeName = TransformationSupport::getTypeName(returnType);


    string sidlMemberFunctionDeclaration = "          $RETURN_TYPE $FUNCTION_NAME($PARAMETERS);\n";

    sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$RETURN_TYPE" , returnTypeName );
    sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$FUNCTION_NAME" , sidlFunctionName );
    sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$PARAMETERS" , parameterTypesAndNames );


    return sidlMemberFunctionDeclaration;
}
Beispiel #8
0
StencilEvaluation_InheritedAttribute
StencilEvaluationTraversal::evaluateInheritedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute )
   {
#if 0
     printf ("In evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     bool foundPairShiftDoubleConstructor = false;

  // This is for stencil specifications using vectors of points to represent offsets (not finished).
  // bool foundVariableDeclarationForStencilInput = false;

     double stencilCoeficientValue = 0.0;

  // StencilOffsetFSM offset;
     StencilOffsetFSM* stencilOffsetFSM = NULL;

  // We want to interogate the SgAssignInitializer, but we need to generality in the refactored function to use any SgInitializer (e.g. SgConstructorInitializer, etc.).
     SgInitializedName* initializedName = detectVariableDeclarationOfSpecificType (astNode,"Point");

     if (initializedName != NULL)
        {
       // This is the code that is specific to the DSL (e.g. the semantics of getZeros() and getUnitv() functions).
       // So this may be the limit of what can be refactored to common DSL support code.
       // Or I can maybe do a second pass at atempting to refactor more code later.

          string name = initializedName->get_name();

          SgInitializer* initializer = initializedName->get_initptr();

          SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer);
          if (assignInitializer != NULL)
             {
               SgExpression* exp = assignInitializer->get_operand();
               ROSE_ASSERT(exp != NULL);
               SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(exp);
               if (functionCallExp != NULL)
                  {
                    SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function());
                    if (functionRefExp != NULL)
                       {
                         SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol();
                         ROSE_ASSERT(functionSymbol != NULL);
                         string functionName = functionSymbol->get_name();
#if 0
                         printf ("functionName = %s \n",functionName.c_str());
#endif
                         if (functionName == "getZeros")
                            {
                           // We leverage the semantics of known functions used to initialize "Point" objects ("getZeros" initialized the Point object to be all zeros).
                           // In a stencil this will be the center point from which all other points will have non-zero offsets.
                           // For a common centered difference discretization this will be the center point of the stencil.
#if 0
                              printf ("Identified and interpreting the semantics of getZeros() function \n");
#endif
                              stencilOffsetFSM = new StencilOffsetFSM(0,0,0);
                              ROSE_ASSERT(stencilOffsetFSM != NULL);
                            }

                         if (functionName == "getUnitv")
                            {
                           // We leverage the semantics of known functions used to initialize "Point" objects 
                           // ("getUnitv" initializes the Point object to be a unit vector for a specific input dimention).
                           // In a stencil this will be an ofset from the center point.
#if 0
                              printf ("Identified and interpreting the semantics of getUnitv() function \n");
#endif
                           // Need to get the dimention argument.
                              SgExprListExp* argumentList = functionCallExp->get_args();
                              ROSE_ASSERT(argumentList != NULL);
                           // This function has a single argument.
                              ROSE_ASSERT(argumentList->get_expressions().size() == 1);
                              SgExpression* functionArg = argumentList->get_expressions()[0];
                              ROSE_ASSERT(functionArg != NULL);
                              SgIntVal* intVal = isSgIntVal(functionArg);
                           // ROSE_ASSERT(intVal != NULL);
                              if (intVal != NULL)
                                 {
                                   int value = intVal->get_value();
#if 0
                                   printf ("value = %d \n",value);
#endif
                                   switch(value)
                                      {
                                        case 0: stencilOffsetFSM = new StencilOffsetFSM(1,0,0); break;
                                        case 1: stencilOffsetFSM = new StencilOffsetFSM(0,1,0); break;
                                        case 2: stencilOffsetFSM = new StencilOffsetFSM(0,0,1); break;

                                        default:
                                           {
                                             printf ("Error: default reached in switch: value = %d (for be value of 0, 1, or 2) \n",value);
                                             ROSE_ASSERT(false);
                                           }
                                      }

                                   ROSE_ASSERT(stencilOffsetFSM != NULL);

                                // End of test for intVal != NULL
                                 }
                                else
                                 {
#if 0
                                   printf ("functionArg = %p = %s \n",functionArg,functionArg->class_name().c_str());
#endif
                                 }
                            }

                          // ROSE_ASSERT(stencilOffsetFSM != NULL);
                       }
                  }
             }

           if (stencilOffsetFSM != NULL)
             {
            // Put the FSM into the map.
#if 0
               printf ("Put the stencilOffsetFSM = %p into the StencilOffsetMap using key = %s \n",stencilOffsetFSM,name.c_str());
#endif
               ROSE_ASSERT(StencilOffsetMap.find(name) == StencilOffsetMap.end());

            // We have a choice of syntax to add the element to the map.
            // StencilOffsetMap.insert(pair<string,StencilOffsetFSM*>(name,stencilOffsetFSM));
               StencilOffsetMap[name] = stencilOffsetFSM;
             }

       // new StencilOffsetFSM();
#if 0
          printf ("Exiting as a test! \n");
          ROSE_ASSERT(false);
#endif
        }

  // Recognize member function calls on "Point" objects so that we can trigger events on those associated finite state machines.
     bool isTemplateClass = false;
     bool isTemplateFunctionInstantiation = false;
     SgInitializedName* initializedNameUsedToCallMemberFunction = NULL;
     SgFunctionCallExp* functionCallExp = detectMemberFunctionOfSpecificClassType(astNode,initializedNameUsedToCallMemberFunction,"Point",isTemplateClass,"operator*=",isTemplateFunctionInstantiation);
     if (functionCallExp != NULL)
        {
       // This is the DSL specific part (capturing the semantics of operator*= with specific integer values).

       // The name of the variable off of which the member function is called (variable has type "Point").
          ROSE_ASSERT(initializedNameUsedToCallMemberFunction != NULL);
          string name = initializedNameUsedToCallMemberFunction->get_name();

       // Need to get the dimention argument.
          SgExprListExp* argumentList = functionCallExp->get_args();
          ROSE_ASSERT(argumentList != NULL);
       // This function has a single argument.
          ROSE_ASSERT(argumentList->get_expressions().size() == 1);
          SgExpression* functionArg = argumentList->get_expressions()[0];
          ROSE_ASSERT(functionArg != NULL);
          SgIntVal* intVal = isSgIntVal(functionArg);

          bool usingUnaryMinus = false;
          if (intVal == NULL)
             {
               SgMinusOp* minusOp = isSgMinusOp(functionArg);
               if (minusOp != NULL)
                  {
#if 0
                    printf ("Using SgMinusOp on stencil constant \n");
#endif
                    usingUnaryMinus = true;
                    intVal = isSgIntVal(minusOp->get_operand());
                  }
             }

          ROSE_ASSERT(intVal != NULL);
          int value = intVal->get_value();

          if (usingUnaryMinus == true)
             {
               value *= -1;
             }
#if 0
          printf ("value = %d \n",value);
#endif
       // Look up the stencil offset finite state machine
          ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end());
          StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name];
          ROSE_ASSERT(stencilOffsetFSM != NULL);
#if 0
          printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str());
#endif
#if 0
          stencilOffsetFSM->display("before multiply event");
#endif
          if (value == -1)
             {
            // Execute the event on the finte state machine to accumulate the state.
               stencilOffsetFSM->operator*=(-1);
             }
            else
             {
               printf ("Error: constant value other than -1 are not supported \n");
               ROSE_ASSERT(false);
             }
#if 0
          stencilOffsetFSM->display("after multiply event");
#endif
        }

  // Detection of "pair<Shift,double>(xdir,ident)" defined as an event in the stencil finite machine model.
  // Actually, it is the Stencil that is create using the "pair<Shift,double>(xdir,ident)" that should be the 
  // event so we first detect the SgConstructorInitializer.  There is not other code similar to this which 
  // has to test for the template arguments, so this has not yet refactored into the dslSupport.C file.
  // I will do this later since this is general support that could be resused in other DSL compilers.
     SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(astNode);
     if (constructorInitializer != NULL)
        {
       // DQ (10/20/2014): This can sometimes be NULL.
       // ROSE_ASSERT(constructorInitializer->get_class_decl() != NULL);
          SgClassDeclaration* classDeclaration = constructorInitializer->get_class_decl();
       // ROSE_ASSERT(classDeclaration != NULL);
          if (classDeclaration != NULL)
             {
#if 0
          printf ("constructorInitializer = %p class name    = %s \n",constructorInitializer,classDeclaration->get_name().str());
#endif
          SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classDeclaration);
       // ROSE_ASSERT(templateInstantiationDecl != NULL);
#if 0
          if (templateInstantiationDecl != NULL)
             {
               printf ("constructorInitializer = %p name = %s template name = %s \n",constructorInitializer,templateInstantiationDecl->get_name().str(),templateInstantiationDecl->get_templateName().str());
             }
#endif

       // if (classDeclaration->get_name() == "pair")
          if (templateInstantiationDecl != NULL && templateInstantiationDecl->get_templateName() == "pair")
             {
            // Look at the template parameters.
#if 0
               printf ("Found template instantiation for pair \n");
#endif
               SgTemplateArgumentPtrList & templateArgs = templateInstantiationDecl->get_templateArguments();
               if (templateArgs.size() == 2)
                  {
                 // Now look at the template arguments and check that they represent the pattern that we are looking for in the AST.
                 // It is not clear now flexible we should be, at present shift/coeficent pairs must be specified exactly one way.

                    SgType* type_0 = templateArgs[0]->get_type();
                    SgType* type_1 = templateArgs[1]->get_type();

                    if ( type_0 != NULL && type_1 != NULL)
                       {
                         SgClassType* classType_0 = isSgClassType(type_0);
                      // ROSE_ASSERT(classType_0 != NULL);
                         if (classType_0 != NULL)
                            {
                         SgClassDeclaration* classDeclarationType_0 = isSgClassDeclaration(classType_0->get_declaration());
                         ROSE_ASSERT(classDeclarationType_0 != NULL);
#if 0
                         printf ("templateArgs[0]->get_name() = %s \n",classDeclarationType_0->get_name().str());
                         printf ("templateArgs[1]->get_type()->class_name() = %s \n",type_1->class_name().c_str());
#endif
                         bool foundShiftExpression   = false;
                         bool foundStencilCoeficient = false;

                      // We might want to be more flexiable about the type of the 2nd parameter (allow SgTypeFloat, SgTypeComplex, etc.).
                         if (classDeclarationType_0->get_name() == "Shift" && type_1->variant() == V_SgTypeDouble)
                            {
                           // Found a pair<Shift,double> input for a stencil.
#if 0
                              printf ("##### Found a pair<Shift,double>() input for a stencil input \n");
#endif
                           // *****************************************************************************************************
                           // Look at the first parameter to the pair<Shift,double>() constructor.
                           // *****************************************************************************************************
                              SgExpression* stencilOffset = constructorInitializer->get_args()->get_expressions()[0];
                              ROSE_ASSERT(stencilOffset != NULL);
#if 0
                              printf ("stencilOffset = %p = %s \n",stencilOffset,stencilOffset->class_name().c_str());
#endif
                              SgConstructorInitializer* stencilOffsetConstructorInitializer = isSgConstructorInitializer(stencilOffset);
                              if (stencilOffsetConstructorInitializer != NULL)
                                 {
                                // This is the case of a Shift being constructed implicitly from a Point (doing so more directly would be easier to make sense of in the AST).
#if 0
                                   printf ("!!!!! Looking for the stencil offset \n");
#endif
                                   ROSE_ASSERT(stencilOffsetConstructorInitializer->get_class_decl() != NULL);
                                   SgClassDeclaration* stencilOffsetClassDeclaration = stencilOffsetConstructorInitializer->get_class_decl();
                                   ROSE_ASSERT(stencilOffsetClassDeclaration != NULL);
#if 0
                                   printf ("stencilOffsetConstructorInitializer = %p class name    = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration->get_name().str());
                                   printf ("stencilOffsetConstructorInitializer = %p class = %p = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration,stencilOffsetClassDeclaration->class_name().c_str());
#endif
                                // This should not be a template instantiation (the Shift is defined to be a noo-template class declaration, not a template class declaration).
                                   SgTemplateInstantiationDecl* stencilOffsetTemplateInstantiationDecl = isSgTemplateInstantiationDecl(stencilOffsetClassDeclaration);
                                   ROSE_ASSERT(stencilOffsetTemplateInstantiationDecl == NULL);

                                   if (stencilOffsetClassDeclaration != NULL && stencilOffsetClassDeclaration->get_name() == "Shift")
                                      {
                                     // Now we know that the type associated with the first template parameter is associated with the class "Shift".
                                     // But we need so also now what the first parametr is associate with the constructor initializer, since it will
                                     // be the name of the variable used to interprete the stencil offset (and the name of the variable will be the 
                                     // key into the map of finite machine models used to accumulate the state of the stencil offsets that we accumulate
                                     // to build the stencil.

                                     // Now we need the value of the input (computed using it's fine state machine).
                                        SgExpression* inputToShiftConstructor = stencilOffsetConstructorInitializer->get_args()->get_expressions()[0];
                                        ROSE_ASSERT(inputToShiftConstructor != NULL);
                                        SgConstructorInitializer* inputToShiftConstructorInitializer = isSgConstructorInitializer(inputToShiftConstructor);
                                        if (stencilOffsetConstructorInitializer != NULL)
                                           {
                                             SgExpression* inputToPointConstructor = inputToShiftConstructorInitializer->get_args()->get_expressions()[0];
                                             ROSE_ASSERT(inputToPointConstructor != NULL);

                                          // This should be a SgVarRefExp (if we strictly follow the stencil specification rules (which are not written down yet).
                                             SgVarRefExp* inputToPointVarRefExp = isSgVarRefExp(inputToPointConstructor);
                                             if (inputToPointVarRefExp != NULL)
                                                {
#if 0
                                                  printf ("Found varRefExp in bottom of chain of constructors \n");
#endif
                                                  SgVariableSymbol* variableSymbolForOffset = isSgVariableSymbol(inputToPointVarRefExp->get_symbol());
                                                  ROSE_ASSERT(variableSymbolForOffset != NULL);
                                                  SgInitializedName* initializedNameForOffset = variableSymbolForOffset->get_declaration();
                                                  ROSE_ASSERT(initializedNameForOffset != NULL);
                                                  SgInitializer* initializer = initializedNameForOffset->get_initptr();
                                                  ROSE_ASSERT(initializer != NULL);
#if 0
                                                  printf ("Found initializedName: name = %s in bottom of chain of constructors: initializer = %p = %s \n",initializedNameForOffset->get_name().str(),initializer,initializer->class_name().c_str());
#endif
                                               // Record the name to be used as a key into the map of "StencilOffset" finite state machines.

                                                  SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer);
                                                  ROSE_ASSERT(assignInitializer != NULL);

                                                  string name = initializedNameForOffset->get_name();
                                               // Look up the current state in the finite state machine for the "Point".

                                               // Check that this is a previously defined stencil offset.
                                                  ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end());
                                               // StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name];
                                                  stencilOffsetFSM = StencilOffsetMap[name];
                                                  ROSE_ASSERT(stencilOffsetFSM != NULL);
#if 0
                                                  printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str());
#endif
#if 0
                                                  printf ("Exiting as a test! \n");
                                                  ROSE_ASSERT(false);
#endif
                                                }
                                               else
                                                {
                                                  printf ("What is this expression: inputToPointConstructor = %p = %s \n",inputToPointConstructor,inputToPointConstructor->class_name().c_str());
                                                  ROSE_ASSERT(false);
                                                }
                                           }
#if 0
                                        printf ("Found Shift type \n");
#endif
                                        foundShiftExpression = true;
                                      }
#if 0
                                   printf ("Exiting as a test! \n");
                                   ROSE_ASSERT(false);
#endif
                                 }
                                else
                                 {
                                // This case for the specification of a Shift in the first argument is not yet supported (need an example of this).
                                   printf ("This case of using a shift is not a part of what is supported \n");
                                 }

                           // *****************************************************************************************************
                           // Look at the second parameter to the pair<Shift,double>(first_parameter,second_parameter) constructor.
                           // *****************************************************************************************************
                              SgExpression* stencilCoeficent = constructorInitializer->get_args()->get_expressions()[1];
                              ROSE_ASSERT(stencilCoeficent != NULL);

                              SgVarRefExp* stencilCoeficentVarRefExp = isSgVarRefExp(stencilCoeficent);
                              if (stencilCoeficentVarRefExp != NULL)
                                 {
                                // Handle the case where this is a constant SgVarRefExp and the value is available in the declaration.
                                   SgVariableSymbol* variableSymbolForConstant = isSgVariableSymbol(stencilCoeficentVarRefExp->get_symbol());
                                   ROSE_ASSERT(variableSymbolForConstant != NULL);
                                   SgInitializedName* initializedNameForConstant = variableSymbolForConstant->get_declaration();
                                   ROSE_ASSERT(initializedNameForConstant != NULL);
                                   SgInitializer* initializer = initializedNameForConstant->get_initptr();
                                   ROSE_ASSERT(initializer != NULL);
                                   SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer);
                                   ROSE_ASSERT(assignInitializer != NULL);

                                   SgValueExp* valueExp = isSgValueExp(assignInitializer->get_operand());

                                   bool usingUnaryMinus = false;
                                // ROSE_ASSERT(valueExp != NULL);
                                   if (valueExp == NULL)
                                      {
                                        SgExpression* operand = assignInitializer->get_operand();
                                        SgMinusOp* minusOp = isSgMinusOp(operand);
                                        if (minusOp != NULL)
                                           {
#if 0
                                             printf ("Using SgMinusOp on stencil constant \n");
#endif
                                             usingUnaryMinus = true;
                                             valueExp = isSgValueExp(minusOp->get_operand());
                                           }
                                      }

                                   SgDoubleVal* doubleVal = isSgDoubleVal(valueExp);
                                // ROSE_ASSERT(doubleVal != NULL);
                                   double value = 0.0;
                                   if (doubleVal == NULL)
                                      {
                                     // Call JP's function to evaluate the constant expression.
                                        ROSE_ASSERT(valueExp == NULL);
                                        ROSE_ASSERT(stencilCoeficent != NULL);
                                        DSL_Support::const_numeric_expr_t const_expression = DSL_Support::evaluateConstNumericExpression(stencilCoeficent);
                                        if (const_expression.hasValue_ == true)
                                           {
                                             ROSE_ASSERT(const_expression.isIntOnly_ == false);
                                             value = const_expression.value_;

                                             printf ("const expression evaluated to value = %4.2f \n",value);
                                           }
                                          else
                                           {
                                             printf ("constnat value expression could not be evaluated to a constant \n");
                                             ROSE_ASSERT(false);
                                           }
                                      }
                                     else
                                      {
#if 1
                                        printf ("SgDoubleVal value = %f \n",doubleVal->get_value());
#endif
                                        value = (usingUnaryMinus == false) ? doubleVal->get_value() : -(doubleVal->get_value());
                                      }
#if 1
                                   printf ("Stencil coeficient = %f \n",value);
#endif
                                   foundStencilCoeficient = true;

                                   stencilCoeficientValue = value;
                                 }
                                else
                                 {
                                // When we turn on constant folding in the frontend we eveluate directly to a SgDoubleVal.
                                   SgDoubleVal* doubleVal = isSgDoubleVal(stencilCoeficent);
                                   if (doubleVal != NULL)
                                      {
                                        ROSE_ASSERT(doubleVal != NULL);
#if 0
                                        printf ("SgDoubleVal value = %f \n",doubleVal->get_value());
#endif
                                        double value = doubleVal->get_value();
#if 0
                                        printf ("Stencil coeficient = %f \n",value);
#endif
                                        foundStencilCoeficient = true;

                                        stencilCoeficientValue = value;
                                      }
                                     else
                                      {
                                        printf ("Error: second parameter in pair for stencil is not a SgVarRefExp (might be explicit value not yet supported) \n");
                                        printf ("   --- stencilCoeficent = %p = %s \n",stencilCoeficent,stencilCoeficent->class_name().c_str());
                                        ROSE_ASSERT(false);
                                      }
                                 }
                            }
#if 0
                         printf ("foundShiftExpression   = %s \n",foundShiftExpression   ? "true" : "false");
                         printf ("foundStencilCoeficient = %s \n",foundStencilCoeficient ? "true" : "false");
#endif
                         if (foundShiftExpression == true && foundStencilCoeficient == true)
                            {
#if 0
                              printf ("Found pair<Shift,double>() constructor expression! \n");
#endif
                              foundPairShiftDoubleConstructor = true;
                            }

                         // End of test for classType_0 != NULL
                            }
                       }
                  }
             }
            else
             {
#if 0
               printf ("This is not a SgConstructorInitializer for the pair templated class \n");
#endif
             }

          // End of test for classDeclaration != NULL
             }
        }

#if 0
     printf ("foundPairShiftDoubleConstructor = %s \n",foundPairShiftDoubleConstructor ? "true" : "false");
#endif

     if (foundPairShiftDoubleConstructor == true)
        {
       // This is the recognition of an event for one of the finite state machines we implement to evaluate the stencil at compile time.
#if 0
          printf ("In evaluateInheritedAttribute(): found pair<Shift,double>() constructor expression! \n");
          printf ("   --- stencilOffsetFSM       = %p \n",stencilOffsetFSM);
          printf ("   --- stencilCoeficientValue = %f \n",stencilCoeficientValue);
#endif
          ROSE_ASSERT(stencilOffsetFSM != NULL);

          inheritedAttribute.stencilOffsetFSM       = stencilOffsetFSM;
          inheritedAttribute.stencilCoeficientValue = stencilCoeficientValue;

#if 0
          printf ("Exiting as a test! \n");
          ROSE_ASSERT(false);
#endif
        }

  // Construct the return attribute from the modified input attribute.
     return StencilEvaluation_InheritedAttribute(inheritedAttribute);
   }
Beispiel #9
0
//-----------------------------------------------------------------------------
// Functions required by the tree traversal mechanism
ClasshierarchyInhAttr
ClasshierarchyTraversal::evaluateInheritedAttribute (
                SgNode* astNode,
                ClasshierarchyInhAttr inheritedAttribute )
{
        GlobalDatabaseConnection *gdb;    // db connection
        //long funcId;                                                                                  // id of a function declaration
        Classhierarchy *classhier = getClasshierarchy();
        gdb = getDB();  

        switch(astNode->variantT())
        {

                case V_SgMemberFunctionDeclaration: {
                        SgMemberFunctionDeclaration *funcDec = isSgMemberFunctionDeclaration( astNode );
                        //funcDec = funcDef->get_declaration();
                        //if(isSgMemberFunctionDeclaration(funcDec)) {
                                // add to class hierarchy if member function definition
                                //if(isSgMemberFunctionDeclaration()) {
                                //cerr << " adding CHvinf for MembFunc " << endl;
                                SgClassDefinition *classDef = isSgClassDefinition( funcDec->get_scope() );
                                //assert(classDef);
                                if(classDef) {
                                        string classname = classDef->get_qualified_name().str();
                                        // get the classhier. vertex
                                        Classhierarchy::dbgVertex chVert = 0; //?? init necessary
                                        bool foundClass = false;
                                        Classhierarchy::dbgVertexIterator chvi,chvend;
                                        boost::tie(chvi,chvend) = boost::vertices( *getClasshierarchy() );
                                        for(; chvi!=chvend; chvi++) {
                                                if( boost::get( vertex_dbg_data,  *getClasshierarchy() , *chvi).get_typeName() == classname ) {
                                                        chVert = *chvi;
                                                        foundClass = true;
                                                }
                                        }
                                        if(foundClass) {
                                                property_map< Classhierarchy::dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *getClasshierarchy() );
                                                chMap[ chVert ].defined.insert( funcDec );
                                                //get type?
                                                //cerr << " added! "; // debug
                                        }
                                }

                        //}
                        cerr << " found V_SgMemberFunctionDeclaration done for " <<funcDec->get_mangled_name().str()<< " " << endl; // debug
                        } break;

                case V_SgClassDefinition: {
                        cerr << " found V_SgClassDef of "; // debug
                        SgClassDefinition *classDef = isSgClassDefinition( astNode );
                        assert( classDef );
                        SgName classname = classDef->get_qualified_name();

                        // make db entry
                        long typeId = UNKNOWNID;
                        typesTableAccess types( gdb );
                        typesRowdata newtype( typeId, getProjectId(), classname.str() );
                        typeId = types.retrieveCreateByColumn( &newtype, "typeName", newtype.get_typeName(), newtype.get_projectId() );
                        cerr << classname.str()<< ", id:" << newtype.get_id() << endl; // debug
                        //classhier->addNode( newtype, newtype.get_typeName() );
                        //classhier->insertWithName( newtype, newtype.get_typeName() );
                        classhier->insertVertex( newtype, newtype.get_typeName() );

                        SgBaseClassList inherits = classDef->get_inheritances();
                        for( SgBaseClassList::iterator i=inherits.begin(); i!=inherits.end(); i++) {
                                SgClassDeclaration *parentDecl = (*i).get_base_class();
                                cerr << " found inheritance from " ; // debug
                                assert( parentDecl );

                                // add new edge
                                typesRowdata partype( UNKNOWNID, getProjectId(), parentDecl->get_name().str() ); // MANGLE
                                long parentId = types.retrieveCreateByColumn( &partype, "typeName", partype.get_typeName(), partype.get_projectId() );
                                cerr << parentDecl->get_name().str() << ", id: " << parentId << endl;

                                // add to class hierarchy graph, allow only one edge per inheritance
                                //A classhier->addNode( partype, partype.get_typeName() );
                                //A classhier->addEdge( newtype, partype, false );
                                classhier->insertEdge( newtype, partype );
                        }
                        
                        } break;

        } // switch node type


        // Note that we have to use a particular constructor (to pass on context information about source code position).
        // This allows the Rewrite mechanism to position new source code relative to the current position using a simple interface.
        ClasshierarchyInhAttr returnAttribute(inheritedAttribute,astNode);
        // FIXME why not return inheritedAttribute???

        return returnAttribute;
}
Beispiel #10
0
ATerm convertNodeToAterm(SgNode* n) 
   {
     if (n == NULL)
        {
#if 0
          printf ("convertNodeToAterm(): n = %p = %s \n",n,"NULL");
#endif
          return ATmake("NULL");
        }

     ROSE_ASSERT(n != NULL);
#if 0
     printf ("convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif

     ATerm term;
     switch (n->variantT())
        {
       // case V_SgFile:
          case V_SgSourceFile:
            // Special case needed to include file name
            // term = ATmake("File(<str>, <term>)", isSgFile(n)->getFileName(), convertNodeToAterm(isSgFile(n)->get_root()));
               term = ATmake("File(<str>, <term>)", isSgSourceFile(n)->getFileName().c_str(), convertNodeToAterm(isSgSourceFile(n)->get_globalScope()));
               break;

          case V_SgPlusPlusOp:
          case V_SgMinusMinusOp:
            // Special cases needed to include prefix/postfix status
               term = ATmake("<appl(<appl>, <term>)>",
                  getShortVariantName((VariantT)(n->variantT())).c_str(),
                  (isSgUnaryOp(n)->get_mode() == SgUnaryOp::prefix ? "Prefix" :
                   isSgUnaryOp(n)->get_mode() == SgUnaryOp::postfix ? "Postfix" :
                   "Unknown"),
                   convertNodeToAterm(isSgUnaryOp(n)->get_operand()));
               break;

          case V_SgExpressionRoot:
            // Special case to remove this node
               term = convertNodeToAterm(isSgExpressionRoot(n)->get_operand());
               break;

    case V_SgCastExp:
    // Special case needed to include type
    term = ATmake("Cast(<term>, <term>)>",
	    convertNodeToAterm(isSgUnaryOp(n)->get_operand()),
	    convertNodeToAterm(isSgCastExp(n)->get_type()));
    break;

    case V_SgVarRefExp:
    // Special case needed to include id
    term = ATmake("Var(<str>)", 
		  uniqueId(isSgVarRefExp(n)->get_symbol()->get_declaration()).c_str());
    break;

    case V_SgFunctionRefExp:
    // Special case needed to include id
    term = ATmake(
                  "Func(<str>)", 
                  uniqueId(isSgFunctionRefExp(n)->get_symbol()->get_declaration()).c_str());
    break;

    case V_SgIntVal:
    // Special case needed to include value
    term = ATmake("IntC(<int>)", isSgIntVal(n)->get_value());
    break;

    case V_SgUnsignedIntVal:
    term = ATmake("UnsignedIntC(<int>)", isSgUnsignedIntVal(n)->get_value());
    break;

    case V_SgUnsignedLongVal: {
      ostringstream s;
      s << isSgUnsignedLongVal(n)->get_value();
      term = ATmake("UnsignedLongC(<str>)", s.str().c_str());
    }
    break;

    case V_SgUnsignedLongLongIntVal: {
      ostringstream s;
      s << isSgUnsignedLongLongIntVal(n)->get_value();
      term = ATmake("UnsignedLongLongC(<str>)", s.str().c_str());
    }
    break;

    case V_SgDoubleVal:
    term = ATmake("DoubleC(<real>)", isSgDoubleVal(n)->get_value());
    break;

          case V_SgInitializedName:
             {
            // Works around double initname problem
               SgInitializer* initializer = isSgInitializedName(n)->get_initializer();
               const SgName& name = isSgInitializedName(n)->get_name();
               SgType* type = isSgInitializedName(n)->get_type();

               ROSE_ASSERT(type != NULL);
#if 0
               printf ("convertNodeToAterm(): case V_SgInitializedName: name = %s initializer = %p type = %p = %s \n",name.str(),initializer,type,type->class_name().c_str());
#endif
            // Works around fact that ... is not really an initname and shouldn't be a type either
               if (isSgTypeEllipse(type))
                  {
                    term = ATmake("Ellipses");
                  }
                 else
                  {
                    std::string uniqueIdString = uniqueId(n);
#if 0
                    printf ("uniqueIdString = %s \n",uniqueIdString.c_str());
                    printf ("Calling generate ATerm for SgInitializedName->get_name() name = %s \n",name.str());
                    ATerm name_aterm = ATmake("Name(<str>)",name.str());
                 // ATerm name_aterm = ATmake(name.str());
                    printf ("Calling convertNodeToAterm(type) \n");
                    ATerm type_aterm = convertNodeToAterm(type);
                    printf ("Calling convertNodeToAterm(initializer) \n");
#endif
                    ATerm initializer_aterm = convertNodeToAterm(initializer);
#if 0
                    printf ("Calling ATmake() \n");
#endif
#if 1
                    term = ATmake("InitName(<str>, <term>, <term>) {[id, <str>]}", 
                                    (name.str() ? name.str() : ""), 
                                    convertNodeToAterm(type), 
                                    convertNodeToAterm(initializer),
                                    uniqueId(n).c_str());
                                 // uniqueIdString.c_str());
#else
                    term = ATmake("InitName(<term>,<term>)",
                                  //(name.str() ? name.str() : ""), 
                                  // name_aterm,
                                    type_aterm, 
                                    initializer_aterm
                                 // uniqueId(n).c_str());
                                 // uniqueIdString.c_str());
                                    );
#endif
#if 0
                    printf ("Calling ATsetAnnotation() \n");
#endif
                    term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str()));
#if 0
                    printf ("DONE: Calling ATsetAnnotation() \n");
#endif
                  }

               break;
             }

    case V_SgFunctionDeclaration: {
      // Special case needed to include name
      SgFunctionDeclaration* fd = isSgFunctionDeclaration(n);
      term = ATmake("Function(<str>, <term>, <term>, <term>)", 
		    fd->get_name().str(), 
		    convertNodeToAterm(fd->get_orig_return_type()),
		    convertSgNodeRangeToAterm(fd->get_args().begin(),
					      fd->get_args().end()),
		    convertNodeToAterm(fd->get_definition()));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgClassDeclaration: {
      // Special case needed to distinguish forward/full definitions and to
      // include class name
      SgClassDeclaration* decl = isSgClassDeclaration(n);
      assert (decl);
      SgName sname = decl->get_name();
      const char* name = sname.str();
      // Suggestion: have a field named local_definition in each class
      // declaration that is 0 whenever the current declaration doesn't
      // have a definition attached, even if there is another declaration
      // which does have a definition attached.
      SgClassDefinition* defn = decl->get_definition();
      // cout << "defn = 0x" << hex << defn << endl << dec;
      if (decl->isForward())
	defn = 0;
      if (defn)
	term = ATmake("Class(<str>, <term>)", 
		      (name ? name : ""), // Will be simpler when SgName
		      // becomes string
		      convertNodeToAterm(defn));
      else
	term = ATmake("ClassFwd(<str>)", (name ? name : ""));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgEnumDeclaration: {
      // Special case to include enum name and enumerator names which are not
      // traversal children
      SgName sname = isSgEnumDeclaration(n)->get_name();
      const char* name = sname.str();
      const SgInitializedNamePtrList& enumerators = 
	isSgEnumDeclaration(n)->get_enumerators();
      term = ATmake("Enum(<str>, <term>)",
		    (name ? name : "{anonymous}"), 
		    convertSgNodeRangeToAterm(enumerators.begin(),
					      enumerators.end()));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgPointerType: {
      // Special case because types can't be traversed yet
      SgType* type = isSgPointerType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Pointer(<term>)", t);
    }
    break;

    case V_SgReferenceType: {
      // Special case because types can't be traversed yet
      SgType* type = isSgReferenceType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Reference(<term>)", t);
    }
    break;

    case V_SgModifierType: {
      // Special case for type traversal and to prettify modifier names
      SgType* type = isSgModifierType(n)->get_base_type();
      SgTypeModifier& modifier = isSgModifierType(n)->get_typeModifier();
      SgConstVolatileModifier& cvmod = modifier.get_constVolatileModifier();
      term = convertNodeToAterm(type);
      if (cvmod.isConst())
	term = ATmake("Const(<term>)", term);
      if (cvmod.isVolatile())
	term = ATmake("Volatile(<term>)", term);
    }
    break;

    case V_SgArrayType: {
      // Special case because types can't be traversed yet, and to get length
      SgType* type = isSgArrayType(n)->get_base_type();
      ATerm t = convertNodeToAterm(type);
      term = ATmake("Array(<term>, <term>)", t, (isSgArrayType(n)->get_index() ? convertNodeToAterm((n->get_traversalSuccessorContainer())[4]) : ATmake("<str>", "NULL")));
      assert (term);
    }
    break;

    case V_SgFunctionType: {
      // Special case to allow argument list to be traversed
      SgFunctionType* ft = isSgFunctionType(n);
      ATerm ret = convertNodeToAterm(ft->get_return_type());
      ATerm args_list = convertSgNodeRangeToAterm(ft->get_arguments().begin(),
						  ft->get_arguments().end());
      term = ATmake("FunctionType(<term>, <term>)", ret, args_list);
    }
    break;

    case V_SgEnumType:
    case V_SgClassType: 
    case V_SgTypedefType: {
      // Special cases to optionally put in type definition instead of
      // reference
      SgNamedType* nt = isSgNamedType(n);
      assert (nt);
      SgName sname = nt->get_name();
   // char* name = sname.str();
      SgDeclarationStatement* decl = nt->get_declaration();
      assert (decl);
      SgClassDefinition* defn = isSgClassDeclaration(decl) ?
				isSgClassDeclaration(decl)->get_definition() :
				0;
      term = ATmake("Type(<term>)",
		    (nt->get_autonomous_declaration() || !defn ? 
                     ATmake("id(<str>)", uniqueId(decl).c_str()) :
		     convertNodeToAterm(nt->get_declaration())));
    }
    break;

    case V_SgLabelStatement: {
      // Special case to put in label id
      const char* name = isSgLabelStatement(n)->get_name().str();
      term = ATmake("Label(<str>)", (name ? name : ""));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgGotoStatement: {
      // Special case to put in label id
      term = ATmake("Goto(<str>)", 
                    uniqueId(isSgGotoStatement(n)->get_label()).c_str());
    }
    break;

    case V_SgTypedefDeclaration: {
      // Special case to put in typedef name
      const SgName& name = isSgTypedefDeclaration(n)->get_name();
      SgType* type = isSgTypedefDeclaration(n)->get_base_type();
      term = ATmake("Typedef(<str>, <term>)", (name.str() ? name.str() : ""), 
		      convertNodeToAterm(type));
      term = ATsetAnnotation(term, ATmake("id"),
                             ATmake("<str>", uniqueId(n).c_str()));
    }
    break;

    case V_SgTemplateDeclaration: {
      // Traversal doesn't work for these
      SgTemplateDeclaration* td = isSgTemplateDeclaration(n);
      ROSE_ASSERT (td);
   // SgTemplateParameterPtrListPtr paramsPtr = td->get_templateParameters();
   // SgTemplateParameterPtrList & paramsPtr = td->get_templateParameters();
   // SgTemplateParameterPtrList params =	paramsPtr ? *paramsPtr : SgTemplateParameterPtrList();
      SgTemplateParameterPtrList & params =	td->get_templateParameters();
      string templateKindString;
      switch (td->get_template_kind()) {
	case SgTemplateDeclaration::e_template_none:
	  templateKindString = "None"; break;
	case SgTemplateDeclaration::e_template_class:
	  templateKindString = "Class"; break;
	case SgTemplateDeclaration::e_template_m_class:
	  templateKindString = "MemberClass"; break;
	case SgTemplateDeclaration::e_template_function:
	  templateKindString = "Function"; break;
	case SgTemplateDeclaration::e_template_m_function:
	  templateKindString = "MemberFunction"; break;
	case SgTemplateDeclaration::e_template_m_data:
	  templateKindString = "MemberData"; break;
	default: templateKindString = "Unknown"; break;
      }
      term = ATmake("TemplateDeclaration(<appl>, <str>, <term>, <str>)",
		    templateKindString.c_str(),
		    td->get_name().str(),
		    convertSgNodeRangeToAterm(params.begin(), params.end()),
		    td->get_string().str());
    }
    break;

    case V_SgTemplateInstantiationDecl: {
      // Traversal doesn't work for these
      SgTemplateInstantiationDecl* td = isSgTemplateInstantiationDecl(n);
      ROSE_ASSERT (td);
   // SgTemplateArgumentPtrListPtr argsPtr = td->get_templateArguments();
   // SgTemplateArgumentPtrList args = argsPtr ? *argsPtr : SgTemplateArgumentPtrList();
      SgTemplateArgumentPtrList & args = td->get_templateArguments();
      term = ATmake("TemplateInstantiationDecl(<str>, <term>)", td->get_templateDeclaration()->get_name().str(), convertSgNodeRangeToAterm(args.begin(), args.end()));
    }
    break;

    case V_SgTemplateParameter: {
      // Traversal doesn't work for these
      SgTemplateParameter* tp = isSgTemplateParameter(n);
      ROSE_ASSERT (tp);
      switch (tp->get_parameterType()) {
	case SgTemplateParameter::parameter_undefined: {
	  term = ATmake("Undefined");
	}
	break;

	case SgTemplateParameter::type_parameter: {
	  term = ATmake("Type(<term>)",
			convertNodeToAterm(tp->get_defaultTypeParameter()));
	}
	break;

	case SgTemplateParameter::nontype_parameter: {
	  term = ATmake("Nontype(<term>, <term>)",
			convertNodeToAterm(tp->get_type()),
			convertNodeToAterm(tp->get_defaultExpressionParameter()));
	}
	break;

	case SgTemplateParameter::template_parameter: {
	  term = ATmake("Template");
	}
	break;

	default: term = ATmake("Unknown"); break;
      }
    }
    break;

    case V_SgTemplateArgument: {
      // Traversal doesn't work for these
      SgTemplateArgument* ta = isSgTemplateArgument(n);
      ROSE_ASSERT (ta);
      switch (ta->get_argumentType()) {
	case SgTemplateArgument::argument_undefined:
	  term = ATmake("Undefined");
	  break;
	case SgTemplateArgument::type_argument:
	  term = ATmake("Type(<term>)", 
			convertNodeToAterm(ta->get_type()));
	  break;
	case SgTemplateArgument::nontype_argument:
	  term = ATmake("Nontype(<term>)", 
			convertNodeToAterm(ta->get_expression()));
	  break;
	// case SgTemplateArgument::template_argument:
	  // term = ATmake("Template");
	  // break;
	default: term = ATmake("Unknown"); break;
      }
    }
    break;

    default: {
      bool isContainer = 
	(AstTests::numSuccContainers(n) == 1) ||
	(!isSgType(n) && (n->get_traversalSuccessorContainer().size() == 0));
      term = ATmake((isContainer ? "<appl(<term>)>" : "<appl(<list>)>"), 
                    getShortVariantName((VariantT)(n->variantT())).c_str(),
                    (isSgType(n) ? ATmake("[]") : getTraversalChildrenAsAterm(n)));
               // Special case for types is because of traversal problems
    }
    break;
  }

#if 0
     printf ("Base of switch statement in convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif
     assert (term);

     term = ATsetAnnotation(term, ATmake("ptr"), pointerAsAterm(n));

#if 1
     if (n->get_file_info() != NULL)
        {
          term = ATsetAnnotation(term, ATmake("location"),convertFileInfoToAterm(n->get_file_info()));
        }

     if (isSgExpression(n))
        term = ATsetAnnotation(term, ATmake("type"), convertNodeToAterm(isSgExpression(n)->get_type()));
#endif

#if 0
     printf ("Leaving convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str());
#endif
#if 0
     printf ("--- n->class_name() = %s ATwriteToString(term) = %s \n",n->class_name().c_str(),ATwriteToString(term));
#endif

  // cout << n->sage_class_name() << " -> " << ATwriteToString(term) << endl;
     return term;
   }
void
FixupSelfReferentialMacrosInAST::visit ( SgNode* node )
   {
  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
  // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
     switch (node->variantT())
        {
          case V_SgInitializedName:
             {
               SgInitializedName* initializedName = isSgInitializedName(node);
               ROSE_ASSERT(initializedName != NULL);
               SgType* type = initializedName->get_type()->stripType();
               SgClassType* classType = isSgClassType(type);
               if (classType != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration());
                    SgName className = targetClassDeclaration->get_name();

                 // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str());

                    if (className == "sigaction")
                       {
                      // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n");

                      // Note we could also check that the declaration came from a known header file.
                         SgStatement* associatedStatement = isSgStatement(initializedName->get_parent());
                         if (associatedStatement != NULL)
                            {
                           // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro.
                           // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n");

                           // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos );

                              PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration;
                              std::string macroString = "#undef sa_handler\n";
                              std::string filenameString = "macro_call_fixupSelfReferentialMacrosInAST";
                              int line_no = 1;
                              int col_no  = 1;
                              int nol     = 1;
                              PreprocessingInfo::RelativePositionType relPos = PreprocessingInfo::before;

                              PreprocessingInfo* macro = new PreprocessingInfo(directiveType,macroString,filenameString,line_no,col_no,nol,relPos);

                           // printf ("Attaching CPP directive %s to IR node %p as attributes. \n",PreprocessingInfo::directiveTypeName(macro->getTypeOfDirective()).c_str(),associatedStatement);
                              associatedStatement->addToAttachedPreprocessingInfo(macro);
#if 0
                              printf ("Exiting as a test! \n");
                              ROSE_ASSERT(false);
#endif
                            }
                       }
                  }
             }

          default:
             {
            // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str());
             }
        }

   }
Beispiel #12
0
Detection_InheritedAttribute
DetectionTraversal::evaluateInheritedAttribute (SgNode* astNode, Detection_InheritedAttribute inheritedAttribute )
   {
#if 0
     printf ("In DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

  // DQ (2/3/2016): Recognize IR nodes that are representative of target DSL abstractions.
     bool foundTargetDslAbstraction = DSL_Support::isDslAbstraction(astNode);

#if 1
     printf ("In DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s: foundTargetDslAbstraction = %s \n",astNode,astNode->class_name().c_str(),foundTargetDslAbstraction ? "true" : "false");
#endif

#if 0
  // OLD CODE (represented by DSL_Support::isDslAbstraction() function).

  // Detection of stencil declaration and stencil operator.
  // Where the stencil specification is using std::vectors as parameters to the constructor, we have to first
  // find the stencil declaration and read the associated SgVarRefExp to get the variable names used.  
  // Then a finite state machine can be constructed for each of the input variables so that we can 
  // interpret the state when the stencil operator is constructed.
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(astNode);
     if (variableDeclaration != NULL)
        {
       // Get the SgInitializedName from the SgVariableDeclaration.
          SgInitializedName* initializedName = SageInterface::getFirstInitializedName(variableDeclaration);

          SgType* base_type = initializedName->get_type()->findBaseType();
          ROSE_ASSERT(base_type != NULL);

       // SgClassType* classType = isSgClassType(initializedName->get_type());
          SgClassType* classType = isSgClassType(base_type);

          if (classType != NULL)
             {
#if 1
               printf ("In DetectionTraversal::evaluateInheritedAttribute(): case SgClassType: class name = %s \n",classType->get_name().str());
#endif
            // Check if this is associated with a template instantiation.
               SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classType->get_declaration());
               if (templateInstantiationDecl != NULL)
                  {
#if 1
                    printf ("case SgTemplateInstaiationDecl: class name = %s \n",classType->get_name().str());
                    printf ("case SgTemplateInstaiationDecl: templateInstantiationDecl->get_templateName() = %s \n",templateInstantiationDecl->get_templateName().str());
#endif
                 // inheritedAttribute.set_StencilDeclaration(templateInstantiationDecl->get_templateName() == "Stencil");
                 // inheritedAttribute.set_StencilOperatorDeclaration(templateInstantiationDecl->get_templateName() == "StencilOperator");

                    if (templateInstantiationDecl->get_templateName() == "Stencil")
                       {
                      // DQ (2/8/2015): Ignore compiler generated IR nodes (from template instantiations, etc.).
                      // Note that simpleCNS.cpp generates one of these from it's use of the tuple template and associated template instantations.

                      // DQ: Test the DSL support.
                         ROSE_ASSERT(isMatchingClassType(classType,"Stencil",true) == true);

                         checkAndResetToMakeConsistantCompilerGenerated(initializedName);

                         if (initializedName->isCompilerGenerated() == false)
                            {
                           // Save the SgInitializedName associated with the stencil.
                           // stencilInitializedNameList.push_back(initializedName);
                           // inheritedAttribute.set_StencilDeclaration(true);
                           // foundStencilVariable = true;
#if 1
                              printf ("Detected Stencil<> typed variable: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str());
                           // printf ("   --- stencilInitializedNameList.size() = %zu \n",stencilInitializedNameList.size());
#endif
#if 1
                              initializedName->get_file_info()->display("In DetectionTraversal::evaluateInheritedAttribute(): initializedName : debug");
#endif
#if 0
                              Stencil_Attribute* dslAttribute = new Stencil_Attribute();
#if 1
                              printf ("Adding (Stencil) dslAttribute = %p \n",dslAttribute);
#endif
                              ROSE_ASSERT(dslAttribute != NULL);

                           // virtual void addNewAttribute (std::string s, AstAttribute *a);   
                              initializedName->addNewAttribute(StencilVariable,dslAttribute);
#endif
                            }
                       }
                  }

               SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration());
               if (classDeclaration != NULL)
                  {
                    if (classDeclaration->get_name() == "Point")
                       {
                      // Save the SgInitializedName associated with the Point type.
#if 0
                         printf ("Detected Point<> typed variable: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str());
#endif
                         checkAndResetToMakeConsistantCompilerGenerated(initializedName);

                         if (initializedName->isCompilerGenerated() == false)
                            {
                           // pointInitializedNameList.push_back(initializedName);
#if 0
                              Point_Attribute* dslAttribute = new Point_Attribute();
                              printf ("Adding (Point) dslAttribute = %p \n",dslAttribute);
                              ROSE_ASSERT(dslAttribute != NULL);

                           // virtual void addNewAttribute (std::string s, AstAttribute *a);   
                              initializedName->addNewAttribute(PointVariable,dslAttribute);
#endif
                            }
                       }
                  }
             }
        }
#endif

#if 1
     printf ("Leaving DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

  // Construct the return attribute from the modified input attribute.
     return Detection_InheritedAttribute(inheritedAttribute);
   }
void
FixupSelfReferentialMacrosInAST::visit ( SgNode* node )
   {
  // DQ (3/11/2006): Set NULL pointers where we would like to have none.
  // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str());

     ROSE_ASSERT(node != NULL);
     switch (node->variantT())
        {
          case V_SgInitializedName:
             {
               SgInitializedName* initializedName = isSgInitializedName(node);
               ROSE_ASSERT(initializedName != NULL);
               SgType* type = initializedName->get_type()->stripType();
               SgClassType* classType = isSgClassType(type);
               if (classType != NULL)
                  {
                    SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration());
                    SgName className = targetClassDeclaration->get_name();

                 // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str());

                 // For sudo_exec_pty.c also look for siginfo
                    if (className == "sigaction" || className == "siginfo")
                       {
                      // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n");

                      // Note we could also check that the declaration came from a known header file.
                         SgStatement* associatedStatement = isSgStatement(initializedName->get_parent());
                         if (associatedStatement != NULL)
                            {
                           // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro.
                           // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n");

                           // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos );

                              PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration;

                           // We are puting out all macros anytime we see either type.  This might be too much...

                           // From the sigaction.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef sa_handler\n",directiveType);
                              addMacro(associatedStatement,"#undef sa_sigaction\n",directiveType);

                           // From the siginfo.h file (included by signal.h):
                              addMacro(associatedStatement,"#undef si_pid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_uid\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_timerid\n",directiveType);
                              addMacro(associatedStatement,"#undef si_overrun\n",directiveType);
                              addMacro(associatedStatement,"#undef si_status\n", directiveType);
                              addMacro(associatedStatement,"#undef si_utime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_stime\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_value\n",  directiveType);
                              addMacro(associatedStatement,"#undef si_int\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_ptr\n",    directiveType);
                              addMacro(associatedStatement,"#undef si_addr\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_band\n",   directiveType);
                              addMacro(associatedStatement,"#undef si_fd\n",     directiveType);
                            }
                       }
                  }
             }

          default:
             {
            // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str());
             }
        }

#if 0
  // DQ (12/30/2013): Comments and CPP directives have not yet been attached to the AST, so we can't process them here.

  // SgLocatedNode* locatedNode = isSgLocatedNode(node);
  // if (locatedNode != NULL)
     SgStatement* stmt = isSgStatement(node);
     if (stmt != NULL)
        {
       // Find all #define statements and look for self referencing macros

          int numberOfComments = -1;
          if (stmt->getAttachedPreprocessingInfo() != NULL)
               numberOfComments = stmt->getAttachedPreprocessingInfo()->size();

          std::string s = std::string(" --- startOfConstruct: file = " ) + stmt->get_startOfConstruct()->get_filenameString()
             + " raw filename = " + stmt->get_startOfConstruct()->get_raw_filename()
             + " raw line = "     + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_line())
             + " raw column = "   + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_col())
             + " #comments = "    + StringUtility::numberToString(numberOfComments)
             + " \n ";

          AttachedPreprocessingInfoType* comments = stmt->getAttachedPreprocessingInfo();

          if (comments != NULL)
             {
               printf ("Found attached comments (at %p of type: %s): \n",stmt,stmt->class_name().c_str());
               AttachedPreprocessingInfoType::iterator i;
               for (i = comments->begin(); i != comments->end(); i++)
                  {
                    ROSE_ASSERT ( (*i) != NULL );
                    printf ("          Attached Comment (relativePosition=%s): %s\n",
                         ((*i)->getRelativePosition() == PreprocessingInfo::before) ? "before" : "after",
                         (*i)->getString().c_str());
                    printf ("Comment/Directive getNumberOfLines = %d getColumnNumberOfEndOfString = %d \n",(*i)->getNumberOfLines(),(*i)->getColumnNumberOfEndOfString());
                    (*i)->get_file_info()->display("comment/directive location");
                  }
             }
            else
             {
               printf ("No attached comments (at %p of type: %s): \n",stmt,stmt->class_name().c_str());
             }
        }
#endif
   }
Beispiel #14
0
void
ProcTraversal::visit(SgNode *node) {
    if (isSgFunctionDeclaration(node)) {
        SgFunctionDeclaration *decl = isSgFunctionDeclaration(node);
        if (decl->get_definition() != NULL) {
            /* collect statistics */
            //AstNumberOfNodesStatistics anons;
            //anons.traverse(decl, postorder);
            //original_ast_nodes += anons.get_numberofnodes();
            //original_ast_statements += anons.get_numberofstatements();

            /* do the real work */
            Procedure *proc = new Procedure();
            proc->procnum = procnum++;
            proc->decl = decl;
            proc->funcsym
                = isSgFunctionSymbol(decl->get_symbol_from_symbol_table());
            if (proc->funcsym == NULL)
            {
#if 0
                std::cout
                        << std::endl
                        << "*** NULL function symbol for declaration "
                        << decl->unparseToString()
                        << std::endl
                        << "symbol: "
                        << (void *) decl->get_symbol_from_symbol_table()
                        << (decl->get_symbol_from_symbol_table() != NULL ?
                            decl->get_symbol_from_symbol_table()->class_name()
                            : "")
                        << std::endl
                        << "first nondef decl: "
                        << (void *) decl->get_firstNondefiningDeclaration()
                        << " sym: "
                        << (decl->get_firstNondefiningDeclaration() != NULL ?
                            (void *) decl->get_firstNondefiningDeclaration()
                            ->get_symbol_from_symbol_table()
                            : (void *) NULL)
                        << std::endl;
#endif
                if (decl->get_firstNondefiningDeclaration() != NULL)
                {
                    proc->funcsym = isSgFunctionSymbol(decl
                                                       ->get_firstNondefiningDeclaration()
                                                       ->get_symbol_from_symbol_table());
                }
            }
            assert(proc->funcsym != NULL);
            // GB (2008-05-14): We need two parameter lists: One for the names of the
            // variables inside the function definition, which is
            // decl->get_parameterList(), and one that contains any default arguments
            // the function might have. The default arguments are supposedly
            // associated with the first nondefining declaration.
            proc->params = decl->get_parameterList();
            SgDeclarationStatement *fndstmt = decl->get_firstNondefiningDeclaration();
            SgFunctionDeclaration *fnd = isSgFunctionDeclaration(fndstmt);
            if (fnd != NULL && fnd != decl)
                proc->default_params = fnd->get_parameterList();
            else
                proc->default_params = proc->params;

            SgMemberFunctionDeclaration *mdecl
                = isSgMemberFunctionDeclaration(decl);
            if (mdecl) {
                proc->class_type = isSgClassDefinition(mdecl->get_scope());
                std::string name = proc->class_type->get_mangled_name().str();
                name += "::";
                name += decl->get_name().str();
                std::string mname = proc->class_type->get_mangled_name().str();
                mname += "::";
                mname += decl->get_mangled_name().str();
                proc->memberf_name = name;
                proc->mangled_memberf_name = mname;
                proc->name = decl->get_name().str();
                proc->mangled_name = decl->get_mangled_name().str();
                // GB (2008-05-26): Computing a single this symbol for each
                // procedure. Thus, this symbol can also be compared by pointer
                // equality (as is the case for all other symbols). While we're at it,
                // we also build a VarRefExp for this which can be used everywhere the
                // this pointer occurs.
                proc->this_type = Ir::createPointerType(
                                      proc->class_type->get_declaration()->get_type());
                proc->this_sym = Ir::createVariableSymbol("this", proc->this_type);
                proc->this_exp = Ir::createVarRefExp(proc->this_sym);
            } else {
                proc->name = decl->get_name().str();
                proc->mangled_name = decl->get_mangled_name().str();
                proc->class_type = NULL;
                proc->memberf_name = proc->mangled_memberf_name = "";
                proc->this_type = NULL;
                proc->this_sym = NULL;
                proc->this_exp = NULL;
                // GB (2008-07-01): Better resolution of calls to static functions.
                // This only makes sense for non-member functions.
                SgStorageModifier &sm =
                    (fnd != NULL ? fnd : decl)->get_declarationModifier().get_storageModifier();
                proc->isStatic = sm.isStatic();
                // Note that we query the first nondefining declaration for the
                // static modifier, but we save the file of the *defining*
                // declaration. This is because the first declaration might be in
                // some header file, but for call resolution, the actual source
                // file with the definition is relevant.
                // Trace back to the enclosing file node. The definition might be
                // included in foo.c from bar.c, in which case the Sg_File_Info
                // would refer to bar.c; but for function call resolution, foo.c is
                // the relevant file.
                SgNode *p = decl->get_parent();
                while (p != NULL && !isSgFile(p))
                    p = p->get_parent();
                proc->containingFile = isSgFile(p);
            }
            proc_map.insert(std::make_pair(proc->name, proc));
            mangled_proc_map.insert(std::make_pair(proc->mangled_name, proc));
            std::vector<SgVariableSymbol* >* arglist
                = new std::vector<SgVariableSymbol* >();
            SgVariableSymbol *this_var = NULL, *this_temp_var = NULL;
            if (mdecl
                    || decl->get_parameterList() != NULL
                    && !decl->get_parameterList()->get_args().empty()) {
                proc->arg_block
                    = new BasicBlock(node_id, INNER, proc->procnum);
                if (mdecl) {
                    // GB (2008-05-26): We now compute the this pointer right at the
                    // beginning of building the procedure.
                    // this_var = Ir::createVariableSymbol("this", this_type);
                    this_var = proc->this_sym;
                    // std::string varname
                    //   = std::string("$") + proc->name + "$this";
                    // this_temp_var = Ir::createVariableSymbol(varname, proc->this_type);
                    this_temp_var = global_this_variable_symbol;
                    ParamAssignment* paramAssignment
                        = Ir::createParamAssignment(this_var, this_temp_var);
                    proc->arg_block->statements.push_back(paramAssignment);
                    arglist->push_back(this_var);
                    if (proc->name.find('~') != std::string::npos) {
                        arglist->push_back(this_temp_var);
                    }
                }
                SgInitializedNamePtrList params
                    = proc->params->get_args();
                SgInitializedNamePtrList::const_iterator i;
#if 0
                int parnum = 0;
                for (i = params.begin(); i != params.end(); ++i) {
                    SgVariableSymbol *i_var = Ir::createVariableSymbol(*i);
                    std::stringstream varname;
                    // varname << "$" << proc->name << "$arg_" << parnum++;
                    SgVariableSymbol* var =
                        Ir::createVariableSymbol(varname.str(),(*i)->get_type());
                    proc->arg_block->statements.push_back(Ir::createParamAssignment(i_var, var));
                    arglist->push_back(i_var);
                }
#else
                // GB (2008-06-23): Trying to replace all procedure-specific argument
                // variables by a global list of argument variables. This means that at
                // this point, we do not necessarily need to build a complete list but
                // only add to the CFG's argument list if it is not long enough.
                size_t func_params = params.size();
                size_t global_args = global_argument_variable_symbols.size();
                std::stringstream varname;
                while (global_args < func_params)
                {
                    varname.str("");
                    varname << "$tmpvar$arg_" << global_args++;
                    SgVariableSymbol *var
                        = Ir::createVariableSymbol(varname.str(),
                                                   global_unknown_type);
                    program->global_map[varname.str()]
                        = std::make_pair(var, var->get_declaration());
                    global_argument_variable_symbols.push_back(var);
                }
                // now create the param assignments
                size_t j = 0;
                for (i = params.begin(); i != params.end(); ++i)
                {
                    SgVariableSymbol *i_var = Ir::createVariableSymbol(params[j]);
                    SgVariableSymbol *var = global_argument_variable_symbols[j];
                    j++;
                    proc->arg_block->statements.push_back(
                        Ir::createParamAssignment(i_var, var));
                    arglist->push_back(i_var);
                }
#if 0
                // replace the arglist allocated above by the new one; this must be
                // fixed for this pointers!
                delete arglist;
                arglist = &global_argument_variable_symbols;
#endif
#endif
            } else {
                proc->arg_block = NULL;
            }
            /* If this is a constructor, call default constructors
             * of all base classes. If base class constructors are
             * called manually, these calls will be removed later. */
            if (mdecl
                    && strcmp(mdecl->get_name().str(),
                              proc->class_type->get_declaration()->get_name().str()) == 0
                    && proc->class_type != NULL) {
                SgBaseClassPtrList::iterator base;
                for (base = proc->class_type->get_inheritances().begin();
                        base != proc->class_type->get_inheritances().end();
                        ++base) {
                    SgClassDeclaration* baseclass = (*base)->get_base_class();
                    SgVariableSymbol *lhs
                        = Ir::createVariableSymbol("$tmpvar$" + baseclass->get_name(),
                                                   baseclass->get_type());
                    program->global_map["$tmpvar$" + baseclass->get_name()]
                        = std::make_pair(lhs, lhs->get_declaration());
                    SgMemberFunctionDeclaration* fd=get_default_constructor(baseclass);
                    assert(fd);
                    SgType* basetype=baseclass->get_type();
                    assert(basetype);
                    SgConstructorInitializer *sci
                        = Ir::createConstructorInitializer(fd,basetype);
                    ArgumentAssignment* a
                        = Ir::createArgumentAssignment(lhs, sci);
                    proc->arg_block->statements.push_back(a);

                    // std::string this_called_varname
                    //   = std::string("$") + baseclass->get_name() + "$this";
                    SgVariableSymbol *this_called_var
                    // = Ir::createVariableSymbol(this_called_varname,
                    //                            baseclass->get_type());
                        = global_this_variable_symbol;
                    ReturnAssignment* this_ass
                        = Ir::createReturnAssignment(this_var, this_called_var);
                    proc->arg_block->statements.push_back(this_ass);
                }
            }
            if (mdecl && mdecl->get_CtorInitializerList() != NULL
                    && !mdecl->get_CtorInitializerList()->get_ctors().empty()) {
                SgInitializedNamePtrList cis
                    = mdecl->get_CtorInitializerList()->get_ctors();
                SgInitializedNamePtrList::const_iterator i;
                if (proc->arg_block == NULL) {
                    proc->arg_block = new BasicBlock(node_id, INNER, proc->procnum);
                }
                for (i = cis.begin(); i != cis.end(); ++i) {
                    SgVariableSymbol* lhs = Ir::createVariableSymbol(*i);
                    SgAssignInitializer *ai
                        = isSgAssignInitializer((*i)->get_initializer());
                    SgConstructorInitializer *ci
                        = isSgConstructorInitializer((*i)->get_initializer());
                    /* TODO: other types of initializers */
                    if (ai) {
                        SgClassDeclaration *class_decl
                            = proc->class_type->get_declaration();
                        // GB (2008-05-26): We now compute the this pointer right at the
                        // beginning of building the procedure.
                        // SgVarRefExp* this_ref
                        //   = Ir::createVarRefExp("this",
                        //                         Ir::createPointerType(class_decl->get_type()));
                        SgVarRefExp* this_ref = proc->this_exp;
                        SgArrowExp* arrowExp
                            = Ir::createArrowExp(this_ref,Ir::createVarRefExp(lhs));
                        // GB (2008-03-17): We need to handle function calls in
                        // initializers. In order to be able to build an argument
                        // assignment, we need to know the function's return variable, so
                        // the expression labeler must be called on it. The expression
                        // number is irrelevant, however, as it does not appear in the
                        // return variable.
                        if (isSgFunctionCallExp(ai->get_operand_i())) {
#if 0
                            ExprLabeler el(0 /*expnum*/);
                            el.traverse(ai->get_operand_i(), preorder);
                            // expnum = el.get_expnum();
#endif
                            // GB (2008-06-25): There is now a single global return
                            // variable. This may or may not mean that we can simply ignore
                            // the code above. I don't quite understand why this labeling
                            // couldn't be done later on, and where its result was used.
                        }
                        ArgumentAssignment* argumentAssignment
                            = Ir::createArgumentAssignment(arrowExp,ai->get_operand_i());
                        proc->arg_block->statements.push_back(argumentAssignment);
                    } else if (ci) {
                        /* if this is a call to a base class's
                         * constructor, remove the call we generated
                         * before */
                        SgStatement* this_a = NULL;
                        SgClassDeclaration* cd = ci->get_class_decl();
                        std::deque<SgStatement *>::iterator i;
                        for (i = proc->arg_block->statements.begin();
                                i != proc->arg_block->statements.end();
                                ++i) {
                            ArgumentAssignment* a
                                = dynamic_cast<ArgumentAssignment *>(*i);
                            if (a && isSgConstructorInitializer(a->get_rhs())) {
                                SgConstructorInitializer* c
                                    = isSgConstructorInitializer(a->get_rhs());
                                std::string c_decl_name = c->get_class_decl()->get_name().str();
                                std::string cd_name = cd->get_name().str();
                                // if (c->get_class_decl()->get_name() == cd->get_name()) {
                                if (c_decl_name == cd_name) {
#if 0
                                    // erase the following assignment
                                    // of the this pointer as well
                                    this_a = *proc->arg_block->statements.erase(i+1);
                                    proc->arg_block->statements.erase(i);
#endif
                                    // GB (2008-03-28): That's an interesting piece of code, but
                                    // it might be very mean to iterators. At least it is hard to
                                    // see whether it is correct. So let's try it like this:
                                    // erase i; we get an iterator back, which refers to the next
                                    // element. Save that element as this_a, and then erase.
                                    std::deque<SgStatement *>::iterator this_pos;
                                    this_pos = proc->arg_block->statements.erase(i);
                                    this_a = *this_pos;
                                    proc->arg_block->statements.erase(this_pos);
                                    // Good. Looks like this fixed a very obscure bug.
                                    break;
                                }
                            }
                        }
                        /* now add the initialization */
                        proc->arg_block->statements.push_back(Ir::createArgumentAssignment(lhs, ci));
                        if (this_a != NULL)
                            proc->arg_block->statements.push_back(this_a);
                    }
                }
            }
            proc->entry = new CallBlock(node_id++, START, proc->procnum,
                                        new std::vector<SgVariableSymbol *>(*arglist),
                                        (proc->memberf_name != ""
                                         ? proc->memberf_name
                                         : proc->name));
            proc->exit = new CallBlock(node_id++, END, proc->procnum,
                                       new std::vector<SgVariableSymbol *>(*arglist),
                                       (proc->memberf_name != ""
                                        ? proc->memberf_name
                                        : proc->name));
            proc->entry->partner = proc->exit;
            proc->exit->partner = proc->entry;
            proc->entry->call_target = Ir::createFunctionRefExp(proc->funcsym);
            proc->exit->call_target = Ir::createFunctionRefExp(proc->funcsym);
            /* In constructors, insert an assignment $A$this = this
             * at the end to make sure that the 'this' pointer can be
             * passed back to the calling function uncobbled. */
            proc->this_assignment = NULL;
            if (mdecl) {
                SgMemberFunctionDeclaration* cmdecl
                    = isSgMemberFunctionDeclaration(mdecl->get_firstNondefiningDeclaration());
                // if (cmdecl && cmdecl->get_specialFunctionModifier().isConstructor()) {
                proc->this_assignment
                    = new BasicBlock(node_id++, INNER, proc->procnum);
                ReturnAssignment* returnAssignment
                    = Ir::createReturnAssignment(this_temp_var, this_var);
                proc->this_assignment->statements.push_back(returnAssignment);
                add_link(proc->this_assignment, proc->exit, NORMAL_EDGE);
                // }
            }
            std::stringstream varname;
            // varname << "$" << proc->name << "$return";
            // proc->returnvar = Ir::createVariableSymbol(varname.str(),
            //                                            decl->get_type()->get_return_type());
            proc->returnvar = global_return_variable_symbol;
            procedures->push_back(proc);
            if(getPrintCollectedFunctionNames()) {
                std::cout << (proc->memberf_name != ""
                              ? proc->memberf_name
                              : proc->name)
                          << " " /*<< proc->decl << std::endl*/;
            }
            if (proc->arg_block != NULL)
            {
                proc->arg_block->call_target
                    = Ir::createFunctionRefExp(proc->funcsym);
            }
            // delete arglist;
        }
    }
}
Beispiel #15
0
DOTSynthesizedAttribute
AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l)
   {
     SubTreeSynthesizedAttributes::iterator iter;
     ROSE_ASSERT(node);

  // printf ("AstDOTGeneration::evaluateSynthesizedAttribute(): node = %s \n",node->class_name().c_str());

  // DQ (5/3/2006): Skip this IR node if it is specified as such in the inherited attribute
     if (ia.skipSubTree == true)
        {
       // I am unclear if I should return NULL or node as a parameter to DOTSynthesizedAttribute
       // Figured this out: if we return a valid pointer then we get a node in the DOT graph 
       // (with just the pointer value as a label), where as if we return a DOTSynthesizedAttribute 
       // with a NUL pointer then the node will NOT appear in the DOT graph.
       // return DOTSynthesizedAttribute(node);
          return DOTSynthesizedAttribute(NULL);
        }

     string nodeoption;
     if(AstTests::isProblematic(node))
        {
       // cout << "problematic node found." << endl;
          nodeoption="color=\"orange\" ";
        }
     string nodelabel=string("\\n")+node->class_name();

  // DQ (1/24/2009): Added support for output of isForward flag in the dot graph.
     SgDeclarationStatement* genericDeclaration = isSgDeclarationStatement(node);
     if (genericDeclaration != NULL)
        {
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
          string name = (genericDeclaration->isForward() == true) ? "isForward" : "!isForward";
          ROSE_ASSERT(name.empty() == false);

       // DQ (3/20/2011): Added class names to the generated dot file graphs of the AST.
          SgClassDeclaration* classDeclaration = isSgClassDeclaration(genericDeclaration);
          if (classDeclaration != NULL)
             {
               nodelabel += string("\\n") + classDeclaration->get_name();
             }

       // DQ (3/20/2011): Added function names to the generated dot file graphs of the AST.
          SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(genericDeclaration);
          if (functionDeclaration != NULL)
             {
               nodelabel += string("\\n") + functionDeclaration->get_name();
             }

          nodelabel += string("\\n") + name;
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgInitializedName* initializedName = isSgInitializedName(node);
     if (initializedName != NULL)
        {
          nodelabel += string("\\n") + initializedName->get_name();
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgIntVal* intValue = isSgIntVal(node);
     if (intValue != NULL)
        {
          nodelabel += string("\\n value = ") + StringUtility::numberToString(intValue->get_value());
        }

  // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes.
     SgVarRefExp* varRefExp = isSgVarRefExp(node);
     if (varRefExp != NULL)
        {
          SgVariableSymbol* variableSymbol = varRefExp->get_symbol();
          ROSE_ASSERT(variableSymbol != NULL);
          string name = variableSymbol->get_name();
          nodelabel += string("\\n name = ") + name;
        }

  // DQ (1/19/2009): Added support for output of what specific instrcution this is in the dot graph.
     SgAsmInstruction* genericInstruction = isSgAsmInstruction(node);
     if (genericInstruction != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // At the moment the mnemonic name is stored, but it could be computed in the 
       // future from the kind and the tostring() function.
#if 1
          string unparsedInstruction = unparseInstruction(genericInstruction);
          string addressString       = StringUtility::numberToString( (void*) genericInstruction->get_address() );
       // string name = genericInstruction->get_mnemonic();
          string name = unparsedInstruction + "\\n address: " + addressString;
#else
          string name = unparsedInstruction + "\\n" + addressString;
#endif
          ROSE_ASSERT(name.empty() == false);

          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

     SgAsmExpression* genericExpression = isSgAsmExpression(node);
     if (genericExpression != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
          string name = unparseExpression(genericExpression, NULL, NULL);
          ROSE_ASSERT(name.empty() == false);
          nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (10/29/2008): Added some support for additional output of internal names for specific IR nodes.
  // In generall there are long list of these IR nodes in the binary and this helps make some sense of 
  // the lists (sections, symbols, etc.).
     SgAsmExecutableFileFormat* binaryFileFormatNode = isSgAsmExecutableFileFormat(node);
     if (binaryFileFormatNode != NULL)
        {
#ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT
       // The case of binary file format IR nodes can be especially confusing so we want the 
       // default to output some more specific information for some IR nodes (e.g. sections).
          string name;

          SgAsmGenericSection* genericSection = isSgAsmGenericSection(node);
          if (genericSection != NULL)
             {
               SgAsmGenericString* genericString = genericSection->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmGenericSymbol* genericSymbol = isSgAsmGenericSymbol(node);
          if (genericSymbol != NULL)
             {
               SgAsmGenericString* genericString = genericSymbol->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();

               if (name.empty() == true)
                    name = "no_name_for_symbol";
             }

          SgAsmGenericDLL* genericDLL = isSgAsmGenericDLL(node);
          if (genericDLL != NULL)
             {
               SgAsmGenericString* genericString = genericDLL->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmPEImportItem* peImportItem = isSgAsmPEImportItem(node);
          if (peImportItem != NULL)
             {
               SgAsmGenericString* genericString = peImportItem->get_name();
               ROSE_ASSERT(genericString != NULL);

               name = genericString->get_string();
             }

          SgAsmDwarfLine* asmDwarfLine = isSgAsmDwarfLine(node);
          if (asmDwarfLine != NULL)
             {
               char buffer[100];

            // It does not work to embed the "\n" into the single sprintf parameter.
            // sprintf(buffer," Addr: 0x%08"PRIx64" \n line: %d col: %d ",asmDwarfLine->get_address(),asmDwarfLine->get_line(),asmDwarfLine->get_column());

               sprintf(buffer,"Addr: 0x%08"PRIx64,asmDwarfLine->get_address());
               name = buffer;
               sprintf(buffer,"line: %d col: %d",asmDwarfLine->get_line(),asmDwarfLine->get_column());
               name += string("\\n") + buffer;
             }

          SgAsmDwarfConstruct* asmDwarfConstruct = isSgAsmDwarfConstruct(node);
          if (asmDwarfConstruct != NULL)
             {
               name = asmDwarfConstruct->get_name();
             }

#if 0
       // This might not be the best way to implement this, since we want to detect common base classes of IR nodes.
          switch (node->variantT())
             {
               case V_SgAsmElfSection:
                  {
                    SgAsmElfSection* n = isSgAsmElfSection(node);
                    name = n->get_name();
                    break;
                  }

               default:
                  {
                 // No additional information is suggested for the default case!
                  }
             }
#endif

          if (name.empty() == false)
               nodelabel += string("\\n") + name;
#else
          printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n");
#endif
        }

  // DQ (11/29/2008): Output the directives in the label of the IR node.
     SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node);
     if (preprocessorDirective != NULL)
        {
          string s = preprocessorDirective->get_directiveString();

       // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables.
          while (s.find("\"") != string::npos)
             {
               s.replace(s.find("\""),1,"\'");
             }

          if (s.empty() == false)
               nodelabel += string("\\n") + s;
        }

     nodelabel += additionalNodeInfo(node);

  // DQ (11/1/2003) added mechanism to add additional options (to add color, etc.)
  // nodeoption += additionalNodeOptions(node);
     string additionalOptions = additionalNodeOptions(node);
  // printf ("nodeoption = %s size() = %ld \n",nodeoption.c_str(),nodeoption.size());
  // printf ("additionalOptions = %s size() = %ld \n",additionalOptions.c_str(),additionalOptions.size());

     string x;
     string y;
     x += additionalOptions;

     nodeoption += additionalOptions;

     DOTSynthesizedAttribute d(0);

  // DQ (7/27/2008): Added mechanism to support pruning of AST
     bool commentoutNode = commentOutNodeInGraph(node);
     if (commentoutNode == true)
        {
       // DQ (11/10/2008): Fixed to only output message when (verbose_level > 0); command-line option.
       // DQ (7/27/2008): For now just return to test this mechanism, then we want to add comment "//" propoerly to generated DOT file.
          if (SgProject::get_verbose() > 0)
             {
               printf ("Skipping the use of this IR node in the DOT Graph \n");
             }
        }
       else
        {

// **************************

     switch(traversal)
        {
          case TOPDOWNBOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdbuTracePos,tdbuTrace)+nodelabel,nodeoption);
               break;
          case PREORDER:
          case TOPDOWN:
               dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
               break;
          case POSTORDER:
          case BOTTOMUP:
               dotrep.addNode(node,dotrep.traceFormat(buTrace)+nodelabel,nodeoption);
               break;
          default:
               assert(false);
        }
  
     ++tdbuTrace;
     ++buTrace;

  // add edges or null values
     int testnum=0;
     for (iter = l.begin(); iter != l.end(); iter++)
        {
          string edgelabel = string(node->get_traversalSuccessorNamesContainer()[testnum]);
          string toErasePrefix = "p_";

          if (AstTests::isPrefix(toErasePrefix,edgelabel))
             {
               edgelabel.erase(0, toErasePrefix.size());
             }

          if ( iter->node == NULL)
             {
            // SgNode* snode=node->get_traversalSuccessorContainer()[testnum];
               AstSuccessorsSelectors::SuccessorsContainer c;
               AstSuccessorsSelectors::selectDefaultSuccessors(node,c);
               SgNode* snode=c[testnum];

            // isDefault shows that the default constructor for synth attribute was used
               if (l[testnum].isDefault() && snode && (visitedNodes.find(snode) != visitedNodes.end()) )
                  {
                 // handle bugs in SAGE
                    dotrep.addEdge(node,edgelabel,snode,"dir=forward arrowhead=\"odot\" color=red ");
                  }
                 else
                  {
                    if (snode == NULL)
                       {
                         dotrep.addNullValue(node,"",edgelabel,"");
                       }
                  }
             }
            else
             {
            // DQ (3/5/2007) added mechanism to add additional options (to add color, etc.)
               string edgeoption = additionalEdgeOptions(node,iter->node,edgelabel);

               switch(traversal)
                  {
                    case TOPDOWNBOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=both");
                         break;
                    case PREORDER:
                    case TOPDOWN:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=forward");
                         break;
                    case POSTORDER:
                    case BOTTOMUP:
                         dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=back");
                         break;
                    default:
                         assert(false);
                  }
             }

          testnum++;
        }

// **************************
        }



  // DQ (7/4/2008): Support for edges specified in AST attributes
     AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism();
     if (astAttributeContainer != NULL)
        {
       // Loop over all the attributes at this IR node
          for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++)
             {
            // std::string name = i->first;
               AstAttribute* attribute = i->second;
               ROSE_ASSERT(attribute != NULL);

            // This can return a non-empty list in user-defined attributes (derived from AstAttribute).
            // printf ("Calling attribute->additionalNodeInfo() \n");
               std::vector<AstAttribute::AttributeNodeInfo> nodeList = attribute->additionalNodeInfo();
            // printf ("nodeList.size() = %lu \n",nodeList.size());

               for (std::vector<AstAttribute::AttributeNodeInfo>::iterator i_node = nodeList.begin(); i_node != nodeList.end(); i_node++)
                  {
                    SgNode* nodePtr   = i_node->nodePtr;
                    string nodelabel  = i_node->label;
                    string nodeoption = i_node->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding a node nodelabel = %s nodeoption = %s \n",nodelabel.c_str(),nodeoption.c_str());
                 // dotrep.addNode(NULL,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption);
                    dotrep.addNode( nodePtr, dotrep.traceFormat(ia.tdTracePos) + nodelabel, nodeoption );
                  }

            // printf ("Calling attribute->additionalEdgeInfo() \n");
               std::vector<AstAttribute::AttributeEdgeInfo> edgeList = attribute->additionalEdgeInfo();
            // printf ("edgeList.size() = %lu \n",edgeList.size());
               for (std::vector<AstAttribute::AttributeEdgeInfo>::iterator i_edge = edgeList.begin(); i_edge != edgeList.end(); i_edge++)
                  {
                    string edgelabel  = i_edge->label;
                    string edgeoption = i_edge->options;
                 // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding an edge from i_edge->fromNode = %p to i_edge->toNode = %p edgelabel = %s edgeoption = %s \n",i_edge->fromNode,i_edge->toNode,edgelabel.c_str(),edgeoption.c_str());
                    dotrep.addEdge(i_edge->fromNode,edgelabel,i_edge->toNode,edgeoption + "dir=forward");
                  }
             }
        }



     switch(node->variantT())
        {
       // DQ (9/1/2008): Added case for output of SgProject rooted DOT file.
       // This allows source code and binary files to be combined into the same DOT file.
          case V_SgProject: 
             {
               SgProject* project = dynamic_cast<SgProject*>(node);
               ROSE_ASSERT(project != NULL);

               string generatedProjectName = SageInterface::generateProjectName( project );
            // printf ("generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
               if (generatedProjectName.length() > 40)
                  {
                 // printf ("Warning: generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str());
                    generatedProjectName = "aggregatedFileNameTooLong";
                    printf ("Proposed (generated) filename is too long, shortened to: %s \n",generatedProjectName.c_str());
                  }

               string filename = string("./") + generatedProjectName + ".dot";

            // printf ("generated filename for dot file (from SgProject) = %s \n",filename.c_str());
               if ( SgProject::get_verbose() >= 1 )
                    printf ("Output the DOT graph from the SgProject IR node (filename = %s) \n",filename.c_str());

               dotrep.writeToFileAsGraph(filename);
               break;
             }

       // case V_SgFile: 
          case V_SgSourceFile: 
          case V_SgBinaryComposite: 
             {
               SgFile* file = dynamic_cast<SgFile*>(node);
               ROSE_ASSERT(file != NULL);

               string original_filename = file->getFileName();

            // DQ (7/4/2008): Fix filenamePostfix to go before the "."
            // string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + "."+filenamePostfix+"dot";
               string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + filenamePostfix + ".dot";

            // printf ("generated filename for dot file (from SgSourceFile or SgBinaryComposite) = %s file->get_parent() = %p \n",filename.c_str(),file->get_parent());

            // printf ("file->get_parent() = %p \n",file->get_parent());
            // cout << "generating DOT file (from SgSourceFile or SgBinaryComposite): " << filename2 << " ... ";

            // DQ (9/1/2008): this effects the output of DOT files when multiple files are specified 
            // on the command line.  A SgProject is still built even when a single file is specificed 
            // on the command line, however there are cases where a SgFile can be built without a 
            // SgProject and this case allows those SgFile rooted subtrees to be output as DOT files.
            // If there is a SgProject then output the dot file from there, else output as a SgFile.
               if (file->get_parent() == NULL)
                  {
                 // If there is no SgProject then output the file now!
                    if ( SgProject::get_verbose() >= 1 )
                         printf ("Output the DOT graph from the SgFile IR node (no SgProject available) \n");

                    dotrep.writeToFileAsGraph(filename);
                  }
                 else
                  {
                 // There is a SgProject IR node, but if we will be traversing it we want to output the 
                 // graph then (so that the graph will include the SgProject IR nodes and connect multiple 
                 // files (SgSourceFile or SgBinaryComposite IR nodes).
                    if ( visitedNodes.find(file->get_parent()) == visitedNodes.end() )
                       {
                      // This SgProject node was not input as part of the traversal, 
                      // so we will not be traversing the SgProject IR nodes and we 
                      // have to output the graph now!

                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Output the DOT graph from the SgFile IR node (SgProject was not traversed) \n");

                         dotrep.writeToFileAsGraph(filename);
                       }
                      else
                       {
                         if ( SgProject::get_verbose() >= 1 )
                              printf ("Skip the output of the DOT graph from the SgFile IR node (SgProject will be traversed) \n");
                       }
                  }
               
            // cout << "done." << endl;
               break;
             }

       // DQ (7/23/2005): Implemented default case to avoid g++ warnings 
       // about enum values not handled by this switch
          default: 
             {
            // nothing to do here
               break;
             }
        }

     d.node = node;
     return d;
   }
bool FixupTemplateArguments::contains_private_type (SgType* type, SgScopeStatement* targetScope)
   {
  // DQ (4/2/2018): Note that this function now addresses requirements of supporting both private and protected types.

#if DEBUGGING_USING_RECURSIVE_DEPTH
  // For debugging, keep track of the recursive depth.
     static size_t depth = 0;

     printf ("In contains_private_type(SgType*): depth = %zu \n",depth);
     ROSE_ASSERT(depth < 500);

     printf ("In contains_private_type(SgType*): global_depth = %zu \n",global_depth);
     ROSE_ASSERT(global_depth < 55);
#endif

  // Note this is the recursive function.
     bool returnValue = false;

#if DEBUG_PRIVATE_TYPE || 0
  // DQ (1/7/2016): It is a problem to do this for some files (failing about 35 files in Cxx_tests).
  // The issues appears to be in the unparsing of the template arguments of the qualified names for the types.
  // printf ("In contains_private_type(SgType*): type = %p = %s = %s \n",type,type->class_name().c_str(),type->unparseToString().c_str());
     printf ("In contains_private_type(SgType*): type = %p = %s \n",type,type->class_name().c_str());
#endif

     SgTypedefType* typedefType = isSgTypedefType(type);
     if (typedefType != NULL)
        {
       // Get the associated declaration.
          SgTypedefDeclaration* typedefDeclaration = isSgTypedefDeclaration(typedefType->get_declaration());
          ROSE_ASSERT(typedefDeclaration != NULL);

#if 0
          bool isPrivate = typedefDeclaration->get_declarationModifier().get_accessModifier().isPrivate();
#else
       // DQ (4/2/2018): Fix this to address requirements of both private and protected class members (see Cxx11_tests/test2018_71.C).
          bool isPrivate = typedefDeclaration->get_declarationModifier().get_accessModifier().isPrivate() ||
                           typedefDeclaration->get_declarationModifier().get_accessModifier().isProtected();
#endif
#if DEBUG_PRIVATE_TYPE || 0
          printf ("typedefDeclaration isPrivate = %s \n",isPrivate ? "true" : "false");
#endif

       // First we need to know if this is a visable type.
          bool isVisable = false;
#if 0
          printf ("targetScope                     = %p = %s \n",targetScope,targetScope->class_name().c_str());
       // printf ("typedefDeclaration              = %p = %s \n",typedefDeclaration,typedefDeclaration->class_name().c_str());
          printf ("typedefDeclaration->get_scope() = %p = %s \n",typedefDeclaration->get_scope(),typedefDeclaration->get_scope()->class_name().c_str());
#endif
#if 0
          printf ("SageInterface::whereAmI(targetScope): \n");
          SageInterface::whereAmI(targetScope);
          printf ("SageInterface::whereAmI(typedefDeclaration): \n");
          SageInterface::whereAmI(typedefDeclaration);
#endif
#if 0
          printf ("\ntargetScope symbol table: \n");
          targetScope->get_symbol_table()->print("targetScope");
          printf ("end of symbol table \n");
          printf ("\ntypedefDeclaration->get_scope() symbol table: \n");
          typedefDeclaration->get_scope()->get_symbol_table()->print("typedefDeclaration->get_scope()");
          printf ("end of symbol table \n\n");
#endif
       // Test for the trivial case of matching scope (an even better test (below) is be to make sure that the targetScope is nested in the typedef scope).
          if (typedefDeclaration->get_scope() == targetScope)
             {
#if 0
               printf ("In contains_private_type(SgType*): This is a typedef type from the same scope as the target declaration \n");
#endif
            // ROSE_ASSERT(false);
            // return false;
               isVisable = true;
             }
            else
             {
            // SgTypedefSymbol*   lookupTypedefSymbolInParentScopes  (const SgName & name, SgScopeStatement *currentScope = NULL);
               SgTypedefSymbol* typedefSymbol = SageInterface::lookupTypedefSymbolInParentScopes (typedefDeclaration->get_name(),targetScope);
               if (typedefSymbol != NULL)
                  {
#if 0
                    printf ("In contains_private_type(SgType*): This is not in the current scope but can be reached from the current scope \n");
#endif
                 // ROSE_ASSERT(false);
                 // return false;
                    isVisable = true;
                  }
                 else
                  {
#if 0
                    printf ("Symbol for typedef name = %s not found in parent scopes \n",typedefDeclaration->get_name().str());
#endif
                 // ROSE_ASSERT(false);
                  }
             }
#if 0
       // Testing codes because it seems that "BitSet" shuld be visiable and so we need to debug this first.
          if (typedefDeclaration->get_name() == "BitSet")
             {
               printf ("Exiting as a test! \n");
               ROSE_ASSERT(false);
             }
#endif
       // If this is not private, then we are looking at what would be possbile template arguments used in a possible name qualification.
       // if (isPrivate == false)
       // if (isPrivate == false && isVisable == false)
          if (isVisable == false)
             {
               if (isPrivate == true)
                  {
                    return true;
                  }
                 else
                  {

                 // Get the scope and see if it is a template instantiation.
                    SgScopeStatement* scope = typedefDeclaration->get_scope();
#if DEBUG_PRIVATE_TYPE || 0
                    printf ("++++++++++++++ Looking in parent scope for template arguments: scope = %p = %s \n",scope,scope->class_name().c_str());
#endif
                 // Get the associated declaration.
                    switch (scope->variantT())
                       {
                         case V_SgTemplateInstantiationDefn:
                            {
                              SgTemplateInstantiationDefn* templateInstantiationDefinition = isSgTemplateInstantiationDefn(scope);
                              ROSE_ASSERT(templateInstantiationDefinition != NULL);

                              SgTemplateInstantiationDecl* templateInstantiationDeclaration = isSgTemplateInstantiationDecl(templateInstantiationDefinition->get_declaration());
                              ROSE_ASSERT(templateInstantiationDeclaration != NULL);

                              SgTemplateArgumentPtrList & templateArgumentPtrList = templateInstantiationDeclaration->get_templateArguments();
                              for (SgTemplateArgumentPtrList::iterator i = templateArgumentPtrList.begin(); i != templateArgumentPtrList.end(); i++)
                                 {
#if DEBUG_PRIVATE_TYPE
                                   printf ("recursive call to contains_private_type(%p): name = %s = %s \n",*i,(*i)->class_name().c_str(),(*i)->unparseToString().c_str());
#endif
#if DEBUGGING_USING_RECURSIVE_DEPTH
                                   global_depth++;
#endif

                                   bool isPrivateType = contains_private_type(*i,targetScope);

#if DEBUGGING_USING_RECURSIVE_DEPTH
                                   global_depth--;
#endif
                                   returnValue |= isPrivateType;
                                 }
                              break;
                            }

                         default:
                            {
#if DEBUG_PRIVATE_TYPE
                              printf ("Ignoring non-SgTemplateInstantiationDefn \n");
#endif
                            }
                       }
                  }
             }
            else
             {
            // If it is visible then it need not be qualified and we don't care about if it was private.
               ROSE_ASSERT(isVisable == true);

            // returnValue = true;
               returnValue = false;
             }
        }
       else
        {
#if DEBUG_PRIVATE_TYPE || 0
          printf ("could be a wrapped type: type = %p = %s (not a template class instantiaton) \n",type,type->class_name().c_str());
          if (isSgModifierType(type) != NULL)
             {
               SgModifierType* modifierType = isSgModifierType(type);
               SgType* base_type = modifierType->get_base_type();
               printf ("--- base_type = %p = %s \n",base_type,base_type->class_name().c_str());
               SgNamedType* namedType = isSgNamedType(base_type);
               if (namedType != NULL)
                  {
                    printf ("--- base_type: name = %s \n",namedType->get_name().str());
                  }
             }
#endif
       // If this is a default SgModifierType then unwrap it.
#if 0
          SgModifierType* modifierType = isSgModifierType(type);
          if (modifierType != NULL)
             {

#error "DEAD CODE!"

            // What kind of modifier is this?
               printf ("What kind of type modifier: %s \n",modifierType->get_typeModifier().displayString().c_str());
               if (modifierType->get_typeModifier().isDefault() == true)
                  {
                 // This is a default mode modifier (acting as a wrapper type).
                    type = modifierType->get_base_type();
                  }
                 else
                  {
                    printf ("Not a default modifierType wrapper (need to handle this case) \n");
                    ROSE_ASSERT(false);
                  }
             }
#else
       // Strip past pointers and other wrapping modifiers (but not the typedef types, since the whole point is to detect private instatances).
          type = type->stripType(SgType::STRIP_MODIFIER_TYPE|SgType::STRIP_REFERENCE_TYPE|SgType::STRIP_RVALUE_REFERENCE_TYPE|SgType::STRIP_POINTER_TYPE|SgType::STRIP_ARRAY_TYPE);
#endif

#if 0
          printf ("After stripType(): type = %p = %s \n",type,type->class_name().c_str());
          SgNamedType* namedType = isSgNamedType(type);
          if (namedType != NULL)
             {
               printf ("--- stripType: name = %s \n",namedType->get_name().str());
             }
#endif
          ROSE_ASSERT(type != NULL);

       // Make sure this is not a simple template type (else we will have infinite recursion).
       // if (type != NULL && type->isIntegerType() == false && type->isFloatType() == false)
       // if (type != NULL)
          SgTemplateType*        templateType        = isSgTemplateType(type);
          SgClassType*           classType           = isSgClassType(type);
          SgTypeVoid*            voidType            = isSgTypeVoid(type);
          SgRvalueReferenceType* rvalueReferenceType = isSgRvalueReferenceType(type);
          SgFunctionType*        functionType        = isSgFunctionType(type);
          SgDeclType*            declType            = isSgDeclType(type);

       // DQ (12/7/2016): An enum type needs to be handled since the declaration might be private (but still debugging this for now).
          SgEnumType*            enumType            = isSgEnumType(type);

       // DQ (2/12/2017): Added specific type (causing infinite recursion for CompileTests/RoseExample_tests/testRoseHeaders_03.C.
          SgTypeEllipse*         typeEllipse         = isSgTypeEllipse(type);
          SgTypeUnknown*         typeUnknown         = isSgTypeUnknown(type);
          SgTypeComplex*         typeComplex         = isSgTypeComplex(type);

       // DQ (2/16/2017): This is a case causeing many C codes to fail.
          SgTypeOfType* typeOfType = isSgTypeOfType(type);

          if (type != NULL && templateType == NULL && classType == NULL && voidType == NULL && rvalueReferenceType == NULL && 
                              functionType == NULL && declType  == NULL && enumType == NULL && typeEllipse         == NULL && 
                              typeUnknown  == NULL && typeComplex == NULL && typeOfType == NULL)
             {
#if DEBUG_PRIVATE_TYPE || 0
               printf ("found unwrapped type = %p = %s = %s (not a template class instantiaton) \n",type,type->class_name().c_str(),type->unparseToString().c_str());
#endif
            // if (type->isIntegerType() == false && type->isFloatType() == false)
            // if (type->isIntegerType() == false && type->isFloatType() == false)
               if (type->isIntegerType() == false && type->isFloatType() == false)
                  {
#if DEBUG_PRIVATE_TYPE || 0
                    printf ("Making a recursive call to contains_private_type(type): not integer or float type: type = %p = %s  \n",type,type->class_name().c_str());
#endif
#if DEBUGGING_USING_RECURSIVE_DEPTH
                    depth++;
                    global_depth++;
#endif
                    bool isPrivateType = contains_private_type(type,targetScope);

#if DEBUGGING_USING_RECURSIVE_DEPTH
                    depth--;
                    global_depth--;
#endif
                    returnValue = isPrivateType;
                  }
                 else
                  {
                 // This can't be a private type.
#if DEBUG_PRIVATE_TYPE
                    printf ("This is an integer or float type (of some sort): type = %p = %s = %s \n",type,type->class_name().c_str(),type->unparseToString().c_str());
#endif
                    returnValue = false;
                  }
             }
            else
             {
            // This is where we need to resolve is any types that are associated with declarations might be private (e.g. SgEnumType).

               if (classType != NULL)
                  {
                 // Check if this is associated with a template class instantiation.
#if 0
                    SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration());
                    ROSE_ASSERT(classDeclaration != NULL);
                    printf ("--------- classDeclaration = %p = %s = %s \n",classDeclaration,classDeclaration->class_name().c_str(),classDeclaration->get_name().str());
#endif
                    SgTemplateInstantiationDecl* templateInstantiationDeclaration = isSgTemplateInstantiationDecl(classType->get_declaration());
                    if (templateInstantiationDeclaration != NULL)
                       {
#if DEBUGGING_USING_RECURSIVE_DEPTH
                         global_depth++;
#endif
#if 0
                         printf ("Calling contains_private_type(SgTemplateArgumentPtrList): templateInstantiationDeclaration = %p = %s \n",
                              templateInstantiationDeclaration,templateInstantiationDeclaration->get_name().str());
#endif
                         returnValue = contains_private_type(templateInstantiationDeclaration->get_templateArguments(),targetScope);

#if DEBUGGING_USING_RECURSIVE_DEPTH
                         global_depth--;
#endif
#if 0
                         printf ("DONE: Calling contains_private_type(SgTemplateArgumentPtrList): templateInstantiationDeclaration = %p = %s \n",
                              templateInstantiationDeclaration,templateInstantiationDeclaration->get_name().str());
#endif
                       }
#if 0
                    printf ("DONE: --- classDeclaration = %p = %s = %s \n",classDeclaration,classDeclaration->class_name().c_str(),classDeclaration->get_name().str());
#endif
                  }
             }
        }

#if DEBUG_PRIVATE_TYPE || 0
     printf ("Leaving contains_private_type(SgType*): type = %p = %s = %s returnValue = %s \n",type,type->class_name().c_str(),type->unparseToString().c_str(),returnValue ? "true" : "false");
#endif

     return returnValue;
   }
Beispiel #17
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
        }
   }
Beispiel #18
0
// DQ (8/27/2006): This functionality already exists elsewhere
// It is a shame that it is recreated here as well !!!
NameQuerySynthesizedAttributeType
NameQuery::queryNameTypeName (SgNode * astNode)
{
  ROSE_ASSERT (astNode != NULL);
  string typeName = "";
  Rose_STL_Container< string > returnList;
  SgType *type = isSgType (astNode);

  // printf ("In TransformationSupport::getTypeName(): type->sage_class_name() = %s \n",type->sage_class_name());

  if (type != NULL)
    switch (type->variantT ())
      {
      case V_SgTypeComplex:
        typeName = "complex";
        break;
      case V_SgTypeImaginary:
        typeName = "imaginary";
        break;
      case V_SgTypeBool:
        typeName = "bool";
        break;
      case V_SgEnumType:
        typeName = "enum";
        break;
      case V_SgTypeChar:
        typeName = "char";
        break;
      case V_SgTypeVoid:
        typeName = "void";
        break;
      case V_SgTypeInt:
        typeName = "int";
        break;
      case V_SgTypeDouble:
        typeName = "double";
        break;
      case V_SgTypeFloat:
        typeName = "float";
        break;
      case V_SgTypeLong:
        typeName = "long";
        break;
      case V_SgTypeLongDouble:
        typeName = "long double";
        break;
      case V_SgTypeEllipse:
        typeName = "ellipse";
        break;
      case V_SgTypeGlobalVoid:
        typeName = "void";
        break;
      case V_SgTypeLongLong:
        typeName = "long long";
        break;
      case V_SgTypeShort:
        typeName = "short";
        break;
      case V_SgTypeSignedChar:
        typeName = "signed char";
        break;
      case V_SgTypeSignedInt:
        typeName = "signed int";
        break;
      case V_SgTypeSignedLong:
        typeName = "signed long";
        break;
      case V_SgTypeSignedShort:
        typeName = "signed short";
        break;
      case V_SgTypeString:
        typeName = "string";
        break;
      case V_SgTypeUnknown:
        typeName = "unknown";
        break;
      case V_SgTypeUnsignedChar:
        typeName = "unsigned char";
        break;
      case V_SgTypeUnsignedInt:
        typeName = "unsigned int";
        break;
      case V_SgTypeUnsignedLong:
        typeName = "unsigned long";
        break;
      case V_SgTypeUnsignedShort:
        typeName = "unsigned short";
        break;
      case V_SgTypeUnsignedLongLong:
        typeName = "unsigned long long";
        break;
      case V_SgReferenceType:
        {
          ROSE_ASSERT (isSgReferenceType (type)->get_base_type () != NULL);

          Rose_STL_Container< string > subTypeNames = queryNameTypeName (isSgReferenceType (type)->get_base_type ());

          typedef Rose_STL_Container< string >::iterator typeIterator;

          //This iterator will only contain one name
          for (typeIterator i = subTypeNames.begin ();
               i != subTypeNames.end (); ++i)
            {
              string e = *i;
              typeName = e;
              break;
            }

          break;
        }
      case V_SgPointerType:
        {
          ROSE_ASSERT (isSgPointerType (type)->get_base_type () != NULL);

          Rose_STL_Container< string > subTypeNames =
            queryNameTypeName (isSgPointerType (type)->get_base_type ());

          typedef Rose_STL_Container< string >::iterator typeIterator;

          //This iterator will only contain one name
          for (typeIterator i = subTypeNames.begin ();
               i != subTypeNames.end (); ++i)
            {
              string e = *i;
              typeName = e;
              break;
            }

          break;
        }
      case V_SgModifierType:
        {
          ROSE_ASSERT (isSgModifierType (type)->get_base_type () != NULL);

          Rose_STL_Container< string > subTypeNames =
            queryNameTypeName (isSgModifierType (type)->get_base_type ());

          typedef Rose_STL_Container< string >::iterator typeIterator;

          //This iterator will only contain one name
          for (typeIterator i = subTypeNames.begin ();
               i != subTypeNames.end (); ++i)
            {
              string e = *i;
              typeName = e;
              break;
            }
          break;
        }
      case V_SgNamedType:
        {
          SgNamedType *sageNamedType = isSgNamedType (type);
          ROSE_ASSERT (sageNamedType != NULL);
          typeName = sageNamedType->get_name ().str ();
          break;
        }
      case V_SgClassType:
        {
          SgClassType *sageClassType = isSgClassType (type);
          ROSE_ASSERT (sageClassType != NULL);
          typeName = sageClassType->get_name ().str ();
          break;
        }
      case V_SgTypedefType:
        {
          SgTypedefType *sageTypedefType = isSgTypedefType (type);
          ROSE_ASSERT (sageTypedefType != NULL);
          typeName = sageTypedefType->get_name ().str ();
          break;
        }
      case V_SgPointerMemberType:
        {
          SgPointerMemberType *pointerMemberType =
            isSgPointerMemberType (type);
          ROSE_ASSERT (pointerMemberType != NULL);
          SgClassType *classType =
            isSgClassType(pointerMemberType->get_class_type()->stripTypedefsAndModifiers());
          ROSE_ASSERT (classType != NULL);
          SgClassDeclaration *classDeclaration =
            isSgClassDeclaration(classType->get_declaration());
          ROSE_ASSERT (classDeclaration != NULL);
          typeName = classDeclaration->get_name ().str ();
          break;
        }
      case V_SgArrayType:
        {
          ROSE_ASSERT (isSgArrayType (type)->get_base_type () != NULL);


          Rose_STL_Container< string > subTypeNames =
            queryNameTypeName (isSgArrayType (type)->get_base_type ());

          typedef Rose_STL_Container< string >::iterator typeIterator;

          //This iterator will only contain one name
          for (typeIterator i = subTypeNames.begin ();
               i != subTypeNames.end (); ++i)
            {
              string e = *i;
              typeName = e;
              break;
            }
          break;
        }
      case V_SgFunctionType:
        {
          SgFunctionType *functionType = isSgFunctionType (type);
          ROSE_ASSERT (functionType != NULL);
          typeName = functionType->get_mangled_type ().str ();
          break;
        }
      case V_SgMemberFunctionType:
        {
          SgMemberFunctionType *memberFunctionType =
            isSgMemberFunctionType (type);
          ROSE_ASSERT (memberFunctionType != NULL);
          SgClassType *classType =
            isSgClassType(memberFunctionType->get_class_type()->stripTypedefsAndModifiers());
          ROSE_ASSERT (classType != NULL);
          SgClassDeclaration *classDeclaration =
            isSgClassDeclaration(classType->get_declaration());
          ROSE_ASSERT (classDeclaration != NULL);
          typeName = classDeclaration->get_name ().str ();
          break;
        }
      case V_SgTypeWchar:
        typeName = "wchar";
        break;
      case V_SgTypeDefault:
        typeName = "default";
        break;
      default:
        printf
          ("default reached in switch within TransformationSupport::getTypeName type->sage_class_name() = %s variant = %d \n",
           type->sage_class_name (), type->variant ());
        ROSE_ABORT ();
        break;
      }

  // Fix for purify problem report
  // typeName = ROSE::stringDuplicate(typeName);

  if (typeName.size () > 0)
    returnList.push_back (typeName);
  //ROSE_ASSERT(typeName.c_str() != NULL);
  // return typeName;
  return returnList;
//return ROSE::stringDuplicate(typeName.c_str());
}