SgClassDeclaration * SageUtils::buildUnionDeclaration(const SgName & name, SgScopeStatement * scope) { SgClassDeclaration* defdecl = SageBuilder::buildClassDeclaration_nfi(name,SgClassDeclaration::e_union,scope,NULL); SageInterface::setOneSourcePositionForTransformation(defdecl); ROSE_ASSERT(defdecl->get_firstNondefiningDeclaration() != NULL); SageInterface::setOneSourcePositionForTransformation(defdecl->get_firstNondefiningDeclaration()); return defdecl; }
SgClassDeclaration* buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope) { // This function builds a class declaration and definition // (both the defining and nondefining declarations as required). // Build a file info object marked as a transformation Sg_File_Info* fileInfo = Sg_File_Info::generateDefaultFileInfoForTransformationNode(); assert(fileInfo != NULL); // This is the class definition (the fileInfo is the position of the opening brace) SgClassDefinition* classDefinition = new SgClassDefinition(fileInfo); assert(classDefinition != NULL); // Set the end of construct explictly (where not a transformation this is the location of the closing brace) classDefinition->set_endOfConstruct(fileInfo); // This is the defining declaration for the class (with a reference to the class definition) SgClassDeclaration* classDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition); assert(classDeclaration != NULL); // Set the defining declaration in the defining declaration! classDeclaration->set_definingDeclaration(classDeclaration); // Set the non defining declaration in the defining declaration (both are required) SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(fileInfo,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL); assert(classDeclaration != NULL); nondefiningClassDeclaration->set_scope(scope); nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration)); // Set the internal reference to the non-defining declaration classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration); classDeclaration->set_type(nondefiningClassDeclaration->get_type()); // Set the defining and no-defining declarations in the non-defining class declaration! nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration); nondefiningClassDeclaration->set_definingDeclaration(classDeclaration); // Set the nondefining declaration as a forward declaration! nondefiningClassDeclaration->setForward(); // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)! classDefinition->set_declaration(classDeclaration); // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!) classDeclaration->set_scope(scope); // some error checking assert(classDeclaration->get_definingDeclaration() != NULL); assert(classDeclaration->get_firstNondefiningDeclaration() != NULL); assert(classDeclaration->get_definition() != NULL); // DQ (9/8/2007): Need to add function symbol to global scope! printf ("Fixing up the symbol table in scope = %p = %s for class = %p = %s \n",scope,scope->class_name().c_str(),classDeclaration,classDeclaration->get_name().str()); SgClassSymbol* classSymbol = new SgClassSymbol(classDeclaration); scope->insert_symbol(classDeclaration->get_name(),classSymbol); ROSE_ASSERT(scope->lookup_class_symbol(classDeclaration->get_name()) != NULL); return classDeclaration; }
SgVariableDeclaration* buildStructVariable ( SgScopeStatement* scope, vector<SgType*> memberTypes, vector<string> memberNames, string structName = "", string varName = "", SgAggregateInitializer *initializer = NULL ) { ROSE_ASSERT(memberTypes.size() == memberNames.size()); SgClassDeclaration* classDeclaration = buildClassDeclarationAndDefinition(structName,scope); vector<SgType*>::iterator typeIterator = memberTypes.begin(); vector<string>::iterator memberNameIterator = memberNames.begin(); while (typeIterator != memberTypes.end()) { // printf ("Adding data member type = %s variable name = %s \n",(*typeIterator)->unparseToString().c_str(),memberNameIterator->c_str()); SgVariableDeclaration* memberDeclaration = new SgVariableDeclaration(SOURCE_POSITION,*memberNameIterator,*typeIterator,NULL); memberDeclaration->set_endOfConstruct(SOURCE_POSITION); classDeclaration->get_definition()->append_member(memberDeclaration); memberDeclaration->set_parent(classDeclaration->get_definition()); // Liao (2/13/2008) scope and symbols for member variables SgInitializedName* initializedName = *(memberDeclaration->get_variables().begin()); initializedName->set_file_info(SOURCE_POSITION); initializedName->set_scope(classDeclaration->get_definition()); // set nondefning declaration pointer memberDeclaration->set_firstNondefiningDeclaration(memberDeclaration); SgVariableSymbol* variableSymbol = new SgVariableSymbol(initializedName); classDeclaration->get_definition()->insert_symbol(*memberNameIterator,variableSymbol); typeIterator++; memberNameIterator++; } SgClassType* classType = new SgClassType(classDeclaration->get_firstNondefiningDeclaration()); SgVariableDeclaration* variableDeclaration = new SgVariableDeclaration(SOURCE_POSITION,varName,classType,initializer); variableDeclaration->set_endOfConstruct(SOURCE_POSITION); //Liao (2/13/2008) scope and symbols for struct variable SgInitializedName* initializedName = *(variableDeclaration->get_variables().begin()); initializedName->set_file_info(SOURCE_POSITION); initializedName->set_scope(scope); SgVariableSymbol* variableSymbol = new SgVariableSymbol(initializedName); scope->insert_symbol(varName,variableSymbol); //set nondefining declaration variableDeclaration->set_firstNondefiningDeclaration(variableDeclaration); // This is required, since it is not set in the SgVariableDeclaration constructor initializer->set_parent(variableDeclaration); variableDeclaration->set_variableDeclarationContainsBaseTypeDefiningDeclaration(true); variableDeclaration->set_baseTypeDefiningDeclaration(classDeclaration->get_definingDeclaration()); classDeclaration->set_parent(variableDeclaration); return variableDeclaration; }
bool ReplacementMapTraversal::verifyODR( SgNode* node, SgNode* duplicateNodeFromOriginalAST ) { bool passesODR = false; // printf ("Verify that node = %p is equivalent to duplicateNodeFromOriginalAST = %p = %s \n",node,duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str()); // Verify that these strings match ROSE_ASSERT (duplicateNodeFromOriginalAST->variantT() == node->variantT()); ROSE_ASSERT (duplicateNodeFromOriginalAST->class_name() == node->class_name()); // ROSE_ASSERT (generateUniqueName(duplicateNodeFromOriginalAST) == generateUniqueName(node)); string nodeString; string duplicateNodeFromOriginalASTstring; #if 0 // DQ (2/3/2007): This is a test to debug the ODR checking. // I think that the unparser has some state specific to the output of access protections. // if the unparsing changes the state then the access permission (public, protected, private) // is output and this cause a falue trigger to the ODR string match. This is a temp fix to // absorbe any change of state, but we need a mechanism to clear the state in the unparser. string absorbeUnparserStateChange_A = node->unparseToString(); string absorbeUnparserStateChange_B = duplicateNodeFromOriginalAST->unparseToString(); #endif #if 0 // DQ (2/3/2007): Make sure that there are close to being related. It appears that if these are if (node->get_parent()->variantT() == duplicateNodeFromOriginalAST->get_parent()->variantT()) { nodeString = node->unparseToString(); duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString(); } #endif bool skip_ODR_test = false; bool nodeIsCompilerGenerated = (node->get_file_info() != NULL) ? node->get_file_info()->isCompilerGenerated() : false; bool duplicateNodeFromOriginalASTIsCompilerGenerated = (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isCompilerGenerated() : false; bool nodeIsFrontendSpecific = (node->get_file_info() != NULL) ? node->get_file_info()->isFrontendSpecific() : false; bool duplicateNodeFromOriginalASTIsFrontendSpecific = (duplicateNodeFromOriginalAST->get_file_info() != NULL) ? duplicateNodeFromOriginalAST->get_file_info()->isFrontendSpecific() : false; // If this is a template declaration for a function then it might have been a part of another template declaration // for the template class and thus might not exist explicitly in the AST (and thus not have enough information from // which to generate a meaningful mangled name). Skip ODR testing of these cases. bool isTemplateMemberFunctionInTemplatedClass = false; SgTemplateDeclaration* templateDeclaration = isSgTemplateDeclaration(node); if (templateDeclaration != NULL) { SgTemplateDeclaration* dup_templateDeclaration = isSgTemplateDeclaration(duplicateNodeFromOriginalAST); ROSE_ASSERT(dup_templateDeclaration != NULL); if ( templateDeclaration->get_string().is_null() && dup_templateDeclaration->get_string().is_null() ) { isTemplateMemberFunctionInTemplatedClass = true; } } if (isTemplateMemberFunctionInTemplatedClass == true) { printf ("ODR not tested isTemplateMemberFunctionInTemplatedClass == true. \n"); skip_ODR_test = true; } if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true || nodeIsCompilerGenerated == true || duplicateNodeFromOriginalASTIsCompilerGenerated == true) { // printf ("ODR not tested for frontend specific compiler generated code. \n"); skip_ODR_test = true; } // DQ (1/20/2007): The unparse will not generate a string if the code is frontend specific or compiler generated (I forget which). // if (nodeIsFrontendSpecific == true || duplicateNodeFromOriginalASTIsFrontendSpecific == true) if (skip_ODR_test == true) { // printf ("ODR not tested for frontend specific compiler generated code. \n"); passesODR = true; } else { SgUnparse_Info info_a; SgUnparse_Info info_b; // DQ (2/6/2007): Force qualified names to be used uniformally (note that info.set_requiresGlobalNameQualification() // causes an error) info.set_requiresGlobalNameQualification(); info_a.set_forceQualifiedNames(); info_b.set_forceQualifiedNames(); nodeString = node->unparseToString(&info_a); // DQ (2/6/2007): The SgUnparse_Info object carries state which controls the use of access qualification and the // first call to unparseToString might have set the access (e.g. to "public") and the second call would drop the // access qualification. We unset the access qualification state in the SgUnparse_Info object so that both will // be unparsed the same (we could have alternatively used two separate SgUnparse_Info objects. // info.set_isUnsetAccess(); duplicateNodeFromOriginalASTstring = duplicateNodeFromOriginalAST->unparseToString(&info_b); passesODR = (nodeString == duplicateNodeFromOriginalASTstring); } // Don't count the cases where the unparse fails to to invalid parent in redundant SgClassDeclaration (fix these later) if (passesODR == false && nodeString.empty() == false && duplicateNodeFromOriginalASTstring.empty() == false) { #if 1 if (SgProject::get_verbose() > 0) printf ("##### In ReplacementMapTraversal::verifyODR() is false: node = %p = %s duplicateNodeFromOriginalAST = %p = %s \n", node,node->class_name().c_str(),duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str()); // printf ("##### passesODR = %s \n",passesODR ? "true" : "false"); // printf ("duplicateNodeFromOriginalASTstring = \n---> %s\n",duplicateNodeFromOriginalASTstring.c_str()); // printf ("nodeString = \n---> %s\n",nodeString.c_str()); if (node->get_file_info() != NULL && duplicateNodeFromOriginalAST->get_file_info() != NULL) { if (SgProject::get_verbose() > 0) { SgNode* parent_node = node->get_parent(); // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code. ROSE_ASSERT(parent_node != NULL); printf ("parent_node = %p = %s = %s \n",parent_node,parent_node->class_name().c_str(),SageInterface::get_name(parent_node).c_str()); SgNode* parent_dup = duplicateNodeFromOriginalAST->get_parent(); // DQ (9/13/2011): Reported as possible NULL value in static analysis of ROSE code. ROSE_ASSERT(parent_dup != NULL); printf ("parent_dup = %p = %s = %s \n",parent_dup,parent_dup->class_name().c_str(),SageInterface::get_name(parent_dup).c_str()); printf ("\nPosition of error: \n"); node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug"); duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug"); printf ("\nPosition of error: \n"); printf ("\nPosition of error (parent IR node): \n"); parent_node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_node) is false: debug"); parent_dup->get_file_info()->display("In ReplacementMapTraversal::verifyODR(parent_dup) is false: debug"); printf ("\nPosition of error (parent IR node): \n"); } } else { SgClassType* classType = isSgClassType(node); SgClassType* duplicateNodeFromOriginalAST_classType = isSgClassType(duplicateNodeFromOriginalAST); if (classType != NULL) { if (SgProject::get_verbose() > 0) { SgClassDeclaration* classDeclaration = isSgClassDeclaration(classType->get_declaration()); ROSE_ASSERT(classDeclaration != NULL); classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (classType)"); printf ("classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n", classDeclaration, classDeclaration->get_definingDeclaration(), classDeclaration->get_firstNondefiningDeclaration()); ROSE_ASSERT(duplicateNodeFromOriginalAST_classType != NULL); SgClassDeclaration* duplicateNodeFromOriginalAST_classDeclaration = isSgClassDeclaration(duplicateNodeFromOriginalAST_classType->get_declaration()); ROSE_ASSERT(duplicateNodeFromOriginalAST_classDeclaration != NULL); duplicateNodeFromOriginalAST_classDeclaration->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false (duplicateNodeFromOriginalAST_classType)"); printf ("duplicateNodeFromOriginalAST_classDeclaration = %p definingDeclaration = %p nondefiningDeclaration = %p \n", duplicateNodeFromOriginalAST_classDeclaration, duplicateNodeFromOriginalAST_classDeclaration->get_definingDeclaration(), duplicateNodeFromOriginalAST_classDeclaration->get_firstNondefiningDeclaration()); } } } #endif odrViolations.push_back(pair<SgNode*,SgNode*>(node,duplicateNodeFromOriginalAST)); } #if 0 printf ("duplicateNodeFromOriginalASTstring = %p = %s \n---> %s\n", duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),duplicateNodeFromOriginalASTstring.c_str()); printf ("nodeString = %p = %s \n---> %s\n", node,node->class_name().c_str(),nodeString.c_str()); #endif #if 0 SgClassType* original = isSgClassType(duplicateNodeFromOriginalAST); SgClassType* target = isSgClassType(node); if (original != NULL && target != NULL) { printf ("original declaration = %p \n",original->get_declaration()); printf ("target declaration = %p \n",target->get_declaration()); } #endif #if 1 if (passesODR == false) { if (SgProject::get_verbose() > 0) { string node_generatedName = SageInterface::generateUniqueName(node,false); string originalNode_generatedName = SageInterface::generateUniqueName(duplicateNodeFromOriginalAST,false); printf ("ODR Violation Source code: nodeString = \n%s\n \n",nodeString.c_str()); printf ("ODR Violation Source code: duplicateNodeFromOriginalASTstring = \n%s\n \n",duplicateNodeFromOriginalASTstring.c_str()); printf ("nodeString = %s \n",nodeString.c_str()); printf ("node_generatedName = %s \n",node_generatedName.c_str()); printf ("originalNode_generatedName = %s \n",originalNode_generatedName.c_str()); printf ("node = %p = %s = %s \n",node,node->class_name().c_str(),SageInterface::get_name(node).c_str()); printf ("duplicateNodeFromOriginalAST = %p = %s = %s \n",duplicateNodeFromOriginalAST,duplicateNodeFromOriginalAST->class_name().c_str(),SageInterface::get_name(duplicateNodeFromOriginalAST).c_str()); printf ("node (unique string) = %s \n",generateUniqueName(node,true).c_str()); printf ("duplicateNodeFromOriginalAST (unique string) = %s \n",generateUniqueName(duplicateNodeFromOriginalAST,true).c_str()); SgDeclarationStatement* declarationStatement = isSgDeclarationStatement(node); if (declarationStatement != NULL) { printf ("declarationStatement->get_definingDeclaration() = %p \n",declarationStatement->get_definingDeclaration()); printf ("declarationStatement->get_firstNondefiningDeclaration() = %p \n",declarationStatement->get_firstNondefiningDeclaration()); } SgDeclarationStatement* declarationStatement2 = isSgDeclarationStatement(duplicateNodeFromOriginalAST); if (declarationStatement2 != NULL) { printf ("declarationStatement2->get_definingDeclaration() = %p \n",declarationStatement2->get_definingDeclaration()); printf ("declarationStatement2->get_firstNondefiningDeclaration() = %p \n",declarationStatement2->get_firstNondefiningDeclaration()); } printf ("Source code positions of ORD violation: \n"); node->get_file_info()->display("In ReplacementMapTraversal::verifyODR(node) is false: debug"); duplicateNodeFromOriginalAST->get_file_info()->display("In ReplacementMapTraversal::verifyODR(duplicateNodeFromOriginalAST) is false: debug"); } } #endif // ROSE_ASSERT(nodeString == duplicateNodeFromOriginalASTstring); ROSE_ASSERT(passesODR == true); return passesODR; }
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); } } }
SgClassDeclaration* buildClassDeclarationAndDefinition (string name, SgScopeStatement* scope) { // This function builds a class declaration and definition // (both the defining and nondefining declarations as required). // This is the class definition (the fileInfo is the position of the opening brace) SgClassDefinition* classDefinition = new SgClassDefinition(SOURCE_POSITION); assert(classDefinition != NULL); // Set the end of construct explictly (where not a transformation this is the location of the closing brace) classDefinition->set_endOfConstruct(SOURCE_POSITION); // This is the defining declaration for the class (with a reference to the class definition) SgClassDeclaration* classDeclaration = new SgClassDeclaration(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,classDefinition); assert(classDeclaration != NULL); classDeclaration->set_endOfConstruct(SOURCE_POSITION); // Set the defining declaration in the defining declaration! classDeclaration->set_definingDeclaration(classDeclaration); // Set the non defining declaration in the defining declaration (both are required) SgClassDeclaration* nondefiningClassDeclaration = new SgClassDeclaration(SOURCE_POSITION,name.c_str(),SgClassDeclaration::e_struct,NULL,NULL); assert(classDeclaration != NULL); nondefiningClassDeclaration->set_endOfConstruct(SOURCE_POSITION); nondefiningClassDeclaration->set_scope(scope); // scope is needed for createType() nondefiningClassDeclaration->set_type(SgClassType::createType(nondefiningClassDeclaration)); // Set the internal reference to the non-defining declaration classDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration); classDeclaration->set_type (nondefiningClassDeclaration->get_type()); // Set the defining and no-defining declarations in the non-defining class declaration! nondefiningClassDeclaration->set_firstNondefiningDeclaration(nondefiningClassDeclaration); nondefiningClassDeclaration->set_definingDeclaration(classDeclaration); // Set the nondefining declaration as a forward declaration! nondefiningClassDeclaration->setForward(); // Liao (2/13/2008), symbol for the declaration SgClassSymbol* mysymbol = new SgClassSymbol(nondefiningClassDeclaration); scope->insert_symbol(name, mysymbol); // Don't forget the set the declaration in the definition (IR node constructors are side-effect free!)! classDefinition->set_declaration(classDeclaration); // set the scope explicitly (name qualification tricks can imply it is not always the parent IR node!) classDeclaration->set_scope(scope); //set parent classDeclaration->set_parent(scope); nondefiningClassDeclaration->set_parent(scope); // some error checking assert(classDeclaration->get_definingDeclaration() != NULL); assert(classDeclaration->get_firstNondefiningDeclaration() != NULL); assert(classDeclaration->get_definition() != NULL); ROSE_ASSERT(classDeclaration->get_definition()->get_parent() != NULL); return classDeclaration; }