int main(int argc, char* argv[]) { SgProject* project = frontend(argc, argv); std::vector<SgIfStmt*> ifs = SageInterface::querySubTree<SgIfStmt>(project, V_SgIfStmt); BOOST_FOREACH(SgIfStmt* if_stmt, ifs) { if (SgExpression *se = isSgExprStatement(if_stmt->get_conditional())->get_expression()) { cout << "--->" << se->unparseToString() << "<---" << endl; Rose_STL_Container<SgNode*> variableList = NodeQuery::querySubTree(se, V_SgVarRefExp); for (Rose_STL_Container<SgNode*>::iterator i = variableList.begin(), end = variableList.end(); i != end; i++) { SgVarRefExp *varRef = isSgVarRefExp(*i); SgVariableSymbol *currSym = varRef->get_symbol(); cout << "Looking at: --|" << currSym->get_name().str() << "|--" << endl; SgDeclarationStatement *decl = currSym->get_declaration()->get_declaration(); cout << "declaration: " << decl->unparseToString() << endl; SgConstVolatileModifier cvm = decl->get_declarationModifier().get_typeModifier().get_constVolatileModifier(); bool constness = cvm.isConst(); cout << "constness via isConst(): " << constness << endl; cout << cvm.displayString() << endl; } } } return 0; }
// DQ (6/25/2011): Put the function definition into the source file (avoid function definitions in header files). // std::string operator()(SgNode* node) std::string AstDOTGenerationExtended_Defaults::NamedExtraNodeInfo::operator()(SgNode* node) { std::ostringstream ss; // add namespace name if (SgNamespaceDeclarationStatement* n = isSgNamespaceDeclarationStatement(node)) { ss << n->get_qualified_name().str() << "\\n"; } // add class name if (SgClassDeclaration* n = isSgClassDeclaration(node)) { ss << n->get_qualified_name().str() << "\\n"; } // add function name if (SgFunctionDeclaration* n = isSgFunctionDeclaration(node)) { ss << n->get_qualified_name().str() << "\\n"; } if (SgFunctionRefExp* n = isSgFunctionRefExp(node)) { SgFunctionDeclaration* decl = n->getAssociatedFunctionDeclaration(); if (decl) // it's null if through a function pointer { ss << decl->get_qualified_name().str() << "\\n"; } } // add variable name if (SgInitializedName* n = isSgInitializedName(node)) { ss << n->get_qualified_name().str() << "\\n"; } if (SgVarRefExp* n = isSgVarRefExp(node)) { SgVariableSymbol* sym = n->get_symbol(); ss << sym->get_name().getString() << "\\n"; } // add variable name if (SgVariableSymbol* n = isSgVariableSymbol(node)) { ss << n->get_name().str() << "\\n"; } return ss.str(); }
DOTSynthesizedAttribute AstDOTGeneration::evaluateSynthesizedAttribute(SgNode* node, DOTInheritedAttribute ia, SubTreeSynthesizedAttributes l) { SubTreeSynthesizedAttributes::iterator iter; ROSE_ASSERT(node); // printf ("AstDOTGeneration::evaluateSynthesizedAttribute(): node = %s \n",node->class_name().c_str()); // DQ (5/3/2006): Skip this IR node if it is specified as such in the inherited attribute if (ia.skipSubTree == true) { // I am unclear if I should return NULL or node as a parameter to DOTSynthesizedAttribute // Figured this out: if we return a valid pointer then we get a node in the DOT graph // (with just the pointer value as a label), where as if we return a DOTSynthesizedAttribute // with a NUL pointer then the node will NOT appear in the DOT graph. // return DOTSynthesizedAttribute(node); return DOTSynthesizedAttribute(NULL); } string nodeoption; if(AstTests::isProblematic(node)) { // cout << "problematic node found." << endl; nodeoption="color=\"orange\" "; } string nodelabel=string("\\n")+node->class_name(); // DQ (1/24/2009): Added support for output of isForward flag in the dot graph. SgDeclarationStatement* genericDeclaration = isSgDeclarationStatement(node); if (genericDeclaration != NULL) { // At the moment the mnemonic name is stored, but it could be computed in the // future from the kind and the tostring() function. string name = (genericDeclaration->isForward() == true) ? "isForward" : "!isForward"; ROSE_ASSERT(name.empty() == false); // DQ (3/20/2011): Added class names to the generated dot file graphs of the AST. SgClassDeclaration* classDeclaration = isSgClassDeclaration(genericDeclaration); if (classDeclaration != NULL) { nodelabel += string("\\n") + classDeclaration->get_name(); } // DQ (3/20/2011): Added function names to the generated dot file graphs of the AST. SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(genericDeclaration); if (functionDeclaration != NULL) { nodelabel += string("\\n") + functionDeclaration->get_name(); } nodelabel += string("\\n") + name; } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgInitializedName* initializedName = isSgInitializedName(node); if (initializedName != NULL) { nodelabel += string("\\n") + initializedName->get_name(); } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgIntVal* intValue = isSgIntVal(node); if (intValue != NULL) { nodelabel += string("\\n value = ") + StringUtility::numberToString(intValue->get_value()); } // DQ (4/6/2011): Added support for output of the name for SgInitializedName IR nodes. SgVarRefExp* varRefExp = isSgVarRefExp(node); if (varRefExp != NULL) { SgVariableSymbol* variableSymbol = varRefExp->get_symbol(); ROSE_ASSERT(variableSymbol != NULL); string name = variableSymbol->get_name(); nodelabel += string("\\n name = ") + name; } // DQ (1/19/2009): Added support for output of what specific instrcution this is in the dot graph. SgAsmInstruction* genericInstruction = isSgAsmInstruction(node); if (genericInstruction != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT // At the moment the mnemonic name is stored, but it could be computed in the // future from the kind and the tostring() function. #if 1 string unparsedInstruction = unparseInstruction(genericInstruction); string addressString = StringUtility::numberToString( (void*) genericInstruction->get_address() ); // string name = genericInstruction->get_mnemonic(); string name = unparsedInstruction + "\\n address: " + addressString; #else string name = unparsedInstruction + "\\n" + addressString; #endif ROSE_ASSERT(name.empty() == false); nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } SgAsmExpression* genericExpression = isSgAsmExpression(node); if (genericExpression != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT string name = unparseExpression(genericExpression, NULL, NULL); ROSE_ASSERT(name.empty() == false); nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } // DQ (10/29/2008): Added some support for additional output of internal names for specific IR nodes. // In generall there are long list of these IR nodes in the binary and this helps make some sense of // the lists (sections, symbols, etc.). SgAsmExecutableFileFormat* binaryFileFormatNode = isSgAsmExecutableFileFormat(node); if (binaryFileFormatNode != NULL) { #ifdef ROSE_BUILD_BINARY_ANALYSIS_SUPPORT // The case of binary file format IR nodes can be especially confusing so we want the // default to output some more specific information for some IR nodes (e.g. sections). string name; SgAsmGenericSection* genericSection = isSgAsmGenericSection(node); if (genericSection != NULL) { SgAsmGenericString* genericString = genericSection->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmGenericSymbol* genericSymbol = isSgAsmGenericSymbol(node); if (genericSymbol != NULL) { SgAsmGenericString* genericString = genericSymbol->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); if (name.empty() == true) name = "no_name_for_symbol"; } SgAsmGenericDLL* genericDLL = isSgAsmGenericDLL(node); if (genericDLL != NULL) { SgAsmGenericString* genericString = genericDLL->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmPEImportItem* peImportItem = isSgAsmPEImportItem(node); if (peImportItem != NULL) { SgAsmGenericString* genericString = peImportItem->get_name(); ROSE_ASSERT(genericString != NULL); name = genericString->get_string(); } SgAsmDwarfLine* asmDwarfLine = isSgAsmDwarfLine(node); if (asmDwarfLine != NULL) { char buffer[100]; // It does not work to embed the "\n" into the single sprintf parameter. // sprintf(buffer," Addr: 0x%08"PRIx64" \n line: %d col: %d ",asmDwarfLine->get_address(),asmDwarfLine->get_line(),asmDwarfLine->get_column()); sprintf(buffer,"Addr: 0x%08"PRIx64,asmDwarfLine->get_address()); name = buffer; sprintf(buffer,"line: %d col: %d",asmDwarfLine->get_line(),asmDwarfLine->get_column()); name += string("\\n") + buffer; } SgAsmDwarfConstruct* asmDwarfConstruct = isSgAsmDwarfConstruct(node); if (asmDwarfConstruct != NULL) { name = asmDwarfConstruct->get_name(); } #if 0 // This might not be the best way to implement this, since we want to detect common base classes of IR nodes. switch (node->variantT()) { case V_SgAsmElfSection: { SgAsmElfSection* n = isSgAsmElfSection(node); name = n->get_name(); break; } default: { // No additional information is suggested for the default case! } } #endif if (name.empty() == false) nodelabel += string("\\n") + name; #else printf ("Warning: In AstDOTGeneration.C ROSE_BUILD_BINARY_ANALYSIS_SUPPORT is not defined \n"); #endif } // DQ (11/29/2008): Output the directives in the label of the IR node. SgC_PreprocessorDirectiveStatement* preprocessorDirective = isSgC_PreprocessorDirectiveStatement(node); if (preprocessorDirective != NULL) { string s = preprocessorDirective->get_directiveString(); // Change any double quotes to single quotes so that DOT will not misunderstand the generated lables. while (s.find("\"") != string::npos) { s.replace(s.find("\""),1,"\'"); } if (s.empty() == false) nodelabel += string("\\n") + s; } nodelabel += additionalNodeInfo(node); // DQ (11/1/2003) added mechanism to add additional options (to add color, etc.) // nodeoption += additionalNodeOptions(node); string additionalOptions = additionalNodeOptions(node); // printf ("nodeoption = %s size() = %ld \n",nodeoption.c_str(),nodeoption.size()); // printf ("additionalOptions = %s size() = %ld \n",additionalOptions.c_str(),additionalOptions.size()); string x; string y; x += additionalOptions; nodeoption += additionalOptions; DOTSynthesizedAttribute d(0); // DQ (7/27/2008): Added mechanism to support pruning of AST bool commentoutNode = commentOutNodeInGraph(node); if (commentoutNode == true) { // DQ (11/10/2008): Fixed to only output message when (verbose_level > 0); command-line option. // DQ (7/27/2008): For now just return to test this mechanism, then we want to add comment "//" propoerly to generated DOT file. if (SgProject::get_verbose() > 0) { printf ("Skipping the use of this IR node in the DOT Graph \n"); } } else { // ************************** switch(traversal) { case TOPDOWNBOTTOMUP: dotrep.addNode(node,dotrep.traceFormat(ia.tdbuTracePos,tdbuTrace)+nodelabel,nodeoption); break; case PREORDER: case TOPDOWN: dotrep.addNode(node,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption); break; case POSTORDER: case BOTTOMUP: dotrep.addNode(node,dotrep.traceFormat(buTrace)+nodelabel,nodeoption); break; default: assert(false); } ++tdbuTrace; ++buTrace; // add edges or null values int testnum=0; for (iter = l.begin(); iter != l.end(); iter++) { string edgelabel = string(node->get_traversalSuccessorNamesContainer()[testnum]); string toErasePrefix = "p_"; if (AstTests::isPrefix(toErasePrefix,edgelabel)) { edgelabel.erase(0, toErasePrefix.size()); } if ( iter->node == NULL) { // SgNode* snode=node->get_traversalSuccessorContainer()[testnum]; AstSuccessorsSelectors::SuccessorsContainer c; AstSuccessorsSelectors::selectDefaultSuccessors(node,c); SgNode* snode=c[testnum]; // isDefault shows that the default constructor for synth attribute was used if (l[testnum].isDefault() && snode && (visitedNodes.find(snode) != visitedNodes.end()) ) { // handle bugs in SAGE dotrep.addEdge(node,edgelabel,snode,"dir=forward arrowhead=\"odot\" color=red "); } else { if (snode == NULL) { dotrep.addNullValue(node,"",edgelabel,""); } } } else { // DQ (3/5/2007) added mechanism to add additional options (to add color, etc.) string edgeoption = additionalEdgeOptions(node,iter->node,edgelabel); switch(traversal) { case TOPDOWNBOTTOMUP: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=both"); break; case PREORDER: case TOPDOWN: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=forward"); break; case POSTORDER: case BOTTOMUP: dotrep.addEdge(node,edgelabel,(*iter).node,edgeoption + "dir=back"); break; default: assert(false); } } testnum++; } // ************************** } // DQ (7/4/2008): Support for edges specified in AST attributes AstAttributeMechanism* astAttributeContainer = node->get_attributeMechanism(); if (astAttributeContainer != NULL) { // Loop over all the attributes at this IR node for (AstAttributeMechanism::iterator i = astAttributeContainer->begin(); i != astAttributeContainer->end(); i++) { // std::string name = i->first; AstAttribute* attribute = i->second; ROSE_ASSERT(attribute != NULL); // This can return a non-empty list in user-defined attributes (derived from AstAttribute). // printf ("Calling attribute->additionalNodeInfo() \n"); std::vector<AstAttribute::AttributeNodeInfo> nodeList = attribute->additionalNodeInfo(); // printf ("nodeList.size() = %lu \n",nodeList.size()); for (std::vector<AstAttribute::AttributeNodeInfo>::iterator i_node = nodeList.begin(); i_node != nodeList.end(); i_node++) { SgNode* nodePtr = i_node->nodePtr; string nodelabel = i_node->label; string nodeoption = i_node->options; // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding a node nodelabel = %s nodeoption = %s \n",nodelabel.c_str(),nodeoption.c_str()); // dotrep.addNode(NULL,dotrep.traceFormat(ia.tdTracePos)+nodelabel,nodeoption); dotrep.addNode( nodePtr, dotrep.traceFormat(ia.tdTracePos) + nodelabel, nodeoption ); } // printf ("Calling attribute->additionalEdgeInfo() \n"); std::vector<AstAttribute::AttributeEdgeInfo> edgeList = attribute->additionalEdgeInfo(); // printf ("edgeList.size() = %lu \n",edgeList.size()); for (std::vector<AstAttribute::AttributeEdgeInfo>::iterator i_edge = edgeList.begin(); i_edge != edgeList.end(); i_edge++) { string edgelabel = i_edge->label; string edgeoption = i_edge->options; // printf ("In AstDOTGeneration::evaluateSynthesizedAttribute(): Adding an edge from i_edge->fromNode = %p to i_edge->toNode = %p edgelabel = %s edgeoption = %s \n",i_edge->fromNode,i_edge->toNode,edgelabel.c_str(),edgeoption.c_str()); dotrep.addEdge(i_edge->fromNode,edgelabel,i_edge->toNode,edgeoption + "dir=forward"); } } } switch(node->variantT()) { // DQ (9/1/2008): Added case for output of SgProject rooted DOT file. // This allows source code and binary files to be combined into the same DOT file. case V_SgProject: { SgProject* project = dynamic_cast<SgProject*>(node); ROSE_ASSERT(project != NULL); string generatedProjectName = SageInterface::generateProjectName( project ); // printf ("generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str()); if (generatedProjectName.length() > 40) { // printf ("Warning: generatedProjectName (from SgProject) = %s \n",generatedProjectName.c_str()); generatedProjectName = "aggregatedFileNameTooLong"; printf ("Proposed (generated) filename is too long, shortened to: %s \n",generatedProjectName.c_str()); } string filename = string("./") + generatedProjectName + ".dot"; // printf ("generated filename for dot file (from SgProject) = %s \n",filename.c_str()); if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgProject IR node (filename = %s) \n",filename.c_str()); dotrep.writeToFileAsGraph(filename); break; } // case V_SgFile: case V_SgSourceFile: case V_SgBinaryComposite: { SgFile* file = dynamic_cast<SgFile*>(node); ROSE_ASSERT(file != NULL); string original_filename = file->getFileName(); // DQ (7/4/2008): Fix filenamePostfix to go before the "." // string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + "."+filenamePostfix+"dot"; string filename = string("./") + ROSE::stripPathFromFileName(original_filename) + filenamePostfix + ".dot"; // printf ("generated filename for dot file (from SgSourceFile or SgBinaryComposite) = %s file->get_parent() = %p \n",filename.c_str(),file->get_parent()); // printf ("file->get_parent() = %p \n",file->get_parent()); // cout << "generating DOT file (from SgSourceFile or SgBinaryComposite): " << filename2 << " ... "; // DQ (9/1/2008): this effects the output of DOT files when multiple files are specified // on the command line. A SgProject is still built even when a single file is specificed // on the command line, however there are cases where a SgFile can be built without a // SgProject and this case allows those SgFile rooted subtrees to be output as DOT files. // If there is a SgProject then output the dot file from there, else output as a SgFile. if (file->get_parent() == NULL) { // If there is no SgProject then output the file now! if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgFile IR node (no SgProject available) \n"); dotrep.writeToFileAsGraph(filename); } else { // There is a SgProject IR node, but if we will be traversing it we want to output the // graph then (so that the graph will include the SgProject IR nodes and connect multiple // files (SgSourceFile or SgBinaryComposite IR nodes). if ( visitedNodes.find(file->get_parent()) == visitedNodes.end() ) { // This SgProject node was not input as part of the traversal, // so we will not be traversing the SgProject IR nodes and we // have to output the graph now! if ( SgProject::get_verbose() >= 1 ) printf ("Output the DOT graph from the SgFile IR node (SgProject was not traversed) \n"); dotrep.writeToFileAsGraph(filename); } else { if ( SgProject::get_verbose() >= 1 ) printf ("Skip the output of the DOT graph from the SgFile IR node (SgProject will be traversed) \n"); } } // cout << "done." << endl; break; } // DQ (7/23/2005): Implemented default case to avoid g++ warnings // about enum values not handled by this switch default: { // nothing to do here break; } } d.node = node; return d; }
ExprSynAttr *examineExpr(SgExpression *expr, ostream &out) { stringstream ss1; stringstream ss2; stringstream ss3; SgExpression *e1; SgExpression *e2; SgBinaryOp *binop; SgUnaryOp *unaryop; SgType *type; ExprSynAttr *ret; ExprSynAttr *attr1, *attr2; string tmp_name; string tmp_type; string tmp2_name; string tmp2_type; if (expr == NULL) return NULL; ret = new ExprSynAttr(); attr1 = NULL; attr2 = NULL; switch(expr->variantT()) { /* Begin UnaryOp */ case V_SgMinusOp: out << "(-"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= -" << attr1->result_var; ret->code << ";" << endl; break; case V_SgUnaryAddOp: out << "(+"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= +" << attr1->result_var; ret->code << ";" << endl; break; case V_SgNotOp: out << "(!"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= (int)!" << attr1->result_var; ret->code << ";" << endl; break; case V_SgPointerDerefExp: out << "(*"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->basetype(attr1); ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= *" << attr1->result_var; ret->code << ";" << endl; break; case V_SgAddressOfOp: out << "(&"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type + "*"; /* FIXME ret->sgtype */ ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= &" << attr1->result_var; ret->code << ";" << endl; break; case V_SgMinusMinusOp: unaryop = isSgUnaryOp(expr); if (unaryop->get_mode()) { out << "("; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << "--)"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl; ret->code << attr1->result_var << "=" << attr1->result_var << "-1;" << endl; } else { out << "(--"; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->result_var = attr1->result_var; ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << "-1;" << endl; } break; case V_SgPlusPlusOp: unaryop = isSgUnaryOp(expr); if (unaryop->get_mode()) { out << "("; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << "++)"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << ";" << endl; ret->code << attr1->result_var << "=" << attr1->result_var << "+1;" << endl; } else { out << "(++"; e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->result_var = attr1->result_var; ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "=" << attr1->result_var << "+1;" << endl; } break; case V_SgBitComplementOp: out << "(~"; unaryop = isSgUnaryOp(expr); e1 = unaryop->get_operand(); attr1 = examineExpr(e1, out); out << ")"; ret->type = attr1->type; ret->sgtype = attr1->sgtype; ret->new_tmp_name(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->union_tmp_decls(attr1); ret->code << attr1->code.str(); ret->code << ret->result_var << "= ~" << attr1->result_var; ret->code << ";" << endl; break; case V_SgCastExp: { out << "("; SgCastExp *castexp = isSgCastExp(expr); e1 = castexp->get_operand(); type = castexp->get_type(); examineType(type, out); out << ")"; attr1 = examineExpr(e1, out); stringstream casts; examineType(type, casts); ret->type = casts.str(); ret->sgtype = type; ret->new_tmp_name(tmp_name); ret->union_tmp_decls(attr1, NULL); ret->add_new_tmp_decl(ret->type, tmp_name); ret->result_var = tmp_name; ret->code << attr1->code.str() << tmp_name; ret->code << "=(" << ret->type << ")" << attr1->result_var; ret->code << ";" << endl; break; } /* End UnaryOp */ /* Begin BinaryOp */ case V_SgEqualityOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "=="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "=="); break; case V_SgLessThanOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<"; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "<"); break; case V_SgGreaterThanOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">"; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, ">"); break; case V_SgNotEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "!="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "!="); break; case V_SgLessOrEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, "<="); break; case V_SgGreaterOrEqualOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">="; attr2 = examineExpr(e2, out); out << ")"; ret->type = "int"; ret->sgtype = attr1->sgtype; binop_noassign(ret, attr1, attr2, ">="); break; case V_SgAddOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "+"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "+"); break; case V_SgSubtractOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "-"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "-"); break; case V_SgMultiplyOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "*"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "*"); break; case V_SgDivideOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "/"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "/"); break; case V_SgIntegerDivideOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "/"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "/"); break; case V_SgModOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "%"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "%"); break; case V_SgAndOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "&&"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); ret->type = "int"; binop_noassign(ret, attr1, attr2, "&&"); break; case V_SgOrOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "||"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); ret->type = "int"; binop_noassign(ret, attr1, attr2, "||"); break; case V_SgBitXorOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "^"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "^"); break; case V_SgBitAndOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "&"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "&"); break; case V_SgBitOrOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "|"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "|"); break; case V_SgCommaOpExp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ","; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, ","); break; case V_SgLshiftOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "<<"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, "<<"); break; case V_SgRshiftOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << ">>"; attr2 = examineExpr(e2, out); out << ")"; ret->cast_type(attr1, attr2); binop_noassign(ret, attr1, attr2, ">>"); break; case V_SgAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret->union_tmp_decls(attr1, attr2); ret->result_var = attr1->result_var; ret->code << attr2->code.str() << attr1->code.str() << ret->result_var; ret->code << "=" << attr2->result_var; ret->code << ";" << endl; break; case V_SgPlusAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "+="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "+"); break; case V_SgMinusAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "-="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "-"); break; case V_SgAndAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "&="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "&"); break; case V_SgIorAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "|="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "|"); break; case V_SgMultAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "*="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "*"); break; case V_SgDivAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "/="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "/"); break; case V_SgModAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "%="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "%"); break; case V_SgXorAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "^="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "^"); break; case V_SgLshiftAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "<<="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, "<<"); break; case V_SgRshiftAssignOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << ">>="; attr2 = examineExpr(e2, out); ret->cast_type(attr1, attr2); ret = binop_assign(ret, attr1, attr2, ">>"); break; case V_SgExponentiationOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "ExpUnknown"; attr2 = examineExpr(e2, out); out << ")"; break; case V_SgConcatenationOp: binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); out << "("; attr1 = examineExpr(e1, out); out << "CatUnknown"; attr2 = examineExpr(e2, out); out << ")"; break; case V_SgPntrArrRefExp: { binop = isSgBinaryOp(expr); e1 = binop->get_lhs_operand(); e2 = binop->get_rhs_operand(); attr1 = examineExpr(e1, out); out << "["; attr2 = examineExpr(e2, out); out << "]"; ret->basetype(attr1); ret->union_tmp_decls(attr1, attr2); ret->result_var = attr1->result_var + "[" + attr2->result_var + "]"; ret->code << attr1->code.str() << attr2->code.str(); break; } /* End BinaryOp */ /* Begin variables */ case V_SgVarRefExp: { stringstream casts; SgVarRefExp *varref = isSgVarRefExp(expr); if (NULL == varref) return NULL; SgVariableSymbol *svsym = varref->get_symbol(); if (NULL == svsym) return NULL; out << svsym->get_name().getString(); ret->result_var = svsym->get_name().getString(); examineType(svsym->get_type(), casts); ret->type = casts.str(); ret->sgtype = svsym->get_type(); /* ret->new_tmp_name(); examineType(svsym->get_type(), casts); ret->type = casts.str(); ret->sgtype = svsym->get_type(); ret->add_new_tmp_decl(ret->type, ret->result_var); ret->code << ret->result_var << " = " << svsym->get_name().getString(); ret->code << ";" << endl; */ break; } case V_SgLabelRefExp: SgLabelRefExp *labref = isSgLabelRefExp(expr); out << labref->get_name().getString(); break; /* Begin Constants */ case V_SgIntVal: { stringstream casts; SgIntVal *intval = isSgIntVal(expr); out << intval->get_value(); casts << intval->get_value(); ret->result_var = casts.str(); ret->type = "int"; ret->sgtype = intval->get_type(); break; } case V_SgLongIntVal: { stringstream casts; SgLongIntVal *longval = isSgLongIntVal(expr); out << longval->get_value() << "L"; casts << longval->get_value() << "L"; ret->result_var = casts.str(); ret->type = "long"; ret->sgtype = longval->get_type(); break; } case V_SgUnsignedIntVal: { stringstream casts; SgUnsignedIntVal *uintval = isSgUnsignedIntVal(expr); out << uintval->get_value() << "U"; casts << uintval->get_value() << "U"; ret->result_var = casts.str(); ret->type = "unsigned"; ret->sgtype = uintval->get_type(); break; } case V_SgUnsignedLongVal: { stringstream casts; SgUnsignedLongVal *ulongval = isSgUnsignedLongVal(expr); out << ulongval->get_value() << "UL"; casts << ulongval->get_value() << "UL"; ret->result_var = casts.str(); ret->type = "unsigned long"; ret->sgtype = ulongval->get_type(); break; } case V_SgDoubleVal: { stringstream casts; SgDoubleVal *doubleval = isSgDoubleVal(expr); out << doubleval->get_value(); casts << doubleval->get_value(); ret->result_var = casts.str(); ret->type = "double"; ret->sgtype = doubleval->get_type(); break; } case V_SgFloatVal: { stringstream casts; SgFloatVal *floatval = isSgFloatVal(expr); out << floatval->get_value(); casts << floatval->get_value(); ret->result_var = casts.str(); ret->type = "float"; ret->sgtype = floatval->get_type(); break; } default: out << "/* UNKNOWN EXPR[" << expr->class_name() << "](" << expr->variantT() << ") " << expr->unparseToString() << " */" << endl; cerr << "UNKNOWN EXPR[" << expr->class_name() << "] " << expr->unparseToString() << endl; break; } if (NULL != attr1) delete attr1; if (NULL != attr2) delete attr2; return ret; }