void ModelBuilder::add(Model::model_t & model, SgMemberFunctionSymbol * member_function_symbol) { Model::method_t element = Model::build<Model::e_model_method>(); element->node->symbol = member_function_symbol; SgFunctionType * func_type = isSgFunctionType(member_function_symbol->get_type()); assert(func_type != NULL); SgType * func_return_type = func_type->get_return_type(); assert(func_return_type != NULL); element->node->return_type = model.lookup_type(func_return_type); if (element->node->return_type == NULL) { add(model, func_return_type); element->node->return_type = model.lookup_type(func_return_type); } assert(element->node->return_type != NULL); SgFunctionParameterTypeList * param_type_list = func_type->get_argument_list(); assert(param_type_list != NULL); const std::vector<SgType *> & arguments = param_type_list->get_arguments(); std::vector<SgType *>::const_iterator it_argument; for (it_argument = arguments.begin(); it_argument != arguments.end(); it_argument++) { Model::type_t type = model.lookup_type(*it_argument); if (type == NULL) { add(model, *it_argument); type = model.lookup_type(*it_argument); } assert(type != NULL); element->node->args_types.push_back(type); } setParentFromScope<Model::e_model_method>(model, element, member_function_symbol); model.methods.push_back(element); }
void FixUpGlobalFunctionTypeTable::visit(SgNode* node) { // This function will be used to visit every node in the SgFunctionType memory pool and the SgMemberFunctionType // memory pool and insert any symbols that are missing after the initial construction of the AST. // Note that the reason why we save the construction of this table to a post-processing step is that // we have to first have the final function names and scope names as required to build the final mangled names. // Since many function will have the same function type and function types are shared, the symbols for // any given function type could have already been placed into the function type symbol tabel and // we have to test each function type, which forces a call to get the mangled name for each function type. // We could improve the performance by optimizing the computation of mangled names. // We could also improve the performance by optimizing the globalFunctionTypeSymbolTable->lookup_function_type(). #if 0 // compute some statistical data about redundant function types static int numberOfFunctionTypesProcessed = 0; static int numberOfRedudantFunctionTypesProcessed = 0; numberOfFunctionTypesProcessed++; #endif // DQ (1/26/2007): Added fixup to place function types into the global function type symbol table. SgFunctionType* functionType = isSgFunctionType(node); ROSE_ASSERT(functionType != NULL); SgFunctionTypeTable* globalFunctionTypeSymbolTable = SgNode::get_globalFunctionTypeTable(); ROSE_ASSERT(globalFunctionTypeSymbolTable != NULL); // printf ("Processing SgFunctionType = %p = %s \n",functionType,functionType->get_mangled().str()); // DQ (3/10/2007): The computation of the mangled name data is only 0.254 sec of the total time of 6.765 sec for an example file (test2001_11.C) const SgName mangleTypeName = functionType->get_mangled(); // DQ (3/10/2007): This symbol table test (together with the insertion of the symbol) is expensive (26/27ths of the cost) if (globalFunctionTypeSymbolTable->lookup_function_type(mangleTypeName) == NULL) { // printf ("Function type not in table, ADDING it: SgFunctionType = %p = %s \n",functionType,functionType->get_mangled().str()); globalFunctionTypeSymbolTable->insert_function_type(mangleTypeName,functionType); } else { // printf ("Function type already in the table, SKIP adding it, this is a redundantly generated function type: SgFunctionType = %p = %s \n",functionType,functionType->get_mangled().str()); #if 0 numberOfRedudantFunctionTypesProcessed++; printf ("Function type already in the table: numberOfFunctionTypesProcessed = %ld numberOfRedudantFunctionTypesProcessed = %ld \n",numberOfFunctionTypesProcessed,numberOfRedudantFunctionTypesProcessed); #endif } }
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); } } }
SgSymbol * ClangToSageTranslator::GetSymbolFromSymbolTable(clang::NamedDecl * decl) { if (decl == NULL) return NULL; SgScopeStatement * scope = SageBuilder::topScopeStack(); SgName name(decl->getNameAsString()); #if DEBUG_SYMBOL_TABLE_LOOKUP std::cerr << "Lookup symbol for: " << name << std::endl; #endif if (name == "") { return NULL; } std::list<SgScopeStatement *>::reverse_iterator it; SgSymbol * sym = NULL; switch (decl->getKind()) { case clang::Decl::Typedef: { it = SageBuilder::ScopeStack.rbegin(); while (it != SageBuilder::ScopeStack.rend() && sym == NULL) { sym = (*it)->lookup_typedef_symbol(name); it++; } break; } case clang::Decl::Var: case clang::Decl::ParmVar: { it = SageBuilder::ScopeStack.rbegin(); while (it != SageBuilder::ScopeStack.rend() && sym == NULL) { sym = (*it)->lookup_variable_symbol(name); it++; } break; } case clang::Decl::Function: { SgType * tmp_type = buildTypeFromQualifiedType(((clang::FunctionDecl *)decl)->getType()); SgFunctionType * type = isSgFunctionType(tmp_type); ROSE_ASSERT(type); it = SageBuilder::ScopeStack.rbegin(); while (it != SageBuilder::ScopeStack.rend() && sym == NULL) { sym = (*it)->lookup_function_symbol(name, type); it++; } break; } case clang::Decl::Field: { SgClassDeclaration * sg_class_decl = isSgClassDeclaration(Traverse(((clang::FieldDecl *)decl)->getParent())); ROSE_ASSERT(sg_class_decl != NULL); if (sg_class_decl->get_definingDeclaration() == NULL) std::cerr << "Runtime Error: cannot find the definition of the class/struct associate to the field: " << name << std::endl; else { scope = isSgClassDeclaration(sg_class_decl->get_definingDeclaration())->get_definition(); // TODO: for C++, if 'scope' is in 'SageBuilder::ScopeStack': problem!!! // It means that we are currently building the class while (scope != NULL && sym == NULL) { sym = scope->lookup_variable_symbol(name); scope = scope->get_scope(); } } break; } case clang::Decl::CXXRecord: case clang::Decl::Record: { it = SageBuilder::ScopeStack.rbegin(); while (it != SageBuilder::ScopeStack.rend() && sym == NULL) { sym = (*it)->lookup_class_symbol(name); it++; } break; } case clang::Decl::Label: { // Should not be reach as we use Traverse to retrieve Label (they are "terminal" statements) (it avoids the problem of forward use of label: goto before declaration) name = SgName(((clang::LabelDecl *)decl)->getStmt()->getName()); it = SageBuilder::ScopeStack.rbegin(); while (it != SageBuilder::ScopeStack.rend() && sym == NULL) { sym = (*it)->lookup_label_symbol(name); it++; } break; } case clang::Decl::EnumConstant: { name = SgName(((clang::EnumConstantDecl *)decl)->getName()); it = SageBuilder::ScopeStack.rbegin(); while (it != SageBuilder::ScopeStack.rend() && sym == NULL) { sym = (*it)->lookup_enum_field_symbol(name); it++; } break; } case clang::Decl::Enum: { name = SgName(((clang::EnumDecl *)decl)->getName()); it = SageBuilder::ScopeStack.rbegin(); while (it != SageBuilder::ScopeStack.rend() && sym == NULL) { sym = (*it)->lookup_enum_symbol(name); it++; } break; } default: std::cerr << "Runtime Error: Unknown type of Decl. (" << decl->getDeclKindName() << ")" << std::endl; } return sym; }
void UnparseFortran_type::unparseFunctionType(SgType* type, SgUnparse_Info& info) { SgFunctionType* func_type = isSgFunctionType(type); ROSE_ASSERT (func_type != NULL); SgUnparse_Info ninfo(info); // DQ (1/24/2011): The case of a procedure type in Fortran is quite simple. // Note that test2011_28.f90 demonstrates an example of this. // curprint("procedure()"); curprint("procedure(), pointer"); #if 0 int needParen = 0; if (ninfo.isReferenceToSomething() || ninfo.isPointerToSomething()) { needParen=1; } // DQ (10/8/2004): Skip output of class definition for return type! C++ standard does not permit // a defining declaration within a return type, function parameter, or sizeof expression. ninfo.set_SkipClassDefinition(); if (ninfo.isTypeFirstPart()) { if (needParen) { ninfo.unset_isReferenceToSomething(); ninfo.unset_isPointerToSomething(); unparseType(func_type->get_return_type(), ninfo); curprint("("); } else { unparseType(func_type->get_return_type(), ninfo); } } else { if (ninfo.isTypeSecondPart()) { if (needParen) { curprint(")"); info.unset_isReferenceToSomething(); info.unset_isPointerToSomething(); } // print the arguments SgUnparse_Info ninfo2(info); ninfo2.unset_SkipBaseType(); ninfo2.unset_isTypeSecondPart(); ninfo2.unset_isTypeFirstPart(); curprint("("); SgTypePtrList::iterator p = func_type->get_arguments().begin(); while(p != func_type->get_arguments().end()) { // printf ("Output function argument ... \n"); unparseType(*p, ninfo2); p++; if (p != func_type->get_arguments().end()) { curprint(", "); } } curprint(")"); unparseType(func_type->get_return_type(), info); // catch the 2nd part of the rtype } else { ninfo.set_isTypeFirstPart(); unparseType(func_type, ninfo); ninfo.set_isTypeSecondPart(); unparseType(func_type, ninfo); } } #endif }
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 }
/** * 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::isFunction() const { return isSgFunctionType(t_) != 0; }