Changeset 122

Show
Ignore:
Timestamp:
01/19/06 02:43:39 (3 years ago)
Author:
Don Clugston
Message:

meta: added some compile-time name demangling to qualifiedname. Includes what I believe is the correct algorithm for demangling template names.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/meta/qualifiedname.d

    r118 r122  
    2828   .. (typeof(&outer!(A)).mangleof.length - pointerendlength-1)]; 
    2929} 
     30 
     31// ======================================================= 
     32//  Now some functions to pull the qualified name apart 
     33// ======================================================= 
     34private import meta.conv; 
     35private import meta.ctype; 
     36 
     37 
     38template demangleIsTemplate(char [] str) 
     39{ 
     40   static if (str.length>2) { 
     41      static if (str[0]=='_' && str[1]=='_' && str[2]=='T') { 
     42          const bool demangleIsTemplate = true; 
     43        } else { 
     44           const bool demangleIsTemplate = false; 
     45        } 
     46   } else { 
     47          const bool demangleIsTemplate = true; 
     48   } 
     49} 
     50 
     51// It could be a template 
     52template demanglesubstring(char [] str) 
     53{ 
     54 
     55  static if (demangleIsTemplate!(str)) { 
     56     const char [] demanglesubstring = convertToDotName!(str[3..(str.length)]) ~  
     57     "!(" 
     58      ~ demangleTemplateParamList!(getDotNameTail!(str[3..(str.length)])) 
     59~ ")"; 
     60  } else  
     61  const char [] demanglesubstring = str; 
     62} 
     63 
     64template demangleTemplateParamList(char [] str, char[] commastr = "") 
     65{ 
     66  static if (str[0]=='Z') { 
     67     const char [] demangleTemplateParamList = ""; 
     68  } else static if (str[0]=='T') { 
     69     const char [] demangleTemplateParamList =  commastr ~ demangleType!(str[1..(str.length)]) ~ .demangleTemplateParamList!(getTypeTail!(str[1..(str.length)]), ", "); 
     70  } else static assert(0); 
     71} 
     72 
     73 
     74 
     75// (length)head tail 
     76// Gets the part of the string. 
     77template demanglegethead(char [] str) 
     78{ 
     79  static if (str.length<=10 || !isdigit!( (str[1]) ) ) { 
     80     const char [] demanglegethead = str[ 
     81     1..(str[0]-'0' + 1)]; 
     82  } else static if (str.length<=100 || !isdigit!( (str[2]) )) { 
     83     const char [] demanglegethead = str[2..((str[0]-'0')*10 + str[1]-'0'+ 2)]; 
     84  } else { 
     85     const char [] demanglegethead =  
     86        str[3..((str[0]-'0')*100 + (str[1]-'0')*10 + str[0]-'0' + 3)]; 
     87  } 
     88} 
     89 
     90template demanglegettail(char [] str) 
     91{ 
     92   static if (str.length<=10 || !isdigit!( (str[1]) ) ) { 
     93     const char [] demanglegettail = str[(str[0]-'0'+1) .. str.length]; 
     94  } else static if (str.length<=100 || !isdigit!( (str[2]) )) { 
     95     const char [] demanglegettail = str[((str[0]-'0')*10 + str[1]-'0'+2)..str.length]; 
     96  } else { 
     97     const char [] demanglegettail =  
     98        str[((str[0]-'0')*100 + (str[1]-'0')*10 + str[0]-'0' + 3)..str.length]; 
     99  } 
     100} 
     101 
     102 
     103template convertToDotName(char [] str, char [] dotchar="") 
     104{ 
     105    static if(str.length == 0) { 
     106        const char [] convertToDotName=""; 
     107    } else static if (isdigit!((str[0]))) { 
     108        const char [] convertToDotName = dotchar ~ demanglesubstring!(demanglegethead!(str)) ~ .convertToDotName!(demanglegettail!(str), "."); 
     109  } 
     110  else const char [] convertToDotName=""; 
     111} 
     112 
     113template getDotNameTail(char [] str) 
     114{ 
     115    static if(str.length == 0) { 
     116        const char [] getDotNameTail=""; 
     117    } else static if (isdigit!((str[0]))) { 
     118        const char [] getDotNameTail = .getDotNameTail!(demanglegettail!(str)); 
     119  } else const char [] getDotNameTail = str; 
     120} 
     121 
     122// qualifiednameof!() can return one of two things: 
     123// (a) a type; (class, struct, typedef, enum) OR 
     124// (b) a static entity (function, variable, module, template). 
     125 
     126 
     127// Given a fully qualifed name, which is a type (ie, str[0] == 'T') 
     128// returns a text string describing the type 
     129template demangleClassifyType(char [] str) 
     130{ 
     131  static if (str[1] == 'C')  
     132        const char [] demangleClassifyType = "class  "; 
     133  else static if (str[1]=='S') 
     134        const char [] demangleClassifyType = "struct "; 
     135  else static if (str[1]=='T') 
     136        const char [] demangleClassifyType = "typedef"; 
     137  else static if (str[1]=='E') 
     138        const char [] demangleClassifyType = "enum   "; 
     139  else const char [] demangleClassifyType = "unknown[ " ~ str ~ " ]"; 
     140} 
     141 
     142template demangleSimpleType(char [] str) 
     143{ 
     144  static if (str[0]=='i') const char [] demangleSimpleType="int"; 
     145  else static if (str[0]=='e') const char [] demangleSimpleType="real"; 
     146  else static if (str[0]=='v') const char [] demangleSimpleType="void"; 
     147  else static if (str[0]=='k') const char [] demangleSimpleType="uint"; 
     148//  else static if (str[0]=='j') const char [] demangleSimpleType="?k?"; 
     149  else const char [] demangleSimpleType=" ?[" ~ str ~ "] "; 
     150} 
     151 
     152template getParamListTail(char [] str) 
     153{ 
     154 static if (str[0]=='Z') { 
     155   const char [] getParamListTail=getTypeTail!(str[1..(str.length)]); 
     156 } else { 
     157    const char [] getParamListTail = getTypeTail!(str); 
     158 } 
     159} 
     160 
     161// where str[0] is a type, returns the part of str which was not consumed 
     162template getTypeTail(char [] str) 
     163{ 
     164  static if(str[0]=='C' || str[0]=='S' || str[0]=='T' || str[0]=='E') { 
     165     const char [] getTypeTail = getDotNameTail!(str[1..(str.length)]); 
     166  } else static if (str[0]=='P') { 
     167   const char [] getTypeTail = .getTypeTail!(str[1..(str.length)]); 
     168  } else static if (str[0]=='F') { 
     169  const char [] getTypeTail = getParamListTail!(str[1..(str.length)]);  
     170  } else const char [] getTypeTail = str[1..(str.length)]; 
     171} 
     172 
     173template demangleReturnValue(char [] str) 
     174{ 
     175  static if (str.length<2) { 
     176   const char[] demangleReturnValue = "(no return)"; 
     177  } else 
     178  static if (str[0]=='Z') const char[] demangleReturnValue = demangleType!(str[1..(str.length)]); 
     179  else const char [] demangleReturnValue = .demangleReturnValue!(getTypeTail!(str)); 
     180} 
     181 
     182template demangleParamList(char [] str, char[] commastr = "") 
     183{ 
     184  static if (str[0]=='Z') { 
     185     const char [] demangleParamList = ""; 
     186  } else { 
     187     const char [] demangleParamList = commastr ~ demangleType!(str) ~ .demangleParamList!(getTypeTail!(str), ","); 
     188  } 
     189} 
     190 
     191template demangleType(char [] str) 
     192{ 
     193  static if (str[0] == 'C')  
     194        const char [] demangleType = "class " ~ convertToDotName!(str[1..(str.length)]); 
     195  else static if (str[0]=='S') 
     196        const char [] demangleType = "struct " ~ convertToDotName!(str[1..(str.length)]); 
     197  else static if (str[0]=='T') 
     198        const char [] demangleType = "typedef " ~ convertToDotName!(str[1..(str.length)]); 
     199  else static if (str[0]=='E') 
     200        const char [] demangleType = "enum " ~ convertToDotName!(str[1..(str.length)]); 
     201  else static if (str[0]=='F') 
     202        const char [] demangleType = demangleReturnValue!(str[1..(str.length)]) ~ " function (" 
     203        ~ demangleParamList!(str[1..(str.length)]) ~ ")"; 
     204  else static if (str[0]=='P') 
     205        const char [] demangleType = "*" ~ .demangleType!(str[1..(str.length)]); 
     206  else const char [] demangleType = demangleSimpleType!(str); 
     207} 
     208 
     209 
     210template demangleStatic(char [] str) 
     211{ 
     212   static if (str[0]=='_' && str[1]=='D') { 
     213      const char [] demangleStatic =  
     214      demangleType!( 
     215      getDotNameTail!(str[2..(str.length)])) ~ "  " 
     216       ~ convertToDotName!(str[2..(str.length)]); 
     217   } else static if (isdigit!( (str[0]) ) ) { 
     218     const char [] demangleStatic = convertToDotName!(str); 
     219   } else const char [] demangleStatic = " No type info: " ~ str; 
     220} 
     221 
     222template demangle(char [] str) 
     223{ 
     224  static if (str[0] == 'T') { 
     225    const char [] demangle =  demangleType!(str[1..(str.length)]); 
     226  } else static if (str[0]=='S') { 
     227      const char [] demangle = demangleStatic!(demanglegethead!(str[1..(str.length)]));  
     228      /+ 
     229      // It seems this is always the full length 
     230       ~ "--" 
     231    ~ demanglegettail!(qualifiednameof!(A)[1..(qualifiednameof!(A).length)]); 
     232    +/ 
     233   } else { 
     234     pragma(msg, "Unknown type " ~ str);      
     235     static assert(0); 
     236   } 
     237} 
  • trunk/meta/qualtest.d

    r118 r122  
    11import meta.qualifiedname; 
    2 import meta.conv; 
    3 import meta.strhacks; 
    4 import meta.ctype; 
    52 
    63 
    7 template ConvertToDotName(char [] str, char [] dotchar=""
     4template describe(alias A
    85{ 
    9     static if(strlen!(str) == 0) { 
    10         const char [] ConvertToDotName=""; 
    11     } else static if (isdigit!((str[0]))) { 
    12      static if (atoi!(str)>=100) { 
    13         // This is a possible bug in the name mangling algorithm? 
    14         // I think it should be putting a "__T" before the number. 
    15         const char [] ConvertToDotName = "(Template) " ~ .ConvertToDotName!(str[2..(str.length)]); 
    16         
    17      } else  static if (atoi!(str)>=10) { 
    18         const char [] ConvertToDotName = dotchar 
    19          ~ str[2.. (atoi!(str)+2)] 
    20         ~ .ConvertToDotName!(str[(2+atoi!(str))..(str.length)], "."); 
    21 } else  { 
    22         const char [] ConvertToDotName =  
    23         dotchar ~ str[1.. (atoi!(str)+1)] //~ str[(1+atoi!(str))..(str.length)]; 
    24         ~ .ConvertToDotName!(str[(1+atoi!(str))..(str.length)], "."); 
     6  const char [] describe = demangle!(qualifiednameof!(A)); 
    257} 
    26   } else const char [] ConvertToDotName="  (and type is: " ~ str ~ ")"; 
    27 
     8 
     9// ----------------------------------- 
     10 
    2811 
    2912class HeresAClass 
     
    4023HeresAClass anInstance; 
    4124 
    42 template ThisIsATemplate (A
     25template ThisIsATemplate (A, B
    4326{ 
    4427  int something; 
    45 } 
    46  
    47 template describe(alias A) 
    48 { 
    49   static if (qualifiednameof!(A)[0] == 'T') { 
    50      static if (qualifiednameof!(A)[1] == 'C') { 
    51      const char [] describe = "Class:   " ~ ConvertToDotName!(qualifiednameof!(A)[2..(qualifiednameof!(A).length)]); 
    52      } else static if (qualifiednameof!(A)[1] == 'S') { 
    53      const char [] describe = "Struct:  " ~ ConvertToDotName!(qualifiednameof!(A)[2..(qualifiednameof!(A).length)]); 
    54      } else static if (qualifiednameof!(A)[1] == 'T') { 
    55      const char [] describe = "Typedef: " ~ ConvertToDotName!(qualifiednameof!(A)[2..(qualifiednameof!(A).length)]); 
    56      } else static if (qualifiednameof!(A)[1] == 'E') { 
    57      const char [] describe = "Enum:    " ~ ConvertToDotName!(qualifiednameof!(A)[2..(qualifiednameof!(A).length)]); 
    58      } else { 
    59           const char [] describe = "?Unknown: " ~ qualifiednameof!(A)[1..(qualifiednameof!(A).length)]; 
    60           } 
    61  
    62   } else { // starts with 'S'... 
    63     static if (qualifiednameof!(A)[3]=='_') { 
    64     const char [] describe = "D external: " ~ ConvertToDotName!(qualifiednameof!(A)[5..(qualifiednameof!(A).length)]); 
    65     } else { 
    66       const char [] describe = "Special: " ~ ConvertToDotName!(qualifiednameof!(A)[1..(qualifiednameof!(A).length)]); // ~ " -- " ~ (A.mangleof); 
    67       } 
    68    } 
    6928} 
    7029 
     
    7231extern (C) real aCFunction(int a, real b) { return b; } 
    7332 
     33typedef real function(int, char []) FuncTypedef; 
    7434typedef HeresAClass TypedefClass; 
     35 
     36real function (void function(int) f) FuncFuncPtr; 
     37typedef typeof(ThisIsATemplate!(real, int)) TemplateTypedef; 
    7538 
    7639enum   HeresAnEnum { Val1, Val2, Val3 }; 
     
    8447pragma(msg, describe!(HeresAnEnum)); 
    8548pragma(msg, describe!(anInstance.AndAnInnerStruct)); 
     49pragma(msg, describe!(FuncTypedef)); 
     50pragma(msg, describe!(TemplateTypedef)); 
    8651 
    87 pragma(msg, \n "* With D linkage, the type is at the end of the name" \n); 
     52pragma(msg, \n "* Some items With D linkage" \n); 
    8853 
    8954pragma(msg, describe!(aStaticFunction)); 
     
    9257pragma(msg, describe!(anInstance)); 
    9358pragma(msg, describe!(someExternalInt)); 
     59pragma(msg, describe!(FuncFuncPtr)); 
    9460 
    9561pragma(msg, \n "* Special cases" \n); 
     
    9864pragma(msg, describe!(aWindowsFunction)); 
    9965pragma(msg, describe!(ThisIsATemplate)); 
    100 pragma(msg, describe!(ThisIsATemplate!(int))); 
     66pragma(msg, describe!(ThisIsATemplate!(int, uint))); 
     67pragma(msg, describe!(ThisIsATemplate!(FuncTypedef, uint))); 
    10168 
    102  
    103 /+ 
    104 pragma(msg, qualifiednameof!(HeresAClass)); 
    105 pragma(msg, qualifiednameof!(HeresAClass.AndAnInnerStruct)); 
    106 pragma(msg, qualifiednameof!(TypedefClass)); 
    107  
    108 pragma(msg, \n); 
    109  
    110 pragma(msg, qualifiednameof!(aStaticFunction)); 
    111 pragma(msg, qualifiednameof!(HeresAClass.MemberFunc)); 
    112  
    113 pragma(msg, qualifiednameof!(anInstance)); 
    114 pragma(msg, qualifiednameof!(someExternalInt)); 
    115  
    116  
    117 pragma(msg, qualifiednameof!(ThisIsATemplate)); 
    118 pragma(msg, qualifiednameof!(ThisIsATemplate!(int))); 
    119 +/ 
     69pragma(msg, describe!(qualtest));