bool ClangToSageTranslator::VisitTypedefDecl(clang::TypedefDecl * typedef_decl, SgNode ** node) { #if DEBUG_VISIT_DECL std::cerr << "ClangToSageTranslator::VisitTypedefDecl" << std::endl; #endif bool res = true; SgName name(typedef_decl->getNameAsString()); SgType * type = buildTypeFromQualifiedType(typedef_decl->getUnderlyingType()); SgTypedefDeclaration * sg_typedef_decl = SageBuilder::buildTypedefDeclaration_nfi(name, type, SageBuilder::topScopeStack()); if (isSgClassType(type)) { std::map<SgClassType *, bool>::iterator bool_it = p_class_type_decl_first_see_in_type.find(isSgClassType(type)); ROSE_ASSERT(bool_it != p_class_type_decl_first_see_in_type.end()); if (bool_it->second) { sg_typedef_decl->set_declaration(isSgNamedType(type)->get_declaration()->get_definingDeclaration()); sg_typedef_decl->set_typedefBaseTypeContainsDefiningDeclaration(true); } } else if (isSgEnumType(type)) { std::map<SgEnumType *, bool>::iterator bool_it = p_enum_type_decl_first_see_in_type.find(isSgEnumType(type)); ROSE_ASSERT(bool_it != p_enum_type_decl_first_see_in_type.end()); if (bool_it->second) { sg_typedef_decl->set_declaration(isSgEnumType(type)->get_declaration()->get_definingDeclaration()); sg_typedef_decl->set_typedefBaseTypeContainsDefiningDeclaration(true); } } *node = sg_typedef_decl; return VisitTypedefNameDecl(typedef_decl, node) && res; }
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())); } } }
bool ClangToSageTranslator::VisitFieldDecl(clang::FieldDecl * field_decl, SgNode ** node) { #if DEBUG_VISIT_DECL std::cerr << "ClangToSageTranslator::VisitFieldDecl" << std::endl; #endif bool res = true; SgName name(field_decl->getNameAsString()); SgType * type = buildTypeFromQualifiedType(field_decl->getType()); clang::Expr * init_expr = field_decl->getInClassInitializer(); SgNode * tmp_init = Traverse(init_expr); SgExpression * expr = isSgExpression(tmp_init); // TODO expression list if aggregated initializer ! if (tmp_init != NULL && expr == NULL) { std::cerr << "Runtime error: not a SgInitializer..." << std::endl; res = false; } SgInitializer * init = expr != NULL ? SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type()) : NULL; if (init != NULL) applySourceRange(init, init_expr->getSourceRange()); // Cannot use 'SageBuilder::buildVariableDeclaration' because of anonymous field // *node = SageBuilder::buildVariableDeclaration(name, type, init, SageBuilder::topScopeStack()); // Build it by hand... SgVariableDeclaration * var_decl = new SgVariableDeclaration(name, type, init); if (isSgClassType(type)) { std::map<SgClassType *, bool>::iterator bool_it = p_class_type_decl_first_see_in_type.find(isSgClassType(type)); ROSE_ASSERT(bool_it != p_class_type_decl_first_see_in_type.end()); if (bool_it->second) { var_decl->set_baseTypeDefiningDeclaration(isSgNamedType(type)->get_declaration()->get_definingDeclaration()); var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } else if (isSgEnumType(type)) { std::map<SgEnumType *, bool>::iterator bool_it = p_enum_type_decl_first_see_in_type.find(isSgEnumType(type)); ROSE_ASSERT(bool_it != p_enum_type_decl_first_see_in_type.end()); if (bool_it->second) { var_decl->set_baseTypeDefiningDeclaration(isSgEnumType(type)->get_declaration()->get_definingDeclaration()); var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } var_decl->set_firstNondefiningDeclaration(var_decl); var_decl->set_parent(SageBuilder::topScopeStack()); ROSE_ASSERT(var_decl->get_variables().size() == 1); SgInitializedName * init_name = var_decl->get_variables()[0]; ROSE_ASSERT(init_name != NULL); init_name->set_scope(SageBuilder::topScopeStack()); applySourceRange(init_name, field_decl->getSourceRange()); SgVariableDefinition * var_def = isSgVariableDefinition(init_name->get_declptr()); ROSE_ASSERT(var_def != NULL); applySourceRange(var_def, field_decl->getSourceRange()); SgVariableSymbol * var_symbol = new SgVariableSymbol(init_name); SageBuilder::topScopeStack()->insert_symbol(name, var_symbol); *node = var_decl; return VisitDeclaratorDecl(field_decl, node) && res; }
bool ClangToSageTranslator::VisitVarDecl(clang::VarDecl * var_decl, SgNode ** node) { #if DEBUG_VISIT_DECL std::cerr << "ClangToSageTranslator::VisitVarDecl" << std::endl; #endif bool res = true; // Create the SAGE node: SgVariableDeclaration SgName name(var_decl->getNameAsString()); SgType * type = buildTypeFromQualifiedType(var_decl->getType()); clang::Expr * init_expr = var_decl->getInit(); SgNode * tmp_init = Traverse(init_expr); SgExpression * expr = isSgExpression(tmp_init); if (tmp_init != NULL && expr == NULL) { std::cerr << "Runtime error: not a SgInitializer..." << std::endl; // TODO res = false; } SgExprListExp * expr_list_expr = isSgExprListExp(expr); SgInitializer * init = NULL; if (expr_list_expr != NULL) init = SageBuilder::buildAggregateInitializer(expr_list_expr, type); else if (expr != NULL) init = SageBuilder::buildAssignInitializer_nfi(expr, expr->get_type()); if (init != NULL) applySourceRange(init, init_expr->getSourceRange()); SgVariableDeclaration * sg_var_decl = new SgVariableDeclaration(name, type, init); // scope: obtain from the scope stack. if (isSgClassType(type)) { std::map<SgClassType *, bool>::iterator bool_it = p_class_type_decl_first_see_in_type.find(isSgClassType(type)); ROSE_ASSERT(bool_it != p_class_type_decl_first_see_in_type.end()); if (bool_it->second) { sg_var_decl->set_baseTypeDefiningDeclaration(isSgNamedType(type)->get_declaration()->get_definingDeclaration()); sg_var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } else if (isSgEnumType(type)) { std::map<SgEnumType *, bool>::iterator bool_it = p_enum_type_decl_first_see_in_type.find(isSgEnumType(type)); ROSE_ASSERT(bool_it != p_enum_type_decl_first_see_in_type.end()); if (bool_it->second) { sg_var_decl->set_baseTypeDefiningDeclaration(isSgEnumType(type)->get_declaration()->get_definingDeclaration()); sg_var_decl->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); } } sg_var_decl->set_firstNondefiningDeclaration(sg_var_decl); sg_var_decl->set_parent(SageBuilder::topScopeStack()); ROSE_ASSERT(sg_var_decl->get_variables().size() == 1); SgInitializedName * init_name = sg_var_decl->get_variables()[0]; ROSE_ASSERT(init_name != NULL); init_name->set_scope(SageBuilder::topScopeStack()); applySourceRange(init_name, var_decl->getSourceRange()); SgVariableDefinition * var_def = isSgVariableDefinition(init_name->get_declptr()); ROSE_ASSERT(var_def != NULL); applySourceRange(var_def, var_decl->getSourceRange()); SgVariableSymbol * var_symbol = new SgVariableSymbol(init_name); SageBuilder::topScopeStack()->insert_symbol(name, var_symbol); *node = sg_var_decl; return VisitDeclaratorDecl(var_decl, node) && res; }
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 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); }
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); } } }