Changeset fc12f05 for src/SymTab
- Timestamp:
- Nov 13, 2023, 3:43:43 AM (23 months ago)
- Branches:
- master
- Children:
- 25f2798
- Parents:
- 0030b508 (diff), 2174191 (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. - Location:
- src/SymTab
- Files:
-
- 8 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Demangle.cc
r0030b508 rfc12f05 9 9 // Author : Rob Schluntz 10 10 // Created On : Thu Jul 19 12:52:41 2018 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Jan 11 21:28:27 202113 // Update Count : 1 111 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Nov 6 15:59:00 2023 13 // Update Count : 12 14 14 // 15 15 … … 17 17 #include <sstream> 18 18 19 #include "AST/Pass.hpp" 20 #include "AST/Type.hpp" 19 21 #include "CodeGen/GenType.h" 20 #include "Co mmon/PassVisitor.h"22 #include "CodeGen/OperatorTable.h" 21 23 #include "Common/utility.h" // isPrefix 22 24 #include "Mangler.h" 23 #include "SynTree/Type.h"24 #include "SynTree/Declaration.h"25 25 26 26 #define DEBUG … … 31 31 #endif 32 32 33 namespace Mangle { 34 33 35 namespace { 34 struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting { 35 std::string typeString; 36 GenType( const std::string &typeString ); 37 38 void previsit( BaseSyntaxNode * ); 39 void postvisit( BaseSyntaxNode * ); 40 41 void postvisit( FunctionType * funcType ); 42 void postvisit( VoidType * voidType ); 43 void postvisit( BasicType * basicType ); 44 void postvisit( PointerType * pointerType ); 45 void postvisit( ArrayType * arrayType ); 46 void postvisit( ReferenceType * refType ); 47 void postvisit( StructInstType * structInst ); 48 void postvisit( UnionInstType * unionInst ); 49 void postvisit( EnumInstType * enumInst ); 50 void postvisit( TypeInstType * typeInst ); 51 void postvisit( TupleType * tupleType ); 52 void postvisit( VarArgsType * varArgsType ); 53 void postvisit( ZeroType * zeroType ); 54 void postvisit( OneType * oneType ); 55 void postvisit( GlobalScopeType * globalType ); 56 void postvisit( QualifiedType * qualType ); 57 58 private: 59 void handleQualifiers( Type *type ); 60 std::string handleGeneric( ReferenceToType * refType ); 61 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 62 }; 63 64 std::string genDemangleType( Type * type, const std::string & baseString ) { 65 PassVisitor<GenType> gt( baseString ); 66 assert( type ); 67 type->accept( gt ); 68 return gt.pass.typeString; 69 } 70 71 GenType::GenType( const std::string &typeString ) : typeString( typeString ) {} 72 73 // *** BaseSyntaxNode 74 void GenType::previsit( BaseSyntaxNode * ) { 75 // turn off automatic recursion for all nodes, to allow each visitor to 76 // precisely control the order in which its children are visited. 77 visit_children = false; 78 } 79 80 void GenType::postvisit( BaseSyntaxNode * node ) { 81 std::stringstream ss; 82 node->print( ss ); 83 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() ); 84 } 85 86 void GenType::postvisit( VoidType * voidType ) { 87 typeString = "void " + typeString; 88 handleQualifiers( voidType ); 89 } 90 91 void GenType::postvisit( BasicType * basicType ) { 92 BasicType::Kind kind = basicType->kind; 93 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES ); 94 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString; 95 handleQualifiers( basicType ); 96 } 97 98 void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool ) { 99 std::ostringstream os; 100 if ( typeString != "" ) { 101 if ( typeString[ 0 ] == '*' ) { 102 os << "(" << typeString << ")"; 103 } else { 104 os << typeString; 105 } // if 106 } // if 107 os << "["; 108 109 if ( qualifiers.is_const ) { 110 os << "const "; 111 } // if 112 if ( qualifiers.is_volatile ) { 113 os << "volatile "; 114 } // if 115 if ( qualifiers.is_restrict ) { 116 os << "__restrict "; 117 } // if 118 if ( qualifiers.is_atomic ) { 119 os << "_Atomic "; 120 } // if 121 if ( dimension != 0 ) { 122 // TODO: ??? 123 // PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 124 // dimension->accept( cg ); 125 } else if ( isVarLen ) { 126 // no dimension expression on a VLA means it came in with the * token 127 os << "*"; 128 } // if 129 os << "]"; 130 131 typeString = os.str(); 132 133 base->accept( *visitor ); 134 } 135 136 void GenType::postvisit( PointerType * pointerType ) { 137 assert( pointerType->base != 0); 138 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) { 139 assert(false); 140 genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() ); 141 } else { 142 handleQualifiers( pointerType ); 143 if ( typeString[ 0 ] == '?' ) { 144 typeString = "* " + typeString; 145 } else { 146 typeString = "*" + typeString; 147 } // if 148 pointerType->base->accept( *visitor ); 149 } // if 150 } 151 152 void GenType::postvisit( ArrayType * arrayType ) { 153 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() ); 154 } 155 156 void GenType::postvisit( ReferenceType * refType ) { 157 assert( false ); 158 assert( refType->base != 0); 159 handleQualifiers( refType ); 160 typeString = "&" + typeString; 161 refType->base->accept( *visitor ); 162 } 163 164 void GenType::postvisit( FunctionType * funcType ) { 165 std::ostringstream os; 166 167 if ( typeString != "" ) { 168 if ( typeString[0] == '*' ) { 169 os << "(" << typeString << ")"; 170 } else { 171 os << typeString; 172 } // if 173 } // if 174 175 /************* parameters ***************/ 176 const std::list<DeclarationWithType *> &pars = funcType->parameters; 177 178 if ( pars.empty() ) { 179 if ( funcType->get_isVarArgs() ) { 180 os << "()"; 181 } else { 182 os << "(void)"; 183 } // if 184 } else { 185 os << "(" ; 186 187 unsigned int i = 0; 188 for (DeclarationWithType * p : pars) { 189 os << genDemangleType( p->get_type(), "" ); 190 if (++i != pars.size()) os << ", "; 191 } 192 193 if ( funcType->get_isVarArgs() ) { 194 os << ", ..."; 195 } // if 196 os << ")"; 197 } // if 198 199 typeString = os.str(); 200 201 if ( funcType->returnVals.size() == 0 ) { 202 typeString += ": void"; 203 } else { 204 typeString += ": " + genDemangleType(funcType->returnVals.front()->get_type(), ""); 205 } // if 206 207 // add forall 208 if( ! funcType->forall.empty() ) { 209 std::ostringstream os; 210 os << "forall("; 211 unsigned int i = 0; 212 for ( auto td : funcType->forall ) { 213 os << td->typeString() << " " << td->name; 214 if (! td->assertions.empty()) { 215 os << " | { "; 216 unsigned int j = 0; 217 for (DeclarationWithType * assert : td->assertions) { 218 os << genDemangleType(assert->get_type(), assert->name); 219 if (++j != td->assertions.size()) os << ", "; 220 } 221 os << "}"; 222 } 223 if (++i != funcType->forall.size()) os << ", "; 224 } 225 os << ")"; 226 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; 227 272 } 228 } 229 230 std::string GenType::handleGeneric( ReferenceToType * refType ) { 231 if ( ! refType->parameters.empty() ) { 232 std::ostringstream os; 233 // TODO: ??? 234 // PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 235 os << "("; 236 // cg.pass.genCommaList( refType->parameters.begin(), refType->parameters.end() ); 237 os << ") "; 238 return os.str(); 239 } 240 return ""; 241 } 242 243 void GenType::postvisit( StructInstType * structInst ) { 244 typeString = "struct " + structInst->name + handleGeneric( structInst ) + " " + typeString; 245 handleQualifiers( structInst ); 246 } 247 248 void GenType::postvisit( UnionInstType * unionInst ) { 249 typeString = "union " + unionInst->name + handleGeneric( unionInst ) + " " + typeString; 250 handleQualifiers( unionInst ); 251 } 252 253 void GenType::postvisit( EnumInstType * enumInst ) { 254 typeString = "enum " + enumInst->name + " " + typeString; 255 handleQualifiers( enumInst ); 256 } 257 258 void GenType::postvisit( TypeInstType * typeInst ) { 259 typeString = typeInst->name + " " + typeString; 260 handleQualifiers( typeInst ); 261 } 262 263 void GenType::postvisit( TupleType * tupleType ) { 264 unsigned int i = 0; 265 std::ostringstream os; 266 os << "["; 267 for ( Type * t : *tupleType ) { 268 i++; 269 os << genDemangleType( t, "" ) << (i == tupleType->size() ? "" : ", "); 270 } 271 os << "] "; 272 typeString = os.str() + typeString; 273 } 274 275 void GenType::postvisit( VarArgsType * varArgsType ) { 276 typeString = "__builtin_va_list " + typeString; 277 handleQualifiers( varArgsType ); 278 } 279 280 void GenType::postvisit( ZeroType * zeroType ) { 281 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 282 typeString = "zero_t " + typeString; 283 handleQualifiers( zeroType ); 284 } 285 286 void GenType::postvisit( OneType * oneType ) { 287 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 288 typeString = "one_t " + typeString; 289 handleQualifiers( oneType ); 290 } 291 292 void GenType::postvisit( GlobalScopeType * globalType ) { 293 handleQualifiers( globalType ); 294 } 295 296 void GenType::postvisit( QualifiedType * qualType ) { 297 std::ostringstream os; 298 os << genDemangleType( qualType->parent, "" ) << "." << genDemangleType( qualType->child, "" ) << typeString; 299 typeString = os.str(); 300 handleQualifiers( qualType ); 301 } 302 303 void GenType::handleQualifiers( Type * type ) { 304 if ( type->get_const() ) { 305 typeString = "const " + typeString; 306 } // if 307 if ( type->get_volatile() ) { 308 typeString = "volatile " + typeString; 309 } // if 310 if ( type->get_restrict() ) { 311 typeString = "__restrict " + typeString; 312 } // if 313 if ( type->get_atomic() ) { 314 typeString = "_Atomic " + typeString; 315 } // if 316 } 317 } 318 319 320 namespace SymTab { 321 namespace Mangler { 322 namespace { 323 struct StringView { 324 private: 325 std::string str; 326 size_t idx = 0; 327 // typedef Type * (StringView::*parser)(Type::Qualifiers); 328 typedef std::function<Type * (Type::Qualifiers)> parser; 329 std::vector<std::pair<std::string, parser>> parsers; 330 public: 331 StringView(const std::string & str); 332 333 bool done() const { return idx >= str.size(); } 334 char cur() const { assert(! done()); return str[idx]; } 335 336 bool expect(char ch) { return str[idx++] == ch; } 337 void next(size_t inc = 1) { idx += inc; } 338 339 /// determines if `pref` is a prefix of `str` 340 bool isPrefix(const std::string & pref); 341 bool extractNumber(size_t & out); 342 bool extractName(std::string & out); 343 bool stripMangleName(std::string & name); 344 345 Type * parseFunction(Type::Qualifiers tq); 346 Type * parseTuple(Type::Qualifiers tq); 347 Type * parseVoid(Type::Qualifiers tq); 348 Type * parsePointer(Type::Qualifiers tq); 349 Type * parseArray(Type::Qualifiers tq); 350 Type * parseStruct(Type::Qualifiers tq); 351 Type * parseUnion(Type::Qualifiers tq); 352 Type * parseEnum(Type::Qualifiers tq); 353 Type * parseType(Type::Qualifiers tq); 354 355 Type * parseType(); 356 bool parse(std::string & name, Type *& type); 357 }; 358 359 StringView::StringView(const std::string & str) : str(str) { 360 // basic types 361 for (size_t k = 0; k < BasicType::NUMBER_OF_BASIC_TYPES; ++k) { 362 parsers.emplace_back(Encoding::basicTypes[k], [k](Type::Qualifiers tq) { 363 PRINT( std::cerr << "basic type: " << k << std::endl; ) 364 return new BasicType(tq, (BasicType::Kind)k); 365 }); 366 } 367 // type variable types 368 for (size_t k = 0; k < TypeDecl::NUMBER_OF_KINDS; ++k) { 369 static const std::string typeVariableNames[] = { "DT", "DST", "OT", "FT", "TT", "ALT", }; 370 static_assert( 371 sizeof(typeVariableNames)/sizeof(typeVariableNames[0]) == TypeDecl::NUMBER_OF_KINDS, 372 "Each type variable kind should have a demangle name prefix" 373 ); 374 parsers.emplace_back(Encoding::typeVariables[k], [k, this](Type::Qualifiers tq) -> TypeInstType * { 375 PRINT( std::cerr << "type variable type: " << k << std::endl; ) 376 size_t N; 377 if (! extractNumber(N)) return nullptr; 378 return new TypeInstType(tq, toString(typeVariableNames[k], N), (TypeDecl::Kind)k != TypeDecl::Ftype); 379 }); 380 } 381 // everything else 382 parsers.emplace_back(Encoding::void_t, [this](Type::Qualifiers tq) { return parseVoid(tq); }); 383 parsers.emplace_back(Encoding::function, [this](Type::Qualifiers tq) { return parseFunction(tq); }); 384 parsers.emplace_back(Encoding::pointer, [this](Type::Qualifiers tq) { return parsePointer(tq); }); 385 parsers.emplace_back(Encoding::array, [this](Type::Qualifiers tq) { return parseArray(tq); }); 386 parsers.emplace_back(Encoding::tuple, [this](Type::Qualifiers tq) { return parseTuple(tq); }); 387 parsers.emplace_back(Encoding::struct_t, [this](Type::Qualifiers tq) { return parseStruct(tq); }); 388 parsers.emplace_back(Encoding::union_t, [this](Type::Qualifiers tq) { return parseUnion(tq); }); 389 parsers.emplace_back(Encoding::enum_t, [this](Type::Qualifiers tq) { return parseEnum(tq); }); 390 parsers.emplace_back(Encoding::type, [this](Type::Qualifiers tq) { return parseType(tq); }); 391 parsers.emplace_back(Encoding::zero, [](Type::Qualifiers tq) { return new ZeroType(tq); }); 392 parsers.emplace_back(Encoding::one, [](Type::Qualifiers tq) { return new OneType(tq); }); 393 } 394 395 bool StringView::extractNumber(size_t & out) { 396 std::stringstream numss; 397 if (idx >= str.size()) return false; 398 while (isdigit(str[idx])) { 399 numss << str[idx]; 400 ++idx; 401 if (idx == str.size()) break; 402 } 403 if (! (numss >> out)) return false; 404 PRINT( std::cerr << "extractNumber success: " << out << std::endl; ) 405 return true; 406 } 407 408 bool StringView::extractName(std::string & out) { 409 size_t len; 410 if (! extractNumber(len)) return false; 411 if (idx+len > str.size()) return false; 412 out = str.substr(idx, len); 413 idx += len; 414 PRINT( std::cerr << "extractName success: " << out << std::endl; ) 415 return true; 416 } 417 418 bool StringView::isPrefix(const std::string & pref) { 419 // if ( pref.size() > str.size()-idx ) return false; 420 // auto its = std::mismatch( pref.begin(), pref.end(), std::next(str.begin(), idx) ); 421 // if (its.first == pref.end()) { 422 // idx += pref.size(); 423 // return true; 424 // } 425 426 // This update is untested because there are no tests for this code. 427 if ( ::isPrefix( str, pref, idx ) ) { 428 idx += pref.size(); 429 return true; 430 } 431 return false; 432 } 433 434 // strips __NAME__cfa__TYPE_N, where N is [0-9]+: returns str is a match is found, returns empty string otherwise 435 bool StringView::stripMangleName(std::string & name) { 436 PRINT( std::cerr << "====== " << str.size() << " " << str << std::endl; ) 437 if (str.size() < 2+Encoding::manglePrefix.size()) return false; // +2 for at least _1 suffix 438 if ( ! isPrefix(Encoding::manglePrefix) || ! isdigit(str.back() ) ) return false; 439 440 // get name 441 if (! extractName(name)) return false; 442 443 // find bounds for type 444 PRINT( std::cerr << idx << " " << str.size() << std::endl; ) 445 PRINT( std::cerr << "["); 446 while (isdigit(str.back())) { 447 PRINT(std::cerr << "."); 448 str.pop_back(); 449 if (str.size() <= idx) return false; 450 } 451 PRINT( std::cerr << "]" << std::endl ); 452 if (str.back() != '_') return false; 453 str.pop_back(); 454 PRINT( std::cerr << str.size() << " " << name << " " << str.substr(idx) << std::endl; ) 455 return str.size() > idx; 456 } 457 458 Type * StringView::parseFunction(Type::Qualifiers tq) { 459 PRINT( std::cerr << "function..." << std::endl; ) 460 if (done()) return nullptr; 461 FunctionType * ftype = new FunctionType( tq, false ); 462 std::unique_ptr<Type> manager(ftype); 463 Type * retVal = parseType(); 464 if (! retVal) return nullptr; 465 PRINT( std::cerr << "with return type: " << retVal << std::endl; ) 466 ftype->returnVals.push_back(ObjectDecl::newObject("", retVal, nullptr)); 467 if (done() || ! expect('_')) return nullptr; 468 while (! done()) { 469 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 470 if (cur() == '_') return manager.release(); 471 Type * param = parseType(); 472 if (! param) return nullptr; 473 PRINT( std::cerr << "with parameter : " << param << std::endl; ) 474 ftype->parameters.push_back(ObjectDecl::newObject("", param, nullptr)); 475 } 476 return nullptr; 477 } 478 479 Type * StringView::parseTuple(Type::Qualifiers tq) { 480 PRINT( std::cerr << "tuple..." << std::endl; ) 481 std::list< Type * > types; 482 size_t ncomponents; 483 if (! extractNumber(ncomponents)) return nullptr; 484 for (size_t i = 0; i < ncomponents; ++i) { 485 // TODO: delete all on return 486 if (done()) return nullptr; 487 PRINT( std::cerr << "got ch: " << cur() << std::endl; ) 488 Type * t = parseType(); 489 if (! t) return nullptr; 490 PRINT( std::cerr << "with type : " << t << std::endl; ) 491 types.push_back(t); 492 } 493 return new TupleType( tq, types ); 494 } 495 496 Type * StringView::parseVoid(Type::Qualifiers tq) { 497 return new VoidType( tq ); 498 } 499 500 Type * StringView::parsePointer(Type::Qualifiers tq) { 501 PRINT( std::cerr << "pointer..." << std::endl; ) 502 Type * t = parseType(); 503 if (! t) return nullptr; 504 return new PointerType( tq, t ); 505 } 506 507 Type * StringView::parseArray(Type::Qualifiers tq) { 508 PRINT( std::cerr << "array..." << std::endl; ) 509 size_t length; 510 if (! extractNumber(length)) return nullptr; 511 Type * t = parseType(); 512 if (! t) return nullptr; 513 return new ArrayType( tq, t, new ConstantExpr( Constant::from_ulong(length) ), false, false ); 514 } 515 516 Type * StringView::parseStruct(Type::Qualifiers tq) { 517 PRINT( std::cerr << "struct..." << std::endl; ) 518 std::string name; 519 if (! extractName(name)) return nullptr; 520 return new StructInstType(tq, name); 521 } 522 523 Type * StringView::parseUnion(Type::Qualifiers tq) { 524 PRINT( std::cerr << "union..." << std::endl; ) 525 std::string name; 526 if (! extractName(name)) return nullptr; 527 return new UnionInstType(tq, name); 528 } 529 530 Type * StringView::parseEnum(Type::Qualifiers tq) { 531 PRINT( std::cerr << "enum..." << std::endl; ) 532 std::string name; 533 if (! extractName(name)) return nullptr; 534 return new EnumInstType(tq, name); 535 } 536 537 Type * StringView::parseType(Type::Qualifiers tq) { 538 PRINT( std::cerr << "type..." << std::endl; ) 539 std::string name; 540 if (! extractName(name)) return nullptr; 541 PRINT( std::cerr << "typename..." << name << std::endl; ) 542 return new TypeInstType(tq, name, false); 543 } 544 545 Type * StringView::parseType() { 546 if (done()) return nullptr; 547 548 std::list<TypeDecl *> forall; 549 if (isPrefix(Encoding::forall)) { 550 PRINT( std::cerr << "polymorphic with..." << std::endl; ) 551 size_t dcount, fcount, vcount, acount; 552 if (! extractNumber(dcount)) return nullptr; 553 PRINT( std::cerr << dcount << " dtypes" << std::endl; ) 554 if (! expect('_')) return nullptr; 555 if (! extractNumber(fcount)) return nullptr; 556 PRINT( std::cerr << fcount << " ftypes" << std::endl; ) 557 if (! expect('_')) return nullptr; 558 if (! extractNumber(vcount)) return nullptr; 559 PRINT( std::cerr << vcount << " ttypes" << std::endl; ) 560 if (! expect('_')) return nullptr; 561 if (! extractNumber(acount)) return nullptr; 562 PRINT( std::cerr << acount << " assertions" << std::endl; ) 563 if (! expect('_')) return nullptr; 564 for (size_t i = 0; i < acount; ++i) { 565 // TODO: need to recursively parse assertions, but for now just return nullptr so that 566 // demangler does not crash if there are assertions 567 return nullptr; 568 } 569 if (! expect('_')) return nullptr; 570 } 571 572 // qualifiers 573 Type::Qualifiers tq; 574 while (true) { 575 auto qual = std::find_if(Encoding::qualifiers.begin(), Encoding::qualifiers.end(), [this](decltype(Encoding::qualifiers)::value_type val) { 576 return isPrefix(val.second); 577 }); 578 if (qual == Encoding::qualifiers.end()) break; 579 tq |= qual->first; 580 } 581 582 // find the correct type parser and use it 583 auto iter = std::find_if(parsers.begin(), parsers.end(), [this](std::pair<std::string, parser> & p) { 584 return isPrefix(p.first); 585 }); 586 assertf(iter != parsers.end(), "Unhandled type letter: %c at index: %zd", cur(), idx); 587 Type * ret = iter->second(tq); 588 if (! ret) return nullptr; 589 ret->forall = std::move(forall); 590 return ret; 591 } 592 593 bool StringView::parse(std::string & name, Type *& type) { 594 if (! stripMangleName(name)) return false; 595 PRINT( std::cerr << "stripped name: " << name << std::endl; ) 596 Type * t = parseType(); 597 if (! t) return false; 598 type = t; 599 return true; 600 } 601 602 std::string demangle(const std::string & mangleName) { 603 SymTab::Mangler::StringView view(mangleName); 604 std::string name; 605 Type * type = nullptr; 606 if (! view.parse(name, type)) return mangleName; 607 std::unique_ptr<Type> manager(type); 608 return genDemangleType(type, name); 609 } 610 } // namespace 611 } // namespace Mangler 612 } // 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 613 318 614 319 extern "C" { 615 320 char * cforall_demangle(const char * mangleName, int option __attribute__((unused))) { 616 const std::string & demangleName = SymTab::Mangler::demangle(mangleName);321 const std::string & demangleName = Mangle::demangle(mangleName); 617 322 return strdup(demangleName.c_str()); 618 323 } -
src/SymTab/Demangle.h
r0030b508 rfc12f05 10 10 // Created On : Fri May 13 10:11:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri May 13 10:30:00 202213 // Update Count : 012 // Last Modified On : Mon Nov 6 15:48:00 2023 13 // Update Count : 1 14 14 // 15 15 … … 17 17 18 18 extern "C" { 19 /// Main interface to the demangler as a utility. 20 /// Caller must free the returned string. 19 21 char * cforall_demangle(const char *, int); 20 22 } -
src/SymTab/FixFunction.cc
r0030b508 rfc12f05 22 22 #include "AST/Type.hpp" 23 23 #include "Common/utility.h" // for copy 24 #include "SynTree/Declaration.h" // for FunctionDecl, ObjectDecl, Declarati...25 #include "SynTree/Expression.h" // for Expression26 #include "SynTree/Type.h" // for ArrayType, PointerType, Type, Basic...27 24 28 25 namespace SymTab { 29 class FixFunction_old : public WithShortCircuiting {30 typedef Mutator Parent;31 public:32 FixFunction_old() : isVoid( false ) {}33 34 void premutate(FunctionDecl *functionDecl);35 DeclarationWithType* postmutate(FunctionDecl *functionDecl);36 37 Type * postmutate(ArrayType * arrayType);38 39 void premutate(ArrayType * arrayType);40 void premutate(VoidType * voidType);41 void premutate(BasicType * basicType);42 void premutate(PointerType * pointerType);43 void premutate(StructInstType * aggregateUseType);44 void premutate(UnionInstType * aggregateUseType);45 void premutate(EnumInstType * aggregateUseType);46 void premutate(TraitInstType * aggregateUseType);47 void premutate(TypeInstType * aggregateUseType);48 void premutate(TupleType * tupleType);49 void premutate(VarArgsType * varArgsType);50 void premutate(ZeroType * zeroType);51 void premutate(OneType * oneType);52 53 bool isVoid;54 };55 56 DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) {57 // can't delete function type because it may contain assertions, so transfer ownership to new object58 ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes );59 pointer->location = functionDecl->location;60 functionDecl->attributes.clear();61 functionDecl->type = nullptr;62 delete functionDecl;63 return pointer;64 }65 66 // xxx - this passes on void[], e.g.67 // void foo(void [10]);68 // does not cause an error69 70 Type * FixFunction_old::postmutate(ArrayType *arrayType) {71 // need to recursively mutate the base type in order for multi-dimensional arrays to work.72 PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );73 pointerType->location = arrayType->location;74 arrayType->base = nullptr;75 arrayType->dimension = nullptr;76 delete arrayType;77 return pointerType;78 }79 80 void FixFunction_old::premutate(VoidType *) {81 isVoid = true;82 }83 84 void FixFunction_old::premutate(FunctionDecl *) { visit_children = false; }85 void FixFunction_old::premutate(ArrayType *) { visit_children = false; }86 void FixFunction_old::premutate(BasicType *) { visit_children = false; }87 void FixFunction_old::premutate(PointerType *) { visit_children = false; }88 void FixFunction_old::premutate(StructInstType *) { visit_children = false; }89 void FixFunction_old::premutate(UnionInstType *) { visit_children = false; }90 void FixFunction_old::premutate(EnumInstType *) { visit_children = false; }91 void FixFunction_old::premutate(TraitInstType *) { visit_children = false; }92 void FixFunction_old::premutate(TypeInstType *) { visit_children = false; }93 void FixFunction_old::premutate(TupleType *) { visit_children = false; }94 void FixFunction_old::premutate(VarArgsType *) { visit_children = false; }95 void FixFunction_old::premutate(ZeroType *) { visit_children = false; }96 void FixFunction_old::premutate(OneType *) { visit_children = false; }97 98 bool fixFunction( DeclarationWithType *& dwt ) {99 PassVisitor<FixFunction_old> fixer;100 dwt = dwt->acceptMutator( fixer );101 return fixer.pass.isVoid;102 }103 26 104 27 namespace { -
src/SymTab/FixFunction.h
r0030b508 rfc12f05 16 16 #pragma once 17 17 18 #include "Common/PassVisitor.h" // for PassVisitor19 #include "SynTree/SynTree.h" // for Types20 21 18 namespace ast { 22 19 class DeclWithType; … … 25 22 26 23 namespace SymTab { 27 /// Replaces function and array types by equivalent pointer types. Returns true if type is28 /// void29 bool fixFunction( DeclarationWithType *& );30 31 24 /// Returns declaration with function and array types replaced by equivalent pointer types. 32 25 /// Sets isVoid to true if type is void -
src/SymTab/Mangler.cc
r0030b508 rfc12f05 22 22 #include <string> // for string, char_traits, operator<< 23 23 24 #include "AST/Pass.hpp" 24 25 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 25 #include "Common/PassVisitor.h"26 26 #include "Common/ToString.hpp" // for toCString 27 27 #include "Common/SemanticError.h" // for SemanticError 28 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment29 #include "SynTree/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int...30 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType31 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<<32 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora...33 34 #include "AST/Pass.hpp"35 36 namespace SymTab {37 namespace Mangler {38 namespace {39 /// Mangles names to a unique C identifier40 struct Mangler_old : public WithShortCircuiting, public WithVisitorRef<Mangler_old>, public WithGuards {41 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams );42 Mangler_old( const Mangler_old & ) = delete;43 44 void previsit( const BaseSyntaxNode * ) { visit_children = false; }45 46 void postvisit( const ObjectDecl * declaration );47 void postvisit( const FunctionDecl * declaration );48 void postvisit( const TypeDecl * declaration );49 50 void postvisit( const VoidType * voidType );51 void postvisit( const BasicType * basicType );52 void postvisit( const PointerType * pointerType );53 void postvisit( const ArrayType * arrayType );54 void postvisit( const ReferenceType * refType );55 void postvisit( const FunctionType * functionType );56 void postvisit( const StructInstType * aggregateUseType );57 void postvisit( const UnionInstType * aggregateUseType );58 void postvisit( const EnumInstType * aggregateUseType );59 void postvisit( const TypeInstType * aggregateUseType );60 void postvisit( const TraitInstType * inst );61 void postvisit( const TupleType * tupleType );62 void postvisit( const VarArgsType * varArgsType );63 void postvisit( const ZeroType * zeroType );64 void postvisit( const OneType * oneType );65 void postvisit( const QualifiedType * qualType );66 67 std::string get_mangleName() { return mangleName; }68 private:69 std::string mangleName; ///< Mangled name being constructed70 typedef std::map< std::string, std::pair< int, int > > VarMapType;71 VarMapType varNums; ///< Map of type variables to indices72 int nextVarNum; ///< Next type variable index73 bool isTopLevel; ///< Is the Mangler at the top level74 bool mangleOverridable; ///< Specially mangle overridable built-in methods75 bool typeMode; ///< Produce a unique mangled name for a type76 bool mangleGenericParams; ///< Include generic parameters in name mangling if true77 bool inFunctionType = false; ///< Include type qualifiers if false.78 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type79 80 public:81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,82 int nextVarNum, const VarMapType& varNums );83 84 private:85 void mangleDecl( const DeclarationWithType * declaration );86 void mangleRef( const ReferenceToType * refType, std::string prefix );87 88 void printQualifiers( const Type *type );89 }; // Mangler_old90 } // namespace91 92 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {93 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );94 maybeAccept( decl, mangler );95 return mangler.pass.get_mangleName();96 }97 98 std::string mangleType( const Type * ty ) {99 PassVisitor<Mangler_old> mangler( false, true, true );100 maybeAccept( ty, mangler );101 return mangler.pass.get_mangleName();102 }103 104 std::string mangleConcrete( const Type * ty ) {105 PassVisitor<Mangler_old> mangler( false, false, false );106 maybeAccept( ty, mangler );107 return mangler.pass.get_mangleName();108 }109 110 namespace {111 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )112 : nextVarNum( 0 ), isTopLevel( true ),113 mangleOverridable( mangleOverridable ), typeMode( typeMode ),114 mangleGenericParams( mangleGenericParams ) {}115 116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,117 int nextVarNum, const VarMapType& varNums )118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),119 mangleOverridable( mangleOverridable ), typeMode( typeMode ),120 mangleGenericParams( mangleGenericParams ) {}121 122 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {123 bool wasTopLevel = isTopLevel;124 if ( isTopLevel ) {125 varNums.clear();126 nextVarNum = 0;127 isTopLevel = false;128 } // if129 mangleName += Encoding::manglePrefix;130 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );131 if ( opInfo ) {132 mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;133 } else {134 mangleName += std::to_string( declaration->name.size() ) + declaration->name;135 } // if136 maybeAccept( declaration->get_type(), *visitor );137 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {138 // want to be able to override autogenerated and intrinsic routines,139 // so they need a different name mangling140 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {141 mangleName += Encoding::autogen;142 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {143 mangleName += Encoding::intrinsic;144 } else {145 // if we add another kind of overridable function, this has to change146 assert( false && "unknown overrideable linkage" );147 } // if148 }149 isTopLevel = wasTopLevel;150 }151 152 void Mangler_old::postvisit( const ObjectDecl * declaration ) {153 mangleDecl( declaration );154 }155 156 void Mangler_old::postvisit( const FunctionDecl * declaration ) {157 mangleDecl( declaration );158 }159 160 void Mangler_old::postvisit( const VoidType * voidType ) {161 printQualifiers( voidType );162 mangleName += Encoding::void_t;163 }164 165 void Mangler_old::postvisit( const BasicType * basicType ) {166 printQualifiers( basicType );167 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );168 mangleName += Encoding::basicTypes[ basicType->kind ];169 }170 171 void Mangler_old::postvisit( const PointerType * pointerType ) {172 printQualifiers( pointerType );173 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers174 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName += Encoding::pointer;175 maybeAccept( pointerType->base, *visitor );176 }177 178 void Mangler_old::postvisit( const ArrayType * arrayType ) {179 // TODO: encode dimension180 printQualifiers( arrayType );181 mangleName += Encoding::array + "0";182 maybeAccept( arrayType->base, *visitor );183 }184 185 void Mangler_old::postvisit( const ReferenceType * refType ) {186 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.187 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),188 // by pretending every reference type is a function parameter.189 GuardValue( inFunctionType );190 inFunctionType = true;191 printQualifiers( refType );192 maybeAccept( refType->base, *visitor );193 }194 195 namespace {196 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {197 std::list< Type* > ret;198 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),199 std::mem_fun( &DeclarationWithType::get_type ) );200 return ret;201 }202 }203 204 void Mangler_old::postvisit( const FunctionType * functionType ) {205 printQualifiers( functionType );206 mangleName += Encoding::function;207 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,208 // since qualifiers on outermost parameter type do not differentiate function types, e.g.,209 // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different210 GuardValue( inFunctionType );211 inFunctionType = true;212 std::list< Type* > returnTypes = getTypes( functionType->returnVals );213 if (returnTypes.empty()) mangleName += Encoding::void_t;214 else acceptAll( returnTypes, *visitor );215 mangleName += "_";216 std::list< Type* > paramTypes = getTypes( functionType->parameters );217 acceptAll( paramTypes, *visitor );218 mangleName += "_";219 }220 221 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {222 printQualifiers( refType );223 224 mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;225 226 if ( mangleGenericParams ) {227 const std::list< Expression* > & params = refType->parameters;228 if ( ! params.empty() ) {229 mangleName += "_";230 for ( const Expression * param : params ) {231 const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );232 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));233 maybeAccept( paramType->type, *visitor );234 }235 mangleName += "_";236 }237 }238 }239 240 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {241 mangleRef( aggregateUseType, Encoding::struct_t );242 }243 244 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {245 mangleRef( aggregateUseType, Encoding::union_t );246 }247 248 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {249 mangleRef( aggregateUseType, Encoding::enum_t );250 }251 252 void Mangler_old::postvisit( const TypeInstType * typeInst ) {253 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );254 if ( varNum == varNums.end() ) {255 mangleRef( typeInst, Encoding::type );256 } else {257 printQualifiers( typeInst );258 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.259 // forall(dtype T) void f(T);260 // forall(dtype S) void f(S);261 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they262 // are first found and prefixing with the appropriate encoding for the type class.263 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );264 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );265 } // if266 }267 268 void Mangler_old::postvisit( const TraitInstType * inst ) {269 printQualifiers( inst );270 mangleName += std::to_string( inst->name.size() ) + inst->name;271 }272 273 void Mangler_old::postvisit( const TupleType * tupleType ) {274 printQualifiers( tupleType );275 mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );276 acceptAll( tupleType->types, *visitor );277 }278 279 void Mangler_old::postvisit( const VarArgsType * varArgsType ) {280 printQualifiers( varArgsType );281 static const std::string vargs = "__builtin_va_list";282 mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;283 }284 285 void Mangler_old::postvisit( const ZeroType * ) {286 mangleName += Encoding::zero;287 }288 289 void Mangler_old::postvisit( const OneType * ) {290 mangleName += Encoding::one;291 }292 293 void Mangler_old::postvisit( const QualifiedType * qualType ) {294 bool inqual = inQualifiedType;295 if (! inqual ) {296 // N marks the start of a qualified type297 inQualifiedType = true;298 mangleName += Encoding::qualifiedTypeStart;299 }300 maybeAccept( qualType->parent, *visitor );301 maybeAccept( qualType->child, *visitor );302 if ( ! inqual ) {303 // E marks the end of a qualified type304 inQualifiedType = false;305 mangleName += Encoding::qualifiedTypeEnd;306 }307 }308 309 void Mangler_old::postvisit( const TypeDecl * decl ) {310 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be311 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.312 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply313 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed314 // aside from the assert false.315 assertf( false, "Mangler_old should not visit typedecl: %s", toCString(decl));316 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );317 mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;318 }319 320 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {321 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {322 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;323 } // for324 }325 326 void Mangler_old::printQualifiers( const Type * type ) {327 // skip if not including qualifiers328 if ( typeMode ) return;329 if ( ! type->forall.empty() ) {330 std::list< std::string > assertionNames;331 int dcount = 0, fcount = 0, vcount = 0, acount = 0;332 mangleName += Encoding::forall;333 for ( const TypeDecl * i : type->forall ) {334 switch ( i->kind ) {335 case TypeDecl::Dtype:336 dcount++;337 break;338 case TypeDecl::Ftype:339 fcount++;340 break;341 case TypeDecl::Ttype:342 vcount++;343 break;344 default:345 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[i->kind].c_str() );346 } // switch347 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );348 for ( const DeclarationWithType * assert : i->assertions ) {349 PassVisitor<Mangler_old> sub_mangler(350 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );351 assert->accept( sub_mangler );352 assertionNames.push_back( sub_mangler.pass.get_mangleName() );353 acount++;354 } // for355 } // for356 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";357 for(const auto & a : assertionNames) mangleName += a;358 // std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );359 mangleName += "_";360 } // if361 if ( ! inFunctionType ) {362 // these qualifiers do not distinguish the outermost type of a function parameter363 if ( type->get_const() ) {364 mangleName += Encoding::qualifiers.at(Type::Const);365 } // if366 if ( type->get_volatile() ) {367 mangleName += Encoding::qualifiers.at(Type::Volatile);368 } // if369 // Removed due to restrict not affecting function compatibility in GCC370 // if ( type->get_isRestrict() ) {371 // mangleName += "E";372 // } // if373 if ( type->get_atomic() ) {374 mangleName += Encoding::qualifiers.at(Type::Atomic);375 } // if376 }377 if ( type->get_mutex() ) {378 mangleName += Encoding::qualifiers.at(Type::Mutex);379 } // if380 if ( inFunctionType ) {381 // turn off inFunctionType so that types can be differentiated for nested qualifiers382 GuardValue( inFunctionType );383 inFunctionType = false;384 }385 }386 } // namespace387 } // namespace Mangler388 } // namespace SymTab389 28 390 29 namespace Mangle { … … 476 115 mangleName += std::to_string( decl->name.size() ) + decl->name; 477 116 } // if 478 maybeAccept( decl->get_type(),*visitor );117 decl->get_type()->accept( *visitor ); 479 118 if ( mangleOverridable && decl->linkage.is_overrideable ) { 480 119 // want to be able to override autogenerated and intrinsic routines, … … 522 161 printQualifiers( arrayType ); 523 162 mangleName += Encoding::array + "0"; 524 maybeAccept( arrayType->base.get(),*visitor );163 arrayType->base->accept( *visitor ); 525 164 } 526 165 … … 532 171 inFunctionType = true; 533 172 printQualifiers( refType ); 534 maybeAccept( refType->base.get(),*visitor );173 refType->base->accept( *visitor ); 535 174 } 536 175 … … 561 200 auto paramType = dynamic_cast< const ast::TypeExpr * >( param ); 562 201 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 563 maybeAccept( paramType->type.get(),*visitor );202 paramType->type->accept( *visitor ); 564 203 } 565 204 mangleName += "_"; … … 590 229 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they 591 230 // are first found and prefixing with the appropriate encoding for the type class. 592 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );231 assertf( varNum->second.second < ast::TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second ); 593 232 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first ); 594 233 } // if … … 622 261 void Mangler_new::postvisit( const ast::QualifiedType * qualType ) { 623 262 bool inqual = inQualifiedType; 624 if ( !inqual ) {263 if ( !inqual ) { 625 264 // N marks the start of a qualified type 626 265 inQualifiedType = true; 627 266 mangleName += Encoding::qualifiedTypeStart; 628 267 } 629 maybeAccept( qualType->parent.get(),*visitor );630 maybeAccept( qualType->child.get(),*visitor );631 if ( ! 268 qualType->parent->accept( *visitor ); 269 qualType->child->accept( *visitor ); 270 if ( !inqual ) { 632 271 // E marks the end of a qualified type 633 272 inQualifiedType = false; … … 691 330 // these qualifiers do not distinguish the outermost type of a function parameter 692 331 if ( type->is_const() ) { 693 mangleName += Encoding::qualifiers.at( Type::Const);332 mangleName += Encoding::qualifiers.at( ast::CV::Const ); 694 333 } // if 695 334 if ( type->is_volatile() ) { 696 mangleName += Encoding::qualifiers.at( Type::Volatile);335 mangleName += Encoding::qualifiers.at( ast::CV::Volatile ); 697 336 } // if 698 337 // Removed due to restrict not affecting function compatibility in GCC … … 701 340 // } // if 702 341 if ( type->is_atomic() ) { 703 mangleName += Encoding::qualifiers.at( Type::Atomic);342 mangleName += Encoding::qualifiers.at( ast::CV::Atomic ); 704 343 } // if 705 344 } 706 345 if ( type->is_mutex() ) { 707 mangleName += Encoding::qualifiers.at( Type::Mutex);346 mangleName += Encoding::qualifiers.at( ast::CV::Mutex ); 708 347 } // if 709 348 if ( inFunctionType ) { -
src/SymTab/Mangler.h
r0030b508 rfc12f05 22 22 23 23 #include "AST/Bitfield.hpp" 24 #include "SynTree/SynTree.h" // for Types25 #include "SynTree/Visitor.h" // for Visitor, maybeAccept26 24 27 25 // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling … … 35 33 class Node; 36 34 } 37 namespace ResolvExpr {38 class TypeEnvironment;39 }40 35 41 36 namespace SymTab { 42 37 namespace Mangler { 43 /// Mangle syntax tree object; primary interface to clients44 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );45 46 /// Mangle a type name; secondary interface47 std::string mangleType( const Type * ty );48 /// Mangle ignoring generic type parameters49 std::string mangleConcrete( const Type * ty );50 51 38 namespace Encoding { 52 39 extern const std::string manglePrefix; -
src/SymTab/ManglerCommon.cc
r0030b508 rfc12f05 15 15 16 16 #include "Mangler.h" 17 #include "SynTree/Type.h" 18 #include "SynTree/Declaration.h" 17 18 #include "AST/Decl.hpp" 19 #include "AST/Type.hpp" 19 20 20 21 namespace SymTab { … … 39 40 // - "Di" char32_t 40 41 // - "Ds" char16_t 41 const std::string basicTypes[ BasicType::NUMBER_OF_BASIC_TYPES] = {42 const std::string basicTypes[ast::BasicType::NUMBER_OF_BASIC_TYPES] = { 42 43 "b", // _Bool 43 44 "c", // char … … 79 80 // GENERATED END 80 81 static_assert( 81 sizeof(basicTypes)/sizeof(basicTypes[0]) == BasicType::NUMBER_OF_BASIC_TYPES,82 sizeof(basicTypes)/sizeof(basicTypes[0]) == ast::BasicType::NUMBER_OF_BASIC_TYPES, 82 83 "Each basic type kind should have a corresponding mangler letter" 83 84 ); 84 85 85 86 const std::map<int, std::string> qualifiers = { 86 { Type::Const, "K" },87 { Type::Volatile, "V" },88 { Type::Atomic, "DA" }, // A is array, so need something unique for atmoic. For now, go with multiletter DA89 { Type::Mutex, "X" },87 { ast::CV::Const, "K" }, 88 { ast::CV::Volatile, "V" }, 89 { ast::CV::Atomic, "DA" }, // A is array, so need something unique for atmoic. For now, go with multiletter DA 90 { ast::CV::Mutex, "X" }, 90 91 }; 91 92 … … 111 112 }; 112 113 static_assert( 113 sizeof(typeVariables) / sizeof(typeVariables[0]) == TypeDecl::NUMBER_OF_KINDS,114 sizeof(typeVariables) / sizeof(typeVariables[0]) == ast::TypeDecl::NUMBER_OF_KINDS, 114 115 "Each type variable kind should have a corresponding mangler prefix" 115 116 ); -
src/SymTab/demangler.cc
r0030b508 rfc12f05 2 2 #include <iostream> 3 3 #include <fstream> 4 using namespace std;5 4 6 void f(const std::string & mangleName) {5 void demangleAndPrint(const std::string & mangleName) { 7 6 char * demangleName = cforall_demangle(mangleName.c_str(), 0); 8 cout << mangleName << " => " << std::flush << demangleName <<endl;7 std::cout << mangleName << " => " << demangleName << std::endl; 9 8 free(demangleName); 10 9 } 11 10 12 int main() { 13 ifstream in("in-demangle.txt"); 11 int main(int argc, char * argv[]) { 12 char const * fileName = (1 < argc) ? argv[1] : "in-demangle.txt"; 13 std::ifstream in(fileName); 14 14 15 std::string line; 15 while (getline(in, line)) { 16 if (line.empty()) { cout << "=================================" << endl; continue; } 17 else if (line[0] == '#') continue; 18 f(line); 16 while (std::getline(in, line)) { 17 if (line.empty()) { 18 std::cout << "=================================" << std::endl; 19 } else if (line[0] == '#') { 20 continue; 21 } else { 22 demangleAndPrint(line); 23 } 19 24 } 20 25 } -
src/SymTab/module.mk
r0030b508 rfc12f05 16 16 17 17 SRC_SYMTAB = \ 18 SymTab/Autogen.cc \19 SymTab/Autogen.h \20 18 SymTab/FixFunction.cc \ 21 19 SymTab/FixFunction.h \ 22 20 SymTab/GenImplicitCall.cpp \ 23 21 SymTab/GenImplicitCall.hpp \ 24 SymTab/Indexer.cc \25 SymTab/Indexer.h \26 22 SymTab/Mangler.cc \ 27 23 SymTab/ManglerCommon.cc \ 28 SymTab/Mangler.h \ 29 SymTab/ValidateType.cc \ 30 SymTab/ValidateType.h 24 SymTab/Mangler.h 31 25 32 SRC += $(SRC_SYMTAB) \ 33 SymTab/Validate.cc \ 34 SymTab/Validate.h 26 SRC += $(SRC_SYMTAB) 35 27 36 28 SRCDEMANGLE += $(SRC_SYMTAB) \
Note:
See TracChangeset
for help on using the changeset viewer.