SynthesizedAttribute Traversal::evaluateSynthesizedAttribute ( SgNode* astNode, InheritedAttribute inheritedAttribute, SynthesizedAttributesList childAttributes ) { if (inheritedAttribute == false) { // The inherited attribute is false, i.e. we are not inside any // function, so there can be no loops here. return false; } else { // Fold up the list of child attributes using logical or, i.e. the local // result will be true iff one of the child attributes is true. SynthesizedAttribute localResult = std::accumulate(childAttributes.begin(), childAttributes.end(), false, std::logical_or<bool>()); if (isSgFunctionDefinition(astNode) && localResult == true) { printf ("Found a function containing a for loop ...\n"); } if (isSgForStatement(astNode)) { localResult = true; } return localResult; } }
SynthesizedAttribute Traversal::evaluateSynthesizedAttribute ( SgNode* astNode, InheritedAttribute inheritedAttribute, SynthesizedAttributesList childAttributes ) { SynthesizedAttribute result; #if 1 // Accumulate the names in the children into the names at the parent (current node). SynthesizedAttributesList::iterator i; for (i = childAttributes.begin(); i != childAttributes.end(); ++i) { vector<NameStructureType>::iterator n; for (n = i->nameList.begin(); n != i->nameList.end(); ++n) { result.nameList.push_back(*n); } } #endif if (isSgScopeStatement(astNode) != NULL) { // Now process the collected names. processNames(astNode, result); } else { processNode(astNode,result); } return result; }
// must pass low_ids from children to parents to accumulate. ids do // not need to be passed because they are an accumulative attribute. pair<long, long> TreeSerializer:: defaultSynthesizedAttribute(Tree* node, Tree* inh, SynthesizedAttributesList& synl) { // compute node's low_id long low_id = -1; int nChildren = 0; for (SynthesizedAttributesList::iterator sa_itr = synl.begin(); sa_itr!=synl.end(); ++sa_itr) { if ( (*sa_itr).second>=0 ) { // valid low_id if ( nChildren==0 ) low_id = (*sa_itr).second; else low_id = min(low_id, (*sa_itr).second); nChildren++; } } // These skipped nodes do not store ids or low_ids to save time and space. if ( nChildren<=0 ) return pair<long, long>(-1, -1); // return invalid ids and invalid low_ids; else return pair<long, long>(-1, low_id); // return invalid ids and valid low_ids accumulated from children. }
std::string evaluateSynthesizedAttribute(SgNode *node, SynthesizedAttributesList synAttributes) { std::string result = ""; SynthesizedAttributesList::iterator s; for (s = synAttributes.begin(); s != synAttributes.end(); ++s) { std::string &str = *s; result += str; if (str.size() > 0 && str[str.size()-1] != '\n') result += "\n"; } return result; }
SynthesizedAttribute visitorTraversal::evaluateSynthesizedAttribute ( SgNode* n, SynthesizedAttributesList childAttributes ) { // Fold up the list of child attributes using logical or, i.e. the local // result will be true iff one of the child attributes is true. SynthesizedAttribute localResult = std::accumulate(childAttributes.begin(), childAttributes.end(), false, std::logical_or<bool>()); if (isSgForStatement(n) != NULL) { printf ("Found a for loop ... \n"); localResult = true; } return localResult; }
PrefixSynthesizedAttribute PrefixSuffixGenerationTraversal::evaluateSynthesizedAttribute ( SgNode* astNode, PrefixInheritedAttribute inputInheritedAttribute, SynthesizedAttributesList inputSynthesizedAttributeList ) { #if 0 printf ("@@@ In evaluateSynthesizedAttribute: astNode = %s \n",astNode->sage_class_name()); printf (" inputSynthesizedAttributeList.size() = %zu \n",inputSynthesizedAttributeList.size()); #endif return PrefixSynthesizedAttribute(); }
// Skipped nodes are not linked into the Sq-Tree. We can use the fact to improve performance. pair<long, long> RelevantNoAtomicParent_TreeSerializer:: defaultSynthesizedAttribute(Tree* node, Tree* inh, SynthesizedAttributesList& synl) { // want to assign each node a unique id, even if the node is // skippable, to make is_tree_in_subtree logically clearer. long low_id = id; // ids always valid for this case. for (SynthesizedAttributesList::iterator sa_itr = synl.begin(); sa_itr!=synl.end(); ++sa_itr) { low_id = min(low_id, (*sa_itr).second); } #ifdef outputnodeids fprintf(stdout, "Skipped tree node type = %d, #tokens = %d, id = %d, low_id = %d\n", node->type, node->terminal_number, id, low_id); #endif node->attributes.insert(pair<NodeAttributeName_t, pair<long, long>*>(NODE_ID, new pair<long, long>(id, low_id))); id++; return pair<long, long>(id-1, low_id); }
SynthesizedAttribute visitorTraversal::evaluateSynthesizedAttribute ( SgNode* n, SynthesizedAttributesList childAttributes ) { SynthesizedAttribute localResult; // printf ("In evaluateSynthesizedAttribute(n = %p = %s) \n",n,n->class_name().c_str()); // Build the list from children (in reverse order to preserve the final ordering) for (SynthesizedAttributesList::reverse_iterator child = childAttributes.rbegin(); child != childAttributes.rend(); child++) { localResult.accumulatedList.splice(localResult.accumulatedList.begin(),child->accumulatedList); } // Add in the information from the current node SgLocatedNode* locatedNode = isSgLocatedNode(n); if (locatedNode != NULL) { AttachedPreprocessingInfoType* commentsAndDirectives = locatedNode->getAttachedPreprocessingInfo(); if (commentsAndDirectives != NULL) { // printf ("Found attached comments (to IR node at %p of type: %s): \n",locatedNode,locatedNode->class_name().c_str()); // int counter = 0; // Use a reverse iterator so that we preserve the order when using push_front to add each directive to the accumulatedList AttachedPreprocessingInfoType::reverse_iterator i; for (i = commentsAndDirectives->rbegin(); i != commentsAndDirectives->rend(); i++) { // The different classifications of comments and directives are in ROSE/src/frontend/SageIII/rose_attributes_list.h if ((*i)->getTypeOfDirective() == PreprocessingInfo::CpreprocessorDefineDeclaration) { #if 0 printf (" Attached Comment #%d in file %s (relativePosition=%s): classification %s :\n%s\n", counter++,(*i)->get_file_info()->get_filenameString().c_str(), ((*i)->getRelativePosition() == PreprocessingInfo::before) ? "before" : "after", PreprocessingInfo::directiveTypeName((*i)->getTypeOfDirective()).c_str(), (*i)->getString().c_str()); #endif // use push_front() to end up with source ordering of final list of directives localResult.accumulatedList.push_front(*i); } } } } // printf ("localResult after adding current node info \n"); // localResult.display(); return localResult; }
AstNodePtrSynAttr AstNodePtrs::evaluateSynthesizedAttribute(SgNode* node,SynthesizedAttributesList l) { ROSE_ASSERT(node); ROSE_ASSERT(node->variantT()<V_SgNumVariants); string s=string(node->sage_class_name())+"("; bool nullValueExists=false; for(SynthesizedAttributesList::iterator i=l.begin(); i!=l.end();i++) { if((*i).node==NULL) { nullValueExists=true; s+=", NULL"; } else { s+=string(", ")+(*i).node->sage_class_name(); } } s+=")"; //if(nullValueExists) { // cout << s << endl; // if(SgDotExp* dotNode=dynamic_cast<SgDotExp*>(node)) { // cout << "AST TEST: SgDotExp(" << dotNode->get_lhs_operand_i() << ", " << dotNode->get_rhs_operand_i() << ") found." << endl; // } //} // provide a list of node pointers for some simple operations on the AST AstNodePointersList pl; for(SynthesizedAttributesList::iterator i=l.begin(); i!=l.end();i++) { SgNode* np=(*i).node; pl.push_back(np); } visitWithAstNodePointersList(node,pl); AstNodePtrSynAttr syn; syn.node=node; return syn; }
pair<long, long> TreeSerializer:: evaluateSynthesizedAttribute(Tree* node, Tree* in, SynthesizedAttributesList& synl) { // establish serialized tree chains: if ( previous_node!=NULL ) { map<NodeAttributeName_t, void*>::iterator attr_itr = previous_node->attributes.find(NODE_SERIALIZED_NEIGHBOR); assert( attr_itr!=previous_node->attributes.end() ); ((pair<Tree*, Tree*>*)(*attr_itr).second)->second = node; node->attributes.insert(pair<NodeAttributeName_t, pair<Tree*, Tree*>*>(NODE_SERIALIZED_NEIGHBOR, new pair<Tree*, Tree*>(previous_node, NULL))); } else { // its the first visited node: serialized_tree.chain_header = node; node->attributes.insert(pair<NodeAttributeName_t, pair<Tree*, Tree*>*>(NODE_SERIALIZED_NEIGHBOR, new pair<Tree*, Tree*>(NULL, NULL))); } previous_node = node; serialized_tree.chain_tail = node; // compute node id and its low_id long low_id = id; // It's the id of the current node. for (SynthesizedAttributesList::iterator sa_itr = synl.begin(); sa_itr!=synl.end(); ++sa_itr) { if ( (*sa_itr).first>=0 ) // valid id and low_id low_id = min(low_id, (*sa_itr).second); } #ifdef outputnodeids fprintf(stdout, "Tree node type = %d(%s), #tokens = %d, id = %d, low_id = %d, value=%s\n", node->type, node->terminal_number, id, low_id, node->toTerminal()?node->toTerminal()->value->c_str():"<NULL>"); #endif node->attributes.insert(pair<NodeAttributeName_t, pair<long, long>*>(NODE_ID, new pair<long, long>(id, low_id))); id2node.insert(pair<long, Tree*>(id, node)); id++; return pair<long, long>(id-1, low_id); }
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; }
ChildUses DefsAndUsesTraversal::evaluateSynthesizedAttribute(SgNode* node, SynthesizedAttributesList attrs) { if (StaticSingleAssignment::getDebug()) { cout << "---------<" << node->class_name() << node << ">-------" << node << endl; } //We want to propagate the def/use information up from the varRefs to the higher expressions. if (SgInitializedName * initName = isSgInitializedName(node)) { VarUniqueName * uName = StaticSingleAssignment::getUniqueName(node); ROSE_ASSERT(uName); //Add this as a def, unless this initialized name is a preinitialization of a parent class. For example, //in the base of B : A(3) { ... } where A is a superclass of B, an initialized name for A appears. //Clearly, the initialized name for the parent class is not a real variable if (initName->get_preinitialization() != SgInitializedName::e_virtual_base_class && initName->get_preinitialization() != SgInitializedName::e_nonvirtual_base_class) { ssa->getOriginalDefTable()[node].insert(uName->getKey()); if (StaticSingleAssignment::getDebug()) { cout << "Defined " << uName->getNameString() << endl; } } return ChildUses(); } //Variable references are where all uses originate else if (isSgVarRefExp(node)) { //Get the unique name of the def. VarUniqueName * uName = StaticSingleAssignment::getUniqueName(node); //In some cases, a varRef isn't actually part of a variable name. For example, //foo().x where foo returns a structure. x is an SgVarRefExp, but is not part of a variable name. if (uName == NULL) { return ChildUses(); } //Add this as a use. If it's not a use (e.g. target of an assignment), we'll fix it up later. ssa->getLocalUsesTable()[node].insert(uName->getKey()); if (StaticSingleAssignment::getDebug()) { cout << "Found use for " << uName->getNameString() << " at " << node->cfgForBeginning().toStringForDebugging() << endl; } //This varref is both the only use in the subtree and the current variable return ChildUses(node, isSgVarRefExp(node)); } //Catch all types of Binary Operations else if (SgBinaryOp * binaryOp = isSgBinaryOp(node)) { ROSE_ASSERT(attrs.size() == 2 && "Error: BinaryOp without exactly 2 children."); ChildUses& lhs = attrs[0]; ChildUses& rhs = attrs[1]; //If we have an assigning operation, we want to list everything on the LHS as being defined //Otherwise, everything is being used. vector<SgNode*> uses; switch (binaryOp->variantT()) { //All the binary ops that define the LHS case V_SgAndAssignOp: case V_SgDivAssignOp: case V_SgIorAssignOp: case V_SgLshiftAssignOp: case V_SgMinusAssignOp: case V_SgModAssignOp: case V_SgMultAssignOp: case V_SgPlusAssignOp: case V_SgPointerAssignOp: case V_SgRshiftAssignOp: case V_SgXorAssignOp: case V_SgAssignOp: { //All the uses from the RHS are propagated uses.insert(uses.end(), rhs.getUses().begin(), rhs.getUses().end()); //All the uses from the LHS are propagated, unless we're an assign op uses.insert(uses.end(), lhs.getUses().begin(), lhs.getUses().end()); SgVarRefExp* currentVar = lhs.getCurrentVar(); if (currentVar != NULL) { vector<SgNode*>::iterator currVarUse = find(uses.begin(), uses.end(), currentVar); //An assign op doesn't use the var it's defining. So, remove that var from the uses if (isSgAssignOp(binaryOp)) { if (currVarUse != uses.end()) { uses.erase(currVarUse); } //Also remove the use from the varRef node, because it's not really a use. ssa->getLocalUsesTable()[currentVar].clear(); } //All the other ops always use the var they're defining (+=, -=, /=, etc) else { if (currVarUse == uses.end()) { uses.push_back(currentVar); } } } //Set all the uses as being used at this node addUsesToNode(binaryOp, uses); //Set the current var as being defined here //It's possible that the LHS has no variable references. For example, //foo() = 3, where foo() returns a reference if (currentVar != NULL) { addDefForVarAtNode(currentVar, binaryOp); } return ChildUses(uses, currentVar); } //Otherwise cover all the non-defining Ops default: { //We want to set all the varRefs as being used here std::vector<SgNode*> uses; uses.insert(uses.end(), lhs.getUses().begin(), lhs.getUses().end()); uses.insert(uses.end(), rhs.getUses().begin(), rhs.getUses().end()); //Set all the uses as being used here. addUsesToNode(binaryOp, uses); //Propagate the current variable up. The rhs variable is the one that could be potentially defined up the tree return ChildUses(uses, rhs.getCurrentVar()); } } } //Catch all unary operations here. else if (isSgUnaryOp(node)) { SgUnaryOp* unaryOp = isSgUnaryOp(node); //Now handle the uses. All unary operators use everything in their operand std::vector<SgNode*> uses; if (isSgAddressOfOp(unaryOp) && isSgPointerMemberType(unaryOp->get_type())) { //SgAddressOfOp is special; it's not always a use of its operand. When creating a reference to a member variable, //we create reference without providing a variable instance. For example, // struct foo { int bar; }; // // void test() // { // int foo::*v = &foo::bar; <---- There is no use of foo.bar on this line // foo b; // b.*v = 3; // } //In this case, there are no uses in the operand. We also want to delete any uses for the children vector<SgNode*> successors = SageInterface::querySubTree<SgNode > (unaryOp); foreach(SgNode* successor, successors) { ssa->getLocalUsesTable()[successor].clear(); } } else { //Guard against unary ops that have no children (exception rethrow statement) if (attrs.size() > 0)
InterleaveAcrossArraysCheckSynthesizedAttributeType interleaveAcrossArraysCheck::evaluateSynthesizedAttribute ( SgNode* n, SynthesizedAttributesList childAttributes ) { //cout << " Node: " << n->unparseToString() << endl; InterleaveAcrossArraysCheckSynthesizedAttributeType localResult; for (SynthesizedAttributesList::reverse_iterator child = childAttributes.rbegin(); child != childAttributes.rend(); child++) { InterleaveAcrossArraysCheckSynthesizedAttributeType childResult = *child; localResult.isArrayRef |= childResult.isArrayRef; localResult.isFunctionRefExp |= childResult.isFunctionRefExp; } if(isSgVariableDeclaration(n)) { SgVariableDeclaration* varDecl = isSgVariableDeclaration(n); SgInitializedNamePtrList & varList = varDecl->get_variables(); for(SgInitializedNamePtrList::iterator initIter = varList.begin(); initIter!=varList.end() ; initIter++) { SgInitializedName* var = *initIter; ROSE_ASSERT(var!=NULL); SgType *variableType = var->get_type(); ROSE_ASSERT (variableType != NULL); string type = TransformationSupport::getTypeName(variableType); string variableName = var->get_name().str(); //Case 6 if(outputName == variableName) { cout << " ERROR: Substituting Array " << outputName << " already declared in the file." << endl; ROSE_ABORT(); } if(type!="doubleArray" && type !="floatArray" && type!="intArray") return localResult; #if DEBUG cout << " Var Name: " << variableName << " Type: " << type << endl; #endif storeArrayReference(var, variableName, type ); } } else if(isSgPntrArrRefExp(n)) { SgVarRefExp* varRefExp = isSgVarRefExp(isSgPntrArrRefExp(n)->get_lhs_operand()); if(varRefExp != NULL) { SgVariableSymbol* variableSymbol = varRefExp->get_symbol(); ROSE_ASSERT (variableSymbol != NULL); SgInitializedName* initializedName = variableSymbol->get_declaration(); ROSE_ASSERT (initializedName != NULL); string variableName = initializedName->get_name().str(); SgType* type = variableSymbol->get_type(); ROSE_ASSERT (type != NULL); string typeName = TransformationSupport::getTypeName(type); // A++ Supported Arrays if(typeName !="doubleArray" && typeName !="floatArray" && typeName !="intArray") return localResult; // Check if variableName matches the input list if(transformation->containsInput(variableName)) localResult.isArrayRef = true; } } else if(isSgFunctionCallExp(n)) { // Case 1 // Check for array being present in function Call if(localResult.isFunctionRefExp && localResult.isArrayRef) { cout << " ERROR: Array Reference present in a function call " << endl; ROSE_ABORT(); } } else if(isSgFunctionRefExp(n)) { localResult.isFunctionRefExp = true; } else if(isSgStatement(n)) { //Case 2 if(isContigousDecl) { cout << " ERROR: Array Declaration are not contigous. " << endl; ROSE_ABORT(); } } return localResult; }