source: src/SymTab/Mangler.cc@ affb51b

ADT ast-experimental
Last change on this file since affb51b was b0d9ff7, checked in by JiadaL <j82liang@…>, 3 years ago

Fix up the QualifiedNameExpr. It should now work on both old AST and new AST. There are some known bugs to fix so make all-tests will fail.

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