⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mangle.cpp

📁 UC Library Extensions UnderC comes with a pocket implementation of the standard C++ libraries, wh
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			out_ref_ptr(t);
			out(cc);  
			out_classname(pc);
  		    if (! m_dont_lookup_class) mClassList.push_back(pc);
       } 
   }

};

OpNames gcc2_fns[] = {
    {"=", "as"},
    {"==","eq"},
    {"!=","ne"},  // *fix 1.2.4 added
    {"[]","vc"},
    {"<<","ls"},
    {">>","rs"},
    {"+","pl"},
    {"-","mi"},
    {"+=","apl"},
    {"-=","ami"},
    {"*","ml"},
    {"++","pp"},
    {"--","mm"},
    {"<","lt"},
    {">","gt"},
    {"&&","aa"},
    {"||","oo"},
    {"&","ad"},
    {"|","or"},
    {NULL,NULL}
   };

class GCC2Mangler: public Mangler {
public:
 GCC2Mangler() 
 {
  m_begin_name = "";
  m_rpt_type = "T";
  m_void_args = "v";  

  m_end_stdarg = "e"; 
  m_end_args = "";
  m_plain_function = "F";
  m_function_ptr = "PF"; 
  m_method_ptr = "";  // ?que           
  m_end_function_ptr = "_v";
  m_method_ptr_type = "";   // *add 1.2.3
  m_use_return_type = false;
  m_plain_obj = "G";
  m_const_attrib = "C";
  m_plain_attrib = "";
  m_ref_chr = 'R';
  m_array_char = 'P';
  m_ptr_char = 'P';
  m_method_type_first = true;
  m_convention_first = false;
  m_collect_repeats = "N";

  m_end_class = "";
  m_template_name = "t";
  m_template_args = "1Z";
  m_namespace = NULL;

  m_discard_sig_types = true;
  m_enum = "";
 }

 bool simple_type(Type t) // GCC2Mangler
 {
//     return ! t.is_class() && ! t.is_signature();
     return t.is_number() && !t.is_ref_or_ptr();
 }

 void out_simple_classname(const string& name) // GCC2Mangler
 {
    outi(name.length());
    outs(name.c_str());
 }

 void do_void_args()  // GCC2Mangler
 {
 // a curious exception - class member functions don't get a special void args
 // *fix 1.2.4 class_context() is non-null if a function is a member (static!)
   if (! m_fn->class_context()) Mangler::do_void_args();
 }
 
 char type_encode(Type t) // GCC2Mangler
 {
   	 char ch;
	 if (t.is_void()) ch = 'v'; else
	 if (t.is_bool()) ch = 'b'; 
	 else
     if (t.is_int()) {
         if(t.is_unsigned()) out('U');
         if (t.is_char())  ch = 'c'; else
         if (t.is_short()) ch = 's'; else
         if (t.is_long())  ch = 'l';
         else ch = 'i'; // plain 'int'
      } else
      if (t.is_float()) {
         if (t.is_double()) ch = 'd';
         else ch = 'f';
      } else 
         return 0;
      return ch;      
  }



  void out_fun_name(string fun_name) // GCC2Mangler
  {
     const char *name = fun_name.c_str();
     if (m_fn->is_constructor()) outs("__");  else
     if (m_fn->is_destructor()) outs(GCC_DTOR);
     else {
   	   char *mn = lookup_opname(gcc2_fns,name);
	   if (mn != NULL) { outs("__"); outs(mn); }
	   else { 
         outs(name);
       }
       outs("__");
     }
   }

  void do_calling_convention() // GCC2Mangler
  {
   //  if (m_fn->is_stdcall()) outs("@0"); 
  }


  void out_method_type(int access) // GCC2Mangler
  {
   if (!m_fn->is_static() && m_fn->is_const()) out('C');
  } 


};

//////// GCC 3 mangler ////////////////////////

struct ArgTypeEntry {
    Type m_t;
    int m_arg_idx;
};

typedef std::list<ArgTypeEntry> ArgTypeList;

ArgTypeList mArgTypeList;

struct TypeObjEntry {
    void* m_pt;
	Type  m_t;
    int m_type_idx;
};

typedef std::list<TypeObjEntry> TypeObjList;

TypeObjList mTypeObjList;

const int NOT_FOUND = -2;
int match_exact_arg(Type t);
int match_type_arg(Type& t);


OpNames gcc3_fns[] = {
    {"__C__","C1"},
    {"__D__","C2"},
    {"=", "aS"},
    {"==","eq"},
    {"!=","ne"},  
    {"[]","ix"},
    {"<<","ls"},
    {">>","rs"},
    {"+","pl"},
    {"-","mi"},
    {"+=","pL"},
    {"-=","mI"},
    {"*","ml"},
    {"++","pp"},
    {"--","mm"},
    {"<","lt"},
    {">","gt"},
    {"&&","aa"},
    {"||","oo"},
    {"&","an"},
    {"|","or"},
    {NULL,NULL}
   };



class GCC3Mangler: public Mangler {
    int m_no_attrib;
    int m_type_idx;
	Type m_t;
    bool m_no_namespace;
public:

    char type_encode(Type t)
    {
        char ch;
        if (t.is_void()) ch = 'v'; else
        if (t.is_bool()) ch = 'b'; 
        else 
        if (t.is_int()) {
          if (! t.is_unsigned()) {
            if (t.is_char())  ch = 'c'; else
            if (t.is_short()) ch = 's'; else
            if (t.is_long())  ch = 'l';
            else ch = 'i'; // plain 'int'
          } else {
            if (t.is_char())  ch = 'h'; else
            if (t.is_short()) ch = 't'; else
            if (t.is_long())  ch = 'm';
            else ch = 'j'; 
          }
        } else
        if (t.is_float()) {
         if (t.is_double()) ch = 'd';
         else ch = 'f';
        } else 
         return 0;
        return ch;      
    }

   bool simple_type(Type t) // GCC3Mangler
   {
     return t.is_number() && !t.is_ref_or_ptr();
   }

   void out_attrib_char(char ch)
   {
       ++m_no_attrib;
       out(ch);
   }


   void out_ref_ptr(Type t)
   {
  // put out ref/ptr attributes 
     if (t.is_ref_or_ptr()) {
         if(t.is_reference())  out_attrib_char('R');  
         if(t.is_pointer()) {
           for(int i = 0; i < t.pointer_depth(); i++)  out_attrib_char('P');
         }
         //..the UnderC type system can't currently represent _multiple const attributes_
         if (t.is_const()) out_attrib_char('K');
     }
   }

   void out_name(const string& name)
   {
    outi(name.length());
    outs(name.c_str());
   }

   bool out_namespace(Table* pc)
   {
      if (! pc || m_no_namespace) return false;
      Namespace* ns = pc->type()==IS_NAMESPACE ? (Namespace*)pc : 0;
      //dynamic_cast<Namespace*>(pc);
      if (ns) {
          out('N');
          out_name(ns->name());
          add_type(ns);
          return true;
      }
      else return false;
   }

   void add_type(void* pt)
   {
       TypeObjEntry toe;
	   toe.m_pt = pt;
	   toe.m_type_idx = m_type_idx;
	   toe.m_t = m_t;       
       mTypeObjList.push_back(toe);
       ++m_type_idx; 
   }

   void out_classname(Class *pc) 
   {
    string name; 
    bool wuz_inside_ns = out_namespace (pc->inside_namespace());
    add_type(pc);
    if (pc->get_template()) {	   
	   out_name(pc->get_template()->name());
       out('I');
       TypeList& tl = pc->get_template()->type_parms();
       TypeList::iterator tli;
       for (tli = tl.begin(); tli != tl.end(); ++tli)
           out_type(*tli);
       out('E');
    } else {
        out_name(pc->name());
    }    
    if (wuz_inside_ns) out('E');
   }


    void out_type(Type t) 
    { 
      // encoding function ptrs
      if (t.is_signature()) {
       Signature* sig = t.as_signature();
      //bool wuz_inside_ns = out_namespace(sig->context());
	   if (sig->class_ptr() == NULL) { // NOT a method
          outs("PF");
       } else {
          out('M');
          out_classname(sig->class_ptr());
          out('F');
       }  
       out_type(sig->return_type());
	   do_signature(sig);
       out('E');
       //if (wuz_inside_ns) out('E');
      } 
      // classes and enums are output simularly
      else if (t.is_class()) out_classname(t.as_class());
      else if (t.is_enum())  { 
          Enum* e = t.as_enum();
          bool wuz_inside_ns = out_namespace(e->context());
          out_name(e->name());
          add_type(e);
          if (wuz_inside_ns) out('E');
      }
      else out(type_encode(t));    
   }


   void out_ref(int idx)
   {
   // references to previous types are of the form Sx_,
   // where x is either empty or a hexadecimal digit.
     out('S');
     if (idx > -1) outx(idx);
     out('_');
   }

   void do_signature(Signature *sig)
   {
      if (sig->begin() == sig->end()) out('v');
      else {
        int arg_idx, type_idx,start_type_idx,start_arg_idx = 0;
        Signature::iterator sigi;
        for (sigi = sig->begin(); sigi != sig->end(); ++sigi) {
           m_t = *sigi;           
         // simple types encode simply according to the above rules
           if (simple_type(m_t)) out(type_encode(m_t));
           else
         // has this (non-simple) type already appeared in the arglist?
           if ((arg_idx = match_exact_arg(m_t)) != NOT_FOUND) out_ref(arg_idx);               
           else {
            // how many attributes (const, pointer, etc) in this type?
            m_no_attrib = 0;
            // has the type already appeared in the arglist?
            if ((type_idx = match_type_arg(m_t)) != NOT_FOUND) {
               out_ref_ptr(m_t);
               out_ref(type_idx);
            } else {
               out_ref_ptr(m_t);
               out_type(m_t);
            }  
            start_arg_idx   = m_type_idx + m_no_attrib - 1;
            ArgTypeEntry ate;
            ate.m_t = m_t;
            ate.m_arg_idx = start_arg_idx;
            mArgTypeList.push_back(ate);
            m_type_idx = start_arg_idx + 1;
           }
        }
      }
   }


  void out_fun_name(string fun_name) // GCC3Mangler
  {
     const char *name = fun_name.c_str();
     bool wuz_inside_ns = false, wuz_inside_class = false;
     outs("_Z");
     PClass pc = m_fn->class_context();
     if (pc != NULL) { // is a class member function
       out('N');
       if (m_fn->is_const()) out('K');
       out_classname(pc);
       wuz_inside_class = true;
     } else { // may well be inside a namespace...
       Table* cntxt = m_fn->context();
       if (cntxt)
         wuz_inside_ns = out_namespace(cntxt->parent_context());
     }
     // the actual name
     char *mn = lookup_opname(gcc3_fns,name);
     if (mn != NULL) outs(mn);
     else 
         out_name(name);
     
     if (wuz_inside_class || wuz_inside_ns) out('E');
   }

  char *mangle(Function *pfn)  // GCC3Mangler
  {
   reset();
   m_no_namespace = true;
   m_t = t_void;
   m_fn = pfn;
   m_type_idx = -1;
   mArgTypeList.clear();
   mTypeObjList.clear();
   out_fun_name(pfn->name());

 // any arguments
   do_signature(m_fn->signature());

 // end output string
   end();
   return ptr();
 }

};

int match_exact_arg(Type t)
{
     ArgTypeList::iterator ali;
     for(ali = mArgTypeList.begin(); ali != mArgTypeList.end(); ++ali)
         if (t == ali->m_t) return ali->m_arg_idx;
     return NOT_FOUND;
}

int match_type_arg(Type& t)
{
     void *pt;
     if (t.is_class()) pt = t.as_class(); else
     if (t.is_enum()) pt = t.as_enum();
     else return NOT_FOUND;
     TypeObjList::iterator ali;
     for (ali = mTypeObjList.begin(); ali != mTypeObjList.end(); ++ali)
       if (ali->m_pt == pt) { // a class or enum has been repeated!
	     int idx = ali->m_type_idx;
         Type at = ali->m_t;
         // we must allow for _partial_ matches, where this argument already has
         // some of the necessary qualifiers.
         if (t.is_const()) {
           if (at.is_const()) {
             t.strip_const();
             idx++;
            } else return idx; // t has more qualifiers
         }
         int ad = at.is_pointer() ? at.pointer_depth() : 0;
         int  d =  t.is_pointer() ?  t.pointer_depth() : 0;
         if (ad > 0 && d > 0 && ad > d) {
           for(int i = 0, n = ad - d; i < n; i++) {
              t.decr_pointer();
              idx++;
           }
         }
         if (at.is_reference() && t.is_reference()) {
            t.strip_reference();
            idx++;
         }                
	     return idx;
       }
     return NOT_FOUND;
}

static MSMangler ms_mangler;
static GCC2Mangler gcc2_mangler;
static GCC3Mangler gcc3_mangler;

char *Mangle::microsoft(Function *pf)
{
  return ms_mangler.mangle(pf);
}

char *Mangle::GCC2(Function *pf)
{
  return gcc2_mangler.mangle(pf);
}

char *Mangle::GCC3(Function *pf)
{
  return gcc3_mangler.mangle(pf);
}

char *i2a(int i)
{
     static char buff[15];
     sprintf(buff,"%d",i);
     return buff;
}

char *i2ax(int i)
{
     static char buff[15];
     sprintf(buff,"%X",i);
     return buff;
}

char *lookup_opname(OpNames *popn, const char *n)
{
  for(; popn->cname != NULL; popn++) 
    if (strcmp(popn->cname,n)==0) return popn->mname;
  return NULL;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -