source: src/SymTab/Mangler.cc@ c20ba169

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since c20ba169 was 60a8062, checked in by Peter A. Buhr <pabuhr@…>, 6 years ago

rewrite most of OperatorTable and change caller modules to use new interface

  • Property mode set to 100644
File size: 29.8 KB
RevLine 
[0dd3a2f]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[8c49c0e]7// Mangler.cc --
[0dd3a2f]8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 21:40:29 2015
[201aeb9]11// Last Modified By : Peter A. Buhr
[60a8062]12// Last Modified On : Sat Feb 15 13:55:12 2020
13// Update Count : 33
[0dd3a2f]14//
[30f9072]15#include "Mangler.h"
[0dd3a2f]16
[ff5caaf]17#include <algorithm> // for copy, transform
18#include <cassert> // for assert, assertf
19#include <functional> // for const_mem_fun_t, mem_fun
20#include <iterator> // for ostream_iterator, back_insert_ite...
21#include <list> // for _List_iterator, list, _List_const...
22#include <string> // for string, char_traits, operator<<
23
24#include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup
[d7d9a60]25#include "Common/PassVisitor.h"
[ff5caaf]26#include "Common/SemanticError.h" // for SemanticError
27#include "Common/utility.h" // for toString
28#include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment
[07de76b]29#include "SynTree/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int...
[ff5caaf]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...
[51b73452]33
[1867c96]34#include "AST/Pass.hpp"
35
[51b73452]36namespace SymTab {
[d7d9a60]37 namespace Mangler {
38 namespace {
39 /// Mangles names to a unique C identifier
[1867c96]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;
[d7d9a60]43
[6f096d2]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 );
[d7d9a60]66
67 std::string get_mangleName() { return mangleName.str(); }
68 private:
69 std::ostringstream mangleName; ///< Mangled name being constructed
[052cd71]70 typedef std::map< std::string, std::pair< int, int > > VarMapType;
[d7d9a60]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
[c0453ca3]77 bool inFunctionType = false; ///< Include type qualifiers if false.
[642bc83]78 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type
[d7d9a60]79
[e1f7eef]80 public:
[6f096d2]81 Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
[052cd71]82 int nextVarNum, const VarMapType& varNums );
[ff5caaf]83
[e1f7eef]84 private:
[6f096d2]85 void mangleDecl( const DeclarationWithType * declaration );
86 void mangleRef( const ReferenceToType * refType, std::string prefix );
[d7d9a60]87
[6f096d2]88 void printQualifiers( const Type *type );
[1867c96]89 }; // Mangler_old
[d7d9a60]90 } // namespace
91
[6f096d2]92 std::string mangle( const BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
[1867c96]93 PassVisitor<Mangler_old> mangler( mangleOverridable, typeMode, mangleGenericParams );
[d7d9a60]94 maybeAccept( decl, mangler );
95 return mangler.pass.get_mangleName();
[4aa0858]96 }
[d7d9a60]97
[6f096d2]98 std::string mangleType( const Type * ty ) {
[1867c96]99 PassVisitor<Mangler_old> mangler( false, true, true );
[d7d9a60]100 maybeAccept( ty, mangler );
101 return mangler.pass.get_mangleName();
102 }
103
[6f096d2]104 std::string mangleConcrete( const Type * ty ) {
[1867c96]105 PassVisitor<Mangler_old> mangler( false, false, false );
[d7d9a60]106 maybeAccept( ty, mangler );
107 return mangler.pass.get_mangleName();
[0dd3a2f]108 }
[d7d9a60]109
110 namespace {
[1867c96]111 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
[6f096d2]112 : nextVarNum( 0 ), isTopLevel( true ),
113 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
[ff5caaf]114 mangleGenericParams( mangleGenericParams ) {}
[6f096d2]115
116 Mangler_old::Mangler_old( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
[052cd71]117 int nextVarNum, const VarMapType& varNums )
[6f096d2]118 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
119 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
[ff5caaf]120 mangleGenericParams( mangleGenericParams ) {}
[d7d9a60]121
[6f096d2]122 void Mangler_old::mangleDecl( const DeclarationWithType * declaration ) {
[d7d9a60]123 bool wasTopLevel = isTopLevel;
124 if ( isTopLevel ) {
125 varNums.clear();
126 nextVarNum = 0;
127 isTopLevel = false;
128 } // if
[642bc83]129 mangleName << Encoding::manglePrefix;
[60a8062]130 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( declaration->get_name() );
131 if ( opInfo ) {
132 mangleName << opInfo->outputName.size() << opInfo->outputName;
[d7d9a60]133 } else {
[642bc83]134 mangleName << declaration->name.size() << declaration->name;
[d7d9a60]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 ) {
[642bc83]141 mangleName << Encoding::autogen;
[d7d9a60]142 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
[642bc83]143 mangleName << Encoding::intrinsic;
[d7d9a60]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
[6f096d2]152 void Mangler_old::postvisit( const ObjectDecl * declaration ) {
[d7d9a60]153 mangleDecl( declaration );
154 }
155
[6f096d2]156 void Mangler_old::postvisit( const FunctionDecl * declaration ) {
[d7d9a60]157 mangleDecl( declaration );
158 }
159
[6f096d2]160 void Mangler_old::postvisit( const VoidType * voidType ) {
[d7d9a60]161 printQualifiers( voidType );
[7804e2a]162 mangleName << Encoding::void_t;
[d7d9a60]163 }
164
[6f096d2]165 void Mangler_old::postvisit( const BasicType * basicType ) {
[d7d9a60]166 printQualifiers( basicType );
[6f096d2]167 assertf( basicType->kind < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
168 mangleName << Encoding::basicTypes[ basicType->kind ];
[d7d9a60]169 }
170
[6f096d2]171 void Mangler_old::postvisit( const PointerType * pointerType ) {
[d7d9a60]172 printQualifiers( pointerType );
[3f024c9]173 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
[642bc83]174 if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer;
[1da22500]175 maybeAccept( pointerType->base, *visitor );
[d7d9a60]176 }
177
[6f096d2]178 void Mangler_old::postvisit( const ArrayType * arrayType ) {
[d7d9a60]179 // TODO: encode dimension
180 printQualifiers( arrayType );
[642bc83]181 mangleName << Encoding::array << "0";
[1da22500]182 maybeAccept( arrayType->base, *visitor );
[d7d9a60]183 }
184
[6f096d2]185 void Mangler_old::postvisit( const ReferenceType * refType ) {
[c0453ca3]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;
[d7d9a60]191 printQualifiers( refType );
[1da22500]192 maybeAccept( refType->base, *visitor );
[d7d9a60]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
[6f096d2]204 void Mangler_old::postvisit( const FunctionType * functionType ) {
[d7d9a60]205 printQualifiers( functionType );
[642bc83]206 mangleName << Encoding::function;
[c0453ca3]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;
[96812c0]212 std::list< Type* > returnTypes = getTypes( functionType->returnVals );
[7804e2a]213 if (returnTypes.empty()) mangleName << Encoding::void_t;
[d1e0979]214 else acceptAll( returnTypes, *visitor );
[d7d9a60]215 mangleName << "_";
[96812c0]216 std::list< Type* > paramTypes = getTypes( functionType->parameters );
[d7d9a60]217 acceptAll( paramTypes, *visitor );
[e35f30a]218 mangleName << "_";
[d7d9a60]219 }
220
[6f096d2]221 void Mangler_old::mangleRef( const ReferenceToType * refType, std::string prefix ) {
[d7d9a60]222 printQualifiers( refType );
223
[642bc83]224 mangleName << prefix << refType->name.length() << refType->name;
[d7d9a60]225
226 if ( mangleGenericParams ) {
[6f096d2]227 const std::list< Expression* > & params = refType->parameters;
[d7d9a60]228 if ( ! params.empty() ) {
229 mangleName << "_";
[6f096d2]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));
[96812c0]233 maybeAccept( paramType->type, *visitor );
[d7d9a60]234 }
235 mangleName << "_";
236 }
[e35f30a]237 }
[d7d9a60]238 }
239
[6f096d2]240 void Mangler_old::postvisit( const StructInstType * aggregateUseType ) {
[7804e2a]241 mangleRef( aggregateUseType, Encoding::struct_t );
[d7d9a60]242 }
243
[6f096d2]244 void Mangler_old::postvisit( const UnionInstType * aggregateUseType ) {
[7804e2a]245 mangleRef( aggregateUseType, Encoding::union_t );
[d7d9a60]246 }
247
[6f096d2]248 void Mangler_old::postvisit( const EnumInstType * aggregateUseType ) {
[7804e2a]249 mangleRef( aggregateUseType, Encoding::enum_t );
[d7d9a60]250 }
251
[6f096d2]252 void Mangler_old::postvisit( const TypeInstType * typeInst ) {
[d7d9a60]253 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
254 if ( varNum == varNums.end() ) {
[d8cb7df]255 mangleRef( typeInst, Encoding::type );
[d7d9a60]256 } else {
257 printQualifiers( typeInst );
[0e761e40]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.
[0e73845]263 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
[0e761e40]264 mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
[d7d9a60]265 } // if
266 }
267
[6f096d2]268 void Mangler_old::postvisit( const TraitInstType * inst ) {
[f465f0e]269 printQualifiers( inst );
[642bc83]270 mangleName << inst->name.size() << inst->name;
[f465f0e]271 }
272
[6f096d2]273 void Mangler_old::postvisit( const TupleType * tupleType ) {
[d7d9a60]274 printQualifiers( tupleType );
[642bc83]275 mangleName << Encoding::tuple << tupleType->types.size();
[d7d9a60]276 acceptAll( tupleType->types, *visitor );
[8360977]277 }
[d7d9a60]278
[6f096d2]279 void Mangler_old::postvisit( const VarArgsType * varArgsType ) {
[d7d9a60]280 printQualifiers( varArgsType );
[642bc83]281 static const std::string vargs = "__builtin_va_list";
[d8cb7df]282 mangleName << Encoding::type << vargs.size() << vargs;
[d7d9a60]283 }
284
[6f096d2]285 void Mangler_old::postvisit( const ZeroType * ) {
[642bc83]286 mangleName << Encoding::zero;
[d7d9a60]287 }
288
[6f096d2]289 void Mangler_old::postvisit( const OneType * ) {
[642bc83]290 mangleName << Encoding::one;
[d7d9a60]291 }
292
[6f096d2]293 void Mangler_old::postvisit( const QualifiedType * qualType ) {
[642bc83]294 bool inqual = inQualifiedType;
295 if (! inqual ) {
296 // N marks the start of a qualified type
297 inQualifiedType = true;
298 mangleName << Encoding::qualifiedTypeStart;
299 }
[e73becf]300 maybeAccept( qualType->parent, *visitor );
301 maybeAccept( qualType->child, *visitor );
[642bc83]302 if ( ! inqual ) {
303 // E marks the end of a qualified type
304 inQualifiedType = false;
305 mangleName << Encoding::qualifiedTypeEnd;
306 }
[e73becf]307 }
308
[6f096d2]309 void Mangler_old::postvisit( const TypeDecl * decl ) {
[0e761e40]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.
[1867c96]315 assertf(false, "Mangler_old should not visit typedecl: %s", toCString(decl));
[6f096d2]316 assertf( decl->kind < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
317 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
[d7d9a60]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;
[0dd3a2f]323 } // for
[d7d9a60]324 }
325
[6f096d2]326 void Mangler_old::printQualifiers( const Type * type ) {
[d7d9a60]327 // skip if not including qualifiers
328 if ( typeMode ) return;
[6f096d2]329 if ( ! type->forall.empty() ) {
[d7d9a60]330 std::list< std::string > assertionNames;
[0e73845]331 int dcount = 0, fcount = 0, vcount = 0, acount = 0;
332 mangleName << Encoding::forall;
[6f096d2]333 for ( const TypeDecl * i : type->forall ) {
334 switch ( i->kind ) {
[d7d9a60]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 assert( false );
346 } // switch
[6f096d2]347 varNums[ i->name ] = std::make_pair( nextVarNum, (int)i->kind );
348 for ( const DeclarationWithType * assert : i->assertions ) {
349 PassVisitor<Mangler_old> sub_mangler(
[052cd71]350 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
[6f096d2]351 assert->accept( sub_mangler );
[ff5caaf]352 assertionNames.push_back( sub_mangler.pass.get_mangleName() );
[0e73845]353 acount++;
[d7d9a60]354 } // for
355 } // for
[0e73845]356 mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
[d7d9a60]357 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
358 mangleName << "_";
359 } // if
[c0453ca3]360 if ( ! inFunctionType ) {
361 // these qualifiers do not distinguish the outermost type of a function parameter
362 if ( type->get_const() ) {
[642bc83]363 mangleName << Encoding::qualifiers.at(Type::Const);
[c0453ca3]364 } // if
365 if ( type->get_volatile() ) {
[642bc83]366 mangleName << Encoding::qualifiers.at(Type::Volatile);
[c0453ca3]367 } // if
368 // Removed due to restrict not affecting function compatibility in GCC
369 // if ( type->get_isRestrict() ) {
370 // mangleName << "E";
371 // } // if
372 if ( type->get_atomic() ) {
[642bc83]373 mangleName << Encoding::qualifiers.at(Type::Atomic);
[c0453ca3]374 } // if
375 }
[d7d9a60]376 if ( type->get_mutex() ) {
[642bc83]377 mangleName << Encoding::qualifiers.at(Type::Mutex);
[d7d9a60]378 } // if
[c0453ca3]379 if ( inFunctionType ) {
380 // turn off inFunctionType so that types can be differentiated for nested qualifiers
381 GuardValue( inFunctionType );
382 inFunctionType = false;
383 }
[d7d9a60]384 }
385 } // namespace
386 } // namespace Mangler
[0dd3a2f]387} // namespace SymTab
388
[d76c588]389namespace Mangle {
[1867c96]390 namespace {
391 /// 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;
395
[1346914]396 void previsit( const ast::Node * ) { visit_children = false; }
397
398 void postvisit( const ast::ObjectDecl * declaration );
399 void postvisit( const ast::FunctionDecl * declaration );
400 void postvisit( const ast::TypeDecl * declaration );
401
402 void postvisit( const ast::VoidType * voidType );
403 void postvisit( const ast::BasicType * basicType );
404 void postvisit( const ast::PointerType * pointerType );
405 void postvisit( const ast::ArrayType * arrayType );
406 void postvisit( const ast::ReferenceType * refType );
407 void postvisit( const ast::FunctionType * functionType );
408 void postvisit( const ast::StructInstType * aggregateUseType );
409 void postvisit( const ast::UnionInstType * aggregateUseType );
410 void postvisit( const ast::EnumInstType * aggregateUseType );
411 void postvisit( const ast::TypeInstType * aggregateUseType );
412 void postvisit( const ast::TraitInstType * inst );
413 void postvisit( const ast::TupleType * tupleType );
414 void postvisit( const ast::VarArgsType * varArgsType );
415 void postvisit( const ast::ZeroType * zeroType );
416 void postvisit( const ast::OneType * oneType );
417 void postvisit( const ast::QualifiedType * qualType );
[1867c96]418
419 std::string get_mangleName() { return mangleName.str(); }
420 private:
421 std::ostringstream mangleName; ///< Mangled name being constructed
422 typedef std::map< std::string, std::pair< int, int > > VarMapType;
423 VarMapType varNums; ///< Map of type variables to indices
424 int nextVarNum; ///< Next type variable index
425 bool isTopLevel; ///< Is the Mangler at the top level
426 bool mangleOverridable; ///< Specially mangle overridable built-in methods
427 bool typeMode; ///< Produce a unique mangled name for a type
428 bool mangleGenericParams; ///< Include generic parameters in name mangling if true
429 bool inFunctionType = false; ///< Include type qualifiers if false.
430 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type
431
432 private:
[6f096d2]433 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
[1867c96]434 int nextVarNum, const VarMapType& varNums );
435 friend class ast::Pass<Mangler_new>;
436
437 private:
[1346914]438 void mangleDecl( const ast::DeclWithType *declaration );
439 void mangleRef( const ast::ReferenceToType *refType, std::string prefix );
[1867c96]440
[1346914]441 void printQualifiers( const ast::Type *type );
[1867c96]442 }; // Mangler_new
443 } // namespace
444
445
[d76c588]446 std::string mangle( const ast::Node * decl, Mangle::Mode mode ) {
[1867c96]447 ast::Pass<Mangler_new> mangler( mode );
448 maybeAccept( decl, mangler );
449 return mangler.pass.get_mangleName();
[d76c588]450 }
[1867c96]451
452 namespace {
453 Mangler_new::Mangler_new( Mangle::Mode mode )
[6f096d2]454 : nextVarNum( 0 ), isTopLevel( true ),
[1867c96]455 mangleOverridable ( ! mode.no_overrideable ),
[6f096d2]456 typeMode ( mode.type ),
[1867c96]457 mangleGenericParams( ! mode.no_generic_params ) {}
[6f096d2]458
459 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
[1867c96]460 int nextVarNum, const VarMapType& varNums )
[6f096d2]461 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
462 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
[1867c96]463 mangleGenericParams( mangleGenericParams ) {}
464
[1346914]465 void Mangler_new::mangleDecl( const ast::DeclWithType * decl ) {
[1867c96]466 bool wasTopLevel = isTopLevel;
467 if ( isTopLevel ) {
468 varNums.clear();
469 nextVarNum = 0;
470 isTopLevel = false;
471 } // if
472 mangleName << Encoding::manglePrefix;
[60a8062]473 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( decl->name );
474 if ( opInfo ) {
475 mangleName << opInfo->outputName.size() << opInfo->outputName;
[1867c96]476 } else {
477 mangleName << decl->name.size() << decl->name;
478 } // if
479 maybeAccept( decl->get_type(), *visitor );
480 if ( mangleOverridable && decl->linkage.is_overrideable ) {
481 // want to be able to override autogenerated and intrinsic routines,
482 // so they need a different name mangling
483 if ( decl->linkage == ast::Linkage::AutoGen ) {
484 mangleName << Encoding::autogen;
485 } else if ( decl->linkage == ast::Linkage::Intrinsic ) {
486 mangleName << Encoding::intrinsic;
487 } else {
488 // if we add another kind of overridable function, this has to change
489 assert( false && "unknown overrideable linkage" );
490 } // if
491 }
492 isTopLevel = wasTopLevel;
493 }
494
[1346914]495 void Mangler_new::postvisit( const ast::ObjectDecl * decl ) {
[1867c96]496 mangleDecl( decl );
497 }
498
[1346914]499 void Mangler_new::postvisit( const ast::FunctionDecl * decl ) {
[1867c96]500 mangleDecl( decl );
501 }
502
[1346914]503 void Mangler_new::postvisit( const ast::VoidType * voidType ) {
[1867c96]504 printQualifiers( voidType );
505 mangleName << Encoding::void_t;
506 }
507
[1346914]508 void Mangler_new::postvisit( const ast::BasicType * basicType ) {
[1867c96]509 printQualifiers( basicType );
510 assertf( basicType->kind < ast::BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->kind );
511 mangleName << Encoding::basicTypes[ basicType->kind ];
512 }
513
[1346914]514 void Mangler_new::postvisit( const ast::PointerType * pointerType ) {
[1867c96]515 printQualifiers( pointerType );
516 // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
517 if ( ! pointerType->base.as<ast::FunctionType>() ) mangleName << Encoding::pointer;
518 maybe_accept( pointerType->base.get(), *visitor );
519 }
520
[1346914]521 void Mangler_new::postvisit( const ast::ArrayType * arrayType ) {
[1867c96]522 // TODO: encode dimension
523 printQualifiers( arrayType );
524 mangleName << Encoding::array << "0";
525 maybeAccept( arrayType->base.get(), *visitor );
526 }
527
[1346914]528 void Mangler_new::postvisit( const ast::ReferenceType * refType ) {
[1867c96]529 // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
530 // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
531 // by pretending every reference type is a function parameter.
532 GuardValue( inFunctionType );
533 inFunctionType = true;
534 printQualifiers( refType );
535 maybeAccept( refType->base.get(), *visitor );
536 }
537
[1346914]538 inline std::vector< ast::ptr< ast::Type > > getTypes( const std::vector< ast::ptr< ast::DeclWithType > > & decls ) {
539 std::vector< ast::ptr< ast::Type > > ret;
540 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
541 std::mem_fun( &ast::DeclWithType::get_type ) );
542 return ret;
[1867c96]543 }
544
[1346914]545 void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
[1867c96]546 printQualifiers( functionType );
547 mangleName << Encoding::function;
548 // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
549 // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
550 // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
551 GuardValue( inFunctionType );
552 inFunctionType = true;
553 std::vector< ast::ptr< ast::Type > > returnTypes = getTypes( functionType->returns );
554 if (returnTypes.empty()) mangleName << Encoding::void_t;
[1346914]555 else accept_each( returnTypes, *visitor );
[1867c96]556 mangleName << "_";
557 std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params );
[1346914]558 accept_each( paramTypes, *visitor );
[1867c96]559 mangleName << "_";
560 }
561
[1346914]562 void Mangler_new::mangleRef( const ast::ReferenceToType * refType, std::string prefix ) {
[1867c96]563 printQualifiers( refType );
564
565 mangleName << prefix << refType->name.length() << refType->name;
566
567 if ( mangleGenericParams ) {
[1346914]568 if ( ! refType->params.empty() ) {
[1867c96]569 mangleName << "_";
[1346914]570 for ( const ast::Expr * param : refType->params ) {
571 auto paramType = dynamic_cast< const ast::TypeExpr * >( param );
572 assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(param));
[1867c96]573 maybeAccept( paramType->type.get(), *visitor );
574 }
575 mangleName << "_";
576 }
577 }
578 }
579
[1346914]580 void Mangler_new::postvisit( const ast::StructInstType * aggregateUseType ) {
[1867c96]581 mangleRef( aggregateUseType, Encoding::struct_t );
582 }
583
[1346914]584 void Mangler_new::postvisit( const ast::UnionInstType * aggregateUseType ) {
[1867c96]585 mangleRef( aggregateUseType, Encoding::union_t );
586 }
587
[1346914]588 void Mangler_new::postvisit( const ast::EnumInstType * aggregateUseType ) {
[1867c96]589 mangleRef( aggregateUseType, Encoding::enum_t );
590 }
591
[1346914]592 void Mangler_new::postvisit( const ast::TypeInstType * typeInst ) {
[1867c96]593 VarMapType::iterator varNum = varNums.find( typeInst->name );
594 if ( varNum == varNums.end() ) {
595 mangleRef( typeInst, Encoding::type );
596 } else {
597 printQualifiers( typeInst );
598 // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
599 // forall(dtype T) void f(T);
600 // forall(dtype S) void f(S);
601 // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
602 // are first found and prefixing with the appropriate encoding for the type class.
603 assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
604 mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
605 } // if
606 }
607
[1346914]608 void Mangler_new::postvisit( const ast::TraitInstType * inst ) {
[1867c96]609 printQualifiers( inst );
610 mangleName << inst->name.size() << inst->name;
611 }
612
[1346914]613 void Mangler_new::postvisit( const ast::TupleType * tupleType ) {
[1867c96]614 printQualifiers( tupleType );
615 mangleName << Encoding::tuple << tupleType->types.size();
[1346914]616 accept_each( tupleType->types, *visitor );
[1867c96]617 }
618
[1346914]619 void Mangler_new::postvisit( const ast::VarArgsType * varArgsType ) {
[1867c96]620 printQualifiers( varArgsType );
621 static const std::string vargs = "__builtin_va_list";
622 mangleName << Encoding::type << vargs.size() << vargs;
623 }
624
[1346914]625 void Mangler_new::postvisit( const ast::ZeroType * ) {
[1867c96]626 mangleName << Encoding::zero;
627 }
628
[1346914]629 void Mangler_new::postvisit( const ast::OneType * ) {
[1867c96]630 mangleName << Encoding::one;
631 }
632
[1346914]633 void Mangler_new::postvisit( const ast::QualifiedType * qualType ) {
[1867c96]634 bool inqual = inQualifiedType;
635 if (! inqual ) {
636 // N marks the start of a qualified type
637 inQualifiedType = true;
638 mangleName << Encoding::qualifiedTypeStart;
639 }
640 maybeAccept( qualType->parent.get(), *visitor );
641 maybeAccept( qualType->child.get(), *visitor );
642 if ( ! inqual ) {
643 // E marks the end of a qualified type
644 inQualifiedType = false;
645 mangleName << Encoding::qualifiedTypeEnd;
646 }
647 }
648
[1346914]649 void Mangler_new::postvisit( const ast::TypeDecl * decl ) {
[1867c96]650 // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
651 // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
652 // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
653 // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
654 // aside from the assert false.
655 assertf(false, "Mangler_new should not visit typedecl: %s", toCString(decl));
[07de76b]656 assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
[1867c96]657 mangleName << Encoding::typeVariables[ decl->kind ] << ( decl->name.length() ) << decl->name;
658 }
659
660 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
661 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
662 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
663 } // for
664 }
665
[1346914]666 void Mangler_new::printQualifiers( const ast::Type * type ) {
[1867c96]667 // skip if not including qualifiers
668 if ( typeMode ) return;
[1346914]669 if ( auto ptype = dynamic_cast< const ast::ParameterizedType * >(type) ) {
[1867c96]670 if ( ! ptype->forall.empty() ) {
671 std::list< std::string > assertionNames;
672 int dcount = 0, fcount = 0, vcount = 0, acount = 0;
673 mangleName << Encoding::forall;
[1346914]674 for ( const ast::TypeDecl * decl : ptype->forall ) {
675 switch ( decl->kind ) {
[07de76b]676 case ast::TypeDecl::Kind::Dtype:
[1867c96]677 dcount++;
678 break;
[07de76b]679 case ast::TypeDecl::Kind::Ftype:
[1867c96]680 fcount++;
681 break;
[07de76b]682 case ast::TypeDecl::Kind::Ttype:
[1867c96]683 vcount++;
684 break;
[1346914]685 default:
[1867c96]686 assert( false );
687 } // switch
[1346914]688 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
689 for ( const ast::DeclWithType * assert : decl->assertions ) {
[6f096d2]690 ast::Pass<Mangler_new> sub_mangler(
[1867c96]691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
[1346914]692 assert->accept( sub_mangler );
[1867c96]693 assertionNames.push_back( sub_mangler.pass.get_mangleName() );
694 acount++;
695 } // for
696 } // for
697 mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
698 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
699 mangleName << "_";
700 } // if
701 } // if
702 if ( ! inFunctionType ) {
703 // these qualifiers do not distinguish the outermost type of a function parameter
704 if ( type->is_const() ) {
705 mangleName << Encoding::qualifiers.at(Type::Const);
706 } // if
707 if ( type->is_volatile() ) {
708 mangleName << Encoding::qualifiers.at(Type::Volatile);
709 } // if
710 // Removed due to restrict not affecting function compatibility in GCC
711 // if ( type->get_isRestrict() ) {
712 // mangleName << "E";
713 // } // if
714 if ( type->is_atomic() ) {
715 mangleName << Encoding::qualifiers.at(Type::Atomic);
716 } // if
717 }
718 if ( type->is_mutex() ) {
719 mangleName << Encoding::qualifiers.at(Type::Mutex);
720 } // if
721 if ( inFunctionType ) {
722 // turn off inFunctionType so that types can be differentiated for nested qualifiers
723 GuardValue( inFunctionType );
724 inFunctionType = false;
725 }
726 }
727 } // namespace
[d76c588]728} // namespace Mangle
729
[0dd3a2f]730// Local Variables: //
731// tab-width: 4 //
732// mode: c++ //
733// compile-command: "make install" //
734// End: //
Note: See TracBrowser for help on using the repository browser.