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; }
SgClassDeclaration* TestCodeBuilder::buildModelStruct() { model_decl_ = buildStructDeclaration("model"); SgClassDefinition* def = buildClassDefinition(model_decl_); pushScopeStack(isSgScopeStatement(def)); SgVariableDeclaration* int_var = buildVariableDeclaration(int_var_name_, buildIntType()); SgVariableDeclaration* int_array_var = buildVariableDeclaration(int_array_var_name_, buildArrayType(buildIntType(), buildIntVal(array_size_))); def->append_member(int_var); def->append_member(int_array_var); popScopeStack(); #if 0 model_type_ = model_decl_->get_type(); model_obj_ = buildInitializedName(model_obj_name_, buildPointerType(model_type_)); // Build the int var. int_var_ = buildBinaryExpression<SgArrowExp>( buildVarRefExp(model_obj_name_), buildVarRefExp(int_var_name_)); int_var_->set_lvalue(true); // Build the int array var int_array_var_ = buildBinaryExpression<SgArrowExp>( buildVarRefExp(model_obj_name_), buildVarRefExp(int_array_var_name_)); #endif return model_decl_; }
NameQuerySynthesizedAttributeType NameQuery::queryNameUnionFieldNames (SgNode * astNode) { ROSE_ASSERT (astNode != 0); NameQuerySynthesizedAttributeType returnNameList; // SgNode *sageReturnNode = NULL; SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode); if (sageClassDefinition != NULL) { ROSE_ASSERT (sageClassDefinition->get_declaration () != NULL); if (sageClassDefinition->get_declaration ()->get_class_type () == SgClassDeclaration::e_struct) { SgDeclarationStatementPtrList declarationStatementPtrList = sageClassDefinition->get_members (); typedef SgDeclarationStatementPtrList::iterator LI; for (LI i = declarationStatementPtrList.begin (); i != declarationStatementPtrList.end (); ++i) { SgNode *listElement = *i; SgVariableDeclaration *sageVariableDeclaration = isSgVariableDeclaration (listElement); if (sageVariableDeclaration != NULL) { typedef SgInitializedNamePtrList::iterator INITLI; SgInitializedNamePtrList sageInitializedNameList = sageVariableDeclaration->get_variables (); for (INITLI i = sageInitializedNameList.begin (); i != sageInitializedNameList.end (); ++i) { SgInitializedName* initializedListElement = *i; ROSE_ASSERT (isSgInitializedName (initializedListElement) != NULL); returnNameList.push_back (initializedListElement->get_name().str()); } /* End iteration over declarationStatementPtrList */ } /* End iteration over declarationStatementPtrList */ } } } return returnNameList; } /* End function queryUnionFieldNames() */
SgMemberFunctionDeclaration* get_default_constructor(SgClassDeclaration *c) { SgClassDefinition *d = c->get_definition(); if (d != NULL) { SgDeclarationStatementPtrList::iterator i; for (i = d->get_members().begin(); i != d->get_members().end(); ++i) { if (SgMemberFunctionDeclaration* m=isSgMemberFunctionDeclaration(*i)) { if (m->get_name() == c->get_name() && m->get_args().empty()) return m; } } } return Ir::createMemberFunctionDeclaration(c->get_name()); }
SgDerivedTypeStatement * RoseStatementsAndExpressionsBuilder::buildTypeDeclaration ( std::string const & typeName, SgScopeStatement * scope) { SgClassDefinition * classDefinition = new SgClassDefinition ( RoseHelper::getFileInfo ()); classDefinition->set_endOfConstruct (RoseHelper::getFileInfo ()); classDefinition->setCaseInsensitive (true); SgDerivedTypeStatement* classDeclaration = new SgDerivedTypeStatement ( RoseHelper::getFileInfo (), typeName, SgClassDeclaration::e_struct, NULL, classDefinition); classDeclaration->set_endOfConstruct (RoseHelper::getFileInfo ()); classDeclaration->set_definingDeclaration (classDeclaration); classDeclaration->get_declarationModifier ().get_accessModifier ().setUndefined (); SgDerivedTypeStatement* nondefiningClassDeclaration = new SgDerivedTypeStatement (RoseHelper::getFileInfo (), typeName, SgClassDeclaration::e_struct, NULL, NULL); nondefiningClassDeclaration->set_endOfConstruct (RoseHelper::getFileInfo ()); nondefiningClassDeclaration->set_parent (scope); nondefiningClassDeclaration->get_declarationModifier ().get_accessModifier ().setUndefined (); nondefiningClassDeclaration->set_type (SgClassType::createType ( nondefiningClassDeclaration)); classDeclaration->set_type (nondefiningClassDeclaration->get_type ()); classDeclaration->set_firstNondefiningDeclaration ( nondefiningClassDeclaration); nondefiningClassDeclaration->set_firstNondefiningDeclaration ( nondefiningClassDeclaration); nondefiningClassDeclaration->set_definingDeclaration (classDeclaration); nondefiningClassDeclaration->setForward (); classDefinition->set_declaration (classDeclaration); classDefinition->get_declaration ()->get_declarationModifier ().get_accessModifier ().setUndefined (); classDeclaration->set_scope (scope); nondefiningClassDeclaration->set_scope (scope); classDeclaration->set_parent (scope); SgClassSymbol * classSymbol = new SgClassSymbol (nondefiningClassDeclaration); scope->insert_symbol (typeName, classSymbol); return classDeclaration; }
void FixupEnumValues::visit(SgNode* node) { #if 0 printf ("##### FixupEnumValues::visit(node = %p = %s) \n",node,node->sage_class_name()); #endif SgEnumVal* enumVal = isSgEnumVal(node); ROSE_ASSERT(enumVal != NULL); if (enumVal->get_declaration() == NULL) { ROSE_ASSERT(enumVal->get_startOfConstruct() != NULL); ROSE_ASSERT(enumVal->get_endOfConstruct() != NULL); // printf ("Found an enum value with a NULL declaration, fixup the declaration! \n"); // enumVal->get_startOfConstruct()->display("Found an enum value with a NULL declaration"); SgClassDefinition* enclosingClassDefinition = TransformationSupport::getClassDefinition(enumVal); ROSE_ASSERT(enclosingClassDefinition != NULL); // Now search for the enumVal name in the symbol table SgEnumFieldSymbol* enumFieldSymbol = enclosingClassDefinition->lookup_enum_field_symbol(enumVal->get_name()); ROSE_ASSERT(enumFieldSymbol != NULL); if (enumFieldSymbol != NULL) { // We have now found the enum symbol in the scope of the class where the enum value was used. // It could have been elsewhere and we don't search there, it could be in a namespace that was // included using a using directive, so this could be very complex if it is not in the enclosing // class. To handle the case of where we can't find it, we ALLOW the declaration in the enumVal // to be NULL, but we try to set it where we can easily figure it out. SgInitializedName* enumFieldName = enumFieldSymbol->get_declaration(); SgNode* parentNode = enumFieldName->get_parent(); ROSE_ASSERT(parentNode != NULL); SgEnumDeclaration* enumDeclaration = isSgEnumDeclaration(parentNode); ROSE_ASSERT(enumDeclaration != NULL); // Set the declaration to the enum declaration found! // printf ("Fixup the NULL declaration in enumVal = %p = %s with valid enum declaration = %p = %s \n",enumVal,enumVal->get_name().str(),enumDeclaration,enumDeclaration->get_name().str()); enumVal->set_declaration(enumDeclaration); } } }
bool findPublicVarMembers (SgNode *node, string &str) { SgVariableDeclaration *decl; if (decl = isSgVariableDeclaration(node)) { SgDeclarationModifier &dfm = decl->get_declarationModifier(); if (dfm.get_accessModifier().isPublic()) { // check if it belongs to a class SgStatement *block = ((SgVariableDeclaration *) node)->get_scope(); SgClassDefinition *classDef; if (classDef = isSgClassDefinition(block)) { if (classDef->get_declaration()->get_class_type() == SgClassDeclaration::e_class) { str = classDef->get_qualified_name().getString(); return true; } } } } return false; }
NodeQuerySynthesizedAttributeType NodeQuery::querySolverClassFields (SgNode * astNode) { ROSE_ASSERT (astNode != 0); NodeQuerySynthesizedAttributeType returnNodeList; /* cout << "The name of the node is: \" " << astNode->sage_class_name() << "\"\n"; SgLocatedNode* sageLocatedNode = isSgLocatedNode(astNode); if(sageLocatedNode != NULL){ cout << "The filename is: " << sageLocatedNode->getFileName() << " At line number :" << sageLocatedNode->get_file_info()->get_line() << "\n"; } */ // SgNode *sageReturnNode = NULL; SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode); if (sageClassDefinition != NULL) { ROSE_ASSERT (sageClassDefinition->get_declaration () != NULL); if (sageClassDefinition->get_declaration ()->get_class_type () == SgClassDeclaration::e_class) { SgDeclarationStatementPtrList declarationStatementPtrList = sageClassDefinition->get_members (); typedef SgDeclarationStatementPtrList::iterator LI; for (LI i = declarationStatementPtrList.begin (); i != declarationStatementPtrList.end (); ++i) { SgNode *listElement = *i; if (isSgVariableDeclaration (listElement) != NULL){ /* if(isSgVariableDeclaration(listElement)->get_name().str() != NULL) cout << "The name of the variable declaration is: \"" << isSgVariableDeclaration(listElement)->get_name().str() << "\"\n"; else cout << "The name of the variable declaration is: \"\"\n";*/ returnNodeList.push_back (listElement); } } } } return returnNodeList; } /* End function querySolverClassFields() */
NodeQuerySynthesizedAttributeType NodeQuery::querySolverStructDefinitions (SgNode * astNode) { ROSE_ASSERT (astNode != 0); SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode); NodeQuerySynthesizedAttributeType returnNodeList; if (sageClassDefinition != NULL) { SgClassDeclaration *sageClassDeclaration = isSgClassDeclaration (sageClassDefinition->get_parent ()); ROSE_ASSERT (sageClassDeclaration != NULL); if (sageClassDeclaration->get_class_type () == SgClassDeclaration::e_struct) returnNodeList.push_back (astNode); } return returnNodeList; } /* End function querySolverClassFields() */
NodeQuerySynthesizedAttributeType NodeQuery::querySolverUnionFields (SgNode * astNode) { ROSE_ASSERT (astNode != 0); NodeQuerySynthesizedAttributeType returnNodeList; // SgNode *sageReturnNode = NULL; SgClassDefinition *sageClassDefinition = isSgClassDefinition (astNode); if (sageClassDefinition != NULL) { ROSE_ASSERT (sageClassDefinition->get_declaration () != NULL); if (sageClassDefinition->get_declaration ()->get_class_type () == SgClassDeclaration::e_union) { SgDeclarationStatementPtrList declarationStatementPtrList = sageClassDefinition->get_members (); typedef SgDeclarationStatementPtrList::iterator LI; for (LI i = declarationStatementPtrList.begin (); i != declarationStatementPtrList.end (); ++i) { SgNode *listElement = *i; if (isSgVariableDeclaration (listElement) != NULL) returnNodeList.push_back (listElement); } } } return returnNodeList; } /* End function querySolverUnionFields() */
void Unparse_Java::unparseEnumType(SgEnumType* type, SgUnparse_Info& info) { SgEnumType* enum_type = isSgEnumType(type); ROSE_ASSERT(enum_type); if (info.isTypeSecondPart() == false) { SgEnumDeclaration *edecl = isSgEnumDeclaration(enum_type->get_declaration()); SgClassDefinition *cdefn = NULL; SgNamespaceDefinitionStatement* namespaceDefn = NULL; ROSE_ASSERT(edecl != NULL); // Build reference to any possible enclosing scope represented by a SgClassDefinition or SgNamespaceDefinition // to be used check if name qualification is required. unp->u_exprStmt->initializeDeclarationsFromParent ( edecl, cdefn, namespaceDefn ); if (info.isTypeFirstPart() == true && info.SkipEnumDefinition() == false) { unp->u_exprStmt->unparseAttachedPreprocessingInfo(edecl, info, PreprocessingInfo::before); } curprint ( "enum "); SgNamedType *ptype = NULL; if (cdefn != NULL) { ptype = isSgNamedType(cdefn->get_declaration()->get_type()); } if (SageInterface::is_C_language() == true || SageInterface::is_C99_language() == true) { curprint ( enum_type->get_name().getString() + " "); } else { // DQ (7/20/2011): Test compilation without the generateNameQualifier() functions. // The C++ support is more complex and can require qualified names! // SgName nameQualifier = unp->u_name->generateNameQualifier( edecl , info ); SgName nameQualifier; // printf ("nameQualifier (from unp->u_name->generateNameQualifier function) = %s \n",nameQualifier.str()); // curprint ( "\n/* nameQualifier (from unp->u_name->generateNameQualifier function) = " + nameQualifier + " */ \n "; curprint ( nameQualifier.str()); SgName nm = enum_type->get_name(); if (nm.getString() != "") { // printf ("Output qualifier of current types to the name = %s \n",nm.str()); curprint ( nm.getString() + " "); } } } if (info.isTypeFirstPart() == true) { // info.display("info before constructing ninfo"); SgUnparse_Info ninfo(info); // don't skip the semicolon in the output of the statement in the class definition ninfo.unset_SkipSemiColon(); ninfo.set_isUnsetAccess(); // printf ("info.SkipEnumDefinition() = %s \n",(info.SkipEnumDefinition() == true) ? "true" : "false"); if ( info.SkipEnumDefinition() == false) { SgUnparse_Info ninfo(info); ninfo.set_inEnumDecl(); SgInitializer *tmp_init = NULL; SgName tmp_name; SgEnumDeclaration *enum_stmt = isSgEnumDeclaration(enum_type->get_declaration()); ROSE_ASSERT(enum_stmt != NULL); // This permits support of the empty enum case! "enum x{};" curprint ( "{"); SgInitializedNamePtrList::iterator p = enum_stmt->get_enumerators().begin(); if (p != enum_stmt->get_enumerators().end()) { // curprint ( "{"; while (1) { unp->u_exprStmt->unparseAttachedPreprocessingInfo(*p, info, PreprocessingInfo::before); tmp_name=(*p)->get_name(); tmp_init=(*p)->get_initializer(); curprint ( tmp_name.str()); if(tmp_init) { curprint ( "="); unp->u_exprStmt->unparseExpression(tmp_init, ninfo); } p++; if (p != enum_stmt->get_enumerators().end()) { curprint ( ","); } else break; } // curprint ( "}"; } // Putting the "inside" info right here is just a wild guess as to where it might really belong. unp->u_exprStmt->unparseAttachedPreprocessingInfo(enum_stmt, info, PreprocessingInfo::inside); curprint ( "}"); unp->u_exprStmt->unparseAttachedPreprocessingInfo(enum_stmt, info, PreprocessingInfo::after); } } }
NodeQuerySynthesizedAttributeType NodeQuery::queryNodeClassDeclarationsFromTypeName(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) { if(TransformationSupport::getTypeName(sageClassDeclaration->get_type()) == nameToMatch) returnList.push_back(node); else { SgClassDefinition* classDefinition = isSgClassDefinition(sageClassDeclaration->get_definition()); ROSE_ASSERT( classDefinition != NULL ); // SgBaseClassList baseClassList = classDefinition->get_inheritances(); SgBaseClassPtrList baseClassList = classDefinition->get_inheritances(); typedef SgBaseClassPtrList::iterator SgBaseClassPtrListIterator; for( SgBaseClassPtrListIterator baseClassElm = baseClassList.begin(); baseClassElm != baseClassList.end(); ++baseClassElm) { // SgBaseClass baseClass = *baseClassElm; SgBaseClass* baseClass = *baseClassElm; // sageClassDeclaration = baseClass.get_base_class(); sageClassDeclaration = baseClass->get_base_class(); std::string typeName = TransformationSupport::getTypeName ( sageClassDeclaration->get_type() ); if( typeName == nameToMatch ) returnList.push_back(node); } } /* SgType* typeNode = sageClassDeclaration->get_type (); ROSE_ASSERT (typeNode != NULL); string currentTypeName = ""; string previousTypeName = ""; do{ previousTypeName = currentTypeName; currentTypeName = TransformationSupport::getTypeName (typeNode); typeNode = typeNode->findBaseType(); ROSE_ASSERT( typeNode != NULL ); if( currentTypeName == nameToMatch ){ returnList.push_back(node); break; } cout<< "\n\n The typenames is : " << currentTypeName << "\n\n" << previousTypeName << "\n\n"; }while( previousTypeName != currentTypeName); */ } return returnList; } /* End function:queryNodeCLassDeclarationFromName() */
StructLayoutInfo NonpackedTypeLayoutGenerator::layoutType(SgType* t) const { switch (t->variantT()) { case V_SgClassType: { // Also covers structs and unions SgClassDeclaration* decl = isSgClassDeclaration(isSgClassType(t)->get_declaration()); ROSE_ASSERT (decl); decl = isSgClassDeclaration(decl->get_definingDeclaration()); ROSE_ASSERT (decl); SgClassDefinition* def = decl->get_definition(); ROSE_ASSERT (def); StructLayoutInfo layout; size_t currentOffset = 0; const SgBaseClassPtrList& bases = def->get_inheritances(); for (SgBaseClassPtrList::const_iterator i = bases.begin(); i != bases.end(); ++i) { SgBaseClass* base = *i; SgClassDeclaration* basecls = base->get_base_class(); layoutOneField(basecls->get_type(), base, false, currentOffset, layout); } const SgDeclarationStatementPtrList& body = def->get_members(); bool isUnion = (decl->get_class_type() == SgClassDeclaration::e_union); for (SgDeclarationStatementPtrList::const_iterator i = body.begin(); i != body.end(); ++i) { SgDeclarationStatement* mem = *i; SgVariableDeclaration* vardecl = isSgVariableDeclaration(mem); SgClassDeclaration* classdecl = isSgClassDeclaration(mem); bool isUnnamedUnion = classdecl ? classdecl->get_isUnNamed() : false; if (vardecl) { if (!vardecl->get_declarationModifier().isDefault()) continue; // Static fields and friends ROSE_ASSERT (!vardecl->get_bitfield()); const SgInitializedNamePtrList& vars = isSgVariableDeclaration(mem)->get_variables(); for (SgInitializedNamePtrList::const_iterator j = vars.begin(); j != vars.end(); ++j) { SgInitializedName* var = *j; layoutOneField(var->get_type(), var, isUnion, currentOffset, layout); } } else if (isUnnamedUnion) { layoutOneField(classdecl->get_type(), classdecl, isUnion, currentOffset, layout); } // else continue; } if (layout.alignment != 0 && layout.size % layout.alignment != 0) { size_t paddingNeeded = layout.alignment - (layout.size % layout.alignment); if (!isUnion) { layout.fields.push_back(StructLayoutEntry(NULL, layout.size, paddingNeeded)); } layout.size += paddingNeeded; } return layout; } case V_SgArrayType: { StructLayoutInfo layout = this->beginning->layoutType(isSgArrayType(t)->get_base_type()); layout.fields.clear(); SgExpression* numElements = isSgArrayType(t)->get_index(); //Adjustment for UPC array like a[100*THREADS],treat it as a[100] // Liao, 8/7/2008 if (isUpcArrayWithThreads(isSgArrayType(t))) { SgMultiplyOp* multiply = isSgMultiplyOp(isSgArrayType(t)->get_index()); ROSE_ASSERT(multiply); // DQ (9/26/2011): Do constant folding if required. // SageInterface::constantFolding(multiply); numElements = multiply->get_lhs_operand(); } if (!isSgValueExp(numElements)) { cerr << "Error: trying to compute static size of an array with non-constant size" << endl; abort(); } layout.size *= SageInterface::getIntegerConstantValue(isSgValueExp(numElements)); return layout; } case V_SgTypeComplex: { //"Each complex type has the same representation and alignment requirements as //an array type containing exactly two elements of the corresponding real type" StructLayoutInfo layout = this->beginning->layoutType(isSgTypeComplex(t)->get_base_type()); layout.size *= 2; return layout; } case V_SgTypeImaginary: { StructLayoutInfo layout = this->beginning->layoutType(isSgTypeImaginary(t)->get_base_type()); return layout; } default: return ChainableTypeLayoutGenerator::layoutType(t); } }
void fixupEdgBugDuplicateVariablesInAST() { // DQ (3/11/2006): Introduce tracking of performance of ROSE. TimingPerformance timer1 ("Fixup known EDG bug where some variable declarations are dropped from the source sequence lists:"); std::set<SgVariableDeclaration*> declarations_to_remove; // Loop over all variables added using the convert_field_use() function. std::set<SgVariableDeclaration*>::iterator i = nodesAddedWithinFieldUseSet.begin(); while (i != nodesAddedWithinFieldUseSet.end()) { SgVariableDeclaration* var_decl = *i; SgName name = var_decl->get_variables()[0]->get_name(); SgClassDefinition* classDefinition = isSgClassDefinition(var_decl->get_parent()); ROSE_ASSERT(classDefinition != NULL); std::vector<SgDeclarationStatement*> & members = classDefinition->get_members(); // Loop over all data members in the class. std::vector<SgDeclarationStatement*>::iterator j = members.begin(); while (j != members.end()) { SgVariableDeclaration* possible_matching_variable_declaration = isSgVariableDeclaration(*j); if (possible_matching_variable_declaration != NULL && possible_matching_variable_declaration != var_decl) { if (possible_matching_variable_declaration->get_variables()[0]->get_name() == name) { #if 0 printf ("matching variable declaration found for name = %s \n",name.str()); #endif declarations_to_remove.insert(var_decl); } } j++; } i++; } // Now remove all of the variable declarations that we detected to be duplicates. std::set<SgVariableDeclaration*>::iterator k = declarations_to_remove.begin(); while (k != declarations_to_remove.end()) { SgDeclarationStatement* var_decl = *k; SgClassDefinition* classDefinition = isSgClassDefinition(var_decl->get_parent()); ROSE_ASSERT(classDefinition != NULL); std::vector<SgDeclarationStatement*> myvector; myvector.push_back(*k); std::vector<SgDeclarationStatement*> & members = classDefinition->get_members(); // members.erase(*k); // members.erase(myvector.begin(),myvector.end()); // This is the remove/erase idiom. members.erase(remove(members.begin(), members.end(), *k), members.end()); k++; } }
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 FixupAstSymbolTablesToSupportAliasedSymbols::visit ( SgNode* node ) { // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST. #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit() (preorder AST traversal) node = %p = %s \n",node,node->class_name().c_str()); #endif #if 0 // DQ (7/23/2011): New support for linking namespaces sharing the same name (mangled name). // std::map<SgName,std::vector<SgNamespaceDefinition*> > namespaceMap; SgNamespaceDefinitionStatement* namespaceDefinition = isSgNamespaceDefinitionStatement(node); if (namespaceDefinition != NULL) { // DQ (7/23/2011): Assemble namespaces with the same name into vectors defined in the map // accessed using the name of the namespace as a key. #error "DEAD CODE" SgName name = namespaceDefinition->get_namespaceDeclaration()->get_name(); #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: namespace definition found for name = %s #symbols = %d \n",name.str(),namespaceDefinition->get_symbol_table()->size()); #endif // It is important to use mangled names to define unique names when namespaces are nested. SgName mangledNamespaceName = namespaceDefinition->get_namespaceDeclaration()->get_mangled_name(); #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: namespace definition associated mangled name = %s \n",mangledNamespaceName.str()); #endif // DQ (7/23/2011): Fixup the name we use as a key in the map to relect that some namespaces don't have a name. if (name == "") { // Modify the mangled name to reflect the unnamed namespace... #if ALIAS_SYMBOL_DEBUGGING printf ("Warning in FixupAstSymbolTablesToSupportAliasedSymbols::visit(): Unnamed namespaces shuld be mangled to reflect the lack of a name \n"); #endif mangledNamespaceName += "_unnamed_namespace"; } #if ALIAS_SYMBOL_DEBUGGING printf ("namespace definition associated mangled name = %s \n",mangledNamespaceName.str()); #endif #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: associated mangled name = %s namespaceMap size = %" PRIuPTR " \n",mangledNamespaceName.str(),namespaceMap.size()); #endif std::map<SgName,std::vector<SgNamespaceDefinitionStatement*> >::iterator i = namespaceMap.find(mangledNamespaceName); if (i != namespaceMap.end()) { std::vector<SgNamespaceDefinitionStatement*> & namespaceVector = i->second; #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: (found an entry): Namespace vector size = %" PRIuPTR " \n",namespaceVector.size()); #endif // Testing each entry... for (size_t j = 0; j < namespaceVector.size(); j++) { ROSE_ASSERT(namespaceVector[j] != NULL); SgName existingNamespaceName = namespaceVector[j]->get_namespaceDeclaration()->get_name(); #if ALIAS_SYMBOL_DEBUGGING printf ("Existing namespace (SgNamespaceDefinitionStatement) %p = %s \n",namespaceVector[j],existingNamespaceName.str()); #endif if (j > 0) { ROSE_ASSERT(namespaceVector[j]->get_previousNamespaceDefinition() != NULL); } if (namespaceVector.size() > 1 && j < namespaceVector.size() - 2) { ROSE_ASSERT(namespaceVector[j]->get_nextNamespaceDefinition() != NULL); } } #error "DEAD CODE" size_t namespaceListSize = namespaceVector.size(); if (namespaceListSize > 0) { size_t lastNamespaceIndex = namespaceListSize - 1; // DQ (5/9/2013): Before setting these, I think they should be unset (to NULL values). // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL); // ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL); // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL); ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL); // namespaceVector[lastNamespaceIndex]->set_nextNamespaceDefinition(namespaceDefinition); #if 1 printf ("namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() = %p \n",namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition()); #endif if (namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL) { namespaceVector[lastNamespaceIndex]->set_nextNamespaceDefinition(namespaceDefinition); } else { // DQ (5/9/2013): If this is already set then make sure it was set to the correct value. ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == namespaceDefinition); } #error "DEAD CODE" // DQ (5/9/2013): If this is already set then make sure it was set to the correct value. // namespaceDefinition->set_previousNamespaceDefinition(namespaceVector[lastNamespaceIndex]); ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL); ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == namespaceVector[lastNamespaceIndex]); // DQ (5/9/2013): I think I can assert this. ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_namespaceDeclaration()->get_name() == namespaceDefinition->get_namespaceDeclaration()->get_name()); ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() != NULL); #if 1 printf ("namespaceDefinition = %p namespaceDefinition->get_nextNamespaceDefinition() = %p \n",namespaceDefinition,namespaceDefinition->get_nextNamespaceDefinition()); #endif // ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition() == NULL); // ROSE_ASSERT(namespaceVector[lastNamespaceIndex]->get_nextNamespaceDefinition() == NULL); } // Add the namespace matching a previous name to the list. namespaceVector.push_back(namespaceDefinition); #error "DEAD CODE" // Setup scopes as sources and distinations of alias symbols. SgNamespaceDefinitionStatement* referencedScope = namespaceDefinition->get_previousNamespaceDefinition(); ROSE_ASSERT(referencedScope != NULL); SgNamespaceDefinitionStatement* currentScope = namespaceDefinition; ROSE_ASSERT(currentScope != NULL); #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: Suppress injection of symbols from one namespace to the other for each reintrant namespace \n"); printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: referencedScope #symbols = %d currentScope #symbols = %d \n",referencedScope->get_symbol_table()->size(),currentScope->get_symbol_table()->size()); printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: referencedScope = %p currentScope = %p \n",referencedScope,currentScope); #endif #if 1 // Generate the alias symbols from the referencedScope and inject into the currentScope. injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,currentScope,SgAccessModifier::e_default); #endif } else { #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols: (entry NOT found): Insert namespace %p for name = %s into the namespaceMap \n",namespaceDefinition,mangledNamespaceName.str()); #endif std::vector<SgNamespaceDefinitionStatement*> list(1); ROSE_ASSERT(list.size() == 1); #error "DEAD CODE" list[0] = namespaceDefinition; #if 0 // DQ (3/11/2012): New code, but maybe we should instead put the implicit "std" namespace into the global scope more directly. if (mangledNamespaceName == "std" && false) { // This case has to be handled special since the implicit "std" namespace primary declaration was // constructed but not added to the global scope. But maybe it should be. } else { // DQ (7/24/2011): get_nextNamespaceDefinition() == NULL is false in the case of the AST copy tests // (see tests/nonsmoke/functional/CompileTests/copyAST_tests/copytest2007_30.C). Only get_nextNamespaceDefinition() // appears to sometimes be non-null, so we reset them both to NULL just to make sure. namespaceDefinition->set_nextNamespaceDefinition(NULL); namespaceDefinition->set_previousNamespaceDefinition(NULL); ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition() == NULL); ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL); } #else // DQ (7/24/2011): get_nextNamespaceDefinition() == NULL is false in the case of the AST copy tests // (see tests/nonsmoke/functional/CompileTests/copyAST_tests/copytest2007_30.C). Only get_nextNamespaceDefinition() // appears to sometimes be non-null, so we reset them both to NULL just to make sure. namespaceDefinition->set_nextNamespaceDefinition(NULL); namespaceDefinition->set_previousNamespaceDefinition(NULL); ROSE_ASSERT(namespaceDefinition->get_nextNamespaceDefinition() == NULL); ROSE_ASSERT(namespaceDefinition->get_previousNamespaceDefinition() == NULL); #endif namespaceMap.insert(std::pair<SgName,std::vector<SgNamespaceDefinitionStatement*> >(mangledNamespaceName,list)); #error "DEAD CODE" #if ALIAS_SYMBOL_DEBUGGING printf ("namespaceMap.size() = %" PRIuPTR " \n",namespaceMap.size()); #endif } } #error "DEAD CODE" #else // DQ (5/23/2013): Commented out since we now have a newer and better namespace support for symbol handling. // printf ("NOTE:: COMMENTED OUT old support for namespace declarations in FixupAstSymbolTablesToSupportAliasedSymbols traversal \n"); #endif SgUseStatement* useDeclaration = isSgUseStatement(node); if (useDeclaration != NULL) { // This must be done in the Fortran AST construction since aliased symbols must be inserted // before they are looked up as part of name resolution of variable, functions, and types. // For C++ we can be more flexible and support the construction of symbol aliases within // post-processing. } // DQ (4/14/2010): Added this C++ specific support. // In the future we may want to support the injection of alias symbols for C++ "using" directives and "using" declarations. SgUsingDeclarationStatement* usingDeclarationStatement = isSgUsingDeclarationStatement(node); if (usingDeclarationStatement != NULL) { #if ALIAS_SYMBOL_DEBUGGING printf ("Found the SgUsingDeclarationStatement \n"); #endif SgScopeStatement* currentScope = usingDeclarationStatement->get_scope(); ROSE_ASSERT(currentScope != NULL); SgDeclarationStatement* declaration = usingDeclarationStatement->get_declaration(); SgInitializedName* initializedName = usingDeclarationStatement->get_initializedName(); // Only one of these can be non-null. ROSE_ASSERT(initializedName != NULL || declaration != NULL); ROSE_ASSERT( (initializedName != NULL && declaration != NULL) == false); if (declaration != NULL) { #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): declaration = %p = %s \n",declaration,declaration->class_name().c_str()); #endif } else { if (initializedName != NULL) { #if ALIAS_SYMBOL_DEBUGGING printf ("In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): initializedName = %s \n",initializedName->get_name().str()); #endif } else { printf ("Error: both declaration and initializedName in SgUsingDeclarationStatement are NULL \n"); ROSE_ASSERT(false); } } #if 0 printf ("Exiting at the base of FixupAstSymbolTablesToSupportAliasedSymbols::visit() \n"); ROSE_ASSERT(false); #endif } SgUsingDirectiveStatement* usingDirectiveStatement = isSgUsingDirectiveStatement(node); if (usingDirectiveStatement != NULL) { #if ALIAS_SYMBOL_DEBUGGING printf ("Found the SgUsingDirectiveStatement \n"); #endif SgNamespaceDeclarationStatement* namespaceDeclaration = usingDirectiveStatement->get_namespaceDeclaration(); ROSE_ASSERT(namespaceDeclaration != NULL); SgScopeStatement* currentScope = usingDirectiveStatement->get_scope(); // To be more specific this is really a SgNamespaceDefinitionStatement SgScopeStatement* referencedScope = namespaceDeclaration->get_definition(); if (referencedScope == NULL) { // DQ (5/21/2010): Handle case of using "std" (predefined namespace in C++), but it not having been explicitly defined (see test2005_57.C). if (namespaceDeclaration->get_name() != "std") { printf ("ERROR: namespaceDeclaration has no valid definition \n"); namespaceDeclaration->get_startOfConstruct()->display("ERROR: namespaceDeclaration has no valid definition"); // DQ (5/20/2010): Added assertion to trap this case. printf ("Exiting because referencedScope could not be identified.\n"); ROSE_ASSERT(false); } } // Note that "std", as a predefined namespace, can have a null definition, so we can't // insist that we inject all symbols in namespaces that we can't see explicitly. if (referencedScope != NULL) { ROSE_ASSERT(referencedScope != NULL); ROSE_ASSERT(currentScope != NULL); #if 0 printf ("Calling injectSymbolsFromReferencedScopeIntoCurrentScope() for usingDirectiveStatement = %p = %s \n",node,node->class_name().c_str()); #endif injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,currentScope,usingDirectiveStatement,SgAccessModifier::e_default); } #if 0 printf ("Exiting at the base of FixupAstSymbolTablesToSupportAliasedSymbols::visit() \n"); ROSE_ASSERT(false); #endif } // DQ (5/6/2011): Added support to build SgAliasSymbols in derived class scopes that reference the symbols of the base classes associated with protected and public declarations. SgClassDefinition* classDefinition = isSgClassDefinition(node); if (classDefinition != NULL) { // Handle any derived classes. SgBaseClassPtrList & baseClassList = classDefinition->get_inheritances(); SgBaseClassPtrList::iterator i = baseClassList.begin(); for ( ; i != baseClassList.end(); ++i) { // Check each base class. SgBaseClass* baseClass = *i; ROSE_ASSERT(baseClass != NULL); /* skip processing for SgExpBaseClasses (which don't have to define p_base_class) */ if (baseClass->variantT() == V_SgExpBaseClass) { continue; } // printf ("baseClass->get_baseClassModifier().displayString() = %s \n",baseClass->get_baseClassModifier().displayString().c_str()); // printf ("baseClass->get_baseClassModifier().get_accessModifier().displayString() = %s \n",baseClass->get_baseClassModifier().get_accessModifier().displayString().c_str()); // if (baseClass->get_modifier() == SgBaseClass::e_virtual) if (baseClass->get_baseClassModifier().get_modifier() == SgBaseClassModifier::e_virtual) { // Not clear if virtual as a modifier effects the handling of alias symbols. // printf ("Not clear if virtual as a modifier effects the handling of alias symbols. \n"); } // DQ (6/22/2011): Define the access level for alias symbol's declarations to be included. SgAccessModifier::access_modifier_enum accessLevel = baseClass->get_baseClassModifier().get_accessModifier().get_modifier(); SgClassDeclaration* tmpClassDeclaration = baseClass->get_base_class(); ROSE_ASSERT(tmpClassDeclaration != NULL); #if 0 // ROSE_ASSERT(tmpClassDeclaration->get_definingDeclaration() != NULL); SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(tmpClassDeclaration->get_definingDeclaration()); ROSE_ASSERT(targetClassDeclaration != NULL); SgScopeStatement* referencedScope = targetClassDeclaration->get_definition(); // We need this function to restrict it's injection of symbol to just those that are associated with public and protected declarations. injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,classDefinition,accessLevel); #else // DQ (2/25/2012) We only want to inject the symbol where we have identified the defining scope. if (tmpClassDeclaration->get_definingDeclaration() != NULL) { SgClassDeclaration* targetClassDeclaration = isSgClassDeclaration(tmpClassDeclaration->get_definingDeclaration()); ROSE_ASSERT(targetClassDeclaration != NULL); SgScopeStatement* referencedScope = targetClassDeclaration->get_definition(); #if 0 printf ("Calling injectSymbolsFromReferencedScopeIntoCurrentScope() for classDefinition = %p = %s baseClass = %p accessLevel = %d \n", node,node->class_name().c_str(),baseClass,accessLevel); #endif // DQ (7/12/2014): Use the SgBaseClass as the causal node that has triggered the insertion of the SgAliasSymbols. // We need this function to restrict it's injection of symbol to just those that are associated with public and protected declarations. injectSymbolsFromReferencedScopeIntoCurrentScope(referencedScope,classDefinition,baseClass,accessLevel); } else { // DQ (2/25/2012): Print a warning message when this happens (so far only test2012_08.C). if (SgProject::get_verbose() > 0) { mprintf ("WARNING: In FixupAstSymbolTablesToSupportAliasedSymbols::visit(): Not really clear how to handle this case where tmpClassDeclaration->get_definingDeclaration() == NULL! \n"); } } #endif } } SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(node); if (functionDeclaration != NULL) { #if ALIAS_SYMBOL_DEBUGGING printf ("Found a the SgFunctionDeclaration \n"); #endif // SgScopeStatement* functionScope = functionDeclaration->get_scope(); SgScopeStatement* currentScope = isSgScopeStatement(functionDeclaration->get_parent()); SgClassDefinition* classDefinition = isSgClassDefinition(currentScope); if (classDefinition != NULL) { // This is a function declared in a class definition, test of friend (forget why it is important to test for isOperator(). if (functionDeclaration->get_declarationModifier().isFriend() == true || functionDeclaration->get_specialFunctionModifier().isOperator() == true) { // printf ("Process all friend function with a SgAliasSymbol to where they are declared in another scope (usually global scope) \n"); #if 0 SgName name = functionDeclaration->get_name(); SgSymbol* symbol = functionDeclaration->search_for_symbol_from_symbol_table(); ROSE_ASSERT ( symbol != NULL ); SgAliasSymbol* aliasSymbol = new SgAliasSymbol (symbol); // Use the current name and the alias to the symbol currentScope->insert_symbol(name,aliasSymbol); #endif #if 0 printf ("Error: friend functions not processed yet! \n"); ROSE_ASSERT(false); #endif } } } #if ALIAS_SYMBOL_DEBUGGING printf ("Leaving FixupAstSymbolTablesToSupportAliasedSymbols::visit() (preorder AST traversal) node = %p = %s \n",node,node->class_name().c_str()); #endif }
SgClassDeclaration* buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope) { // This function builds a class declaration and definition // (both the defining and nondefining declarations as required). // This is the class definition (the fileInfo is the position of the opening brace) SgClassDefinition* classDefinition = new SgClassDefinition(SOURCE_POSITION); assert(classDefinition != NULL); // Set the end of construct explictly (where not a transformation this is the location of the closing brace) classDefinition->set_endOfConstruct(SOURCE_POSITION); // This is the defining declaration for the class (with a reference to the class definition) SgClassDeclaration* classDeclaration = new SgClassDeclaration(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition); assert(classDeclaration != NULL); classDeclaration->set_endOfConstruct(SOURCE_POSITION); // 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(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL); assert(classDeclaration != NULL); nondefiningClassDeclaration->set_endOfConstruct(SOURCE_POSITION); nondefiningClassDeclaration->set_scope(scope); // scope is needed for createType() 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(); // Liao (2/13/2008), symbol for the declaration SgClassSymbol* mysymbol = new SgClassSymbol(nondefiningClassDeclaration); scope->insert_symbol(name, mysymbol); // 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); //set parent classDeclaration->set_parent(scope); nondefiningClassDeclaration->set_parent(scope); // some error checking assert(classDeclaration->get_definingDeclaration() != NULL); assert(classDeclaration->get_firstNondefiningDeclaration() != NULL); assert(classDeclaration->get_definition() != NULL); ROSE_ASSERT(classDeclaration->get_definition()->get_parent() != NULL); return classDeclaration; }
//----------------------------------------------------------------------------- // 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; }
//! search for all possible (virtual) function calls vector<SgMemberFunctionDeclaration*> Classhierarchy::searchMemberFunctionCalls(SgMemberFunctionDeclaration* mfCall) { vector<SgMemberFunctionDeclaration*> retvec; property_map< dbgType, boost::vertex_classhierarchy_t>::type chMap = boost::get( boost::vertex_classhierarchy, *this ); SgClassDefinition *classDef = mfCall->get_scope(); SgName classname = classDef->get_qualified_name(); // MANGLE string cnamestr = classname.str(); graph_traits< dbgType >::vertex_iterator vi,vend; dbgVertex vdesc = *vi; bool foundVertex = false; tie(vi,vend) = vertices( *this ); for(; vi!=vend; vi++) { //cerr << " BCH v i"<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; if( get(vertex_dbg_data, *this, *vi).get_typeName() == cnamestr ) { //cerr << " SMF srch "<< cnamestr <<" vi "<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; vdesc = *vi; foundVertex = true; break; } } if(!foundVertex) { cerr << " SMF srch "<< cnamestr <<" vi "<< get(vertex_index,*this,*vi)<< " i1" << get(vertex_index1, *this, *vi)<<","<< get(vertex_name, *this, *vi) << endl; } assert( foundVertex ); set<dbgVertex> treeset; treeset.insert( vdesc ); // first find "highest" class in CH that still provides this MF dbgVertex vhighest = vdesc; // first assume its the current one graph_traits<dbgType>::out_edge_iterator oi,oend; tie(oi,oend) = out_edges( vdesc, *this); for(; oi!=oend; oi++) { //cerr << " SMF inherits from "<< get(vertex_index,*this,target(*oi,*this))<< " i1" << get(vertex_index1, *this, target(*oi,*this))<<","<< get(vertex_name, *this, target(*oi,*this)) << endl; // does any of the base classes implement the member function? bool noParentImpl = true; // check if this base class also implements MF for(set<SgNode*>::iterator chd= chMap[target(*oi,*this)].inherited.begin(); chd!= chMap[target(*oi,*this)].inherited.end(); chd++) { SgFunctionDeclaration *inhFunc = isSgFunctionDeclaration( *chd ); bool virt = false; //cerr << " TOPO v srch1" << endl; if(inhFunc->isVirtual()) virt = true; if( (virt) && (compareFunctionDeclarations(inhFunc,mfCall)) ) { // remeber for traversal treeset.insert( target(*oi, *this) ); noParentImpl = false; } } if(noParentImpl) { // we found it vhighest = target(*oi, *this); break; } } //cerr << " SMF high "<< cnamestr <<" vi "<< get(vertex_index,*this,vhighest)<< " i1" << get(vertex_index1, *this, vhighest)<<","<< get(vertex_name, *this, vhighest) << endl; // now traverse class hierachy downwards, for all children that implement this function, add to set set<dbgVertex> tovisit; set<dbgVertex> visited; tovisit.insert( vhighest ); //hier weiter while( tovisit.size() > 0 ) { dbgVertex currVert = *(tovisit.begin()); tovisit.erase( currVert ); visited.insert( currVert ); //cerr << " SMF visi "<< get(vertex_index,*this,currVert)<< " i1" << get(vertex_index1, *this, currVert)<<","<< get(vertex_name, *this, currVert) << endl; for(set<SgNode*>::iterator chd= chMap[currVert].defined.begin(); chd!= chMap[currVert].defined.end(); chd++) { SgMemberFunctionDeclaration*inhFunc = isSgMemberFunctionDeclaration( *chd ); if(compareFunctionDeclarations(inhFunc,mfCall)) { retvec.push_back( inhFunc ); } } graph_traits<dbgType>::in_edge_iterator ii,iend; tie(ii,iend) = in_edges( currVert, *this); for(; ii!=iend; ii++) { dbgVertex child = source(*ii, *this); // only insert of not already visited set<dbgVertex>::iterator found = visited.find( child ); if(found == visited.end()) tovisit.insert( child ); } } //retvec.push_back( mfCall ); return retvec; }
int main(int argc, char **argv) { SgProject *project = frontend(argc, argv); // Instantiate a class hierarchy wrapper. ClassHierarchyWrapper classHierarchy( project ); #if 0 std::list<SgNode *> nodes2 = NodeQuery::querySubTree(project, V_SgVariableDefinition); for (std::list<SgNode *>::iterator it = nodes2.begin(); it != nodes2.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgVariableDefinition *varDefn = isSgVariableDefinition(n); ROSE_ASSERT(varDefn != NULL); std::cout << "Var defn: " << varDefn->unparseToCompleteString() << std::endl; } std::list<SgNode *> nodes1 = NodeQuery::querySubTree(project, V_SgVariableDeclaration); for (std::list<SgNode *>::iterator it = nodes1.begin(); it != nodes1.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgVariableDeclaration *varDecl = isSgVariableDeclaration(n); ROSE_ASSERT(varDecl != NULL); SgInitializedNamePtrList &variables = varDecl->get_variables(); SgInitializedNamePtrList::iterator varIter; for (varIter = variables.begin(); varIter != variables.end(); ++varIter) { SgNode *var = *varIter; ROSE_ASSERT(var != NULL); SgInitializedName *initName = isSgInitializedName(var); ROSE_ASSERT(initName != NULL); if ( isSgClassType(initName->get_type()) ) { SgClassType *classType = isSgClassType(initName->get_type()); ROSE_ASSERT(classType != NULL); SgDeclarationStatement *declStmt = classType->get_declaration(); ROSE_ASSERT(declStmt != NULL); SgClassDeclaration *classDeclaration = isSgClassDeclaration(declStmt); ROSE_ASSERT(classDeclaration != NULL); // std::cout << "From var decl got: " << classDeclaration->unparseToCompleteString() << std::endl; SgClassDefinition *classDefinition = classDeclaration->get_definition(); if ( classDefinition != NULL ) { std::cout << "From var decl got: " << classDefinition->unparseToCompleteString() << std::endl; } } } } std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgClassDeclaration); for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgClassDeclaration *classDeclaration1 = isSgClassDeclaration(n); ROSE_ASSERT(classDeclaration1 != NULL); SgDeclarationStatement *definingDecl = classDeclaration1->get_definingDeclaration(); if ( definingDecl == NULL ) continue; SgClassDeclaration *classDeclaration = isSgClassDeclaration(definingDecl); ROSE_ASSERT(classDeclaration != NULL); SgClassDefinition *classDefinition = classDeclaration->get_definition(); ROSE_ASSERT(classDefinition != NULL); std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl; SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; } } #endif #if 1 #if 0 std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgClassDefinition); for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgClassDefinition *classDefinition = isSgClassDefinition(n); ROSE_ASSERT(classDefinition != NULL); std::cout << "Calling getSubclasses on " << classDefinition->unparseToCompleteString() << std::endl; SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); std::cout << "subclass" << std::endl; } } #else // Collect all function/method invocations. std::list<SgNode *> nodes = NodeQuery::querySubTree(project, V_SgFunctionCallExp); unsigned int numCallSites = 0; unsigned int numMonomorphicCallSites = 0; unsigned int numPossibleResolutions = 0; // Visit each call site. for (std::list<SgNode *>::iterator it = nodes.begin(); it != nodes.end(); ++it ) { SgNode *n = *it; ROSE_ASSERT(n != NULL); SgFunctionCallExp *functionCallExp = isSgFunctionCallExp(n); ROSE_ASSERT(functionCallExp != NULL); // We are only interested in examining method invocations. bool isDotExp = false; bool isLhsRefOrPtr = false; // std::cout << "method?: " << functionCallExp->unparseToCompleteString() << std::endl; if ( !isMethodCall(functionCallExp, isDotExp, isLhsRefOrPtr) ) continue; // std::cout << "method: " << functionCallExp->unparseToCompleteString() << std::endl; numCallSites++; if ( isDotExp && !isLhsRefOrPtr ) { // If this is a dot expression (i.e., a.foo()), we can // statically determine its type-- unless the left-hand // side is a reference type. numMonomorphicCallSites++; numPossibleResolutions++; // std::cout << "dot: " << functionCallExp->unparseToCompleteString() << std::endl; continue; } // std::cout << "methodPtr: " << functionCallExp->unparseToCompleteString() << std::endl; // Retrieve the static function declaration. SgFunctionDeclaration *functionDeclaration = getFunctionDeclaration(functionCallExp); // Ensure it is actually a method declaration. SgMemberFunctionDeclaration *memberFunctionDeclaration = isSgMemberFunctionDeclaration(functionDeclaration); ROSE_ASSERT(memberFunctionDeclaration != NULL); unsigned int numResolutionsForMethod = 0; // Certainly can be resolved to the static method (unless it // is pure virtual). if ( !isPureVirtual(memberFunctionDeclaration) ) { numResolutionsForMethod++; } #if 0 if ( ( isVirtual(functionDeclaration) ) || ( isDeclaredVirtualWithinAncestor(functionDeclaration) ) ) { #else if ( isVirtual(functionDeclaration) ) { #endif // std::cout << "tracking: " << functionDeclaration->unparseToString() << std::endl; SgClassDefinition *classDefinition = isSgClassDefinition(memberFunctionDeclaration->get_scope()); ROSE_ASSERT(classDefinition != NULL); SgClassDefinitionPtrList subclasses = classHierarchy.getSubclasses(classDefinition); // Iterate over all subclasses. for (SgClassDefinitionPtrList::iterator subclassIt = subclasses.begin(); subclassIt != subclasses.end(); ++subclassIt) { SgClassDefinition *subclass = *subclassIt; ROSE_ASSERT(subclass != NULL); // std::cout << "subclass" << std::endl; // Iterate over all of the methods defined in this subclass. SgDeclarationStatementPtrList &decls = subclass->get_members(); for (SgDeclarationStatementPtrList::iterator declIter = decls.begin(); declIter != decls.end(); ++declIter) { SgDeclarationStatement *declStmt = *declIter; ROSE_ASSERT(declStmt != NULL); SgMemberFunctionDeclaration *method = isSgMemberFunctionDeclaration(declStmt); if ( method == NULL ) { continue; } // std::cout << "checking overrides" << std::endl; // Determine whether subclass of the class defining this // method overrides the method. #if 1 if ( matchingFunctions(method, memberFunctionDeclaration) ) { // std::cout << "overries" << std::endl; // Do not consider a pure virtual method to be an // overriding method (since it can not be invoked). if ( !isPureVirtual(method) ) { numResolutionsForMethod++; } } #else if ( methodOverridesVirtualMethod(method, memberFunctionDeclaration) ) { // std::cout << "overries" << std::endl; numResolutionsForMethod++; } #endif } } if ( numResolutionsForMethod <= 1 ) numMonomorphicCallSites++; numPossibleResolutions += numResolutionsForMethod; if ( ( numResolutionsForMethod ) > 1 ) { std::cout << "Method invocation has " << numResolutionsForMethod << " possible resolutions " << std::endl; std::cout << functionCallExp->unparseToCompleteString() << std::endl; } } } #endif #endif return 0; }
bool isDeclaredVirtualWithinClassAncestry(SgFunctionDeclaration *functionDeclaration, SgClassDefinition *classDefinition) { SgType *functionType = functionDeclaration->get_type(); ROSE_ASSERT(functionType != NULL); // Look in each of the class' parent classes. SgBaseClassPtrList & baseClassList = classDefinition->get_inheritances(); for (SgBaseClassPtrList::iterator i = baseClassList.begin(); i != baseClassList.end(); ++i) { SgBaseClass *baseClass = *i; ROSE_ASSERT(baseClass != NULL); SgClassDeclaration *classDeclaration = baseClass->get_base_class(); ROSE_ASSERT(classDeclaration != NULL); SgDeclarationStatement *definingDecl = classDeclaration->get_definingDeclaration(); if ( definingDecl == NULL ) continue; SgClassDeclaration *definingClassDeclaration = isSgClassDeclaration(definingDecl); ROSE_ASSERT(classDeclaration != NULL); SgClassDefinition *parentClassDefinition = definingClassDeclaration->get_definition(); if ( parentClassDefinition == NULL ) continue; // Visit all methods in the parent class. SgDeclarationStatementPtrList &members = parentClassDefinition->get_members(); bool isDeclaredVirtual = false; for (SgDeclarationStatementPtrList::iterator it = members.begin(); it != members.end(); ++it) { SgDeclarationStatement *declarationStatement = *it; ROSE_ASSERT(declarationStatement != NULL); switch(declarationStatement->variantT()) { case V_SgMemberFunctionDeclaration: { SgMemberFunctionDeclaration *memberFunctionDeclaration = isSgMemberFunctionDeclaration(declarationStatement); if ( isVirtual(memberFunctionDeclaration) ) { SgType *parentMemberFunctionType = memberFunctionDeclaration->get_type(); ROSE_ASSERT(parentMemberFunctionType != NULL); if ( parentMemberFunctionType == functionType ) { return true; } } break; } default: { break; } } } if ( isDeclaredVirtualWithinClassAncestry(functionDeclaration, parentClassDefinition) ) { return true; } } return false; }
void InsertFortranContainsStatement::visit ( SgNode* node ) { // DQ (10/3/2008): This bug in OFP is now fixed so no fixup is required. printf ("Error: fixup of contains statement no longer required. \n"); ROSE_ASSERT(false); // DQ (11/24/2007): Output the current IR node for debugging the traversal of the Fortran AST. ROSE_ASSERT(node != NULL); #if 0 Sg_File_Info* fileInfo = node->get_file_info(); printf ("node = %s fileInfo = %p \n",node->class_name().c_str(),fileInfo); if (fileInfo != NULL) { bool isCompilerGenerated = fileInfo->isCompilerGenerated(); std::string filename = fileInfo->get_filenameString(); int line_number = fileInfo->get_line(); int column_number = fileInfo->get_line(); printf ("--- isCompilerGenerated = %s position = %d:%d filename = %s \n",isCompilerGenerated ? "true" : "false",line_number,column_number,filename.c_str()); } #endif SgFunctionDefinition* functionDefinition = isSgFunctionDefinition(node); // This is for handling where CONTAINS is required in a function if (functionDefinition != NULL) { SgBasicBlock* block = functionDefinition->get_body(); SgStatementPtrList & statementList = block->get_statements(); SgStatementPtrList::iterator i = statementList.begin(); bool firstFunctionDeclaration = false; bool functionDeclarationSeen = false; while (i != statementList.end() && firstFunctionDeclaration == false) { SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); // DQ (1/20/2008): Note that entry statements should not cause introduction of a contains statement! if (isSgEntryStatement(functionDeclaration) != NULL) functionDeclaration = NULL; if (functionDeclaration != NULL) { firstFunctionDeclaration = functionDeclarationSeen == false; functionDeclarationSeen = true; if (firstFunctionDeclaration == true) { // Insert a CONTAINS statement. // printf ("Building a contains statement (in function) \n"); SgContainsStatement* containsStatement = new SgContainsStatement(); SageInterface::setSourcePosition(containsStatement); containsStatement->set_definingDeclaration(containsStatement); block->get_statements().insert(i,containsStatement); containsStatement->set_parent(block); ROSE_ASSERT(containsStatement->get_parent() != NULL); } } i++; } } #if 0 // OFP now has better support for the CONTAINS statement so this code is not longer required. // The use of CONTAINS in modules appears to be handled by OFP, so no fixup is required. SgClassDefinition* classDefinition = isSgClassDefinition(node); // This is for handling where CONTAINS is required in a module if (classDefinition != NULL) { SgDeclarationStatementPtrList & statementList = classDefinition->get_members(); SgDeclarationStatementPtrList::iterator i = statementList.begin(); bool firstFunctionDeclaration = false; bool functionDeclarationSeen = false; while (i != statementList.end() && firstFunctionDeclaration == false) { printf ("InsertFortranContainsStatement: *i in statementList in module = %p = %s \n",*i,(*i)->class_name().c_str()); SgFunctionDeclaration* functionDeclaration = isSgFunctionDeclaration(*i); if (functionDeclaration != NULL) { firstFunctionDeclaration = functionDeclarationSeen == false; functionDeclarationSeen = true; if (firstFunctionDeclaration == true) { // Insert a CONTAINS statement. // printf ("Building a contains statement (in module) \n"); SgContainsStatement* containsStatement = new SgContainsStatement(); SageInterface::setSourcePosition(containsStatement); containsStatement->set_definingDeclaration(containsStatement); // This insert function does not set the parent (unlike for SgBasicBlock) classDefinition->get_members().insert(i,containsStatement); containsStatement->set_parent(classDefinition); ROSE_ASSERT(containsStatement->get_parent() != NULL); } } i++; } } #endif }
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; }