source: src/SymTab/Mangler.cc@ 41fcd94

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 41fcd94 was d7d9a60, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

Convert Mangler to PassVisitor

  • Property mode set to 100644
File size: 12.9 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 Sep 25 15:49:26 2017
13// Update Count : 23
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 "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int...
29#include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType
30#include "SynTree/Expression.h" // for TypeExpr, Expression, operator<<
31#include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora...
32
33namespace SymTab {
34 namespace Mangler {
35 namespace {
36 /// Mangles names to a unique C identifier
37 struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> {
38 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
39 Mangler( const Mangler & );
40
41 void previsit( BaseSyntaxNode * ) { visit_children = false; }
42
43 void postvisit( ObjectDecl * declaration );
44 void postvisit( FunctionDecl * declaration );
45 void postvisit( TypeDecl * declaration );
46
47 void postvisit( VoidType * voidType );
48 void postvisit( BasicType * basicType );
49 void postvisit( PointerType * pointerType );
50 void postvisit( ArrayType * arrayType );
51 void postvisit( ReferenceType * refType );
52 void postvisit( FunctionType * functionType );
53 void postvisit( StructInstType * aggregateUseType );
54 void postvisit( UnionInstType * aggregateUseType );
55 void postvisit( EnumInstType * aggregateUseType );
56 void postvisit( TypeInstType * aggregateUseType );
57 void postvisit( TupleType * tupleType );
58 void postvisit( VarArgsType * varArgsType );
59 void postvisit( ZeroType * zeroType );
60 void postvisit( OneType * oneType );
61
62 std::string get_mangleName() { return mangleName.str(); }
63 private:
64 std::ostringstream mangleName; ///< Mangled name being constructed
65 typedef std::map< std::string, std::pair< int, int > > VarMapType;
66 VarMapType varNums; ///< Map of type variables to indices
67 int nextVarNum; ///< Next type variable index
68 bool isTopLevel; ///< Is the Mangler at the top level
69 bool mangleOverridable; ///< Specially mangle overridable built-in methods
70 bool typeMode; ///< Produce a unique mangled name for a type
71 bool mangleGenericParams; ///< Include generic parameters in name mangling if true
72
73 void mangleDecl( DeclarationWithType *declaration );
74 void mangleRef( ReferenceToType *refType, std::string prefix );
75
76 void printQualifiers( Type *type );
77 }; // Mangler
78 } // namespace
79
80 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
81 PassVisitor<Mangler> mangler( mangleOverridable, typeMode, mangleGenericParams );
82 maybeAccept( decl, mangler );
83 return mangler.pass.get_mangleName();
84 }
85
86 std::string mangleType( Type * ty ) {
87 PassVisitor<Mangler> mangler( false, true, true );
88 maybeAccept( ty, mangler );
89 return mangler.pass.get_mangleName();
90 }
91
92 std::string mangleConcrete( Type * ty ) {
93 PassVisitor<Mangler> mangler( false, false, false );
94 maybeAccept( ty, mangler );
95 return mangler.pass.get_mangleName();
96 }
97
98 namespace {
99 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
100 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
101
102 Mangler::Mangler( const Mangler &rhs ) : mangleName() {
103 varNums = rhs.varNums;
104 nextVarNum = rhs.nextVarNum;
105 isTopLevel = rhs.isTopLevel;
106 mangleOverridable = rhs.mangleOverridable;
107 typeMode = rhs.typeMode;
108 }
109
110 void Mangler::mangleDecl( DeclarationWithType * declaration ) {
111 bool wasTopLevel = isTopLevel;
112 if ( isTopLevel ) {
113 varNums.clear();
114 nextVarNum = 0;
115 isTopLevel = false;
116 } // if
117 mangleName << "__";
118 CodeGen::OperatorInfo opInfo;
119 if ( operatorLookup( declaration->get_name(), opInfo ) ) {
120 mangleName << opInfo.outputName;
121 } else {
122 mangleName << declaration->get_name();
123 } // if
124 mangleName << "__";
125 maybeAccept( declaration->get_type(), *visitor );
126 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
127 // want to be able to override autogenerated and intrinsic routines,
128 // so they need a different name mangling
129 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
130 mangleName << "autogen__";
131 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
132 mangleName << "intrinsic__";
133 } else {
134 // if we add another kind of overridable function, this has to change
135 assert( false && "unknown overrideable linkage" );
136 } // if
137 }
138 isTopLevel = wasTopLevel;
139 }
140
141 void Mangler::postvisit( ObjectDecl * declaration ) {
142 mangleDecl( declaration );
143 }
144
145 void Mangler::postvisit( FunctionDecl * declaration ) {
146 mangleDecl( declaration );
147 }
148
149 void Mangler::postvisit( VoidType * voidType ) {
150 printQualifiers( voidType );
151 mangleName << "v";
152 }
153
154 void Mangler::postvisit( BasicType * basicType ) {
155 static const char *btLetter[] = {
156 "b", // Bool
157 "c", // Char
158 "Sc", // SignedChar
159 "Uc", // UnsignedChar
160 "s", // ShortSignedInt
161 "Us", // ShortUnsignedInt
162 "i", // SignedInt
163 "Ui", // UnsignedInt
164 "l", // LongSignedInt
165 "Ul", // LongUnsignedInt
166 "q", // LongLongSignedInt
167 "Uq", // LongLongUnsignedInt
168 "f", // Float
169 "d", // Double
170 "r", // LongDouble
171 "Xf", // FloatComplex
172 "Xd", // DoubleComplex
173 "Xr", // LongDoubleComplex
174 "If", // FloatImaginary
175 "Id", // DoubleImaginary
176 "Ir", // LongDoubleImaginary
177 "w", // SignedInt128
178 "Uw", // UnsignedInt128
179 };
180
181 printQualifiers( basicType );
182 mangleName << btLetter[ basicType->get_kind() ];
183 }
184
185 void Mangler::postvisit( PointerType * pointerType ) {
186 printQualifiers( pointerType );
187 mangleName << "P";
188 maybeAccept( pointerType->get_base(), *visitor );
189 }
190
191 void Mangler::postvisit( ArrayType * arrayType ) {
192 // TODO: encode dimension
193 printQualifiers( arrayType );
194 mangleName << "A0";
195 maybeAccept( arrayType->get_base(), *visitor );
196 }
197
198 void Mangler::postvisit( ReferenceType * refType ) {
199 printQualifiers( refType );
200 mangleName << "R";
201 maybeAccept( refType->get_base(), *visitor );
202 }
203
204 namespace {
205 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
206 std::list< Type* > ret;
207 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
208 std::mem_fun( &DeclarationWithType::get_type ) );
209 return ret;
210 }
211 }
212
213 void Mangler::postvisit( FunctionType * functionType ) {
214 printQualifiers( functionType );
215 mangleName << "F";
216 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
217 acceptAll( returnTypes, *visitor );
218 mangleName << "_";
219 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
220 acceptAll( paramTypes, *visitor );
221 mangleName << "_";
222 }
223
224 void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
225 printQualifiers( refType );
226
227 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
228
229 if ( mangleGenericParams ) {
230 std::list< Expression* >& params = refType->get_parameters();
231 if ( ! params.empty() ) {
232 mangleName << "_";
233 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
234 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
235 assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
236 maybeAccept( paramType->get_type(), *visitor );
237 }
238 mangleName << "_";
239 }
240 }
241 }
242
243 void Mangler::postvisit( StructInstType * aggregateUseType ) {
244 mangleRef( aggregateUseType, "s" );
245 }
246
247 void Mangler::postvisit( UnionInstType * aggregateUseType ) {
248 mangleRef( aggregateUseType, "u" );
249 }
250
251 void Mangler::postvisit( EnumInstType * aggregateUseType ) {
252 mangleRef( aggregateUseType, "e" );
253 }
254
255 void Mangler::postvisit( TypeInstType * typeInst ) {
256 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
257 if ( varNum == varNums.end() ) {
258 mangleRef( typeInst, "t" );
259 } else {
260 printQualifiers( typeInst );
261 std::ostringstream numStream;
262 numStream << varNum->second.first;
263 switch ( (TypeDecl::Kind )varNum->second.second ) {
264 case TypeDecl::Dtype:
265 mangleName << "d";
266 break;
267 case TypeDecl::Ftype:
268 mangleName << "f";
269 break;
270 case TypeDecl::Ttype:
271 mangleName << "tVARGS";
272 break;
273 default:
274 assert( false );
275 } // switch
276 mangleName << numStream.str();
277 } // if
278 }
279
280 void Mangler::postvisit( TupleType * tupleType ) {
281 printQualifiers( tupleType );
282 mangleName << "T";
283 acceptAll( tupleType->types, *visitor );
284 mangleName << "_";
285 }
286
287 void Mangler::postvisit( VarArgsType * varArgsType ) {
288 printQualifiers( varArgsType );
289 mangleName << "VARGS";
290 }
291
292 void Mangler::postvisit( ZeroType * ) {
293 mangleName << "Z";
294 }
295
296 void Mangler::postvisit( OneType * ) {
297 mangleName << "O";
298 }
299
300 void Mangler::postvisit( TypeDecl * decl ) {
301 static const char *typePrefix[] = { "BT", "BD", "BF" };
302 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
303 }
304
305 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
306 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
307 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
308 } // for
309 }
310
311 void Mangler::printQualifiers( Type * type ) {
312 // skip if not including qualifiers
313 if ( typeMode ) return;
314
315 if ( ! type->get_forall().empty() ) {
316 std::list< std::string > assertionNames;
317 int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
318 mangleName << "A";
319 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
320 switch ( (*i)->get_kind() ) {
321 case TypeDecl::Dtype:
322 dcount++;
323 break;
324 case TypeDecl::Ftype:
325 fcount++;
326 break;
327 case TypeDecl::Ttype:
328 vcount++;
329 break;
330 default:
331 assert( false );
332 } // switch
333 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
334 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
335 PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams );
336 sub_mangler.pass.nextVarNum = nextVarNum;
337 sub_mangler.pass.isTopLevel = false;
338 sub_mangler.pass.varNums = varNums;
339 (*assert)->accept( sub_mangler );
340 assertionNames.push_back( sub_mangler.pass.mangleName.str() );
341 } // for
342 } // for
343 mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
344 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
345 mangleName << "_";
346 } // if
347 if ( type->get_const() ) {
348 mangleName << "C";
349 } // if
350 if ( type->get_volatile() ) {
351 mangleName << "V";
352 } // if
353 if ( type->get_mutex() ) {
354 mangleName << "M";
355 } // if
356 // Removed due to restrict not affecting function compatibility in GCC
357 // if ( type->get_isRestrict() ) {
358 // mangleName << "E";
359 // } // if
360 if ( type->get_lvalue() ) {
361 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
362 mangleName << "L";
363 }
364 if ( type->get_atomic() ) {
365 mangleName << "A";
366 } // if
367 }
368 } // namespace
369 } // namespace Mangler
370} // namespace SymTab
371
372// Local Variables: //
373// tab-width: 4 //
374// mode: c++ //
375// compile-command: "make install" //
376// End: //
Note: See TracBrowser for help on using the repository browser.