static bool isVoidStar(SgType* type) { SgPointerType *ptr = isSgPointerType(ignoreModifiers(type)); if (ptr == NULL) return false; return (isSgTypeVoid(ignoreModifiers(ptr->get_base_type())) != NULL); }
::KLT::Data<Annotation<Language> > * convertData(typename Language::data_clause_t * data_clause, const DLX::Frontend::data_sections_t & data_section) { typedef Annotation<Language> Annotation; typedef ::KLT::Data<Annotation> Data; SgVariableSymbol * data_sym = data_section.first; SgType * base_type = data_sym->get_type(); std::vector<DLX::Frontend::section_t>::const_iterator it_section; for (it_section = data_section.second.begin(); it_section != data_section.second.end(); it_section++) { if (isSgPointerType(base_type)) base_type = ((SgPointerType *)base_type)->get_base_type(); else if (isSgArrayType (base_type)) base_type = ((SgArrayType *)base_type)->get_base_type(); else assert(false); assert(base_type != NULL); } Data * data = new Data(data_sym, base_type); for (it_section = data_section.second.begin(); it_section != data_section.second.end(); it_section++) { typename Data::section_t section; section.offset = it_section->lower_bound; section.length = it_section->size; // section.stride = it_section->stride; assert(it_section->stride == NULL); data->addSection(section); } data->annotations.push_back(Annotation(data_clause)); return data; }
SgType* findBaseType(SgType* sageType){ ROSE_ASSERT( sageType != NULL); SgType* baseType = sageType; switch(sageType->variantT()) { case V_SgReferenceType: { baseType = isSgReferenceType(sageType)->get_base_type(); break; } case V_SgPointerType: { baseType = isSgPointerType(sageType)->get_base_type(); break; } case V_SgTypedefType: { while(isSgTypedefType(baseType) != NULL) baseType = isSgTypedefType(baseType)->get_base_type(); break; } default: break; }; ROSE_ASSERT ( baseType != NULL ); return baseType; };
//! Returns 'true' if the given type is 'const'. static bool isReadOnlyType (const SgType* type) { ROSE_ASSERT (type); const SgModifierType* mod = 0; switch (type->variantT ()) { case V_SgModifierType: mod = isSgModifierType (type); break; case V_SgReferenceType: mod = isSgModifierType (isSgReferenceType (type)->get_base_type ()); break; case V_SgPointerType: mod = isSgModifierType (isSgPointerType (type)->get_base_type ()); break; default: mod = 0; break; } return mod && mod->get_typeModifier ().get_constVolatileModifier ().isConst (); }
// very trivial transfer function // NOTE: requires extension for a full blown analysis void PointsToAnalysisTransfer::visit(SgAssignOp* sgn) { SgExpression* rhs_operand = sgn->get_rhs_operand(); SgExpression* lhs_operand = sgn->get_lhs_operand(); // handle p = &x // NOTE: rhs can be a complex expression but code below only handles the trivial case if(isSgAddressOfOp(rhs_operand)) { // operand of SgAddressOfOp should be a variable SgVarRefExp* sgvexp = isSgVarRefExp(isSgAddressOfOp(rhs_operand)->get_operand()); assert(sgvexp); MemLocObjectPtr _ml = composer->OperandExpr2MemLoc(rhs_operand, sgvexp, part->inEdgeFromAny(), analysis); assert(_ml); // get the lattice for lhs_operand // insert memory object for rhs_operand into this lattice AbstractObjectSetPtr aos = getLatticeOperand(sgn, lhs_operand); aos->insert(_ml); // update the product lattice setLatticeOperand(sgn, lhs_operand, aos); setLattice(sgn, aos); modified = true; } //TODO: handle p = q else if(isSgPointerType(lhs_operand->get_type()) && isSgPointerType(rhs_operand->get_type())) { AbstractObjectSetPtr l_aos = getLatticeOperand(sgn, lhs_operand); AbstractObjectSetPtr r_aos = getLatticeOperand(sgn, rhs_operand); // union the information // NOTE: points to information can be NULL // merge pointsToSet from rhs if available if(l_aos && r_aos) l_aos->meetUpdate(dynamic_cast<Lattice*>(r_aos.get())); // pointsToSet is empty for lhs, populate it with rhs information if(!l_aos && r_aos) l_aos = boost::make_shared<AbstractObjectSet>(*r_aos); // set the map with this pointsToSet setLatticeOperand(sgn, lhs_operand, l_aos); setLattice(sgn, l_aos); modified = true; } }
void Expr2MemLocTraversal::visit(SgVarRefExp* sgn) { scope regvis("Expr2MemLocTraversal::visit(SgVarRefExp* sgn)", scope::medium, ptaDebugLevel, 1); dbg << "isSgPointerType(sgn->get_type())="<<isSgPointerType(sgn->get_type())<<endl; // return points to set only for pointer types /*if(isSgPointerType(sgn->get_type())) { MemLocObjectPtr ml = composer->Expr2MemLoc(sgn, pedge, analysis); p_aos = boost::dynamic_pointer_cast<AbstractObjectSet>(aom->get(ml)); }*/ p_aos = boost::make_shared<AbstractObjectSet>(pedge, composer, analysis, AbstractObjectSet::may); p_aos->insert(composer->Expr2MemLoc(sgn, pedge, analysis)); if(ptaDebugLevel>=1) dbg << "p_aos="<<p_aos->str()<<endl; }
void RtedTransformation::transformPtrDerefs(PtrDerefContainer::value_type data) { const SgSourceFile& srcfile = *data.first; SgPointerDerefExp* deref = data.second; // lookup generated function SgExpression& operand = extractOperand(*deref); SgPointerType* ptrtype = isSgPointerType(operand.get_type()); ROSE_ASSERT(ptrtype); /* SgSymbol& sym = lookup_safeRead(srcfile, *ptrtype); SgExprListExp& args = *SB::buildExprListExp(); SgFunctionCallExp& call = *SB::buildFunctionCallExp(&sym, &args); SI::replaceExpression(deref, call, delete_old_tree); SI::appendExpression(args, operand); */ }
void UnparseFortran_type::unparseReferenceType(SgType* type, SgUnparse_Info& info) { SgReferenceType* ref_type = isSgReferenceType(type); ROSE_ASSERT(ref_type != NULL); /* special cases: ptr to array, int (*p) [10] */ /* ptr to function, int (*p)(int) */ /* ptr to ptr to .. int (**p) (int) */ SgUnparse_Info ninfo(info); if (isSgReferenceType(ref_type->get_base_type()) || isSgPointerType(ref_type->get_base_type()) || isSgArrayType(ref_type->get_base_type()) || isSgFunctionType(ref_type->get_base_type()) || isSgMemberFunctionType(ref_type->get_base_type()) || isSgModifierType(ref_type->get_base_type()) ) { ninfo.set_isReferenceToSomething(); } if (ninfo.isTypeFirstPart()) { unparseType(ref_type->get_base_type(), ninfo); // curprint("& /* reference */ "); curprint("&"); } else { if (ninfo.isTypeSecondPart()) { unparseType(ref_type->get_base_type(), ninfo); } else { SgUnparse_Info ninfo2(ninfo); ninfo2.set_isTypeFirstPart(); unparseType(ref_type, ninfo2); ninfo2.set_isTypeSecondPart(); unparseType(ref_type, ninfo2); } } }
/* * Constructor for registering an expression. */ RegisterPointers::RegisterPointers(SgExpression* p_expression) : expression(p_expression), varName(NULL), varSymbol(NULL), isGlobal(false), definedInSystemHeader(false), compilerGenerated(false), addrUsedInIO(false) { //TODO maybe need to do a while loop until we get a var ref? ROSE_ASSERT(isSgPointerType(expression->get_type())); SgAddressOfOp* addrOf = isSgAddressOfOp(expression); if(addrOf) { //Check to make sure we don't register vars the compiler added SgVarRefExp* varRef = isSgVarRefExp(addrOf->get_operand()); if(varRef) { varSymbol = varRef->get_symbol(); compilerGenerated = isCompilerGenerated(varSymbol); addrUsedInIO = isAddrTakenInIrrelevantFunc(varRef); } } }
std::string initializeVariable(SgInitializedName* initName) { //if array type we need to get the index expression std::string index_expression_string; std::stringstream nameStringStream; SgName initNameName = initName->get_qualified_name(); SgSymbol* initNameSym = initName->search_for_symbol_from_symbol_table(); if (variablesOfNameX.find(initNameName.getString()) == variablesOfNameX.end()) { nameStringStream << initNameName.getString() << "_0"; variablesOfNameX[initNameName.getString()] = 1; } else { int occurrence = variablesOfNameX[initNameName.getString()]; nameStringStream << initNameName.getString() << "_" << occurrence; variablesOfNameX[initNameName.getString()] = occurrence+1; } SymbolToZ3[initNameSym] = nameStringStream.str(); SymbolToInstances[initNameSym] = 0; SgType* initNameType = initName->get_type(); std::string typeZ3; if (initNameType->isIntegerType()) { typeZ3 = "Int"; } else if (initNameType->isFloatType()) { typeZ3 = "Real"; } else if (isSgArrayType(initNameType)) { SgArrayType* arrTyp = isSgArrayType(initNameType); ROSE_ASSERT(arrTyp != NULL); SgType* underlying_type = arrTyp->get_base_type(); std::string array_typeZ3; if (underlying_type->isIntegerType()) { array_typeZ3 = "Int"; } else if (underlying_type->isFloatType()) { array_typeZ3 = "Real"; } else { std::cout << "unknown underlying type of array!" << std::endl; std::cout << underlying_type->class_name() << std::endl; ROSE_ASSERT(false); } SgExpression* ind = arrTyp->get_index(); std::stringstream arrStr; index_expression_string = getSgExpressionString(ind); typeZ3 = "(Array Int " + array_typeZ3 + ")"; } else if (isSgClassType(initNameType)) { std::cout << "structs are not yet implemented" << std::endl; ROSE_ASSERT(false); } else if (isSgPointerType(initNameType)) { std::cout << "pointers are not yet implemented" << std::endl; ROSE_ASSERT(false); } else if (isSgEnumType(initNameType)) { SgEnumType* et = isSgEnumType(initNameType); SgEnumDeclaration* enum_d = isSgEnumDeclaration(et->getAssociatedDeclaration()); getSgDeclarationStatement(enum_d); typeZ3 = et->get_name().getString(); } else { std::cout << "unknown type: " << initNameType->class_name() << std::endl; ROSE_ASSERT(false); } std::string name = nameStringStream.str() + "_0"; std::stringstream streamZ3; if (isSgArrayType(initNameType)) { streamZ3 << "(declare-const " << name << " " << typeZ3 << ")"; streamZ3 << "\n(declare-fun " << name << "_len () Int)"; streamZ3 << "\n(assert (= " << name << "_len " << index_expression_string << "))"; #ifdef ARRAY_TEST std::cout << "arrStream: " << streamZ3.str() << std::endl; #endif } else if (isSgEnumType(initNameType)) { streamZ3 << "(declare-const " << name << " " << typeZ3 << ")"; } else { streamZ3 << "(declare-fun " << name << " () " << typeZ3 << ")"; } return streamZ3.str(); }
void UnparseFortran_type::unparsePointerType(SgType* type, SgUnparse_Info& info, bool printAttrs) { #if 0 // printf ("Inside of UnparserFort::unparsePointerType \n"); // cur << "\n/* Inside of UnparserFort::unparsePointerType */\n"; curprint ("\n! Inside of UnparserFort::unparsePointerType \n"); #endif // DQ (1/16/2011): Note that pointers in fortran are not expressed the same as in C/C++, are are // only a part of the type which is managed more directly using attributes in the variable declaration. // Not clear that we want to do anything here in the unparser... SgPointerType* pointer_type = isSgPointerType(type); ROSE_ASSERT(pointer_type != NULL); #if 0 /* special cases: ptr to array, int (*p) [10] */ /* ptr to function, int (*p)(int) */ /* ptr to ptr to .. int (**p) (int) */ if (isSgReferenceType(pointer_type->get_base_type()) || isSgPointerType(pointer_type->get_base_type()) || isSgArrayType(pointer_type->get_base_type()) || isSgFunctionType(pointer_type->get_base_type()) || isSgMemberFunctionType(pointer_type->get_base_type()) || isSgModifierType(pointer_type->get_base_type()) ) { info.set_isPointerToSomething(); } // If not isTypeFirstPart nor isTypeSecondPart this unparse call // is not controlled from the statement level but from the type level if (info.isTypeFirstPart() == true) { unparseType(pointer_type->get_base_type(), info); // DQ (9/21/2004): Moved this conditional into this branch (to fix test2004_93.C) // DQ (9/21/2004): I think we can assert this, and if so we can simplify the logic below ROSE_ASSERT(info.isTypeSecondPart() == false); curprint("*"); } else { if (info.isTypeSecondPart() == true) { unparseType(pointer_type->get_base_type(), info); } else { SgUnparse_Info ninfo(info); ninfo.set_isTypeFirstPart(); unparseType(pointer_type, ninfo); ninfo.set_isTypeSecondPart(); unparseType(pointer_type, ninfo); } } #else if (info.supressStrippedTypeName() == false) { // DQ (1/16/2011): We only want to output the name of the stripped type once! SgType* stripType = pointer_type->stripType(); unparseType(stripType, info); info.set_supressStrippedTypeName(); } curprint(type->get_isCoArray()? ", COPOINTER": ", POINTER"); // DQ (1/16/2011): Plus unparse the base type...(unless it will just output the stripped types name). if (pointer_type->get_base_type()->containsInternalTypes() == true) { unparseType(pointer_type->get_base_type(), info, printAttrs); } #endif #if 0 // printf ("Leaving of UnparserFort::unparsePointerType \n"); // cur << "\n/* Leaving of UnparserFort::unparsePointerType */\n"; curprint ("\n! Leaving UnparserFort::unparsePointerType \n"); #endif }
void TypeTransformation::visit ( SgNode* astNode ) { SgVariableDeclaration* variableDeclaration = isSgVariableDeclaration(astNode); if (variableDeclaration != NULL) { #if 0 // One way to know where you are when your doing a transformation (debugging). printf ("Found a variable decaration: \n"); variableDeclaration->get_file_info()->display("Found a variable decaration"); #endif SgInitializedNamePtrList & varList = variableDeclaration->get_variables(); SgInitializedNamePtrList::iterator i = varList.begin(); bool transformed = false; // Iterate over the SgInitializedName objects. while (i != varList.end()) { SgPointerType* pointerType = isSgPointerType((*i)->get_type()); if (pointerType != NULL) { // Types are shared, so don't modify the types directly, but point to a new type. (*i)->set_type(SageBuilder::buildRestrictType((*i)->get_type())); #if 1 printf ("In TypeTransformation::visit(): Calling setTransformation on SgInitializedName: i = %p = %s \n",*i,(*i)->get_name().str()); #endif // DQ (4/14/2015): Explicitly set this as containing a transformation (we might want // to alternatively fixup the token-based unparsing frontier tests to triggered based // on the setting of the isModified flag in each IR node. // (*i)->set_containsTransformation(true); // (*i)->setTransformation(); transformed = true; } i++; } if (transformed == true) { #if 0 // DQ (4/16/2015): That this can be commented out means that we have general support in place to // interpret transformations from status of the isModified flags that are set by all of the // set_* access functions. This interpretation of the isModified flag status to explicitly // mark transformations is handled in the function: // SimpleFrontierDetectionForTokenStreamMapping::evaluateInheritedAttribute() // in file: simpleFrontierDetection.C // DQ (4/14/2015): Mark the SgVariableDeclaration as being a transformation. variableDeclaration->setTransformation(); // Also set to be output in the generated code. variableDeclaration->setOutputInCodeGeneration(); // By definition: for this to be a transformation it cannot also contain a transforamtion. ROSE_ASSERT(variableDeclaration->get_containsTransformation() == false); ROSE_ASSERT(variableDeclaration->isTransformation() == true); #endif } } }
void ModelBuilder::add(Model::model_t & model, SgType * sg_type) { SgModifierType * modifier_type = isSgModifierType(sg_type); if (modifier_type != NULL) { add(model, modifier_type->get_base_type()); return; } Model::type_t element = Model::build<Model::e_model_type>(); element->node->type = sg_type; SgNamedType * named_type = isSgNamedType(sg_type); SgArrayType * array_type = isSgArrayType(sg_type); SgPointerType * pointer_type = isSgPointerType(sg_type); SgReferenceType * reference_type = isSgReferenceType(sg_type); if (named_type != NULL) { SgClassType * class_type = isSgClassType(named_type); SgEnumType * enum_type = isSgEnumType(named_type); SgTypedefType * typedef_type = isSgTypedefType(named_type); SgDeclarationStatement * decl_stmt = named_type->get_declaration()->get_firstNondefiningDeclaration(); assert(decl_stmt != NULL); SgSymbol * decl_sym = decl_stmt->get_symbol_from_symbol_table(); assert(decl_sym != NULL); if (class_type != NULL) { element->node->kind = Model::node_t<Model::e_model_type>::e_class_type; SgClassSymbol * class_sym = isSgClassSymbol(decl_sym); assert(class_sym != NULL); element->node->base_class = model.lookup_class(class_sym); if (element->node->base_class == NULL) { add(model, class_sym); element->node->base_class = model.lookup_class(class_sym); } assert(element->node->base_class != NULL); } else if (enum_type != NULL) { element->node->kind = Model::node_t<Model::e_model_type>::e_enum_type; SgEnumSymbol * enum_sym = isSgEnumSymbol(decl_sym); assert(enum_sym != NULL); element->node->enum_symbol = enum_sym; } else if (typedef_type != NULL) { element->node->kind = Model::node_t<Model::e_model_type>::e_typedef_type; SgTypedefSymbol * typedef_sym = isSgTypedefSymbol(decl_sym); assert(typedef_sym != NULL); element->node->typedef_symbol = typedef_sym; element->node->base_type = model.lookup_type(typedef_type->get_base_type()); if (element->node->base_type == NULL) { add(model, typedef_type->get_base_type()); element->node->base_type = model.lookup_type(typedef_type->get_base_type()); } assert(element->node->base_type != NULL); } else assert(false); } else if (array_type != NULL) { element->node->kind = Model::node_t<Model::e_model_type>::e_array_type; element->node->base_type = model.lookup_type(array_type->get_base_type()); if (element->node->base_type == NULL) { add(model, array_type->get_base_type()); element->node->base_type = model.lookup_type(array_type->get_base_type()); } assert(element->node->base_type != NULL); } else if (pointer_type != NULL) { element->node->kind = Model::node_t<Model::e_model_type>::e_pointer_type; element->node->base_type = model.lookup_type(pointer_type->get_base_type()); if (element->node->base_type == NULL) { add(model, pointer_type->get_base_type()); element->node->base_type = model.lookup_type(pointer_type->get_base_type()); } assert(element->node->base_type != NULL); } else if (reference_type != NULL) { element->node->kind = Model::node_t<Model::e_model_type>::e_reference_type; element->node->base_type = model.lookup_type(reference_type->get_base_type()); if (element->node->base_type == NULL) { add(model, reference_type->get_base_type()); element->node->base_type = model.lookup_type(reference_type->get_base_type()); } assert(element->node->base_type != NULL); } else { element->node->kind = Model::node_t<Model::e_model_type>::e_native_type; } element->scope->parent.a_namespace = NULL; /// \todo model.types.push_back(element); }
/* * Add calls to register and unregister expressions/arrays with the memory * management wrapper. */ bool RegisterPointers::addRegUnregCalls() { string msg; if(definedInSystemHeader) { msg = "\t\t\tVariable " + NAME(varSymbol) + " is in system headers"; WARNING(TOOL, msg); return false; } if(compilerGenerated) { msg = "\t\t\tVariable " + NAME(varSymbol) + " is compiler-generated"; WARNING(TOOL, msg); return false; } if(addrUsedInIO) { msg = "\t\t\tVariable " + NAME(varSymbol) + " has its address taken in " + "a function known to not require registering/unregistering"; WARNING(TOOL, msg); return false; } //Add register/unregister calls SgStatement* prevStmt = NULL; SgExprStatement* funcCall = NULL; SgType* type = NULL; SgExpression* expr = NULL; if(isGlobal) { type = varName->get_type(); SgName name = varName->get_name(); int numVals = 1; if(isSgPointerType(type)) return false; //If its a pointer, it points to a static array, dynamic array, or scalar //which has its address taken (all of which have already been registered) SgFunctionDeclaration* main = findMain(getScope(varName)); ROSE_ASSERT(main); expr = buildVarRefExp(name, varName->get_scope()); if(isSgArrayType(type)) numVals = getArrayElementCount(isSgArrayType(type)); else expr = buildAddressOfOp(expr); funcCall = MMCallBuilder::buildRegisterPointerCall(expr, buildUnsignedIntVal(numVals), main->get_definition()); insertStatement(getFirstStatement(main->get_definition()), funcCall);//, false, true); funcCall = MMCallBuilder::buildUnregisterPointerCall(expr, main->get_definition()); instrumentEndOfFunction(main, funcCall); } else if(expression) //Address-of expressions { prevStmt = getEnclosingStatement(expression); funcCall = MMCallBuilder::buildRegisterPointerCall(expression, buildUnsignedIntVal(1), getScope(expression)); insertStatement(prevStmt, funcCall); funcCall = MMCallBuilder::buildUnregisterPointerCall(expression, getScope(expression)); instrumentEndOfFunction(getEnclosingFunctionDeclaration(prevStmt), funcCall); } else //Array types { SgVarRefExp* varRef = buildVarRefExp(varName, getScope(varName)); int numVals = getArrayElementCount(isSgArrayType(varName->get_type())); funcCall = MMCallBuilder::buildRegisterPointerCall(varRef, buildUnsignedIntVal(numVals), varName->get_scope()); insertStatement(varName->get_declaration(), funcCall, false, true); varRef = buildVarRefExp(varName, getScope(varName)); funcCall = MMCallBuilder::buildUnregisterPointerCall(varRef, varName->get_scope()); instrumentEndOfFunction(getEnclosingFunctionDeclaration(varName), funcCall); } return true; }
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); } } }
void TypeTraversal::transformType(SgType* type) { // Since only the base_types of pointers are shared, we can take as input the pointer type and just change it internally. // The reference to the type from non-type IR nodes need not be modified. ROSE_ASSERT(type != NULL); #if DEBUG_TYPE_TRAVERSAL printf ("Inside of TypeTraversal::transformType(): type = %p = %s \n",type,type->class_name().c_str()); #endif // How complex can be expect the type system to be (do we required a nested type traversal). SgPointerType* pointerType = isSgPointerType(type); if (pointerType != NULL) { // Check if the base type is marked as shared. SgModifierType* mod_type = isSgModifierType(pointerType->get_base_type()); if (mod_type != NULL) { #if DEBUG_TYPE_TRAVERSAL printf ("(mod_type != NULL): mod_type->get_typeModifier().displayString() = %s \n",mod_type->get_typeModifier().displayString().c_str()); #endif if (mod_type->get_typeModifier().get_upcModifier().get_isShared() == true) { #if DEBUG_TYPE_TRAVERSAL printf ("TypeTraversal::transformType(): (mod_type != NULL): Detected a shared type! (transform the type) \n"); #endif // Reset the base_type on the pointer to point to the base_type of the modifier. // Note that a less elegant solution would be to call: mod_type->get_typeModifier().get_upcModifier().set_isShared(false). SgType* modifier_base_type = mod_type->get_base_type(); ROSE_ASSERT(modifier_base_type != NULL); #if DEBUG_TYPE_TRAVERSAL printf ("TypeTraversal::transformType(): (mod_type != NULL): Removing shared base_type from pointerType = %p replacing with modifier_base_type = %p = %s \n",pointerType,modifier_base_type,modifier_base_type->class_name().c_str()); #endif pointerType->set_base_type(modifier_base_type); #if 1 // DQ (4/26/2014): Also mark this as not shared, since the cast expressions will refer directly to this SgModifierType type. mod_type->get_typeModifier().get_upcModifier().set_isShared(false); #else #error "DEAD CODE!" printf ("In TypeTraversal::transformType(): (mod_type != NULL): Skipping reset of upc modifier in SgModifierType: mod_type = %p \n",mod_type); #endif } else { // DQ (5/16/2014): in the case of test2014_20.c the function parameter has a type with a short // chain of SgModifierType IR nodes. In this case only the last one is marked as shared. // There might be a more general AST post processing step for this, or it might be that we // need to build the attributes better to avoid such chains of SgModifierType IR nodes. SgModifierType* nested_mod_type = isSgModifierType(mod_type->get_base_type()); if (nested_mod_type != NULL) { #if DEBUG_TYPE_TRAVERSAL printf ("(mod_type != NULL): (nested_mod_type != NULL): nested_mod_type->get_typeModifier().displayString() = %s \n",nested_mod_type->get_typeModifier().displayString().c_str()); #endif if (nested_mod_type->get_typeModifier().get_upcModifier().get_isShared() == true) { #if DEBUG_TYPE_TRAVERSAL printf ("TypeTraversal::transformType(): (mod_type != NULL): (nested_mod_type != NULL): Detected a nested shared type! (transform the type) \n"); #endif // Reset the base_type on the pointer to point to the base_type of the modifier. // Note that a less elegant solution would be to call: mod_type->get_typeModifier().get_upcModifier().set_isShared(false). SgType* nested_modifier_base_type = nested_mod_type->get_base_type(); ROSE_ASSERT(nested_modifier_base_type != NULL); #if 0 printf ("TypeTraversal::transformType(): (mod_type != NULL): (nested_mod_type != NULL): Removing shared base_type from pointerType = %p replacing with modifier_base_type = %p = %s \n",pointerType,modifier_base_type,modifier_base_type->class_name().c_str()); #endif mod_type->set_base_type(nested_modifier_base_type); #if 1 // DQ (4/26/2014): Also mark this as not shared, since the cast expressions will refer directly to this SgModifierType type. nested_mod_type->get_typeModifier().get_upcModifier().set_isShared(false); #else #error "DEAD CODE!" printf ("In TypeTraversal::transformType(): (mod_type != NULL): (nested_mod_type != NULL): Skipping reset of upc modifier in SgModifierType: mod_type = %p \n",mod_type); #endif } } } } } else { SgModifierType* mod_type = isSgModifierType(type); if (mod_type != NULL) { #if DEBUG_TYPE_TRAVERSAL printf ("Found a modifier type (not from a pointer type) \n"); #endif #if DEBUG_TYPE_TRAVERSAL printf ("(Found a modifier type (not from a pointer type): mod_type->get_typeModifier().displayString() = %s \n",mod_type->get_typeModifier().displayString().c_str()); #endif SgType* base_type = mod_type->get_base_type(); #if DEBUG_TYPE_TRAVERSAL printf ("Found a modifier type (not from a pointer type): base_type = %p = %s \n",base_type,base_type->class_name().c_str()); #endif // DQ (5/31/2014): Reset the type to eliminate the shared keyword. mod_type->get_typeModifier().get_upcModifier().set_isShared(false); } } }
/** * Const-qualify immutable objects * * \todo count assignments, if only one, report violation */ bool DCL00_C( const SgNode *node ) { const SgInitializedName *varName = isSgInitializedName(node); if (!varName) return false; /** * Ignore variables generated by macros */ if ((varName->get_name().getString().substr(0,2) == "__") || isCompilerGeneratedNode(node)) return false; /** * Ignore global variables */ if (isGlobalVar(varName)) return false; /** * Ignore variables that are already const, are function pointers, or are * declared inside of a struct, enum, or as an argument to a function */ SgType *varType = varName->get_type(); if (isConstType(varType) || isConstType(varType->dereference()) || isConstType(varType->dereference()->dereference()) || isSgFunctionType(varType) || isSgClassType(varType) || findParentOfType(varName, SgCtorInitializerList) || findParentOfType(varName, SgEnumDeclaration) || findParentOfType(varName, SgClassDeclaration)) return false; /** * DCL13-C is a subset of this rule, figure out which rule we are dealing * with here */ std::string ruleStr; std::string errStr; if (findParentOfType(varName, SgFunctionParameterList)) { /** ignore function prototypes, just worry about the definitions */ const SgFunctionDeclaration *fnDecl = findParentOfType(varName, SgFunctionDeclaration); /** * Disabling assertion due to C++ code */ if (!fnDecl) return false; // assert(fnDecl); if (!fnDecl->get_definition()) return false; if (isSgPointerType(varName->get_type()) || isSgArrayType(varName->get_type())) { ruleStr = "DCL13-C"; errStr = "Declare function parameters that are pointers to values not changed by the function as const: "; } else { return false; } } else { ruleStr = "DCL00-C"; errStr = "Const-qualify immutable objects: "; } /** * Ignore global variables or variables declared as extern */ const SgScopeStatement *varScope = varName->get_scope(); if (isSgGlobal(varScope) || isExternVar(varName)) return false; FOREACH_SUBNODE(varScope, nodes, i, V_SgVarRefExp) { const SgVarRefExp *iVar = isSgVarRefExp(*i); assert(iVar); if (getRefDecl(iVar) != varName) continue; const SgNode *parent = iVar->get_parent(); while(isSgCastExp(parent)) { parent = parent->get_parent(); } assert(parent); /** * If the variable is written to or it's address is taken, we can no * longer be sure it should be const, if it's a struct and gets * dereferenced, who knows what's getting written there :/ */ if (varWrittenTo(iVar) || isSgArrowExp(parent) || findParentOfType(iVar, SgAddressOfOp)) return false; /** * If the variable is a pointer or array, and we pass it to a function * or as an argument to pointer arithmetic, or assign it's value * somewhere, we can longer be sure it should be const */ if ((isSgPointerType(varType) || isSgArrayType(varType)) && (findParentOfType(iVar, SgFunctionCallExp) || isSgAddOp(parent) || isSgSubtractOp(parent) || isSgAssignOp(parent) || isSgPntrArrRefExp(parent) || isSgPointerDerefExp(parent) || isSgAssignInitializer(parent))) return false; } const std::string msg = errStr + varName->get_name().getString(); print_error(node, ruleStr.c_str(), msg.c_str(), true); return true; }
bool Type::isPointer() const { return (isSgPointerType(t_) != 0) && !isMemberPointer(); //XXX ROSE identifies ptr to member as ptr! }
/*! * \brief Creates a new outlined-function parameter for a given * variable. The requirement is to preserve data read/write semantics. * * For C/C++: we use pointer dereferencing to implement pass-by-reference * In a recent implementation, side effect analysis is used to find out * variables which are not modified so pointer types are not used. * * * Given a variable (i.e., its type and name) whose references are to * be outlined, create a suitable outlined-function parameter. * For C/C++, the parameter is created as a pointer, to support parameter passing of * aggregate types in C programs. * Moreover, the type is made 'void' if the base type is not a primitive type. * * An original type may need adjustments before we can make a pointer type from it. * For example: * a)Array types from a function parameter: its first dimension is auto converted to a pointer type * * b) Pointer to a C++ reference type is illegal, we create a pointer to its * base type in this case. It also match the semantics for addressof(refType) * * * The implementation follows two steps: * step 1: adjust a variable's base type * step 2: decide on its function parameter type * Liao, 8/14/2009 */ static OutlinedFuncParam_t createParam (const SgInitializedName* i_name, bool readOnly=false) { ROSE_ASSERT (i_name); SgType* init_type = i_name->get_type(); ROSE_ASSERT (init_type); // Stores the real parameter type to be used in new_param_type string init_name = i_name->get_name ().str (); SgType* param_base_type; //has to be not scalar if(isSgArrayType (init_type) ){ SgType* base_type = init_type->findBaseType(); param_base_type = buildPointerType(base_type); } else if (isSgPointerType (init_type)) { //Didem, this used to be 2 but I changed into 0. Didn't make any sense init_name = init_name.substr(0); //Didem: I have changed the types into 1D pointer type SgType* base_type = init_type->findBaseType(); param_base_type = buildPointerType(base_type); //param_base_type = init_type; } else{ param_base_type = init_type; } // The parameter name reflects the type: the same name means the same type, // p__ means a pointer type string new_param_name = init_name; SgType* new_param_type = NULL; // For classic behavior, read only variables are passed by values for C/C++ // They share the same name and type if (Outliner::enable_classic) { // read only parameter: pass-by-value, the same type and name // shared parameters : already pointer type //if (readOnly) { new_param_type = param_base_type; } /* else { new_param_name= "d__" + new_param_name; new_param_type = SgPointerType::createType (param_base_type); }*/ } else // very conservative one, assume the worst side effects (all are written) { new_param_name= new_param_name; } // So use base type directly // C/C++ parameters will use their new param type to implement pass-by-reference return OutlinedFuncParam_t (new_param_name, new_param_type); }