source: src/SymTab/Mangler.cc@ 0ac366b

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 0ac366b was b8a52f5, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

Fix Mangler warning

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