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! } } }
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++; } }