SgVariableDeclaration* buildStructVariable ( SgScopeStatement* scope, vector<SgType*> memberTypes, vector<string> memberNames, string structName = "", string varName = "", SgAggregateInitializer *initializer = NULL ) { ROSE_ASSERT(memberTypes.size() == memberNames.size()); SgClassDeclaration* classDeclaration = buildClassDeclarationAndDefinition(structName,scope); vector<SgType*>::iterator typeIterator = memberTypes.begin(); vector<string>::iterator memberNameIterator = memberNames.begin(); while (typeIterator != memberTypes.end()) { // printf ("Adding data member type = %s variable name = %s \n",(*typeIterator)->unparseToString().c_str(),memberNameIterator->c_str()); SgVariableDeclaration* memberDeclaration = new SgVariableDeclaration(SOURCE_POSITION,*memberNameIterator,*typeIterator,NULL); memberDeclaration->set_endOfConstruct(SOURCE_POSITION); classDeclaration->get_definition()->append_member(memberDeclaration); memberDeclaration->set_parent(classDeclaration->get_definition()); // Liao (2/13/2008) scope and symbols for member variables SgInitializedName* initializedName = *(memberDeclaration->get_variables().begin()); initializedName->set_file_info(SOURCE_POSITION); initializedName->set_scope(classDeclaration->get_definition()); // set nondefning declaration pointer memberDeclaration->set_firstNondefiningDeclaration(memberDeclaration); SgVariableSymbol* variableSymbol = new SgVariableSymbol(initializedName); classDeclaration->get_definition()->insert_symbol(*memberNameIterator,variableSymbol); typeIterator++; memberNameIterator++; } SgClassType* classType = new SgClassType(classDeclaration->get_firstNondefiningDeclaration()); SgVariableDeclaration* variableDeclaration = new SgVariableDeclaration(SOURCE_POSITION,varName,classType,initializer); variableDeclaration->set_endOfConstruct(SOURCE_POSITION); //Liao (2/13/2008) scope and symbols for struct variable SgInitializedName* initializedName = *(variableDeclaration->get_variables().begin()); initializedName->set_file_info(SOURCE_POSITION); initializedName->set_scope(scope); SgVariableSymbol* variableSymbol = new SgVariableSymbol(initializedName); scope->insert_symbol(varName,variableSymbol); //set nondefining declaration variableDeclaration->set_firstNondefiningDeclaration(variableDeclaration); // This is required, since it is not set in the SgVariableDeclaration constructor initializer->set_parent(variableDeclaration); variableDeclaration->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); variableDeclaration->set_baseTypeDefiningDeclaration(classDeclaration->get_definingDeclaration()); classDeclaration->set_parent(variableDeclaration); return variableDeclaration; }
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; }
void RtedTransformation::insertNamespaceIntoSourceFile( SgProject* project ) { //******************************************* // for all of the sourcefiles create a namespace at the top of the file // add to top of each source file // insert at top of all C files in reverse order // only if the class has a constructor and if it is declared in a header file std::vector<SgSourceFile*>::const_iterator aa = srcfiles.begin(); const std::vector<SgSourceFile*>::const_iterator zz = srcfiles.end(); for ( ; aa != zz; ++aa) { SgSourceFile* sf = *aa; bool isInSourceFileSet = isInInstrumentedFile(sf); if (isInSourceFileSet) { // if it is a C++ program, then insert namespace if ( fileType(*sf) == ftCxx ) { if (RTEDDEBUG) cerr << " **** Inserting file into sourceFileRoseNamespaceMap:" << sf -> get_file_info() -> get_filename() << endl; insertNamespaceIntoSourceFile(sf); } } } if (RTEDDEBUG) cerr << "Deep copy of all C++ class declarations to allow offsetof to be used." << endl; std::vector<SgClassDeclaration*> classdecls; collectClassesInHeaderFiles(project, classdecls); // insert at top of all C files in reverse order // only if the class has a constructor and if it is declared in a header file std::vector<SgClassDeclaration*>::const_reverse_iterator classaa = classdecls.rbegin(); std::vector<SgClassDeclaration*>::const_reverse_iterator classzz = classdecls.rend(); while (classaa != classzz) { SgClassDeclaration* classDecl = *classaa; if (hasPrivateDataMembers(classDecl)) { instrumentClassDeclarationIntoTopOfAllSourceFiles(project, classDecl); } visit_isClassDefinition(classDecl->get_definition()); ++classaa; } }
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 instr(SgProject* project, Rose_STL_Container<SgType*> types) { SgGlobal* global = SI::getFirstGlobalScope(project); std::string prefix("rtc_ti_"); //struct prefix std::string ti_type_str("struct rtc_typeinfo*"); SgType* ti_type = SB::buildOpaqueType(ti_type_str,global); //Insert declarations from the typechecking library. //void minalloc_check(unsigned long long addr) SgFunctionDeclaration* minalloc_check_decl = SB::buildNondefiningFunctionDeclaration( SgName("minalloc_check"), SgTypeVoid::createType(), SB::buildFunctionParameterList( SB::buildInitializedName("addr",SB::buildUnsignedLongLongType())), global,NULL); SI::prependStatement(minalloc_check_decl,global); //void typetracker_add(unsigned long long addr, struct rtc_typeinfo* ti); SgFunctionDeclaration* typetracker_add_decl = SB::buildNondefiningFunctionDeclaration( SgName("typetracker_add"), SgTypeVoid::createType(), SB::buildFunctionParameterList( SB::buildInitializedName("addr",SB::buildUnsignedLongLongType()), SB::buildInitializedName("ti",ti_type)), global,NULL); SI::prependStatement(typetracker_add_decl,global); //void setBaseType(rtc_typeinfo* ti, rtc_typeinfo* base) SgFunctionDeclaration* setBaseType_decl = SB::buildNondefiningFunctionDeclaration( SgName("setBaseType"), SgTypeVoid::createType(), SB::buildFunctionParameterList( SB::buildInitializedName("ti",ti_type), SB::buildInitializedName("base",ti_type)), global,NULL); SI::prependStatement(setBaseType_decl,global); //struct rtc_typeinfo* ti_init(const char* a, size_t sz, int c) SgFunctionDeclaration* ti_init_decl = SB::buildNondefiningFunctionDeclaration( SgName("ti_init"), ti_type, SB::buildFunctionParameterList( // SB::buildInitializedName("a",SB::buildPointerType(SB::buildConstType(SB::buildCharType()))), SB::buildInitializedName("a",SB::buildPointerType(SB::buildCharType())), // SB::buildInitializedName("sz", SB::buildOpaqueType("size_t",global)), SB::buildInitializedName("sz", SB::buildLongLongType()), SB::buildInitializedName("c", SB::buildIntType())), global,NULL); SI::prependStatement(ti_init_decl,global); //void traverseAndPrint() SgFunctionDeclaration* traverseAndPrint_decl = SB::buildNondefiningFunctionDeclaration( SgName("traverseAndPrint"),SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL); SI::prependStatement(traverseAndPrint_decl,global); //non-defining declaration of rtc_init_typeinfo SgName init_name("rtc_init_typeinfo"); SgFunctionDeclaration* init_nondef = SB::buildNondefiningFunctionDeclaration(init_name,SgTypeVoid::createType(),SB::buildFunctionParameterList(),global,NULL); SI::prependStatement(init_nondef,global); //call to rtc_init_typeinfo placed in main function. SgFunctionDeclaration* maindecl = SI::findMain(project); SgExprStatement* initcall = SB::buildFunctionCallStmt(init_name,SgTypeVoid::createType(),NULL,maindecl->get_definition()); maindecl->get_definition()->prepend_statement(initcall); //defining declaration of rtc_init_typeinfo SgFunctionDeclaration* init_definingDecl = new SgFunctionDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_name,init_nondef->get_type(),NULL); init_definingDecl->set_firstNondefiningDeclaration(init_nondef); SgFunctionDefinition* init_definition = new SgFunctionDefinition(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),init_definingDecl,SB::buildBasicBlock()); init_definingDecl->set_definition(init_definition); SI::appendStatement(init_definingDecl,global); std::vector<std::string> lst; for(unsigned int index = 0; index < types.size(); index++) { SgType* ptr = types[index]; ptr = ptr->stripTypedefsAndModifiers(); if(!shouldInstrumentType(ptr)) continue; std::string nameStr = prefix + Util::getNameForType(ptr).getString(); if(!contains(lst,nameStr)) { SgVariableDeclaration* decl = SB::buildVariableDeclaration(nameStr,ti_type,NULL,global); SI::prependStatement(decl,global); lst.push_back(nameStr); } } for(unsigned int index = 0; index < types.size(); index++) { SgType* ptr = types[index]; ptr = ptr->stripTypedefsAndModifiers(); if(!shouldInstrumentType(ptr)) continue; std::string typeNameStr = Util::getNameForType(ptr).getString(); std::string structNameStr = prefix + Util::getNameForType(ptr).getString(); if(contains(lst,structNameStr)) { SgExpression* lhs; SgExpression* rhs; //In case of an anonymous struct or union, we create a local, named version of the declaration so we can know its size. SgClassDeclaration* altDecl = NULL; if(isSgNamedType(ptr) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()) && isSgClassDeclaration(isSgNamedType(ptr)->get_declaration())->get_isUnNamed()) { SgClassDeclaration* originalDecl = isSgClassDeclaration(isSgNamedType(ptr)->get_declaration()->get_definingDeclaration()); SgName altDecl_name(typeNameStr + "_def"); altDecl = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type()); SgClassDefinition* altDecl_definition = SB::buildClassDefinition(altDecl); SgDeclarationStatementPtrList originalMembers = originalDecl->get_definition()->get_members(); for(SgDeclarationStatementPtrList::iterator it = originalMembers.begin(); it != originalMembers.end(); it++) { SgDeclarationStatement* member = *it; SgDeclarationStatement* membercpy = isSgDeclarationStatement(SI::copyStatement(member)); altDecl_definition->append_member(membercpy); } SgClassDeclaration* altDecl_nondef = new SgClassDeclaration(new Sg_File_Info(SI::getEnclosingFileNode(global)->getFileName()),altDecl_name,originalDecl->get_class_type()); altDecl_nondef->set_scope(global); altDecl->set_scope(global); altDecl->set_firstNondefiningDeclaration(altDecl_nondef); altDecl_nondef->set_firstNondefiningDeclaration(altDecl_nondef); altDecl->set_definingDeclaration(altDecl); altDecl_nondef->set_definingDeclaration(altDecl); SgClassType* altDecl_ct = SgClassType::createType(altDecl_nondef); altDecl->set_type(altDecl_ct); altDecl_nondef->set_type(altDecl_ct); altDecl->set_isUnNamed(false); altDecl_nondef->set_isUnNamed(false); altDecl_nondef->set_forward(true); SgSymbol* sym = new SgClassSymbol(altDecl_nondef); global->insert_symbol(altDecl_name, sym); altDecl->set_linkage("C"); altDecl_nondef->set_linkage("C"); ROSE_ASSERT(sym && sym->get_symbol_basis() == altDecl_nondef); ROSE_ASSERT(altDecl->get_definingDeclaration() == altDecl); ROSE_ASSERT(altDecl->get_firstNondefiningDeclaration() == altDecl_nondef); ROSE_ASSERT(altDecl->search_for_symbol_from_symbol_table() == sym); ROSE_ASSERT(altDecl->get_definition() == altDecl_definition); ROSE_ASSERT(altDecl->get_scope() == global && altDecl->get_scope() == altDecl_nondef->get_scope()); ROSE_ASSERT(altDecl_ct->get_declaration() == altDecl_nondef); //For some reason, this is not working... //global->append_statement(altDecl); //global->prepend_statement(altDecl_nondef); //SI::setOneSourcePositionForTransformation(altDecl); //SI::setOneSourcePositionForTransformation(altDecl_nondef); } SgType* baseType; if(isSgPointerType(ptr)) baseType = ptr->dereference(); else baseType = ptr->findBaseType(); baseType = baseType->stripTypedefsAndModifiers(); if(baseType == NULL || baseType == ptr) { //In this case, there is no base type. rhs = SB::buildFunctionCallExp(SgName("ti_init"),SgTypeVoid::createType(),SB::buildExprListExp( SB::buildStringVal(ptr->unparseToString()), ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)), SB::buildIntVal(getClassification(ptr)) ),init_definition); } else { //The type has a base type. std::string baseStructNameStr = prefix + Util::getNameForType(baseType).getString(); rhs = SB::buildFunctionCallExp(SgName("ti_init"),ti_type,SB::buildExprListExp( SB::buildStringVal(ptr->unparseToString()), ((altDecl == NULL && !isSgTypeVoid(ptr)) ? (SgExpression*) SB::buildSizeOfOp(types[index]) : (SgExpression*) SB::buildIntVal(-1)), SB::buildIntVal(getClassification(ptr)) ),init_definition); SgExprStatement* set_BT = SB::buildFunctionCallStmt(SgName("setBaseType"),ti_type,SB::buildExprListExp( SB::buildVarRefExp(structNameStr), SB::buildVarRefExp(baseStructNameStr)), init_definition); init_definition->append_statement(set_BT); } lhs = SB::buildVarRefExp(structNameStr); SgExprStatement* assignstmt = SB::buildAssignStatement(lhs,rhs); init_definition->prepend_statement(assignstmt); std::remove(lst.begin(),lst.end(),structNameStr); } } }
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; }
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 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; }