bool
FixupTemplateArguments::contains_private_type (SgTemplateArgument* templateArgument, SgScopeStatement* targetScope)
   {
  // Note that within EDG and ROSE the template arguments may be shared so that we can support testing for equivalence.

  // static std::list<SgTemplateArgument*> templateArgumentList;
  // templateArgumentList.push_back(templateArgument);
     static std::set<SgTemplateArgument*> templateArgumentSet;

     if (templateArgumentSet.find(templateArgument) == templateArgumentSet.end())
        {
          templateArgumentSet.insert(templateArgument);
        }
       else
        {
#if DEBUGGING_USING_RECURSIVE_DEPTH
          printf ("@@@@@@@@@@@@@@@@@ Already been or being processed: templateArgument = %p = %s templateArgumentSet.size() = %zu \n",templateArgument,templateArgument->unparseToString().c_str(),templateArgumentSet.size());
#endif

#if 0
          printf ("Leaving contains_private_type(SgTemplateArgument): templateArgument = %p returning FALSE \n",templateArgument);
#endif

       // DQ (2/15/2017): Unclear if this is the correct return value, it might be that we want to record 
       // the associated value from the first time the argument list was processed and use that value.
       // Then again, if the value had already been substituted into the template argument then no further 
       // processing is required.
          return false;
        }

#if DEBUGGING_USING_RECURSIVE_DEPTH
     printf ("--- added templateArgument = %p templateArgumentSet.size() = %zu \n",templateArgument,templateArgumentSet.size());
#endif

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

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

     printf ("In contains_private_type(SgTemplateArgument*): global_depth = %zu \n",global_depth);
     if (global_depth >= 50)
        {
       // output the list of SgTemplateArgument in the list
          printf ("Error: too many elements in list: recursuion too deep \n");
          size_t counter = 0;
          for (std::set<SgTemplateArgument*>::iterator i = templateArgumentSet.begin(); i != templateArgumentSet.end(); i++)
             {
               printf ("--- templateArgumentSet[counter] = %p = %s \n",*i,templateArgument->unparseToString().c_str()); 
               counter++;
             }
        }
     ROSE_ASSERT(global_depth < 50);
#endif

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

#if DEBUG_PRIVATE_TYPE
     printf ("In contains_private_type(SgTemplateArgument*): templateArgument = %p = %s = %s \n",templateArgument,templateArgument->class_name().c_str(),templateArgument->unparseToString().c_str());
#endif

     switch (templateArgument->get_argumentType())
        {
          case SgTemplateArgument::type_argument:
             {
               ROSE_ASSERT (templateArgument->get_type() != NULL);

               SgType* templateArgumentType = templateArgument->get_type();
#if DEBUG_PRIVATE_TYPE
               printf ("templateArgumentType = %p = %s \n",templateArgumentType,templateArgumentType->class_name().c_str());
               if (isSgModifierType(templateArgumentType) != NULL)
                  {
                    SgModifierType* modifierType = isSgModifierType(templateArgumentType);
                    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 DEBUGGING_USING_RECURSIVE_DEPTH
               depth++;
               global_depth++;
#endif

#if 0
               printf ("In contains_private_type(SgTemplateArgument*): case SgTemplateArgument::type_argument: Calling contains_private_type(templateArgumentType) \n");
#endif
            // DQ (2/14/2017): We might want to generate a list of the private types used so
            // that we can check them against the scope of the declaration where they occur.
            // Note also that this does not address types that might appear in name qualification.
               returnValue = contains_private_type(templateArgumentType,targetScope);

#if DEBUGGING_USING_RECURSIVE_DEPTH
               depth--;
               global_depth--;
#endif
#if 0
               printf ("In contains_private_type(SgTemplateArgument*): case SgTemplateArgument::type_argument: DONE calling contains_private_type(templateArgumentType): returnValue = %s \n",returnValue ? "true" : "false");
#endif
               if (returnValue == true)
                  {
                 // Find an alternative typedef to use instead.

                 // Note that this need not be a SgTypedefType (the lists are available in every SgType).
                    SgTypedefType* typedefType = isSgTypedefType(templateArgumentType);

                    if (typedefType == NULL && isSgModifierType(templateArgumentType) != NULL)
                       {
                         SgModifierType* modifierType = isSgModifierType(templateArgumentType);
                         SgType* base_type = modifierType->get_base_type();
#if 0
                         printf ("Found SgModifierType: --- 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 0
                         printf ("******* Reset the typedefType to what was found in the modifier type as a base type = %p = %s \n",base_type,base_type->class_name().c_str());
#endif
                         typedefType = isSgTypedefType(base_type);
                       }

                    if (typedefType != NULL)
                       {
                      // Check if this is a type from a typedef that is in the same scope as the target declaration (variable declaration).
                         SgTypedefDeclaration* typedefDeclaration = isSgTypedefDeclaration(typedefType->get_declaration());
                         ROSE_ASSERT(typedefDeclaration != NULL);

                      // Test for the matching scope (an even better test would be to make sure that the targetScope is nested in the typedef scope).
                         SgScopeStatement* typedefDeclarationScope = typedefDeclaration->get_scope();
                         ROSE_ASSERT(targetScope != NULL);
                         ROSE_ASSERT(typedefDeclarationScope != NULL);
#if 0
                         printf ("targetScope             = %p = %s \n",targetScope,targetScope->class_name().c_str());
                         printf ("typedefDeclarationScope = %p = %s \n",typedefDeclarationScope,typedefDeclarationScope->class_name().c_str());
                         if (typedefDeclarationScope == targetScope)
                            {
                              printf ("In contains_private_type(SgTemplateArgument*): This is a typedef type from the same scope as the target declaration \n");
                              ROSE_ASSERT(false);
                            }
#endif

                      // Consult the list of alreanative typedefs.
                         SgTypedefSeq* typedef_table = typedefType->get_typedefs();
                         ROSE_ASSERT(typedef_table != NULL);

#if DEBUG_PRIVATE_TYPE || 0
                         printf ("Looking at typedef typedefType = %p = %s = %s \n",typedefType,typedefType->class_name().c_str(),typedefType->unparseToString().c_str());
#endif

                         SgTypePtrList & typedefList = typedef_table->get_typedefs();

                         bool foundNonPrivateTypeAlias = false;
                         SgType* suitableTypeAlias = NULL;

                         int counter = 0;
                         SgTypePtrList::iterator i = typedefList.begin();
                         while (foundNonPrivateTypeAlias == false && i != typedefList.end())
                           {
                             ROSE_ASSERT(*i != NULL);
#if DEBUG_PRIVATE_TYPE || 0
                             printf ("Looking for suitable type alias (#%d): *i = %p = %s = %s \n",counter,*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
                             if (isPrivateType == false)
                                {
                                  suitableTypeAlias = *i;
                                  foundNonPrivateTypeAlias = true;
                                }

                          // foundNonPrivateTypeAlias = !isPrivateType;

                             i++;
                             counter++;
                           }
#if 0
                         printf ("foundNonPrivateTypeAlias = %s \n",foundNonPrivateTypeAlias ? "true" : "false");
#endif
                         if (foundNonPrivateTypeAlias == true)
                            {
                              ROSE_ASSERT(suitableTypeAlias != NULL);
#if DEBUG_PRIVATE_TYPE_TRANSFORMATION || 0
                              printf ("targetScope             = %p = %s \n",targetScope,targetScope->class_name().c_str());
                              printf ("typedefDeclarationScope = %p = %s \n",typedefDeclarationScope,typedefDeclarationScope->class_name().c_str());
                              targetScope->get_file_info()->display("targetScope: debug");
                              typedefDeclarationScope->get_file_info()->display("typedefDeclarationScope: debug");

                              printf ("Found private type to be replaced: typedefType       = %p = %s = %s \n",typedefType,typedefType->class_name().c_str(),typedefType->unparseToString().c_str());
                              printf ("Found suitable type alias:         suitableTypeAlias = %p = %s = %s \n",suitableTypeAlias,suitableTypeAlias->class_name().c_str(),suitableTypeAlias->unparseToString().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 ("Selecting alternative type to use for unparsing: \n");
                              printf ("--- were going to use: %s \n",templateArgument->unparseToString().c_str());
                              printf ("--- selecing instead : %s \n",suitableTypeAlias->unparseToString().c_str());
#endif

                           // TV (10/05/2018): (ROSE-1431) Traverse the chain of all associated template arguments (coming from the same EDG template argument)
                              SgTemplateArgument * templateArgument_it = templateArgument;
                              while (templateArgument_it->get_previous_instance() != NULL) {
                                templateArgument_it = templateArgument_it->get_previous_instance();
                              }
                              ROSE_ASSERT(templateArgument_it != NULL && templateArgument_it->get_previous_instance() == NULL);
                              do {
#if 0
                                   printf ("  Update templateArgument = %p\n", templateArgument);
#endif
                                   templateArgument_it->set_unparsable_type_alias(suitableTypeAlias);

                                // DQ (1/9/2017): Also set the return result from get_type() so that the name qualification will be handled correctly.
                                   templateArgument_it->set_type(suitableTypeAlias);

                                   templateArgument_it = templateArgument_it->get_next_instance();
                                 }
                              while (templateArgument_it != NULL);

                              ROSE_ASSERT(templateArgument_it == NULL);

// #if DEBUG_PRIVATE_TYPE_TRANSFORMATION
#if 0
                              string typedefType_typeName       = generate_string_name (typedefType,NULL);
                              printf ("typedefType_typeName size = %zu \n",typedefType_typeName.length());
                              printf ("typedefType_typeName       = %s \n",typedefType_typeName.c_str());

                              string suitableTypeAlias_typeName = generate_string_name (suitableTypeAlias,NULL);
                              printf ("suitableTypeAlias_typeName size = %zu \n",suitableTypeAlias_typeName.length());
                              printf ("suitableTypeAlias_typeName size = %s \n",suitableTypeAlias_typeName.c_str());

                              ROSE_ASSERT(suitableTypeAlias_typeName.length() < typedefType_typeName.length() * 100);
                              ROSE_ASSERT(suitableTypeAlias_typeName.length() < 40000);
#endif
                            }
                       }
                      else
                       {
#if DEBUG_PRIVATE_TYPE
                         printf ("Alternative types not searched for in nontypedef types (not implemented) \n");
#endif
#if 0
                         printf ("####### Alternative types not searched: templateArgumentType = %p = %s \n",templateArgumentType,templateArgumentType->class_name().c_str());
                         if (isSgModifierType(templateArgumentType) != NULL)
                            {
                              SgModifierType* modifierType = isSgModifierType(templateArgumentType);
                              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
                       }
                  }

               break;
             }

          default:
             {
#if DEBUG_PRIVATE_TYPE
               printf ("Ignoring non-type template arguments \n");
#endif
             }
        }

#if DEBUG_PRIVATE_TYPE
     printf ("Leaving contains_private_type(SgTemplateArgument*): templateArgument = %p = %s = %s \n",templateArgument,templateArgument->class_name().c_str(),templateArgument->unparseToString().c_str());
#endif

  // templateArgumentList.pop_back();
     templateArgumentSet.erase(templateArgument);

#if DEBUGGING_USING_RECURSIVE_DEPTH
     printf ("--- pop templateArgument = %p templateArgumentSet.size() = %zu \n",templateArgument,templateArgumentSet.size());
#endif

#if 0
     printf ("Leaving contains_private_type(SgTemplateArgument): templateArgument = %p returnValue = %s \n",templateArgument,returnValue ? "true" : "false");
#endif

     return returnValue;
   }
Example #2
0
void
FixupAstSymbolTables::visit ( SgNode* node )
   {
  // DQ (6/27/2005): Output the local symbol table from each scope.
  // printf ("node = %s \n",node->sage_class_name());

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

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

               scope->set_symbol_table(tempSymbolTable);

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

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

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

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

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


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

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

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

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

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

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

                         SgDeclarationStatement* declarationToFindInScope = NULL;

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

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

                         SgName name = classDeclaration->get_name();

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

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

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

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

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

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

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

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

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

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

                         break;
                       }

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

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

            // Increment iterator!
               i++;

            // Increment counter!
               idx++;
             }

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

               ROSE_ASSERT(associatedSymbolTable == symbolTable);

               associatedSymbolTable->remove(removeSymbol);

               printf ("Redundant symbol removed...from symbol table \n");
            // ROSE_ASSERT(false);
             }
#if 0
       // debugging
          symbolTable->print("In FixupAstSymbolTables::visit(): printing out the symbol tables");
#endif
        }
   }
Example #3
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++;
        }
   }