Ignore:
Timestamp:
Nov 8, 2023, 2:01:11 PM (8 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
3e4bf0d, f5ec35a
Parents:
790d835
Message:

Remove BaseSyntaxNode? and clean-up.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Demangle.cc

    r790d835 rc6b4432  
    2121#include "CodeGen/GenType.h"
    2222#include "CodeGen/OperatorTable.h"
    23 #include "Common/PassVisitor.h"
    2423#include "Common/utility.h"                                                             // isPrefix
    2524#include "Mangler.h"
    26 #include "SynTree/Type.h"
    27 #include "SynTree/Declaration.h"
    2825
    2926#define DEBUG
     
    3330#define PRINT(x) {}
    3431#endif
    35 
    36 namespace SymTab {
    37         namespace Mangler {
    38                 namespace {
    39                         struct StringView {
    40                         private:
    41                                 std::string str;
    42                                 size_t idx = 0;
    43                                 // typedef Type * (StringView::*parser)(Type::Qualifiers);
    44                                 typedef std::function<Type * (Type::Qualifiers)> parser;
    45                                 std::vector<std::pair<std::string, parser>> parsers;
    46                         public:
    47                                 StringView(const std::string & str);
    48 
    49                                 bool done() const { return idx >= str.size(); }
    50                                 char cur() const { assert(! done()); return str[idx]; }
    51 
    52                                 bool expect(char ch) { return str[idx++] == ch; }
    53                                 void next(size_t inc = 1) { idx += inc; }
    54 
    55                                 /// determines if `pref` is a prefix of `str`
    56                                 bool isPrefix(const std::string & pref);
    57                                 bool extractNumber(size_t & out);
    58                                 bool extractName(std::string & out);
    59                                 bool stripMangleName(std::string & name);
    60 
    61                                 Type * parseFunction(Type::Qualifiers tq);
    62                                 Type * parseTuple(Type::Qualifiers tq);
    63                                 Type * parseVoid(Type::Qualifiers tq);
    64                                 Type * parsePointer(Type::Qualifiers tq);
    65                                 Type * parseArray(Type::Qualifiers tq);
    66                                 Type * parseStruct(Type::Qualifiers tq);
    67                                 Type * parseUnion(Type::Qualifiers tq);
    68                                 Type * parseEnum(Type::Qualifiers tq);
    69                                 Type * parseType(Type::Qualifiers tq);
    70 
    71                                 Type * parseType();
    72                                 bool parse(std::string & name, Type *& type);
    73                         };
    74 
    75                         StringView::StringView(const std::string & str) : str(str) {
    76                                 // basic types
    77                                 for (size_t k = 0; k < BasicType::NUMBER_OF_BASIC_TYPES; ++k) {
    78                                         parsers.emplace_back(Encoding::basicTypes[k], [k](Type::Qualifiers tq) {
    79                                                 PRINT( std::cerr << "basic type: " << k << std::endl; )
    80                                                 return new BasicType(tq, (BasicType::Kind)k);
    81                                         });
    82                                 }
    83                                 // type variable types
    84                                 for (size_t k = 0; k < TypeDecl::NUMBER_OF_KINDS; ++k) {
    85                                         static const std::string typeVariableNames[] = { "DT", "DST", "OT", "FT", "TT", "ALT", };
    86                                         static_assert(
    87                                                 sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == TypeDecl::NUMBER_OF_KINDS,
    88                                                 "Each type variable kind should have a demangle name prefix"
    89                                         );
    90                                         parsers.emplace_back(Encoding::typeVariables[k], [k, this](Type::Qualifiers tq) -> TypeInstType * {
    91                                                 PRINT( std::cerr << "type variable type: " << k << std::endl; )
    92                                                 size_t N;
    93                                                 if (! extractNumber(N)) return nullptr;
    94                                                 return new TypeInstType(tq, toString(typeVariableNames[k], N), (TypeDecl::Kind)k != TypeDecl::Ftype);
    95                                         });
    96                                 }
    97                                 // everything else
    98                                 parsers.emplace_back(Encoding::void_t, [this](Type::Qualifiers tq) { return parseVoid(tq); });
    99                                 parsers.emplace_back(Encoding::function, [this](Type::Qualifiers tq) { return parseFunction(tq); });
    100                                 parsers.emplace_back(Encoding::pointer, [this](Type::Qualifiers tq) { return parsePointer(tq); });
    101                                 parsers.emplace_back(Encoding::array, [this](Type::Qualifiers tq) { return parseArray(tq); });
    102                                 parsers.emplace_back(Encoding::tuple, [this](Type::Qualifiers tq) { return parseTuple(tq); });
    103                                 parsers.emplace_back(Encoding::struct_t, [this](Type::Qualifiers tq) { return parseStruct(tq); });
    104                                 parsers.emplace_back(Encoding::union_t, [this](Type::Qualifiers tq) { return parseUnion(tq); });
    105                                 parsers.emplace_back(Encoding::enum_t, [this](Type::Qualifiers tq) { return parseEnum(tq); });
    106                                 parsers.emplace_back(Encoding::type, [this](Type::Qualifiers tq) { return parseType(tq); });
    107                                 parsers.emplace_back(Encoding::zero, [](Type::Qualifiers tq) { return new ZeroType(tq); });
    108                                 parsers.emplace_back(Encoding::one, [](Type::Qualifiers tq) { return new OneType(tq); });
    109                         }
    110 
    111                         bool StringView::extractNumber(size_t & out) {
    112                                 std::stringstream numss;
    113                                 if (idx >= str.size()) return false;
    114                                 while (isdigit(str[idx])) {
    115                                         numss << str[idx];
    116                                         ++idx;
    117                                         if (idx == str.size()) break;
    118                                 }
    119                                 if (! (numss >> out)) return false;
    120                                 PRINT( std::cerr << "extractNumber success: " << out << std::endl; )
    121                                 return true;
    122                         }
    123 
    124                         bool StringView::extractName(std::string & out) {
    125                                 size_t len;
    126                                 if (! extractNumber(len)) return false;
    127                                 if (idx+len > str.size()) return false;
    128                                 out = str.substr(idx, len);
    129                                 idx += len;
    130                                 PRINT( std::cerr << "extractName success: " << out << std::endl; )
    131                                 return true;
    132                         }
    133 
    134                         bool StringView::isPrefix(const std::string & pref) {
    135                                 // if ( pref.size() > str.size()-idx ) return false;
    136                                 // auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) );
    137                                 // if (its.first == pref.end()) {
    138                                 //      idx += pref.size();
    139                                 //      return true;
    140                                 // }
    141 
    142                                 // This update is untested because there are no tests for this code.
    143                                 if ( ::isPrefix( str, pref, idx ) ) {
    144                                         idx += pref.size();
    145                                         return true;
    146                                 }
    147                                 return false;
    148                         }
    149 
    150                         // strips __NAME__cfa__TYPE_N, where N is [0-9]+: returns str is a match is found, returns empty string otherwise
    151                         bool StringView::stripMangleName(std::string & name) {
    152                                 PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; )
    153                                 if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix
    154                                 if ( ! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back() ) ) return false;
    155 
    156                                 // get name
    157                                 if (! extractName(name)) return false;
    158 
    159                                 // find bounds for type
    160                                 PRINT( std::cerr << idx << " " << str.size() << std::endl; )
    161                                 PRINT( std::cerr << "[");
    162                                 while (isdigit(str.back())) {
    163                                         PRINT(std::cerr << ".");
    164                                         str.pop_back();
    165                                         if (str.size() <= idx) return false;
    166                                 }
    167                                 PRINT( std::cerr << "]" << std::endl );
    168                                 if (str.back() != '_') return false;
    169                                 str.pop_back();
    170                                 PRINT( std::cerr << str.size() << " " << name << " " << str.substr(idx) << std::endl; )
    171                                 return str.size() > idx;
    172                         }
    173 
    174                         Type * StringView::parseFunction(Type::Qualifiers tq) {
    175                                 PRINT( std::cerr << "function..." << std::endl; )
    176                                 if (done()) return nullptr;
    177                                 FunctionType * ftype = new FunctionType( tq, false );
    178                                 std::unique_ptr<Type> manager(ftype);
    179                                 Type * retVal = parseType();
    180                                 if (! retVal) return nullptr;
    181                                 PRINT( std::cerr << "with return type: " << retVal << std::endl; )
    182                                 ftype->returnVals.push_back(ObjectDecl::newObject("", retVal, nullptr));
    183                                 if (done() || ! expect('_')) return nullptr;
    184                                 while (! done()) {
    185                                         PRINT( std::cerr << "got ch: " << cur() << std::endl; )
    186                                         if (cur() == '_') return manager.release();
    187                                         Type * param = parseType();
    188                                         if (! param) return nullptr;
    189                                         PRINT( std::cerr << "with parameter : " << param << std::endl; )
    190                                         ftype->parameters.push_back(ObjectDecl::newObject("", param, nullptr));
    191                                 }
    192                                 return nullptr;
    193                         }
    194 
    195                         Type * StringView::parseTuple(Type::Qualifiers tq) {
    196                                 PRINT( std::cerr << "tuple..." << std::endl; )
    197                                 std::list< Type * > types;
    198                                 size_t ncomponents;
    199                                 if (! extractNumber(ncomponents)) return nullptr;
    200                                 for (size_t i = 0; i < ncomponents; ++i) {
    201                                         // TODO: delete all on return
    202                                         if (done()) return nullptr;
    203                                         PRINT( std::cerr << "got ch: " << cur() << std::endl; )
    204                                         Type * t = parseType();
    205                                         if (! t) return nullptr;
    206                                         PRINT( std::cerr << "with type : " << t << std::endl; )
    207                                         types.push_back(t);
    208                                 }
    209                                 return new TupleType( tq, types );
    210                         }
    211 
    212                         Type * StringView::parseVoid(Type::Qualifiers tq) {
    213                                 return new VoidType( tq );
    214                         }
    215 
    216                         Type * StringView::parsePointer(Type::Qualifiers tq) {
    217                                 PRINT( std::cerr << "pointer..." << std::endl; )
    218                                 Type * t = parseType();
    219                                 if (! t) return nullptr;
    220                                 return new PointerType( tq, t );
    221                         }
    222 
    223                         Type * StringView::parseArray(Type::Qualifiers tq) {
    224                                 PRINT( std::cerr << "array..." << std::endl; )
    225                                 size_t length;
    226                                 if (! extractNumber(length)) return nullptr;
    227                                 Type * t = parseType();
    228                                 if (! t) return nullptr;
    229                                 return new ArrayType( tq, t, new ConstantExpr( Constant::from_ulong(length) ), false, false );
    230                         }
    231 
    232                         Type * StringView::parseStruct(Type::Qualifiers tq) {
    233                                 PRINT( std::cerr << "struct..." << std::endl; )
    234                                 std::string name;
    235                                 if (! extractName(name)) return nullptr;
    236                                 return new StructInstType(tq, name);
    237                         }
    238 
    239                         Type * StringView::parseUnion(Type::Qualifiers tq) {
    240                                 PRINT( std::cerr << "union..." << std::endl; )
    241                                 std::string name;
    242                                 if (! extractName(name)) return nullptr;
    243                                 return new UnionInstType(tq, name);
    244                         }
    245 
    246                         Type * StringView::parseEnum(Type::Qualifiers tq) {
    247                                 PRINT( std::cerr << "enum..." << std::endl; )
    248                                 std::string name;
    249                                 if (! extractName(name)) return nullptr;
    250                                 return new EnumInstType(tq, name);
    251                         }
    252 
    253                         Type * StringView::parseType(Type::Qualifiers tq) {
    254                                 PRINT( std::cerr << "type..." << std::endl; )
    255                                 std::string name;
    256                                 if (! extractName(name)) return nullptr;
    257                                 PRINT( std::cerr << "typename..." << name << std::endl; )
    258                                 return new TypeInstType(tq, name, false);
    259                         }
    260 
    261                         Type * StringView::parseType() {
    262                                 if (done()) return nullptr;
    263 
    264                                 std::list<TypeDecl *> forall;
    265                                 if (isPrefix(Encoding::forall)) {
    266                                         PRINT( std::cerr << "polymorphic with..." << std::endl; )
    267                                         size_t dcount, fcount, vcount, acount;
    268                                         if (! extractNumber(dcount)) return nullptr;
    269                                         PRINT( std::cerr << dcount << " dtypes" << std::endl; )
    270                                         if (! expect('_')) return nullptr;
    271                                         if (! extractNumber(fcount)) return nullptr;
    272                                         PRINT( std::cerr << fcount << " ftypes" << std::endl; )
    273                                         if (! expect('_')) return nullptr;
    274                                         if (! extractNumber(vcount)) return nullptr;
    275                                         PRINT( std::cerr << vcount << " ttypes" << std::endl; )
    276                                         if (! expect('_')) return nullptr;
    277                                         if (! extractNumber(acount)) return nullptr;
    278                                         PRINT( std::cerr << acount << " assertions" << std::endl; )
    279                                         if (! expect('_')) return nullptr;
    280                                         for (size_t i = 0; i < acount; ++i) {
    281                                                 // TODO: need to recursively parse assertions, but for now just return nullptr so that
    282                                                 // demangler does not crash if there are assertions
    283                                                 return nullptr;
    284                                         }
    285                                         if (! expect('_')) return nullptr;
    286                                 }
    287 
    288                                 // qualifiers
    289                                 Type::Qualifiers tq;
    290                                 while (true) {
    291                                         auto qual = std::find_if(Encoding::qualifiers.begin(), Encoding::qualifiers.end(), [this](decltype(Encoding::qualifiers)::value_type val) {
    292                                                 return isPrefix(val.second);
    293                                         });
    294                                         if (qual == Encoding::qualifiers.end()) break;
    295                                         tq |= qual->first;
    296                                 }
    297 
    298                                 // find the correct type parser and use it
    299                                 auto iter = std::find_if(parsers.begin(), parsers.end(), [this](std::pair<std::string, parser> & p) {
    300                                         return isPrefix(p.first);
    301                                 });
    302                                 assertf(iter != parsers.end(), "Unhandled type letter: %c at index: %zd", cur(), idx);
    303                                 Type * ret = iter->second(tq);
    304                                 if (! ret) return nullptr;
    305                                 ret->forall = std::move(forall);
    306                                 return ret;
    307                         }
    308 
    309                         bool StringView::parse(std::string & name, Type *& type) {
    310                                 if (! stripMangleName(name)) return false;
    311                                 PRINT( std::cerr << "stripped name: " << name << std::endl; )
    312                                 Type * t = parseType();
    313                                 if (! t) return false;
    314                                 type = t;
    315                                 return true;
    316                         }
    317 
    318                         std::string demangle(const std::string & mangleName) {
    319                                 SymTab::Mangler::StringView view(mangleName);
    320                                 std::string name;
    321                                 Type * type = nullptr;
    322                                 if (! view.parse(name, type)) return mangleName;
    323                                 auto info = CodeGen::operatorLookupByOutput(name);
    324                                 if (info) name = info->inputName;
    325                                 std::unique_ptr<Type> manager(type);
    326                                 return CodeGen::genType(type, name);
    327                         }
    328                 } // namespace
    329         } // namespace Mangler
    330 } // namespace SymTab
    33132
    33233namespace Mangle {
     
    550251        if (done()) return nullptr;
    551252
    552         std::list<TypeDecl *> forall;
    553253        if (isPrefix(Encoding::forall)) {
    554254                PRINT( std::cerr << "polymorphic with..." << std::endl; )
Note: See TracChangeset for help on using the changeset viewer.