Changeset 210

Show
Ignore:
Timestamp:
07/06/06 15:25:30 (2 years ago)
Author:
Don Clugston
Message:

Refactoring nameof and demangle, to make it closer to library standard.

Files:

Legend:

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

    r209 r210  
    44 */ 
    55  
    6 /* Implementation is via pairs of metafunctions: 
     6module meta.demangle; 
     7private import meta.ctype; 
     8/* 
     9 Implementation is via pairs of metafunctions: 
    710 a 'demangle' metafunction, which returns a const char [], 
    811 and a 'Consumed' metafunction, which returns an integer, the number of characters which 
     
    1013*/ 
    1114 
    12 module meta.demangle; 
    13 private import meta.ctype; 
    14  
     15/***************************************** 
     16 * How should the name be displayed? 
     17 */ 
    1518enum MangledNameType 
    1619{ 
    17     PrettyName, 
    18     QualifiedName, 
    19     SymbolName 
    20 } 
    21  
    22 /*************************** 
     20    PrettyName,    // With full type information 
     21    QualifiedName, // No type information, just identifiers seperated by dots 
     22    SymbolName     // Only the ultimate identifier 
     23} 
     24 
     25/***************************************** 
    2326 * Pretty-prints a mangled type string. 
    2427 */ 
    2528template demangleType(char[] str, MangledNameType wantQualifiedNames = MangledNameType.PrettyName) 
    2629{ 
    27    static if (wantQualifiedNames != MangledNameType.PrettyName) { 
    28        // Deal with symbolnameof!(), qualifiednameof!(). 
    29        static if (str[0]=='C' || str[0]=='S' || str[0]=='E' || str[0]=='T') 
    30            const char [] demangleType = prettyLname!(str[1..$], wantQualifiedNames); 
    31        else static assert(0, "Demangle error: type '" ~ str ~ "' does not contain a qualified name"); 
    32    } else static if (str[0] == 'A') // dynamic array 
     30    static if (wantQualifiedNames != MangledNameType.PrettyName) { 
     31        // Deal with symbolnameof!(), qualifiednameof!(). 
     32        static if (str[0]=='C' || str[0]=='S' || str[0]=='E' || str[0]=='T') 
     33            const char [] demangleType = prettyLname!(str[1..$], wantQualifiedNames); 
     34        else static assert(0, "Demangle error: type '" ~ str ~ "' does not contain a qualified name"); 
     35    } else static if (str[0] == 'A') // dynamic array 
    3336        const char [] demangleType = demangleType!(str[1..$], wantQualifiedNames) ~ "[]"; 
    3437    else static if (str[0] == 'H')   // associative array 
    3538        const char [] demangleType  
    36            = demangleType!(str[1+demangleTypeConsumed!(str[1..$])..$], wantQualifiedNames)  
    37            ~ "[" ~ demangleType!(str[1..1+(demangleTypeConsumed!(str[1..$]))], wantQualifiedNames) ~ "]"; 
     39            = demangleType!(str[1+demangleTypeConsumed!(str[1..$])..$], wantQualifiedNames)  
     40            ~ "[" ~ demangleType!(str[1..1+(demangleTypeConsumed!(str[1..$]))], wantQualifiedNames) ~ "]"; 
    3841    else static if (str[0] == 'G') // static array 
    3942        const char [] demangleType 
    40            = demangleType!(str[1+countLeadingDigits!(str[1..$])..$], wantQualifiedNames)  
    41            ~ "[" ~ str[1..1+countLeadingDigits!(str[1..$]) ] ~ "]"; 
     43            = demangleType!(str[1+countLeadingDigits!(str[1..$])..$], wantQualifiedNames)  
     44            ~ "[" ~ str[1..1+countLeadingDigits!(str[1..$]) ] ~ "]"; 
    4245    else static if (str[0]=='C') 
    43            const char [] demangleType = "class " ~ prettyLname!(str[1..$], wantQualifiedNames); 
     46        const char [] demangleType = "class " ~ prettyLname!(str[1..$], wantQualifiedNames); 
    4447    else static if (str[0]=='S') 
    4548        const char [] demangleType = "struct " ~ prettyLname!(str[1..$], wantQualifiedNames);  
     
    4952        const char [] demangleType = "typedef " ~ prettyLname!(str[1..$], wantQualifiedNames);  
    5053    else static if (str[0]=='D' && str.length>2 && isMangledFunction!(( str[1] )) ) // delegate 
    51        const char [] demangleType = demangleFunctionOrDelegate!(str[1..$], "delegate ", wantQualifiedNames); 
     54        const char [] demangleType = demangleFunctionOrDelegate!(str[1..$], "delegate ", wantQualifiedNames); 
    5255    else static if (str[0]=='P' && str.length>2 && isMangledFunction!(( str[1] )) ) // function pointer 
    53        const char [] demangleType = demangleFunctionOrDelegate!(str[1..$], "function ", wantQualifiedNames); 
     56        const char [] demangleType = demangleFunctionOrDelegate!(str[1..$], "function ", wantQualifiedNames); 
    5457    else static if (str[0]=='P') // only after we've dealt with function pointers 
    5558        const char [] demangleType = demangleType!(str[1..$], wantQualifiedNames) ~ "*"; 
    5659    else static if (str[0]=='F') 
    57        const char [] demangleType = demangleFunctionOrDelegate!(str, "", wantQualifiedNames); 
     60        const char [] demangleType = demangleFunctionOrDelegate!(str, "", wantQualifiedNames); 
    5861    else const char [] demangleType = demangleBasicType!(str);   
    5962} 
     
    103106    else static if (str[0]=='H') 
    104107        const int demangleTypeConsumed = 1 + demangleTypeConsumed!(str[1..$])  
    105            + demangleTypeConsumed!(str[1+demangleTypeConsumed!(str[1..$])..$]); 
     108            + demangleTypeConsumed!(str[1+demangleTypeConsumed!(str[1..$])..$]); 
    106109    else static if (str[0]=='G') 
    107110        const int demangleTypeConsumed = 1 + countLeadingDigits!(str[1..$]) 
     
    112115        const int demangleTypeConsumed = 1 + demangleTypeConsumed!(str[1..$]);      
    113116    else static if (str[0]=='C' || str[0]=='S' || str[0]=='E' || str[0]=='T') 
    114         const int demangleTypeConsumed = 1 + getDotNameConsumed!(str[1..$]); 
    115     else static if (str[0]=='F') { 
    116         static assert(str.length>1); 
     117        const int demangleTypeConsumed = 1 + getQualifiedNameConsumed!(str[1..$]); 
     118    else static if (str[0]=='F' && str.length>1) 
    117119        const int demangleTypeConsumed = 1 + demangleParamListAndRetValConsumed!(str[1..$]);      
    118     }else // it's a Basic Type 
    119        const int demangleTypeConsumed = 1; 
     120    else // it's a Basic Type 
     121        const int demangleTypeConsumed = 1; 
    120122} 
    121123 
     
    154156template pretty_Dname(char [] str, int dotnameconsumed, MangledNameType wantQualifiedNames) 
    155157{ 
    156   static if ( isMangledFunction!( (str[2+dotnameconsumed]))) { 
    157     const char [] pretty_Dname = pretty_Dfunction!(str, dotnameconsumed, demangleParamListAndRetValConsumed!(str[3+dotnameconsumed..$]), wantQualifiedNames); 
    158   } else { 
    159     static if (wantQualifiedNames == MangledNameType.PrettyName) { 
    160         const char [] pretty_Dname =  
    161             demangleType!(str[2+dotnameconsumed..$], wantQualifiedNames) 
    162             ~ " " ~ getDotName!(str[2..$], wantQualifiedNames); 
     158    static if ( isMangledFunction!( (str[2+dotnameconsumed]))) { 
     159        const char [] pretty_Dname = pretty_Dfunction!(str, dotnameconsumed, 
     160            demangleParamListAndRetValConsumed!(str[3+dotnameconsumed..$]), wantQualifiedNames); 
    163161    } else { 
    164         const char [] pretty_Dname = getDotName!(str[2..$], wantQualifiedNames);         
    165     } 
    166   } 
     162        static if (wantQualifiedNames == MangledNameType.PrettyName) { 
     163            const char [] pretty_Dname =  
     164                demangleType!(str[2+dotnameconsumed..$], wantQualifiedNames) 
     165                ~ " " ~ getQualifiedName!(str[2..$], wantQualifiedNames); 
     166        } else { 
     167            const char [] pretty_Dname = getQualifiedName!(str[2..$], wantQualifiedNames);       
     168        } 
     169    } 
    167170} 
    168171 
    169172// Deal with the case where an Lname contains an embedded ("__D") function. 
    170173// Split into a seperate function because it's so complicated. 
    171 template pretty_Dfunction(char [] str, int dotnameconsumed, int paramlistconsumed, MangledNameType wantQualifiedNames) 
    172 
    173    static if (wantQualifiedNames == MangledNameType.PrettyName) { 
    174       const char [] pretty_Dfunction =  
    175             demangleFunctionOrDelegate!(str[2 + dotnameconsumed .. 3 + dotnameconsumed + paramlistconsumed], 
    176                 getDotName!(str[2..$], wantQualifiedNames), wantQualifiedNames) 
    177             ~ getQualifiedName!(str[3 + dotnameconsumed + paramlistconsumed .. $], wantQualifiedNames, "."); 
     174template pretty_Dfunction(char [] str, int dotnameconsumed, int paramlistconsumed, 
     175    MangledNameType wantQualifiedNames) 
     176
     177    static if (wantQualifiedNames == MangledNameType.PrettyName) { 
     178        const char [] pretty_Dfunction =  
     179            demangleFunctionOrDelegate!(str[2 + dotnameconsumed .. 3 + dotnameconsumed + paramlistconsumed], 
     180                getQualifiedName!(str[2..$], wantQualifiedNames), wantQualifiedNames) 
     181            ~ getQualifiedName!(str[3 + dotnameconsumed + paramlistconsumed .. $], wantQualifiedNames, "."); 
    178182    } else static if (wantQualifiedNames == MangledNameType.QualifiedName) { 
    179        // Qualified names     
    180        const char [] pretty_Dfunction = getDotName!(str[2..$], wantQualifiedNames) 
    181            ~ getQualifiedName!(str[3 + dotnameconsumed + paramlistconsumed .. $], wantQualifiedNames, "."); 
     183        // Qualified name     
     184        const char [] pretty_Dfunction = getQualifiedName!(str[2..$], wantQualifiedNames) 
     185            ~ getQualifiedName!(str[3 + dotnameconsumed + paramlistconsumed .. $], wantQualifiedNames, "."); 
    182186    } else {  // symbol name 
    183        static if (3 + dotnameconsumed + paramlistconsumed == str.length) 
    184            const char [] pretty_Dfunction = getDotName!(str[2..$], wantQualifiedNames); 
    185        else const char [] pretty_Dfunction = getQualifiedName!( 
    186            str[3 + dotnameconsumed + paramlistconsumed .. $], wantQualifiedNames); 
    187    
     187        static if (3 + dotnameconsumed + paramlistconsumed == str.length) 
     188            const char [] pretty_Dfunction = getQualifiedName!(str[2..$], wantQualifiedNames); 
     189        else const char [] pretty_Dfunction = getQualifiedName!( 
     190            str[3 + dotnameconsumed + paramlistconsumed .. $], wantQualifiedNames); 
     191   
    188192 } 
    189193 
     
    191195template get_DnameConsumed(char [] str) 
    192196{ 
    193    const int get_DnameConsumed = 2 + getDotNameConsumed!(str[2..$])  
    194            + demangleTypeConsumed!(str[2+getDotNameConsumed!(str[2..$])..$]); 
     197    const int get_DnameConsumed = 2 + getQualifiedNameConsumed!(str[2..$])  
     198        + demangleTypeConsumed!(str[2+getQualifedNameConsumed!(str[2..$])..$]); 
    195199} 
    196200 
     
    199203template prettyLname(char [] str, MangledNameType wantQualifiedNames) 
    200204{ 
    201     static if (str.length>3 && str[0..3] == "__T") // Template instance name 
    202         static if (wantQualifiedNames == MangledNameType.PrettyName) { 
    203             const char [] prettyLname = 
    204                 prettyLname!(str[3..$], wantQualifiedNames) ~ "!(" 
    205                 ~ prettyTemplateArgList!(str[3+getDotNameConsumed!(str[3..$])..$], wantQualifiedNames)  ~ ")"; 
    206         } else { 
    207             const char [] prettyLname = 
    208                 prettyLname!(str[3..$], wantQualifiedNames); 
    209         } 
    210     else static if (str.length>2 && str[0..2] == "_D") { 
    211         const char [] prettyLname = pretty_Dname!(str, getDotNameConsumed!(str[2..$]), wantQualifiedNames); 
    212     } else static if ( isdigit!( (str[0]) ) )  
    213         const char [] prettyLname = getDotName!(str[0..getDotNameConsumed!(str)], wantQualifiedNames); 
    214     else const char [] prettyLname = str; 
     205    static if (str.length>3 && str[0..3] == "__T") // Template instance name 
     206        static if (wantQualifiedNames == MangledNameType.PrettyName) { 
     207            const char [] prettyLname = 
     208                prettyLname!(str[3..$], wantQualifiedNames) ~ "!(" 
     209                ~ prettyTemplateArgList!(str[3+getQualifiedNameConsumed!(str[3..$])..$], wantQualifiedNames) 
     210                ~ ")"; 
     211        } else { 
     212            const char [] prettyLname = 
     213                prettyLname!(str[3..$], wantQualifiedNames); 
     214        } 
     215    else static if (str.length>2 && str[0..2] == "_D") { 
     216        const char [] prettyLname = pretty_Dname!(str, getQualifiedNameConsumed!(str[2..$]), wantQualifiedNames); 
     217    } else static if ( isdigit!( (str[0]) ) )  
     218        const char [] prettyLname = getQualifiedName!(str[0..getQualifiedNameConsumed!(str)], wantQualifiedNames); 
     219    else const char [] prettyLname = str; 
    215220} 
    216221 
     
    220225{ 
    221226    static if (str.length==0) 
    222        const int getLnameConsumed=0; 
     227        const int getLnameConsumed=0; 
    223228    else static if (str.length<=10 || !isdigit!( (str[1]) ) ) 
    224229        const int getLnameConsumed = 1 + str[0]-'0'; 
     
    226231        const int getLnameConsumed = (str[0]-'0')*10 + str[1]-'0' + 2; 
    227232    else 
    228        const int getLnameConsumed = (str[0]-'0')*100 + (str[1]-'0')*10 + str[0]-'0' + 3; 
     233        const int getLnameConsumed = (str[0]-'0')*100 + (str[1]-'0')*10 + str[0]-'0' + 3; 
    229234} 
    230235 
    231236template getQualifiedName(char [] str, MangledNameType wantQualifiedNames, char [] dotstr = "") 
    232237{ 
    233 // main() is a special case, it isn't qualified by a module. 
    234 //    static if (str.length>4 && dotstr="" && str[0..4] == "main") 
    235238    static if (str.length==0) const char [] getQualifiedName=""; 
     239    else static if (str.length>2 && str[0]=='_' && str[1]=='D') 
     240        const char [] getDotName = getQualifiedName!(str[2..$], wantQualifiedNames); 
    236241    else static if (isdigit!(( str[0] ))) { 
    237242        static if (str[getLnameConsumed!(str)..$].length>0) { 
    238            static if (wantQualifiedNames == MangledNameType.SymbolName) { 
    239                 static if (getLnameConsumed!(str)==str.length) { 
    240                     const char [] getQualifiedName = prettyLname!(getLname!(str), wantQualifiedNames); 
    241                 } else static if ( isdigit!(( str[getLnameConsumed!(str)] ))) { 
    242                     const char [] getQualifiedName = getQualifiedName!(str[getLnameConsumed!(str) .. $], wantQualifiedNames, ""); 
    243                 } else const char [] getQualifiedName = prettyLname!(getLname!(str), wantQualifiedNames); 
    244            } else { 
    245            // Qualified and pretty names 
    246             const char [] getQualifiedName = dotstr ~ prettyLname!(getLname!(str), wantQualifiedNames) 
    247                 ~ getQualifiedName!(str[getLnameConsumed!(str) .. $], wantQualifiedNames, "."); 
    248             } 
    249         } else const char [] getQualifiedName = dotstr ~ prettyLname!(getLname!(str), wantQualifiedNames); 
     243            static if (wantQualifiedNames == MangledNameType.SymbolName) { 
     244                static if (getLnameConsumed!(str)==str.length) { 
     245                    const char [] getQualifiedName = prettyLname!(getLname!(str), wantQualifiedNames); 
     246                } else static if ( isdigit!(( str[getLnameConsumed!(str)] ))) { 
     247                    const char [] getQualifiedName = 
     248                        getQualifiedName!(str[getLnameConsumed!(str) .. $], wantQualifiedNames, ""); 
     249                } else { 
     250                    const char [] getQualifiedName = prettyLname!(getLname!(str), wantQualifiedNames); 
     251                } 
     252            } else { 
     253                // Qualified and pretty names 
     254                const char [] getQualifiedName = dotstr 
     255                    ~ prettyLname!(getLname!(str), wantQualifiedNames) 
     256                    ~ getQualifiedName!(str[getLnameConsumed!(str) .. $], wantQualifiedNames, "."); 
     257            } 
     258        } else { 
     259            const char [] getQualifiedName = dotstr ~ prettyLname!(getLname!(str), wantQualifiedNames); 
     260        } 
    250261    } else const char [] getQualifiedName = ""; 
    251 //      static assert(0, "Demangle error, Unrecognized qualified name " ~ str); 
    252 
    253  
    254 template getDotName(char [] str, MangledNameType wantQualifiedNames) 
    255 
    256     static if (str.length>2 && str[0]=='_' && str[1]=='D') { 
    257         const char [] getDotName = getDotName!(str[2..$], wantQualifiedNames); 
    258     } else //static if (wantQualifiedNames != MangledNameType.SymbolName)  
    259         const char [] getDotName = getQualifiedName!(str, wantQualifiedNames); 
    260  //   else  const char [] getDotName = getSymbolName!(str); 
    261 
    262  
    263 // how much of the str is taken up with a qualified name? 
    264 template getDotNameConsumed (char [] str) 
    265 
    266     static if (str.length>1) { 
    267      static if ( isdigit!(( str[0] )) ) { 
    268         static if (getLnameConsumed!(str) <= str.length)          
    269             const int getDotNameConsumed = getLnameConsumed!(str) 
    270                 + getDotNameConsumed!(str[getLnameConsumed!(str) .. $]); 
    271          else const int getDotNameConsumed = str.length; 
    272     } else static if (str[0]=='_' && str[1]=='D') { 
    273         const int getDotNameConsumed = get_DnameConsumed!(str) 
    274             + getDotNameConsumed!(str[get_DnameConsumed!(str)..$]); 
    275         } 
    276     else const int getDotNameConsumed=0; 
    277     } else const int getDotNameConsumed=0; 
     262
     263 
     264// BUG: This isn't correct. It's making getQualifiedName() unnecessarily complicated. 
     265template getQualifiedNameConsumed (char [] str) 
     266
     267    static if (str.length>1 &&  isdigit!(( str[0] )) ) { 
     268        static if (getLnameConsumed!(str) <= str.length) { 
     269            const int getQualifiedNameConsumed = getLnameConsumed!(str) 
     270                + getQualifiedNameConsumed!(str[getLnameConsumed!(str) .. $]); 
     271        } else { 
     272            const int getQualifiedNameConsumed = str.length; 
     273        } 
     274    } else static if (str.length>1 && str[0]=='_' && str[1]=='D') { 
     275        const int getQualifiedNameConsumed = get_DnameConsumed!(str) 
     276            + getQualifiedNameConsumed!(str[get_DnameConsumed!(str)..$]); 
     277    } else const int getQualifiedNameConsumed=0; 
    278278} 
    279279 
     
    286286template demangleFunctionOrDelegate(char [] str, char [] funcOrDelegStr, MangledNameType wantQualifiedNames) 
    287287{ 
    288         const char [] demangleFunctionOrDelegate = demangleExtern!(( str[0] ))  
    289            ~ demangleReturnValue!(str[1..$], wantQualifiedNames) 
    290            ~ " " ~ funcOrDelegStr ~ "(" 
    291             ~ demangleParamList!(str[1..1+demangleParamListAndRetValConsumed!(str[1..$])], wantQualifiedNames) 
    292             ~ ")"; 
     288    const char [] demangleFunctionOrDelegate = demangleExtern!(( str[0] ))  
     289        ~ demangleReturnValue!(str[1..$], wantQualifiedNames) 
     290        ~ " " ~ funcOrDelegStr ~ "(" 
     291        ~ demangleParamList!(str[1..1+demangleParamListAndRetValConsumed!(str[1..$])], wantQualifiedNames) 
     292        ~ ")"; 
    293293} 
    294294 
     
    297297template demangleFunctionParamType(char[] str, MangledNameType wantQualifiedNames) 
    298298{ 
    299    static if (str[0]=='K') 
    300        const char [] demangleFunctionParamType = "inout " ~ demangleType!(str[1..$], wantQualifiedNames); 
    301    else static if (str[0]=='J') 
    302        const char [] demangleFunctionParamType = "out " ~ demangleType!(str[1..$], wantQualifiedNames); 
    303    else const char [] demangleFunctionParamType = demangleType!(str, wantQualifiedNames); 
     299    static if (str[0]=='K') 
     300        const char [] demangleFunctionParamType = "inout " ~ demangleType!(str[1..$], wantQualifiedNames); 
     301    else static if (str[0]=='J') 
     302        const char [] demangleFunctionParamType = "out " ~ demangleType!(str[1..$], wantQualifiedNames); 
     303    else const char [] demangleFunctionParamType = demangleType!(str, wantQualifiedNames); 
    304304} 
    305305 
     
    307307template demangleFunctionParamTypeConsumed(char[] str) 
    308308{ 
    309    static if (str[0]=='K' || str[0]=='J')  
    310        const int demangleFunctionParamTypeConsumed = 1 + demangleTypeConsumed!(str[1..$]); 
    311    else const int demangleFunctionParamTypeConsumed = demangleTypeConsumed!(str); 
     309    static if (str[0]=='K' || str[0]=='J')  
     310        const int demangleFunctionParamTypeConsumed = 1 + demangleTypeConsumed!(str[1..$]); 
     311    else const int demangleFunctionParamTypeConsumed = demangleTypeConsumed!(str); 
    312312} 
    313313 
     
    315315template isMangledFunction(char c) 
    316316{ 
    317    const bool isMangledFunction = (c=='F' || c=='U' || c=='W' || c=='V' || c=='R'); 
     317    const bool isMangledFunction = (c=='F' || c=='U' || c=='W' || c=='V' || c=='R'); 
    318318} 
    319319 
    320320template demangleExtern(char c) 
    321321{ 
    322    static if (c=='F') const char [] demangleExtern = ""; 
    323    else static if (c=='U') const char [] demangleExtern = "extern (C) "; 
    324    else static if (c=='W') const char [] demangleExtern = "extern (Windows) "; 
    325    else static if (c=='V') const char [] demangleExtern = "extern (Pascal) "; 
    326    else static if (c=='R') const char [] demangleExtern = "extern (C++) "; 
    327    else static assert(0, "Unrecognized extern function."); 
     322    static if (c=='F') const char [] demangleExtern = ""; 
     323    else static if (c=='U') const char [] demangleExtern = "extern (C) "; 
     324    else static if (c=='W') const char [] demangleExtern = "extern (Windows) "; 
     325    else static if (c=='V') const char [] demangleExtern = "extern (Pascal) "; 
     326    else static if (c=='R') const char [] demangleExtern = "extern (C++) "; 
     327    else static assert(0, "Unrecognized extern function."); 
    328328} 
    329329 
     
    333333{ 
    334334    static assert(str.length>=1, "Demangle error(Function): No return value found"); 
    335    static if (str[0]=='Z' || str[0]=='Y') 
     335    static if (str[0]=='Z' || str[0]=='Y') 
    336336        const char[] demangleReturnValue = demangleType!(str[1..$], wantQualifiedNames); 
    337337    else const char [] demangleReturnValue = demangleReturnValue!(str[demangleFunctionParamTypeConsumed!(str)..$], wantQualifiedNames); 
     
    346346        const char [] demangleParamList = commastr ~ "..."; 
    347347    else 
    348         const char [] demangleParamList =  commastr ~ demangleFunctionParamType!(str[0..demangleFunctionParamTypeConsumed!(str)], wantQualifiedNames) 
     348        const char [] demangleParamList =  commastr ~  
     349            demangleFunctionParamType!(str[0..demangleFunctionParamTypeConsumed!(str)], wantQualifiedNames) 
    349350            ~ demangleParamList!(str[demangleFunctionParamTypeConsumed!(str)..$], wantQualifiedNames, ", "); 
    350351} 
     
    393394    else static if (str[0]=='V') // value 
    394395        const char [] prettyTemplateArg =  
    395            demangleType!(str[1..1+demangleTypeConsumed!(str[1..$])], wantQualifiedNames) 
    396            ~ " = " ~ prettyValueArg!(str[1+demangleTypeConsumed!(str[1..$])..$]); 
     396            demangleType!(str[1..1+demangleTypeConsumed!(str[1..$])], wantQualifiedNames) 
     397            ~ " = " ~ prettyValueArg!(str[1+demangleTypeConsumed!(str[1..$])..$]); 
    397398    else static if (str[0]=='T') // type 
    398399        const char [] prettyTemplateArg = demangleType!(str[1..$], wantQualifiedNames); 
     
    406407    else static if (str[0]=='V') // value 
    407408        const int templateArgConsumed = 1 + demangleTypeConsumed!(str[1..$]) +  
    408            templateValueArgConsumed!(str[1+demangleTypeConsumed!(str[1..$])..$]); 
     409            templateValueArgConsumed!(str[1+demangleTypeConsumed!(str[1..$])..$]); 
    409410    else static if (str[0]=='T') // type 
    410411        const int templateArgConsumed = 1 + demangleTypeConsumed!(str[1..$]); 
     
    427428{ 
    428429    static assert(str.length>0, "No Z found at end of template argument list"); 
    429    static if (str[0]=='Z') 
     430    static if (str[0]=='Z') 
    430431        const int templateArgListConsumed = 1; 
    431432    else 
     
    449450 
    450451extern (Windows) { 
    451    typedef void function (double, long) WinFunc; 
     452    typedef void function (double, long) WinFunc; 
    452453} 
    453454extern (Pascal) { 
    454    typedef short[wchar] delegate (bool, ...) PascFunc; 
     455    typedef short[wchar] delegate (bool, ...) PascFunc; 
    455456} 
    456457extern (C) { 
    457    typedef dchar delegate () CFunc; 
     458    typedef dchar delegate () CFunc; 
    458459} 
    459460extern (C++) { 
    460    typedef cfloat function (wchar) CPPFunc; 
     461    typedef cfloat function (wchar) CPPFunc; 
    461462} 
    462463 
     
    471472template ComplexTemplate(real a, creal b) 
    472473{ 
    473    class ComplexTemplate {} 
     474    class ComplexTemplate {} 
    474475} 
    475476 
  • trunk/meta/nameof.d

    r209 r210  
    11/** 
    2  *   Given any D symbol (class, template, function, module name, 
    3  *   or non-local variable), convert it to a compile-time string literal, 
    4  *   optionally containing the fully qualified and decorated name.  
     2 *   Convert any D symbol or type to a human-readable string, at compile time. 
     3 * 
     4 *   Given any D symbol (class, template, function, module name, or non-local variable) 
     5 *   or any D type, convert it to a compile-time string literal, 
     6 *   optionally containing the fully qualified and decorated name. 
     7 * 
     8 *   Limitations (as of DMD 0.162): 
     9 *   1. Names of local variables cannot be determined, because they are not permitted 
     10 *      as template alias parameters. Technically, it's possible to determine the name by using 
     11 *      a mixin hack, but it's so ugly that it cannot be recommended. 
     12 *   2. The name mangling for symbols declared inside extern(Windows), extern(C) and extern(Pascal) 
     13 *      functions is inherently ambiguous, so such inner symbols are not always correctly displayed. 
    514 */ 
    615module meta.nameof; 
     
    2736    } 
    2837 
    29    // We will get the .mangleof for a pointer to this function pointer. 
    30    template rawmanglednameof(alias A) 
    31    
    32      const char [] rawmanglednameof  = 
    33                 typeof(&outer!(A)).mangleof; 
    34    
     38    // We will get the .mangleof for a pointer to this function pointer. 
     39    template rawmanglednameof(alias A) 
     40   
     41      const char [] rawmanglednameof  = 
     42                typeof(&outer!(A)).mangleof; 
     43   
    3544 
    3645// If the identifier is "MyIdentifier" and this module is "QualModule" 
     
    7180 
    7281 
    73 /** Like .mangleof, except that it works for an alias template parameter instead of a type. 
     82/** 
     83 * Like .mangleof, except that it works for an alias template parameter instead of a type. 
    7484 */ 
    7585template manglednameof(alias A) 
    7686{ 
    77    static if (rawmanglednameof!(A).length - pointerstartlength - pointerendlength <= 99+2) { 
    78        // the length of the template argument requires 2 byte
    79        const char [] manglednameof  = 
     87    static if (rawmanglednameof!(A).length - pointerstartlength <= 100 + 1) { 
     88        // the length of the template argument requires 2 character
     89        const char [] manglednameof  = 
    8090             rawmanglednameof!(A)[ pointerstartlength + 2 .. $ - pointerendlength]; 
    81    } else  
    82        const char [] manglednameof  = 
     91    } else  
     92        const char [] manglednameof  = 
    8393             rawmanglednameof!(A)[ pointerstartlength + 3 .. $ - pointerendlength]; 
    8494} 
    8595 
    86 // The symbol as it was declared (but fully qualified). 
    87 // example: "int mymodule.myclass.myfunc(uint, class otherclass)" 
     96/** 
     97 * The symbol as it was declared, but including full type qualification. 
     98 * 
     99 * example: "int mymodule.myclass.myfunc(uint, class otherclass)" 
     100 */ 
    88101template prettynameof(alias A) 
    89102{ 
     
    91104} 
    92105 
    93 /** The textual representation of a type 
     106/** Convert any D type to a human-readable string literal 
     107 * 
    94108 * example: "int function(double, char[])" 
    95109 */ 
     
    111125} 
    112126 
    113 /** Returns the unqualified name, as a single text string. 
     127/** 
     128 * Returns the unqualified name, as a single text string. 
    114129 * 
    115130 * eg. "myfunc" 
     
    121136 
    122137//---------------------------------------------- 
    123 //    Unit Tests 
     138//                Unit Tests 
    124139//---------------------------------------------- 
    125140 
     
    164179 
    165180static assert( prettynameof!(SomeInt) 
    166    == "enum " ~ THISFILE ~ ".SomeEnum " ~ THISFILE ~ ".SomeInt"); 
     181    == "enum " ~ THISFILE ~ ".SomeEnum " ~ THISFILE ~ ".SomeInt"); 
    167182static assert( qualifiednameof!(OuterClass) == THISFILE ~".OuterClass"); 
    168183static assert( symbolnameof!(SomeInt) == "SomeInt"); 
    169184 
    170185static assert( prettynameof!(inner!( MyInt!(68u) )) 
    171    ==  "class " ~ THISFILE ~ ".inner!(" ~ THISFILE ~ ".MyInt!(uint = 68)).inner"); 
    172 static assert( symbolnameof!(inner!( MyInt!(68u) ))    ==  "inner"); 
     186    ==  "class " ~ THISFILE ~ ".inner!(" ~ THISFILE ~ ".MyInt!(uint = 68)).inner"); 
     187static assert( symbolnameof!(inner!( MyInt!(68u) )) ==  "inner"); 
    173188static assert( prettynameof!(ClassTemplate!(OuterClass.SomeClass)) 
    174    == "class "~ THISFILE ~ ".ClassTemplate!(class "~ THISFILE ~ ".OuterClass.SomeClass).ClassTemplate"); 
    175 static assert( symbolnameof!(ClassTemplate!(OuterClass.SomeClass)) == "ClassTemplate"); 
     189    == "class "~ THISFILE ~ ".ClassTemplate!(class "~ THISFILE ~ ".OuterClass.SomeClass).ClassTemplate"); 
     190static assert( symbolnameof!(ClassTemplate!(OuterClass.SomeClass))  == "ClassTemplate"); 
    176191 
    177192// Extern(D) declarations have full type information. 
     
    184199// Extern(Windows) declarations contain no type information. 
    185200extern (Windows) { 
    186    extern int dog(); 
    187    extern int dig; 
     201    extern int dog(); 
     202    extern int dig; 
    188203} 
    189204 
     
    195210 
    196211extern (Windows) { 
    197 // "Gad! You think of everything." - Ned Seagoon 
    198 // "No! Sometimes I forget aardvarks." - Major Denis Bloodnok. 
    199212template aardvark(X) { 
    200    int aardvark(short goon) { 
    201        class wolf {} 
    202        static assert(prettynameof!(wolf)== "class extern (Windows) int " ~ THISFILE ~ ".aardvark!(struct "  
    203            ~ THISFILE ~ ".OuterClass).aardvark(short).wolf"); 
    204        static assert(qualifiednameof!(wolf)== THISFILE ~ ".aardvark.aardvark.wolf"); 
    205        static assert( symbolnameof!(wolf) == "wolf"); 
    206        return 3; 
    207        
    208    
     213    int aardvark(short goon) { 
     214        class wolf {} 
     215        static assert(prettynameof!(wolf)== "class extern (Windows) int " ~ THISFILE ~ ".aardvark!(struct "  
     216            ~ THISFILE ~ ".OuterClass).aardvark(short).wolf"); 
     217        static assert(qualifiednameof!(wolf)== THISFILE ~ ".aardvark.aardvark.wolf"); 
     218        static assert( symbolnameof!(wolf) == "wolf"); 
     219        return 3; 
     220       
     221   
    209222} 
    210223 
     
    214227// Corner case #2: template inside function. This is currently possible only with mixins. 
    215228template fox(B, ushort C) { 
    216    class fox {} 
     229    class fox {} 
    217230} 
    218231 
    219232void wolf() { 
    220        mixin fox!(cfloat, 21); 
    221        static assert(prettynameof!(fox)== "class void " ~ THISFILE ~ ".wolf().fox!(cfloat, int = 21).fox"); 
    222        static assert(qualifiednameof!(fox)== THISFILE ~ ".wolf.fox.fox"); 
    223        static assert(symbolnameof!(fox)== "fox"); 
    224 } 
    225  
    226 } 
     233        mixin fox!(cfloat, 21); 
     234        static assert(prettynameof!(fox)== "class void " ~ THISFILE ~ ".wolf().fox!(cfloat, int = 21).fox"); 
     235        static assert(qualifiednameof!(fox)== THISFILE ~ ".wolf.fox.fox"); 
     236        static assert(symbolnameof!(fox)== "fox"); 
     237} 
     238 
     239}