void examineFunctionDeclaration(SgFunctionDeclaration* decl, ostream &out) { SgSymbol* symbol = decl->get_symbol_from_symbol_table(); SgFunctionDefinition* def = decl->get_definition(); ExprSynAttr *attr; stringstream fake; /* We don't want to output the function withou definition */ if (NULL == symbol || NULL == def) return; SgType *ret_type = decl->get_orig_return_type(); examineType(ret_type, out); out << " " << symbol->get_name().getString(); out << "("; SgInitializedNamePtrList& name_list = decl->get_args(); SgInitializedNamePtrList::const_iterator name_iter; for (name_iter = name_list.begin(); name_iter != name_list.end(); name_iter++) { if (name_iter != name_list.begin()) out << ", "; SgInitializedName* name = *name_iter; examineInitializedName(name, out); } out << ")"; out << endl; SgBasicBlock* body = def->get_body(); attr = examineScopeStatement(body,symbol->get_name().getString(), fake); out << attr->code.str(); delete attr; }
void examineInitializedName(SgInitializedName *name, ostream &out) { SgSymbol* symbol = name->get_symbol_from_symbol_table(); if (NULL == symbol) return; SgType *type = symbol->get_type(); int nr_stars = 0; stringstream ss1; while (isSgArrayType(type) || isSgPointerType(type)) { if (isSgArrayType(type)) { SgArrayType *atype = isSgArrayType(type); SgExpression *expr = atype->get_index(); type = atype->get_base_type(); ss1 << "["; if (expr) examineExpr(expr, ss1); ss1 << "]"; } else { SgPointerType *ttype = isSgPointerType(type); type = ttype->get_base_type(); nr_stars++; } } examinePrimTypeName(type, out); out << " "; for (int i = 0; i < nr_stars; ++i) out << "*"; out << symbol->get_name().getString(); out << ss1.str(); SgInitializer *initer = name->get_initializer(); if (initer) { switch (initer->variantT()) { case V_SgAssignInitializer: SgAssignInitializer *ai = isSgAssignInitializer(initer); SgExpression *expr = ai->get_operand(); if (expr) { out << "="; examineExpr(expr, out); } break; default: break; } } }
void FortranAnalysis::visit(SgFunctionCallExp * fcall) { SgFunctionRefExp * fref = isSgFunctionRefExp(fcall->get_function()); if (fref != NULL) { SgExpressionPtrList::iterator it = fcall->get_args()->get_expressions().begin(); std::string name = fref->get_symbol()->get_name().getString(); if (name == "interior" && it != fcall->get_args()->get_expressions().end()) { SgVarRefExp * var = isSgVarRefExp(*it); SgSymbol * sym = var->get_symbol(); sym->setAttribute("halo_attr", new AstTextAttribute("HALO_VAR")); debug("SgFunctionCallExp: adding halo attribute to %s\n", sym->get_name().getString().c_str()); } } }
VariableIdTypeInfo getVariableIdTypeInfo(VariableId vid, VariableIdMapping& vidm) { SgSymbol* symb = vidm.getSymbol(vid); ROSE_ASSERT(symb); SgType* sgn_type = symb->get_type(); VariableIdTypeInfo sgn_type_info; if(isSgArrayType(sgn_type)) sgn_type_info = arrayType; else if(isSgPointerType(sgn_type)) sgn_type_info = pointerType; else if(isSgReferenceType(sgn_type)) sgn_type_info = referenceType; else if(isSgClassType(sgn_type)) sgn_type_info = classType; else sgn_type_info = variableType; return sgn_type_info; }
void mlmFrontend::attachAttribute(SgPragmaDeclaration* pragma, AstAttribute* attr) { // attribute to specify memory level if(isSgVariableDeclaration(getNextStatement(pragma))) { SgVariableDeclaration* decl = isSgVariableDeclaration(getNextStatement(pragma)); ROSE_ASSERT(decl); SgInitializedNamePtrList nameList = decl->get_variables(); if(nameList.size() == 1) { SgInitializedName* initName = nameList[0]; SgSymbol* symbol = initName->get_symbol_from_symbol_table(); symbol->setAttribute("mlmAttribute", attr); } } // attribute to specify tiling level else if(isSgForStatement(getNextStatement(pragma))) { SgForStatement* forStmt = isSgForStatement(getNextStatement(pragma)); ROSE_ASSERT(forStmt); forStmt->setAttribute("mlmAttribute", attr); } }
void Driver<Sage>::addPointerToTopParentDeclaration(SgSymbol * symbol, unsigned file_id) { SgSymbol * parent = symbol; std::map<SgSymbol *, SgSymbol *>::const_iterator it_parent = p_parent_map.find(symbol); assert(it_parent != p_parent_map.end()); while (it_parent->second != NULL) { parent = it_parent->second; it_parent = p_parent_map.find(parent); assert(it_parent != p_parent_map.end()); } assert(parent != NULL); SgDeclarationStatement * decl_to_add = NULL; SgVariableSymbol * var_sym = isSgVariableSymbol(parent); if (var_sym != NULL) { assert(var_sym == symbol); SgInitializedName * init_name = isSgInitializedName(var_sym->get_symbol_basis()); assert(init_name != NULL); // TODO } else decl_to_add = isSgDeclarationStatement(parent->get_symbol_basis()); assert(decl_to_add != NULL); std::map<unsigned, SgSourceFile *>::iterator it_file = id_to_file_map.find(file_id); assert(it_file != id_to_file_map.end()); SgSourceFile * file = it_file->second; assert(file != NULL); SgGlobal * global_scope = file->get_globalScope(); assert(global_scope != NULL); const std::vector<SgDeclarationStatement *> & declaration_list = global_scope->getDeclarationList(); if (find(declaration_list.begin(), declaration_list.end(), decl_to_add) == declaration_list.end()) SageInterface::prependStatement(decl_to_add, global_scope); }
PrologCompTerm* RoseToTerm::getVariableDeclarationSpecific(SgVariableDeclaration* d) { ROSE_ASSERT(d != NULL); /* add base type forward declaration */ SgNode *baseTypeDecl = NULL; if (d->get_variableDeclarationContainsBaseTypeDefiningDeclaration()) { baseTypeDecl = d->get_baseTypeDefiningDeclaration(); } else { /* The complication is that in the AST, the type declaration member is * only set if it is a type definition, not if it is a forward * declaration. So we need to check whether the base type (possibly * below layers of pointers) is a class type, and whether its first * declaration appears to be hidden here in the variable declaration. */ SgClassType *ctype = isSgClassType(d->get_variables().front() ->get_type()->findBaseType()); if (ctype) { /* See if the type is declared in the scope where it belongs. If no, * then the declaration is apparently inside this variable * declaration, so we add it as a subterm. */ SgDeclarationStatement *cdecl = ctype->get_declaration(); SgSymbol *symbol = cdecl->get_symbol_from_symbol_table(); if (!typeWasDeclaredBefore( getTypeSpecific(symbol->get_type())->getRepresentation())) { baseTypeDecl = cdecl; } } } return new PrologCompTerm ("variable_declaration_specific", //3, getDeclarationModifierSpecific(&(d->get_declarationModifier())), (baseTypeDecl != NULL ? traverseSingleNode(baseTypeDecl) : new PrologAtom("null")), PPI(d)); }
void FortranAnalysis::visit(SgFunctionDefinition * func_def) { SgFunctionDeclaration * func_decl = isSgFunctionDeclaration(func_def->get_declaration()); if (func_decl == NULL) return; SgInitializedNamePtrList func_args = func_decl->get_parameterList()->get_args(); SgInitializedNamePtrList::iterator arg = func_args.begin(); // for (it_args = func_args.begin(); it_args != func_args.end(); it_args++) { while (arg != func_args.end()) { SgInitializedName * func_arg = isSgInitializedName(*arg++); SgSymbol * sym = func_def->lookup_symbol(func_arg->get_name()); SgType * type = sym->get_type(); if (sym == NULL) { printf("FortranAnalysis::visit: no symbol for name %s\n", func_arg->get_name().getString().c_str()); } else if (isSgArrayType(type) != NULL) { printf("WARNING: arg %s must be a scalar\n", func_arg->get_name().str()); sym->setAttribute("dummy_attr", new AstTextAttribute("DUMMY_ARRAY_TYPE_ARG")); } else if (isSgNamedType(type)) { sym->setAttribute("dummy_attr", new AstTextAttribute("DUMMY_NAMED_TYPE_ARG")); } else { sym->setAttribute("dummy_attr", new AstTextAttribute("DUMMY_ARG")); } if (sym != NULL && isElementalArrayType(func_arg)) { sym->setAttribute("elemental_attr", new AstTextAttribute("ELEMENTAL_ARRAY")); sym->setAttribute("index_attr", new AstTextAttribute("idx")); } if (sym != NULL && hasArrayDescriptor(func_arg)) { sym->setAttribute("descriptor_attr", new AstTextAttribute("desc_"+func_arg->get_name())); sym->setAttribute("index_attr", new AstTextAttribute("idx_"+func_arg->get_name())); } } }
void FixupAstSymbolTables::visit ( SgNode* node ) { // DQ (6/27/2005): Output the local symbol table from each scope. // printf ("node = %s \n",node->sage_class_name()); SgScopeStatement* scope = isSgScopeStatement(node); if (scope != NULL) { #if 0 printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str()); #endif SgSymbolTable* symbolTable = scope->get_symbol_table(); if (symbolTable == NULL) { #if 0 printf ("AST Fixup: Fixup Symbol Table for %p = %s at: \n",scope,scope->class_name().c_str()); scope->get_file_info()->display("Symbol Table Location"); #endif SgSymbolTable* tempSymbolTable = new SgSymbolTable(); ROSE_ASSERT(tempSymbolTable != NULL); // name this table as compiler generated! The name is a static member used to store // state for the next_symbol() functions. It is meaningless to set these. // tempSymbolTable->set_name("compiler-generated symbol table"); scope->set_symbol_table(tempSymbolTable); // reset the symbolTable using the get_symbol_table() member function symbolTable = scope->get_symbol_table(); ROSE_ASSERT(symbolTable != NULL); // DQ (2/16/2006): Set this parent directly (now tested) symbolTable->set_parent(scope); ROSE_ASSERT(symbolTable->get_parent() != NULL); } ROSE_ASSERT(symbolTable != NULL); if (symbolTable->get_parent() == NULL) { printf ("Warning: Fixing up symbolTable, calling symbolTable->set_parent() (parent not previously set) \n"); symbolTable->set_parent(scope); } ROSE_ASSERT(symbolTable->get_parent() != NULL); // Make sure that the internal hash table used in the symbol table is also present! if (symbolTable->get_table() == NULL) { // DQ (6/27/2005): There are a lot of these built, perhaps more than we really need! #if 0 printf ("AST Fixup: Building internal Symbol Table hash table (rose_hash_multimap) for %p = %s at: \n", scope,scope->sage_class_name()); scope->get_file_info()->display("Symbol Table Location"); #endif rose_hash_multimap* internalHashTable = new rose_hash_multimap(); ROSE_ASSERT(internalHashTable != NULL); symbolTable->set_table(internalHashTable); } ROSE_ASSERT(symbolTable->get_table() != NULL); SgSymbolTable::BaseHashType* internalTable = symbolTable->get_table(); ROSE_ASSERT(internalTable != NULL); // DQ (6/23/2011): Note: Declarations that reference types that have not been seen yet may be placed into the // wronge scope, then later when we see the correct scope we have a symbol in two or more symbol tables. The // code below detects and fixes this problem. // DQ (6/16/2011): List of symbols we need to remove from symbol tables where they are multibily represented. std::vector<SgSymbol*> listOfSymbolsToRemove; // DQ (6/12/2011): Fixup symbol table by removing symbols that are not associated with a declaration in the current scope. int idx = 0; SgSymbolTable::hash_iterator i = internalTable->begin(); while (i != internalTable->end()) { // DQ: removed SgName casting operator to char* // cout << "[" << idx << "] " << (*i).first.str(); ROSE_ASSERT ( (*i).first.str() != NULL ); ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); // printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) sage_class_name() = %s \n", // idx,(*i).first.str(),(*i).second->sage_class_name()); SgSymbol* symbol = isSgSymbol((*i).second); ROSE_ASSERT ( symbol != NULL ); // We have to look at each type of symbol separately! This is because there is no virtual function, // the reason for this is that each get_declaration() function returns a different type! // ROSE_ASSERT ( symbol->get_declaration() != NULL ); switch(symbol->variantT()) { case V_SgClassSymbol: { SgClassSymbol* classSymbol = isSgClassSymbol(symbol); ROSE_ASSERT(classSymbol != NULL); ROSE_ASSERT(classSymbol->get_declaration() != NULL); SgDeclarationStatement* declarationToFindInScope = NULL; // Search for the declaration in the associated scope. declarationToFindInScope = classSymbol->get_declaration(); ROSE_ASSERT(declarationToFindInScope != NULL); SgClassDeclaration* classDeclaration = isSgClassDeclaration(declarationToFindInScope); ROSE_ASSERT(classDeclaration != NULL); SgName name = classDeclaration->get_name(); // SgType* declarationType = declarationToFindInScope->get_type(); SgType* declarationType = classDeclaration->get_type(); ROSE_ASSERT(declarationType != NULL); if (declarationToFindInScope->get_definingDeclaration() != NULL) { declarationToFindInScope = declarationToFindInScope->get_definingDeclaration(); SgClassDeclaration* definingClassDeclaration = isSgClassDeclaration(declarationToFindInScope); ROSE_ASSERT(definingClassDeclaration != NULL); // SgType* definingDeclarationType = declarationToFindInScope->get_type(); SgType* definingDeclarationType = definingClassDeclaration->get_type(); ROSE_ASSERT(definingDeclarationType != NULL); // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C // A simple rule that all declarations should follow (now that we have proper global type tables). // ROSE_ASSERT(definingDeclarationType == declarationType); if (definingDeclarationType != declarationType) { printf ("In fixupSymbolTables.C: Note that definingDeclarationType != declarationType \n"); } } SgNamedType* namedType = isSgNamedType(declarationType); ROSE_ASSERT(namedType != NULL); SgDeclarationStatement* declarationAssociatedToType = namedType->get_declaration(); ROSE_ASSERT(declarationAssociatedToType != NULL); #if 0 printf ("Found a symbol without a matching declaration in the current scope (declList): declarationToFindInScope = %p = %s \n",declarationToFindInScope,declarationToFindInScope->class_name().c_str()); printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) class_name() = %s \n",idx,(*i).first.str(),(*i).second->class_name().c_str()); #endif SgScopeStatement* scopeOfDeclarationToFindInScope = declarationToFindInScope->get_scope(); SgScopeStatement* scopeOfDeclarationAssociatedWithType = declarationAssociatedToType->get_scope(); #if 0 printf ("declarationToFindInScope = %p declarationToFindInScope->get_scope() = %p = %s \n",declarationToFindInScope,declarationToFindInScope->get_scope(),declarationToFindInScope->get_scope()->class_name().c_str()); printf ("declarationAssociatedToType = %p declarationAssociatedToType->get_scope() = %p = %s \n",declarationAssociatedToType,declarationAssociatedToType->get_scope(),declarationAssociatedToType->get_scope()->class_name().c_str()); #endif if (scopeOfDeclarationToFindInScope != scopeOfDeclarationAssociatedWithType) { // DQ (6/12/2011): Houston, we have a problem! The trick is to fix it... // A symbol has been placed into a scope when we could not be certain which scope it should be placed. // We have a default of placing such symbols into the global scope, but it might be better to just have // a special scope where such symbols could be placed so that we could have them separate from the global // scope and then fix them up more clearly. // Note that test2011_80.C still fails but the AST is at least correct (I think). SgGlobal* scopeOfDeclarationToFindInScope_GlobalScope = isSgGlobal(scopeOfDeclarationToFindInScope); // SgGlobal* scopeOfDeclarationAssociatedWithType_GlobalScope = isSgGlobal(scopeOfDeclarationAssociatedWithType); if (scopeOfDeclarationToFindInScope_GlobalScope != NULL) { // In general which ever scope is the global scope is where the error is...??? // This is because when we don't know where to put a symbol (e.g. from a declaration of a pointer) we put it into global scope. // There is even an agrument that this is correct as a default for C/C++, but only if it must exist (see test2011_80.C). // Remove the symbol from the symbol table of the global scope. printf ("Remove the associated symbol in the current symbol table \n"); // DQ (6/22/2011): This assertion fails for CompileTests/copyAST_tests/copytest2007_24.C // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope()); if (declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope()) printf ("In fixupSymbolTables.C: Note that declarationToFindInScope->get_scope() != declarationAssociatedToType->get_scope() \n"); } else { listOfSymbolsToRemove.push_back(classSymbol); } } // ROSE_ASSERT (declarationToFindInScope->get_scope() == declarationAssociatedToType->get_scope()); break; } default: { // It night be there are are no other types of symbols to consider... // printf ("Ignoring non SgClassSymbols (fixupSymbolTables.C) symbol = %s \n",symbol->class_name().c_str()); // ROSE_ASSERT(false); } } // Increment iterator! i++; // Increment counter! idx++; } // DQ (6/18/2011): Now that we are through with the symbol table we can support removal of any // identified problematic symbol without worrying about STL iterator invalidation. for (size_t j = 0; j < listOfSymbolsToRemove.size(); j++) { // Remove these symbols. SgSymbol* removeSymbol = listOfSymbolsToRemove[j]; ROSE_ASSERT(removeSymbol != NULL); SgSymbolTable* associatedSymbolTable = isSgSymbolTable(removeSymbol->get_parent()); ROSE_ASSERT(associatedSymbolTable != NULL); ROSE_ASSERT(associatedSymbolTable == symbolTable); associatedSymbolTable->remove(removeSymbol); printf ("Redundant symbol removed...from symbol table \n"); // ROSE_ASSERT(false); } #if 0 // debugging symbolTable->print("In FixupAstSymbolTables::visit(): printing out the symbol tables"); #endif } }
void AstPDFGeneration_private::edit_page(size_t pageNumber, SgNode* node, PDFInheritedAttribute inheritedValue) { // JW (added by DQ 7/23/2004): Adds address of each IR node to the top of the page HPDF_Page_SetRGBFill(currentPage, 1, 0, 0); // DQ (1/20/2006): Modified for 64 bit machines // ostringstream _ss; _ss << "0x" << std::hex << (int)node; ostringstream _ss; _ss << "pointer:" << std::hex << node; HPDF_Page_ShowTextNextLine(currentPage, _ss.str().c_str()); // Liao, 2/11/2009, move some essential information from bookmark into the page also // since some deep levels of bookmarks cannot display long lines properly by acrobat reader HPDF_Page_ShowTextNextLine(currentPage, node->sage_class_name()); SgLocatedNode* sgLocNode = dynamic_cast<SgLocatedNode*> (node); if(sgLocNode) { Sg_File_Info* fi = sgLocNode->get_file_info(); ostringstream temp; temp<<fi->get_filename()<<" "<<fi->get_line()<<":"<<fi->get_col(); if(fi) HPDF_Page_ShowTextNextLine(currentPage,temp.str().c_str()); if (fi->isTransformation()) HPDF_Page_ShowTextNextLine(currentPage,"IsTransformation:1"); else HPDF_Page_ShowTextNextLine(currentPage,"IsTransformation:0"); if (fi->isOutputInCodeGeneration()) HPDF_Page_ShowTextNextLine(currentPage,"IsOutputInCodeGeneration:1"); else HPDF_Page_ShowTextNextLine(currentPage,"IsOutputInCodeGeneration:0"); } if (isSgDeclarationStatement(node)) { HPDF_Page_ShowTextNextLine(currentPage, ("Declaration mangled name: " + isSgDeclarationStatement(node)->get_mangled_name().getString()).c_str()); #if 0 // not necessary, p_name field gives the similar information if (isSgDeclarationStatement(node)->hasAssociatedSymbol()) { SgSymbol *symbol = isSgDeclarationStatement(node)->get_symbol_from_symbol_table (); if (symbol) HPDF_Page_ShowTextNextLine(currentPage, ("Symbol name: " + symbol->get_name().getString()).c_str()); } #endif } // JW hack to show expression types if (isSgExpression(node)) HPDF_Page_ShowTextNextLine(currentPage, ("Expression type: " + isSgExpression(node)->get_type()->unparseToString()).c_str()); HPDF_Page_SetRGBFill(currentPage, 0, 1, 0); if (inheritedValue.parentPage==NULL) { HPDF_Page_ShowTextNextLine(currentPage, ""); HPDF_Page_ShowTextNextLine(currentPage, " root node"); } else { HPDF_Page_ShowTextNextLine(currentPage, ""); HPDF_Page_ShowTextNextLine(currentPage, " "); create_textlink("Click here to go to the parent node", inheritedValue.parentPage, 9); } HPDF_Page_ShowTextNextLine(currentPage, ""); HPDF_Page_ShowTextNextLine(currentPage, ""); // generate RTI information for SgNode { RTIReturnType rti=node->roseRTI(); for(RTIReturnType::iterator i=rti.begin(); i<rti.end(); i++) { if (strlen(i->type) >= 7 && strncmp(i->type, "static ", 7) == 0) { continue; // Skip static members } HPDF_Page_SetRGBFill(currentPage, 0.5, 0, 0.1); HPDF_Page_ShowTextNextLine(currentPage, i->type); HPDF_Page_ShowText(currentPage, " "); HPDF_Page_SetRGBFill(currentPage, 0.0, 0.5, 0.5); HPDF_Page_ShowText(currentPage, i->name); HPDF_Page_ShowText(currentPage, " : "); HPDF_Page_SetRGBFill(currentPage, 0.0, 0.0, 0.0); string value=i->value; if (value.size() >= 80) { // HPDF doesn't like strings > 64k, and we probably shouldn't be trying to print them anyway; this trims things to a reasonable length value = "<too long>: " + value.substr(0, 80); } if (value.size() >= 80) { value = "<too long>: " + value.substr(0, 80); } AstNodeVisitMapping::MappingType::iterator mapit; // ensure that mapping value exists (otherwise it would be added to the map) // and decide whether to create a link to a page (representing a node) or not mapit=addrPageMapping.find(value); if (mapit!=addrPageMapping.end()) { size_t destPageNum = mapit->second; ROSE_ASSERT (destPageNum < pageDests.size()); create_textlink(value.c_str(), pageDests[destPageNum] /* targetpage */); } else { HPDF_Page_ShowText(currentPage,value.c_str()); } } } // generate AstAttribute information { // printf ("In AstPDFGeneration_private::edit_page(): using new attribute interface \n"); // if (node->get_attribute() != NULL) #if 0 if (node->getAttribute() != NULL) { AstAttributeMechanism::AttributeIdentifiers aidents = node->attribute().getAttributeIdentifiers(); PDF_continue_text(pdfFile, ""); // next line PDF_setrgbcolor(pdfFile, 0.0, 0.2, 0.7); PDF_continue_text(pdfFile, "AstAttributes:"); // next line for (AstAttributeMechanism::AttributeIdentifiers::iterator it = aidents.begin(); it != aidents.end(); it++) { PDF_continue_text(pdfFile, ""); // next line PDF_setrgbcolor(pdfFile, 0.0, 0.2, 0.7); PDF_show(pdfFile,((*it)+": ").c_str()); PDF_setrgbcolor(pdfFile, 0.0, 0.0, 0.0); // float textxpos=PDF_get_value(pdfFile,"textx",0.0); // float textypos=PDF_get_value(pdfFile,"texty",0.0); string attributeValue = (node->attribute()[*it])->toString(); // split string into different substrings separated by newlines string substring=""; int oldpos=0; int newpos; do { newpos=attributeValue.find('\n', oldpos); substring=attributeValue.substr(oldpos,newpos-oldpos); if(oldpos==0) PDF_show(pdfFile, substring.append(" ").c_str()); else PDF_continue_text(pdfFile, substring.c_str()); oldpos = newpos+1; // go to next '\n' and skip it } // DQ (8/9/2005): Suggested fix from Rich (fixes infinite loop where AST Attributes are attached) // while( newpos < (int) attributeValue.size()); while( newpos < (int) attributeValue.size() && newpos >= 0 ); // PDF_show_boxed(pdfFile, attributeValue.c_str(), textxpos, textypos, 0, 0, "left", ""); } } #else // DQ (4/10/2006): New AstAttribute Interface (but access the AstAttributeMechanism directly // since "getAttributeIdentifiers()" is not in the interface implemented at the IR nodes). if (node->get_attributeMechanism() != NULL) { AstAttributeMechanism::AttributeIdentifiers aidents = node->get_attributeMechanism()->getAttributeIdentifiers(); HPDF_Page_ShowTextNextLine(currentPage, ""); // next line HPDF_Page_SetRGBFill(currentPage, 0.0, 0.2, 0.7); HPDF_Page_ShowTextNextLine(currentPage, "AstAttributes:"); // next line for (AstAttributeMechanism::AttributeIdentifiers::iterator it = aidents.begin(); it != aidents.end(); it++) { HPDF_Page_ShowTextNextLine(currentPage, ""); // next line HPDF_Page_SetRGBFill(currentPage, 0.0, 0.2, 0.7); HPDF_Page_ShowText(currentPage,((*it)+": ").c_str()); HPDF_Page_SetRGBFill(currentPage, 0.0, 0.0, 0.0); // float textxpos=PDF_get_value(pdfFile,"textx",0.0); // float textypos=PDF_get_value(pdfFile,"texty",0.0); // string attributeValue = (node->attribute()[*it])->toString(); string attributeValue = node->getAttribute(*it)->toString(); // split string into different substrings separated by newlines string substring=""; int oldpos=0; int newpos; do { newpos=attributeValue.find('\n', oldpos); substring=attributeValue.substr(oldpos,newpos-oldpos); if(oldpos==0) HPDF_Page_ShowText(currentPage, substring.append(" ").c_str()); else HPDF_Page_ShowTextNextLine(currentPage, substring.c_str()); oldpos = newpos+1; // go to next '\n' and skip it } // DQ (8/9/2005): Suggested fix from Rich (fixes infinite loop where AST Attributes are attached) // while( newpos < (int) attributeValue.size()); while( newpos < (int) attributeValue.size() && newpos >= 0 ); // PDF_show_boxed(pdfFile, attributeValue.c_str(), textxpos, textypos, 0, 0, "left", ""); } } // end if #endif } }
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); } } }
ExprSynAttr *examineVariableDeclaration(SgVariableDeclaration* decl, ostream &out) { SgInitializedNamePtrList& name_list = decl->get_variables(); SgInitializedNamePtrList::const_iterator name_iter; ExprSynAttr *ret = NULL; ExprSynAttr *gc = NULL; ret = new ExprSynAttr(); for (name_iter = name_list.begin(); name_iter != name_list.end(); name_iter++) { SgInitializedName* name = *name_iter; SgSymbol* symbol = name->get_symbol_from_symbol_table(); SgType *type = symbol->get_type(); int nr_stars = 0; stringstream ss1; while (isSgArrayType(type) || isSgPointerType(type)) { if (isSgArrayType(type)) { SgArrayType *atype = isSgArrayType(type); SgExpression *expr = atype->get_index(); type = atype->get_base_type(); ss1 << "["; if (expr) examineExpr(expr, ss1); ss1 << "]"; } else { SgPointerType *ttype = isSgPointerType(type); type = ttype->get_base_type(); nr_stars++; } } examinePrimTypeName(type, ret->code); ret->code << " "; for (int i = 0; i < nr_stars; ++i) ret->code << "*"; ret->code << symbol->get_name().getString(); ret->code << ss1.str(); ss1.str(""); SgInitializer *initer = name->get_initializer(); if (initer) { switch (initer->variantT()) { case V_SgAssignInitializer: SgAssignInitializer *ai = isSgAssignInitializer(initer); SgExpression *expr = ai->get_operand(); if (expr) { ret->code << "="; gc = examineExpr(expr, ret->code); if (gc != NULL) delete gc; } break; default: break; } } /* end of this decl */ ret->code << ";"; out << ret->code.str(); return ret; /* cout << "[Decl] Variable (name:"<<symbol->get_name().getString(); cout << ",type:"<<symbol->get_type()->class_name(); cout << ",init:"; SgInitializer* init_expr = name->get_initializer(); if (init_expr) cout << init_expr->class_name(); else cout << "none"; cout << ")" << endl; */ } }
void TransformationSupport::getTransformationOptions ( SgNode* astNode, list<OptionDeclaration> & generatedList, string identifingTypeName ) { // This function searches for variables of type ScopeBasedTransformationOptimization. Variables // of type ScopeBasedTransformationOptimization are used to communicate optimizations from the // application to the preprocessor. If called from a project or file object it traverses down to // the global scope of the file and searches only the global scope, if called from and other // location within the AST it searches the current scope and then traverses the parent nodes to // find all enclosing scopes until in reaches the global scope. At each scope it searches for // variables of type ScopeBasedTransformationOptimization. // printf ("######################### START OF TRANSFORMATION OPTION QUERY ######################## \n"); ROSE_ASSERT (astNode != NULL); ROSE_ASSERT (identifingTypeName.c_str() != NULL); #if 0 printf ("In getTransformationOptions(): astNode->sage_class_name() = %s generatedList.size() = %d \n", astNode->sage_class_name(),generatedList.size()); SgLocatedNode* locatedNode = isSgLocatedNode(astNode); if (locatedNode != NULL) { printf (" locatedNode->get_file_info()->get_filename() = %s \n",locatedNode->get_file_info()->get_filename()); printf (" locatedNode->get_file_info()->get_line() = %d \n",locatedNode->get_file_info()->get_line()); } #endif switch (astNode->variant()) { case ProjectTag: { SgProject* project = isSgProject(astNode); ROSE_ASSERT (project != NULL); //! Loop through all the files in the project and call the mainTransform function for each file int i = 0; for (i=0; i < project->numberOfFiles(); i++) { SgFile* file = &(project->get_file(i)); // printf ("Calling Query::traverse(SgFile,QueryFunctionType,QueryAssemblyFunctionType) \n"); getTransformationOptions ( file, generatedList, identifingTypeName ); } break; } case SourceFileTag: { SgSourceFile* file = isSgSourceFile(astNode); ROSE_ASSERT (file != NULL); SgGlobal* globalScope = file->get_globalScope(); ROSE_ASSERT (globalScope != NULL); ROSE_ASSERT (isSgGlobal(globalScope) != NULL); getTransformationOptions ( globalScope, generatedList, identifingTypeName ); break; } // Global Scope case GLOBAL_STMT: { SgGlobal* globalScope = isSgGlobal(astNode); ROSE_ASSERT (globalScope != NULL); SgSymbolTable* symbolTable = globalScope->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // printf ("Processed global scope, exiting .. \n"); // ROSE_ABORT(); break; } case SymbolTableTag: { // List the variable in each scope // printf ("List all the variables in this symbol table! \n"); SgSymbolTable* symbolTable = isSgSymbolTable(astNode); ROSE_ASSERT (symbolTable != NULL); bool foundTransformationOptimizationSpecifier = false; // printf ("Now print out the information in the symbol table for this scope: \n"); // symbolTable->print(); #if 0 // I don't know when a SymbolTable is given a name! printf ("SymbolTable has a name = %s \n", (symbolTable->get_no_name()) ? "NO: it has no name" : "YES: it does have a name"); if (!symbolTable->get_no_name()) printf ("SymbolTable name = %s \n",symbolTable->get_name().str()); else ROSE_ASSERT (symbolTable->get_name().str() == NULL); #endif if (symbolTable->get_table() != NULL) { SgSymbolTable::hash_iterator i = symbolTable->get_table()->begin(); int counter = 0; while (i != symbolTable->get_table()->end()) { ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); // printf ("Initial info: number: %d pair.first (SgName) = %s pair.second (SgSymbol) sage_class_name() = %s \n", // counter,(*i).first.str(),(*i).second->sage_class_name()); SgSymbol* symbol = isSgSymbol((*i).second); ROSE_ASSERT ( symbol != NULL ); SgType* type = symbol->get_type(); ROSE_ASSERT ( type != NULL ); SgNamedType* namedType = isSgNamedType(type); string typeName; if (namedType != NULL) { SgName n = namedType->get_name(); typeName = namedType->get_name().str(); // char* nameString = namedType->get_name().str(); // printf ("Type is: (named type) = %s \n",nameString); ROSE_ASSERT (identifingTypeName.c_str() != NULL); // ROSE_ASSERT (typeName != NULL); // printf ("In getTransformationOptions(): typeName = %s identifingTypeName = %s \n",typeName.c_str(),identifingTypeName.c_str()); // if ( (typeName != NULL) && ( typeName == identifingTypeName) ) if ( typeName == identifingTypeName ) { // Now look at the parameter list to the constructor and save the // values into the list. // printf ("Now save the constructor arguments! \n"); SgVariableSymbol* variableSymbol = isSgVariableSymbol(symbol); if ( variableSymbol != NULL ) { SgInitializedName* initializedNameDeclaration = variableSymbol->get_declaration(); ROSE_ASSERT (initializedNameDeclaration != NULL); SgDeclarationStatement* declarationStatement = initializedNameDeclaration->get_declaration(); ROSE_ASSERT (declarationStatement != NULL); SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(declarationStatement); ROSE_ASSERT (variableDeclaration != NULL); getTransformationOptionsFromVariableDeclarationConstructorArguments(variableDeclaration,generatedList); foundTransformationOptimizationSpecifier = true; // printf ("Exiting after saving the constructor arguments! \n"); // ROSE_ABORT(); } else { #if 0 printf ("Not a SgVariableSymbol: symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif } } else { #if 0 printf ("typeName != identifingTypeName : symbol->sage_class_name() = %s \n", symbol->sage_class_name()); #endif #if 0 // I don't think this should ever be NULL (but it is sometimes) if (typeName != NULL) printf ("typeName == NULL \n"); #endif } } else { typeName = (char *)type->sage_class_name(); } // printf ("In while loop at the base: counter = %d \n",counter); i++; counter++; } } else { // printf ("Pointer to symbol table is NULL \n"); } // printf ("foundTransformationOptimizationSpecifier = %s \n",foundTransformationOptimizationSpecifier ? "true" : "false"); // SgSymbolTable objects don't have a parent node (specifically they lack a get_parent // member function in the interface)! break; } case BASIC_BLOCK_STMT: { // List the variable in each scope // printf ("List all the variables in this scope! \n"); SgBasicBlock* basicBlock = isSgBasicBlock(astNode); ROSE_ASSERT (basicBlock != NULL); SgSymbolTable* symbolTable = basicBlock->get_symbol_table(); ROSE_ASSERT (symbolTable != NULL); getTransformationOptions ( symbolTable, generatedList, identifingTypeName ); // Next go (fall through this case) to the default case so that we traverse the parent // of the SgBasicBlock. // break; } default: // Most cases will be the default (this is by design) // printf ("default in switch found in globalQueryGetListOperandStringFunction() (sage_class_name = %s) \n",astNode->sage_class_name()); // Need to recursively backtrack through the parents until we reach the SgGlobal (global scope) SgStatement* statement = isSgStatement(astNode); if (statement != NULL) { SgNode* parentNode = statement->get_parent(); ROSE_ASSERT (parentNode != NULL); // printf ("parent = %p parentNode->sage_class_name() = %s \n",parentNode,parentNode->sage_class_name()); SgStatement* parentStatement = isSgStatement(parentNode); if (parentStatement == NULL) { printf ("parentStatement == NULL: statement (%p) is a %s \n",statement,statement->sage_class_name()); printf ("parentStatement == NULL: statement->get_file_info()->get_filename() = %s \n",statement->get_file_info()->get_filename()); printf ("parentStatement == NULL: statement->get_file_info()->get_line() = %d \n",statement->get_file_info()->get_line()); } ROSE_ASSERT (parentStatement != NULL); // Call this function recursively (directly rather than through the query mechanism) getTransformationOptions ( parentStatement, generatedList, identifingTypeName ); } else { // printf ("astNode is not a SgStatement! \n"); } break; } #if 0 printf ("At BASE of getTransformationOptions(): astNode->sage_class_name() = %s size of generatedList = %d \n", astNode->sage_class_name(),generatedList.size()); #endif // printf ("######################### END OF TRANSFORMATION OPTION QUERY ######################## \n"); }
void mlmTransform::transformCallExp(SgCallExpression* callExp) { ROSE_ASSERT(callExp); SgFunctionRefExp* funcName = isSgFunctionRefExp(callExp->get_function()); if(!funcName) return; SgExprListExp* funcArgList = callExp->get_args(); SgExpressionPtrList argList = funcArgList->get_expressions(); SgScopeStatement* scope = getScope(callExp); //cout << funcName->get_symbol()->get_name() << endl; /** if it is malloc, search for the mlm attribute and append the memory level **/ if(strncmp("malloc",funcName->get_symbol()->get_name().str(),6) == 0) { if(argList.size() != 1) return; SgExprListExp* funcArgList = callExp->get_args(); // check if LHS of malloc has an attribute assigned SgNode* parentNode = callExp->get_parent(); // parent node can be a casting expression if(isSgCastExp(parentNode)) { parentNode = parentNode->get_parent(); } // the mlm attribute AstAttribute* attr = NULL; // So far we spot two candidates for parentNode that we need to transform if(isSgAssignOp(parentNode)) { SgAssignOp* assignOp = isSgAssignOp(parentNode); SgExpression* lhs = isSgExpression(assignOp->get_lhs_operand()); if(!isSgVarRefExp(lhs)) { //cout << "lhs:" << assignOp->get_lhs_operand()->class_name() << endl; // if pointer is packaged inside a struct, then we need to look down in lhs. if(isSgDotExp(lhs)) { lhs = isSgDotExp(lhs)->get_rhs_operand(); } } SgVarRefExp* lhsVarRef = isSgVarRefExp(lhs); ROSE_ASSERT(lhsVarRef); SgSymbol* symbol = lhsVarRef->get_symbol(); ROSE_ASSERT(symbol); //retrieve the attribute from symbol attr = symbol->getAttribute("mlmAttribute"); //cout << "LHS symbol name: " << symbol->get_name() << endl; } else if(isSgAssignInitializer(parentNode)) { SgInitializedName* initName = isSgInitializedName(parentNode->get_parent()); ROSE_ASSERT(initName); SgSymbol* symbol = initName->get_symbol_from_symbol_table(); if(!symbol) return; ROSE_ASSERT(symbol); //retrieve the attribute from symbol attr = symbol->getAttribute("mlmAttribute"); //cout << "Initialized symbol name: " << symbol->get_name() << endl; } else { // do nothing because no attribute assigned or we always set to default } // if there is a mlm attribute attached to the symbol, then create new malloc if(attr) { mlmAttribute* mlmAttr = dynamic_cast<mlmAttribute*> (attr); SgExprListExp* funcArgList = callExp->get_args(); funcArgList->append_expression(buildIntVal(mlmAttr->getMemType())); replaceExpression(callExp, buildFunctionCallExp("mlm_malloc",deepCopy(callExp->get_type()),deepCopy(funcArgList),getScope(callExp))); } } else if(strncmp("memcpy",funcName->get_symbol()->get_name().str(),6) == 0) { // cout << "replacing memcpy" << endl; if(argList.size() != 3) return; Rose_STL_Container<SgNode*> varList = NodeQuery::querySubTree(funcArgList, V_SgVarRefExp); SgVarRefExp* dst = isSgVarRefExp(varList[0]); SgVarRefExp* src = isSgVarRefExp(varList[1]); AstAttribute* attrDst = dst->get_symbol()->getAttribute("mlmAttribute"); AstAttribute* attrSrc = src->get_symbol()->getAttribute("mlmAttribute"); mlmAttribute* mlmAttrDst = dynamic_cast<mlmAttribute*>(attrDst); mlmAttribute* mlmAttrSrc = dynamic_cast<mlmAttribute*>(attrSrc); // if((mlmAttrDst && !mlmAttrSrc) || (mlmAttrDst && mlmAttrSrc && (mlmAttrDst->getMemType() < mlmAttrDst->getMemType()))) // { // replaceExpression(callExp, buildFunctionCallExp("mlm_memcpy",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope),true); // DeletepragmasList2.push_back(callExp); // } // // else if((!mlmAttrDst && mlmAttrSrc) || (mlmAttrDst && mlmAttrSrc && (mlmAttrDst->getMemType() > mlmAttrDst->getMemType()))) // 09/30/14 Following Simon's suggestion, we always insert wait for the mlm_memcpy // { string tagName = generateUniqueVariableName(scope,"copy_tag"); SgVariableDeclaration* newDecl = buildVariableDeclaration(tagName, buildOpaqueType("mlm_Tag",getGlobalScope(callExp)), buildAssignInitializer(buildFunctionCallExp("mlm_memcpy",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope))); SgExprStatement* waitStmt = buildFunctionCallStmt("mlm_waitComplete", buildVoidType(), buildExprListExp(buildVarRefExp(tagName,scope)), scope); insertStatement(getEnclosingStatement(callExp),newDecl,true); insertStatement(getEnclosingStatement(callExp),waitStmt,true); removeStatement(getEnclosingStatement(callExp)); // } } else if(strncmp("free",funcName->get_symbol()->get_name().str(),4) == 0) { // cout << "replacing free" << endl; if(argList.size() != 1) return; SgExpression* varExp = isSgExpression(argList[0]); //cout << "exp:" << varExp->class_name() << endl; if(!isSgVarRefExp(varExp)) { if(isSgCastExp(varExp)) { varExp = isSgCastExp(varExp)->get_operand_i(); } // if pointer is packaged inside a struct, then we need to look down in lhs. if(isSgDotExp(varExp)) { varExp = isSgDotExp(varExp)->get_rhs_operand(); } } SgVarRefExp* varRef = isSgVarRefExp(varExp); ROSE_ASSERT(varRef); AstAttribute* attr = varRef->get_symbol()->getAttribute("mlmAttribute"); if(attr) { replaceExpression(callExp, buildFunctionCallExp("mlm_free",deepCopy(callExp->get_type()),deepCopy(funcArgList),scope),false); } } }
// DQ (8/23/2011): Made this a static function so that I could call it from the Java support. void FixupAstSymbolTablesToSupportAliasedSymbols::injectSymbolsFromReferencedScopeIntoCurrentScope ( SgScopeStatement* referencedScope, SgScopeStatement* currentScope, SgNode* causalNode, SgAccessModifier::access_modifier_enum accessLevel ) { ROSE_ASSERT(referencedScope != NULL); ROSE_ASSERT(currentScope != NULL); #if ALIAS_SYMBOL_DEBUGGING || 0 printf ("In injectSymbolsFromReferencedScopeIntoCurrentScope(): referencedScope = %p = %s currentScope = %p = %s accessLevel = %d \n",referencedScope,referencedScope->class_name().c_str(),currentScope,currentScope->class_name().c_str(),accessLevel); #endif SgSymbolTable* symbolTable = referencedScope->get_symbol_table(); ROSE_ASSERT(symbolTable != NULL); #if 0 printf ("AST Fixup: Building Symbol Table for %p = %s at: \n",scope,scope->sage_class_name()); referencedScope->get_file_info()->display("Symbol Table Location"); #endif SgClassDefinition* classDefinition = isSgClassDefinition(referencedScope); if (classDefinition != NULL) { // If this is a class definition, then we need to make sure that we only for alias symbols for those declarations. #if ALIAS_SYMBOL_DEBUGGING printf ("Injection of symbols from a class definition needs to respect access priviledge (private, protected, public) declarations \n"); #endif } SgSymbolTable::BaseHashType* internalTable = symbolTable->get_table(); ROSE_ASSERT(internalTable != NULL); int counter = 0; SgSymbolTable::hash_iterator i = internalTable->begin(); while (i != internalTable->end()) { // DQ: removed SgName casting operator to char* // cout << "[" << idx << "] " << (*i).first.str(); ROSE_ASSERT ( (*i).first.str() != NULL ); ROSE_ASSERT ( isSgSymbol( (*i).second ) != NULL ); #if ALIAS_SYMBOL_DEBUGGING printf ("Symbol number: %d (pair.first (SgName) = %s) pair.second (SgSymbol) class_name() = %s \n",counter,(*i).first.str(),(*i).second->class_name().c_str()); #endif SgName name = (*i).first; SgSymbol* symbol = (*i).second; ROSE_ASSERT ( symbol != NULL ); // Make sure that this is not a SgLabelSymbol, I think these should not be aliased // (if only because I don't think that C++ support name qualification for labels). ROSE_ASSERT ( isSgLabelSymbol(symbol) == NULL ); // DQ (6/22/2011): For now skip the handling of alias symbol from other scopes. // ROSE_ASSERT(isSgAliasSymbol(symbol) == NULL); if (isSgAliasSymbol(symbol) != NULL) { #if ALIAS_SYMBOL_DEBUGGING printf ("WARNING: Not clear if we want to nest SgAliasSymbol inside of SgAliasSymbol \n"); #endif // DQ (9/22/2012): We need to avoid building chains of SgAliasSymbol (to simplify the representation in the AST). while (isSgAliasSymbol(symbol) != NULL) { #if ALIAS_SYMBOL_DEBUGGING printf (" --- Iterating to root of alias: symbol = %p = %s \n",symbol,symbol->class_name().c_str()); #endif symbol = isSgAliasSymbol(symbol)->get_alias(); ROSE_ASSERT(symbol != NULL); } #if ALIAS_SYMBOL_DEBUGGING printf ("Resolved aliased symbol to root symbol: symbol = %p = %s \n",symbol,symbol->class_name().c_str()); #endif } SgNode* symbolBasis = symbol->get_symbol_basis(); ROSE_ASSERT(symbolBasis != NULL); #if ALIAS_SYMBOL_DEBUGGING printf ("symbolBasis = %p = %s \n",symbolBasis,symbolBasis->class_name().c_str()); #endif // SgDeclarationStatement* declarationFromSymbol = symbol->get_declaration(); SgDeclarationStatement* declarationFromSymbol = isSgDeclarationStatement(symbolBasis); SgAccessModifier::access_modifier_enum declarationAccessLevel = SgAccessModifier::e_unknown; // ROSE_ASSERT(declarationFromSymbol != NULL); if (declarationFromSymbol != NULL) { // DQ (6/22/2011): Can I, or should I, do relational operations on enum values (note that the values are designed to allow this). declarationAccessLevel = declarationFromSymbol->get_declarationModifier().get_accessModifier().get_modifier(); } else { SgInitializedName* initializedNameFromSymbol = isSgInitializedName(symbolBasis); ROSE_ASSERT(initializedNameFromSymbol != NULL); // DQ (9/8/2014): This fails for test2013_234, 235, 240, 241, 242, 246.C. // ROSE_ASSERT(initializedNameFromSymbol->get_declptr() != NULL); // declarationAccessLevel = initializedNameFromSymbol->get_declptr()->get_declarationModifier().get_accessModifier().get_modifier(); if (initializedNameFromSymbol->get_declptr() != NULL) { declarationAccessLevel = initializedNameFromSymbol->get_declptr()->get_declarationModifier().get_accessModifier().get_modifier(); } else { mprintf ("WARNING: In injectSymbolsFromReferencedScopeIntoCurrentScope(): initializedNameFromSymbol->get_declptr() == NULL: initializedNameFromSymbol->get_name() = %s \n",initializedNameFromSymbol->get_name().str()); } } #if ALIAS_SYMBOL_DEBUGGING || 0 printf ("declarationAccessLevel = %d accessLevel = %d \n",declarationAccessLevel,accessLevel); #endif #if 0 // DQ (12/23/2015): Is this only supporting the SgBaseClass IR nodes? No, another example is the case of a SgUsingDirectiveStatement. ROSE_ASSERT(causalNode != NULL); if (isSgBaseClass(causalNode) == NULL) { printf ("ERROR: This is not a SgBaseClass: causalNode = %p = %s \n",causalNode,causalNode->class_name().c_str()); ROSE_ASSERT(false); } #endif // DQ (12/23/2015): See test2015_140.C for where even private base classes will require representations // of it's symbols in the derived class (to support correct name qualification). // if (declarationAccessLevel >= accessLevel) if ( (declarationAccessLevel >= accessLevel) || isSgBaseClass(causalNode) != NULL) { // This declaration is visible, so build an alias. // DQ (7/24/2011): Need to make sure that the symbol is not already present in the symbol table // (else injection would be redundant. This is a likely key to the problem we are having with // symbol table explosions for some codes. This should be refactored to a member function of // the symbol table support. // Note that this change improves the performance from 15 minutes to 5 seconds for the outlining example. bool alreadyExists = currentScope->symbol_exists(name); if (alreadyExists == true) { // Just because the names match is not strong enough. // SgSymbol* symbol currentScope->symbol_exists(name); switch (symbol->variantT()) { case V_SgAliasSymbol: { // not clear what to do here... // I think we need more symbol table support for detecting matching symbols. // I think we also need more alias symbol specific query support. break; } // DQ (11/10/2014): Added support for templated typedef symbols. case V_SgTemplateTypedefSymbol: case V_SgEnumSymbol: case V_SgVariableSymbol: case V_SgTemplateClassSymbol: case V_SgClassSymbol: case V_SgTemplateFunctionSymbol: case V_SgTemplateMemberFunctionSymbol: case V_SgFunctionSymbol: case V_SgMemberFunctionSymbol: case V_SgTypedefSymbol: case V_SgEnumFieldSymbol: case V_SgNamespaceSymbol: case V_SgTemplateSymbol: case V_SgLabelSymbol: { // Liao, 10/31/2012. // Using lookup_function_symbol () etc. is not good enough since it returns the first match only. // There might be multiple hits. We have to go through them all instead of checking only the first hit alreadyExists = false; // reset to be false // using less expensive equal_range(), which can be O(logN) instead of O(N) // This matters since this function is called inside another loop with complexity of O(N) already. rose_hash_multimap * internal_table = currentScope->get_symbol_table()->get_table(); ROSE_ASSERT (internal_table != NULL); std::pair<rose_hash_multimap::iterator, rose_hash_multimap::iterator> range = internal_table ->equal_range (name); for (rose_hash_multimap::iterator i = range.first; i != range.second; ++i) { SgSymbol * orig_current_symbol = i->second; ROSE_ASSERT (orig_current_symbol != NULL); // strip off alias symbols SgSymbol * non_alias_symbol = orig_current_symbol; while (isSgAliasSymbol(non_alias_symbol)) { non_alias_symbol = isSgAliasSymbol(non_alias_symbol) ->get_alias(); ROSE_ASSERT (non_alias_symbol != NULL); } SgNode* associatedDeclaration = i->second->get_symbol_basis(); assert(associatedDeclaration != NULL); // same basis and same symbol type // The assumption is that no two symbols can share the same basis declaration TODO double check this! if (associatedDeclaration == symbolBasis && (non_alias_symbol->variantT() == symbol->variantT())) { alreadyExists = true; break; } } // end for break; } #if 0 // uniform handling by code above now case V_SgEnumSymbol: { // alreadyExists = (currentScope->lookup_enum_symbol(name) != NULL); SgEnumSymbol* tmpSymbol = currentScope->lookup_enum_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } case V_SgVariableSymbol: { // alreadyExists = (currentScope->lookup_variable_symbol(name) != NULL); SgVariableSymbol* tmpSymbol = currentScope->lookup_variable_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } // DQ (2/12/2012): Not clear if this is the best way to add this support. case V_SgTemplateClassSymbol: case V_SgClassSymbol: { // alreadyExists = (currentScope->lookup_class_symbol(name) != NULL); SgClassSymbol* tmpSymbol = currentScope->lookup_class_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } #if 0 // DQ (2/12/2012): Added support for SgTemplateFunctionSymbol. case V_SgTemplateFunctionSymbol: { SgTemplateFunctionSymbol* tmpSymbol = currentScope->lookup_template_function_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } // DQ (2/12/2012): Added support for SgTemplateMemberFunctionSymbol. case V_SgTemplateMemberFunctionSymbol: { SgTemplateMemberFunctionSymbol* tmpSymbol = currentScope->lookup_template_member_function_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } #else // DQ (2/12/2012): Not clear if this is the best way to add this support. case V_SgTemplateFunctionSymbol: case V_SgTemplateMemberFunctionSymbol: #endif case V_SgFunctionSymbol: case V_SgMemberFunctionSymbol: { // alreadyExists = (currentScope->lookup_function_symbol(name) != NULL); SgFunctionSymbol* tmpSymbol = currentScope->lookup_function_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } case V_SgTypedefSymbol: { // alreadyExists = (currentScope->lookup_typedef_symbol(name) != NULL); SgTypedefSymbol* tmpSymbol = currentScope->lookup_typedef_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } case V_SgEnumFieldSymbol: { // alreadyExists = (currentScope->lookup_enum_field_symbol(name) != NULL); SgEnumFieldSymbol* tmpSymbol = currentScope->lookup_enum_field_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } case V_SgNamespaceSymbol: { // alreadyExists = (currentScope->lookup_namespace_symbol(name) != NULL); SgNamespaceSymbol* tmpSymbol = currentScope->lookup_namespace_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } case V_SgTemplateSymbol: { // alreadyExists = (currentScope->lookup_template_symbol(name) != NULL); SgTemplateSymbol* tmpSymbol = currentScope->lookup_template_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } case V_SgLabelSymbol: { // alreadyExists = (currentScope->lookup_label_symbol(name) != NULL); SgLabelSymbol* tmpSymbol = currentScope->lookup_label_symbol(name); if (tmpSymbol != NULL) { SgNode* tmpSymbolBasis = tmpSymbol->get_symbol_basis(); ROSE_ASSERT(tmpSymbolBasis != NULL); alreadyExists = (tmpSymbolBasis == symbolBasis); } break; } #endif default: printf ("Error: default reached in switch symbol = %p = %s \n",symbol,symbol->class_name().c_str()); ROSE_ASSERT(false); break; } } if ( alreadyExists == false) { #if 0 printf ("Building a SgAliasSymbol \n"); #endif // DQ: The parameter to a SgAliasSymbol is a SgSymbol (but should not be another SgAliasSymbol). SgAliasSymbol* aliasSymbol = new SgAliasSymbol(symbol); ROSE_ASSERT(aliasSymbol != NULL); // DQ (7/12/2014): Added support to trace back the SgAliasSymbol to the declarations that caused it to be added. ROSE_ASSERT(causalNode != NULL); aliasSymbol->get_causal_nodes().push_back(causalNode); #if ALIAS_SYMBOL_DEBUGGING // printf ("In injectSymbolsFromReferencedScopeIntoCurrentScope(): Adding symbol to new scope as a SgAliasSymbol = %p causalNode = %p = %s \n",aliasSymbol,causalNode,causalNode->class_name().c_str()); printf ("In injectSymbolsFromReferencedScopeIntoCurrentScope(): Adding symbol to new scope (currentScope = %p = %s) as a SgAliasSymbol = %p causalNode = %p = %s \n",currentScope,currentScope->class_name().c_str(),aliasSymbol,causalNode,causalNode->class_name().c_str()); #endif // Use the current name and the alias to the symbol currentScope->insert_symbol(name, aliasSymbol); #if ALIAS_SYMBOL_DEBUGGING printf ("In injectSymbolsFromReferencedScopeIntoCurrentScope(): DONE: Adding symbol to new scope (currentScope = %p = %s) as a SgAliasSymbol = %p causalNode = %p = %s \n",currentScope,currentScope->class_name().c_str(),aliasSymbol,causalNode,causalNode->class_name().c_str()); #endif } } else { #if ALIAS_SYMBOL_DEBUGGING printf ("NO SgAliasSymbol ADDED (wrong permissions): declarationFromSymbol = %p \n",declarationFromSymbol); #endif } #if 0 // Older version of code... // SgAliasSymbol* aliasSymbol = new SgAliasSymbol (SgSymbol *alias=NULL, bool isRenamed=false, SgName new_name="") SgAliasSymbol* aliasSymbol = new SgAliasSymbol (symbol); // Use the current name and the alias to the symbol currentScope->insert_symbol(name, aliasSymbol); #endif // Increment iterator and counter i++; counter++; } #if 0 // debugging symbolTable->print("In injectSymbolsFromReferencedScopeIntoCurrentScope(): printing out the symbol tables"); #endif #if ALIAS_SYMBOL_DEBUGGING printf ("In injectSymbolsFromReferencedScopeIntoCurrentScope(): referencedScope = %p = %s currentScope = %p = %s accessLevel = %d \n",referencedScope,referencedScope->class_name().c_str(),currentScope,currentScope->class_name().c_str(),accessLevel); #endif }