Ejemplo n.º 1
0
StencilEvaluation_SynthesizedAttribute
StencilEvaluationTraversal::evaluateSynthesizedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute, SubTreeSynthesizedAttributes synthesizedAttributeList )
   {
     StencilEvaluation_SynthesizedAttribute return_synthesizedAttribute;

#if 0
     printf ("In StencilEvaluationTraversal::evaluateSynthesizedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif

     bool foundStencilOffsetFSM = false;
     SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(astNode);
     if (constructorInitializer != NULL && inheritedAttribute.stencilOffsetFSM != NULL)
        {
#if 0
          printf ("Found pair<Shift,double>(x,y): set then in the synthesizedAttribute: astNode = %p = %s \n",astNode,astNode->class_name().c_str());
#endif
          return_synthesizedAttribute.stencilOffsetFSM       = inheritedAttribute.stencilOffsetFSM;
          return_synthesizedAttribute.stencilCoeficientValue = inheritedAttribute.stencilCoeficientValue;
#if 0
          printf ("return_synthesizedAttribute.stencilCoeficientValue = %f \n",return_synthesizedAttribute.stencilCoeficientValue);
#endif
          foundStencilOffsetFSM = true;
        }

  // There should only be a single child set with a pair<Shift,double>(x,y) object.
     for (size_t i = 0; i < synthesizedAttributeList.size(); i++)
        {
          if (synthesizedAttributeList[i].stencilOffsetFSM != NULL)
             {
            // Check that the return_synthesizedAttribute.stencilOffsetFSM has not already been set.
            // This could happend if we allows nesting of pair<Shift,double>(x,y) within itself (not allowed).
#if 0
               printf ("synthesizedAttributeList[i].stencilOffsetFSM != NULL \n");
#endif
            // ROSE_ASSERT(foundStencilOffsetFSM == false);
               if (foundStencilOffsetFSM == false)
                  {
#if 0
                    printf ("foundStencilOffsetFSM == false \n");
#endif
                 // ROSE_ASSERT(return_synthesizedAttribute.stencilOffsetFSM == NULL);
                    if (return_synthesizedAttribute.stencilOffsetFSM == NULL)
                       {
#if 0
                         printf ("return_synthesizedAttribute.stencilOffsetFSM != NULL \n");
#endif
                         return_synthesizedAttribute.stencilOffsetFSM = synthesizedAttributeList[i].stencilOffsetFSM;
                         return_synthesizedAttribute.stencilCoeficientValue = synthesizedAttributeList[i].stencilCoeficientValue;
                       }

                    foundStencilOffsetFSM = true;
                  }
             }
        }

  // This allows us to find the variables of type vector<Point> and vector<double> used as an alternative way
  // to specify a stencil (using the Stencil constructor that takes these variables as input arguments).
  // It relies upon a previous traversal to have identified the inputs to Stencil constructor.
  // This support is incomplete while I focus on the alternative approach to the specification of the stencil
  // using intremental union of a stencil with a pair<Shift,double>() template instantiation.
     SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(astNode);
     if (variableDeclaration != NULL)
        {
       // Get the SgInitializedName from the SgVariableDeclaration.
          SgInitializedName* initializedName = SageInterface::getFirstInitializedName(variableDeclaration);
#if 0
          printf ("In evaluateInheritedAttribute(): case SgInitializedName from variable declaration: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str());
#endif
          bool foundStencilDeclaration = false;
          if (find(stencilInputInitializedNameList.begin(),stencilInputInitializedNameList.end(),initializedName) != stencilInputInitializedNameList.end())
             {
#if 0
               printf ("Found declaration associated with stencil input: initializedName = %p = %s name = %s \n",initializedName,initializedName->class_name().c_str(),initializedName->get_name().str());
#endif
            // Build the finite state machine for the stencil and add it to the map using the name (in SgInitializedName) as a key.
            // For now we assume that the stencil specification is using the default construction.
               if (initializedName->get_initptr() != NULL)
                  {
                    printf ("FIXME: This declaration of a stencil appears to have constrcutor arguments (this not the default constuctor as interprest below). \n");
#if 0
                    ROSE_ASSERT(false);
#endif
                  }

               foundStencilDeclaration = true;
             }
            else
             {
            // Verify that this is a Stencil declaration.
               SgClassType* classType = isSgClassType(initializedName->get_type());
               if (classType != NULL)
                  {
                 // Check if this is associated with a template instantiation.
                    SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classType->get_declaration());
                    if (templateInstantiationDecl != NULL)
                       {
#if 0
                         printf ("case SgTemplateInstaiationDecl: class name = %s \n",classType->get_name().str());
                         printf ("case SgTemplateInstaiationDecl: templateInstantiationDecl->get_templateName() = %s \n",templateInstantiationDecl->get_templateName().str());
#endif
                         if (templateInstantiationDecl->get_templateName() == "Stencil")
                            {
#if 0
                              printf ("This is verified to be associated with the Stencil template class \n");
#endif
                              foundStencilDeclaration = true;
                            }
                       }
                  }
             }

          if (foundStencilDeclaration == true)
             {
               string name = initializedName->get_name();
               ROSE_ASSERT(stencilMap.find(name) == stencilMap.end());
            // stencilMap[name] = new StencilFSM();
               StencilFSM* stencilFSM = new StencilFSM();
               ROSE_ASSERT(stencilFSM != NULL);
               stencilMap[name] = stencilFSM;
               ROSE_ASSERT(stencilMap.find(name) != stencilMap.end());
#if 0
               printf ("Added StencilFSM to stencilMap using name = %s \n",name.c_str());
#endif
#if 0
               printf ("Trigger an event on the stencilFSM ========================== %p \n",stencilFSM);
               printf ("   --- Use the return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
               if (return_synthesizedAttribute.stencilOffsetFSM != NULL)
                  {
                 // Trigger the event to add the stencil offset to the stencil.
                 // Trigger the event on the finite state machine using the elements saved in the synthesized attribute.
                    StencilFSM stencil_rhs (*(return_synthesizedAttribute.stencilOffsetFSM),return_synthesizedAttribute.stencilCoeficientValue);

                 // This reproduces the same semantics in our finite state machine as the Stencil class's operator+()
                 // in the stencil specification. but this permits use to accumulate the state at compile time.
                    stencilFSM->operator+(stencil_rhs);

                 // We have now used these values so avoid letting then be used again.
                    return_synthesizedAttribute.stencilOffsetFSM       = NULL;
                    return_synthesizedAttribute.stencilCoeficientValue = 0.0;
                  }
#if 0
               stencilFSM->display("after FSM stencil default construction plus union event: StencilEvaluationTraversal::evaluateSynthesizedAttribute()");
#endif
#if 0
               printf ("Exiting as a test! \n");
               ROSE_ASSERT(false);
#endif
             }
        }

  // Recognize member function calls on "Stencil" objects so that we can trigger events on those associated finite state machines.
     bool isTemplateClass = true;
     bool isTemplateFunctionInstantiation = true;
     SgInitializedName* initializedNameUsedToCallMemberFunction = NULL;
     SgFunctionCallExp* functionCallExp = detectMemberFunctionOfSpecificClassType(astNode,initializedNameUsedToCallMemberFunction,"Stencil",isTemplateClass,"operator+",isTemplateFunctionInstantiation);
     if (return_synthesizedAttribute.stencilOffsetFSM != NULL && functionCallExp != NULL)
        {
       // This is the DSL specific part of the synthesized attribute evaluation.

          ROSE_ASSERT(initializedNameUsedToCallMemberFunction != NULL);
          string name = initializedNameUsedToCallMemberFunction->get_name();
#if 0
          printf ("This is verified to be the operator+ member function of the Stencil templated class (so this corresponds to an event in the Stencil finite state machine) \n");
          printf ("   --- stencil object name = %s \n",name.c_str());
#endif
       // Lookup the stencil FSM in the map of stencil FSMs using the name as the key.
          ROSE_ASSERT(stencilMap.find(name) != stencilMap.end());
          StencilFSM* stencilFSM = stencilMap[name];
          ROSE_ASSERT(stencilFSM != NULL);
#if 0
          printf ("Trigger an event on the stencilFSM ========================== %p \n",stencilFSM);
          printf ("   --- Use the return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
       // Make sure we have the input parameter for the stencil's finite state machine.
          ROSE_ASSERT(return_synthesizedAttribute.stencilOffsetFSM != NULL);

       // Trigger the event on the finite state machine using the elements saved in the synthesized attribute.
          StencilFSM stencil_rhs (*(return_synthesizedAttribute.stencilOffsetFSM),return_synthesizedAttribute.stencilCoeficientValue);

       // This reproduces the same semantics in our finite state machine as the Stencil class's operator+()
       // in the stencil specification. but this permits use to accumulate the state at compile time.
          stencilFSM->operator+(stencil_rhs);

       // We have now used these values so avoid letting then be used again.
          return_synthesizedAttribute.stencilOffsetFSM       = NULL;
          return_synthesizedAttribute.stencilCoeficientValue = 0.0;
#if 0
          stencilFSM->display("after FSM stencil union event: StencilEvaluationTraversal::evaluateSynthesizedAttribute()");
#endif
        }

#if 0
     printf ("Leaving StencilEvaluationTraversal::evaluateSynthesizedAttribute(): return_synthesizedAttribute.stencilOffsetFSM = %p \n",return_synthesizedAttribute.stencilOffsetFSM);
#endif
#if 0
     printf ("Leaving StencilEvaluationTraversal::evaluateSynthesizedAttribute(): return_synthesizedAttribute.stencilCoeficientValue = %f \n",return_synthesizedAttribute.stencilCoeficientValue);
#endif

     return return_synthesizedAttribute;
   }
void
ProcessTemplateHandlingOptions::visit ( SgNode* node )
   {
  // DQ (8/19/2005): Unmark implicit template instantiations that would be output

  // printf ("node = %s \n",node->sage_class_name());

     switch (node->variantT())
        {
          case V_SgTemplateInstantiationDecl:
             {
               SgTemplateInstantiationDecl* s = isSgTemplateInstantiationDecl(node);
               if (buildImplicitTemplates == false)
                  {
                 // Mark all template class instantiations except specialized template 
                 // instantiations to NOT be output in code generation
                    if (s->get_file_info()->isOutputInCodeGeneration() == true && s->isSpecialization() == false)
                       {
                         printf ("AST Fixup: This template class will not be output within code generation \n");
                         s->get_file_info()->unsetOutputInCodeGeneration();
                       }
                    ROSE_ASSERT (s->get_file_info()->isOutputInCodeGeneration() == false || s->isSpecialization() == true);
                  }
               break;
             }

          case V_SgTemplateInstantiationFunctionDecl:
             {
               SgTemplateInstantiationFunctionDecl* s = isSgTemplateInstantiationFunctionDecl(node);
               if (buildImplicitTemplates == false)
                  {
                 // Mark all template function instantiations except specialized template 
                 // instantiations to NOT be output in code generation
                    if (s->get_file_info()->isOutputInCodeGeneration() == true && s->isSpecialization() == false)
                       {
                         printf ("AST Fixup: This template function will not be output within code generation \n");
                         s->get_file_info()->unsetOutputInCodeGeneration();
                       }
                    ROSE_ASSERT (s->get_file_info()->isOutputInCodeGeneration() == false || s->isSpecialization() == true);
                  }
               break;
             }

          case V_SgTemplateInstantiationMemberFunctionDecl:
             {
               SgTemplateInstantiationMemberFunctionDecl* s = isSgTemplateInstantiationMemberFunctionDecl(node);
               if (buildImplicitTemplates == false && buildImplicitInlineTemplates == false)
                  {
                 // Mark all template member function instantiations except specialized template 
                 // instantiations to NOT be output in code generation
                    if (s->get_file_info()->isOutputInCodeGeneration() == true && s->isSpecialization() == false)
                       {
                         printf ("AST Fixup: This template member function will not be output within code generation \n");
                         s->get_file_info()->unsetOutputInCodeGeneration();
                       }
                    ROSE_ASSERT (s->get_file_info()->isOutputInCodeGeneration() == false || s->isSpecialization() == true);
                  }
               break;
             }

          default:
             {
            // no other cases appear to be a problem!
             }
        }
   }
Ejemplo n.º 3
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);
   }
Ejemplo n.º 4
0
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;
   }
Ejemplo n.º 5
0
void
fixupInstantiatedTemplates ( SgProject* project )
   {
  // DQ (7/12/2005): Introduce tracking of performance of ROSE.
     TimingPerformance timer ("AST Object Code Generation (fixupInstantiatedTemplates): time (sec) = ");

  // DQ (9/6/2005): I think these operations have been superseded
  // by the AST post processing mechanism which is more complete.
     printf ("In fixupInstantiatedTemplates(): I think this may be dead code! \n");
     ROSE_ASSERT(false);

  // This must be done prior to the unparsing of the SAGE III AST, so that any transformations
  // (new function prototypes for the specialized template function) can be inserted before we 
  // unparse the final code!  Could be done in AST fixup!  Not clear if it should be done in
  // the EDG/SAGE III connection!  It is currently called from the backend() function just 
  // before the unparser!

  // Add forward references for instantiated template functions and member functions 
  // (which are by default defined at the bottom of the file (but should be declared 
  // at the top once we know what instantiations should be built)).  They must be 
  // defined at the bottom since they could call other functions not yet declared in 
  // the file.  Note that this fixup is required since we have skipped the class template 
  // definitions which would contain the declarations that we are generating.  We might 
  // need that as a solution at some point if this fails to be sufficently robust.

  // Build a lists of intatiatied templates
     Rose_STL_Container<SgNode*> classList          = NodeQuery::querySubTree (project,V_SgTemplateInstantiationDecl);
     Rose_STL_Container<SgNode*> functionList       = NodeQuery::querySubTree (project,V_SgTemplateInstantiationFunctionDecl);
     Rose_STL_Container<SgNode*> memberFunctionList = NodeQuery::querySubTree (project,V_SgTemplateInstantiationMemberFunctionDecl);

#if 1
     printf ("In fixupInstantiatedTemplates SgTemplateInstantiationDecl:               classList.size()          = %ld \n",classList.size());
     printf ("In fixupInstantiatedTemplates SgTemplateInstantiationFunctionDecl:       functionList.size()       = %ld \n",functionList.size());
     printf ("In fixupInstantiatedTemplates SgTemplateInstantiationMemberFunctionDecl: memberFunctionList.size() = %ld \n",memberFunctionList.size());
#endif

  // These are not handled yet!
  // ROSE_ASSERT(classList.size()    == 0);
  // ROSE_ASSERT(functionList.size() == 0);

     Rose_STL_Container<SgNode*>::iterator functionIndex = functionList.begin();
     while ( functionIndex != functionList.end() )
        {
       // SgDeclarationStatement* declaration = isSgDeclarationStatement(*i);
          SgTemplateInstantiationFunctionDecl* templateInstantiationFunctionDeclaration = 
               isSgTemplateInstantiationFunctionDecl(*functionIndex);
          ROSE_ASSERT (templateInstantiationFunctionDeclaration != NULL);

       // printf ("SgTemplateInstantiationFunctionDecl: *i = %p = %s \n",*functionIndex,(*functionIndex)->unparseToString().c_str());

       // Mark this function as a specialization, since we have transformed it into one when we converted the
       // name format (e.g.from  __A45_ to A<int>).  The handling of templates in ROSE is one of converting
       // the templae instantiations (generated by EDG) into explicit template specializations so that they
       // can be operated upon within ROSE (for translation/optimization).
          printf ("Error in fixupInstantiatedTemplates (function templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n");
          templateInstantiationFunctionDeclaration->set_specialization(SgTemplateInstantiationFunctionDecl::e_specialization);

          bool generateForwardDeclarationForFunction = (templateInstantiationFunctionDeclaration->isForward() == false);

          if ( generateForwardDeclarationForFunction == true )
             {
            // This is just a regular member function inside of a templated class (or a class nested in a templated class)
            // it's associated template declaration will not have the template text (appears to be lost in EDG), but it 
            // is not essential if we unparse the instantated template for the member function.

            // This is the instantiate template member function definition, the steps are:
            //    1) Build a forward declaration for the instantiated template (member function).
            //    2) Place the new forward declaration after the class containing the templated member function.
             }

          functionIndex++;
        }

     Rose_STL_Container<SgNode*>::iterator classIndex = classList.begin();
     while ( classIndex != classList.end() )
        {
          SgTemplateInstantiationDecl* templateInstantiationClassDeclaration = 
               isSgTemplateInstantiationDecl(*classIndex);
          ROSE_ASSERT (templateInstantiationClassDeclaration != NULL);

       // printf ("SgTemplateInstantiationDecl: *i = %p = %s \n",*classIndex,(*classIndex)->unparseToString().c_str());

#if 0
          printf ("In fixupInstantiatedTemplates: templateInstantiationClassDeclaration = %p compilerGenerated = %s \n",
                  templateInstantiationClassDeclaration,
                  templateInstantiationClassDeclaration->get_file_info()->isCompilerGenerated() ? "true" : "false");
          templateInstantiationClassDeclaration->get_file_info()->display("In fixupInstantiatedTemplates: templateInstantiationClassDeclaration");
#endif

       // Mark this class as a specialization, since we have transformed it into one when we converted the
       // name format (e.g.from  __A45_ to A<int>).  The handling of templates in ROSE is one of converting
       // the templae instantiations (generated by EDG) into explicit template specializations so that they
       // can be operated upon within ROSE (for translation/optimization).
          printf ("Error in fixupInstantiatedTemplates (class templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n");
          templateInstantiationClassDeclaration->set_specialization(SgTemplateInstantiationDecl::e_specialization);

          bool generateForwardDeclarationForClass = (templateInstantiationClassDeclaration->isForward() == false);

          if ( generateForwardDeclarationForClass == true )
             {
            // Nothing to do in this case since EDG should have already instered the forward class declaration!
             }

          classIndex++;
        }

  // Loop over the SgTemplateInstantiationMemberFunction objects and insert a function prototype.
  // We need the function prototypes because the template instatiation function definitions appear 
  // at the end of the file!
     Rose_STL_Container<SgNode*>::iterator i = memberFunctionList.begin();
     while ( i != memberFunctionList.end() )
        {
       // SgDeclarationStatement* declaration = isSgDeclarationStatement(*i);
          SgTemplateInstantiationMemberFunctionDecl* templateInstantiationMemberFunctionDeclaration = 
               isSgTemplateInstantiationMemberFunctionDecl(*i);
          ROSE_ASSERT (templateInstantiationMemberFunctionDeclaration != NULL);
#if 0
          printf ("templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == %s \n",
               templateInstantiationMemberFunctionDeclaration->isTemplateFunction() ? "true" : "false");
#endif
       // Mark this function as a specialization, since we have transformed it into one when we converted the
       // name formate (e.g.from  __A45_ to A<int>).  The handling of templates in ROSE is one of converting
       // the templae instantiations (generated by EDG) into explicit template specializations so that they
       // can be operated upon within ROSE (for translation/optimization).
       // If this is not a truely templated function then it can't be a specialization!
       // if it is not a templated function then is is likely just a member function of a templated class.
          if (templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == true)
             {
               printf ("Error in fixupInstantiatedTemplates (member function templates): It is now an error to mark something that was not explicitly a specialization in the original source code as a specialization ... \n");
               templateInstantiationMemberFunctionDeclaration->set_specialization(SgTemplateInstantiationMemberFunctionDecl::e_specialization);
             }
#if 0
       // DQ (9/5/2005): Updated comment.
       // DQ (5/31/2005): Commented out since the class declaration itself is the forward declaration 
       // for the member function. I don't think we need another one!  Actually we do but this is now 
       // handled within ROSE/src/frontend/SageIII/astPostProcessing/ files.

          bool generateForwardDeclarationForInlinedMemberFunction = 
               (templateInstantiationMemberFunctionDeclaration->isForward() == false) &&
               (templateInstantiationMemberFunctionDeclaration->isTemplateFunction() == false);

          if ( generateForwardDeclarationForInlinedMemberFunction == true )
             {
            // This is just a regular member function inside of a templated class (or a class nested in a templated class)
            // it's associated template declaration will not have the templae text (appears to be lost in EDG), but it 
            // is not essential if we unparse the instantated template for the member function.

               printf ("For inlined template member functions get the templateDeclaration from the class declaration \n");

            // This is the instantiate template member function definition, the steps are:
            //    1) Build a forward declaration for the instantiated template (member function).
            //    2) Place the new forward declaration after the class containing the templated member function.

               printf ("SgTemplateInstantiationMemberFunctionDecl: *i = %p = %s \n",*i,(*i)->unparseToString().c_str());

            // Call the AST's copy mechanism
               SgShallowCopy shallow;
               SgNode * forwardDeclarationNode = templateInstantiationMemberFunctionDeclaration->copy(shallow);
               SgTemplateInstantiationMemberFunctionDecl* forwardDeclaration = isSgTemplateInstantiationMemberFunctionDecl(forwardDeclarationNode);
               ROSE_ASSERT(forwardDeclaration != NULL);

            // find the template declaration of the class contining the member function
               SgClassDeclaration* classDeclaration = templateInstantiationMemberFunctionDeclaration->get_class_scope()->get_declaration();
               ROSE_ASSERT(classDeclaration != NULL);
               SgTemplateInstantiationDecl* templateInstantiationDeclaration = isSgTemplateInstantiationDecl(classDeclaration);
               ROSE_ASSERT(templateInstantiationDeclaration != NULL);
               SgTemplateDeclaration* templateDeclaration = templateInstantiationDeclaration->get_templateDeclaration();
               ROSE_ASSERT (templateDeclaration != NULL);

            // Reset the file info object so that we can mark this as compiler generated (copy builds a new Sg_File_Info object)
            // ROSE_ASSERT (forwardDeclaration->get_file_info() != NULL);
            // forwardDeclaration->set_file_info(new Sg_File_Info(*(forwardDeclaration->get_file_info())));
               ROSE_ASSERT(forwardDeclaration->get_file_info() != templateInstantiationMemberFunctionDeclaration->get_file_info());

            // Both of these may be set (implemented as bit flags internally)
               forwardDeclaration->get_file_info()->setCompilerGenerated();
               forwardDeclaration->get_file_info()->setTransformation();

            // Remove the shallow copy of the function definition
               forwardDeclaration->set_definition(NULL);

            // Mark the declaration as a forward declarations
               forwardDeclaration->setForward();

            // Mark this function as a specialization (should be done within copy function)
            // forwardDeclaration->set_specialization(SgTemplateInstantiationMemberFunctionDecl::e_specialization);

               ROSE_ASSERT(forwardDeclaration->isSpecialization() == true);
               ROSE_ASSERT(forwardDeclaration->isPartialSpecialization() == false);

            // Now insert the forwardDeclaration after the templateDeclaration!
            // templateDeclaration.insert_statement(forwardDeclaration,true);
               SgScopeStatement* templateDeclarationScope = templateDeclaration->get_scope();
               ROSE_ASSERT (templateDeclarationScope != NULL);
               printf ("BEFORE loop: Insert before: templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name());

            // Trace back through the scopes to find a non class declaration scope into which to put the forward declaration
            // Does this then work with nested template classes?????
               while (isSgTemplateInstantiationDefn(templateDeclarationScope) != NULL)
                  {
                    templateDeclarationScope = templateDeclarationScope->get_scope();
                    printf ("In loop templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name());
                  }

               ROSE_ASSERT (templateDeclarationScope != NULL);
               printf ("AFTER loop: Insert before: templateDeclarationScope = %p = %s \n",templateDeclarationScope,templateDeclarationScope->sage_class_name());

               templateDeclaration->get_file_info()->display("templateDeclaration");
               templateDeclarationScope->get_file_info()->display("templateDeclarationScope");

               int insertBeforeStatement = false;
            // printf ("Calling templateDeclarationScope->insert_statement() \n");
            // templateDeclaration->insert_statement ( templateDeclaration, forwardDeclaration, insertBeforeStatement );
               SgTemplateInstantiationDefn *templateClassDefinition = isSgTemplateInstantiationDefn(templateDeclarationScope);
               if (templateClassDefinition != NULL)
                  {
                    SgDeclarationStatementPtrList::iterator start = templateClassDefinition->get_members().begin();
                    SgDeclarationStatementPtrList::iterator end   = templateClassDefinition->get_members().end();

                    printf ("templateDeclaration unparsed = %s \n",templateDeclaration->unparseToString().c_str());
                    printf ("templateDeclaration name = %s string = %s \n",
                         templateDeclaration->get_name().str(),templateDeclaration->get_string().str());

                    for (SgDeclarationStatementPtrList::iterator i = start; i != end; i++)
                       {
                         string s = (*i)->unparseToString();
                         printf ("(*i)->unparseToString() = %s \n",s.c_str());
                       }

                    ROSE_ASSERT(find(start,end,templateInstantiationMemberFunctionDeclaration) != end);
                    templateDeclarationScope->insert_statement ( templateInstantiationMemberFunctionDeclaration, forwardDeclaration, insertBeforeStatement );
                  }
                 else
                  {
                 // ROSE_ASSERT(find(templateDeclarationScope->get_members().begin(),templateDeclarationScope->get_members().end(),templateDeclaration) != templateDeclarationScope->get_members().end() );
                    templateDeclarationScope->insert_statement ( templateDeclaration, forwardDeclaration, insertBeforeStatement );
                  }

               printf ("forwardDeclaration = %s \n",forwardDeclaration->unparseToString().c_str());

            // printf ("DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD \n");
            // printf ("Exiting after construction of forward declaration for template instantiation! \n");
            // ROSE_ASSERT (false);
             }
            else
             {
            // This is a forward declaration (does it have the template arguments!)
               printf ("SgTemplateInstantiationMemberFunctionDecl: (forward) *i = %p = %s \n",*i,(*i)->unparseToString().c_str());
             }
#endif
          i++;
        }
   }
Ejemplo n.º 6
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;
   }
Ejemplo n.º 7
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);
   }