int main(int argc, char* argv[]) { SgProject* proj = frontend(argc,argv); SgFunctionDeclaration* mainDecl = SageInterface::findMain(proj); SgFunctionDefinition* mainDef = mainDecl->get_definition(); // std::vector<SgNode*> dotExps = NodeQuery::querySubTree(mainDef, V_SgDotExp); std::vector<SgNode*> varRefs = NodeQuery::querySubTree(mainDef,V_SgVarRefExp); int classExps = 0; for (unsigned int i = 0; i < varRefs.size(); i++) { if (isSgClassType(isSgVarRefExp(varRefs[i])->get_type())) { SgClassType* ct = isSgClassType(isSgVarRefExp(varRefs[i])->get_type()); std::cout << "name of ref: " << isSgVarRefExp(varRefs[i])->get_symbol()->get_name().getString() << std::endl; if (SageInterface::isStructType(ct)) { SgDeclarationStatement* decl = isSgType(ct)->getAssociatedDeclaration(); SgDeclarationStatement* defining_decl = decl->get_definingDeclaration(); if (!(defining_decl->isNameOnly())) { if (isSgClassDeclaration(defining_decl)) { if (isSgClassDeclaration(defining_decl)->get_definition()) { SgDeclarationStatementPtrList member_stats = isSgClassDeclaration(defining_decl)->get_definition()->get_members(); SgDeclarationStatementPtrList::iterator j = member_stats.begin(); for (; j != member_stats.end(); j++) { SgDeclarationStatement* d = isSgDeclarationStatement(*j); std::cout << "decl stat name: " << d->class_name() << std::endl; SgInitializedNamePtrList init_lst = isSgVariableDeclaration(d)->get_variables(); SgInitializedNamePtrList::iterator k = init_lst.begin(); std::cout << "variables in initialized name ptr list..." << std::endl; for (; k != init_lst.end(); k++) { std::cout << isSgInitializedName(*k)->get_name().getString() << std::endl; std::cout << isSgInitializedName(*k)->get_type()->class_name() << std::endl; } } classExps+=1; } } } } } } std::cout << "num class_exp: " << classExps << std::endl; return 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 } }
bool ReplacementMapTraversal::verifyODR( SgNode* node, SgNode* duplicateNodeFromOriginalAST ) { bool passesODR = false; // printf ("Verify that node = %p is equivalent to duplicateNodeFromOriginalAST = %p = %s \n",node,duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str()); // Verify that these strings match ROSE_ASSERT (duplicateNodeFromOriginalAST->variantT() == node->variantT()); ROSE_ASSERT (duplicateNodeFromOriginalAST->class_name() == node->class_name()); // ROSE_ASSERT (generateUniqueName(duplicateNodeFromOriginalAST) == generateUniqueName(node)); string nodeString; string duplicateNodeFromOriginalASTstring; #if 0 // DQ (2/3/2007): This is a test to debug the ODR checking. // I think that the unparser has some state specific to the output of access protections. // if the unparsing changes the state then the access permission (public, protected, private) // is output and this cause a falue trigger to the ODR string match. This is a temp fix to // absorbe any change of state, but we need a mechanism to clear the state in the unparser. string absorbeUnparserStateChange_A = node->unparseToString(); string absorbeUnparserStateChange_B = duplicateNodeFromOriginalAST->unparseToString(); #endif #if 0 // DQ (2/3/2007): Make sure that there are close to being related. It appears that if these are if (node->get_parent()->variantT() == duplicateNodeFromOriginalAST->get_parent()->variantT()) { nodeString = node->unparseToString(); duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString(); } #endif bool skip_ODR_test = false; bool nodeIsCompilerGenerated = (node->get_file_info() != NULL) ? node->get_file_info()->isCompilerGenerated() : false; bool duplicateNodeFromOriginalASTIsCompilerGenerated = (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isCompilerGenerated() : false; bool nodeIsFrontendSpecific = (node->get_file_info() != NULL) ? node->get_file_info()->isFrontendSpecific() : false; bool duplicateNodeFromOriginalASTIsFrontendSpecific = (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isFrontendSpecific() : false; // If this is a template declaration for a function then it might have been a part of another template declaration // for the template class and thus might not exist explicitly in the AST (and thus not have enough information from // which to generate a meaningful mangled name). Skip ODR testing of these cases. bool isTemplateMemberFunctionInTemplatedClass = false; SgTemplateDeclaration* templateDeclaration = isSgTemplateDeclaration(node); if (templateDeclaration != NULL) { SgTemplateDeclaration* dup_templateDeclaration = isSgTemplateDeclaration(duplicateNodeFromOriginalAST); ROSE_ASSERT(dup_templateDeclaration != NULL); if ( templateDeclaration->get_string().is_null() && dup_templateDeclaration->get_string().is_null() ) { isTemplateMemberFunctionInTemplatedClass = true; } } if (isTemplateMemberFunctionInTemplatedClass == true) { printf ("ODR not tested isTemplateMemberFunctionInTemplatedClass == true. \n"); skip_ODR_test = true; } if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true || nodeIsCompilerGenerated == true || duplicateNodeFromOriginalASTIsCompilerGenerated == true) { // printf ("ODR not tested for frontend specific compiler generated code. \n"); skip_ODR_test = true; } // DQ (1/20/2007): The unparse will not generate a string if the code is frontend specific or compiler generated (I forget which). // if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true) if (skip_ODR_test == true) { // printf ("ODR not tested for frontend specific compiler generated code. \n"); passesODR = true; } else { SgUnparse_Info info_a; SgUnparse_Info info_b; // DQ (2/6/2007): Force qualified names to be used uniformally (note that info.set_requiresGlobalNameQualification() // causes an error) info.set_requiresGlobalNameQualification(); info_a.set_forceQualifiedNames(); info_b.set_forceQualifiedNames(); nodeString = node->unparseToString(&info_a); // DQ (2/6/2007): The SgUnparse_Info object carries state which controls the use of access qualification and the // first call to unparseToString might have set the access (e.g. to "public") and the second call would drop the // access qualification. We unset the access qualification state in the SgUnparse_Info object so that both will // be unparsed the same (we could have alternatively used two separate SgUnparse_Info objects. // info.set_isUnsetAccess(); duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString(&info_b); passesODR = (nodeString == duplicateNodeFromOriginalASTstring); } // Don't count the cases where the unparse fails to to invalid parent in redundant SgClassDeclaration (fix these later) if (passesODR == false && nodeString.empty() == false && duplicateNodeFromOriginalASTstring.empty() == false) { #if 1 if (SgProject::get_verbose() > 0) printf ("##### In ReplacementMapTraversal::verifyODR() is false: node = %p = %s duplicateNodeFromOriginalAST = %p = %s \n", node,node->class_name().c_str(),duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str()); // printf ("##### passesODR = %s \n",passesODR ? "true" : "false"); // printf ("duplicateNodeFromOriginalASTstring = \n---> %s\n",duplicateNodeFromOriginalASTstring.c_str()); // printf ("nodeString = \n---> %s\n",nodeString.c_str()); if (node->get_file_info() != NULL && duplicateNodeFromOriginalAST->get_file_info() != NULL) { if (SgProject::get_verbose() > 0) { SgNode* parent_node = node->get_parent(); // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code. ROSE_ASSERT(parent_node != NULL); printf ("parent_node = %p = %s = %s \n",parent_node,parent_node->class_name().c_str(),SageInterface::get_name(parent_node).c_str()); SgNode* parent_dup = duplicateNodeFromOriginalAST->get_parent(); // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code. ROSE_ASSERT(parent_dup != NULL); printf ("parent_dup = %p = %s = %s \n",parent_dup,parent_dup->class_name().c_str(),SageInterface::get_name(parent_dup).c_str()); printf ("\nPosition of error: \n"); node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug"); duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug"); printf ("\nPosition of error: \n"); printf ("\nPosition of error (parent IR node): \n"); parent_node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_node) is false: debug"); parent_dup->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_dup) is false: debug"); printf ("\nPosition of error (parent IR node): \n"); } } else { SgClassType* classType = isSgClassType(node); SgClassType* duplicateNodeFromOriginalAST_classType = isSgClassType(duplicateNodeFromOriginalAST); if (classType != NULL) { if (SgProject::get_verbose() > 0) { SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration()); ROSE_ASSERT(classDeclaration != NULL); classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (classType)"); printf ("classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n", classDeclaration, classDeclaration->get_definingDeclaration(), classDeclaration->get_firstNondefiningDeclaration()); ROSE_ASSERT(duplicateNodeFromOriginalAST_classType != NULL); SgClassDeclaration* duplicateNodeFromOriginalAST_classDeclaration = isSgClassDeclaration(duplicateNodeFromOriginalAST_classType->get_declaration()); ROSE_ASSERT(duplicateNodeFromOriginalAST_classDeclaration != NULL); duplicateNodeFromOriginalAST_classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (duplicateNodeFromOriginalAST_classType)"); printf ("duplicateNodeFromOriginalAST_classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n", duplicateNodeFromOriginalAST_classDeclaration, duplicateNodeFromOriginalAST_classDeclaration->get_definingDeclaration(), duplicateNodeFromOriginalAST_classDeclaration->get_firstNondefiningDeclaration()); } } } #endif odrViolations.push_back(pair<SgNode*,SgNode*>(node,duplicateNodeFromOriginalAST)); } #if 0 printf ("duplicateNodeFromOriginalASTstring = %p = %s \n---> %s\n", duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),duplicateNodeFromOriginalASTstring.c_str()); printf ("nodeString = %p = %s \n---> %s\n", node,node->class_name().c_str(),nodeString.c_str()); #endif #if 0 SgClassType* original = isSgClassType(duplicateNodeFromOriginalAST); SgClassType* target = isSgClassType(node); if (original != NULL && target != NULL) { printf ("original declaration = %p \n",original->get_declaration()); printf ("target declaration = %p \n",target->get_declaration()); } #endif #if 1 if (passesODR == false) { if (SgProject::get_verbose() > 0) { string node_generatedName = SageInterface::generateUniqueName(node,false); string originalNode_generatedName = SageInterface::generateUniqueName(duplicateNodeFromOriginalAST,false); printf ("ODR Violation Source code: nodeString = \n%s\n \n",nodeString.c_str()); printf ("ODR Violation Source code: duplicateNodeFromOriginalASTstring = \n%s\n \n",duplicateNodeFromOriginalASTstring.c_str()); printf ("nodeString = %s \n",nodeString.c_str()); printf ("node_generatedName = %s \n",node_generatedName.c_str()); printf ("originalNode_generatedName = %s \n",originalNode_generatedName.c_str()); printf ("node = %p = %s = %s \n",node,node->class_name().c_str(),SageInterface::get_name(node).c_str()); printf ("duplicateNodeFromOriginalAST = %p = %s = %s \n",duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),SageInterface::get_name(duplicateNodeFromOriginalAST).c_str()); printf ("node (unique string) = %s \n",generateUniqueName(node,true).c_str()); printf ("duplicateNodeFromOriginalAST (unique string) = %s \n",generateUniqueName(duplicateNodeFromOriginalAST,true).c_str()); SgDeclarationStatement* declarationStatement = isSgDeclarationStatement(node); if (declarationStatement != NULL) { printf ("declarationStatement->get_definingDeclaration() = %p \n",declarationStatement->get_definingDeclaration()); printf ("declarationStatement->get_firstNondefiningDeclaration() = %p \n",declarationStatement->get_firstNondefiningDeclaration()); } SgDeclarationStatement* declarationStatement2 = isSgDeclarationStatement(duplicateNodeFromOriginalAST); if (declarationStatement2 != NULL) { printf ("declarationStatement2->get_definingDeclaration() = %p \n",declarationStatement2->get_definingDeclaration()); printf ("declarationStatement2->get_firstNondefiningDeclaration() = %p \n",declarationStatement2->get_firstNondefiningDeclaration()); } printf ("Source code positions of ORD violation: \n"); node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug"); duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug"); } } #endif // ROSE_ASSERT(nodeString == duplicateNodeFromOriginalASTstring); ROSE_ASSERT(passesODR == true); return passesODR; }
// void FixupTemplateArguments::visit ( SgNode* node ) void FixupTemplateArguments::processTemplateArgument ( SgTemplateArgument* templateArgument, SgScopeStatement* targetScope ) { // ROSE_ASSERT(node != NULL); ROSE_ASSERT(templateArgument != NULL); #if DEBUGGING_USING_RECURSIVE_DEPTH // For debugging, keep track of the recursive depth. printf ("In FixupTemplateArguments::visit: global_depth = %zu \n",global_depth); ROSE_ASSERT(global_depth < 50); #endif // DQ (2/11/2017): Change this traversal to not use memory pools. // SgTemplateArgument* templateArgument = isSgTemplateArgument(node); ROSE_ASSERT(templateArgument != NULL); #if DEBUGGING_USING_RECURSIVE_DEPTH global_depth++; #endif bool result = contains_private_type(templateArgument,targetScope); #if DEBUGGING_USING_RECURSIVE_DEPTH global_depth--; #endif if (result == true) { // This type will be a problem to unparse, because it contains parts that are private (or protected). #if DEBUG_VISIT_PRIVATE_TYPE printf ("\n\nWARNING: This template parameter can NOT be unparsed (contains references to private types): templateArgument = %p = %s \n",templateArgument,templateArgument->unparseToString().c_str()); SgNode* parent = templateArgument->get_parent(); SgDeclarationStatement* parentDeclaration = isSgDeclarationStatement(parent); if (parentDeclaration != NULL) { if (parentDeclaration->get_file_info() != NULL) { #if 0 parentDeclaration->get_file_info()->display("location of parent non-defining declaration using templateArgument: debug"); SgDeclarationStatement* parentDefiningDeclaration = isSgDeclarationStatement(parentDeclaration->get_definingDeclaration()); if (parentDefiningDeclaration != NULL) { parentDefiningDeclaration->get_file_info()->display("location of parent defining declaration using templateArgument: debug"); } #endif } } else { if (parent->get_file_info() != NULL) { #if 0 parent->get_file_info()->display("location of parent node using templateArgument: debug"); #endif } } #endif } else { // This type is fine to unparse #if DEBUG_PRIVATE_TYPE printf ("Template parameter CAN be unparsed (no private types) \n\n"); #endif } }