00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #define __STDC_LIMIT_MACROS
00026
00027 #include "ipa_chg.h"
00028
00029 IPA_CLASS_HIERARCHY *IPA_Class_Hierarchy;
00030
00031 IPA_CLASS_HIERARCHY::IPA_CLASS_HIERARCHY() {
00032 }
00033
00034 IPA_CLASS_HIERARCHY::~IPA_CLASS_HIERARCHY() {
00035
00036 }
00037
00038 INT
00039 IPA_CLASS_HIERARCHY::Get_Num_Base_Classes(TY_INDEX tyi) {
00040 CLASS_RELATIONSHIP::const_iterator node = baseclass.find(tyi);
00041 if (node != baseclass.end())
00042 return node->second.size();
00043 return 0;
00044 }
00045
00046 INT
00047 IPA_CLASS_HIERARCHY::Get_Num_Sub_Classes(TY_INDEX tyi) {
00048 CLASS_RELATIONSHIP::const_iterator node = subclass.find(tyi);
00049 if (node != subclass.end())
00050 return node->second.size();
00051 return 0;
00052 }
00053
00054 TY_INDEX
00055 IPA_CLASS_HIERARCHY::Get_Base_Class(TY_INDEX tyi, INT index) {
00056 CLASS_RELATIONSHIP::const_iterator node = baseclass.find(tyi);
00057 if (node != baseclass.end())
00058 return node->second[index];
00059 return 0;
00060 }
00061
00062 TY_INDEX
00063 IPA_CLASS_HIERARCHY::Get_Sub_Class(TY_INDEX tyi, INT index) {
00064 CLASS_RELATIONSHIP::const_iterator node = subclass.find(tyi);
00065 if (node != subclass.end())
00066 return node->second[index];
00067 return 0;
00068 }
00069
00070 void
00071 IPA_CLASS_HIERARCHY::Add_Base_Class(TY_INDEX tyi, TY_INDEX base) {
00072 _ty_idx_list list;
00073 if (baseclass.find(tyi) != baseclass.end()) {
00074 baseclass[tyi].push_back(base);
00075 }
00076 else {
00077 _ty_idx_list list;
00078 list.push_back(base);
00079 baseclass[tyi] = list;
00080 }
00081 return;
00082 }
00083
00084 void
00085 IPA_CLASS_HIERARCHY::Add_Sub_Class(TY_INDEX tyi, TY_INDEX sub) {
00086 if (subclass.find(tyi) != subclass.end()) {
00087 subclass[tyi].push_back(sub);
00088 }
00089 else {
00090 _ty_idx_list list;
00091 list.push_back(sub);
00092 subclass[tyi] = list;
00093 }
00094 return;
00095 }
00096
00097 BOOL
00098 IPA_CLASS_HIERARCHY::Is_Sub_Class(TY_INDEX tyi, TY_INDEX sub) {
00099 if (subclass.find(tyi) != subclass.end()) {
00100 _ty_idx_list &list = subclass[tyi];
00101 for (size_t i = 0; i < list.size(); i++)
00102 if (list[i] == sub)
00103 return TRUE;
00104 }
00105 return FALSE;
00106 }
00107
00108 BOOL
00109 IPA_CLASS_HIERARCHY::Is_Ancestor(TY_INDEX ancestor, TY_INDEX descendant) {
00110 if (ancestor == descendant || Is_Sub_Class(ancestor, descendant))
00111 return TRUE;
00112 for (UINT i=0; i<Get_Num_Sub_Classes(ancestor); i++) {
00113 TY_INDEX sub = Get_Sub_Class(ancestor, i);
00114 if (Is_Ancestor(sub, descendant))
00115 return TRUE;
00116 }
00117 return FALSE;
00118 }
00119
00120 IPA_CLASS_HIERARCHY*
00121 Build_Class_Hierarchy() {
00122
00123 IPA_CLASS_HIERARCHY *chg = CXX_NEW(IPA_CLASS_HIERARCHY, Malloc_Mem_Pool);
00124 UINT32 num_type = TY_Table_Size();
00125
00126
00127 for (UINT32 i = 1; i < num_type; i++) {
00128 TY &ty = Ty_tab[i];
00129 if (Is_Structure_Type(ty) && !TY_is_union(ty) && ty.Fld() > 0) {
00130
00131 FLD_IDX fld_idx = ty.Fld();
00132 do {
00133 FLD_HANDLE fld(fld_idx);
00134 if (FLD_is_base_class(fld)) {
00135 TY_INDEX base = TY_IDX_index(FLD_type(fld));
00136 chg->Add_Base_Class(i, base);
00137 chg->Add_Sub_Class(base, i);
00138 }
00139 if (FLD_last_field(fld))
00140 break;
00141 fld_idx++;
00142 } while (1);
00143 }
00144 }
00145 return chg;
00146 }
00147
00148
00149
00150
00151 size_t
00152 IPA_CLASS_HIERARCHY::Get_Ancestor_Offset(TY_INDEX sub, TY_INDEX anc) {
00153 if (sub == anc)
00154 return 0;
00155 TY &ty = Ty_tab[sub];
00156 if (Is_Structure_Type(ty) && !TY_is_union(ty) && ty.Fld() > 0) {
00157
00158 FLD_IDX fld_idx = ty.Fld();
00159 do {
00160 FLD_HANDLE fld(fld_idx);
00161 if (FLD_is_base_class(fld)) {
00162 TY_INDEX current_base = TY_IDX_index(FLD_type(fld));
00163
00164 if (current_base == anc)
00165 return FLD_ofst(fld);
00166
00167 size_t ofst = Get_Ancestor_Offset(current_base, anc);
00168 if (ofst != BASE_CLASS_NOT_FOUND)
00169 return FLD_ofst(fld) + ofst;
00170 }
00171 if (FLD_last_field(fld))
00172 break;
00173 fld_idx++;
00174 } while (1);
00175 }
00176 return BASE_CLASS_NOT_FOUND;
00177 }
00178