void DetectHiddenOriginalExpressionTreeTraversal::visit ( SgNode* node ) { // We only want to search for original expression trees where they can be hidden. ROSE_ASSERT(node != NULL); SgArrayType* arrayType = isSgArrayType(node); if (arrayType != NULL) { #if 0 printf ("Found an array type arrayType = %p (looking for original expression tree) \n",arrayType); #endif SgExpression* index = arrayType->get_index(); if (index != NULL) { DetectOriginalExpressionTreeTraversal t; t.traverse(index,preorder); } } #if 0 // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression. SgVariableDefinition* variableDefinition = isSgVariableDefinition(node); if (variableDefinition != NULL) { #if 0 printf ("Found a SgVariableDefinition (looking for original expression tree) \n"); #endif SgExpression* bitfieldExp = variableDefinition->get_bitfield(); if (bitfieldExp != NULL) { DetectOriginalExpressionTreeTraversal t; t.traverse(bitfieldExp,preorder); } } #endif }
bool ClangToSageTranslator::VisitFieldDecl(clang::FieldDecl * field_decl, SgNode ** node) { #if DEBUG_VISIT_DECL std::cerr << "ClangToSageTranslator::VisitFieldDecl" << std::endl; #endif bool res = true; SgName name(field_decl->getNameAsString()); SgType * type = buildTypeFromQualifiedType(field_decl->getType()); clang::Expr * init_expr = field_decl->getInClassInitializer(); SgNode * tmp_init = Traverse(init_expr); SgExpression * expr = isSgExpression(tmp_init); // TODO expression list if aggregated initializer ! if (tmp_init != NULL && expr == NULL) { std::cerr << "Runtime error: not a SgInitializer..." << std::endl; res = false; } SgInitializer * init = expr != NULL ? SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type()) : NULL; if (init != NULL) applySourceRange(init, init_expr->getSourceRange()); // Cannot use 'SageBuilder::buildVariableDeclaration' because of anonymous field // *node = SageBuilder::buildVariableDeclaration(name, type, init, SageBuilder::topScopeStack()); // Build it by hand... SgVariableDeclaration * var_decl = new SgVariableDeclaration(name, type, init); if (isSgClassType(type)) { std::map<SgClassType *, bool>::iterator bool_it = p_class_type_decl_first_see_in_type.find(isSgClassType(type)); ROSE_ASSERT(bool_it != p_class_type_decl_first_see_in_type.end()); if (bool_it->second) { var_decl->set_baseTypeDefiningDeclaration(isSgNamedType(type)->get_declaration()->get_definingDeclaration()); var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } else if (isSgEnumType(type)) { std::map<SgEnumType *, bool>::iterator bool_it = p_enum_type_decl_first_see_in_type.find(isSgEnumType(type)); ROSE_ASSERT(bool_it != p_enum_type_decl_first_see_in_type.end()); if (bool_it->second) { var_decl->set_baseTypeDefiningDeclaration(isSgEnumType(type)->get_declaration()->get_definingDeclaration()); var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } var_decl->set_firstNondefiningDeclaration(var_decl); var_decl->set_parent(SageBuilder::topScopeStack()); ROSE_ASSERT(var_decl->get_variables().size() == 1); SgInitializedName * init_name = var_decl->get_variables()[0]; ROSE_ASSERT(init_name != NULL); init_name->set_scope(SageBuilder::topScopeStack()); applySourceRange(init_name, field_decl->getSourceRange()); SgVariableDefinition * var_def = isSgVariableDefinition(init_name->get_declptr()); ROSE_ASSERT(var_def != NULL); applySourceRange(var_def, field_decl->getSourceRange()); SgVariableSymbol * var_symbol = new SgVariableSymbol(init_name); SageBuilder::topScopeStack()->insert_symbol(name, var_symbol); *node = var_decl; return VisitDeclaratorDecl(field_decl, node) && res; }
bool ClangToSageTranslator::VisitVarDecl(clang::VarDecl * var_decl, SgNode ** node) { #if DEBUG_VISIT_DECL std::cerr << "ClangToSageTranslator::VisitVarDecl" << std::endl; #endif bool res = true; // Create the SAGE node: SgVariableDeclaration SgName name(var_decl->getNameAsString()); SgType * type = buildTypeFromQualifiedType(var_decl->getType()); clang::Expr * init_expr = var_decl->getInit(); SgNode * tmp_init = Traverse(init_expr); SgExpression * expr = isSgExpression(tmp_init); if (tmp_init != NULL && expr == NULL) { std::cerr << "Runtime error: not a SgInitializer..." << std::endl; // TODO res = false; } SgExprListExp * expr_list_expr = isSgExprListExp(expr); SgInitializer * init = NULL; if (expr_list_expr != NULL) init = SageBuilder::buildAggregateInitializer(expr_list_expr, type); else if (expr != NULL) init = SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type()); if (init != NULL) applySourceRange(init, init_expr->getSourceRange()); SgVariableDeclaration * sg_var_decl = new SgVariableDeclaration(name, type, init); // scope: obtain from the scope stack. if (isSgClassType(type)) { std::map<SgClassType *, bool>::iterator bool_it = p_class_type_decl_first_see_in_type.find(isSgClassType(type)); ROSE_ASSERT(bool_it != p_class_type_decl_first_see_in_type.end()); if (bool_it->second) { sg_var_decl->set_baseTypeDefiningDeclaration(isSgNamedType(type)->get_declaration()->get_definingDeclaration()); sg_var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } else if (isSgEnumType(type)) { std::map<SgEnumType *, bool>::iterator bool_it = p_enum_type_decl_first_see_in_type.find(isSgEnumType(type)); ROSE_ASSERT(bool_it != p_enum_type_decl_first_see_in_type.end()); if (bool_it->second) { sg_var_decl->set_baseTypeDefiningDeclaration(isSgEnumType(type)->get_declaration()->get_definingDeclaration()); sg_var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } sg_var_decl->set_firstNondefiningDeclaration(sg_var_decl); sg_var_decl->set_parent(SageBuilder::topScopeStack()); ROSE_ASSERT(sg_var_decl->get_variables().size() == 1); SgInitializedName * init_name = sg_var_decl->get_variables()[0]; ROSE_ASSERT(init_name != NULL); init_name->set_scope(SageBuilder::topScopeStack()); applySourceRange(init_name, var_decl->getSourceRange()); SgVariableDefinition * var_def = isSgVariableDefinition(init_name->get_declptr()); ROSE_ASSERT(var_def != NULL); applySourceRange(var_def, var_decl->getSourceRange()); SgVariableSymbol * var_symbol = new SgVariableSymbol(init_name); SageBuilder::topScopeStack()->insert_symbol(name, var_symbol); *node = sg_var_decl; return VisitDeclaratorDecl(var_decl, node) && res; }
void VerifyOriginalExpressionTreesSetToNull::visit ( SgNode* node ) { // This traversal is used to verify that all of the original expression trees in the AST have // been either deleted (optional) or used to replace the constant folded values (the default // for the ROSE AST so that we can preserve the greatest amount of source-to-source detail). // Note that it can detect problems that are due to orphaned expressions in the AST. // An example is test2011_138.C where the multidimensional array indexing causes and orphaned // expression to be created and it has a original expression tree. Since the orphaned expression // can't be reached we can eliminate the original expression tree. The bug in ROSE is that there // is an orphaned expression tree not that there is a remaining original expression tree. // We need a mechanism to detect nodes that exist in the AST and are not pointed to by any other // IR node (and then we have to decide if parent pointers count). ROSE_ASSERT(node != NULL); // printf ("In VerifyOriginalExpressionTreesSetToNull::visit(): node = %s \n",node->class_name().c_str()); SgExpression* exp = isSgExpression(node); if (exp != NULL) { SgExpression* originalExpressionTree = exp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION printf ("Error: there is a valid originalExpressionTree = %p = %s on node = %p = %s \n",originalExpressionTree,originalExpressionTree->class_name().c_str(),exp,exp->class_name().c_str()); #endif } #if 0 // Liao debugging 11/13/2012 ROSE_ASSERT(originalExpressionTree == NULL); #endif // Allow us to ignore the cases of originalExpressionTrees hidden in array types. // I want to narrow down the failing tests codes to eliminate this case which is handled separately. if (originalExpressionTree != NULL) { #if 0 SgNode* parent = exp; // Note that test2011_121.C fails to be either a SgArrayType or a SgVariableDefinition (failing in some part of "complex" header file). // test2005_203.C demonstrates the use of constant folding in bitfield specifications. // while (parent != NULL && isSgArrayType(parent) == NULL) while (parent != NULL && isSgArrayType(parent) == NULL && isSgVariableDefinition(parent) == NULL) { parent = parent->get_parent(); } if (isSgArrayType(parent) == NULL) { printf ("So what is the parent: parent = %p = %s \n",parent, (parent != NULL) ? parent->class_name().c_str() : "NULL"); } ROSE_ASSERT(isSgArrayType(parent) != NULL || isSgVariableDefinition(parent) != NULL); #else #ifdef ROSE_DEBUG_NEW_EDG_ROSE_CONNECTION printf ("In VerifyOriginalExpressionTreesSetToNull(): originalExpressionTree = %p = %s on node = %p = %s Ingoring originalExpressionTree != NULL \n", originalExpressionTree,originalExpressionTree->class_name().c_str(),exp,exp->class_name().c_str()); #endif #endif } } }
void RemoveConstantFoldedValueViaParent::visit ( SgNode* node ) { // This is an alternative implementation that allows us to handle expression that are not // traversed in the AST (e.g. types like SgArrayType which can contain expressions). ROSE_ASSERT(node != NULL); // DQ (3/11/2006): Set NULL pointers where we would like to have none. #if 0 printf ("In RemoveConstantFoldedValueViaParent::visit(): node = %p = %s \n",node,node->class_name().c_str()); #endif // DQ (10/12/2012): Turn this on so that we can detect failing IR nodes (failing later) that have valid originalExpressionTrees. // DQ (10/12/2012): Turn this back off because it appears to fail... #if 0 SgExpression* exp = isSgExpression(node); if (exp != NULL) { SgExpression* originalExpressionTree = exp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { SgNode* parent = exp->get_parent(); if (parent != NULL) { printf ("Current IR node with SgExpression parent = %p = %s child = %p = %s originalExpressionTree = %p = %s \n",parent,parent->class_name().c_str(),node,node->class_name().c_str(),originalExpressionTree,originalExpressionTree->class_name().c_str()); bool traceReplacement = true; ConstantFoldedValueReplacer r(traceReplacement, exp); parent->processDataMemberReferenceToPointers(&r); // node->processDataMemberReferenceToPointers(&r); } // Set the originalExpressionTree to NULL. exp->set_originalExpressionTree(NULL); // Set the parent of originalExpressionTree to be the parent of exp. originalExpressionTree->set_parent(parent); // And then delete the folded constant. SageInterface::deleteAST(exp); } } #endif SgArrayType* arrayType = isSgArrayType(node); if (arrayType != NULL) { #if 0 printf ("Found an array type arrayType = %p arrayType->get_index() = %p \n",arrayType,arrayType->get_index()); #endif SgExpression* index = arrayType->get_index(); if (index != NULL) { #if 0 printf ("Fixup array index = %p = %s (traverse index AST subtree) \n",index,index->class_name().c_str()); #endif RemoveConstantFoldedValue astFixupTraversal; astFixupTraversal.traverse(index); #if 0 printf ("DONE: Fixup array index = %p (traverse index AST) \n\n\n\n",index); #endif #if 0 printf ("Found an array index = %p (fixup index directly) \n",index); #endif // Handle the case where the original expression tree is at the root of the subtree. SgExpression* originalExpressionTree = index->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 printf ("Found an originalExpressionTree in the array index originalExpressionTree = %p \n",originalExpressionTree); #endif // DQ (6/12/2013): This appears to be a problem in EDG 4.7 (see test2011_117.C). std::vector<SgExpression*> redundantChainOfOriginalExpressionTrees; if (originalExpressionTree->get_originalExpressionTree() != NULL) { #if 0 printf ("Detected originalExpressionTree nested directly within the originalExpressionTree \n", originalExpressionTree,originalExpressionTree->class_name().c_str(), originalExpressionTree->get_originalExpressionTree(),originalExpressionTree->get_originalExpressionTree()->class_name().c_str()); #endif // Loop to the end of the chain of original expressions (which EDG 4.7 should never have constructed). while (originalExpressionTree->get_originalExpressionTree() != NULL) { #if 0 printf ("Looping through a chain of originalExpressionTrees \n"); #endif // Save the list of redundnat nodes so that we can delete them properly. redundantChainOfOriginalExpressionTrees.push_back(originalExpressionTree); originalExpressionTree = originalExpressionTree->get_originalExpressionTree(); } #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } arrayType->set_index(originalExpressionTree); originalExpressionTree->set_parent(arrayType); index->set_originalExpressionTree(NULL); // printf ("DEBUGING: skip delete of index in array type \n"); delete index; // DQ (6/12/2013): Delete the nodes that we had to skip over (caused by chain of redundant entries from EDG 4.7). std::vector<SgExpression*>::iterator i = redundantChainOfOriginalExpressionTrees.begin(); while (i != redundantChainOfOriginalExpressionTrees.end()) { #if 0 printf ("deleting the redundnat originalExpressionTree chain caused by EDG 4.7 (delete %p = %s) \n",*i,(*i)->class_name().c_str()); #endif delete *i; i++; } index = NULL; } } } SgVariableDefinition* variableDefinition = isSgVariableDefinition(node); if (variableDefinition != NULL) { #if 0 printf ("Found a SgVariableDefinition \n"); #endif SgExpression* bitfieldExp = variableDefinition->get_bitfield(); if (bitfieldExp != NULL) { #if 0 printf ("Fixup bitfieldExp = %p (traverse bitfieldExp AST subtree) \n",bitfieldExp); #endif RemoveConstantFoldedValue astFixupTraversal; astFixupTraversal.traverse(bitfieldExp); // Handle the case where the original expression tree is at the root of the subtree. SgExpression* originalExpressionTree = bitfieldExp->get_originalExpressionTree(); if (originalExpressionTree != NULL) { #if 0 // DQ (9/18/2011): This code will not work since the bitfile data member in SgVariableDefinition is a SgUnsignedLongVal instead of a SgExpression. variableDefinition->set_bitfield(originalExpressionTree); originalExpressionTree->set_parent(variableDefinition); bitfieldExp->set_originalExpressionTree(NULL); delete bitfieldExp; bitfieldExp = NULL; #else // The ROSE AST needs to be fixed to handle more general expressions for bitfield widths (this does not effect the CFG). // TODO: Change the data type of the bitfield data member in SgVariableDefinition. // DQ (1/20/2014): This has been done now. // printf ("Member data bitfield widths need to be changed (in the ROSE IR) to support more general expressions (can't fix this original expression tree) \n"); #endif #if 0 // This case is not handled yet! printf ("Found an original expression tree in a bitfield expression \n"); ROSE_ASSERT(false); #endif } } } }
int main(int argc, char **argv) { SgProject *project = frontend(argc, argv); // Instantiate a class hierarchy wrapper. ClassHierarchyWrapper classHierarchy( project ); std::list<SgNode *> nodes2 = NodeQuery::querySubTree(project, V_SgVariableDefinition); for (std::list<SgNode *>::iterator it = nodes2.begin(); it != nodes2.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgVariableDefinition *varDefn = isSgVariableDefinition(n); ROSE_ASSERT(varDefn != NULL); std::cout << "Var defn: " << varDefn->unparseToCompleteString() << std::endl; } std::list<SgNode *> nodes1 = NodeQuery::querySubTree(project, V_SgVariableDeclaration); for (std::list<SgNode *>::iterator it = nodes1.begin(); it != nodes1.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgVariableDeclaration *varDecl = isSgVariableDeclaration(n); ROSE_ASSERT(varDecl != NULL); SgInitializedNamePtrList &variables = varDecl->get_variables(); SgInitializedNamePtrList::iterator varIter; for (varIter = variables.begin(); varIter != variables.end(); ++varIter) { SgNode *var = *varIter; ROSE_ASSERT(var != NULL); SgInitializedName *initName = isSgInitializedName(var); ROSE_ASSERT(initName != NULL); if ( isSgClassType(initName->get_type()) ) { SgClassType *classType = isSgClassType(initName->get_type()); ROSE_ASSERT(classType != NULL); SgDeclarationStatement *declStmt = classType->get_declaration(); ROSE_ASSERT(declStmt != NULL); SgClassDeclaration *classDeclaration = isSgClassDeclaration(declStmt); ROSE_ASSERT(classDeclaration != NULL); // std::cout << "From var decl got: " << classDeclaration->unparseToCompleteString() << std::endl; SgClassDefinition *classDefinition = classDeclaration->get_definition(); if ( classDefinition != NULL ) { std::cout << "From var decl got: " << classDefinition->unparseToCompleteString() << std::endl; } } } } std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgClassDeclaration); for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgClassDeclaration *classDeclaration1 = isSgClassDeclaration(n); ROSE_ASSERT(classDeclaration1 != NULL); SgDeclarationStatement *definingDecl = classDeclaration1->get_definingDeclaration(); if ( definingDecl == NULL ) continue; SgClassDeclaration *classDeclaration = isSgClassDeclaration(definingDecl); ROSE_ASSERT(classDeclaration != NULL); SgClassDefinition *classDefinition = classDeclaration->get_definition(); ROSE_ASSERT(classDefinition != NULL); std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl; SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; } } #if 0 #if 0 std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgClassDefinition); for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgClassDefinition *classDefinition = isSgClassDefinition(n); ROSE_ASSERT(classDefinition != NULL); std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl; SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; } } #else // Collect all function/method invocations. std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgFunctionCallExp); unsigned int numCallSites = 0; unsigned int numMonomorphicCallSites = 0; unsigned int numPossibleResolutions = 0; // Visit each call site. for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgFunctionCallExp *functionCallExp = isSgFunctionCallExp(n); ROSE_ASSERT(functionCallExp != NULL); // We are only interested in examining method invocations. bool isDotExp = false; if ( !isMethodCall(functionCallExp, isDotExp) ) continue; numCallSites++; // Certainly can be resolved to the static method. numPossibleResolutions++; if ( isDotExp ) { // If this is a dot expression (i.e., a.foo()), we can // statically determine its type. numMonomorphicCallSites++; continue; } // Retrieve the static function declaration. SgFunctionDeclaration *functionDeclaration = getFunctionDeclaration(functionCallExp); // Ensure it is actually a method declaration. SgMemberFunctionDeclaration *memberFunctionDeclaration = isSgMemberFunctionDeclaration(functionDeclaration); ROSE_ASSERT(memberFunctionDeclaration != NULL); unsigned int numOverridesForMethod = 0; if ( ( isVirtual(functionDeclaration) ) || ( isDeclaredVirtualWithinAncestor(functionDeclaration) ) ) { SgClassDefinition *classDefinition = isSgClassDefinition(memberFunctionDeclaration->get_scope()); ROSE_ASSERT(classDefinition != NULL); SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; // Iterate over all of the methods defined in this subclass. SgDeclarationStatementPtrList &decls = subclass->get_members(); for (SgDeclarationStatementPtrList::iterator declIter = decls.begin(); declIter != decls.end(); ++declIter) { SgDeclarationStatement *declStmt = *declIter; ROSE_ASSERT(declStmt != NULL); SgMemberFunctionDeclaration *method = isSgMemberFunctionDeclaration(declStmt); if ( method == NULL ) { continue; } // Determine whether subclass of the class defining this // method overrides the method. if ( methodOverridesVirtualMethod(method, memberFunctionDeclaration) ) { numOverridesForMethod++; } } } if ( numOverridesForMethod == 0 ) numMonomorphicCallSites++; numPossibleResolutions += numOverridesForMethod; std::cout << "Method invocation has " << numOverridesForMethod + 1 << " possible resolutions " << std::endl; std::cout << functionCallExp->unparseToCompleteString() << std::endl; } } #endif #endif return 0; }