// Turn an reference pointer into an array reference expression void ReferenceCleanupPass::CleanupArrayStore(StoreStatement* s) { assert(s != NULL) ; // Check to see if the destination is a reference variable Expression* destination = s->get_destination_address() ; VariableSymbol* storedVariable = FindVariable(destination) ; if (storedVariable == NULL) { return ; } if (dynamic_cast<ReferenceType*>(storedVariable->get_type()->get_base_type())) { // Can I just change the type? Pointer conversion should take care of it // then, but I'll have to annotate it ReferenceType* refType = dynamic_cast<ReferenceType*>(storedVariable->get_type()->get_base_type()) ; QualifiedType* internalType = dynamic_cast<QualifiedType*>(refType->get_reference_type()) ; assert(internalType != NULL) ; DataType* internalType2 = internalType->get_base_type() ; QualifiedType* qualType = storedVariable->get_type() ; qualType->set_base_type(NULL) ; refType->set_parent(NULL) ; internalType->set_parent(NULL) ; refType->set_reference_type(NULL) ; qualType->set_base_type(internalType2) ; } }
// Do a sort of garbage collection. Take all of the types that we want to // delete and collect them. If there are no uses of them after this function // has finished, then remove them. void RemoveModulePass::RemoveProcedure(ProcedureSymbol* p) { assert(repository != NULL) ; list<Type*> usedTypes ; if (p == NULL) { return ; } // There should be no definition, but just in case remove it ProcedureDefinition* defToRemove = p->get_definition() ; p->set_definition(NULL) ; if (defToRemove != NULL) { delete defToRemove ; } // Clear out all of the values associated with the procedure type CProcedureType* procType = dynamic_cast<CProcedureType*>(p->get_type()) ; assert(procType != NULL) ; DataType* returnTypeToRemove = procType->get_result_type() ; procType->set_result_type(NULL) ; if (returnTypeToRemove != NULL) { usedTypes.push_back(returnTypeToRemove) ; } while (procType->get_argument_count() > 0) { QualifiedType* currentArg = procType->get_argument(0) ; procType->remove_argument(0) ; if (!InList(usedTypes, currentArg)) { usedTypes.push_back(currentArg) ; } } SymbolTable* symTab = repository->get_external_symbol_table() ; p->set_type(NULL) ; symTab->remove_symbol_table_object(procType) ; delete procType ; symTab->remove_symbol_table_object(p) ; delete p ; // Now, go through each used type and see if it is used anywhere list<Type*>::iterator typeIter = usedTypes.begin() ; while (typeIter != usedTypes.end()) { bool removeMe = true ; for (int i = 0 ; i < symTab->get_symbol_table_object_count() ; ++i) { CProcedureType* currentType = dynamic_cast<CProcedureType*>(symTab->get_symbol_table_object(i)) ; if (currentType != NULL) { if (IsUsed(*typeIter, currentType)) { removeMe = false ; break ; } } } if (removeMe) { if ((*typeIter)->lookup_annote_by_name("Output") != NULL) { delete (*typeIter)->remove_annote_by_name("Output") ; } QualifiedType* q = dynamic_cast<QualifiedType*>(*typeIter) ; DataType* d = dynamic_cast<DataType*>(*typeIter) ; if (q != NULL) { DataType* internalD = q->get_base_type() ; q->set_base_type(NULL) ; symTab->remove_symbol_table_object(internalD) ; symTab->remove_symbol_table_object(q) ; delete internalD ; delete q ; } else if (d != NULL) { symTab->remove_symbol_table_object(d) ; delete d ; } else { assert(0 && "Trying to remove something weird...") ; } } ++typeIter ; } }