source: src/SymTab/Mangler.cc@ ef9988b

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 ef9988b was 7ff3e522, checked in by Andrew Beach <ajbeach@…>, 5 years ago

{pass_t Pass::pass; => core_t Pass::core;} To avoid confusion about which pass we are talking about.

  • Property mode set to 100644
File size: 29.8 KB
Line 
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//
7// Mangler.cc --
8//
9// Author : Richard C. Bilson
10// Created On : Sun May 17 21:40:29 2015
11// Last Modified By : Peter A. Buhr
12// Last Modified On : Sat Feb 15 13:55:12 2020
13// Update Count : 33
14//
15#include "Mangler.h"
16
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
25#include "Common/PassVisitor.h"
26#include "Common/SemanticError.h" // for SemanticError
27#include "Common/utility.h" // for toString
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
36namespace 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.str(); }
68 private:
69 std::ostringstream 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 << opInfo->outputName.size() << opInfo->outputName;
133 } else {
134 mangleName << 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 << 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] << varNum->second.first;
265 } // if
266 }
267
268 void Mangler_old::postvisit( const TraitInstType * inst ) {
269 printQualifiers( inst );
270 mangleName << inst->name.size() << inst->name;
271 }
272
273 void Mangler_old::postvisit( const TupleType * tupleType ) {
274 printQualifiers( tupleType );
275 mangleName << Encoding::tuple << 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 << 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 ] << ( 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 assert( false );
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 << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
357 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
358 mangleName << "_";
359 } // if
360 if ( ! inFunctionType ) {
361 // these qualifiers do not distinguish the outermost type of a function parameter
362 if ( type->get_const() ) {
363 mangleName << Encoding::qualifiers.at(Type::Const);
364 } // if
365 if ( type->get_volatile() ) {
366 mangleName << Encoding::qualifiers.at(Type::Volatile);
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() ) {
373 mangleName << Encoding::qualifiers.at(Type::Atomic);
374 } // if
375 }
376 if ( type->get_mutex() ) {
377 mangleName << Encoding::qualifiers.at(Type::Mutex);
378 } // if
379 if ( inFunctionType ) {
380 // turn off inFunctionType so that types can be differentiated for nested qualifiers
381 GuardValue( inFunctionType );
382 inFunctionType = false;
383 }
384 }
385 } // namespace
386 } // namespace Mangler
387} // namespace SymTab
388
389namespace Mangle {
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
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 );
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:
433 Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
434 int nextVarNum, const VarMapType& varNums );
435 friend class ast::Pass<Mangler_new>;
436
437 private:
438 void mangleDecl( const ast::DeclWithType *declaration );
439 void mangleRef( const ast::ReferenceToType *refType, std::string prefix );
440
441 void printQualifiers( const ast::Type *type );
442 }; // Mangler_new
443 } // namespace
444
445
446 std::string mangle( const ast::Node * decl, Mangle::Mode mode ) {
447 ast::Pass<Mangler_new> mangler( mode );
448 maybeAccept( decl, mangler );
449 return mangler.core.get_mangleName();
450 }
451
452 namespace {
453 Mangler_new::Mangler_new( Mangle::Mode mode )
454 : nextVarNum( 0 ), isTopLevel( true ),
455 mangleOverridable ( ! mode.no_overrideable ),
456 typeMode ( mode.type ),
457 mangleGenericParams( ! mode.no_generic_params ) {}
458
459 Mangler_new::Mangler_new( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
460 int nextVarNum, const VarMapType& varNums )
461 : varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( false ),
462 mangleOverridable( mangleOverridable ), typeMode( typeMode ),
463 mangleGenericParams( mangleGenericParams ) {}
464
465 void Mangler_new::mangleDecl( const ast::DeclWithType * decl ) {
466 bool wasTopLevel = isTopLevel;
467 if ( isTopLevel ) {
468 varNums.clear();
469 nextVarNum = 0;
470 isTopLevel = false;
471 } // if
472 mangleName << Encoding::manglePrefix;
473 const CodeGen::OperatorInfo * opInfo = CodeGen::operatorLookup( decl->name );
474 if ( opInfo ) {
475 mangleName << opInfo->outputName.size() << opInfo->outputName;
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
495 void Mangler_new::postvisit( const ast::ObjectDecl * decl ) {
496 mangleDecl( decl );
497 }
498
499 void Mangler_new::postvisit( const ast::FunctionDecl * decl ) {
500 mangleDecl( decl );
501 }
502
503 void Mangler_new::postvisit( const ast::VoidType * voidType ) {
504 printQualifiers( voidType );
505 mangleName << Encoding::void_t;
506 }
507
508 void Mangler_new::postvisit( const ast::BasicType * basicType ) {
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
514 void Mangler_new::postvisit( const ast::PointerType * pointerType ) {
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
521 void Mangler_new::postvisit( const ast::ArrayType * arrayType ) {
522 // TODO: encode dimension
523 printQualifiers( arrayType );
524 mangleName << Encoding::array << "0";
525 maybeAccept( arrayType->base.get(), *visitor );
526 }
527
528 void Mangler_new::postvisit( const ast::ReferenceType * refType ) {
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
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;
543 }
544
545 void Mangler_new::postvisit( const ast::FunctionType * functionType ) {
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;
555 else accept_each( returnTypes, *visitor );
556 mangleName << "_";
557 std::vector< ast::ptr< ast::Type > > paramTypes = getTypes( functionType->params );
558 accept_each( paramTypes, *visitor );
559 mangleName << "_";
560 }
561
562 void Mangler_new::mangleRef( const ast::ReferenceToType * refType, std::string prefix ) {
563 printQualifiers( refType );
564
565 mangleName << prefix << refType->name.length() << refType->name;
566
567 if ( mangleGenericParams ) {
568 if ( ! refType->params.empty() ) {
569 mangleName << "_";
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));
573 maybeAccept( paramType->type.get(), *visitor );
574 }
575 mangleName << "_";
576 }
577 }
578 }
579
580 void Mangler_new::postvisit( const ast::StructInstType * aggregateUseType ) {
581 mangleRef( aggregateUseType, Encoding::struct_t );
582 }
583
584 void Mangler_new::postvisit( const ast::UnionInstType * aggregateUseType ) {
585 mangleRef( aggregateUseType, Encoding::union_t );
586 }
587
588 void Mangler_new::postvisit( const ast::EnumInstType * aggregateUseType ) {
589 mangleRef( aggregateUseType, Encoding::enum_t );
590 }
591
592 void Mangler_new::postvisit( const ast::TypeInstType * typeInst ) {
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
608 void Mangler_new::postvisit( const ast::TraitInstType * inst ) {
609 printQualifiers( inst );
610 mangleName << inst->name.size() << inst->name;
611 }
612
613 void Mangler_new::postvisit( const ast::TupleType * tupleType ) {
614 printQualifiers( tupleType );
615 mangleName << Encoding::tuple << tupleType->types.size();
616 accept_each( tupleType->types, *visitor );
617 }
618
619 void Mangler_new::postvisit( const ast::VarArgsType * varArgsType ) {
620 printQualifiers( varArgsType );
621 static const std::string vargs = "__builtin_va_list";
622 mangleName << Encoding::type << vargs.size() << vargs;
623 }
624
625 void Mangler_new::postvisit( const ast::ZeroType * ) {
626 mangleName << Encoding::zero;
627 }
628
629 void Mangler_new::postvisit( const ast::OneType * ) {
630 mangleName << Encoding::one;
631 }
632
633 void Mangler_new::postvisit( const ast::QualifiedType * qualType ) {
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
649 void Mangler_new::postvisit( const ast::TypeDecl * decl ) {
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));
656 assertf( decl->kind < ast::TypeDecl::Kind::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->kind );
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
666 void Mangler_new::printQualifiers( const ast::Type * type ) {
667 // skip if not including qualifiers
668 if ( typeMode ) return;
669 if ( auto ptype = dynamic_cast< const ast::ParameterizedType * >(type) ) {
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;
674 for ( const ast::TypeDecl * decl : ptype->forall ) {
675 switch ( decl->kind ) {
676 case ast::TypeDecl::Kind::Dtype:
677 dcount++;
678 break;
679 case ast::TypeDecl::Kind::Ftype:
680 fcount++;
681 break;
682 case ast::TypeDecl::Kind::Ttype:
683 vcount++;
684 break;
685 default:
686 assert( false );
687 } // switch
688 varNums[ decl->name ] = std::make_pair( nextVarNum, (int)decl->kind );
689 for ( const ast::DeclWithType * assert : decl->assertions ) {
690 ast::Pass<Mangler_new> sub_mangler(
691 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, varNums );
692 assert->accept( sub_mangler );
693 assertionNames.push_back( sub_mangler.core.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
728} // namespace Mangle
729
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.