Changeset 8d182b1 for src/SymTab/Demangle.cc
- Timestamp:
- Nov 14, 2023, 12:19:09 PM (23 months ago)
- Branches:
- master
- Children:
- 1ccae59, 89a8bab
- Parents:
- df8ba61a (diff), 5625427 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Demangle.cc
rdf8ba61a r8d182b1 17 17 #include <sstream> 18 18 19 #include "AST/Pass.hpp" 20 #include "AST/Type.hpp" 19 21 #include "CodeGen/GenType.h" 20 22 #include "CodeGen/OperatorTable.h" 21 #include "Common/PassVisitor.h"22 23 #include "Common/utility.h" // isPrefix 23 24 #include "Mangler.h" 24 #include "SynTree/Type.h"25 #include "SynTree/Declaration.h"26 25 27 26 #define DEBUG … … 32 31 #endif 33 32 33 namespace Mangle { 34 34 35 namespace { 35 struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting { 36 std::string typeString; 37 GenType( const std::string &typeString ); 38 39 void previsit( BaseSyntaxNode * ); 40 void postvisit( BaseSyntaxNode * ); 41 42 void postvisit( FunctionType * funcType ); 43 void postvisit( VoidType * voidType ); 44 void postvisit( BasicType * basicType ); 45 void postvisit( PointerType * pointerType ); 46 void postvisit( ArrayType * arrayType ); 47 void postvisit( ReferenceType * refType ); 48 void postvisit( StructInstType * structInst ); 49 void postvisit( UnionInstType * unionInst ); 50 void postvisit( EnumInstType * enumInst ); 51 void postvisit( TypeInstType * typeInst ); 52 void postvisit( TupleType * tupleType ); 53 void postvisit( VarArgsType * varArgsType ); 54 void postvisit( ZeroType * zeroType ); 55 void postvisit( OneType * oneType ); 56 void postvisit( GlobalScopeType * globalType ); 57 void postvisit( QualifiedType * qualType ); 58 59 private: 60 void handleQualifiers( Type *type ); 61 std::string handleGeneric( ReferenceToType * refType ); 62 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 63 }; 64 65 std::string genDemangleType( Type * type, const std::string & baseString ) { 66 PassVisitor<GenType> gt( baseString ); 67 assert( type ); 68 type->accept( gt ); 69 return gt.pass.typeString; 70 } 71 72 GenType::GenType( const std::string &typeString ) : typeString( typeString ) {} 73 74 // *** BaseSyntaxNode 75 void GenType::previsit( BaseSyntaxNode * ) { 76 // turn off automatic recursion for all nodes, to allow each visitor to 77 // precisely control the order in which its children are visited. 78 visit_children = false; 79 } 80 81 void GenType::postvisit( BaseSyntaxNode * node ) { 82 std::stringstream ss; 83 node->print( ss ); 84 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() ); 85 } 86 87 void GenType::postvisit( VoidType * voidType ) { 88 typeString = "void " + typeString; 89 handleQualifiers( voidType ); 90 } 91 92 void GenType::postvisit( BasicType * basicType ) { 93 BasicType::Kind kind = basicType->kind; 94 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES ); 95 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString; 96 handleQualifiers( basicType ); 97 } 98 99 void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool ) { 100 std::ostringstream os; 101 if ( typeString != "" ) { 102 if ( typeString[ 0 ] == '*' ) { 103 os << "(" << typeString << ")"; 104 } else { 105 os << typeString; 106 } // if 107 } // if 108 os << "["; 109 110 if ( qualifiers.is_const ) { 111 os << "const "; 112 } // if 113 if ( qualifiers.is_volatile ) { 114 os << "volatile "; 115 } // if 116 if ( qualifiers.is_restrict ) { 117 os << "__restrict "; 118 } // if 119 if ( qualifiers.is_atomic ) { 120 os << "_Atomic "; 121 } // if 122 if ( dimension != 0 ) { 123 // TODO: ??? 124 // PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 125 // dimension->accept( cg ); 126 } else if ( isVarLen ) { 127 // no dimension expression on a VLA means it came in with the * token 128 os << "*"; 129 } // if 130 os << "]"; 131 132 typeString = os.str(); 133 134 base->accept( *visitor ); 135 } 136 137 void GenType::postvisit( PointerType * pointerType ) { 138 assert( pointerType->base != 0); 139 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) { 140 assert(false); 141 genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() ); 142 } else { 143 handleQualifiers( pointerType ); 144 if ( typeString[ 0 ] == '?' ) { 145 typeString = "* " + typeString; 146 } else { 147 typeString = "*" + typeString; 148 } // if 149 pointerType->base->accept( *visitor ); 150 } // if 151 } 152 153 void GenType::postvisit( ArrayType * arrayType ) { 154 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() ); 155 } 156 157 void GenType::postvisit( ReferenceType * refType ) { 158 assert( false ); 159 assert( refType->base != 0); 160 handleQualifiers( refType ); 161 typeString = "&" + typeString; 162 refType->base->accept( *visitor ); 163 } 164 165 void GenType::postvisit( FunctionType * funcType ) { 166 std::ostringstream os; 167 168 if ( typeString != "" ) { 169 if ( typeString[0] == '*' ) { 170 os << "(" << typeString << ")"; 171 } else { 172 os << typeString; 173 } // if 174 } // if 175 176 /************* parameters ***************/ 177 const std::list<DeclarationWithType *> &pars = funcType->parameters; 178 179 if ( pars.empty() ) { 180 if ( funcType->get_isVarArgs() ) { 181 os << "()"; 182 } else { 183 os << "(void)"; 184 } // if 185 } else { 186 os << "(" ; 187 188 unsigned int i = 0; 189 for (DeclarationWithType * p : pars) { 190 os << genDemangleType( p->get_type(), "" ); 191 if (++i != pars.size()) os << ", "; 192 } 193 194 if ( funcType->get_isVarArgs() ) { 195 os << ", ..."; 196 } // if 197 os << ")"; 198 } // if 199 200 typeString = os.str(); 201 202 if ( funcType->returnVals.size() == 0 ) { 203 typeString += ": void"; 204 } else { 205 typeString += ": " + genDemangleType(funcType->returnVals.front()->get_type(), ""); 206 } // if 207 208 // add forall 209 if( ! funcType->forall.empty() ) { 210 std::ostringstream os; 211 os << "forall("; 212 unsigned int i = 0; 213 for ( auto td : funcType->forall ) { 214 os << td->typeString() << " " << td->name; 215 if (! td->assertions.empty()) { 216 os << " | { "; 217 unsigned int j = 0; 218 for (DeclarationWithType * assert : td->assertions) { 219 os << genDemangleType(assert->get_type(), assert->name); 220 if (++j != td->assertions.size()) os << ", "; 221 } 222 os << "}"; 223 } 224 if (++i != funcType->forall.size()) os << ", "; 225 } 226 os << ")"; 227 typeString = typeString + " -> " + os.str(); 36 37 struct Demangler { 38 private: 39 std::string str; 40 size_t index = 0; 41 using Parser = std::function<ast::Type * ( ast::CV::Qualifiers )>; 42 std::vector<std::pair<std::string, Parser>> parsers; 43 public: 44 Demangler( const std::string & str ); 45 46 bool done() const { return str.size() <= index; } 47 char cur() const { assert( !done() ); return str[index]; } 48 bool expect( char ch ) { return str[index++] == ch; } 49 50 bool isPrefix( const std::string & pref ); 51 bool extractNumber( size_t & out ); 52 bool extractName( std::string & out ); 53 bool stripMangleName( std::string & name ); 54 55 ast::Type * parseFunction( ast::CV::Qualifiers tq ); 56 ast::Type * parseTuple( ast::CV::Qualifiers tq ); 57 ast::Type * parsePointer( ast::CV::Qualifiers tq ); 58 ast::Type * parseArray( ast::CV::Qualifiers tq ); 59 ast::Type * parseStruct( ast::CV::Qualifiers tq ); 60 ast::Type * parseUnion( ast::CV::Qualifiers tq ); 61 ast::Type * parseEnum( ast::CV::Qualifiers tq ); 62 ast::Type * parseType( ast::CV::Qualifiers tq ); 63 ast::Type * parseZero( ast::CV::Qualifiers tq ); 64 ast::Type * parseOne( ast::CV::Qualifiers tq ); 65 66 ast::Type * parseType(); 67 bool parse( std::string & name, ast::Type *& type ); 68 }; 69 70 Demangler::Demangler(const std::string & str) : str(str) { 71 for (size_t k = 0; k < ast::BasicType::NUMBER_OF_BASIC_TYPES; ++k) { 72 parsers.emplace_back(Encoding::basicTypes[k], [k]( ast::CV::Qualifiers tq ) { 73 PRINT( std::cerr << "basic type: " << k << std::endl; ) 74 return new ast::BasicType( (ast::BasicType::Kind)k, tq ); 75 }); 76 } 77 78 for (size_t k = 0; k < ast::TypeDecl::NUMBER_OF_KINDS; ++k) { 79 static const std::string typeVariableNames[] = { "DT", "DST", "OT", "FT", "TT", "ALT", }; 80 static_assert( 81 sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == ast::TypeDecl::NUMBER_OF_KINDS, 82 "Each type variable kind should have a demangle name prefix" 83 ); 84 parsers.emplace_back(Encoding::typeVariables[k], [k, this]( ast::CV::Qualifiers tq ) -> ast::TypeInstType * { 85 PRINT( std::cerr << "type variable type: " << k << std::endl; ) 86 size_t N; 87 if (!extractNumber(N)) return nullptr; 88 return new ast::TypeInstType( 89 toString(typeVariableNames[k], N), 90 (ast::TypeDecl::Kind)k, 91 tq ); 92 }); 93 } 94 95 parsers.emplace_back(Encoding::void_t, [this]( ast::CV::Qualifiers tq ) { return new ast::VoidType(tq); }); 96 parsers.emplace_back(Encoding::function, [this]( ast::CV::Qualifiers tq ) { return parseFunction(tq); }); 97 parsers.emplace_back(Encoding::pointer, [this]( ast::CV::Qualifiers tq ) { return parsePointer(tq); }); 98 parsers.emplace_back(Encoding::array, [this]( ast::CV::Qualifiers tq ) { return parseArray(tq); }); 99 parsers.emplace_back(Encoding::tuple, [this]( ast::CV::Qualifiers tq ) { return parseTuple(tq); }); 100 parsers.emplace_back(Encoding::struct_t, [this]( ast::CV::Qualifiers tq ) { return parseStruct(tq); }); 101 parsers.emplace_back(Encoding::union_t, [this]( ast::CV::Qualifiers tq ) { return parseUnion(tq); }); 102 parsers.emplace_back(Encoding::enum_t, [this]( ast::CV::Qualifiers tq ) { return parseEnum(tq); }); 103 parsers.emplace_back(Encoding::type, [this]( ast::CV::Qualifiers tq ) { return parseType(tq); }); 104 parsers.emplace_back(Encoding::zero, []( ast::CV::Qualifiers tq ) { return new ast::ZeroType(tq); }); 105 parsers.emplace_back(Encoding::one, []( ast::CV::Qualifiers tq ) { return new ast::OneType(tq); }); 106 } 107 108 bool Demangler::extractNumber( size_t & out ) { 109 std::stringstream numss; 110 if ( str.size() <= index ) return false; 111 while ( isdigit( str[index] ) ) { 112 numss << str[index]; 113 ++index; 114 if ( str.size() == index ) break; 115 } 116 if ( !(numss >> out) ) return false; 117 PRINT( std::cerr << "extractNumber success: " << out << std::endl; ) 118 return true; 119 } 120 121 bool Demangler::extractName( std::string & out ) { 122 size_t len; 123 if ( !extractNumber(len) ) return false; 124 if ( str.size() < index + len ) return false; 125 out = str.substr( index, len ); 126 index += len; 127 PRINT( std::cerr << "extractName success: " << out << std::endl; ) 128 return true; 129 } 130 131 bool Demangler::isPrefix( const std::string & pref ) { 132 // Wraps the utility isPrefix function. 133 if ( ::isPrefix( str, pref, index ) ) { 134 index += pref.size(); 135 return true; 136 } 137 return false; 138 } 139 140 // strips __NAME__cfa__TYPE_N, where N is [0-9]+: returns str is a match is found, returns empty string otherwise 141 bool Demangler::stripMangleName( std::string & name ) { 142 PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; ) 143 if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix 144 if ( !isPrefix(Encoding::manglePrefix) || !isdigit(str.back() ) ) return false; 145 146 if (!extractName(name)) return false; 147 148 // Find bounds for type. 149 PRINT( std::cerr << index << " " << str.size() << std::endl; ) 150 PRINT( std::cerr << "["); 151 while (isdigit(str.back())) { 152 PRINT(std::cerr << "."); 153 str.pop_back(); 154 if (str.size() <= index) return false; 155 } 156 PRINT( std::cerr << "]" << std::endl ); 157 if (str.back() != '_') return false; 158 str.pop_back(); 159 PRINT( std::cerr << str.size() << " " << name << " " << str.substr(index) << std::endl; ) 160 return index < str.size(); 161 } 162 163 ast::Type * Demangler::parseFunction( ast::CV::Qualifiers tq ) { 164 PRINT( std::cerr << "function..." << std::endl; ) 165 if ( done() ) return nullptr; 166 ast::FunctionType * ftype = new ast::FunctionType( ast::FixedArgs, tq ); 167 std::unique_ptr<ast::Type> manager( ftype ); 168 ast::Type * retVal = parseType(); 169 if ( !retVal ) return nullptr; 170 PRINT( std::cerr << "with return type: " << retVal << std::endl; ) 171 ftype->returns.emplace_back( retVal ); 172 if ( done() || !expect('_') ) return nullptr; 173 while ( !done() ) { 174 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 175 if ( cur() == '_' ) return manager.release(); 176 ast::Type * param = parseType(); 177 if ( !param ) return nullptr; 178 PRINT( std::cerr << "with parameter : " << param << std::endl; ) 179 ftype->params.emplace_back( param ); 180 } 181 return nullptr; 182 } 183 184 ast::Type * Demangler::parseTuple( ast::CV::Qualifiers tq ) { 185 PRINT( std::cerr << "tuple..." << std::endl; ) 186 std::vector<ast::ptr<ast::Type>> types; 187 size_t ncomponents; 188 if ( !extractNumber(ncomponents) ) return nullptr; 189 for ( size_t i = 0; i < ncomponents; ++i ) { 190 if ( done() ) return nullptr; 191 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 192 ast::Type * t = parseType(); 193 if ( !t ) return nullptr; 194 PRINT( std::cerr << "with type : " << t << std::endl; ) 195 types.push_back( t ); 196 } 197 return new ast::TupleType( std::move( types ), tq ); 198 } 199 200 ast::Type * Demangler::parsePointer( ast::CV::Qualifiers tq ) { 201 PRINT( std::cerr << "pointer..." << std::endl; ) 202 ast::Type * t = parseType(); 203 if ( !t ) return nullptr; 204 return new ast::PointerType( t, tq ); 205 } 206 207 ast::Type * Demangler::parseArray( ast::CV::Qualifiers tq ) { 208 PRINT( std::cerr << "array..." << std::endl; ) 209 size_t length; 210 if ( !extractNumber(length) ) return nullptr; 211 ast::Type * t = parseType(); 212 if ( !t ) return nullptr; 213 return new ast::ArrayType( 214 t, 215 ast::ConstantExpr::from_ulong( CodeLocation(), length ), 216 ast::FixedLen, 217 ast::DynamicDim, 218 tq ); 219 } 220 221 ast::Type * Demangler::parseStruct( ast::CV::Qualifiers tq ) { 222 PRINT( std::cerr << "struct..." << std::endl; ) 223 std::string name; 224 if ( !extractName(name) ) return nullptr; 225 return new ast::StructInstType( name, tq ); 226 } 227 228 ast::Type * Demangler::parseUnion( ast::CV::Qualifiers tq ) { 229 PRINT( std::cerr << "union..." << std::endl; ) 230 std::string name; 231 if ( !extractName(name) ) return nullptr; 232 return new ast::UnionInstType( name, tq ); 233 } 234 235 ast::Type * Demangler::parseEnum( ast::CV::Qualifiers tq ) { 236 PRINT( std::cerr << "enum..." << std::endl; ) 237 std::string name; 238 if ( !extractName(name) ) return nullptr; 239 return new ast::EnumInstType( name, tq ); 240 } 241 242 ast::Type * Demangler::parseType( ast::CV::Qualifiers tq ) { 243 PRINT( std::cerr << "type..." << std::endl; ) 244 std::string name; 245 if ( !extractName(name) ) return nullptr; 246 PRINT( std::cerr << "typename..." << name << std::endl; ) 247 return new ast::TypeInstType( name, ast::TypeDecl::Dtype, tq ); 248 } 249 250 ast::Type * Demangler::parseType() { 251 if (done()) return nullptr; 252 253 if (isPrefix(Encoding::forall)) { 254 PRINT( std::cerr << "polymorphic with..." << std::endl; ) 255 size_t dcount, fcount, vcount, acount; 256 if ( !extractNumber(dcount) ) return nullptr; 257 PRINT( std::cerr << dcount << " dtypes" << std::endl; ) 258 if ( !expect('_') ) return nullptr; 259 if ( !extractNumber(fcount) ) return nullptr; 260 PRINT( std::cerr << fcount << " ftypes" << std::endl; ) 261 if ( !expect('_')) return nullptr; 262 if ( !extractNumber(vcount)) return nullptr; 263 PRINT( std::cerr << vcount << " ttypes" << std::endl; ) 264 if ( !expect('_') ) return nullptr; 265 if ( !extractNumber(acount) ) return nullptr; 266 PRINT( std::cerr << acount << " assertions" << std::endl; ) 267 if ( !expect('_') ) return nullptr; 268 for ( size_t i = 0 ; i < acount ; ++i ) { 269 // TODO: need to recursively parse assertions, but for now just return nullptr so that 270 // demangler does not crash if there are assertions 271 return nullptr; 228 272 } 229 } 230 231 std::string GenType::handleGeneric( ReferenceToType * refType ) { 232 if ( ! refType->parameters.empty() ) { 233 std::ostringstream os; 234 // TODO: ??? 235 // PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 236 os << "("; 237 // cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() ); 238 os << ") "; 239 return os.str(); 240 } 241 return ""; 242 } 243 244 void GenType::postvisit( StructInstType * structInst ) { 245 typeString = "struct " + structInst->name + handleGeneric( structInst ) + " " + typeString; 246 handleQualifiers( structInst ); 247 } 248 249 void GenType::postvisit( UnionInstType * unionInst ) { 250 typeString = "union " + unionInst->name + handleGeneric( unionInst ) + " " + typeString; 251 handleQualifiers( unionInst ); 252 } 253 254 void GenType::postvisit( EnumInstType * enumInst ) { 255 typeString = "enum " + enumInst->name + " " + typeString; 256 handleQualifiers( enumInst ); 257 } 258 259 void GenType::postvisit( TypeInstType * typeInst ) { 260 typeString = typeInst->name + " " + typeString; 261 handleQualifiers( typeInst ); 262 } 263 264 void GenType::postvisit( TupleType * tupleType ) { 265 unsigned int i = 0; 266 std::ostringstream os; 267 os << "["; 268 for ( Type * t : *tupleType ) { 269 i++; 270 os << genDemangleType( t, "" ) << (i == tupleType->size() ? "" : ", "); 271 } 272 os << "] "; 273 typeString = os.str() + typeString; 274 } 275 276 void GenType::postvisit( VarArgsType * varArgsType ) { 277 typeString = "__builtin_va_list " + typeString; 278 handleQualifiers( varArgsType ); 279 } 280 281 void GenType::postvisit( ZeroType * zeroType ) { 282 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 283 typeString = "zero_t " + typeString; 284 handleQualifiers( zeroType ); 285 } 286 287 void GenType::postvisit( OneType * oneType ) { 288 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 289 typeString = "one_t " + typeString; 290 handleQualifiers( oneType ); 291 } 292 293 void GenType::postvisit( GlobalScopeType * globalType ) { 294 handleQualifiers( globalType ); 295 } 296 297 void GenType::postvisit( QualifiedType * qualType ) { 298 std::ostringstream os; 299 os << genDemangleType( qualType->parent, "" ) << "." << genDemangleType( qualType->child, "" ) << typeString; 300 typeString = os.str(); 301 handleQualifiers( qualType ); 302 } 303 304 void GenType::handleQualifiers( Type * type ) { 305 if ( type->get_const() ) { 306 typeString = "const " + typeString; 307 } // if 308 if ( type->get_volatile() ) { 309 typeString = "volatile " + typeString; 310 } // if 311 if ( type->get_restrict() ) { 312 typeString = "__restrict " + typeString; 313 } // if 314 if ( type->get_atomic() ) { 315 typeString = "_Atomic " + typeString; 316 } // if 317 } 318 } 319 320 321 namespace SymTab { 322 namespace Mangler { 323 namespace { 324 struct StringView { 325 private: 326 std::string str; 327 size_t idx = 0; 328 // typedef Type * (StringView::*parser)(Type::Qualifiers); 329 typedef std::function<Type * (Type::Qualifiers)> parser; 330 std::vector<std::pair<std::string, parser>> parsers; 331 public: 332 StringView(const std::string & str); 333 334 bool done() const { return idx >= str.size(); } 335 char cur() const { assert(! done()); return str[idx]; } 336 337 bool expect(char ch) { return str[idx++] == ch; } 338 void next(size_t inc = 1) { idx += inc; } 339 340 /// determines if `pref` is a prefix of `str` 341 bool isPrefix(const std::string & pref); 342 bool extractNumber(size_t & out); 343 bool extractName(std::string & out); 344 bool stripMangleName(std::string & name); 345 346 Type * parseFunction(Type::Qualifiers tq); 347 Type * parseTuple(Type::Qualifiers tq); 348 Type * parseVoid(Type::Qualifiers tq); 349 Type * parsePointer(Type::Qualifiers tq); 350 Type * parseArray(Type::Qualifiers tq); 351 Type * parseStruct(Type::Qualifiers tq); 352 Type * parseUnion(Type::Qualifiers tq); 353 Type * parseEnum(Type::Qualifiers tq); 354 Type * parseType(Type::Qualifiers tq); 355 356 Type * parseType(); 357 bool parse(std::string & name, Type *& type); 358 }; 359 360 StringView::StringView(const std::string & str) : str(str) { 361 // basic types 362 for (size_t k = 0; k < BasicType::NUMBER_OF_BASIC_TYPES; ++k) { 363 parsers.emplace_back(Encoding::basicTypes[k], [k](Type::Qualifiers tq) { 364 PRINT( std::cerr << "basic type: " << k << std::endl; ) 365 return new BasicType(tq, (BasicType::Kind)k); 366 }); 367 } 368 // type variable types 369 for (size_t k = 0; k < TypeDecl::NUMBER_OF_KINDS; ++k) { 370 static const std::string typeVariableNames[] = { "DT", "DST", "OT", "FT", "TT", "ALT", }; 371 static_assert( 372 sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == TypeDecl::NUMBER_OF_KINDS, 373 "Each type variable kind should have a demangle name prefix" 374 ); 375 parsers.emplace_back(Encoding::typeVariables[k], [k, this](Type::Qualifiers tq) -> TypeInstType * { 376 PRINT( std::cerr << "type variable type: " << k << std::endl; ) 377 size_t N; 378 if (! extractNumber(N)) return nullptr; 379 return new TypeInstType(tq, toString(typeVariableNames[k], N), (TypeDecl::Kind)k != TypeDecl::Ftype); 380 }); 381 } 382 // everything else 383 parsers.emplace_back(Encoding::void_t, [this](Type::Qualifiers tq) { return parseVoid(tq); }); 384 parsers.emplace_back(Encoding::function, [this](Type::Qualifiers tq) { return parseFunction(tq); }); 385 parsers.emplace_back(Encoding::pointer, [this](Type::Qualifiers tq) { return parsePointer(tq); }); 386 parsers.emplace_back(Encoding::array, [this](Type::Qualifiers tq) { return parseArray(tq); }); 387 parsers.emplace_back(Encoding::tuple, [this](Type::Qualifiers tq) { return parseTuple(tq); }); 388 parsers.emplace_back(Encoding::struct_t, [this](Type::Qualifiers tq) { return parseStruct(tq); }); 389 parsers.emplace_back(Encoding::union_t, [this](Type::Qualifiers tq) { return parseUnion(tq); }); 390 parsers.emplace_back(Encoding::enum_t, [this](Type::Qualifiers tq) { return parseEnum(tq); }); 391 parsers.emplace_back(Encoding::type, [this](Type::Qualifiers tq) { return parseType(tq); }); 392 parsers.emplace_back(Encoding::zero, [](Type::Qualifiers tq) { return new ZeroType(tq); }); 393 parsers.emplace_back(Encoding::one, [](Type::Qualifiers tq) { return new OneType(tq); }); 394 } 395 396 bool StringView::extractNumber(size_t & out) { 397 std::stringstream numss; 398 if (idx >= str.size()) return false; 399 while (isdigit(str[idx])) { 400 numss << str[idx]; 401 ++idx; 402 if (idx == str.size()) break; 403 } 404 if (! (numss >> out)) return false; 405 PRINT( std::cerr << "extractNumber success: " << out << std::endl; ) 406 return true; 407 } 408 409 bool StringView::extractName(std::string & out) { 410 size_t len; 411 if (! extractNumber(len)) return false; 412 if (idx+len > str.size()) return false; 413 out = str.substr(idx, len); 414 idx += len; 415 PRINT( std::cerr << "extractName success: " << out << std::endl; ) 416 return true; 417 } 418 419 bool StringView::isPrefix(const std::string & pref) { 420 // if ( pref.size() > str.size()-idx ) return false; 421 // auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) ); 422 // if (its.first == pref.end()) { 423 // idx += pref.size(); 424 // return true; 425 // } 426 427 // This update is untested because there are no tests for this code. 428 if ( ::isPrefix( str, pref, idx ) ) { 429 idx += pref.size(); 430 return true; 431 } 432 return false; 433 } 434 435 // strips __NAME__cfa__TYPE_N, where N is [0-9]+: returns str is a match is found, returns empty string otherwise 436 bool StringView::stripMangleName(std::string & name) { 437 PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; ) 438 if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix 439 if ( ! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back() ) ) return false; 440 441 // get name 442 if (! extractName(name)) return false; 443 444 // find bounds for type 445 PRINT( std::cerr << idx << " " << str.size() << std::endl; ) 446 PRINT( std::cerr << "["); 447 while (isdigit(str.back())) { 448 PRINT(std::cerr << "."); 449 str.pop_back(); 450 if (str.size() <= idx) return false; 451 } 452 PRINT( std::cerr << "]" << std::endl ); 453 if (str.back() != '_') return false; 454 str.pop_back(); 455 PRINT( std::cerr << str.size() << " " << name << " " << str.substr(idx) << std::endl; ) 456 return str.size() > idx; 457 } 458 459 Type * StringView::parseFunction(Type::Qualifiers tq) { 460 PRINT( std::cerr << "function..." << std::endl; ) 461 if (done()) return nullptr; 462 FunctionType * ftype = new FunctionType( tq, false ); 463 std::unique_ptr<Type> manager(ftype); 464 Type * retVal = parseType(); 465 if (! retVal) return nullptr; 466 PRINT( std::cerr << "with return type: " << retVal << std::endl; ) 467 ftype->returnVals.push_back(ObjectDecl::newObject("", retVal, nullptr)); 468 if (done() || ! expect('_')) return nullptr; 469 while (! done()) { 470 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 471 if (cur() == '_') return manager.release(); 472 Type * param = parseType(); 473 if (! param) return nullptr; 474 PRINT( std::cerr << "with parameter : " << param << std::endl; ) 475 ftype->parameters.push_back(ObjectDecl::newObject("", param, nullptr)); 476 } 477 return nullptr; 478 } 479 480 Type * StringView::parseTuple(Type::Qualifiers tq) { 481 PRINT( std::cerr << "tuple..." << std::endl; ) 482 std::list< Type * > types; 483 size_t ncomponents; 484 if (! extractNumber(ncomponents)) return nullptr; 485 for (size_t i = 0; i < ncomponents; ++i) { 486 // TODO: delete all on return 487 if (done()) return nullptr; 488 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 489 Type * t = parseType(); 490 if (! t) return nullptr; 491 PRINT( std::cerr << "with type : " << t << std::endl; ) 492 types.push_back(t); 493 } 494 return new TupleType( tq, types ); 495 } 496 497 Type * StringView::parseVoid(Type::Qualifiers tq) { 498 return new VoidType( tq ); 499 } 500 501 Type * StringView::parsePointer(Type::Qualifiers tq) { 502 PRINT( std::cerr << "pointer..." << std::endl; ) 503 Type * t = parseType(); 504 if (! t) return nullptr; 505 return new PointerType( tq, t ); 506 } 507 508 Type * StringView::parseArray(Type::Qualifiers tq) { 509 PRINT( std::cerr << "array..." << std::endl; ) 510 size_t length; 511 if (! extractNumber(length)) return nullptr; 512 Type * t = parseType(); 513 if (! t) return nullptr; 514 return new ArrayType( tq, t, new ConstantExpr( Constant::from_ulong(length) ), false, false ); 515 } 516 517 Type * StringView::parseStruct(Type::Qualifiers tq) { 518 PRINT( std::cerr << "struct..." << std::endl; ) 519 std::string name; 520 if (! extractName(name)) return nullptr; 521 return new StructInstType(tq, name); 522 } 523 524 Type * StringView::parseUnion(Type::Qualifiers tq) { 525 PRINT( std::cerr << "union..." << std::endl; ) 526 std::string name; 527 if (! extractName(name)) return nullptr; 528 return new UnionInstType(tq, name); 529 } 530 531 Type * StringView::parseEnum(Type::Qualifiers tq) { 532 PRINT( std::cerr << "enum..." << std::endl; ) 533 std::string name; 534 if (! extractName(name)) return nullptr; 535 return new EnumInstType(tq, name); 536 } 537 538 Type * StringView::parseType(Type::Qualifiers tq) { 539 PRINT( std::cerr << "type..." << std::endl; ) 540 std::string name; 541 if (! extractName(name)) return nullptr; 542 PRINT( std::cerr << "typename..." << name << std::endl; ) 543 return new TypeInstType(tq, name, false); 544 } 545 546 Type * StringView::parseType() { 547 if (done()) return nullptr; 548 549 std::list<TypeDecl *> forall; 550 if (isPrefix(Encoding::forall)) { 551 PRINT( std::cerr << "polymorphic with..." << std::endl; ) 552 size_t dcount, fcount, vcount, acount; 553 if (! extractNumber(dcount)) return nullptr; 554 PRINT( std::cerr << dcount << " dtypes" << std::endl; ) 555 if (! expect('_')) return nullptr; 556 if (! extractNumber(fcount)) return nullptr; 557 PRINT( std::cerr << fcount << " ftypes" << std::endl; ) 558 if (! expect('_')) return nullptr; 559 if (! extractNumber(vcount)) return nullptr; 560 PRINT( std::cerr << vcount << " ttypes" << std::endl; ) 561 if (! expect('_')) return nullptr; 562 if (! extractNumber(acount)) return nullptr; 563 PRINT( std::cerr << acount << " assertions" << std::endl; ) 564 if (! expect('_')) return nullptr; 565 for (size_t i = 0; i < acount; ++i) { 566 // TODO: need to recursively parse assertions, but for now just return nullptr so that 567 // demangler does not crash if there are assertions 568 return nullptr; 569 } 570 if (! expect('_')) return nullptr; 571 } 572 573 // qualifiers 574 Type::Qualifiers tq; 575 while (true) { 576 auto qual = std::find_if(Encoding::qualifiers.begin(), Encoding::qualifiers.end(), [this](decltype(Encoding::qualifiers)::value_type val) { 577 return isPrefix(val.second); 578 }); 579 if (qual == Encoding::qualifiers.end()) break; 580 tq |= qual->first; 581 } 582 583 // find the correct type parser and use it 584 auto iter = std::find_if(parsers.begin(), parsers.end(), [this](std::pair<std::string, parser> & p) { 585 return isPrefix(p.first); 586 }); 587 assertf(iter != parsers.end(), "Unhandled type letter: %c at index: %zd", cur(), idx); 588 Type * ret = iter->second(tq); 589 if (! ret) return nullptr; 590 ret->forall = std::move(forall); 591 return ret; 592 } 593 594 bool StringView::parse(std::string & name, Type *& type) { 595 if (! stripMangleName(name)) return false; 596 PRINT( std::cerr << "stripped name: " << name << std::endl; ) 597 Type * t = parseType(); 598 if (! t) return false; 599 type = t; 600 return true; 601 } 602 603 std::string demangle(const std::string & mangleName) { 604 SymTab::Mangler::StringView view(mangleName); 605 std::string name; 606 Type * type = nullptr; 607 if (! view.parse(name, type)) return mangleName; 608 auto info = CodeGen::operatorLookupByOutput(name); 609 if (info) name = info->inputName; 610 std::unique_ptr<Type> manager(type); 611 return genDemangleType(type, name); 612 } 613 } // namespace 614 } // namespace Mangler 615 } // namespace SymTab 273 if ( !expect('_') ) return nullptr; 274 } 275 276 ast::CV::Qualifiers tq; 277 while (true) { 278 auto qual = std::find_if(Encoding::qualifiers.begin(), Encoding::qualifiers.end(), [this](decltype(Encoding::qualifiers)::value_type val) { 279 return isPrefix(val.second); 280 }); 281 if (qual == Encoding::qualifiers.end()) break; 282 tq |= qual->first; 283 } 284 285 // Find the correct type parser and then apply it. 286 auto iter = std::find_if(parsers.begin(), parsers.end(), [this](std::pair<std::string, Parser> & p) { 287 return isPrefix(p.first); 288 }); 289 assertf(iter != parsers.end(), "Unhandled type letter: %c at index: %zd", cur(), index); 290 ast::Type * ret = iter->second(tq); 291 if ( !ret ) return nullptr; 292 return ret; 293 } 294 295 bool Demangler::parse( std::string & name, ast::Type *& type) { 296 if ( !stripMangleName(name) ) return false; 297 PRINT( std::cerr << "stripped name: " << name << std::endl; ) 298 ast::Type * t = parseType(); 299 if ( !t ) return false; 300 type = t; 301 return true; 302 } 303 304 std::string demangle( const std::string & mangleName ) { 305 using namespace CodeGen; 306 Demangler demangler( mangleName ); 307 std::string name; 308 ast::Type * type = nullptr; 309 if ( !demangler.parse( name, type ) ) return mangleName; 310 ast::readonly<ast::Type> roType = type; 311 if ( auto info = operatorLookupByOutput( name ) ) name = info->inputName; 312 return genType( type, name, Options( false, false, false, false ) ); 313 } 314 315 } // namespace 316 317 } // namespace Mangle 616 318 617 319 extern "C" { 618 320 char * cforall_demangle(const char * mangleName, int option __attribute__((unused))) { 619 const std::string & demangleName = SymTab::Mangler::demangle(mangleName);321 const std::string & demangleName = Mangle::demangle(mangleName); 620 322 return strdup(demangleName.c_str()); 621 323 }
Note:
See TracChangeset
for help on using the changeset viewer.