Changeset c6b4432 for src/SymTab/Demangle.cc
- Timestamp:
- Nov 8, 2023, 2:01:11 PM (8 months ago)
- Branches:
- master
- Children:
- 3e4bf0d, f5ec35a
- Parents:
- 790d835
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Demangle.cc
r790d835 rc6b4432 21 21 #include "CodeGen/GenType.h" 22 22 #include "CodeGen/OperatorTable.h" 23 #include "Common/PassVisitor.h"24 23 #include "Common/utility.h" // isPrefix 25 24 #include "Mangler.h" 26 #include "SynTree/Type.h"27 #include "SynTree/Declaration.h"28 25 29 26 #define DEBUG … … 33 30 #define PRINT(x) {} 34 31 #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 types77 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 types84 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 else98 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 otherwise151 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 suffix154 if ( ! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back() ) ) return false;155 156 // get name157 if (! extractName(name)) return false;158 159 // find bounds for type160 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 return202 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 that282 // demangler does not crash if there are assertions283 return nullptr;284 }285 if (! expect('_')) return nullptr;286 }287 288 // qualifiers289 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 it299 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 } // namespace329 } // namespace Mangler330 } // namespace SymTab331 32 332 33 namespace Mangle { … … 550 251 if (done()) return nullptr; 551 252 552 std::list<TypeDecl *> forall;553 253 if (isPrefix(Encoding::forall)) { 554 254 PRINT( std::cerr << "polymorphic with..." << std::endl; )
Note: See TracChangeset
for help on using the changeset viewer.