void CompassAnalyses::FunctionDefinitionPrototype::Traversal:: visit(SgNode* node) { SgDeclarationStatement *sgdecl = isSgDeclarationStatement(node); if( sgdecl != NULL ) { SgFunctionDeclaration *fd = isSgFunctionDeclaration(node); if( fd != NULL ) { if( sgdecl->get_firstNondefiningDeclaration() == NULL ) { output->addOutput( new CompassAnalyses::FunctionDefinitionPrototype::CheckerOutput( node, fd->get_name().getString().c_str() ) ); } } //if( fd != NULL ) } } //End of the visit function.
SynthesizedAttribute Traversal::evaluateSynthesizedAttribute ( SgNode* astNode, InheritedAttribute inheritedAttribute, SynthesizedAttributesList childAttributes ) { SynthesizedAttribute localResult; // printf ("evaluateSynthesizedAttribute(): astNode = %p = %s inheritedAttribute.isFirstFile = %s \n",astNode,astNode->class_name().c_str(),inheritedAttribute.isFirstFile ? "true" : "false"); // Accumulate any valid pointer to main on a child node and pass it to the local synthesized attribute. for (size_t i = 0; i < childAttributes.size(); i++) { if (childAttributes[i].main_function != NULL) { localResult.main_function = childAttributes[i].main_function; } } if (inheritedAttribute.isFirstFile == true) { SgGlobal* globalScope = isSgGlobal(astNode); if (globalScope != NULL) { // Gather all of the functions in global scope of the first file. vector<SgDeclarationStatement*> globalScopeDeclarationsToMove = globalScope->get_declarations(); inheritedAttribute.statements_from_first_file = globalScopeDeclarationsToMove; // printf ("evaluateSynthesizedAttribute(): Gather all of the functions in global scope of the first file inheritedAttribute.statements_from_first_file.size() = %zu \n",inheritedAttribute.statements_from_first_file.size()); // Erase the declarations in the global scope of the first file. globalScope->get_declarations().clear(); } SgDeclarationStatement* declarationStatement = isSgDeclarationStatement(astNode); if (declarationStatement != NULL && isSgGlobal(declarationStatement->get_parent()) != NULL) { // Mark as a transformation (recursively mark the whole subtree). // printf ("*** Mark as a transformation: declarationStatement = %p \n",declarationStatement); markAsTransformation(declarationStatement); if (declarationStatement->get_firstNondefiningDeclaration() != NULL) markAsTransformation(declarationStatement->get_firstNondefiningDeclaration()); } } else { SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(astNode); if (functionDeclaration != NULL && functionDeclaration->get_name() == "main") { // Save the pointer to the main function (in the second file). localResult.main_function = functionDeclaration; // printf ("Found the main function ...(saved pointer) inheritedAttribute.main_function = %p \n",localResult.main_function); } // printf ("evaluateSynthesizedAttribute(): localResult.main_function = %p \n",localResult.main_function); // Test for the selected insertion point in the 2nd file for the declarations gathered from the first file. SgGlobal* globalScope = isSgGlobal(astNode); if (globalScope != NULL && localResult.main_function != NULL) { printf ("evaluateSynthesizedAttribute(): Found the main function ...\n"); vector<SgDeclarationStatement*>::iterator i = find(globalScope->get_declarations().begin(),globalScope->get_declarations().end(),localResult.main_function); globalScope->get_declarations().insert(i,inheritedAttribute.statements_from_first_file.begin(),inheritedAttribute.statements_from_first_file.end()); #if 0 // Set the parents of each declaration to match the new location (avoids warning that might later be an error). for (size_t i = 0; i < inheritedAttribute.statements_from_first_file.size(); i++) { inheritedAttribute.statements_from_first_file[i]->set_parent(globalScope); } #endif } } return localResult; }
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 fixupAstDeclarationScope( SgNode* node ) { // This function was designed to fixup what I thought were inconsistancies in how the // defining and some non-defining declarations associated with friend declarations had // their scope set. I now know this this was not a problem, but it is helpful to enforce the // consistancy. It might also be useful to process declarations with scopes set to // namespace definitions, so that the namespace definition can be normalized to be // consistant across all of the different re-entrant namespace definitions. This is // possible within the new namespace support in ROSE. TimingPerformance timer ("Fixup declaration scopes:"); // This simplifies how the traversal is called! FixupAstDeclarationScope astFixupTraversal; // DQ (1/29/2007): This traversal now uses the memory pool (so that we will visit declaration hidden in types (e.g. SgClassType) // SgClassType::traverseMemoryPoolNodes(v); astFixupTraversal.traverseMemoryPool(); // Now process the map of sets of declarations. std::map<SgDeclarationStatement*,std::set<SgDeclarationStatement*>* > & mapOfSets = astFixupTraversal.mapOfSets; #if 0 printf ("In fixupAstDeclarationScope(): mapOfSets.size() = %" PRIuPTR " \n",mapOfSets.size()); #endif std::map<SgDeclarationStatement*,std::set<SgDeclarationStatement*>* >::iterator i = mapOfSets.begin(); while (i != mapOfSets.end()) { SgDeclarationStatement* firstNondefiningDeclaration = i->first; // DQ (3/2/2015): Added assertion. ROSE_ASSERT(firstNondefiningDeclaration != NULL); // DQ (3/2/2015): Added assertion. ROSE_ASSERT(firstNondefiningDeclaration->get_firstNondefiningDeclaration() != NULL); // DQ (3/2/2015): Make this assertion a warning: fails in outlining example seq7a_test2006_78.C. // ROSE_ASSERT(firstNondefiningDeclaration == firstNondefiningDeclaration->get_firstNondefiningDeclaration()); if (firstNondefiningDeclaration != firstNondefiningDeclaration->get_firstNondefiningDeclaration()) { printf ("WARNING: In fixupAstDeclarationScope(): firstNondefiningDeclaration != firstNondefiningDeclaration->get_firstNondefiningDeclaration() \n"); printf (" --- firstNondefiningDeclaration = %p = %s \n", firstNondefiningDeclaration,firstNondefiningDeclaration->class_name().c_str()); printf (" --- firstNondefiningDeclaration->get_firstNondefiningDeclaration() = %p = %s \n", firstNondefiningDeclaration->get_firstNondefiningDeclaration(),firstNondefiningDeclaration->get_firstNondefiningDeclaration()->class_name().c_str()); } SgScopeStatement* correctScope = firstNondefiningDeclaration->get_scope(); ROSE_ASSERT(correctScope != NULL); #if 0 printf ("In FixupAstDeclarationScope::visit(): node = %p = %s firstNondefiningDeclaration = %p correctScope = %p = %s \n",node,node->class_name().c_str(),firstNondefiningDeclaration,correctScope,correctScope->class_name().c_str()); #endif std::set<SgDeclarationStatement*>* declarationSet = i->second; ROSE_ASSERT(declarationSet != NULL); #if 0 printf ("In fixupAstDeclarationScope(): mapOfSets[%p]->size() = %" PRIuPTR " \n",firstNondefiningDeclaration,mapOfSets[firstNondefiningDeclaration]->size()); #endif std::set<SgDeclarationStatement*>::iterator j = declarationSet->begin(); while (j != declarationSet->end()) { SgScopeStatement* associatedScope = (*j)->get_scope(); ROSE_ASSERT(associatedScope != NULL); // DQ (6/11/2013): This is triggered by namespace definition scopes that are different // due to re-entrant namespace declarations. We should maybe fix this. // TV (7/22/13): This is also triggered when for global scope accross files. if (associatedScope != correctScope) { // DQ (1/30/2014): Cleaning up some output spew. if (SgProject::get_verbose() > 0) { mprintf ("WARNING: This is the wrong scope (declaration = %p = %s): associatedScope = %p = %s correctScope = %p = %s \n", *j,(*j)->class_name().c_str(),associatedScope,associatedScope->class_name().c_str(),correctScope,correctScope->class_name().c_str()); } #if 0 printf ("Make this an error for now! \n"); ROSE_ASSERT(false); #endif } j++; } i++; } #if 0 printf ("Leaving fixupAstDeclarationScope() node = %p = %s \n",node,node->class_name().c_str()); #endif }
void FixupAstDeclarationScope::visit ( SgNode* node ) { // DQ (6/11/2013): This corrects where EDG can set the scope of a friend declaration to be different from the defining declaration. // We need it to be a rule in ROSE that the scope of the declarations are consistant between defining and all non-defining declaration). #if 0 printf ("In FixupAstDeclarationScope::visit(node = %p = %s) \n",node,node->class_name().c_str()); #endif SgDeclarationStatement* declaration = isSgDeclarationStatement(node); if (declaration != NULL) { // SgDeclarationStatement* definingDeclaration = declaration->get_definingDeclaration(); SgDeclarationStatement* firstNondefiningDeclaration = declaration->get_firstNondefiningDeclaration(); // Note that these declarations don't follow the same rules (namely the get_firstNondefiningDeclaration() can be NULL). if ( isSgFunctionParameterList(node) != NULL || isSgVariableDefinition(node) != NULL) { #if 0 printf ("In FixupAstDeclarationScope::visit(): node = %p = %s firstNondefiningDeclaration = %p (skipping this processing) \n",node,node->class_name().c_str(),firstNondefiningDeclaration); #endif } else { // DQ (6/15/2013): The older tutorial examples demonstrate addition of new functions using older rules that allows // there to not be a non-defining declaration. We need to remove these tutrial example in favor of the AST builder // API to build functions that will follow the newer AST constistancy rules. Until we do this work in the tutorial // we can't inforce this below else the older tutorial examples (e.g. addFunctionDeclaration.C) will fail. So I will // allow this for now and output a warning when (firstNondefiningDeclaration == NULL). // ROSE_ASSERT(firstNondefiningDeclaration != NULL); if (firstNondefiningDeclaration == NULL) { printf ("WARNING: In FixupAstDeclarationScope::visit(): firstNondefiningDeclaration == NULL for case of node = %p = %s (allowed for tutorial example transformations only) \n",node,node->class_name().c_str()); } else { if (mapOfSets.find(firstNondefiningDeclaration) == mapOfSets.end()) { std::set<SgDeclarationStatement*>* new_empty_set = new std::set<SgDeclarationStatement*>(); ROSE_ASSERT(new_empty_set != NULL); #if 0 printf ("In FixupAstDeclarationScope::visit(): Adding a set of declarations to the mapOfSets: new_empty_set = %p \n",new_empty_set); #endif // DQ (3/2/2015): Added assertion. ROSE_ASSERT(firstNondefiningDeclaration != NULL); mapOfSets.insert(std::pair<SgDeclarationStatement*,std::set<SgDeclarationStatement*>*>(firstNondefiningDeclaration,new_empty_set)); } ROSE_ASSERT(mapOfSets.find(firstNondefiningDeclaration) != mapOfSets.end()); // DQ (3/2/2015): Added assertion. ROSE_ASSERT(declaration != NULL); #if 0 printf ("In FixupAstDeclarationScope::visit(): Adding a declaration = %p = %s to a specific set in the mapOfSets: mapOfSets[firstNondefiningDeclaration=%p] = %p \n", declaration,declaration->class_name().c_str(),firstNondefiningDeclaration,mapOfSets[firstNondefiningDeclaration]); printf (" --- declaration->get_firstNondefiningDeclaration() = %p \n",declaration->get_firstNondefiningDeclaration()); #endif // DQ (3/2/2015): Added assertion. // ROSE_ASSERT(declaration == declaration->get_firstNondefiningDeclaration()); // mapOfSets[firstNondefiningDeclaration]->insert(firstNondefiningDeclaration); mapOfSets[firstNondefiningDeclaration]->insert(declaration); } } } }