1 //===-- Mangler.cpp - Self-contained c/asm llvm name mangler --------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Unified name mangler for CWriter and assembly backends.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/Support/Mangler.h"
15 #include "llvm/Function.h"
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/ADT/StringExtras.h"
18 #include "llvm/ADT/StringMap.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/Support/raw_ostream.h"
23 static char HexDigit(int V
) {
24 return V
< 10 ? V
+'0' : V
+'A'-10;
27 static std::string
MangleLetter(unsigned char C
) {
28 char Result
[] = { '_', HexDigit(C
>> 4), HexDigit(C
& 15), '_', 0 };
32 /// makeNameProper - We don't want identifier names non-C-identifier characters
33 /// in them, so mangle them as appropriate.
35 std::string
Mangler::makeNameProper(const std::string
&X
,
36 ManglerPrefixTy PrefixTy
) {
37 assert(!X
.empty() && "Cannot mangle empty strings");
42 // If X does not start with (char)1, add the prefix.
43 bool NeedPrefix
= true;
44 std::string::const_iterator I
= X
.begin();
47 ++I
; // Skip over the marker.
50 // Mangle the first letter specially, don't allow numbers.
51 if (*I
>= '0' && *I
<= '9')
52 Result
+= MangleLetter(*I
++);
54 for (std::string::const_iterator E
= X
.end(); I
!= E
; ++I
) {
55 if (!isCharAcceptable(*I
))
56 Result
+= MangleLetter(*I
);
62 Result
= Prefix
+ Result
;
64 if (PrefixTy
== Mangler::Private
)
65 Result
= PrivatePrefix
+ Result
;
66 else if (PrefixTy
== Mangler::LinkerPrivate
)
67 Result
= LinkerPrivatePrefix
+ Result
;
73 bool NeedPrefix
= true;
74 bool NeedQuotes
= false;
76 std::string::const_iterator I
= X
.begin();
79 ++I
; // Skip over the marker.
82 // If the first character is a number, we need quotes.
83 if (*I
>= '0' && *I
<= '9')
86 // Do an initial scan of the string, checking to see if we need quotes or
87 // to escape a '"' or not.
89 for (std::string::const_iterator E
= X
.end(); I
!= E
; ++I
)
90 if (!isCharAcceptable(*I
)) {
95 // In the common case, we don't need quotes. Handle this quickly.
98 return X
.substr(1); // Strip off the \001.
102 if (PrefixTy
== Mangler::Private
)
103 Result
= PrivatePrefix
+ Result
;
104 else if (PrefixTy
== Mangler::LinkerPrivate
)
105 Result
= LinkerPrivatePrefix
+ Result
;
111 Result
= X
.substr(0, I
-X
.begin());
113 // Otherwise, construct the string the expensive way.
114 for (std::string::const_iterator E
= X
.end(); I
!= E
; ++I
) {
124 Result
= Prefix
+ Result
;
126 if (PrefixTy
== Mangler::Private
)
127 Result
= PrivatePrefix
+ Result
;
128 else if (PrefixTy
== Mangler::LinkerPrivate
)
129 Result
= LinkerPrivatePrefix
+ Result
;
132 Result
= '"' + Result
+ '"';
136 /// getMangledName - Returns the mangled name of V, an LLVM Value,
137 /// in the current module. If 'Suffix' is specified, the name ends with the
138 /// specified suffix. If 'ForcePrivate' is specified, the label is specified
139 /// to have a private label prefix.
141 std::string
Mangler::getMangledName(const GlobalValue
*GV
, const char *Suffix
,
143 assert((!isa
<Function
>(GV
) || !cast
<Function
>(GV
)->isIntrinsic()) &&
144 "Intrinsic functions cannot be mangled by Mangler");
146 ManglerPrefixTy PrefixTy
=
147 (GV
->hasPrivateLinkage() || ForcePrivate
) ? Mangler::Private
:
148 GV
->hasLinkerPrivateLinkage() ? Mangler::LinkerPrivate
: Mangler::Default
;
151 return makeNameProper(GV
->getNameStr() + Suffix
, PrefixTy
);
153 // Get the ID for the global, assigning a new one if we haven't got one
155 unsigned &ID
= AnonGlobalIDs
[GV
];
156 if (ID
== 0) ID
= NextAnonGlobalID
++;
158 // Must mangle the global into a unique ID.
159 return makeNameProper("__unnamed_" + utostr(ID
) + Suffix
, PrefixTy
);
163 /// getNameWithPrefix - Fill OutName with the name of the appropriate prefix
164 /// and the specified global variable's name. If the global variable doesn't
165 /// have a name, this fills in a unique name for the global.
166 void Mangler::getNameWithPrefix(SmallVectorImpl
<char> &OutName
,
167 const GlobalValue
*GV
,
168 bool isImplicitlyPrivate
) {
170 // If the global is anonymous or not led with \1, then add the appropriate
172 if (!GV
->hasName() || GV
->getName()[0] != '\1') {
173 if (GV
->hasPrivateLinkage() || isImplicitlyPrivate
)
174 OutName
.append(PrivatePrefix
, PrivatePrefix
+strlen(PrivatePrefix
));
175 else if (GV
->hasLinkerPrivateLinkage())
176 OutName
.append(LinkerPrivatePrefix
,
177 LinkerPrivatePrefix
+strlen(LinkerPrivatePrefix
));;
178 OutName
.append(Prefix
, Prefix
+strlen(Prefix
));
181 // If the global has a name, just append it now.
183 StringRef Name
= GV
->getName();
185 // Strip off the prefix marker if present.
187 OutName
.append(Name
.begin(), Name
.end());
189 OutName
.append(Name
.begin()+1, Name
.end());
193 // If the global variable doesn't have a name, return a unique name for the
194 // global based on a numbering.
196 // Get the ID for the global, assigning a new one if we haven't got one
198 unsigned &ID
= AnonGlobalIDs
[GV
];
199 if (ID
== 0) ID
= NextAnonGlobalID
++;
201 // Must mangle the global into a unique ID.
202 raw_svector_ostream(OutName
) << "__unnamed_" << ID
;
206 Mangler::Mangler(Module
&M
, const char *prefix
, const char *privatePrefix
,
207 const char *linkerPrivatePrefix
)
208 : Prefix(prefix
), PrivatePrefix(privatePrefix
),
209 LinkerPrivatePrefix(linkerPrivatePrefix
), UseQuotes(false),
210 NextAnonGlobalID(1) {
211 std::fill(AcceptableChars
, array_endof(AcceptableChars
), 0);
213 // Letters and numbers are acceptable.
214 for (unsigned char X
= 'a'; X
<= 'z'; ++X
)
215 markCharAcceptable(X
);
216 for (unsigned char X
= 'A'; X
<= 'Z'; ++X
)
217 markCharAcceptable(X
);
218 for (unsigned char X
= '0'; X
<= '9'; ++X
)
219 markCharAcceptable(X
);
221 // These chars are acceptable.
222 markCharAcceptable('_');
223 markCharAcceptable('$');
224 markCharAcceptable('.');
225 markCharAcceptable('@');