SgClassDeclaration* buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope) { // This function builds a class declaration and definition // (both the defining and nondefining declarations as required). // Build a file info object marked as a transformation Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode(); assert(fileInfo != NULL); // This is the class definition (the fileInfo is the position of the opening brace) SgClassDefinition* classDefinition = new SgClassDefinition(fileInfo); assert(classDefinition != NULL); // Set the end of construct explictly (where not a transformation this is the location of the closing brace) classDefinition->set_endOfConstruct(fileInfo); // This is the defining declaration for the class (with a reference to the class definition) SgClassDeclaration* classDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition); assert(classDeclaration != NULL); // Set the defining declaration in the defining declaration! classDeclaration->set_definingDeclaration(classDeclaration); // Set the non defining declaration in the defining declaration (both are required) SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL); assert(classDeclaration != NULL); nondefiningClassDeclaration->set_scope(scope); nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration)); // Set the internal reference to the non-defining declaration classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration); classDeclaration->set_type(nondefiningClassDeclaration->get_type()); // Set the defining and no-defining declarations in the non-defining class declaration! nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration); nondefiningClassDeclaration->set_definingDeclaration(classDeclaration); // Set the nondefining declaration as a forward declaration! nondefiningClassDeclaration->setForward(); // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)! classDefinition->set_declaration(classDeclaration); // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!) classDeclaration->set_scope(scope); // some error checking assert(classDeclaration->get_definingDeclaration() != NULL); assert(classDeclaration->get_firstNondefiningDeclaration() != NULL); assert(classDeclaration->get_definition() != NULL); // DQ (9/8/2007): Need to add function symbol to global scope! printf ("Fixing up the symbol table in scope = %p = %s for class = %p = %s \n",scope,scope->class_name().c_str(),classDeclaration,classDeclaration->get_name().str()); SgClassSymbol* classSymbol = new SgClassSymbol(classDeclaration); scope->insert_symbol(classDeclaration->get_name(),classSymbol); ROSE_ASSERT(scope->lookup_class_symbol(classDeclaration->get_name()) != NULL); return classDeclaration; }
NodeQuerySynthesizedAttributeType NodeQuery::queryNodeClassDeclarationFromName(SgNode* node, SgNode* nameNode){ NodeQuerySynthesizedAttributeType returnList; ROSE_ASSERT( nameNode != NULL ); ROSE_ASSERT( node != NULL ); //finds the name which should be matched to SgName* sageName = isSgName(nameNode); ROSE_ASSERT( sageName != NULL ); std::string nameToMatch = sageName->str(); ROSE_ASSERT( nameToMatch.length() > 0 ); SgClassDeclaration *sageClassDeclaration = isSgClassDeclaration (node); if (sageClassDeclaration != NULL) { std::string name = sageClassDeclaration->get_name ().str (); if( name == nameToMatch ) returnList.push_back(node); } return returnList; } /* End function:queryNodeCLassDeclarationFromName() */
string Doxygen::getDeclStmtName(SgDeclarationStatement *st) { SgFunctionDeclaration *fn = isSgFunctionDeclaration(st); SgVariableDeclaration *vn = isSgVariableDeclaration(st); SgClassDeclaration *cn = isSgClassDeclaration(st); if (fn) { return fn->get_name().str(); } else if (vn) { /* XXX The following is a bit dodgy since single * SgVariableDeclaration may declare multiple * variables. But doxygen doesn't handle this case * properly. A useful transform may split up the * SgVariableDeclaration for doxygen's sake */ return (*(vn->get_variables().begin()))->get_name().str(); } else if (cn) { return cn->get_name().str(); } else { fprintf(stderr, "Cannot handle this case: %s\n", st->sage_class_name()); abort(); } }
NameQuerySynthesizedAttributeType NameQuery::queryNameStructNames (SgNode * astNode) { ROSE_ASSERT (astNode != 0); NameQuerySynthesizedAttributeType returnNameList; SgClassDeclaration *sageClassDeclaration = isSgClassDeclaration (astNode); if (sageClassDeclaration != NULL) if (sageClassDeclaration->get_class_type () == SgClassDeclaration::e_struct) { string name = sageClassDeclaration->get_name ().str (); #if DEBUG_NAMEQUERY printf ("In case: CLASS_DECL_STMT name = %s \n", name.c_str ()); #endif returnNameList.push_back (name); } return returnNameList; } /* End function queryNameStructNames() */
void CompassAnalyses::VariableNameEqualsDatabaseName::Traversal:: visit(SgNode* node) { if( isSgAssignInitializer(node) != NULL ) assignExp = node; if( isSgAssignOp(node) != NULL ) assignExp = node; SgFunctionCallExp* funcCall = isSgFunctionCallExp(node); // See if we have a dot expression or arrow expression which // accesses the desired member function in the class we are looking for. if ( funcCall != NULL ) { SgExpression* funcExp = funcCall->get_function(); if ( ( isSgDotExp(funcExp) != NULL ) | ( isSgArrowExp(funcExp) != NULL ) ) { SgBinaryOp* binOp = isSgBinaryOp(funcExp); SgExpression* rhsOp = binOp->get_rhs_operand(); // SgExpression* lhsOp = binOp->get_lhs_operand(); if ( SgMemberFunctionRefExp* funcRef = isSgMemberFunctionRefExp(rhsOp) ) { // std::cout << "c1\n" ; SgMemberFunctionSymbol* funcSymbol = funcRef->get_symbol(); ROSE_ASSERT(funcSymbol->get_declaration() != NULL); // DQ (1/16/2008): Note that the defining declaration need not exist (see test2001_11.C) // ROSE_ASSERT(funcSymbol->get_declaration()->get_definingDeclaration() != NULL); if (funcSymbol->get_declaration()->get_definingDeclaration() != NULL) { SgMemberFunctionDeclaration* funcDecl = isSgMemberFunctionDeclaration(funcSymbol->get_declaration()->get_definingDeclaration()); ROSE_ASSERT( funcDecl != NULL ); SgClassDefinition* clDef = isSgClassDefinition(funcDecl->get_scope()); SgClassDeclaration* clDecl = isSgClassDeclaration(clDef->get_declaration()); // SgClassDeclaration* clDecl = funcDecl->get_associatedClassDeclaration(); ROSE_ASSERT( clDecl != NULL ); std::string className = clDecl->get_name().getString(); ROSE_ASSERT(funcDecl != NULL); std::string functionName = funcDecl->get_name().getString(); // If the class is the class we are looking for see if the member function // access is to the member function we are interested in. // std::cout << "className = " << className << std::endl; // std::cout << "functionName = " << functionName << std::endl; if ( (className == classToLookFor) && ( functionName == memberFunctionToLookFor ) ) { SgExprListExp* actualArgs = funcCall->get_args(); SgExpressionPtrList& actualExpArgs = actualArgs->get_expressions (); ROSE_ASSERT(actualExpArgs.size() == 1); Rose_STL_Container<SgNode*> nodeLst = NodeQuery::querySubTree(*actualExpArgs.begin(), V_SgStringVal); ROSE_ASSERT( nodeLst.size() > 0); SgStringVal* actualArg = isSgStringVal(*nodeLst.begin()); ROSE_ASSERT(actualArg != NULL); std::string stringArg = actualArg->get_value(); std::cout << "arg:" << stringArg << std::endl; std::string varName; // SgInitializedName* initName = NULL; if ( SgAssignInitializer* assignInit = isSgAssignInitializer(assignExp) ) { SgInitializedName* initName = isSgInitializedName(assignInit->get_parent()); ROSE_ASSERT(initName != NULL); varName = initName->get_name().getString(); } else { if ( SgAssignOp* assignOp = isSgAssignOp(assignExp) ) { SgExpression* lhsOp = assignOp->get_lhs_operand(); SgVarRefExp* varRef = isSgVarRefExp(lhsOp); ROSE_ASSERT(varRef!=NULL); SgVariableSymbol* varSymbol = varRef->get_symbol(); ROSE_ASSERT(varSymbol != NULL); SgInitializedName* initName = varSymbol->get_declaration(); varName = initName->get_name().getString(); } } if (varName != "") { // we are only interested in the part of the argument after the last ":" // Database scopes in ALE3D are separated by ":" size_t posCol = stringArg.find_last_of(':'); if (posCol != std::string::npos) stringArg = stringArg.substr(posCol+1); //Find violations to the rule if ( stringArg != varName) { output->addOutput(new CheckerOutput(assignExp)); std::cout << "violation" << varName << std::endl; } else { std::cout << "non=violation" << varName << std::endl; } } } } } } } } // End of the visit function.
void FixupSelfReferentialMacrosInAST::visit ( SgNode* node ) { // DQ (3/11/2006): Set NULL pointers where we would like to have none. // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str()); ROSE_ASSERT(node != NULL); switch (node->variantT()) { case V_SgInitializedName: { SgInitializedName* initializedName = isSgInitializedName(node); ROSE_ASSERT(initializedName != NULL); SgType* type = initializedName->get_type()->stripType(); SgClassType* classType = isSgClassType(type); if (classType != NULL) { SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration()); SgName className = targetClassDeclaration->get_name(); // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str()); // For sudo_exec_pty.c also look for siginfo if (className == "sigaction" || className == "siginfo") { // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n"); // Note we could also check that the declaration came from a known header file. SgStatement* associatedStatement = isSgStatement(initializedName->get_parent()); if (associatedStatement != NULL) { // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro. // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n"); // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos ); PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration; // We are puting out all macros anytime we see either type. This might be too much... // From the sigaction.h file (included by signal.h): addMacro(associatedStatement,"#undef sa_handler\n",directiveType); addMacro(associatedStatement,"#undef sa_sigaction\n",directiveType); // From the siginfo.h file (included by signal.h): addMacro(associatedStatement,"#undef si_pid\n", directiveType); addMacro(associatedStatement,"#undef si_uid\n", directiveType); addMacro(associatedStatement,"#undef si_timerid\n",directiveType); addMacro(associatedStatement,"#undef si_overrun\n",directiveType); addMacro(associatedStatement,"#undef si_status\n", directiveType); addMacro(associatedStatement,"#undef si_utime\n", directiveType); addMacro(associatedStatement,"#undef si_stime\n", directiveType); addMacro(associatedStatement,"#undef si_value\n", directiveType); addMacro(associatedStatement,"#undef si_int\n", directiveType); addMacro(associatedStatement,"#undef si_ptr\n", directiveType); addMacro(associatedStatement,"#undef si_addr\n", directiveType); addMacro(associatedStatement,"#undef si_band\n", directiveType); addMacro(associatedStatement,"#undef si_fd\n", directiveType); } } } } default: { // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str()); } } }
string SIDL_TreeTraversal::generateSIDLFunctionDeclaration(SgFunctionDeclaration* functionDeclarationStatement ) { ROSE_ASSERT (functionDeclarationStatement != NULL); ROSE_ASSERT (functionDeclarationStatement->get_file_info() != NULL); const SgSpecialFunctionModifier &functionModifier = functionDeclarationStatement->get_specialFunctionModifier(); string functionName = functionDeclarationStatement->get_name().str(); string sidlFunctionName ; if (functionModifier.isConstructor()) { if (functionDeclarationStatement->get_args().size() == 0) return ""; // skip empty constructor sidlFunctionName = constructorName; } else { sidlFunctionName = functionName; } // We have to force the mangled name to be generated before we access it (else we just get "defaultName") string mangledFunctionName = functionDeclarationStatement->get_mangled_name().str(); sidlFunctionName = stringifyOperatorWithoutSymbols(sidlFunctionName); // Get the class name SgClassDefinition* classDefinition = isSgClassDefinition(functionDeclarationStatement->get_scope()); // DQ (1/7/2004): Modified for make EDG version 3.3 work (member function declarations's normalized by EDG) if (classDefinition != NULL) { SgClassDeclaration* classDeclaration = classDefinition->get_declaration(); string className = classDeclaration->get_name().str(); overloadInformation info = isOverloaded(classDefinition,functionName,mangledFunctionName); int orderofOverloadedFunction = info.get_order(); // If function is overloaded then append the number indicating the order of appearance in the // class declaration if (info.get_count() > 1) { vector<SgType*> types = info.get_types(); // SgInitializedNamePtrList &args = functionDeclarationStatement->get_args (); int size = types.size(); if(size > 0) { if(size < 3) { sidlFunctionName += "["; for(vector<SgType*>::iterator i = types.begin(); i!= types.end(); i++) { if(i != types.begin()) sidlFunctionName += "_"; if(isSgPointerType(*i) != NULL) sidlFunctionName += "P"; sidlFunctionName += sidlOverloadExtension(TransformationSupport::getTypeName(*i)); } sidlFunctionName += "]"; } else sidlFunctionName += "["+numberToOverloadString(orderofOverloadedFunction)+"]"; } } } else { printf ("EDG version 3.3 can return a null pointer to the member function definition \n"); } SgFunctionType* functionType = functionDeclarationStatement->get_type(); ROSE_ASSERT(functionType != NULL); // SgType* returnType = functionType->get_return_type(); // ROSE_ASSERT (returnType != NULL); // string returnTypeName = TransformationSupport::getTypeName(returnType); // printf ("function has_ellipses %s \n",(functionType->get_has_ellipses() != false) ? "true" : "false"); // showSgFunctionType(cout, functionType, "Called from generateSIDLFunctionDeclaration", 0 ); // printf ("Function return type = %s \n",returnTypeName.c_str()); #if 0 SgTypePtrList & argumentTypeList = functionType->get_arguments(); ROSE_ASSERT (argumentTypeList.size() >= 0); SgTypePtrList::iterator argumentIterator = argumentTypeList.begin(); for (argumentIterator = argumentTypeList.begin(); argumentIterator != argumentTypeList.end(); argumentIterator++) { // showSgType(os,(*argumentIterator), label, depth+1); string argumentTypeName = TransformationSupport::getTypeName(*argumentIterator); printf ("-----> argument #%d argumentTypeName = %s \n",argumentCounter++,argumentTypeName.c_str()); } #endif //Determine the SIDL parameter passing mechanism (in,out,inout) SgInitializedNamePtrList & argumentList = functionDeclarationStatement->get_args(); string parameterTypesAndNames; SgInitializedNamePtrList::iterator i; unsigned int argumentCounter = 0; for (i = argumentList.begin(); i != argumentList.end(); i++) { SgType* type = (*i)->get_type(); ROSE_ASSERT (type != NULL); string typeName = TransformationSupport::getTypeName(type); ROSE_ASSERT (typeName.c_str() != NULL); string sidlParameterPassingMechanim = "in"; //it seems like the has_ellipses value is wrong, so we'll set it functionType->set_has_ellipses(false); if(type->variantT() == V_SgTypeEllipse) { sidlParameterPassingMechanim = "inout"; functionType->set_has_ellipses(true); } //else if (type->variantT() == V_SgTypeVoid) /*else if (rose::stringDuplicate(type->sage_class_name()) == "SgTypeVoid") { printf("found a void\n"); //void type is only viable for a pointer. foo(void) will just become foo() if(isSgPointerType(type) != NULL) { printf("found a void pointer\n"); sidlParameterPassingMechanim ="inout opaque"; } }*/ else if (isSgReferenceType(type) != NULL) { sidlParameterPassingMechanim = "inout"; } else if (isSgPointerType(type) != NULL) { sidlParameterPassingMechanim = "inout"; } else if (isSgArrayType(type) != NULL) { SgArrayType array = isSgArrayType(type); sidlParameterPassingMechanim = "inout Array<"; SgType* baseType = array.get_base_type(); sidlParameterPassingMechanim += TransformationSupport::getTypeName(baseType); sidlParameterPassingMechanim += ",1>"; //FIXME: I don't see a way to determine the dimention of the array } // Build the substring for each parameter parameterTypesAndNames += sidlParameterPassingMechanim; parameterTypesAndNames += " "; //if(type->variantT() != V_SgTypeGlobalVoid) //{ if(type->variantT() == V_SgTypeEllipse) { parameterTypesAndNames += "Array<BabelBaseType,1> "; //FIXME: need to include a declaration for BaseType parameterTypesAndNames += "elips" + argumentCounter; //this fails to actually append the counter, but I don't think it will matter: kmk } else { SgName name = (*i)->get_name(); string nameString = name.str(); string typeName = TransformationSupport::getTypeName(type); if(typeName == "void") { if(nameString!="") { parameterTypesAndNames += "opaque "; parameterTypesAndNames += nameString; } } else { parameterTypesAndNames += typeName; parameterTypesAndNames += " "; if(nameString != "") //will be empty if the function declaration doesn't provide a name parameterTypesAndNames += nameString; } } // Add a "," to the string if there are more parameters in the list if ( argumentCounter < argumentList.size()-1 ) parameterTypesAndNames += ","; //}else printf("avoiding the void\n"); argumentCounter++; } SgType* returnType = functionType->get_return_type(); ROSE_ASSERT (returnType != NULL); string returnTypeName = "void"; if(returnType->variantT() != V_SgTypeVoid) returnTypeName = TransformationSupport::getTypeName(returnType); string sidlMemberFunctionDeclaration = " $RETURN_TYPE $FUNCTION_NAME($PARAMETERS);\n"; sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$RETURN_TYPE" , returnTypeName ); sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$FUNCTION_NAME" , sidlFunctionName ); sidlMemberFunctionDeclaration = StringUtility::copyEdit ( sidlMemberFunctionDeclaration, "$PARAMETERS" , parameterTypesAndNames ); return sidlMemberFunctionDeclaration; }
StencilEvaluation_InheritedAttribute StencilEvaluationTraversal::evaluateInheritedAttribute (SgNode* astNode, StencilEvaluation_InheritedAttribute inheritedAttribute ) { #if 0 printf ("In evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str()); #endif bool foundPairShiftDoubleConstructor = false; // This is for stencil specifications using vectors of points to represent offsets (not finished). // bool foundVariableDeclarationForStencilInput = false; double stencilCoeficientValue = 0.0; // StencilOffsetFSM offset; StencilOffsetFSM* stencilOffsetFSM = NULL; // We want to interogate the SgAssignInitializer, but we need to generality in the refactored function to use any SgInitializer (e.g. SgConstructorInitializer, etc.). SgInitializedName* initializedName = detectVariableDeclarationOfSpecificType (astNode,"Point"); if (initializedName != NULL) { // This is the code that is specific to the DSL (e.g. the semantics of getZeros() and getUnitv() functions). // So this may be the limit of what can be refactored to common DSL support code. // Or I can maybe do a second pass at atempting to refactor more code later. string name = initializedName->get_name(); SgInitializer* initializer = initializedName->get_initptr(); SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer); if (assignInitializer != NULL) { SgExpression* exp = assignInitializer->get_operand(); ROSE_ASSERT(exp != NULL); SgFunctionCallExp* functionCallExp = isSgFunctionCallExp(exp); if (functionCallExp != NULL) { SgFunctionRefExp* functionRefExp = isSgFunctionRefExp(functionCallExp->get_function()); if (functionRefExp != NULL) { SgFunctionSymbol* functionSymbol = functionRefExp->get_symbol(); ROSE_ASSERT(functionSymbol != NULL); string functionName = functionSymbol->get_name(); #if 0 printf ("functionName = %s \n",functionName.c_str()); #endif if (functionName == "getZeros") { // We leverage the semantics of known functions used to initialize "Point" objects ("getZeros" initialized the Point object to be all zeros). // In a stencil this will be the center point from which all other points will have non-zero offsets. // For a common centered difference discretization this will be the center point of the stencil. #if 0 printf ("Identified and interpreting the semantics of getZeros() function \n"); #endif stencilOffsetFSM = new StencilOffsetFSM(0,0,0); ROSE_ASSERT(stencilOffsetFSM != NULL); } if (functionName == "getUnitv") { // We leverage the semantics of known functions used to initialize "Point" objects // ("getUnitv" initializes the Point object to be a unit vector for a specific input dimention). // In a stencil this will be an ofset from the center point. #if 0 printf ("Identified and interpreting the semantics of getUnitv() function \n"); #endif // Need to get the dimention argument. SgExprListExp* argumentList = functionCallExp->get_args(); ROSE_ASSERT(argumentList != NULL); // This function has a single argument. ROSE_ASSERT(argumentList->get_expressions().size() == 1); SgExpression* functionArg = argumentList->get_expressions()[0]; ROSE_ASSERT(functionArg != NULL); SgIntVal* intVal = isSgIntVal(functionArg); // ROSE_ASSERT(intVal != NULL); if (intVal != NULL) { int value = intVal->get_value(); #if 0 printf ("value = %d \n",value); #endif switch(value) { case 0: stencilOffsetFSM = new StencilOffsetFSM(1,0,0); break; case 1: stencilOffsetFSM = new StencilOffsetFSM(0,1,0); break; case 2: stencilOffsetFSM = new StencilOffsetFSM(0,0,1); break; default: { printf ("Error: default reached in switch: value = %d (for be value of 0, 1, or 2) \n",value); ROSE_ASSERT(false); } } ROSE_ASSERT(stencilOffsetFSM != NULL); // End of test for intVal != NULL } else { #if 0 printf ("functionArg = %p = %s \n",functionArg,functionArg->class_name().c_str()); #endif } } // ROSE_ASSERT(stencilOffsetFSM != NULL); } } } if (stencilOffsetFSM != NULL) { // Put the FSM into the map. #if 0 printf ("Put the stencilOffsetFSM = %p into the StencilOffsetMap using key = %s \n",stencilOffsetFSM,name.c_str()); #endif ROSE_ASSERT(StencilOffsetMap.find(name) == StencilOffsetMap.end()); // We have a choice of syntax to add the element to the map. // StencilOffsetMap.insert(pair<string,StencilOffsetFSM*>(name,stencilOffsetFSM)); StencilOffsetMap[name] = stencilOffsetFSM; } // new StencilOffsetFSM(); #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } // Recognize member function calls on "Point" objects so that we can trigger events on those associated finite state machines. bool isTemplateClass = false; bool isTemplateFunctionInstantiation = false; SgInitializedName* initializedNameUsedToCallMemberFunction = NULL; SgFunctionCallExp* functionCallExp = detectMemberFunctionOfSpecificClassType(astNode,initializedNameUsedToCallMemberFunction,"Point",isTemplateClass,"operator*=",isTemplateFunctionInstantiation); if (functionCallExp != NULL) { // This is the DSL specific part (capturing the semantics of operator*= with specific integer values). // The name of the variable off of which the member function is called (variable has type "Point"). ROSE_ASSERT(initializedNameUsedToCallMemberFunction != NULL); string name = initializedNameUsedToCallMemberFunction->get_name(); // Need to get the dimention argument. SgExprListExp* argumentList = functionCallExp->get_args(); ROSE_ASSERT(argumentList != NULL); // This function has a single argument. ROSE_ASSERT(argumentList->get_expressions().size() == 1); SgExpression* functionArg = argumentList->get_expressions()[0]; ROSE_ASSERT(functionArg != NULL); SgIntVal* intVal = isSgIntVal(functionArg); bool usingUnaryMinus = false; if (intVal == NULL) { SgMinusOp* minusOp = isSgMinusOp(functionArg); if (minusOp != NULL) { #if 0 printf ("Using SgMinusOp on stencil constant \n"); #endif usingUnaryMinus = true; intVal = isSgIntVal(minusOp->get_operand()); } } ROSE_ASSERT(intVal != NULL); int value = intVal->get_value(); if (usingUnaryMinus == true) { value *= -1; } #if 0 printf ("value = %d \n",value); #endif // Look up the stencil offset finite state machine ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end()); StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name]; ROSE_ASSERT(stencilOffsetFSM != NULL); #if 0 printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str()); #endif #if 0 stencilOffsetFSM->display("before multiply event"); #endif if (value == -1) { // Execute the event on the finte state machine to accumulate the state. stencilOffsetFSM->operator*=(-1); } else { printf ("Error: constant value other than -1 are not supported \n"); ROSE_ASSERT(false); } #if 0 stencilOffsetFSM->display("after multiply event"); #endif } // Detection of "pair<Shift,double>(xdir,ident)" defined as an event in the stencil finite machine model. // Actually, it is the Stencil that is create using the "pair<Shift,double>(xdir,ident)" that should be the // event so we first detect the SgConstructorInitializer. There is not other code similar to this which // has to test for the template arguments, so this has not yet refactored into the dslSupport.C file. // I will do this later since this is general support that could be resused in other DSL compilers. SgConstructorInitializer* constructorInitializer = isSgConstructorInitializer(astNode); if (constructorInitializer != NULL) { // DQ (10/20/2014): This can sometimes be NULL. // ROSE_ASSERT(constructorInitializer->get_class_decl() != NULL); SgClassDeclaration* classDeclaration = constructorInitializer->get_class_decl(); // ROSE_ASSERT(classDeclaration != NULL); if (classDeclaration != NULL) { #if 0 printf ("constructorInitializer = %p class name = %s \n",constructorInitializer,classDeclaration->get_name().str()); #endif SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classDeclaration); // ROSE_ASSERT(templateInstantiationDecl != NULL); #if 0 if (templateInstantiationDecl != NULL) { printf ("constructorInitializer = %p name = %s template name = %s \n",constructorInitializer,templateInstantiationDecl->get_name().str(),templateInstantiationDecl->get_templateName().str()); } #endif // if (classDeclaration->get_name() == "pair") if (templateInstantiationDecl != NULL && templateInstantiationDecl->get_templateName() == "pair") { // Look at the template parameters. #if 0 printf ("Found template instantiation for pair \n"); #endif SgTemplateArgumentPtrList & templateArgs = templateInstantiationDecl->get_templateArguments(); if (templateArgs.size() == 2) { // Now look at the template arguments and check that they represent the pattern that we are looking for in the AST. // It is not clear now flexible we should be, at present shift/coeficent pairs must be specified exactly one way. SgType* type_0 = templateArgs[0]->get_type(); SgType* type_1 = templateArgs[1]->get_type(); if ( type_0 != NULL && type_1 != NULL) { SgClassType* classType_0 = isSgClassType(type_0); // ROSE_ASSERT(classType_0 != NULL); if (classType_0 != NULL) { SgClassDeclaration* classDeclarationType_0 = isSgClassDeclaration(classType_0->get_declaration()); ROSE_ASSERT(classDeclarationType_0 != NULL); #if 0 printf ("templateArgs[0]->get_name() = %s \n",classDeclarationType_0->get_name().str()); printf ("templateArgs[1]->get_type()->class_name() = %s \n",type_1->class_name().c_str()); #endif bool foundShiftExpression = false; bool foundStencilCoeficient = false; // We might want to be more flexiable about the type of the 2nd parameter (allow SgTypeFloat, SgTypeComplex, etc.). if (classDeclarationType_0->get_name() == "Shift" && type_1->variant() == V_SgTypeDouble) { // Found a pair<Shift,double> input for a stencil. #if 0 printf ("##### Found a pair<Shift,double>() input for a stencil input \n"); #endif // ***************************************************************************************************** // Look at the first parameter to the pair<Shift,double>() constructor. // ***************************************************************************************************** SgExpression* stencilOffset = constructorInitializer->get_args()->get_expressions()[0]; ROSE_ASSERT(stencilOffset != NULL); #if 0 printf ("stencilOffset = %p = %s \n",stencilOffset,stencilOffset->class_name().c_str()); #endif SgConstructorInitializer* stencilOffsetConstructorInitializer = isSgConstructorInitializer(stencilOffset); if (stencilOffsetConstructorInitializer != NULL) { // This is the case of a Shift being constructed implicitly from a Point (doing so more directly would be easier to make sense of in the AST). #if 0 printf ("!!!!! Looking for the stencil offset \n"); #endif ROSE_ASSERT(stencilOffsetConstructorInitializer->get_class_decl() != NULL); SgClassDeclaration* stencilOffsetClassDeclaration = stencilOffsetConstructorInitializer->get_class_decl(); ROSE_ASSERT(stencilOffsetClassDeclaration != NULL); #if 0 printf ("stencilOffsetConstructorInitializer = %p class name = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration->get_name().str()); printf ("stencilOffsetConstructorInitializer = %p class = %p = %s \n",stencilOffsetConstructorInitializer,stencilOffsetClassDeclaration,stencilOffsetClassDeclaration->class_name().c_str()); #endif // This should not be a template instantiation (the Shift is defined to be a noo-template class declaration, not a template class declaration). SgTemplateInstantiationDecl* stencilOffsetTemplateInstantiationDecl = isSgTemplateInstantiationDecl(stencilOffsetClassDeclaration); ROSE_ASSERT(stencilOffsetTemplateInstantiationDecl == NULL); if (stencilOffsetClassDeclaration != NULL && stencilOffsetClassDeclaration->get_name() == "Shift") { // Now we know that the type associated with the first template parameter is associated with the class "Shift". // But we need so also now what the first parametr is associate with the constructor initializer, since it will // be the name of the variable used to interprete the stencil offset (and the name of the variable will be the // key into the map of finite machine models used to accumulate the state of the stencil offsets that we accumulate // to build the stencil. // Now we need the value of the input (computed using it's fine state machine). SgExpression* inputToShiftConstructor = stencilOffsetConstructorInitializer->get_args()->get_expressions()[0]; ROSE_ASSERT(inputToShiftConstructor != NULL); SgConstructorInitializer* inputToShiftConstructorInitializer = isSgConstructorInitializer(inputToShiftConstructor); if (stencilOffsetConstructorInitializer != NULL) { SgExpression* inputToPointConstructor = inputToShiftConstructorInitializer->get_args()->get_expressions()[0]; ROSE_ASSERT(inputToPointConstructor != NULL); // This should be a SgVarRefExp (if we strictly follow the stencil specification rules (which are not written down yet). SgVarRefExp* inputToPointVarRefExp = isSgVarRefExp(inputToPointConstructor); if (inputToPointVarRefExp != NULL) { #if 0 printf ("Found varRefExp in bottom of chain of constructors \n"); #endif SgVariableSymbol* variableSymbolForOffset = isSgVariableSymbol(inputToPointVarRefExp->get_symbol()); ROSE_ASSERT(variableSymbolForOffset != NULL); SgInitializedName* initializedNameForOffset = variableSymbolForOffset->get_declaration(); ROSE_ASSERT(initializedNameForOffset != NULL); SgInitializer* initializer = initializedNameForOffset->get_initptr(); ROSE_ASSERT(initializer != NULL); #if 0 printf ("Found initializedName: name = %s in bottom of chain of constructors: initializer = %p = %s \n",initializedNameForOffset->get_name().str(),initializer,initializer->class_name().c_str()); #endif // Record the name to be used as a key into the map of "StencilOffset" finite state machines. SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer); ROSE_ASSERT(assignInitializer != NULL); string name = initializedNameForOffset->get_name(); // Look up the current state in the finite state machine for the "Point". // Check that this is a previously defined stencil offset. ROSE_ASSERT(StencilOffsetMap.find(name) != StencilOffsetMap.end()); // StencilOffsetFSM* stencilOffsetFSM = StencilOffsetMap[name]; stencilOffsetFSM = StencilOffsetMap[name]; ROSE_ASSERT(stencilOffsetFSM != NULL); #if 0 printf ("We have found the StencilOffsetFSM associated with the StencilOffset named %s \n",name.c_str()); #endif #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } else { printf ("What is this expression: inputToPointConstructor = %p = %s \n",inputToPointConstructor,inputToPointConstructor->class_name().c_str()); ROSE_ASSERT(false); } } #if 0 printf ("Found Shift type \n"); #endif foundShiftExpression = true; } #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } else { // This case for the specification of a Shift in the first argument is not yet supported (need an example of this). printf ("This case of using a shift is not a part of what is supported \n"); } // ***************************************************************************************************** // Look at the second parameter to the pair<Shift,double>(first_parameter,second_parameter) constructor. // ***************************************************************************************************** SgExpression* stencilCoeficent = constructorInitializer->get_args()->get_expressions()[1]; ROSE_ASSERT(stencilCoeficent != NULL); SgVarRefExp* stencilCoeficentVarRefExp = isSgVarRefExp(stencilCoeficent); if (stencilCoeficentVarRefExp != NULL) { // Handle the case where this is a constant SgVarRefExp and the value is available in the declaration. SgVariableSymbol* variableSymbolForConstant = isSgVariableSymbol(stencilCoeficentVarRefExp->get_symbol()); ROSE_ASSERT(variableSymbolForConstant != NULL); SgInitializedName* initializedNameForConstant = variableSymbolForConstant->get_declaration(); ROSE_ASSERT(initializedNameForConstant != NULL); SgInitializer* initializer = initializedNameForConstant->get_initptr(); ROSE_ASSERT(initializer != NULL); SgAssignInitializer* assignInitializer = isSgAssignInitializer(initializer); ROSE_ASSERT(assignInitializer != NULL); SgValueExp* valueExp = isSgValueExp(assignInitializer->get_operand()); bool usingUnaryMinus = false; // ROSE_ASSERT(valueExp != NULL); if (valueExp == NULL) { SgExpression* operand = assignInitializer->get_operand(); SgMinusOp* minusOp = isSgMinusOp(operand); if (minusOp != NULL) { #if 0 printf ("Using SgMinusOp on stencil constant \n"); #endif usingUnaryMinus = true; valueExp = isSgValueExp(minusOp->get_operand()); } } SgDoubleVal* doubleVal = isSgDoubleVal(valueExp); // ROSE_ASSERT(doubleVal != NULL); double value = 0.0; if (doubleVal == NULL) { // Call JP's function to evaluate the constant expression. ROSE_ASSERT(valueExp == NULL); ROSE_ASSERT(stencilCoeficent != NULL); DSL_Support::const_numeric_expr_t const_expression = DSL_Support::evaluateConstNumericExpression(stencilCoeficent); if (const_expression.hasValue_ == true) { ROSE_ASSERT(const_expression.isIntOnly_ == false); value = const_expression.value_; printf ("const expression evaluated to value = %4.2f \n",value); } else { printf ("constnat value expression could not be evaluated to a constant \n"); ROSE_ASSERT(false); } } else { #if 1 printf ("SgDoubleVal value = %f \n",doubleVal->get_value()); #endif value = (usingUnaryMinus == false) ? doubleVal->get_value() : -(doubleVal->get_value()); } #if 1 printf ("Stencil coeficient = %f \n",value); #endif foundStencilCoeficient = true; stencilCoeficientValue = value; } else { // When we turn on constant folding in the frontend we eveluate directly to a SgDoubleVal. SgDoubleVal* doubleVal = isSgDoubleVal(stencilCoeficent); if (doubleVal != NULL) { ROSE_ASSERT(doubleVal != NULL); #if 0 printf ("SgDoubleVal value = %f \n",doubleVal->get_value()); #endif double value = doubleVal->get_value(); #if 0 printf ("Stencil coeficient = %f \n",value); #endif foundStencilCoeficient = true; stencilCoeficientValue = value; } else { printf ("Error: second parameter in pair for stencil is not a SgVarRefExp (might be explicit value not yet supported) \n"); printf (" --- stencilCoeficent = %p = %s \n",stencilCoeficent,stencilCoeficent->class_name().c_str()); ROSE_ASSERT(false); } } } #if 0 printf ("foundShiftExpression = %s \n",foundShiftExpression ? "true" : "false"); printf ("foundStencilCoeficient = %s \n",foundStencilCoeficient ? "true" : "false"); #endif if (foundShiftExpression == true && foundStencilCoeficient == true) { #if 0 printf ("Found pair<Shift,double>() constructor expression! \n"); #endif foundPairShiftDoubleConstructor = true; } // End of test for classType_0 != NULL } } } } else { #if 0 printf ("This is not a SgConstructorInitializer for the pair templated class \n"); #endif } // End of test for classDeclaration != NULL } } #if 0 printf ("foundPairShiftDoubleConstructor = %s \n",foundPairShiftDoubleConstructor ? "true" : "false"); #endif if (foundPairShiftDoubleConstructor == true) { // This is the recognition of an event for one of the finite state machines we implement to evaluate the stencil at compile time. #if 0 printf ("In evaluateInheritedAttribute(): found pair<Shift,double>() constructor expression! \n"); printf (" --- stencilOffsetFSM = %p \n",stencilOffsetFSM); printf (" --- stencilCoeficientValue = %f \n",stencilCoeficientValue); #endif ROSE_ASSERT(stencilOffsetFSM != NULL); inheritedAttribute.stencilOffsetFSM = stencilOffsetFSM; inheritedAttribute.stencilCoeficientValue = stencilCoeficientValue; #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } // Construct the return attribute from the modified input attribute. return StencilEvaluation_InheritedAttribute(inheritedAttribute); }
//----------------------------------------------------------------------------- // Functions required by the tree traversal mechanism ClasshierarchyInhAttr ClasshierarchyTraversal::evaluateInheritedAttribute ( SgNode* astNode, ClasshierarchyInhAttr inheritedAttribute ) { GlobalDatabaseConnection *gdb; // db connection //long funcId; // id of a function declaration Classhierarchy *classhier = getClasshierarchy(); gdb = getDB(); switch(astNode->variantT()) { case V_SgMemberFunctionDeclaration: { SgMemberFunctionDeclaration *funcDec = isSgMemberFunctionDeclaration( astNode ); //funcDec = funcDef->get_declaration(); //if(isSgMemberFunctionDeclaration(funcDec)) { // add to class hierarchy if member function definition //if(isSgMemberFunctionDeclaration()) { //cerr << " adding CHvinf for MembFunc " << endl; SgClassDefinition *classDef = isSgClassDefinition( funcDec->get_scope() ); //assert(classDef); if(classDef) { string classname = classDef->get_qualified_name().str(); // get the classhier. vertex Classhierarchy::dbgVertex chVert = 0; //?? init necessary bool foundClass = false; Classhierarchy::dbgVertexIterator chvi,chvend; boost::tie(chvi,chvend) = boost::vertices( *getClasshierarchy() ); for(; chvi!=chvend; chvi++) { if( boost::get( vertex_dbg_data, *getClasshierarchy() , *chvi).get_typeName() == classname ) { chVert = *chvi; foundClass = true; } } if(foundClass) { property_map< Classhierarchy::dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *getClasshierarchy() ); chMap[ chVert ].defined.insert( funcDec ); //get type? //cerr << " added! "; // debug } } //} cerr << " found V_SgMemberFunctionDeclaration done for " <<funcDec->get_mangled_name().str()<< " " << endl; // debug } break; case V_SgClassDefinition: { cerr << " found V_SgClassDef of "; // debug SgClassDefinition *classDef = isSgClassDefinition( astNode ); assert( classDef ); SgName classname = classDef->get_qualified_name(); // make db entry long typeId = UNKNOWNID; typesTableAccess types( gdb ); typesRowdata newtype( typeId, getProjectId(), classname.str() ); typeId = types.retrieveCreateByColumn( &newtype, "typeName", newtype.get_typeName(), newtype.get_projectId() ); cerr << classname.str()<< ", id:" << newtype.get_id() << endl; // debug //classhier->addNode( newtype, newtype.get_typeName() ); //classhier->insertWithName( newtype, newtype.get_typeName() ); classhier->insertVertex( newtype, newtype.get_typeName() ); SgBaseClassList inherits = classDef->get_inheritances(); for( SgBaseClassList::iterator i=inherits.begin(); i!=inherits.end(); i++) { SgClassDeclaration *parentDecl = (*i).get_base_class(); cerr << " found inheritance from " ; // debug assert( parentDecl ); // add new edge typesRowdata partype( UNKNOWNID, getProjectId(), parentDecl->get_name().str() ); // MANGLE long parentId = types.retrieveCreateByColumn( &partype, "typeName", partype.get_typeName(), partype.get_projectId() ); cerr << parentDecl->get_name().str() << ", id: " << parentId << endl; // add to class hierarchy graph, allow only one edge per inheritance //A classhier->addNode( partype, partype.get_typeName() ); //A classhier->addEdge( newtype, partype, false ); classhier->insertEdge( newtype, partype ); } } break; } // switch node type // Note that we have to use a particular constructor (to pass on context information about source code position). // This allows the Rewrite mechanism to position new source code relative to the current position using a simple interface. ClasshierarchyInhAttr returnAttribute(inheritedAttribute,astNode); // FIXME why not return inheritedAttribute??? return returnAttribute; }
ATerm convertNodeToAterm(SgNode* n) { if (n == NULL) { #if 0 printf ("convertNodeToAterm(): n = %p = %s \n",n,"NULL"); #endif return ATmake("NULL"); } ROSE_ASSERT(n != NULL); #if 0 printf ("convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str()); #endif ATerm term; switch (n->variantT()) { // case V_SgFile: case V_SgSourceFile: // Special case needed to include file name // term = ATmake("File(<str>, <term>)", isSgFile(n)->getFileName(), convertNodeToAterm(isSgFile(n)->get_root())); term = ATmake("File(<str>, <term>)", isSgSourceFile(n)->getFileName().c_str(), convertNodeToAterm(isSgSourceFile(n)->get_globalScope())); break; case V_SgPlusPlusOp: case V_SgMinusMinusOp: // Special cases needed to include prefix/postfix status term = ATmake("<appl(<appl>, <term>)>", getShortVariantName((VariantT)(n->variantT())).c_str(), (isSgUnaryOp(n)->get_mode() == SgUnaryOp::prefix ? "Prefix" : isSgUnaryOp(n)->get_mode() == SgUnaryOp::postfix ? "Postfix" : "Unknown"), convertNodeToAterm(isSgUnaryOp(n)->get_operand())); break; case V_SgExpressionRoot: // Special case to remove this node term = convertNodeToAterm(isSgExpressionRoot(n)->get_operand()); break; case V_SgCastExp: // Special case needed to include type term = ATmake("Cast(<term>, <term>)>", convertNodeToAterm(isSgUnaryOp(n)->get_operand()), convertNodeToAterm(isSgCastExp(n)->get_type())); break; case V_SgVarRefExp: // Special case needed to include id term = ATmake("Var(<str>)", uniqueId(isSgVarRefExp(n)->get_symbol()->get_declaration()).c_str()); break; case V_SgFunctionRefExp: // Special case needed to include id term = ATmake( "Func(<str>)", uniqueId(isSgFunctionRefExp(n)->get_symbol()->get_declaration()).c_str()); break; case V_SgIntVal: // Special case needed to include value term = ATmake("IntC(<int>)", isSgIntVal(n)->get_value()); break; case V_SgUnsignedIntVal: term = ATmake("UnsignedIntC(<int>)", isSgUnsignedIntVal(n)->get_value()); break; case V_SgUnsignedLongVal: { ostringstream s; s << isSgUnsignedLongVal(n)->get_value(); term = ATmake("UnsignedLongC(<str>)", s.str().c_str()); } break; case V_SgUnsignedLongLongIntVal: { ostringstream s; s << isSgUnsignedLongLongIntVal(n)->get_value(); term = ATmake("UnsignedLongLongC(<str>)", s.str().c_str()); } break; case V_SgDoubleVal: term = ATmake("DoubleC(<real>)", isSgDoubleVal(n)->get_value()); break; case V_SgInitializedName: { // Works around double initname problem SgInitializer* initializer = isSgInitializedName(n)->get_initializer(); const SgName& name = isSgInitializedName(n)->get_name(); SgType* type = isSgInitializedName(n)->get_type(); ROSE_ASSERT(type != NULL); #if 0 printf ("convertNodeToAterm(): case V_SgInitializedName: name = %s initializer = %p type = %p = %s \n",name.str(),initializer,type,type->class_name().c_str()); #endif // Works around fact that ... is not really an initname and shouldn't be a type either if (isSgTypeEllipse(type)) { term = ATmake("Ellipses"); } else { std::string uniqueIdString = uniqueId(n); #if 0 printf ("uniqueIdString = %s \n",uniqueIdString.c_str()); printf ("Calling generate ATerm for SgInitializedName->get_name() name = %s \n",name.str()); ATerm name_aterm = ATmake("Name(<str>)",name.str()); // ATerm name_aterm = ATmake(name.str()); printf ("Calling convertNodeToAterm(type) \n"); ATerm type_aterm = convertNodeToAterm(type); printf ("Calling convertNodeToAterm(initializer) \n"); #endif ATerm initializer_aterm = convertNodeToAterm(initializer); #if 0 printf ("Calling ATmake() \n"); #endif #if 1 term = ATmake("InitName(<str>, <term>, <term>) {[id, <str>]}", (name.str() ? name.str() : ""), convertNodeToAterm(type), convertNodeToAterm(initializer), uniqueId(n).c_str()); // uniqueIdString.c_str()); #else term = ATmake("InitName(<term>,<term>)", //(name.str() ? name.str() : ""), // name_aterm, type_aterm, initializer_aterm // uniqueId(n).c_str()); // uniqueIdString.c_str()); ); #endif #if 0 printf ("Calling ATsetAnnotation() \n"); #endif term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str())); #if 0 printf ("DONE: Calling ATsetAnnotation() \n"); #endif } break; } case V_SgFunctionDeclaration: { // Special case needed to include name SgFunctionDeclaration* fd = isSgFunctionDeclaration(n); term = ATmake("Function(<str>, <term>, <term>, <term>)", fd->get_name().str(), convertNodeToAterm(fd->get_orig_return_type()), convertSgNodeRangeToAterm(fd->get_args().begin(), fd->get_args().end()), convertNodeToAterm(fd->get_definition())); term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str())); } break; case V_SgClassDeclaration: { // Special case needed to distinguish forward/full definitions and to // include class name SgClassDeclaration* decl = isSgClassDeclaration(n); assert (decl); SgName sname = decl->get_name(); const char* name = sname.str(); // Suggestion: have a field named local_definition in each class // declaration that is 0 whenever the current declaration doesn't // have a definition attached, even if there is another declaration // which does have a definition attached. SgClassDefinition* defn = decl->get_definition(); // cout << "defn = 0x" << hex << defn << endl << dec; if (decl->isForward()) defn = 0; if (defn) term = ATmake("Class(<str>, <term>)", (name ? name : ""), // Will be simpler when SgName // becomes string convertNodeToAterm(defn)); else term = ATmake("ClassFwd(<str>)", (name ? name : "")); term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str())); } break; case V_SgEnumDeclaration: { // Special case to include enum name and enumerator names which are not // traversal children SgName sname = isSgEnumDeclaration(n)->get_name(); const char* name = sname.str(); const SgInitializedNamePtrList& enumerators = isSgEnumDeclaration(n)->get_enumerators(); term = ATmake("Enum(<str>, <term>)", (name ? name : "{anonymous}"), convertSgNodeRangeToAterm(enumerators.begin(), enumerators.end())); term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str())); } break; case V_SgPointerType: { // Special case because types can't be traversed yet SgType* type = isSgPointerType(n)->get_base_type(); ATerm t = convertNodeToAterm(type); term = ATmake("Pointer(<term>)", t); } break; case V_SgReferenceType: { // Special case because types can't be traversed yet SgType* type = isSgReferenceType(n)->get_base_type(); ATerm t = convertNodeToAterm(type); term = ATmake("Reference(<term>)", t); } break; case V_SgModifierType: { // Special case for type traversal and to prettify modifier names SgType* type = isSgModifierType(n)->get_base_type(); SgTypeModifier& modifier = isSgModifierType(n)->get_typeModifier(); SgConstVolatileModifier& cvmod = modifier.get_constVolatileModifier(); term = convertNodeToAterm(type); if (cvmod.isConst()) term = ATmake("Const(<term>)", term); if (cvmod.isVolatile()) term = ATmake("Volatile(<term>)", term); } break; case V_SgArrayType: { // Special case because types can't be traversed yet, and to get length SgType* type = isSgArrayType(n)->get_base_type(); ATerm t = convertNodeToAterm(type); term = ATmake("Array(<term>, <term>)", t, (isSgArrayType(n)->get_index() ? convertNodeToAterm((n->get_traversalSuccessorContainer())[4]) : ATmake("<str>", "NULL"))); assert (term); } break; case V_SgFunctionType: { // Special case to allow argument list to be traversed SgFunctionType* ft = isSgFunctionType(n); ATerm ret = convertNodeToAterm(ft->get_return_type()); ATerm args_list = convertSgNodeRangeToAterm(ft->get_arguments().begin(), ft->get_arguments().end()); term = ATmake("FunctionType(<term>, <term>)", ret, args_list); } break; case V_SgEnumType: case V_SgClassType: case V_SgTypedefType: { // Special cases to optionally put in type definition instead of // reference SgNamedType* nt = isSgNamedType(n); assert (nt); SgName sname = nt->get_name(); // char* name = sname.str(); SgDeclarationStatement* decl = nt->get_declaration(); assert (decl); SgClassDefinition* defn = isSgClassDeclaration(decl) ? isSgClassDeclaration(decl)->get_definition() : 0; term = ATmake("Type(<term>)", (nt->get_autonomous_declaration() || !defn ? ATmake("id(<str>)", uniqueId(decl).c_str()) : convertNodeToAterm(nt->get_declaration()))); } break; case V_SgLabelStatement: { // Special case to put in label id const char* name = isSgLabelStatement(n)->get_name().str(); term = ATmake("Label(<str>)", (name ? name : "")); term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str())); } break; case V_SgGotoStatement: { // Special case to put in label id term = ATmake("Goto(<str>)", uniqueId(isSgGotoStatement(n)->get_label()).c_str()); } break; case V_SgTypedefDeclaration: { // Special case to put in typedef name const SgName& name = isSgTypedefDeclaration(n)->get_name(); SgType* type = isSgTypedefDeclaration(n)->get_base_type(); term = ATmake("Typedef(<str>, <term>)", (name.str() ? name.str() : ""), convertNodeToAterm(type)); term = ATsetAnnotation(term, ATmake("id"), ATmake("<str>", uniqueId(n).c_str())); } break; case V_SgTemplateDeclaration: { // Traversal doesn't work for these SgTemplateDeclaration* td = isSgTemplateDeclaration(n); ROSE_ASSERT (td); // SgTemplateParameterPtrListPtr paramsPtr = td->get_templateParameters(); // SgTemplateParameterPtrList & paramsPtr = td->get_templateParameters(); // SgTemplateParameterPtrList params = paramsPtr ? *paramsPtr : SgTemplateParameterPtrList(); SgTemplateParameterPtrList & params = td->get_templateParameters(); string templateKindString; switch (td->get_template_kind()) { case SgTemplateDeclaration::e_template_none: templateKindString = "None"; break; case SgTemplateDeclaration::e_template_class: templateKindString = "Class"; break; case SgTemplateDeclaration::e_template_m_class: templateKindString = "MemberClass"; break; case SgTemplateDeclaration::e_template_function: templateKindString = "Function"; break; case SgTemplateDeclaration::e_template_m_function: templateKindString = "MemberFunction"; break; case SgTemplateDeclaration::e_template_m_data: templateKindString = "MemberData"; break; default: templateKindString = "Unknown"; break; } term = ATmake("TemplateDeclaration(<appl>, <str>, <term>, <str>)", templateKindString.c_str(), td->get_name().str(), convertSgNodeRangeToAterm(params.begin(), params.end()), td->get_string().str()); } break; case V_SgTemplateInstantiationDecl: { // Traversal doesn't work for these SgTemplateInstantiationDecl* td = isSgTemplateInstantiationDecl(n); ROSE_ASSERT (td); // SgTemplateArgumentPtrListPtr argsPtr = td->get_templateArguments(); // SgTemplateArgumentPtrList args = argsPtr ? *argsPtr : SgTemplateArgumentPtrList(); SgTemplateArgumentPtrList & args = td->get_templateArguments(); term = ATmake("TemplateInstantiationDecl(<str>, <term>)", td->get_templateDeclaration()->get_name().str(), convertSgNodeRangeToAterm(args.begin(), args.end())); } break; case V_SgTemplateParameter: { // Traversal doesn't work for these SgTemplateParameter* tp = isSgTemplateParameter(n); ROSE_ASSERT (tp); switch (tp->get_parameterType()) { case SgTemplateParameter::parameter_undefined: { term = ATmake("Undefined"); } break; case SgTemplateParameter::type_parameter: { term = ATmake("Type(<term>)", convertNodeToAterm(tp->get_defaultTypeParameter())); } break; case SgTemplateParameter::nontype_parameter: { term = ATmake("Nontype(<term>, <term>)", convertNodeToAterm(tp->get_type()), convertNodeToAterm(tp->get_defaultExpressionParameter())); } break; case SgTemplateParameter::template_parameter: { term = ATmake("Template"); } break; default: term = ATmake("Unknown"); break; } } break; case V_SgTemplateArgument: { // Traversal doesn't work for these SgTemplateArgument* ta = isSgTemplateArgument(n); ROSE_ASSERT (ta); switch (ta->get_argumentType()) { case SgTemplateArgument::argument_undefined: term = ATmake("Undefined"); break; case SgTemplateArgument::type_argument: term = ATmake("Type(<term>)", convertNodeToAterm(ta->get_type())); break; case SgTemplateArgument::nontype_argument: term = ATmake("Nontype(<term>)", convertNodeToAterm(ta->get_expression())); break; // case SgTemplateArgument::template_argument: // term = ATmake("Template"); // break; default: term = ATmake("Unknown"); break; } } break; default: { bool isContainer = (AstTests::numSuccContainers(n) == 1) || (!isSgType(n) && (n->get_traversalSuccessorContainer().size() == 0)); term = ATmake((isContainer ? "<appl(<term>)>" : "<appl(<list>)>"), getShortVariantName((VariantT)(n->variantT())).c_str(), (isSgType(n) ? ATmake("[]") : getTraversalChildrenAsAterm(n))); // Special case for types is because of traversal problems } break; } #if 0 printf ("Base of switch statement in convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str()); #endif assert (term); term = ATsetAnnotation(term, ATmake("ptr"), pointerAsAterm(n)); #if 1 if (n->get_file_info() != NULL) { term = ATsetAnnotation(term, ATmake("location"),convertFileInfoToAterm(n->get_file_info())); } if (isSgExpression(n)) term = ATsetAnnotation(term, ATmake("type"), convertNodeToAterm(isSgExpression(n)->get_type())); #endif #if 0 printf ("Leaving convertNodeToAterm(): n = %p = %s \n",n,n->class_name().c_str()); #endif #if 0 printf ("--- n->class_name() = %s ATwriteToString(term) = %s \n",n->class_name().c_str(),ATwriteToString(term)); #endif // cout << n->sage_class_name() << " -> " << ATwriteToString(term) << endl; return term; }
void FixupSelfReferentialMacrosInAST::visit ( SgNode* node ) { // DQ (3/11/2006): Set NULL pointers where we would like to have none. // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str()); ROSE_ASSERT(node != NULL); switch (node->variantT()) { case V_SgInitializedName: { SgInitializedName* initializedName = isSgInitializedName(node); ROSE_ASSERT(initializedName != NULL); SgType* type = initializedName->get_type()->stripType(); SgClassType* classType = isSgClassType(type); if (classType != NULL) { SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration()); SgName className = targetClassDeclaration->get_name(); // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str()); if (className == "sigaction") { // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n"); // Note we could also check that the declaration came from a known header file. SgStatement* associatedStatement = isSgStatement(initializedName->get_parent()); if (associatedStatement != NULL) { // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro. // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n"); // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos ); PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration; std::string macroString = "#undef sa_handler\n"; std::string filenameString = "macro_call_fixupSelfReferentialMacrosInAST"; int line_no = 1; int col_no = 1; int nol = 1; PreprocessingInfo::RelativePositionType relPos = PreprocessingInfo::before; PreprocessingInfo* macro = new PreprocessingInfo(directiveType,macroString,filenameString,line_no,col_no,nol,relPos); // printf ("Attaching CPP directive %s to IR node %p as attributes. \n",PreprocessingInfo::directiveTypeName(macro->getTypeOfDirective()).c_str(),associatedStatement); associatedStatement->addToAttachedPreprocessingInfo(macro); #if 0 printf ("Exiting as a test! \n"); ROSE_ASSERT(false); #endif } } } } default: { // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str()); } } }
Detection_InheritedAttribute DetectionTraversal::evaluateInheritedAttribute (SgNode* astNode, Detection_InheritedAttribute inheritedAttribute ) { #if 0 printf ("In DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str()); #endif // DQ (2/3/2016): Recognize IR nodes that are representative of target DSL abstractions. bool foundTargetDslAbstraction = DSL_Support::isDslAbstraction(astNode); #if 1 printf ("In DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s: foundTargetDslAbstraction = %s \n",astNode,astNode->class_name().c_str(),foundTargetDslAbstraction ? "true" : "false"); #endif #if 0 // OLD CODE (represented by DSL_Support::isDslAbstraction() function). // Detection of stencil declaration and stencil operator. // Where the stencil specification is using std::vectors as parameters to the constructor, we have to first // find the stencil declaration and read the associated SgVarRefExp to get the variable names used. // Then a finite state machine can be constructed for each of the input variables so that we can // interpret the state when the stencil operator is constructed. SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(astNode); if (variableDeclaration != NULL) { // Get the SgInitializedName from the SgVariableDeclaration. SgInitializedName* initializedName = SageInterface::getFirstInitializedName(variableDeclaration); SgType* base_type = initializedName->get_type()->findBaseType(); ROSE_ASSERT(base_type != NULL); // SgClassType* classType = isSgClassType(initializedName->get_type()); SgClassType* classType = isSgClassType(base_type); if (classType != NULL) { #if 1 printf ("In DetectionTraversal::evaluateInheritedAttribute(): case SgClassType: class name = %s \n",classType->get_name().str()); #endif // Check if this is associated with a template instantiation. SgTemplateInstantiationDecl* templateInstantiationDecl = isSgTemplateInstantiationDecl(classType->get_declaration()); if (templateInstantiationDecl != NULL) { #if 1 printf ("case SgTemplateInstaiationDecl: class name = %s \n",classType->get_name().str()); printf ("case SgTemplateInstaiationDecl: templateInstantiationDecl->get_templateName() = %s \n",templateInstantiationDecl->get_templateName().str()); #endif // inheritedAttribute.set_StencilDeclaration(templateInstantiationDecl->get_templateName() == "Stencil"); // inheritedAttribute.set_StencilOperatorDeclaration(templateInstantiationDecl->get_templateName() == "StencilOperator"); if (templateInstantiationDecl->get_templateName() == "Stencil") { // DQ (2/8/2015): Ignore compiler generated IR nodes (from template instantiations, etc.). // Note that simpleCNS.cpp generates one of these from it's use of the tuple template and associated template instantations. // DQ: Test the DSL support. ROSE_ASSERT(isMatchingClassType(classType,"Stencil",true) == true); checkAndResetToMakeConsistantCompilerGenerated(initializedName); if (initializedName->isCompilerGenerated() == false) { // Save the SgInitializedName associated with the stencil. // stencilInitializedNameList.push_back(initializedName); // inheritedAttribute.set_StencilDeclaration(true); // foundStencilVariable = true; #if 1 printf ("Detected Stencil<> typed variable: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str()); // printf (" --- stencilInitializedNameList.size() = %zu \n",stencilInitializedNameList.size()); #endif #if 1 initializedName->get_file_info()->display("In DetectionTraversal::evaluateInheritedAttribute(): initializedName : debug"); #endif #if 0 Stencil_Attribute* dslAttribute = new Stencil_Attribute(); #if 1 printf ("Adding (Stencil) dslAttribute = %p \n",dslAttribute); #endif ROSE_ASSERT(dslAttribute != NULL); // virtual void addNewAttribute (std::string s, AstAttribute *a); initializedName->addNewAttribute(StencilVariable,dslAttribute); #endif } } } SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration()); if (classDeclaration != NULL) { if (classDeclaration->get_name() == "Point") { // Save the SgInitializedName associated with the Point type. #if 0 printf ("Detected Point<> typed variable: initializedName = %p name = %s \n",initializedName,initializedName->get_name().str()); #endif checkAndResetToMakeConsistantCompilerGenerated(initializedName); if (initializedName->isCompilerGenerated() == false) { // pointInitializedNameList.push_back(initializedName); #if 0 Point_Attribute* dslAttribute = new Point_Attribute(); printf ("Adding (Point) dslAttribute = %p \n",dslAttribute); ROSE_ASSERT(dslAttribute != NULL); // virtual void addNewAttribute (std::string s, AstAttribute *a); initializedName->addNewAttribute(PointVariable,dslAttribute); #endif } } } } } #endif #if 1 printf ("Leaving DetectionTraversal::evaluateInheritedAttribute(): astNode = %p = %s \n",astNode,astNode->class_name().c_str()); #endif // Construct the return attribute from the modified input attribute. return Detection_InheritedAttribute(inheritedAttribute); }
void FixupSelfReferentialMacrosInAST::visit ( SgNode* node ) { // DQ (3/11/2006): Set NULL pointers where we would like to have none. // printf ("In FixupSelfReferentialMacrosInAST::visit(): node = %s \n",node->class_name().c_str()); ROSE_ASSERT(node != NULL); switch (node->variantT()) { case V_SgInitializedName: { SgInitializedName* initializedName = isSgInitializedName(node); ROSE_ASSERT(initializedName != NULL); SgType* type = initializedName->get_type()->stripType(); SgClassType* classType = isSgClassType(type); if (classType != NULL) { SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(classType->get_declaration()); SgName className = targetClassDeclaration->get_name(); // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a class declaration name = %s \n",className.str()); // For sudo_exec_pty.c also look for siginfo if (className == "sigaction" || className == "siginfo") { // printf ("In FixupSelfReferentialMacrosInAST::visit(): Found a sigaction type \n"); // Note we could also check that the declaration came from a known header file. SgStatement* associatedStatement = isSgStatement(initializedName->get_parent()); if (associatedStatement != NULL) { // Add a macro to undefine the "#define sa_handler __sigaction_handler.sa_handler" macro. // printf ("In FixupSelfReferentialMacrosInAST::visit(): Add a macro to undefine the macro #define sa_handler __sigaction_handler.sa_handler \n"); // PreprocessingInfo* macro = new PreprocessingInfo(DirectiveType, const std::string & inputString,const std::string & filenameString, int line_no , int col_no,int nol, RelativePositionType relPos ); PreprocessingInfo::DirectiveType directiveType = PreprocessingInfo::CpreprocessorUndefDeclaration; // We are puting out all macros anytime we see either type. This might be too much... // From the sigaction.h file (included by signal.h): addMacro(associatedStatement,"#undef sa_handler\n",directiveType); addMacro(associatedStatement,"#undef sa_sigaction\n",directiveType); // From the siginfo.h file (included by signal.h): addMacro(associatedStatement,"#undef si_pid\n", directiveType); addMacro(associatedStatement,"#undef si_uid\n", directiveType); addMacro(associatedStatement,"#undef si_timerid\n",directiveType); addMacro(associatedStatement,"#undef si_overrun\n",directiveType); addMacro(associatedStatement,"#undef si_status\n", directiveType); addMacro(associatedStatement,"#undef si_utime\n", directiveType); addMacro(associatedStatement,"#undef si_stime\n", directiveType); addMacro(associatedStatement,"#undef si_value\n", directiveType); addMacro(associatedStatement,"#undef si_int\n", directiveType); addMacro(associatedStatement,"#undef si_ptr\n", directiveType); addMacro(associatedStatement,"#undef si_addr\n", directiveType); addMacro(associatedStatement,"#undef si_band\n", directiveType); addMacro(associatedStatement,"#undef si_fd\n", directiveType); } } } } default: { // printf ("Not handled in FixupSelfReferentialMacrosInAST::visit(%s) \n",node->class_name().c_str()); } } #if 0 // DQ (12/30/2013): Comments and CPP directives have not yet been attached to the AST, so we can't process them here. // SgLocatedNode* locatedNode = isSgLocatedNode(node); // if (locatedNode != NULL) SgStatement* stmt = isSgStatement(node); if (stmt != NULL) { // Find all #define statements and look for self referencing macros int numberOfComments = -1; if (stmt->getAttachedPreprocessingInfo() != NULL) numberOfComments = stmt->getAttachedPreprocessingInfo()->size(); std::string s = std::string(" --- startOfConstruct: file = " ) + stmt->get_startOfConstruct()->get_filenameString() + " raw filename = " + stmt->get_startOfConstruct()->get_raw_filename() + " raw line = " + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_line()) + " raw column = " + StringUtility::numberToString(stmt->get_startOfConstruct()->get_raw_col()) + " #comments = " + StringUtility::numberToString(numberOfComments) + " \n "; AttachedPreprocessingInfoType* comments = stmt->getAttachedPreprocessingInfo(); if (comments != NULL) { printf ("Found attached comments (at %p of type: %s): \n",stmt,stmt->class_name().c_str()); AttachedPreprocessingInfoType::iterator i; for (i = comments->begin(); i != comments->end(); i++) { ROSE_ASSERT ( (*i) != NULL ); printf (" Attached Comment (relativePosition=%s): %s\n", ((*i)->getRelativePosition() == PreprocessingInfo::before) ? "before" : "after", (*i)->getString().c_str()); printf ("Comment/Directive getNumberOfLines = %d getColumnNumberOfEndOfString = %d \n",(*i)->getNumberOfLines(),(*i)->getColumnNumberOfEndOfString()); (*i)->get_file_info()->display("comment/directive location"); } } else { printf ("No attached comments (at %p of type: %s): \n",stmt,stmt->class_name().c_str()); } } #endif }
void ProcTraversal::visit(SgNode *node) { if (isSgFunctionDeclaration(node)) { SgFunctionDeclaration *decl = isSgFunctionDeclaration(node); if (decl->get_definition() != NULL) { /* collect statistics */ //AstNumberOfNodesStatistics anons; //anons.traverse(decl, postorder); //original_ast_nodes += anons.get_numberofnodes(); //original_ast_statements += anons.get_numberofstatements(); /* do the real work */ Procedure *proc = new Procedure(); proc->procnum = procnum++; proc->decl = decl; proc->funcsym = isSgFunctionSymbol(decl->get_symbol_from_symbol_table()); if (proc->funcsym == NULL) { #if 0 std::cout << std::endl << "*** NULL function symbol for declaration " << decl->unparseToString() << std::endl << "symbol: " << (void *) decl->get_symbol_from_symbol_table() << (decl->get_symbol_from_symbol_table() != NULL ? decl->get_symbol_from_symbol_table()->class_name() : "") << std::endl << "first nondef decl: " << (void *) decl->get_firstNondefiningDeclaration() << " sym: " << (decl->get_firstNondefiningDeclaration() != NULL ? (void *) decl->get_firstNondefiningDeclaration() ->get_symbol_from_symbol_table() : (void *) NULL) << std::endl; #endif if (decl->get_firstNondefiningDeclaration() != NULL) { proc->funcsym = isSgFunctionSymbol(decl ->get_firstNondefiningDeclaration() ->get_symbol_from_symbol_table()); } } assert(proc->funcsym != NULL); // GB (2008-05-14): We need two parameter lists: One for the names of the // variables inside the function definition, which is // decl->get_parameterList(), and one that contains any default arguments // the function might have. The default arguments are supposedly // associated with the first nondefining declaration. proc->params = decl->get_parameterList(); SgDeclarationStatement *fndstmt = decl->get_firstNondefiningDeclaration(); SgFunctionDeclaration *fnd = isSgFunctionDeclaration(fndstmt); if (fnd != NULL && fnd != decl) proc->default_params = fnd->get_parameterList(); else proc->default_params = proc->params; SgMemberFunctionDeclaration *mdecl = isSgMemberFunctionDeclaration(decl); if (mdecl) { proc->class_type = isSgClassDefinition(mdecl->get_scope()); std::string name = proc->class_type->get_mangled_name().str(); name += "::"; name += decl->get_name().str(); std::string mname = proc->class_type->get_mangled_name().str(); mname += "::"; mname += decl->get_mangled_name().str(); proc->memberf_name = name; proc->mangled_memberf_name = mname; proc->name = decl->get_name().str(); proc->mangled_name = decl->get_mangled_name().str(); // GB (2008-05-26): Computing a single this symbol for each // procedure. Thus, this symbol can also be compared by pointer // equality (as is the case for all other symbols). While we're at it, // we also build a VarRefExp for this which can be used everywhere the // this pointer occurs. proc->this_type = Ir::createPointerType( proc->class_type->get_declaration()->get_type()); proc->this_sym = Ir::createVariableSymbol("this", proc->this_type); proc->this_exp = Ir::createVarRefExp(proc->this_sym); } else { proc->name = decl->get_name().str(); proc->mangled_name = decl->get_mangled_name().str(); proc->class_type = NULL; proc->memberf_name = proc->mangled_memberf_name = ""; proc->this_type = NULL; proc->this_sym = NULL; proc->this_exp = NULL; // GB (2008-07-01): Better resolution of calls to static functions. // This only makes sense for non-member functions. SgStorageModifier &sm = (fnd != NULL ? fnd : decl)->get_declarationModifier().get_storageModifier(); proc->isStatic = sm.isStatic(); // Note that we query the first nondefining declaration for the // static modifier, but we save the file of the *defining* // declaration. This is because the first declaration might be in // some header file, but for call resolution, the actual source // file with the definition is relevant. // Trace back to the enclosing file node. The definition might be // included in foo.c from bar.c, in which case the Sg_File_Info // would refer to bar.c; but for function call resolution, foo.c is // the relevant file. SgNode *p = decl->get_parent(); while (p != NULL && !isSgFile(p)) p = p->get_parent(); proc->containingFile = isSgFile(p); } proc_map.insert(std::make_pair(proc->name, proc)); mangled_proc_map.insert(std::make_pair(proc->mangled_name, proc)); std::vector<SgVariableSymbol* >* arglist = new std::vector<SgVariableSymbol* >(); SgVariableSymbol *this_var = NULL, *this_temp_var = NULL; if (mdecl || decl->get_parameterList() != NULL && !decl->get_parameterList()->get_args().empty()) { proc->arg_block = new BasicBlock(node_id, INNER, proc->procnum); if (mdecl) { // GB (2008-05-26): We now compute the this pointer right at the // beginning of building the procedure. // this_var = Ir::createVariableSymbol("this", this_type); this_var = proc->this_sym; // std::string varname // = std::string("$") + proc->name + "$this"; // this_temp_var = Ir::createVariableSymbol(varname, proc->this_type); this_temp_var = global_this_variable_symbol; ParamAssignment* paramAssignment = Ir::createParamAssignment(this_var, this_temp_var); proc->arg_block->statements.push_back(paramAssignment); arglist->push_back(this_var); if (proc->name.find('~') != std::string::npos) { arglist->push_back(this_temp_var); } } SgInitializedNamePtrList params = proc->params->get_args(); SgInitializedNamePtrList::const_iterator i; #if 0 int parnum = 0; for (i = params.begin(); i != params.end(); ++i) { SgVariableSymbol *i_var = Ir::createVariableSymbol(*i); std::stringstream varname; // varname << "$" << proc->name << "$arg_" << parnum++; SgVariableSymbol* var = Ir::createVariableSymbol(varname.str(),(*i)->get_type()); proc->arg_block->statements.push_back(Ir::createParamAssignment(i_var, var)); arglist->push_back(i_var); } #else // GB (2008-06-23): Trying to replace all procedure-specific argument // variables by a global list of argument variables. This means that at // this point, we do not necessarily need to build a complete list but // only add to the CFG's argument list if it is not long enough. size_t func_params = params.size(); size_t global_args = global_argument_variable_symbols.size(); std::stringstream varname; while (global_args < func_params) { varname.str(""); varname << "$tmpvar$arg_" << global_args++; SgVariableSymbol *var = Ir::createVariableSymbol(varname.str(), global_unknown_type); program->global_map[varname.str()] = std::make_pair(var, var->get_declaration()); global_argument_variable_symbols.push_back(var); } // now create the param assignments size_t j = 0; for (i = params.begin(); i != params.end(); ++i) { SgVariableSymbol *i_var = Ir::createVariableSymbol(params[j]); SgVariableSymbol *var = global_argument_variable_symbols[j]; j++; proc->arg_block->statements.push_back( Ir::createParamAssignment(i_var, var)); arglist->push_back(i_var); } #if 0 // replace the arglist allocated above by the new one; this must be // fixed for this pointers! delete arglist; arglist = &global_argument_variable_symbols; #endif #endif } else { proc->arg_block = NULL; } /* If this is a constructor, call default constructors * of all base classes. If base class constructors are * called manually, these calls will be removed later. */ if (mdecl && strcmp(mdecl->get_name().str(), proc->class_type->get_declaration()->get_name().str()) == 0 && proc->class_type != NULL) { SgBaseClassPtrList::iterator base; for (base = proc->class_type->get_inheritances().begin(); base != proc->class_type->get_inheritances().end(); ++base) { SgClassDeclaration* baseclass = (*base)->get_base_class(); SgVariableSymbol *lhs = Ir::createVariableSymbol("$tmpvar$" + baseclass->get_name(), baseclass->get_type()); program->global_map["$tmpvar$" + baseclass->get_name()] = std::make_pair(lhs, lhs->get_declaration()); SgMemberFunctionDeclaration* fd=get_default_constructor(baseclass); assert(fd); SgType* basetype=baseclass->get_type(); assert(basetype); SgConstructorInitializer *sci = Ir::createConstructorInitializer(fd,basetype); ArgumentAssignment* a = Ir::createArgumentAssignment(lhs, sci); proc->arg_block->statements.push_back(a); // std::string this_called_varname // = std::string("$") + baseclass->get_name() + "$this"; SgVariableSymbol *this_called_var // = Ir::createVariableSymbol(this_called_varname, // baseclass->get_type()); = global_this_variable_symbol; ReturnAssignment* this_ass = Ir::createReturnAssignment(this_var, this_called_var); proc->arg_block->statements.push_back(this_ass); } } if (mdecl && mdecl->get_CtorInitializerList() != NULL && !mdecl->get_CtorInitializerList()->get_ctors().empty()) { SgInitializedNamePtrList cis = mdecl->get_CtorInitializerList()->get_ctors(); SgInitializedNamePtrList::const_iterator i; if (proc->arg_block == NULL) { proc->arg_block = new BasicBlock(node_id, INNER, proc->procnum); } for (i = cis.begin(); i != cis.end(); ++i) { SgVariableSymbol* lhs = Ir::createVariableSymbol(*i); SgAssignInitializer *ai = isSgAssignInitializer((*i)->get_initializer()); SgConstructorInitializer *ci = isSgConstructorInitializer((*i)->get_initializer()); /* TODO: other types of initializers */ if (ai) { SgClassDeclaration *class_decl = proc->class_type->get_declaration(); // GB (2008-05-26): We now compute the this pointer right at the // beginning of building the procedure. // SgVarRefExp* this_ref // = Ir::createVarRefExp("this", // Ir::createPointerType(class_decl->get_type())); SgVarRefExp* this_ref = proc->this_exp; SgArrowExp* arrowExp = Ir::createArrowExp(this_ref,Ir::createVarRefExp(lhs)); // GB (2008-03-17): We need to handle function calls in // initializers. In order to be able to build an argument // assignment, we need to know the function's return variable, so // the expression labeler must be called on it. The expression // number is irrelevant, however, as it does not appear in the // return variable. if (isSgFunctionCallExp(ai->get_operand_i())) { #if 0 ExprLabeler el(0 /*expnum*/); el.traverse(ai->get_operand_i(), preorder); // expnum = el.get_expnum(); #endif // GB (2008-06-25): There is now a single global return // variable. This may or may not mean that we can simply ignore // the code above. I don't quite understand why this labeling // couldn't be done later on, and where its result was used. } ArgumentAssignment* argumentAssignment = Ir::createArgumentAssignment(arrowExp,ai->get_operand_i()); proc->arg_block->statements.push_back(argumentAssignment); } else if (ci) { /* if this is a call to a base class's * constructor, remove the call we generated * before */ SgStatement* this_a = NULL; SgClassDeclaration* cd = ci->get_class_decl(); std::deque<SgStatement *>::iterator i; for (i = proc->arg_block->statements.begin(); i != proc->arg_block->statements.end(); ++i) { ArgumentAssignment* a = dynamic_cast<ArgumentAssignment *>(*i); if (a && isSgConstructorInitializer(a->get_rhs())) { SgConstructorInitializer* c = isSgConstructorInitializer(a->get_rhs()); std::string c_decl_name = c->get_class_decl()->get_name().str(); std::string cd_name = cd->get_name().str(); // if (c->get_class_decl()->get_name() == cd->get_name()) { if (c_decl_name == cd_name) { #if 0 // erase the following assignment // of the this pointer as well this_a = *proc->arg_block->statements.erase(i+1); proc->arg_block->statements.erase(i); #endif // GB (2008-03-28): That's an interesting piece of code, but // it might be very mean to iterators. At least it is hard to // see whether it is correct. So let's try it like this: // erase i; we get an iterator back, which refers to the next // element. Save that element as this_a, and then erase. std::deque<SgStatement *>::iterator this_pos; this_pos = proc->arg_block->statements.erase(i); this_a = *this_pos; proc->arg_block->statements.erase(this_pos); // Good. Looks like this fixed a very obscure bug. break; } } } /* now add the initialization */ proc->arg_block->statements.push_back(Ir::createArgumentAssignment(lhs, ci)); if (this_a != NULL) proc->arg_block->statements.push_back(this_a); } } } proc->entry = new CallBlock(node_id++, START, proc->procnum, new std::vector<SgVariableSymbol *>(*arglist), (proc->memberf_name != "" ? proc->memberf_name : proc->name)); proc->exit = new CallBlock(node_id++, END, proc->procnum, new std::vector<SgVariableSymbol *>(*arglist), (proc->memberf_name != "" ? proc->memberf_name : proc->name)); proc->entry->partner = proc->exit; proc->exit->partner = proc->entry; proc->entry->call_target = Ir::createFunctionRefExp(proc->funcsym); proc->exit->call_target = Ir::createFunctionRefExp(proc->funcsym); /* In constructors, insert an assignment $A$this = this * at the end to make sure that the 'this' pointer can be * passed back to the calling function uncobbled. */ proc->this_assignment = NULL; if (mdecl) { SgMemberFunctionDeclaration* cmdecl = isSgMemberFunctionDeclaration(mdecl->get_firstNondefiningDeclaration()); // if (cmdecl && cmdecl->get_specialFunctionModifier().isConstructor()) { proc->this_assignment = new BasicBlock(node_id++, INNER, proc->procnum); ReturnAssignment* returnAssignment = Ir::createReturnAssignment(this_temp_var, this_var); proc->this_assignment->statements.push_back(returnAssignment); add_link(proc->this_assignment, proc->exit, NORMAL_EDGE); // } } std::stringstream varname; // varname << "$" << proc->name << "$return"; // proc->returnvar = Ir::createVariableSymbol(varname.str(), // decl->get_type()->get_return_type()); proc->returnvar = global_return_variable_symbol; procedures->push_back(proc); if(getPrintCollectedFunctionNames()) { std::cout << (proc->memberf_name != "" ? proc->memberf_name : proc->name) << " " /*<< proc->decl << std::endl*/; } if (proc->arg_block != NULL) { proc->arg_block->call_target = Ir::createFunctionRefExp(proc->funcsym); } // delete arglist; } } }
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; }
bool FixupTemplateArguments::contains_private_type (SgType* type, SgScopeStatement* targetScope) { // DQ (4/2/2018): Note that this function now addresses requirements of supporting both private and protected types. #if DEBUGGING_USING_RECURSIVE_DEPTH // For debugging, keep track of the recursive depth. static size_t depth = 0; printf ("In contains_private_type(SgType*): depth = %zu \n",depth); ROSE_ASSERT(depth < 500); printf ("In contains_private_type(SgType*): global_depth = %zu \n",global_depth); ROSE_ASSERT(global_depth < 55); #endif // Note this is the recursive function. bool returnValue = false; #if DEBUG_PRIVATE_TYPE || 0 // DQ (1/7/2016): It is a problem to do this for some files (failing about 35 files in Cxx_tests). // The issues appears to be in the unparsing of the template arguments of the qualified names for the types. // printf ("In contains_private_type(SgType*): type = %p = %s = %s \n",type,type->class_name().c_str(),type->unparseToString().c_str()); printf ("In contains_private_type(SgType*): type = %p = %s \n",type,type->class_name().c_str()); #endif SgTypedefType* typedefType = isSgTypedefType(type); if (typedefType != NULL) { // Get the associated declaration. SgTypedefDeclaration* typedefDeclaration = isSgTypedefDeclaration(typedefType->get_declaration()); ROSE_ASSERT(typedefDeclaration != NULL); #if 0 bool isPrivate = typedefDeclaration->get_declarationModifier().get_accessModifier().isPrivate(); #else // DQ (4/2/2018): Fix this to address requirements of both private and protected class members (see Cxx11_tests/test2018_71.C). bool isPrivate = typedefDeclaration->get_declarationModifier().get_accessModifier().isPrivate() || typedefDeclaration->get_declarationModifier().get_accessModifier().isProtected(); #endif #if DEBUG_PRIVATE_TYPE || 0 printf ("typedefDeclaration isPrivate = %s \n",isPrivate ? "true" : "false"); #endif // First we need to know if this is a visable type. bool isVisable = false; #if 0 printf ("targetScope = %p = %s \n",targetScope,targetScope->class_name().c_str()); // printf ("typedefDeclaration = %p = %s \n",typedefDeclaration,typedefDeclaration->class_name().c_str()); printf ("typedefDeclaration->get_scope() = %p = %s \n",typedefDeclaration->get_scope(),typedefDeclaration->get_scope()->class_name().c_str()); #endif #if 0 printf ("SageInterface::whereAmI(targetScope): \n"); SageInterface::whereAmI(targetScope); printf ("SageInterface::whereAmI(typedefDeclaration): \n"); SageInterface::whereAmI(typedefDeclaration); #endif #if 0 printf ("\ntargetScope symbol table: \n"); targetScope->get_symbol_table()->print("targetScope"); printf ("end of symbol table \n"); printf ("\ntypedefDeclaration->get_scope() symbol table: \n"); typedefDeclaration->get_scope()->get_symbol_table()->print("typedefDeclaration->get_scope()"); printf ("end of symbol table \n\n"); #endif // Test for the trivial case of matching scope (an even better test (below) is be to make sure that the targetScope is nested in the typedef scope). if (typedefDeclaration->get_scope() == targetScope) { #if 0 printf ("In contains_private_type(SgType*): This is a typedef type from the same scope as the target declaration \n"); #endif // ROSE_ASSERT(false); // return false; isVisable = true; } else { // SgTypedefSymbol* lookupTypedefSymbolInParentScopes (const SgName & name, SgScopeStatement *currentScope = NULL); SgTypedefSymbol* typedefSymbol = SageInterface::lookupTypedefSymbolInParentScopes (typedefDeclaration->get_name(),targetScope); if (typedefSymbol != NULL) { #if 0 printf ("In contains_private_type(SgType*): This is not in the current scope but can be reached from the current scope \n"); #endif // ROSE_ASSERT(false); // return false; isVisable = true; } else { #if 0 printf ("Symbol for typedef name = %s not found in parent scopes \n",typedefDeclaration->get_name().str()); #endif // ROSE_ASSERT(false); } } #if 0 // Testing codes because it seems that "BitSet" shuld be visiable and so we need to debug this first. if (typedefDeclaration->get_name() == "BitSet") { printf ("Exiting as a test! \n"); ROSE_ASSERT(false); } #endif // If this is not private, then we are looking at what would be possbile template arguments used in a possible name qualification. // if (isPrivate == false) // if (isPrivate == false && isVisable == false) if (isVisable == false) { if (isPrivate == true) { return true; } else { // Get the scope and see if it is a template instantiation. SgScopeStatement* scope = typedefDeclaration->get_scope(); #if DEBUG_PRIVATE_TYPE || 0 printf ("++++++++++++++ Looking in parent scope for template arguments: scope = %p = %s \n",scope,scope->class_name().c_str()); #endif // Get the associated declaration. switch (scope->variantT()) { case V_SgTemplateInstantiationDefn: { SgTemplateInstantiationDefn* templateInstantiationDefinition = isSgTemplateInstantiationDefn(scope); ROSE_ASSERT(templateInstantiationDefinition != NULL); SgTemplateInstantiationDecl* templateInstantiationDeclaration = isSgTemplateInstantiationDecl(templateInstantiationDefinition->get_declaration()); ROSE_ASSERT(templateInstantiationDeclaration != NULL); SgTemplateArgumentPtrList & templateArgumentPtrList = templateInstantiationDeclaration->get_templateArguments(); for (SgTemplateArgumentPtrList::iterator i = templateArgumentPtrList.begin(); i != templateArgumentPtrList.end(); i++) { #if DEBUG_PRIVATE_TYPE printf ("recursive call to contains_private_type(%p): name = %s = %s \n",*i,(*i)->class_name().c_str(),(*i)->unparseToString().c_str()); #endif #if DEBUGGING_USING_RECURSIVE_DEPTH global_depth++; #endif bool isPrivateType = contains_private_type(*i,targetScope); #if DEBUGGING_USING_RECURSIVE_DEPTH global_depth--; #endif returnValue |= isPrivateType; } break; } default: { #if DEBUG_PRIVATE_TYPE printf ("Ignoring non-SgTemplateInstantiationDefn \n"); #endif } } } } else { // If it is visible then it need not be qualified and we don't care about if it was private. ROSE_ASSERT(isVisable == true); // returnValue = true; returnValue = false; } } else { #if DEBUG_PRIVATE_TYPE || 0 printf ("could be a wrapped type: type = %p = %s (not a template class instantiaton) \n",type,type->class_name().c_str()); if (isSgModifierType(type) != NULL) { SgModifierType* modifierType = isSgModifierType(type); SgType* base_type = modifierType->get_base_type(); printf ("--- base_type = %p = %s \n",base_type,base_type->class_name().c_str()); SgNamedType* namedType = isSgNamedType(base_type); if (namedType != NULL) { printf ("--- base_type: name = %s \n",namedType->get_name().str()); } } #endif // If this is a default SgModifierType then unwrap it. #if 0 SgModifierType* modifierType = isSgModifierType(type); if (modifierType != NULL) { #error "DEAD CODE!" // What kind of modifier is this? printf ("What kind of type modifier: %s \n",modifierType->get_typeModifier().displayString().c_str()); if (modifierType->get_typeModifier().isDefault() == true) { // This is a default mode modifier (acting as a wrapper type). type = modifierType->get_base_type(); } else { printf ("Not a default modifierType wrapper (need to handle this case) \n"); ROSE_ASSERT(false); } } #else // Strip past pointers and other wrapping modifiers (but not the typedef types, since the whole point is to detect private instatances). type = type->stripType(SgType::STRIP_MODIFIER_TYPE|SgType::STRIP_REFERENCE_TYPE|SgType::STRIP_RVALUE_REFERENCE_TYPE|SgType::STRIP_POINTER_TYPE|SgType::STRIP_ARRAY_TYPE); #endif #if 0 printf ("After stripType(): type = %p = %s \n",type,type->class_name().c_str()); SgNamedType* namedType = isSgNamedType(type); if (namedType != NULL) { printf ("--- stripType: name = %s \n",namedType->get_name().str()); } #endif ROSE_ASSERT(type != NULL); // Make sure this is not a simple template type (else we will have infinite recursion). // if (type != NULL && type->isIntegerType() == false && type->isFloatType() == false) // if (type != NULL) SgTemplateType* templateType = isSgTemplateType(type); SgClassType* classType = isSgClassType(type); SgTypeVoid* voidType = isSgTypeVoid(type); SgRvalueReferenceType* rvalueReferenceType = isSgRvalueReferenceType(type); SgFunctionType* functionType = isSgFunctionType(type); SgDeclType* declType = isSgDeclType(type); // DQ (12/7/2016): An enum type needs to be handled since the declaration might be private (but still debugging this for now). SgEnumType* enumType = isSgEnumType(type); // DQ (2/12/2017): Added specific type (causing infinite recursion for CompileTests/RoseExample_tests/testRoseHeaders_03.C. SgTypeEllipse* typeEllipse = isSgTypeEllipse(type); SgTypeUnknown* typeUnknown = isSgTypeUnknown(type); SgTypeComplex* typeComplex = isSgTypeComplex(type); // DQ (2/16/2017): This is a case causeing many C codes to fail. SgTypeOfType* typeOfType = isSgTypeOfType(type); if (type != NULL && templateType == NULL && classType == NULL && voidType == NULL && rvalueReferenceType == NULL && functionType == NULL && declType == NULL && enumType == NULL && typeEllipse == NULL && typeUnknown == NULL && typeComplex == NULL && typeOfType == NULL) { #if DEBUG_PRIVATE_TYPE || 0 printf ("found unwrapped type = %p = %s = %s (not a template class instantiaton) \n",type,type->class_name().c_str(),type->unparseToString().c_str()); #endif // if (type->isIntegerType() == false && type->isFloatType() == false) // if (type->isIntegerType() == false && type->isFloatType() == false) if (type->isIntegerType() == false && type->isFloatType() == false) { #if DEBUG_PRIVATE_TYPE || 0 printf ("Making a recursive call to contains_private_type(type): not integer or float type: type = %p = %s \n",type,type->class_name().c_str()); #endif #if DEBUGGING_USING_RECURSIVE_DEPTH depth++; global_depth++; #endif bool isPrivateType = contains_private_type(type,targetScope); #if DEBUGGING_USING_RECURSIVE_DEPTH depth--; global_depth--; #endif returnValue = isPrivateType; } else { // This can't be a private type. #if DEBUG_PRIVATE_TYPE printf ("This is an integer or float type (of some sort): type = %p = %s = %s \n",type,type->class_name().c_str(),type->unparseToString().c_str()); #endif returnValue = false; } } else { // This is where we need to resolve is any types that are associated with declarations might be private (e.g. SgEnumType). if (classType != NULL) { // Check if this is associated with a template class instantiation. #if 0 SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration()); ROSE_ASSERT(classDeclaration != NULL); printf ("--------- classDeclaration = %p = %s = %s \n",classDeclaration,classDeclaration->class_name().c_str(),classDeclaration->get_name().str()); #endif SgTemplateInstantiationDecl* templateInstantiationDeclaration = isSgTemplateInstantiationDecl(classType->get_declaration()); if (templateInstantiationDeclaration != NULL) { #if DEBUGGING_USING_RECURSIVE_DEPTH global_depth++; #endif #if 0 printf ("Calling contains_private_type(SgTemplateArgumentPtrList): templateInstantiationDeclaration = %p = %s \n", templateInstantiationDeclaration,templateInstantiationDeclaration->get_name().str()); #endif returnValue = contains_private_type(templateInstantiationDeclaration->get_templateArguments(),targetScope); #if DEBUGGING_USING_RECURSIVE_DEPTH global_depth--; #endif #if 0 printf ("DONE: Calling contains_private_type(SgTemplateArgumentPtrList): templateInstantiationDeclaration = %p = %s \n", templateInstantiationDeclaration,templateInstantiationDeclaration->get_name().str()); #endif } #if 0 printf ("DONE: --- classDeclaration = %p = %s = %s \n",classDeclaration,classDeclaration->class_name().c_str(),classDeclaration->get_name().str()); #endif } } } #if DEBUG_PRIVATE_TYPE || 0 printf ("Leaving contains_private_type(SgType*): type = %p = %s = %s returnValue = %s \n",type,type->class_name().c_str(),type->unparseToString().c_str(),returnValue ? "true" : "false"); #endif return returnValue; }
void FixupAstSymbolTables::visit ( SgNode* node ) { // DQ (6/27/2005): Output the local symbol table from each scope. // printf ("node = %s \n",node->sage_class_name()); SgScopeStatement* scope = isSgScopeStatement(node); if (scope != NULL) { #if 0 printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str()); #endif SgSymbolTable* symbolTable = scope->get_symbol_table(); if (symbolTable == NULL) { #if 0 printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str()); scope->get_file_info()->display("Symbol Table Location"); #endif SgSymbolTable* tempSymbolTable = new SgSymbolTable(); ROSE_ASSERT(tempSymbolTable != NULL); // name this table as compiler generated! The name is a static member used to store // state for the next_symbol() functions. It is meaningless to set these. // tempSymbolTable->set_name("compiler-generated symbol table"); scope->set_symbol_table(tempSymbolTable); // reset the symbolTable using the get_symbol_table() member function symbolTable = scope->get_symbol_table(); ROSE_ASSERT(symbolTable != NULL); // DQ (2/16/2006): Set this parent directly (now tested) symbolTable->set_parent(scope); ROSE_ASSERT(symbolTable->get_parent() != NULL); } ROSE_ASSERT(symbolTable != NULL); if (symbolTable->get_parent() == NULL) { printf ("Warning: Fixing up symbolTable, calling symbolTable->set_parent() (parent not previously set) \n"); symbolTable->set_parent(scope); } ROSE_ASSERT(symbolTable->get_parent() != NULL); // Make sure that the internal hash table used in the symbol table is also present! if (symbolTable->get_table() == NULL) { // DQ (6/27/2005): There are a lot of these built, perhaps more than we really need! #if 0 printf ("AST Fixup: Building internal Symbol Table hash table (rose_hash_multimap) for %p = %s at: \n", scope,scope->sage_class_name()); scope->get_file_info()->display("Symbol Table Location"); #endif rose_hash_multimap* internalHashTable = new rose_hash_multimap(); ROSE_ASSERT(internalHashTable != NULL); symbolTable->set_table(internalHashTable); } ROSE_ASSERT(symbolTable->get_table() != NULL); SgSymbolTable::BaseHashType* internalTable = symbolTable->get_table(); ROSE_ASSERT(internalTable != NULL); // DQ (6/23/2011): Note: Declarations that reference types that have not been seen yet may be placed into the // wronge scope, then later when we see the correct scope we have a symbol in two or more symbol tables. The // code below detects and fixes this problem. // DQ (6/16/2011): List of symbols we need to remove from symbol tables where they are multibily represented. std::vector<SgSymbol*> listOfSymbolsToRemove; // DQ (6/12/2011): Fixup symbol table by removing symbols that are not associated with a declaration in the current scope. int idx = 0; SgSymbolTable::hash_iterator i = internalTable->begin(); while (i != internalTable->end()) { // DQ: removed SgName casting operator to char* // cout << "[" << idx << "] " << (*i).first.str(); ROSE_ASSERT ( (*i).first.str() != NULL ); ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); // printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) sage_class_name() = %s \n", // idx,(*i).first.str(),(*i).second->sage_class_name()); SgSymbol* symbol = isSgSymbol((*i).second); ROSE_ASSERT ( symbol != NULL ); // We have to look at each type of symbol separately! This is because there is no virtual function, // the reason for this is that each get_declaration() function returns a different type! // ROSE_ASSERT ( symbol->get_declaration() != NULL ); switch(symbol->variantT()) { case V_SgClassSymbol: { SgClassSymbol* classSymbol = isSgClassSymbol(symbol); ROSE_ASSERT(classSymbol != NULL); ROSE_ASSERT(classSymbol->get_declaration() != NULL); SgDeclarationStatement* declarationToFindInScope = NULL; // Search for the declaration in the associated scope. declarationToFindInScope = classSymbol->get_declaration(); ROSE_ASSERT(declarationToFindInScope != NULL); SgClassDeclaration* classDeclaration = isSgClassDeclaration(declarationToFindInScope); ROSE_ASSERT(classDeclaration != NULL); SgName name = classDeclaration->get_name(); // SgType* declarationType = declarationToFindInScope->get_type(); SgType* declarationType = classDeclaration->get_type(); ROSE_ASSERT(declarationType != NULL); if (declarationToFindInScope->get_definingDeclaration() != NULL) { declarationToFindInScope = declarationToFindInScope->get_definingDeclaration(); SgClassDeclaration* definingClassDeclaration = isSgClassDeclaration(declarationToFindInScope); ROSE_ASSERT(definingClassDeclaration != NULL); // SgType* definingDeclarationType = declarationToFindInScope->get_type(); SgType* definingDeclarationType = definingClassDeclaration->get_type(); ROSE_ASSERT(definingDeclarationType != NULL); // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C // A simple rule that all declarations should follow (now that we have proper global type tables). // ROSE_ASSERT(definingDeclarationType == declarationType); if (definingDeclarationType != declarationType) { printf ("In fixupSymbolTables.C: Note that definingDeclarationType != declarationType \n"); } } SgNamedType* namedType = isSgNamedType(declarationType); ROSE_ASSERT(namedType != NULL); SgDeclarationStatement* declarationAssociatedToType = namedType->get_declaration(); ROSE_ASSERT(declarationAssociatedToType != NULL); #if 0 printf ("Found a symbol without a matching declaration in the current scope (declList): declarationToFindInScope = %p = %s \n",declarationToFindInScope,declarationToFindInScope->class_name().c_str()); printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) class_name() = %s \n",idx,(*i).first.str(),(*i).second->class_name().c_str()); #endif SgScopeStatement* scopeOfDeclarationToFindInScope = declarationToFindInScope->get_scope(); SgScopeStatement* scopeOfDeclarationAssociatedWithType = declarationAssociatedToType->get_scope(); #if 0 printf ("declarationToFindInScope = %p declarationToFindInScope->get_scope() = %p = %s \n",declarationToFindInScope,declarationToFindInScope->get_scope(),declarationToFindInScope->get_scope()->class_name().c_str()); printf ("declarationAssociatedToType = %p declarationAssociatedToType->get_scope() = %p = %s \n",declarationAssociatedToType,declarationAssociatedToType->get_scope(),declarationAssociatedToType->get_scope()->class_name().c_str()); #endif if (scopeOfDeclarationToFindInScope != scopeOfDeclarationAssociatedWithType) { // DQ (6/12/2011): Houston, we have a problem! The trick is to fix it... // A symbol has been placed into a scope when we could not be certain which scope it should be placed. // We have a default of placing such symbols into the global scope, but it might be better to just have // a special scope where such symbols could be placed so that we could have them separate from the global // scope and then fix them up more clearly. // Note that test2011_80.C still fails but the AST is at least correct (I think). SgGlobal* scopeOfDeclarationToFindInScope_GlobalScope = isSgGlobal(scopeOfDeclarationToFindInScope); // SgGlobal* scopeOfDeclarationAssociatedWithType_GlobalScope = isSgGlobal(scopeOfDeclarationAssociatedWithType); if (scopeOfDeclarationToFindInScope_GlobalScope != NULL) { // In general which ever scope is the global scope is where the error is...??? // This is because when we don't know where to put a symbol (e.g. from a declaration of a pointer) we put it into global scope. // There is even an agrument that this is correct as a default for C/C++, but only if it must exist (see test2011_80.C). // Remove the symbol from the symbol table of the global scope. printf ("Remove the associated symbol in the current symbol table \n"); // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope()); if (declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope()) printf ("In fixupSymbolTables.C: Note that declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope() \n"); } else { listOfSymbolsToRemove.push_back(classSymbol); } } // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope()); break; } default: { // It night be there are are no other types of symbols to consider... // printf ("Ignoring non SgClassSymbols (fixupSymbolTables.C) symbol = %s \n",symbol->class_name().c_str()); // ROSE_ASSERT(false); } } // Increment iterator! i++; // Increment counter! idx++; } // DQ (6/18/2011): Now that we are through with the symbol table we can support removal of any // identified problematic symbol without worrying about STL iterator invalidation. for (size_t j = 0; j < listOfSymbolsToRemove.size(); j++) { // Remove these symbols. SgSymbol* removeSymbol = listOfSymbolsToRemove[j]; ROSE_ASSERT(removeSymbol != NULL); SgSymbolTable* associatedSymbolTable = isSgSymbolTable(removeSymbol->get_parent()); ROSE_ASSERT(associatedSymbolTable != NULL); ROSE_ASSERT(associatedSymbolTable == symbolTable); associatedSymbolTable->remove(removeSymbol); printf ("Redundant symbol removed...from symbol table \n"); // ROSE_ASSERT(false); } #if 0 // debugging symbolTable->print("In FixupAstSymbolTables::visit(): printing out the symbol tables"); #endif } }
// DQ (8/27/2006): This functionality already exists elsewhere // It is a shame that it is recreated here as well !!! NameQuerySynthesizedAttributeType NameQuery::queryNameTypeName (SgNode * astNode) { ROSE_ASSERT (astNode != NULL); string typeName = ""; Rose_STL_Container< string > returnList; SgType *type = isSgType (astNode); // printf ("In TransformationSupport::getTypeName(): type->sage_class_name() = %s \n",type->sage_class_name()); if (type != NULL) switch (type->variantT ()) { case V_SgTypeComplex: typeName = "complex"; break; case V_SgTypeImaginary: typeName = "imaginary"; break; case V_SgTypeBool: typeName = "bool"; break; case V_SgEnumType: typeName = "enum"; break; case V_SgTypeChar: typeName = "char"; break; case V_SgTypeVoid: typeName = "void"; break; case V_SgTypeInt: typeName = "int"; break; case V_SgTypeDouble: typeName = "double"; break; case V_SgTypeFloat: typeName = "float"; break; case V_SgTypeLong: typeName = "long"; break; case V_SgTypeLongDouble: typeName = "long double"; break; case V_SgTypeEllipse: typeName = "ellipse"; break; case V_SgTypeGlobalVoid: typeName = "void"; break; case V_SgTypeLongLong: typeName = "long long"; break; case V_SgTypeShort: typeName = "short"; break; case V_SgTypeSignedChar: typeName = "signed char"; break; case V_SgTypeSignedInt: typeName = "signed int"; break; case V_SgTypeSignedLong: typeName = "signed long"; break; case V_SgTypeSignedShort: typeName = "signed short"; break; case V_SgTypeString: typeName = "string"; break; case V_SgTypeUnknown: typeName = "unknown"; break; case V_SgTypeUnsignedChar: typeName = "unsigned char"; break; case V_SgTypeUnsignedInt: typeName = "unsigned int"; break; case V_SgTypeUnsignedLong: typeName = "unsigned long"; break; case V_SgTypeUnsignedShort: typeName = "unsigned short"; break; case V_SgTypeUnsignedLongLong: typeName = "unsigned long long"; break; case V_SgReferenceType: { ROSE_ASSERT (isSgReferenceType (type)->get_base_type () != NULL); Rose_STL_Container< string > subTypeNames = queryNameTypeName (isSgReferenceType (type)->get_base_type ()); typedef Rose_STL_Container< string >::iterator typeIterator; //This iterator will only contain one name for (typeIterator i = subTypeNames.begin (); i != subTypeNames.end (); ++i) { string e = *i; typeName = e; break; } break; } case V_SgPointerType: { ROSE_ASSERT (isSgPointerType (type)->get_base_type () != NULL); Rose_STL_Container< string > subTypeNames = queryNameTypeName (isSgPointerType (type)->get_base_type ()); typedef Rose_STL_Container< string >::iterator typeIterator; //This iterator will only contain one name for (typeIterator i = subTypeNames.begin (); i != subTypeNames.end (); ++i) { string e = *i; typeName = e; break; } break; } case V_SgModifierType: { ROSE_ASSERT (isSgModifierType (type)->get_base_type () != NULL); Rose_STL_Container< string > subTypeNames = queryNameTypeName (isSgModifierType (type)->get_base_type ()); typedef Rose_STL_Container< string >::iterator typeIterator; //This iterator will only contain one name for (typeIterator i = subTypeNames.begin (); i != subTypeNames.end (); ++i) { string e = *i; typeName = e; break; } break; } case V_SgNamedType: { SgNamedType *sageNamedType = isSgNamedType (type); ROSE_ASSERT (sageNamedType != NULL); typeName = sageNamedType->get_name ().str (); break; } case V_SgClassType: { SgClassType *sageClassType = isSgClassType (type); ROSE_ASSERT (sageClassType != NULL); typeName = sageClassType->get_name ().str (); break; } case V_SgTypedefType: { SgTypedefType *sageTypedefType = isSgTypedefType (type); ROSE_ASSERT (sageTypedefType != NULL); typeName = sageTypedefType->get_name ().str (); break; } case V_SgPointerMemberType: { SgPointerMemberType *pointerMemberType = isSgPointerMemberType (type); ROSE_ASSERT (pointerMemberType != NULL); SgClassType *classType = isSgClassType(pointerMemberType->get_class_type()->stripTypedefsAndModifiers()); ROSE_ASSERT (classType != NULL); SgClassDeclaration *classDeclaration = isSgClassDeclaration(classType->get_declaration()); ROSE_ASSERT (classDeclaration != NULL); typeName = classDeclaration->get_name ().str (); break; } case V_SgArrayType: { ROSE_ASSERT (isSgArrayType (type)->get_base_type () != NULL); Rose_STL_Container< string > subTypeNames = queryNameTypeName (isSgArrayType (type)->get_base_type ()); typedef Rose_STL_Container< string >::iterator typeIterator; //This iterator will only contain one name for (typeIterator i = subTypeNames.begin (); i != subTypeNames.end (); ++i) { string e = *i; typeName = e; break; } break; } case V_SgFunctionType: { SgFunctionType *functionType = isSgFunctionType (type); ROSE_ASSERT (functionType != NULL); typeName = functionType->get_mangled_type ().str (); break; } case V_SgMemberFunctionType: { SgMemberFunctionType *memberFunctionType = isSgMemberFunctionType (type); ROSE_ASSERT (memberFunctionType != NULL); SgClassType *classType = isSgClassType(memberFunctionType->get_class_type()->stripTypedefsAndModifiers()); ROSE_ASSERT (classType != NULL); SgClassDeclaration *classDeclaration = isSgClassDeclaration(classType->get_declaration()); ROSE_ASSERT (classDeclaration != NULL); typeName = classDeclaration->get_name ().str (); break; } case V_SgTypeWchar: typeName = "wchar"; break; case V_SgTypeDefault: typeName = "default"; break; default: printf ("default reached in switch within TransformationSupport::getTypeName type->sage_class_name() = %s variant = %d \n", type->sage_class_name (), type->variant ()); ROSE_ABORT (); break; } // Fix for purify problem report // typeName = ROSE::stringDuplicate(typeName); if (typeName.size () > 0) returnList.push_back (typeName); //ROSE_ASSERT(typeName.c_str() != NULL); // return typeName; return returnList; //return ROSE::stringDuplicate(typeName.c_str()); }