Changeset 8d182b1 for src/SymTab
- Timestamp:
- Nov 14, 2023, 12:19:09 PM (2 years 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. - Location:
- src/SymTab
- Files:
-
- 8 deleted
- 8 edited
-
Autogen.cc (deleted)
-
Autogen.h (deleted)
-
Demangle.cc (modified) (2 diffs)
-
FixFunction.cc (modified) (3 diffs)
-
FixFunction.h (modified) (2 diffs)
-
GenImplicitCall.cpp (modified) (5 diffs)
-
GenImplicitCall.hpp (modified) (1 diff)
-
Indexer.cc (deleted)
-
Indexer.h (deleted)
-
Mangler.cc (modified) (19 diffs)
-
Mangler.h (modified) (2 diffs)
-
Validate.cc (deleted)
-
Validate.h (deleted)
-
ValidateType.cc (deleted)
-
ValidateType.h (deleted)
-
module.mk (modified) (1 diff)
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 } -
src/SymTab/FixFunction.cc
rdf8ba61a r8d182b1 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 { 105 struct FixFunction _newfinal : public ast::WithShortCircuiting {28 struct FixFunction final : public ast::WithShortCircuiting { 106 29 bool isVoid = false; 107 30 … … 147 70 148 71 const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ) { 149 ast::Pass< FixFunction _new> fixer;72 ast::Pass< FixFunction > fixer; 150 73 dwt = dwt->accept( fixer ); 151 74 isVoid |= fixer.core.isVoid; … … 154 77 155 78 const ast::Type * fixFunction( const ast::Type * type, bool & isVoid ) { 156 ast::Pass< FixFunction _new> fixer;79 ast::Pass< FixFunction > fixer; 157 80 type = type->accept( fixer ); 158 81 isVoid |= fixer.core.isVoid; -
src/SymTab/FixFunction.h
rdf8ba61a r8d182b1 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/GenImplicitCall.cpp
rdf8ba61a r8d182b1 32 32 template< typename OutIter > 33 33 ast::ptr< ast::Stmt > genCall( 34 InitTweak::InitExpander _new& srcParam, const ast::Expr * dstParam,34 InitTweak::InitExpander & srcParam, const ast::Expr * dstParam, 35 35 const CodeLocation & loc, const std::string & fname, OutIter && out, 36 36 const ast::Type * type, const ast::Type * addCast, LoopDirection forward = LoopForward ); … … 42 42 template< typename OutIter > 43 43 ast::ptr< ast::Stmt > genScalarCall( 44 InitTweak::InitExpander _new& srcParam, const ast::Expr * dstParam,44 InitTweak::InitExpander & srcParam, const ast::Expr * dstParam, 45 45 const CodeLocation & loc, std::string fname, OutIter && out, const ast::Type * type, 46 46 const ast::Type * addCast = nullptr … … 98 98 template< typename OutIter > 99 99 void genArrayCall( 100 InitTweak::InitExpander _new& srcParam, const ast::Expr * dstParam,100 InitTweak::InitExpander & srcParam, const ast::Expr * dstParam, 101 101 const CodeLocation & loc, const std::string & fname, OutIter && out, 102 102 const ast::ArrayType * array, const ast::Type * addCast = nullptr, … … 167 167 template< typename OutIter > 168 168 ast::ptr< ast::Stmt > genCall( 169 InitTweak::InitExpander _new& srcParam, const ast::Expr * dstParam,169 InitTweak::InitExpander & srcParam, const ast::Expr * dstParam, 170 170 const CodeLocation & loc, const std::string & fname, OutIter && out, 171 171 const ast::Type * type, const ast::Type * addCast, LoopDirection forward … … 185 185 186 186 ast::ptr< ast::Stmt > genImplicitCall( 187 InitTweak::InitExpander _new& srcParam, const ast::Expr * dstParam,187 InitTweak::InitExpander & srcParam, const ast::Expr * dstParam, 188 188 const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj, 189 189 LoopDirection forward -
src/SymTab/GenImplicitCall.hpp
rdf8ba61a r8d182b1 26 26 /// dstParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 27 27 ast::ptr<ast::Stmt> genImplicitCall( 28 InitTweak::InitExpander _new& srcParam, const ast::Expr * dstParam,28 InitTweak::InitExpander & srcParam, const ast::Expr * dstParam, 29 29 const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * obj, 30 30 LoopDirection forward = LoopForward -
src/SymTab/Mangler.cc
rdf8ba61a r8d182b1 24 24 #include "AST/Pass.hpp" 25 25 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 26 #include "Common/PassVisitor.h"27 26 #include "Common/ToString.hpp" // for toCString 28 27 #include "Common/SemanticError.h" // for SemanticError 29 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment30 #include "SynTree/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int...31 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType32 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<<33 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora...34 35 namespace SymTab {36 namespace Mangler {37 namespace {38 /// Mangles names to a unique C identifier39 struct Mangler_old : public WithShortCircuiting, public WithVisitorRef<Mangler_old>, public WithGuards {40 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams );41 Mangler_old( const Mangler_old & ) = delete;42 43 void previsit( const BaseSyntaxNode * ) { visit_children = false; }44 45 void postvisit( const ObjectDecl * declaration );46 void postvisit( const FunctionDecl * declaration );47 void postvisit( const TypeDecl * declaration );48 49 void postvisit( const VoidType * voidType );50 void postvisit( const BasicType * basicType );51 void postvisit( const PointerType * pointerType );52 void postvisit( const ArrayType * arrayType );53 void postvisit( const ReferenceType * refType );54 void postvisit( const FunctionType * functionType );55 void postvisit( const StructInstType * aggregateUseType );56 void postvisit( const UnionInstType * aggregateUseType );57 void postvisit( const EnumInstType * aggregateUseType );58 void postvisit( const TypeInstType * aggregateUseType );59 void postvisit( const TraitInstType * inst );60 void postvisit( const TupleType * tupleType );61 void postvisit( const VarArgsType * varArgsType );62 void postvisit( const ZeroType * zeroType );63 void postvisit( const OneType * oneType );64 void postvisit( const QualifiedType * qualType );65 66 std::string get_mangleName() { return mangleName; }67 private:68 std::string mangleName; ///< Mangled name being constructed69 typedef std::map< std::string, std::pair< int, int > > VarMapType;70 VarMapType varNums; ///< Map of type variables to indices71 int nextVarNum; ///< Next type variable index72 bool isTopLevel; ///< Is the Mangler at the top level73 bool mangleOverridable; ///< Specially mangle overridable built-in methods74 bool typeMode; ///< Produce a unique mangled name for a type75 bool mangleGenericParams; ///< Include generic parameters in name mangling if true76 bool inFunctionType = false; ///< Include type qualifiers if false.77 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type78 79 public:80 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,81 int nextVarNum, const VarMapType& varNums );82 83 private:84 void mangleDecl( const DeclarationWithType * declaration );85 void mangleRef( const ReferenceToType * refType, std::string prefix );86 87 void printQualifiers( const Type *type );88 }; // Mangler_old89 } // namespace90 91 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {92 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );93 maybeAccept( decl, mangler );94 return mangler.pass.get_mangleName();95 }96 97 std::string mangleType( const Type * ty ) {98 PassVisitor<Mangler_old> mangler( false, true, true );99 maybeAccept( ty, mangler );100 return mangler.pass.get_mangleName();101 }102 103 std::string mangleConcrete( const Type * ty ) {104 PassVisitor<Mangler_old> mangler( false, false, false );105 maybeAccept( ty, mangler );106 return mangler.pass.get_mangleName();107 }108 109 namespace {110 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )111 : nextVarNum( 0 ), isTopLevel( true ),112 mangleOverridable( mangleOverridable ), typeMode( typeMode ),113 mangleGenericParams( mangleGenericParams ) {}114 115 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,116 int nextVarNum, const VarMapType& varNums )117 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),118 mangleOverridable( mangleOverridable ), typeMode( typeMode ),119 mangleGenericParams( mangleGenericParams ) {}120 121 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {122 bool wasTopLevel = isTopLevel;123 if ( isTopLevel ) {124 varNums.clear();125 nextVarNum = 0;126 isTopLevel = false;127 } // if128 mangleName += Encoding::manglePrefix;129 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );130 if ( opInfo ) {131 mangleName += std::to_string( opInfo->outputName.size() ) + opInfo->outputName;132 } else {133 mangleName += std::to_string( declaration->name.size() ) + declaration->name;134 } // if135 maybeAccept( declaration->get_type(), *visitor );136 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {137 // want to be able to override autogenerated and intrinsic routines,138 // so they need a different name mangling139 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {140 mangleName += Encoding::autogen;141 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {142 mangleName += Encoding::intrinsic;143 } else {144 // if we add another kind of overridable function, this has to change145 assert( false && "unknown overrideable linkage" );146 } // if147 }148 isTopLevel = wasTopLevel;149 }150 151 void Mangler_old::postvisit( const ObjectDecl * declaration ) {152 mangleDecl( declaration );153 }154 155 void Mangler_old::postvisit( const FunctionDecl * declaration ) {156 mangleDecl( declaration );157 }158 159 void Mangler_old::postvisit( const VoidType * voidType ) {160 printQualifiers( voidType );161 mangleName += Encoding::void_t;162 }163 164 void Mangler_old::postvisit( const BasicType * basicType ) {165 printQualifiers( basicType );166 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );167 mangleName += Encoding::basicTypes[ basicType->kind ];168 }169 170 void Mangler_old::postvisit( const PointerType * pointerType ) {171 printQualifiers( pointerType );172 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers173 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName += Encoding::pointer;174 maybeAccept( pointerType->base, *visitor );175 }176 177 void Mangler_old::postvisit( const ArrayType * arrayType ) {178 // TODO: encode dimension179 printQualifiers( arrayType );180 mangleName += Encoding::array + "0";181 maybeAccept( arrayType->base, *visitor );182 }183 184 void Mangler_old::postvisit( const ReferenceType * refType ) {185 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.186 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),187 // by pretending every reference type is a function parameter.188 GuardValue( inFunctionType );189 inFunctionType = true;190 printQualifiers( refType );191 maybeAccept( refType->base, *visitor );192 }193 194 namespace {195 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {196 std::list< Type* > ret;197 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),198 std::mem_fun( &DeclarationWithType::get_type ) );199 return ret;200 }201 }202 203 void Mangler_old::postvisit( const FunctionType * functionType ) {204 printQualifiers( functionType );205 mangleName += Encoding::function;206 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,207 // since qualifiers on outermost parameter type do not differentiate function types, e.g.,208 // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different209 GuardValue( inFunctionType );210 inFunctionType = true;211 std::list< Type* > returnTypes = getTypes( functionType->returnVals );212 if (returnTypes.empty()) mangleName += Encoding::void_t;213 else acceptAll( returnTypes, *visitor );214 mangleName += "_";215 std::list< Type* > paramTypes = getTypes( functionType->parameters );216 acceptAll( paramTypes, *visitor );217 mangleName += "_";218 }219 220 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {221 printQualifiers( refType );222 223 mangleName += prefix + std::to_string( refType->name.length() ) + refType->name;224 225 if ( mangleGenericParams ) {226 const std::list< Expression* > & params = refType->parameters;227 if ( ! params.empty() ) {228 mangleName += "_";229 for ( const Expression * param : params ) {230 const TypeExpr * paramType = dynamic_cast< const TypeExpr * >( param );231 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));232 maybeAccept( paramType->type, *visitor );233 }234 mangleName += "_";235 }236 }237 }238 239 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {240 mangleRef( aggregateUseType, Encoding::struct_t );241 }242 243 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {244 mangleRef( aggregateUseType, Encoding::union_t );245 }246 247 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {248 mangleRef( aggregateUseType, Encoding::enum_t );249 }250 251 void Mangler_old::postvisit( const TypeInstType * typeInst ) {252 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );253 if ( varNum == varNums.end() ) {254 mangleRef( typeInst, Encoding::type );255 } else {256 printQualifiers( typeInst );257 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.258 // forall(dtype T) void f(T);259 // forall(dtype S) void f(S);260 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they261 // are first found and prefixing with the appropriate encoding for the type class.262 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );263 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first );264 } // if265 }266 267 void Mangler_old::postvisit( const TraitInstType * inst ) {268 printQualifiers( inst );269 mangleName += std::to_string( inst->name.size() ) + inst->name;270 }271 272 void Mangler_old::postvisit( const TupleType * tupleType ) {273 printQualifiers( tupleType );274 mangleName += Encoding::tuple + std::to_string( tupleType->types.size() );275 acceptAll( tupleType->types, *visitor );276 }277 278 void Mangler_old::postvisit( const VarArgsType * varArgsType ) {279 printQualifiers( varArgsType );280 static const std::string vargs = "__builtin_va_list";281 mangleName += Encoding::type + std::to_string( vargs.size() ) + vargs;282 }283 284 void Mangler_old::postvisit( const ZeroType * ) {285 mangleName += Encoding::zero;286 }287 288 void Mangler_old::postvisit( const OneType * ) {289 mangleName += Encoding::one;290 }291 292 void Mangler_old::postvisit( const QualifiedType * qualType ) {293 bool inqual = inQualifiedType;294 if (! inqual ) {295 // N marks the start of a qualified type296 inQualifiedType = true;297 mangleName += Encoding::qualifiedTypeStart;298 }299 maybeAccept( qualType->parent, *visitor );300 maybeAccept( qualType->child, *visitor );301 if ( ! inqual ) {302 // E marks the end of a qualified type303 inQualifiedType = false;304 mangleName += Encoding::qualifiedTypeEnd;305 }306 }307 308 void Mangler_old::postvisit( const TypeDecl * decl ) {309 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be310 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.311 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply312 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed313 // aside from the assert false.314 assertf( false, "Mangler_old should not visit typedecl: %s", toCString(decl));315 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );316 mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name;317 }318 319 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {320 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {321 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;322 } // for323 }324 325 void Mangler_old::printQualifiers( const Type * type ) {326 // skip if not including qualifiers327 if ( typeMode ) return;328 if ( ! type->forall.empty() ) {329 std::list< std::string > assertionNames;330 int dcount = 0, fcount = 0, vcount = 0, acount = 0;331 mangleName += Encoding::forall;332 for ( const TypeDecl * i : type->forall ) {333 switch ( i->kind ) {334 case TypeDecl::Dtype:335 dcount++;336 break;337 case TypeDecl::Ftype:338 fcount++;339 break;340 case TypeDecl::Ttype:341 vcount++;342 break;343 default:344 assertf( false, "unimplemented kind for type variable %s", SymTab::Mangler::Encoding::typeVariables[i->kind].c_str() );345 } // switch346 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );347 for ( const DeclarationWithType * assert : i->assertions ) {348 PassVisitor<Mangler_old> sub_mangler(349 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );350 assert->accept( sub_mangler );351 assertionNames.push_back( sub_mangler.pass.get_mangleName() );352 acount++;353 } // for354 } // for355 mangleName += std::to_string( dcount ) + "_" + std::to_string( fcount ) + "_" + std::to_string( vcount ) + "_" + std::to_string( acount ) + "_";356 for(const auto & a : assertionNames) mangleName += a;357 // std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );358 mangleName += "_";359 } // if360 if ( ! inFunctionType ) {361 // these qualifiers do not distinguish the outermost type of a function parameter362 if ( type->get_const() ) {363 mangleName += Encoding::qualifiers.at(Type::Const);364 } // if365 if ( type->get_volatile() ) {366 mangleName += Encoding::qualifiers.at(Type::Volatile);367 } // if368 // Removed due to restrict not affecting function compatibility in GCC369 // if ( type->get_isRestrict() ) {370 // mangleName += "E";371 // } // if372 if ( type->get_atomic() ) {373 mangleName += Encoding::qualifiers.at(Type::Atomic);374 } // if375 }376 if ( type->get_mutex() ) {377 mangleName += Encoding::qualifiers.at(Type::Mutex);378 } // if379 if ( inFunctionType ) {380 // turn off inFunctionType so that types can be differentiated for nested qualifiers381 GuardValue( inFunctionType );382 inFunctionType = false;383 }384 }385 } // namespace386 } // namespace Mangler387 } // namespace SymTab388 28 389 29 namespace Mangle { 390 30 namespace { 391 31 /// Mangles names to a unique C identifier 392 struct Mangler _new : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler_new>, public ast::WithGuards {393 Mangler _new( Mangle::Mode mode );394 Mangler _new( const Mangler_new& ) = delete;32 struct Mangler : public ast::WithShortCircuiting, public ast::WithVisitorRef<Mangler>, public ast::WithGuards { 33 Mangler( Mangle::Mode mode ); 34 Mangler( const Mangler & ) = delete; 395 35 396 36 void previsit( const ast::Node * ) { visit_children = false; } … … 432 72 433 73 private: 434 Mangler _new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,74 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 435 75 int nextVarNum, const VarMapType& varNums ); 436 friend class ast::Pass<Mangler _new>;76 friend class ast::Pass<Mangler>; 437 77 438 78 private: … … 441 81 442 82 void printQualifiers( const ast::Type *type ); 443 }; // Mangler _new83 }; // Mangler 444 84 } // namespace 445 85 446 86 std::string mangle( const ast::Node * decl, Mangle::Mode mode ) { 447 return ast::Pass<Mangler _new>::read( decl, mode );87 return ast::Pass<Mangler>::read( decl, mode ); 448 88 } 449 89 450 90 namespace { 451 Mangler _new::Mangler_new( Mangle::Mode mode )91 Mangler::Mangler( Mangle::Mode mode ) 452 92 : nextVarNum( 0 ), isTopLevel( true ), 453 93 mangleOverridable ( ! mode.no_overrideable ), … … 455 95 mangleGenericParams( ! mode.no_generic_params ) {} 456 96 457 Mangler _new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,97 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 458 98 int nextVarNum, const VarMapType& varNums ) 459 99 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ), … … 461 101 mangleGenericParams( mangleGenericParams ) {} 462 102 463 void Mangler _new::mangleDecl( const ast::DeclWithType * decl ) {103 void Mangler::mangleDecl( const ast::DeclWithType * decl ) { 464 104 bool wasTopLevel = isTopLevel; 465 105 if ( isTopLevel ) { … … 491 131 } 492 132 493 void Mangler _new::postvisit( const ast::ObjectDecl * decl ) {133 void Mangler::postvisit( const ast::ObjectDecl * decl ) { 494 134 mangleDecl( decl ); 495 135 } 496 136 497 void Mangler _new::postvisit( const ast::FunctionDecl * decl ) {137 void Mangler::postvisit( const ast::FunctionDecl * decl ) { 498 138 mangleDecl( decl ); 499 139 } 500 140 501 void Mangler _new::postvisit( const ast::VoidType * voidType ) {141 void Mangler::postvisit( const ast::VoidType * voidType ) { 502 142 printQualifiers( voidType ); 503 143 mangleName += Encoding::void_t; 504 144 } 505 145 506 void Mangler _new::postvisit( const ast::BasicType * basicType ) {146 void Mangler::postvisit( const ast::BasicType * basicType ) { 507 147 printQualifiers( basicType ); 508 148 assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind ); … … 510 150 } 511 151 512 void Mangler _new::postvisit( const ast::PointerType * pointerType ) {152 void Mangler::postvisit( const ast::PointerType * pointerType ) { 513 153 printQualifiers( pointerType ); 514 154 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers … … 517 157 } 518 158 519 void Mangler _new::postvisit( const ast::ArrayType * arrayType ) {159 void Mangler::postvisit( const ast::ArrayType * arrayType ) { 520 160 // TODO: encode dimension 521 161 printQualifiers( arrayType ); … … 524 164 } 525 165 526 void Mangler _new::postvisit( const ast::ReferenceType * refType ) {166 void Mangler::postvisit( const ast::ReferenceType * refType ) { 527 167 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload. 528 168 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.), … … 534 174 } 535 175 536 void Mangler _new::postvisit( const ast::FunctionType * functionType ) {176 void Mangler::postvisit( const ast::FunctionType * functionType ) { 537 177 printQualifiers( functionType ); 538 178 mangleName += Encoding::function; … … 549 189 } 550 190 551 void Mangler _new::mangleRef(191 void Mangler::mangleRef( 552 192 const ast::BaseInstType * refType, const std::string & prefix ) { 553 193 printQualifiers( refType ); … … 566 206 } 567 207 568 void Mangler _new::postvisit( const ast::StructInstType * aggregateUseType ) {208 void Mangler::postvisit( const ast::StructInstType * aggregateUseType ) { 569 209 mangleRef( aggregateUseType, Encoding::struct_t ); 570 210 } 571 211 572 void Mangler _new::postvisit( const ast::UnionInstType * aggregateUseType ) {212 void Mangler::postvisit( const ast::UnionInstType * aggregateUseType ) { 573 213 mangleRef( aggregateUseType, Encoding::union_t ); 574 214 } 575 215 576 void Mangler _new::postvisit( const ast::EnumInstType * aggregateUseType ) {216 void Mangler::postvisit( const ast::EnumInstType * aggregateUseType ) { 577 217 mangleRef( aggregateUseType, Encoding::enum_t ); 578 218 } 579 219 580 void Mangler _new::postvisit( const ast::TypeInstType * typeInst ) {220 void Mangler::postvisit( const ast::TypeInstType * typeInst ) { 581 221 VarMapType::iterator varNum = varNums.find( typeInst->name ); 582 222 if ( varNum == varNums.end() ) { … … 594 234 } 595 235 596 void Mangler _new::postvisit( const ast::TraitInstType * inst ) {236 void Mangler::postvisit( const ast::TraitInstType * inst ) { 597 237 printQualifiers( inst ); 598 238 mangleName += std::to_string( inst->name.size() ) + inst->name; 599 239 } 600 240 601 void Mangler _new::postvisit( const ast::TupleType * tupleType ) {241 void Mangler::postvisit( const ast::TupleType * tupleType ) { 602 242 printQualifiers( tupleType ); 603 243 mangleName += Encoding::tuple + std::to_string( tupleType->types.size() ); … … 605 245 } 606 246 607 void Mangler _new::postvisit( const ast::VarArgsType * varArgsType ) {247 void Mangler::postvisit( const ast::VarArgsType * varArgsType ) { 608 248 printQualifiers( varArgsType ); 609 249 static const std::string vargs = "__builtin_va_list"; … … 611 251 } 612 252 613 void Mangler _new::postvisit( const ast::ZeroType * ) {253 void Mangler::postvisit( const ast::ZeroType * ) { 614 254 mangleName += Encoding::zero; 615 255 } 616 256 617 void Mangler _new::postvisit( const ast::OneType * ) {257 void Mangler::postvisit( const ast::OneType * ) { 618 258 mangleName += Encoding::one; 619 259 } 620 260 621 void Mangler _new::postvisit( const ast::QualifiedType * qualType ) {261 void Mangler::postvisit( const ast::QualifiedType * qualType ) { 622 262 bool inqual = inQualifiedType; 623 263 if ( !inqual ) { … … 635 275 } 636 276 637 void Mangler _new::postvisit( const ast::TypeDecl * decl ) {277 void Mangler::postvisit( const ast::TypeDecl * decl ) { 638 278 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be 639 279 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa. … … 641 281 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed 642 282 // aside from the assert false. 643 assertf(false, "Mangler _newshould not visit typedecl: %s", toCString(decl));283 assertf(false, "Mangler should not visit typedecl: %s", toCString(decl)); 644 284 assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind ); 645 285 mangleName += Encoding::typeVariables[ decl->kind ] + std::to_string( decl->name.length() ) + decl->name; … … 653 293 } 654 294 655 void Mangler _new::printQualifiers( const ast::Type * type ) {295 void Mangler::printQualifiers( const ast::Type * type ) { 656 296 // skip if not including qualifiers 657 297 if ( typeMode ) return; … … 678 318 } // for 679 319 for ( auto & assert : funcType->assertions ) { 680 assertionNames.push_back( ast::Pass<Mangler _new>::read(320 assertionNames.push_back( ast::Pass<Mangler>::read( 681 321 assert->var.get(), 682 322 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums ) ); -
src/SymTab/Mangler.h
rdf8ba61a r8d182b1 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/module.mk
rdf8ba61a r8d182b1 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.