Changes in src/SymTab/Mangler.cc [c6b4432:9feb34b]
- File:
-
- 1 edited
-
src/SymTab/Mangler.cc (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Mangler.cc
rc6b4432 r9feb34b 22 22 #include <string> // for string, char_traits, operator<< 23 23 24 #include "AST/Pass.hpp"25 24 #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 TypeEnvironment 29 #include "SynTree/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... 30 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType 31 #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 identifier 40 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 constructed 70 typedef std::map< std::string, std::pair< int, int > > VarMapType; 71 VarMapType varNums; ///< Map of type variables to indices 72 int nextVarNum; ///< Next type variable index 73 bool isTopLevel; ///< Is the Mangler at the top level 74 bool mangleOverridable; ///< Specially mangle overridable built-in methods 75 bool typeMode; ///< Produce a unique mangled name for a type 76 bool mangleGenericParams; ///< Include generic parameters in name mangling if true 77 bool inFunctionType = false; ///< Include type qualifiers if false. 78 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type 79 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_old 90 } // namespace 91 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 } // if 129 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 } // if 136 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 mangling 140 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 change 146 assert( false && "unknown overrideable linkage" ); 147 } // if 148 } 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 pointers 174 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 dimension 180 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 different 210 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 they 262 // 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 } // if 266 } 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 type 297 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 type 304 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 be 311 // 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 deeply 313 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed 314 // 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 } // for 324 } 325 326 void Mangler_old::printQualifiers( const Type * type ) { 327 // skip if not including qualifiers 328 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 } // switch 347 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 } // for 355 } // for 356 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 } // if 361 if ( ! inFunctionType ) { 362 // these qualifiers do not distinguish the outermost type of a function parameter 363 if ( type->get_const() ) { 364 mangleName += Encoding::qualifiers.at(Type::Const); 365 } // if 366 if ( type->get_volatile() ) { 367 mangleName += Encoding::qualifiers.at(Type::Volatile); 368 } // if 369 // Removed due to restrict not affecting function compatibility in GCC 370 // if ( type->get_isRestrict() ) { 371 // mangleName += "E"; 372 // } // if 373 if ( type->get_atomic() ) { 374 mangleName += Encoding::qualifiers.at(Type::Atomic); 375 } // if 376 } 377 if ( type->get_mutex() ) { 378 mangleName += Encoding::qualifiers.at(Type::Mutex); 379 } // if 380 if ( inFunctionType ) { 381 // turn off inFunctionType so that types can be differentiated for nested qualifiers 382 GuardValue( inFunctionType ); 383 inFunctionType = false; 384 } 385 } 386 } // namespace 387 } // namespace Mangler 388 } // namespace SymTab 28 389 29 390 namespace Mangle { … … 115 476 mangleName += std::to_string( decl->name.size() ) + decl->name; 116 477 } // if 117 decl->get_type()->accept(*visitor );478 maybeAccept( decl->get_type(), *visitor ); 118 479 if ( mangleOverridable && decl->linkage.is_overrideable ) { 119 480 // want to be able to override autogenerated and intrinsic routines, … … 161 522 printQualifiers( arrayType ); 162 523 mangleName += Encoding::array + "0"; 163 arrayType->base->accept(*visitor );524 maybeAccept( arrayType->base.get(), *visitor ); 164 525 } 165 526 … … 171 532 inFunctionType = true; 172 533 printQualifiers( refType ); 173 refType->base->accept(*visitor );534 maybeAccept( refType->base.get(), *visitor ); 174 535 } 175 536 … … 200 561 auto paramType = dynamic_cast< const ast::TypeExpr * >( param ); 201 562 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param)); 202 paramType->type->accept(*visitor );563 maybeAccept( paramType->type.get(), *visitor ); 203 564 } 204 565 mangleName += "_"; … … 229 590 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they 230 591 // are first found and prefixing with the appropriate encoding for the type class. 231 assertf( varNum->second.second < ast::TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );592 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second ); 232 593 mangleName += Encoding::typeVariables[varNum->second.second] + std::to_string( varNum->second.first ); 233 594 } // if … … 261 622 void Mangler_new::postvisit( const ast::QualifiedType * qualType ) { 262 623 bool inqual = inQualifiedType; 263 if ( !inqual ) {624 if (! inqual ) { 264 625 // N marks the start of a qualified type 265 626 inQualifiedType = true; 266 627 mangleName += Encoding::qualifiedTypeStart; 267 628 } 268 qualType->parent->accept(*visitor );269 qualType->child->accept(*visitor );270 if ( ! inqual ) {629 maybeAccept( qualType->parent.get(), *visitor ); 630 maybeAccept( qualType->child.get(), *visitor ); 631 if ( ! inqual ) { 271 632 // E marks the end of a qualified type 272 633 inQualifiedType = false; … … 330 691 // these qualifiers do not distinguish the outermost type of a function parameter 331 692 if ( type->is_const() ) { 332 mangleName += Encoding::qualifiers.at( ast::CV::Const);693 mangleName += Encoding::qualifiers.at(Type::Const); 333 694 } // if 334 695 if ( type->is_volatile() ) { 335 mangleName += Encoding::qualifiers.at( ast::CV::Volatile);696 mangleName += Encoding::qualifiers.at(Type::Volatile); 336 697 } // if 337 698 // Removed due to restrict not affecting function compatibility in GCC … … 340 701 // } // if 341 702 if ( type->is_atomic() ) { 342 mangleName += Encoding::qualifiers.at( ast::CV::Atomic);703 mangleName += Encoding::qualifiers.at(Type::Atomic); 343 704 } // if 344 705 } 345 706 if ( type->is_mutex() ) { 346 mangleName += Encoding::qualifiers.at( ast::CV::Mutex);707 mangleName += Encoding::qualifiers.at(Type::Mutex); 347 708 } // if 348 709 if ( inFunctionType ) {
Note:
See TracChangeset
for help on using the changeset viewer.