/[pkg-src]/trunk/llvm/patches/llvm-3.8.0-D18035-PR23529-Mangler-part-of-attrbute-abi_tag-support.patch |
Annotation of /trunk/llvm/patches/llvm-3.8.0-D18035-PR23529-Mangler-part-of-attrbute-abi_tag-support.patch
Parent Directory | Revision Log
Revision 2804 -
(hide annotations)
(download)
Wed Jun 8 12:54:34 2016 UTC (8 years, 3 months ago) by niro
File size: 43777 byte(s)
Wed Jun 8 12:54:34 2016 UTC (8 years, 3 months ago) by niro
File size: 43777 byte(s)
-llvm-3.8.0 upstream patches
1 | niro | 2804 | Index: lib/AST/ItaniumMangle.cpp |
2 | =================================================================== | ||
3 | --- lib/AST/ItaniumMangle.cpp | ||
4 | +++ lib/AST/ItaniumMangle.cpp | ||
5 | @@ -214,6 +214,12 @@ | ||
6 | class CXXNameMangler { | ||
7 | ItaniumMangleContextImpl &Context; | ||
8 | raw_ostream &Out; | ||
9 | + bool NullOut = false; | ||
10 | + /// In the "DisableDerivedAbiTags" mode derived ABI tags are not calculated. | ||
11 | + /// This mode is used when mangler creates another mangler recursively to | ||
12 | + /// calculate ABI tags for the function return value or the variable type. | ||
13 | + /// Also it is required to avoid infinite recursion in some cases. | ||
14 | + bool DisableDerivedAbiTags = false; | ||
15 | |||
16 | /// The "structor" is the top-level declaration being mangled, if | ||
17 | /// that's not a template specialization; otherwise it's the pattern | ||
18 | @@ -263,27 +269,148 @@ | ||
19 | |||
20 | } FunctionTypeDepth; | ||
21 | |||
22 | + // abi_tag is a gcc attribute, taking one or more strings called "tags". | ||
23 | + // The goal is to annotate against which version of a library an object was | ||
24 | + // built and to be able to provide backwards compatibility ("dual abi"). | ||
25 | + // For more information see docs/ItaniumMangleAbiTags.rst. | ||
26 | + typedef SmallVector<StringRef, 4> AbiTagList; | ||
27 | + typedef llvm::SmallSetVector<StringRef, 4> AbiTagSet; | ||
28 | + | ||
29 | + // State to gather all implicit and explicit tags used in a mangled name. | ||
30 | + // Must always have an instance of this while emitting any name to keep | ||
31 | + // track. | ||
32 | + class AbiTagState final { | ||
33 | + //! All abi tags used implicitly or explicitly | ||
34 | + AbiTagSet UsedAbiTags; | ||
35 | + //! All explicit abi tags (i.e. not from namespace) | ||
36 | + AbiTagSet EmittedAbiTags; | ||
37 | + | ||
38 | + AbiTagState *&LinkHead; | ||
39 | + AbiTagState *Parent = nullptr; | ||
40 | + | ||
41 | + bool LinkActive = false; | ||
42 | + | ||
43 | + public: | ||
44 | + explicit AbiTagState(AbiTagState *&Head) : LinkHead(Head) { | ||
45 | + Parent = LinkHead; | ||
46 | + LinkHead = this; | ||
47 | + LinkActive = true; | ||
48 | + } | ||
49 | + | ||
50 | + // no copy, no move | ||
51 | + AbiTagState(const AbiTagState &) = delete; | ||
52 | + AbiTagState &operator=(const AbiTagState &) = delete; | ||
53 | + | ||
54 | + ~AbiTagState() { pop(); } | ||
55 | + | ||
56 | + void pop() { | ||
57 | + if (!LinkActive) | ||
58 | + return; | ||
59 | + | ||
60 | + assert(LinkHead == this && | ||
61 | + "abi tag link head must point to us on destruction"); | ||
62 | + LinkActive = false; | ||
63 | + if (Parent) { | ||
64 | + Parent->UsedAbiTags.insert(UsedAbiTags.begin(), UsedAbiTags.end()); | ||
65 | + Parent->EmittedAbiTags.insert(EmittedAbiTags.begin(), | ||
66 | + EmittedAbiTags.end()); | ||
67 | + } | ||
68 | + LinkHead = Parent; | ||
69 | + } | ||
70 | + | ||
71 | + void write(raw_ostream &Out, const NamedDecl *ND, | ||
72 | + const AbiTagList *AdditionalAbiTags) { | ||
73 | + ND = cast<NamedDecl>(ND->getCanonicalDecl()); | ||
74 | + | ||
75 | + if (!isa<FunctionDecl>(ND) && !isa<VarDecl>(ND)) { | ||
76 | + assert( | ||
77 | + !AdditionalAbiTags && | ||
78 | + "only function and variables need a list of additional abi tags"); | ||
79 | + if (const auto *NS = dyn_cast<NamespaceDecl>(ND)) { | ||
80 | + if (const auto *AbiTag = NS->getAttr<AbiTagAttr>()) { | ||
81 | + for (const auto &Tag : AbiTag->tags()) { | ||
82 | + UsedAbiTags.insert(Tag); | ||
83 | + } | ||
84 | + } | ||
85 | + // Don't emit abi tags for namespaces. | ||
86 | + return; | ||
87 | + } | ||
88 | + } | ||
89 | + | ||
90 | + AbiTagList TagList; | ||
91 | + if (const auto *AbiTag = ND->getAttr<AbiTagAttr>()) { | ||
92 | + for (const auto &Tag : AbiTag->tags()) { | ||
93 | + UsedAbiTags.insert(Tag); | ||
94 | + // AbiTag->tags() is sorted and has no duplicates | ||
95 | + TagList.push_back(Tag); | ||
96 | + } | ||
97 | + } | ||
98 | + | ||
99 | + if (AdditionalAbiTags) { | ||
100 | + for (const auto &Tag : *AdditionalAbiTags) { | ||
101 | + UsedAbiTags.insert(Tag); | ||
102 | + if (std::find(TagList.begin(), TagList.end(), Tag) == TagList.end()) { | ||
103 | + // don't insert duplicates | ||
104 | + TagList.push_back(Tag); | ||
105 | + } | ||
106 | + } | ||
107 | + // AbiTag->tags() are already sorted; only add if we had additional tags | ||
108 | + std::sort(TagList.begin(), TagList.end()); | ||
109 | + } | ||
110 | + | ||
111 | + writeSortedUniqueAbiTags(Out, TagList); | ||
112 | + } | ||
113 | + | ||
114 | + const AbiTagSet &getUsedAbiTags() const { return UsedAbiTags; } | ||
115 | + void setUsedAbiTags(const AbiTagSet &AbiTags) { | ||
116 | + UsedAbiTags = AbiTags; | ||
117 | + } | ||
118 | + | ||
119 | + const AbiTagSet &getEmittedAbiTags() const { | ||
120 | + return EmittedAbiTags; | ||
121 | + } | ||
122 | + | ||
123 | + private: | ||
124 | + template <typename TagList> | ||
125 | + void writeSortedUniqueAbiTags(raw_ostream &Out, TagList const &AbiTags) { | ||
126 | + for (const auto &Tag : AbiTags) { | ||
127 | + EmittedAbiTags.insert(Tag); | ||
128 | + Out << "B"; | ||
129 | + Out << Tag.size(); | ||
130 | + Out << Tag; | ||
131 | + } | ||
132 | + } | ||
133 | + }; | ||
134 | + | ||
135 | + AbiTagState *AbiTags = nullptr; | ||
136 | + AbiTagState AbiTagsRoot; | ||
137 | + | ||
138 | llvm::DenseMap<uintptr_t, unsigned> Substitutions; | ||
139 | |||
140 | ASTContext &getASTContext() const { return Context.getASTContext(); } | ||
141 | |||
142 | public: | ||
143 | CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, | ||
144 | - const NamedDecl *D = nullptr) | ||
145 | - : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(0), | ||
146 | - SeqID(0) { | ||
147 | + const NamedDecl *D = nullptr, bool NullOut_ = false) | ||
148 | + : Context(C), Out(Out_), NullOut(NullOut_), Structor(getStructor(D)), | ||
149 | + StructorType(0), SeqID(0), AbiTagsRoot(AbiTags) { | ||
150 | // These can't be mangled without a ctor type or dtor type. | ||
151 | assert(!D || (!isa<CXXDestructorDecl>(D) && | ||
152 | !isa<CXXConstructorDecl>(D))); | ||
153 | } | ||
154 | CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, | ||
155 | const CXXConstructorDecl *D, CXXCtorType Type) | ||
156 | : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), | ||
157 | - SeqID(0) { } | ||
158 | + SeqID(0), AbiTagsRoot(AbiTags) { } | ||
159 | CXXNameMangler(ItaniumMangleContextImpl &C, raw_ostream &Out_, | ||
160 | const CXXDestructorDecl *D, CXXDtorType Type) | ||
161 | : Context(C), Out(Out_), Structor(getStructor(D)), StructorType(Type), | ||
162 | - SeqID(0) { } | ||
163 | + SeqID(0), AbiTagsRoot(AbiTags) { } | ||
164 | + | ||
165 | + CXXNameMangler(CXXNameMangler &Outer, llvm::raw_null_ostream &Out_) | ||
166 | + : Context(Outer.Context), Out(Out_), NullOut(true), | ||
167 | + Structor(Outer.Structor), StructorType(Outer.StructorType), | ||
168 | + SeqID(Outer.SeqID), AbiTagsRoot(AbiTags) {} | ||
169 | |||
170 | #if MANGLE_CHECKER | ||
171 | ~CXXNameMangler() { | ||
172 | @@ -298,14 +425,18 @@ | ||
173 | #endif | ||
174 | raw_ostream &getStream() { return Out; } | ||
175 | |||
176 | + void disableDerivedAbiTags() { DisableDerivedAbiTags = true; } | ||
177 | + static bool shouldHaveAbiTags(ItaniumMangleContextImpl &C, const VarDecl *VD); | ||
178 | + | ||
179 | void mangle(const NamedDecl *D); | ||
180 | void mangleCallOffset(int64_t NonVirtual, int64_t Virtual); | ||
181 | void mangleNumber(const llvm::APSInt &I); | ||
182 | void mangleNumber(int64_t Number); | ||
183 | void mangleFloat(const llvm::APFloat &F); | ||
184 | - void mangleFunctionEncoding(const FunctionDecl *FD); | ||
185 | + void mangleFunctionEncoding(const FunctionDecl *FD, | ||
186 | + bool ExcludeUnqualifiedName = false); | ||
187 | void mangleSeqID(unsigned SeqID); | ||
188 | - void mangleName(const NamedDecl *ND); | ||
189 | + void mangleName(const NamedDecl *ND, bool ExcludeUnqualifiedName = false); | ||
190 | void mangleType(QualType T); | ||
191 | void mangleNameOrStandardSubstitution(const NamedDecl *ND); | ||
192 | |||
193 | @@ -336,31 +467,53 @@ | ||
194 | DeclarationName name, | ||
195 | unsigned KnownArity = UnknownArity); | ||
196 | |||
197 | - void mangleName(const TemplateDecl *TD, | ||
198 | - const TemplateArgument *TemplateArgs, | ||
199 | - unsigned NumTemplateArgs); | ||
200 | - void mangleUnqualifiedName(const NamedDecl *ND) { | ||
201 | - mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity); | ||
202 | + void mangleFunctionEncodingBareType(const FunctionDecl *FD); | ||
203 | + | ||
204 | + void mangleNameWithAbiTags(const NamedDecl *ND, | ||
205 | + const AbiTagList *AdditionalAbiTags, | ||
206 | + bool ExcludeUnqualifiedName); | ||
207 | + void mangleTemplateName(const TemplateDecl *TD, | ||
208 | + const AbiTagList *AdditionalAbiTags, | ||
209 | + bool ExcludeUnqualifiedName, | ||
210 | + const TemplateArgument *TemplateArgs, | ||
211 | + unsigned NumTemplateArgs); | ||
212 | + void mangleUnqualifiedName(const NamedDecl *ND, | ||
213 | + const AbiTagList *AdditionalAbiTags) { | ||
214 | + mangleUnqualifiedName(ND, ND->getDeclName(), UnknownArity, | ||
215 | + AdditionalAbiTags); | ||
216 | } | ||
217 | void mangleUnqualifiedName(const NamedDecl *ND, DeclarationName Name, | ||
218 | - unsigned KnownArity); | ||
219 | - void mangleUnscopedName(const NamedDecl *ND); | ||
220 | - void mangleUnscopedTemplateName(const TemplateDecl *ND); | ||
221 | - void mangleUnscopedTemplateName(TemplateName); | ||
222 | + unsigned KnownArity, | ||
223 | + const AbiTagList *AdditionalAbiTags); | ||
224 | + void mangleUnscopedName(const NamedDecl *ND, | ||
225 | + const AbiTagList *AdditionalAbiTags); | ||
226 | + void mangleUnscopedTemplateName(const TemplateDecl *ND, | ||
227 | + const AbiTagList *AdditionalAbiTags); | ||
228 | + void mangleUnscopedTemplateName(TemplateName, | ||
229 | + const AbiTagList *AdditionalAbiTags); | ||
230 | void mangleSourceName(const IdentifierInfo *II); | ||
231 | - void mangleLocalName(const Decl *D); | ||
232 | + void mangleLocalName(const Decl *D, | ||
233 | + const AbiTagList *AdditionalAbiTags, | ||
234 | + bool ExcludeUnqualifiedName); | ||
235 | void mangleBlockForPrefix(const BlockDecl *Block); | ||
236 | void mangleUnqualifiedBlock(const BlockDecl *Block); | ||
237 | void mangleLambda(const CXXRecordDecl *Lambda); | ||
238 | void mangleNestedName(const NamedDecl *ND, const DeclContext *DC, | ||
239 | - bool NoFunction=false); | ||
240 | + const AbiTagList *AdditionalAbiTags, | ||
241 | + bool NoFunction, | ||
242 | + bool ExcludeUnqualifiedName); | ||
243 | void mangleNestedName(const TemplateDecl *TD, | ||
244 | + const AbiTagList *AdditionalAbiTags, | ||
245 | + bool ExcludeUnqualifiedName, | ||
246 | const TemplateArgument *TemplateArgs, | ||
247 | unsigned NumTemplateArgs); | ||
248 | void manglePrefix(NestedNameSpecifier *qualifier); | ||
249 | void manglePrefix(const DeclContext *DC, bool NoFunction=false); | ||
250 | void manglePrefix(QualType type); | ||
251 | - void mangleTemplatePrefix(const TemplateDecl *ND, bool NoFunction=false); | ||
252 | + void mangleTemplatePrefix(const TemplateDecl *ND, | ||
253 | + const AbiTagList *AdditionalAbiTags, | ||
254 | + bool NoFunction = false, | ||
255 | + bool ExcludeUnqualifiedName = false); | ||
256 | void mangleTemplatePrefix(TemplateName Template); | ||
257 | bool mangleUnresolvedTypeOrSimpleId(QualType DestroyedType, | ||
258 | StringRef Prefix = ""); | ||
259 | @@ -411,6 +564,13 @@ | ||
260 | void mangleTemplateParameter(unsigned Index); | ||
261 | |||
262 | void mangleFunctionParam(const ParmVarDecl *parm); | ||
263 | + | ||
264 | + void writeAbiTags(const NamedDecl *ND, | ||
265 | + const AbiTagList *AdditionalAbiTags = nullptr); | ||
266 | + | ||
267 | + AbiTagSet getTagsFromPrefixAndTemplateArguments(const NamedDecl *ND); | ||
268 | + AbiTagList makeAdditionalTagsForFunction(const FunctionDecl *FD); | ||
269 | + AbiTagList makeAdditionalTagsForVariable(const VarDecl *VD); | ||
270 | }; | ||
271 | |||
272 | } | ||
273 | @@ -454,13 +614,20 @@ | ||
274 | while (!DC->isNamespace() && !DC->isTranslationUnit()) | ||
275 | DC = getEffectiveParentContext(DC); | ||
276 | if (DC->isTranslationUnit() && D->getFormalLinkage() != InternalLinkage && | ||
277 | + !CXXNameMangler::shouldHaveAbiTags(*this, VD) && | ||
278 | !isa<VarTemplateSpecializationDecl>(D)) | ||
279 | return false; | ||
280 | } | ||
281 | |||
282 | return true; | ||
283 | } | ||
284 | |||
285 | +void CXXNameMangler::writeAbiTags(const NamedDecl *ND, | ||
286 | + const AbiTagList *AdditionalAbiTags) { | ||
287 | + assert(AbiTags && "require AbiTagState"); | ||
288 | + AbiTags->write(Out, ND, DisableDerivedAbiTags ? nullptr : AdditionalAbiTags); | ||
289 | +} | ||
290 | + | ||
291 | void CXXNameMangler::mangle(const NamedDecl *D) { | ||
292 | // <mangled-name> ::= _Z <encoding> | ||
293 | // ::= <data name> | ||
294 | @@ -476,14 +643,31 @@ | ||
295 | mangleName(cast<FieldDecl>(D)); | ||
296 | } | ||
297 | |||
298 | -void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD) { | ||
299 | - // <encoding> ::= <function name> <bare-function-type> | ||
300 | - mangleName(FD); | ||
301 | - | ||
302 | +void CXXNameMangler::mangleFunctionEncoding(const FunctionDecl *FD, | ||
303 | + bool ExcludeUnqualifiedName) { | ||
304 | // Don't mangle in the type if this isn't a decl we should typically mangle. | ||
305 | - if (!Context.shouldMangleDeclName(FD)) | ||
306 | + if (!Context.shouldMangleDeclName(FD)) { | ||
307 | + mangleNameWithAbiTags(FD, /* AdditionalAbiTags */ nullptr, | ||
308 | + ExcludeUnqualifiedName); | ||
309 | return; | ||
310 | + } | ||
311 | + | ||
312 | + // <encoding> ::= <function name> <bare-function-type> | ||
313 | + | ||
314 | + if (ExcludeUnqualifiedName) { | ||
315 | + // running makeAdditionalTagsForFunction would loop, don't need it here | ||
316 | + // anyway | ||
317 | + mangleNameWithAbiTags(FD, /* AdditionalAbiTags */ nullptr, | ||
318 | + ExcludeUnqualifiedName); | ||
319 | + } else { | ||
320 | + AbiTagList AdditionalAbiTags = makeAdditionalTagsForFunction(FD); | ||
321 | + mangleNameWithAbiTags(FD, &AdditionalAbiTags, ExcludeUnqualifiedName); | ||
322 | + } | ||
323 | + | ||
324 | + mangleFunctionEncodingBareType(FD); | ||
325 | +} | ||
326 | |||
327 | +void CXXNameMangler::mangleFunctionEncodingBareType(const FunctionDecl *FD) { | ||
328 | if (FD->hasAttr<EnableIfAttr>()) { | ||
329 | FunctionTypeDepthState Saved = FunctionTypeDepth.push(); | ||
330 | Out << "Ua9enable_ifI"; | ||
331 | @@ -587,7 +771,24 @@ | ||
332 | return nullptr; | ||
333 | } | ||
334 | |||
335 | -void CXXNameMangler::mangleName(const NamedDecl *ND) { | ||
336 | +// Must not be run from mangleLocalName for the <entity name> as it would loop | ||
337 | +// otherwise. | ||
338 | +void CXXNameMangler::mangleName(const NamedDecl *ND, | ||
339 | + bool ExcludeUnqualifiedName) { | ||
340 | + if (!ExcludeUnqualifiedName) { | ||
341 | + if (const auto *VD = dyn_cast<VarDecl>(ND)) { | ||
342 | + AbiTagList VariableAdditionalAbiTags = makeAdditionalTagsForVariable(VD); | ||
343 | + mangleNameWithAbiTags(VD, &VariableAdditionalAbiTags, | ||
344 | + ExcludeUnqualifiedName); | ||
345 | + return; | ||
346 | + } | ||
347 | + } | ||
348 | + mangleNameWithAbiTags(ND, nullptr, ExcludeUnqualifiedName); | ||
349 | +} | ||
350 | + | ||
351 | +void CXXNameMangler::mangleNameWithAbiTags(const NamedDecl *ND, | ||
352 | + const AbiTagList *AdditionalAbiTags, | ||
353 | + bool ExcludeUnqualifiedName) { | ||
354 | // <name> ::= <nested-name> | ||
355 | // ::= <unscoped-name> | ||
356 | // ::= <unscoped-template-name> <template-args> | ||
357 | @@ -603,7 +804,7 @@ | ||
358 | while (!DC->isNamespace() && !DC->isTranslationUnit()) | ||
359 | DC = getEffectiveParentContext(DC); | ||
360 | else if (GetLocalClassDecl(ND)) { | ||
361 | - mangleLocalName(ND); | ||
362 | + mangleLocalName(ND, AdditionalAbiTags, ExcludeUnqualifiedName); | ||
363 | return; | ||
364 | } | ||
365 | |||
366 | @@ -613,76 +814,93 @@ | ||
367 | // Check if we have a template. | ||
368 | const TemplateArgumentList *TemplateArgs = nullptr; | ||
369 | if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { | ||
370 | - mangleUnscopedTemplateName(TD); | ||
371 | + if (!ExcludeUnqualifiedName) | ||
372 | + mangleUnscopedTemplateName(TD, AdditionalAbiTags); | ||
373 | mangleTemplateArgs(*TemplateArgs); | ||
374 | return; | ||
375 | } | ||
376 | |||
377 | - mangleUnscopedName(ND); | ||
378 | + if (!ExcludeUnqualifiedName) | ||
379 | + mangleUnscopedName(ND, AdditionalAbiTags); | ||
380 | return; | ||
381 | } | ||
382 | |||
383 | if (isLocalContainerContext(DC)) { | ||
384 | - mangleLocalName(ND); | ||
385 | + mangleLocalName(ND, AdditionalAbiTags, ExcludeUnqualifiedName); | ||
386 | return; | ||
387 | } | ||
388 | |||
389 | - mangleNestedName(ND, DC); | ||
390 | + mangleNestedName(ND, DC, AdditionalAbiTags, /* NoFunction */ false, | ||
391 | + ExcludeUnqualifiedName); | ||
392 | } | ||
393 | -void CXXNameMangler::mangleName(const TemplateDecl *TD, | ||
394 | - const TemplateArgument *TemplateArgs, | ||
395 | - unsigned NumTemplateArgs) { | ||
396 | + | ||
397 | +void CXXNameMangler::mangleTemplateName(const TemplateDecl *TD, | ||
398 | + const AbiTagList *AdditionalAbiTags, | ||
399 | + bool ExcludeUnqualifiedName, | ||
400 | + const TemplateArgument *TemplateArgs, | ||
401 | + unsigned NumTemplateArgs) { | ||
402 | const DeclContext *DC = IgnoreLinkageSpecDecls(getEffectiveDeclContext(TD)); | ||
403 | |||
404 | if (DC->isTranslationUnit() || isStdNamespace(DC)) { | ||
405 | - mangleUnscopedTemplateName(TD); | ||
406 | + if (!ExcludeUnqualifiedName) | ||
407 | + mangleUnscopedTemplateName(TD, AdditionalAbiTags); | ||
408 | mangleTemplateArgs(TemplateArgs, NumTemplateArgs); | ||
409 | } else { | ||
410 | - mangleNestedName(TD, TemplateArgs, NumTemplateArgs); | ||
411 | + mangleNestedName(TD, AdditionalAbiTags, ExcludeUnqualifiedName, | ||
412 | + TemplateArgs, NumTemplateArgs); | ||
413 | } | ||
414 | } | ||
415 | |||
416 | -void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND) { | ||
417 | +void CXXNameMangler::mangleUnscopedName(const NamedDecl *ND, | ||
418 | + const AbiTagList *AdditionalAbiTags) { | ||
419 | // <unscoped-name> ::= <unqualified-name> | ||
420 | // ::= St <unqualified-name> # ::std:: | ||
421 | |||
422 | if (isStdNamespace(IgnoreLinkageSpecDecls(getEffectiveDeclContext(ND)))) | ||
423 | Out << "St"; | ||
424 | |||
425 | - mangleUnqualifiedName(ND); | ||
426 | + mangleUnqualifiedName(ND, AdditionalAbiTags); | ||
427 | } | ||
428 | |||
429 | -void CXXNameMangler::mangleUnscopedTemplateName(const TemplateDecl *ND) { | ||
430 | +void CXXNameMangler::mangleUnscopedTemplateName( | ||
431 | + const TemplateDecl *ND, const AbiTagList *AdditionalAbiTags) { | ||
432 | // <unscoped-template-name> ::= <unscoped-name> | ||
433 | // ::= <substitution> | ||
434 | if (mangleSubstitution(ND)) | ||
435 | return; | ||
436 | |||
437 | // <template-template-param> ::= <template-param> | ||
438 | - if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) | ||
439 | + if (const auto *TTP = dyn_cast<TemplateTemplateParmDecl>(ND)) { | ||
440 | + assert(!AdditionalAbiTags && | ||
441 | + "template template param cannot have abi tags"); | ||
442 | mangleTemplateParameter(TTP->getIndex()); | ||
443 | - else | ||
444 | - mangleUnscopedName(ND->getTemplatedDecl()); | ||
445 | + } else { | ||
446 | + mangleUnscopedName(ND->getTemplatedDecl(), AdditionalAbiTags); | ||
447 | + } | ||
448 | |||
449 | addSubstitution(ND); | ||
450 | } | ||
451 | |||
452 | -void CXXNameMangler::mangleUnscopedTemplateName(TemplateName Template) { | ||
453 | +void CXXNameMangler::mangleUnscopedTemplateName( | ||
454 | + TemplateName Template, const AbiTagList *AdditionalAbiTags) { | ||
455 | // <unscoped-template-name> ::= <unscoped-name> | ||
456 | // ::= <substitution> | ||
457 | if (TemplateDecl *TD = Template.getAsTemplateDecl()) | ||
458 | - return mangleUnscopedTemplateName(TD); | ||
459 | + return mangleUnscopedTemplateName(TD, AdditionalAbiTags); | ||
460 | |||
461 | if (mangleSubstitution(Template)) | ||
462 | return; | ||
463 | |||
464 | + assert(!AdditionalAbiTags && | ||
465 | + "dependent template name cannot have abi tags"); | ||
466 | + | ||
467 | DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); | ||
468 | assert(Dependent && "Not a dependent template name?"); | ||
469 | if (const IdentifierInfo *Id = Dependent->getIdentifier()) | ||
470 | mangleSourceName(Id); | ||
471 | else | ||
472 | mangleOperatorName(Dependent->getOperator(), UnknownArity); | ||
473 | - | ||
474 | + | ||
475 | addSubstitution(Template); | ||
476 | } | ||
477 | |||
478 | @@ -841,14 +1059,16 @@ | ||
479 | else | ||
480 | Out << "sr"; | ||
481 | mangleSourceName(qualifier->getAsNamespace()->getIdentifier()); | ||
482 | + writeAbiTags(qualifier->getAsNamespace()); | ||
483 | break; | ||
484 | case NestedNameSpecifier::NamespaceAlias: | ||
485 | if (qualifier->getPrefix()) | ||
486 | mangleUnresolvedPrefix(qualifier->getPrefix(), | ||
487 | /*recursive*/ true); | ||
488 | else | ||
489 | Out << "sr"; | ||
490 | mangleSourceName(qualifier->getAsNamespaceAlias()->getIdentifier()); | ||
491 | + writeAbiTags(qualifier->getAsNamespaceAlias()); | ||
492 | break; | ||
493 | |||
494 | case NestedNameSpecifier::TypeSpec: | ||
495 | @@ -883,6 +1103,7 @@ | ||
496 | Out << "sr"; | ||
497 | |||
498 | mangleSourceName(qualifier->getAsIdentifier()); | ||
499 | + // an Identifier has no type information, so we can't emit abi tags for it | ||
500 | break; | ||
501 | } | ||
502 | |||
503 | @@ -928,7 +1149,8 @@ | ||
504 | |||
505 | void CXXNameMangler::mangleUnqualifiedName(const NamedDecl *ND, | ||
506 | DeclarationName Name, | ||
507 | - unsigned KnownArity) { | ||
508 | + unsigned KnownArity, | ||
509 | + const AbiTagList *AdditionalAbiTags) { | ||
510 | unsigned Arity = KnownArity; | ||
511 | // <unqualified-name> ::= <operator-name> | ||
512 | // ::= <ctor-dtor-name> | ||
513 | @@ -947,6 +1169,7 @@ | ||
514 | Out << 'L'; | ||
515 | |||
516 | mangleSourceName(II); | ||
517 | + writeAbiTags(ND, AdditionalAbiTags); | ||
518 | break; | ||
519 | } | ||
520 | |||
521 | @@ -986,6 +1209,7 @@ | ||
522 | assert(FD->getIdentifier() && "Data member name isn't an identifier!"); | ||
523 | |||
524 | mangleSourceName(FD->getIdentifier()); | ||
525 | + // Not emitting abi tags: internal name anyway | ||
526 | break; | ||
527 | } | ||
528 | |||
529 | @@ -1006,6 +1230,10 @@ | ||
530 | assert(D->getDeclName().getAsIdentifierInfo() && | ||
531 | "Typedef was not named!"); | ||
532 | mangleSourceName(D->getDeclName().getAsIdentifierInfo()); | ||
533 | + assert(!AdditionalAbiTags && "Type cannot have additional abi tags"); | ||
534 | + // explicit abi tags are still possible; take from underlying type, not | ||
535 | + // from typedef. | ||
536 | + writeAbiTags(TD, nullptr); | ||
537 | break; | ||
538 | } | ||
539 | |||
540 | @@ -1015,6 +1243,8 @@ | ||
541 | // <lambda-sig> ::= <parameter-type>+ # Parameter types or 'v' for 'void'. | ||
542 | if (const CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(TD)) { | ||
543 | if (Record->isLambda() && Record->getLambdaManglingNumber()) { | ||
544 | + assert(!AdditionalAbiTags && | ||
545 | + "Lambda type cannot have additional abi tags"); | ||
546 | mangleLambda(Record); | ||
547 | break; | ||
548 | } | ||
549 | @@ -1026,11 +1256,13 @@ | ||
550 | if (UnnamedMangle > 1) | ||
551 | Out << UnnamedMangle - 2; | ||
552 | Out << '_'; | ||
553 | + writeAbiTags(TD, AdditionalAbiTags); | ||
554 | break; | ||
555 | } | ||
556 | |||
557 | - // Get a unique id for the anonymous struct. | ||
558 | - unsigned AnonStructId = Context.getAnonymousStructId(TD); | ||
559 | + // Get a unique id for the anonymous struct. If it is not a real output | ||
560 | + // ID doesn't matter so use fake one. | ||
561 | + unsigned AnonStructId = NullOut ? 0 : Context.getAnonymousStructId(TD); | ||
562 | |||
563 | // Mangle it as a source name in the form | ||
564 | // [n] $_<id> | ||
565 | @@ -1058,6 +1290,7 @@ | ||
566 | // Otherwise, use the complete constructor name. This is relevant if a | ||
567 | // class with a constructor is declared within a constructor. | ||
568 | mangleCXXCtorType(Ctor_Complete); | ||
569 | + writeAbiTags(ND, AdditionalAbiTags); | ||
570 | break; | ||
571 | |||
572 | case DeclarationName::CXXDestructorName: | ||
573 | @@ -1069,6 +1302,7 @@ | ||
574 | // Otherwise, use the complete destructor name. This is relevant if a | ||
575 | // class with a destructor is declared within a destructor. | ||
576 | mangleCXXDtorType(Dtor_Complete); | ||
577 | + writeAbiTags(ND, AdditionalAbiTags); | ||
578 | break; | ||
579 | |||
580 | case DeclarationName::CXXOperatorName: | ||
581 | @@ -1084,6 +1318,7 @@ | ||
582 | case DeclarationName::CXXConversionFunctionName: | ||
583 | case DeclarationName::CXXLiteralOperatorName: | ||
584 | mangleOperatorName(Name, Arity); | ||
585 | + writeAbiTags(ND, AdditionalAbiTags); | ||
586 | break; | ||
587 | |||
588 | case DeclarationName::CXXUsingDirective: | ||
589 | @@ -1100,7 +1335,9 @@ | ||
590 | |||
591 | void CXXNameMangler::mangleNestedName(const NamedDecl *ND, | ||
592 | const DeclContext *DC, | ||
593 | - bool NoFunction) { | ||
594 | + const AbiTagList *AdditionalAbiTags, | ||
595 | + bool NoFunction, | ||
596 | + bool ExcludeUnqualifiedName) { | ||
597 | // <nested-name> | ||
598 | // ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix> <unqualified-name> E | ||
599 | // ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix> | ||
600 | @@ -1120,30 +1357,36 @@ | ||
601 | // Check if we have a template. | ||
602 | const TemplateArgumentList *TemplateArgs = nullptr; | ||
603 | if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { | ||
604 | - mangleTemplatePrefix(TD, NoFunction); | ||
605 | + mangleTemplatePrefix(TD, AdditionalAbiTags, NoFunction, | ||
606 | + ExcludeUnqualifiedName); | ||
607 | mangleTemplateArgs(*TemplateArgs); | ||
608 | } | ||
609 | else { | ||
610 | manglePrefix(DC, NoFunction); | ||
611 | - mangleUnqualifiedName(ND); | ||
612 | + if (!ExcludeUnqualifiedName) | ||
613 | + mangleUnqualifiedName(ND, AdditionalAbiTags); | ||
614 | } | ||
615 | |||
616 | Out << 'E'; | ||
617 | } | ||
618 | void CXXNameMangler::mangleNestedName(const TemplateDecl *TD, | ||
619 | + const AbiTagList *AdditionalAbiTags, | ||
620 | + bool ExcludeUnqualifiedName, | ||
621 | const TemplateArgument *TemplateArgs, | ||
622 | unsigned NumTemplateArgs) { | ||
623 | // <nested-name> ::= N [<CV-qualifiers>] <template-prefix> <template-args> E | ||
624 | |||
625 | Out << 'N'; | ||
626 | |||
627 | - mangleTemplatePrefix(TD); | ||
628 | + mangleTemplatePrefix(TD, AdditionalAbiTags, ExcludeUnqualifiedName); | ||
629 | mangleTemplateArgs(TemplateArgs, NumTemplateArgs); | ||
630 | |||
631 | Out << 'E'; | ||
632 | } | ||
633 | |||
634 | -void CXXNameMangler::mangleLocalName(const Decl *D) { | ||
635 | +void CXXNameMangler::mangleLocalName(const Decl *D, | ||
636 | + const AbiTagList *AdditionalAbiTags, | ||
637 | + bool ExcludeUnqualifiedName) { | ||
638 | // <local-name> := Z <function encoding> E <entity name> [<discriminator>] | ||
639 | // := Z <function encoding> E s [<discriminator>] | ||
640 | // <local-name> := Z <function encoding> E d [ <parameter number> ] | ||
641 | @@ -1155,15 +1398,26 @@ | ||
642 | |||
643 | Out << 'Z'; | ||
644 | |||
645 | - if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) | ||
646 | - mangleObjCMethodName(MD); | ||
647 | - else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) | ||
648 | - mangleBlockForPrefix(BD); | ||
649 | - else | ||
650 | - mangleFunctionEncoding(cast<FunctionDecl>(DC)); | ||
651 | + { | ||
652 | + AbiTagState LocalAbiTags(AbiTags); | ||
653 | + | ||
654 | + if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(DC)) | ||
655 | + mangleObjCMethodName(MD); | ||
656 | + else if (const BlockDecl *BD = dyn_cast<BlockDecl>(DC)) | ||
657 | + mangleBlockForPrefix(BD); | ||
658 | + else | ||
659 | + mangleFunctionEncoding(cast<FunctionDecl>(DC)); | ||
660 | + | ||
661 | + // Implicit ABI tags (from namespace) are not available in the following | ||
662 | + // entity; reset to actually emitted tags, which are available. | ||
663 | + LocalAbiTags.setUsedAbiTags(LocalAbiTags.getEmittedAbiTags()); | ||
664 | + } | ||
665 | |||
666 | Out << 'E'; | ||
667 | |||
668 | + // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to | ||
669 | + // be a bug that is fixed in trunk. | ||
670 | + | ||
671 | if (RD) { | ||
672 | // The parameter number is omitted for the last parameter, 0 for the | ||
673 | // second-to-last parameter, 1 for the third-to-last parameter, etc. The | ||
674 | @@ -1188,13 +1442,17 @@ | ||
675 | // Mangle the name relative to the closest enclosing function. | ||
676 | // equality ok because RD derived from ND above | ||
677 | if (D == RD) { | ||
678 | - mangleUnqualifiedName(RD); | ||
679 | + if (!ExcludeUnqualifiedName) | ||
680 | + mangleUnqualifiedName(RD, AdditionalAbiTags); | ||
681 | } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { | ||
682 | manglePrefix(getEffectiveDeclContext(BD), true /*NoFunction*/); | ||
683 | - mangleUnqualifiedBlock(BD); | ||
684 | + assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); | ||
685 | + if (!ExcludeUnqualifiedName) | ||
686 | + mangleUnqualifiedBlock(BD); | ||
687 | } else { | ||
688 | const NamedDecl *ND = cast<NamedDecl>(D); | ||
689 | - mangleNestedName(ND, getEffectiveDeclContext(ND), true /*NoFunction*/); | ||
690 | + mangleNestedName(ND, getEffectiveDeclContext(ND), AdditionalAbiTags, | ||
691 | + true /*NoFunction*/, ExcludeUnqualifiedName); | ||
692 | } | ||
693 | } else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { | ||
694 | // Mangle a block in a default parameter; see above explanation for | ||
695 | @@ -1211,30 +1469,37 @@ | ||
696 | } | ||
697 | } | ||
698 | |||
699 | - mangleUnqualifiedBlock(BD); | ||
700 | + assert(!AdditionalAbiTags && "Block cannot have additional abi tags"); | ||
701 | + if (!ExcludeUnqualifiedName) | ||
702 | + mangleUnqualifiedBlock(BD); | ||
703 | } else { | ||
704 | - mangleUnqualifiedName(cast<NamedDecl>(D)); | ||
705 | - } | ||
706 | - | ||
707 | - if (const NamedDecl *ND = dyn_cast<NamedDecl>(RD ? RD : D)) { | ||
708 | - unsigned disc; | ||
709 | - if (Context.getNextDiscriminator(ND, disc)) { | ||
710 | - if (disc < 10) | ||
711 | - Out << '_' << disc; | ||
712 | - else | ||
713 | - Out << "__" << disc << '_'; | ||
714 | + if (!ExcludeUnqualifiedName) | ||
715 | + mangleUnqualifiedName(cast<NamedDecl>(D), AdditionalAbiTags); | ||
716 | + } | ||
717 | + | ||
718 | + if (!ExcludeUnqualifiedName) { | ||
719 | + if (const NamedDecl *ND = dyn_cast<NamedDecl>(RD ? RD : D)) { | ||
720 | + unsigned disc; | ||
721 | + if (Context.getNextDiscriminator(ND, disc)) { | ||
722 | + if (disc < 10) | ||
723 | + Out << '_' << disc; | ||
724 | + else | ||
725 | + Out << "__" << disc << '_'; | ||
726 | + } | ||
727 | } | ||
728 | } | ||
729 | } | ||
730 | |||
731 | void CXXNameMangler::mangleBlockForPrefix(const BlockDecl *Block) { | ||
732 | if (GetLocalClassDecl(Block)) { | ||
733 | - mangleLocalName(Block); | ||
734 | + mangleLocalName(Block, /* AdditionalAbiTags */ nullptr, | ||
735 | + /* ExcludeUnqualifiedName */ false); | ||
736 | return; | ||
737 | } | ||
738 | const DeclContext *DC = getEffectiveDeclContext(Block); | ||
739 | if (isLocalContainerContext(DC)) { | ||
740 | - mangleLocalName(Block); | ||
741 | + mangleLocalName(Block, /* AdditionalAbiTags */ nullptr, | ||
742 | + /* ExcludeUnqualifiedName */ false); | ||
743 | return; | ||
744 | } | ||
745 | manglePrefix(getEffectiveDeclContext(Block)); | ||
746 | @@ -1245,10 +1510,11 @@ | ||
747 | if (Decl *Context = Block->getBlockManglingContextDecl()) { | ||
748 | if ((isa<VarDecl>(Context) || isa<FieldDecl>(Context)) && | ||
749 | Context->getDeclContext()->isRecord()) { | ||
750 | - if (const IdentifierInfo *Name | ||
751 | - = cast<NamedDecl>(Context)->getIdentifier()) { | ||
752 | + const auto *ND = cast<NamedDecl>(Context); | ||
753 | + if (const IdentifierInfo *Name = ND->getIdentifier()) { | ||
754 | mangleSourceName(Name); | ||
755 | - Out << 'M'; | ||
756 | + writeAbiTags(ND, /* AdditionalAbiTags */ nullptr); | ||
757 | + Out << 'M'; | ||
758 | } | ||
759 | } | ||
760 | } | ||
761 | @@ -1281,7 +1547,7 @@ | ||
762 | if (const IdentifierInfo *Name | ||
763 | = cast<NamedDecl>(Context)->getIdentifier()) { | ||
764 | mangleSourceName(Name); | ||
765 | - Out << 'M'; | ||
766 | + Out << 'M'; | ||
767 | } | ||
768 | } | ||
769 | } | ||
770 | @@ -1364,11 +1630,11 @@ | ||
771 | // Check if we have a template. | ||
772 | const TemplateArgumentList *TemplateArgs = nullptr; | ||
773 | if (const TemplateDecl *TD = isTemplate(ND, TemplateArgs)) { | ||
774 | - mangleTemplatePrefix(TD); | ||
775 | + mangleTemplatePrefix(TD, /* AdditionalAbiTags */ nullptr); | ||
776 | mangleTemplateArgs(*TemplateArgs); | ||
777 | } else { | ||
778 | manglePrefix(getEffectiveDeclContext(ND), NoFunction); | ||
779 | - mangleUnqualifiedName(ND); | ||
780 | + mangleUnqualifiedName(ND, /* AdditionalAbiTags */ nullptr); | ||
781 | } | ||
782 | |||
783 | addSubstitution(ND); | ||
784 | @@ -1379,27 +1645,30 @@ | ||
785 | // ::= <template-param> | ||
786 | // ::= <substitution> | ||
787 | if (TemplateDecl *TD = Template.getAsTemplateDecl()) | ||
788 | - return mangleTemplatePrefix(TD); | ||
789 | + return mangleTemplatePrefix(TD, /* AdditionalAbiTags */ nullptr); | ||
790 | |||
791 | if (QualifiedTemplateName *Qualified = Template.getAsQualifiedTemplateName()) | ||
792 | manglePrefix(Qualified->getQualifier()); | ||
793 | - | ||
794 | + | ||
795 | if (OverloadedTemplateStorage *Overloaded | ||
796 | = Template.getAsOverloadedTemplate()) { | ||
797 | mangleUnqualifiedName(nullptr, (*Overloaded->begin())->getDeclName(), | ||
798 | - UnknownArity); | ||
799 | + UnknownArity, | ||
800 | + /* AdditionalAbiTags */ nullptr); | ||
801 | return; | ||
802 | } | ||
803 | - | ||
804 | + | ||
805 | DependentTemplateName *Dependent = Template.getAsDependentTemplateName(); | ||
806 | assert(Dependent && "Unknown template name kind?"); | ||
807 | if (NestedNameSpecifier *Qualifier = Dependent->getQualifier()) | ||
808 | manglePrefix(Qualifier); | ||
809 | - mangleUnscopedTemplateName(Template); | ||
810 | + mangleUnscopedTemplateName(Template, /* AdditionalAbiTags */ nullptr); | ||
811 | } | ||
812 | |||
813 | void CXXNameMangler::mangleTemplatePrefix(const TemplateDecl *ND, | ||
814 | - bool NoFunction) { | ||
815 | + const AbiTagList *AdditionalAbiTags, | ||
816 | + bool NoFunction, | ||
817 | + bool ExcludeUnqualifiedName) { | ||
818 | // <template-prefix> ::= <prefix> <template unqualified-name> | ||
819 | // ::= <template-param> | ||
820 | // ::= <substitution> | ||
821 | @@ -1414,7 +1683,8 @@ | ||
822 | mangleTemplateParameter(TTP->getIndex()); | ||
823 | } else { | ||
824 | manglePrefix(getEffectiveDeclContext(ND), NoFunction); | ||
825 | - mangleUnqualifiedName(ND->getTemplatedDecl()); | ||
826 | + if (!ExcludeUnqualifiedName) | ||
827 | + mangleUnqualifiedName(ND->getTemplatedDecl(), AdditionalAbiTags); | ||
828 | } | ||
829 | |||
830 | addSubstitution(ND); | ||
831 | @@ -1458,6 +1728,7 @@ | ||
832 | // <name> ::= <nested-name> | ||
833 | mangleUnresolvedPrefix(Dependent->getQualifier()); | ||
834 | mangleSourceName(Dependent->getIdentifier()); | ||
835 | + // writeAbiTags(Dependent); | ||
836 | break; | ||
837 | } | ||
838 | |||
839 | @@ -1550,16 +1821,19 @@ | ||
840 | |||
841 | case Type::Typedef: | ||
842 | mangleSourceName(cast<TypedefType>(Ty)->getDecl()->getIdentifier()); | ||
843 | + writeAbiTags(cast<TypedefType>(Ty)->getDecl()); | ||
844 | break; | ||
845 | |||
846 | case Type::UnresolvedUsing: | ||
847 | mangleSourceName( | ||
848 | cast<UnresolvedUsingType>(Ty)->getDecl()->getIdentifier()); | ||
849 | + writeAbiTags(cast<UnresolvedUsingType>(Ty)->getDecl()); | ||
850 | break; | ||
851 | |||
852 | case Type::Enum: | ||
853 | case Type::Record: | ||
854 | mangleSourceName(cast<TagType>(Ty)->getDecl()->getIdentifier()); | ||
855 | + writeAbiTags(cast<TagType>(Ty)->getDecl()); | ||
856 | break; | ||
857 | |||
858 | case Type::TemplateSpecialization: { | ||
859 | @@ -1578,6 +1852,7 @@ | ||
860 | goto unresolvedType; | ||
861 | |||
862 | mangleSourceName(TD->getIdentifier()); | ||
863 | + writeAbiTags(TD); | ||
864 | break; | ||
865 | } | ||
866 | |||
867 | @@ -1609,16 +1884,19 @@ | ||
868 | case Type::InjectedClassName: | ||
869 | mangleSourceName( | ||
870 | cast<InjectedClassNameType>(Ty)->getDecl()->getIdentifier()); | ||
871 | + writeAbiTags(cast<InjectedClassNameType>(Ty)->getDecl()); | ||
872 | break; | ||
873 | |||
874 | case Type::DependentName: | ||
875 | mangleSourceName(cast<DependentNameType>(Ty)->getIdentifier()); | ||
876 | + // writeAbiTags(cast<DependentNameType>(Ty)); | ||
877 | break; | ||
878 | |||
879 | case Type::DependentTemplateSpecialization: { | ||
880 | const DependentTemplateSpecializationType *DTST = | ||
881 | cast<DependentTemplateSpecializationType>(Ty); | ||
882 | mangleSourceName(DTST->getIdentifier()); | ||
883 | + // writeAbiTags(DTST); | ||
884 | mangleTemplateArgs(DTST->getArgs(), DTST->getNumArgs()); | ||
885 | break; | ||
886 | } | ||
887 | @@ -2088,7 +2366,9 @@ | ||
888 | case BuiltinType::Id: | ||
889 | #include "clang/AST/BuiltinTypes.def" | ||
890 | case BuiltinType::Dependent: | ||
891 | - llvm_unreachable("mangling a placeholder type"); | ||
892 | + if (!NullOut) | ||
893 | + llvm_unreachable("mangling a placeholder type"); | ||
894 | + break; | ||
895 | case BuiltinType::ObjCId: | ||
896 | Out << "11objc_object"; | ||
897 | break; | ||
898 | @@ -2620,7 +2900,11 @@ | ||
899 | |||
900 | void CXXNameMangler::mangleType(const TemplateSpecializationType *T) { | ||
901 | if (TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl()) { | ||
902 | - mangleName(TD, T->getArgs(), T->getNumArgs()); | ||
903 | + // types only have explicit abi tags, no addition tags | ||
904 | + mangleTemplateName(TD, | ||
905 | + /* AdditionalAbiTags */ nullptr, | ||
906 | + /* ExcludeUnqualifiedName */ false, | ||
907 | + T->getArgs(), T->getNumArgs()); | ||
908 | } else { | ||
909 | if (mangleSubstitution(QualType(T, 0))) | ||
910 | return; | ||
911 | @@ -2946,12 +3230,14 @@ | ||
912 | case Expr::PseudoObjectExprClass: | ||
913 | case Expr::AtomicExprClass: | ||
914 | { | ||
915 | - // As bad as this diagnostic is, it's better than crashing. | ||
916 | - DiagnosticsEngine &Diags = Context.getDiags(); | ||
917 | - unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, | ||
918 | - "cannot yet mangle expression type %0"); | ||
919 | - Diags.Report(E->getExprLoc(), DiagID) | ||
920 | - << E->getStmtClassName() << E->getSourceRange(); | ||
921 | + if (!NullOut) { | ||
922 | + // As bad as this diagnostic is, it's better than crashing. | ||
923 | + DiagnosticsEngine &Diags = Context.getDiags(); | ||
924 | + unsigned DiagID = Diags.getCustomDiagID(DiagnosticsEngine::Error, | ||
925 | + "cannot yet mangle expression type %0"); | ||
926 | + Diags.Report(E->getExprLoc(), DiagID) | ||
927 | + << E->getStmtClassName() << E->getSourceRange(); | ||
928 | + } | ||
929 | break; | ||
930 | } | ||
931 | |||
932 | @@ -4094,6 +4380,97 @@ | ||
933 | Substitutions[Ptr] = SeqID++; | ||
934 | } | ||
935 | |||
936 | +CXXNameMangler::AbiTagSet | ||
937 | +CXXNameMangler::getTagsFromPrefixAndTemplateArguments(const NamedDecl *ND) { | ||
938 | + llvm::raw_null_ostream NullOutStream; | ||
939 | + CXXNameMangler TrackPrefixAndTemplateArguments(*this, NullOutStream); | ||
940 | + | ||
941 | + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) { | ||
942 | + TrackPrefixAndTemplateArguments.mangleFunctionEncoding( | ||
943 | + FD, /* ExcludeUnqualifiedName */ true); | ||
944 | + } else { | ||
945 | + TrackPrefixAndTemplateArguments.mangleName( | ||
946 | + ND, /* ExcludeUnqualifiedName */ true); | ||
947 | + } | ||
948 | + | ||
949 | + return std::move( | ||
950 | + TrackPrefixAndTemplateArguments.AbiTagsRoot.getUsedAbiTags()); | ||
951 | +} | ||
952 | + | ||
953 | +CXXNameMangler::AbiTagList | ||
954 | +CXXNameMangler::makeAdditionalTagsForFunction(const FunctionDecl *FD) { | ||
955 | + // when derived abi tags are disabled there is no need to make any list | ||
956 | + if (DisableDerivedAbiTags) | ||
957 | + return AbiTagList(); | ||
958 | + | ||
959 | + AbiTagSet ImplicitlyAvailableTags = | ||
960 | + getTagsFromPrefixAndTemplateArguments(FD); | ||
961 | + AbiTagSet ReturnTypeTags; | ||
962 | + | ||
963 | + { | ||
964 | + llvm::raw_null_ostream NullOutStream; | ||
965 | + CXXNameMangler TrackReturnTypeTags(*this, NullOutStream); | ||
966 | + TrackReturnTypeTags.disableDerivedAbiTags(); | ||
967 | + | ||
968 | + const FunctionProtoType *Proto = | ||
969 | + cast<FunctionProtoType>(FD->getType()->getAs<FunctionType>()); | ||
970 | + TrackReturnTypeTags.FunctionTypeDepth.enterResultType(); | ||
971 | + TrackReturnTypeTags.mangleType(Proto->getReturnType()); | ||
972 | + TrackReturnTypeTags.FunctionTypeDepth.leaveResultType(); | ||
973 | + | ||
974 | + ReturnTypeTags = | ||
975 | + std::move(TrackReturnTypeTags.AbiTagsRoot.getUsedAbiTags()); | ||
976 | + } | ||
977 | + | ||
978 | + AbiTagList AdditionalAbiTags; | ||
979 | + | ||
980 | + for (const auto &Tag : ReturnTypeTags) { | ||
981 | + if (ImplicitlyAvailableTags.count(Tag) == 0) | ||
982 | + AdditionalAbiTags.push_back(Tag); | ||
983 | + } | ||
984 | + | ||
985 | + return AdditionalAbiTags; | ||
986 | +} | ||
987 | + | ||
988 | +CXXNameMangler::AbiTagList | ||
989 | +CXXNameMangler::makeAdditionalTagsForVariable(const VarDecl *VD) { | ||
990 | + // when derived abi tags are disabled there is no need to make any list | ||
991 | + if (DisableDerivedAbiTags) | ||
992 | + return AbiTagList(); | ||
993 | + | ||
994 | + AbiTagSet ImplicitlyAvailableTags = | ||
995 | + getTagsFromPrefixAndTemplateArguments(VD); | ||
996 | + AbiTagSet VariableTypeTags; | ||
997 | + | ||
998 | + { | ||
999 | + llvm::raw_null_ostream NullOutStream; | ||
1000 | + CXXNameMangler TrackVariableType(*this, NullOutStream); | ||
1001 | + TrackVariableType.disableDerivedAbiTags(); | ||
1002 | + | ||
1003 | + TrackVariableType.mangleType(VD->getType()); | ||
1004 | + | ||
1005 | + VariableTypeTags = | ||
1006 | + std::move(TrackVariableType.AbiTagsRoot.getUsedAbiTags()); | ||
1007 | + } | ||
1008 | + | ||
1009 | + AbiTagList AdditionalAbiTags; | ||
1010 | + | ||
1011 | + for (const auto &Tag : VariableTypeTags) { | ||
1012 | + if (ImplicitlyAvailableTags.count(Tag) == 0) | ||
1013 | + AdditionalAbiTags.push_back(Tag); | ||
1014 | + } | ||
1015 | + | ||
1016 | + return AdditionalAbiTags; | ||
1017 | +} | ||
1018 | + | ||
1019 | +bool CXXNameMangler::shouldHaveAbiTags(ItaniumMangleContextImpl &C, | ||
1020 | + const VarDecl *VD) { | ||
1021 | + llvm::raw_null_ostream NullOutStream; | ||
1022 | + CXXNameMangler TrackAbiTags(C, NullOutStream, nullptr, true); | ||
1023 | + TrackAbiTags.mangle(VD); | ||
1024 | + return TrackAbiTags.AbiTagsRoot.getUsedAbiTags().size(); | ||
1025 | +} | ||
1026 | + | ||
1027 | // | ||
1028 | |||
1029 | /// Mangles the name of the declaration D and emits that name to the given | ||
1030 | @@ -4195,6 +4572,8 @@ | ||
1031 | // <special-name> ::= GV <object name> # Guard variable for one-time | ||
1032 | // # initialization | ||
1033 | CXXNameMangler Mangler(*this, Out); | ||
1034 | + // GCC 5.3.0 doesn't emit derived ABI tags for local names but that seems to | ||
1035 | + // be a bug that is fixed in trunk. | ||
1036 | Mangler.getStream() << "_ZGV"; | ||
1037 | Mangler.mangleName(D); | ||
1038 | } | ||
1039 | Index: lib/Sema/SemaDeclAttr.cpp | ||
1040 | =================================================================== | ||
1041 | --- lib/Sema/SemaDeclAttr.cpp | ||
1042 | +++ lib/Sema/SemaDeclAttr.cpp | ||
1043 | @@ -4700,10 +4700,6 @@ | ||
1044 | D->addAttr(::new (S.Context) | ||
1045 | AbiTagAttr(Attr.getRange(), S.Context, Tags.data(), Tags.size(), | ||
1046 | Attr.getAttributeSpellingListIndex())); | ||
1047 | - | ||
1048 | - // FIXME: remove this warning as soon as mangled part is ready. | ||
1049 | - S.Diag(Attr.getRange().getBegin(), diag::warn_attribute_ignored) | ||
1050 | - << Attr.getName(); | ||
1051 | } | ||
1052 | |||
1053 | static void handleARMInterruptAttr(Sema &S, Decl *D, | ||
1054 | Index: test/CodeGenCXX/mangle-abi-tag.cpp | ||
1055 | =================================================================== | ||
1056 | --- /dev/null | ||
1057 | +++ test/CodeGenCXX/mangle-abi-tag.cpp | ||
1058 | @@ -0,0 +1,146 @@ | ||
1059 | +// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -std=c++11 -o - | FileCheck %s | ||
1060 | +// RUN: %clang_cc1 %s -emit-llvm -triple i686-linux-gnu -std=c++11 -o - | FileCheck %s | ||
1061 | +// RUN: %clang_cc1 %s -emit-llvm -triple x86_64-linux-gnu -std=c++11 -o - | FileCheck %s | ||
1062 | + | ||
1063 | +struct __attribute__((abi_tag("A", "B"))) A { }; | ||
1064 | + | ||
1065 | +struct B: A { }; | ||
1066 | + | ||
1067 | +template<class T> | ||
1068 | + | ||
1069 | +struct C { | ||
1070 | +}; | ||
1071 | + | ||
1072 | +struct D { A* p; }; | ||
1073 | + | ||
1074 | +template<class T> | ||
1075 | +struct __attribute__((abi_tag("C", "D"))) E { | ||
1076 | +}; | ||
1077 | + | ||
1078 | +struct __attribute__((abi_tag("A", "B"))) F { }; | ||
1079 | + | ||
1080 | +A a1; | ||
1081 | +// CHECK: @_Z2a1B1AB1B = | ||
1082 | + | ||
1083 | +__attribute__((abi_tag("C", "D"))) | ||
1084 | +A a2; | ||
1085 | +// CHECK: @_Z2a2B1AB1BB1CB1D = | ||
1086 | + | ||
1087 | +B a3; | ||
1088 | +// CHECK: @a3 = | ||
1089 | + | ||
1090 | +C<A> a4; | ||
1091 | +// CHECK: @_Z2a4B1AB1B = | ||
1092 | + | ||
1093 | +D a5; | ||
1094 | +// CHECK: @a5 = | ||
1095 | + | ||
1096 | +E<int> a6; | ||
1097 | +// CHECK: @_Z2a6B1CB1D = | ||
1098 | + | ||
1099 | +E<A> a7; | ||
1100 | +// CHECK: @_Z2a7B1AB1BB1CB1D = | ||
1101 | + | ||
1102 | +template<> | ||
1103 | +struct E<float> { | ||
1104 | + static float a8; | ||
1105 | +}; | ||
1106 | +float E<float>::a8; | ||
1107 | +// CHECK: @_ZN1EB1CB1DIfE2a8E = | ||
1108 | + | ||
1109 | +template<> | ||
1110 | +struct E<F> { | ||
1111 | + static bool a9; | ||
1112 | +}; | ||
1113 | +bool E<F>::a9; | ||
1114 | +// CHECK: @_ZN1EB1CB1DI1FB1AB1BE2a9E = | ||
1115 | + | ||
1116 | +struct __attribute__((abi_tag("A", "B"))) A10 { | ||
1117 | + virtual ~A10() {} | ||
1118 | +} a10; | ||
1119 | +// vtable | ||
1120 | +// CHECK: @_ZTV3A10B1AB1B = | ||
1121 | +// typeinfo | ||
1122 | +// CHECK: @_ZTI3A10B1AB1B = | ||
1123 | + | ||
1124 | +// Local variables from f13. | ||
1125 | +// f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B] | ||
1126 | +// CHECK-DAG: @_ZZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B = | ||
1127 | +// guard variable for f13()::L::foo[abi:C][abi:D]()::a[abi:A][abi:B] | ||
1128 | +// CHECK-DAG: @_ZGVZZ3f13vEN1L3fooB1CB1DEvE1aB1AB1B = | ||
1129 | + | ||
1130 | +__attribute__ ((abi_tag("C", "D"))) | ||
1131 | +void* f1() { | ||
1132 | + return 0; | ||
1133 | +} | ||
1134 | +// CHECK: define {{.*}} @_Z2f1B1CB1Dv( | ||
1135 | + | ||
1136 | +__attribute__ ((abi_tag("C", "D"))) | ||
1137 | +A* f2() { | ||
1138 | + return 0; | ||
1139 | +} | ||
1140 | +// CHECK: define {{.*}} @_Z2f2B1AB1BB1CB1Dv( | ||
1141 | + | ||
1142 | +B* f3() { | ||
1143 | + return 0; | ||
1144 | +} | ||
1145 | +// CHECK: define {{.*}} @_Z2f3v( | ||
1146 | + | ||
1147 | +C<A>* f4() { | ||
1148 | + return 0; | ||
1149 | +} | ||
1150 | +// CHECK: define {{.*}} @_Z2f4B1AB1Bv( | ||
1151 | + | ||
1152 | +D* f5() { | ||
1153 | + return 0; | ||
1154 | +} | ||
1155 | +// CHECK: define {{.*}} @_Z2f5v( | ||
1156 | + | ||
1157 | +E<char>* f6() { | ||
1158 | + return 0; | ||
1159 | +} | ||
1160 | +// CHECK: define {{.*}} @_Z2f6B1CB1Dv( | ||
1161 | + | ||
1162 | +E<A>* f7() { | ||
1163 | + return 0; | ||
1164 | +} | ||
1165 | +// CHECK: define {{.*}} @_Z2f7B1AB1BB1CB1Dv( | ||
1166 | + | ||
1167 | +void f8(E<A>*) { | ||
1168 | +} | ||
1169 | +// CHECK: define {{.*}} @_Z2f8P1EB1CB1DI1AB1AB1BE( | ||
1170 | + | ||
1171 | +inline namespace Names1 __attribute__((__abi_tag__)) { | ||
1172 | + class C1 {}; | ||
1173 | +} | ||
1174 | +C1 f9() { return C1(); } | ||
1175 | +// CHECK: @_Z2f9B6Names1v( | ||
1176 | + | ||
1177 | +inline namespace Names2 __attribute__((__abi_tag__("Tag1", "Tag2"))) { | ||
1178 | + class C2 {}; | ||
1179 | +} | ||
1180 | +C2 f10() { return C2(); } | ||
1181 | +// CHECK: @_Z3f10B4Tag1B4Tag2v( | ||
1182 | + | ||
1183 | +void __attribute__((abi_tag("A"))) f11(A) {} | ||
1184 | +// f11[abi:A](A[abi:A][abi:B]) | ||
1185 | +// CHECK: define {{.*}} @_Z3f11B1A1AB1AB1B( | ||
1186 | + | ||
1187 | +A f12(A) { return A(); } | ||
1188 | +// f12(A[abi:A][abi:B]) | ||
1189 | +// CHECK: define {{.*}} @_Z3f121AB1AB1B( | ||
1190 | + | ||
1191 | +inline void f13() { | ||
1192 | + struct L { | ||
1193 | + static E<int>* foo() { | ||
1194 | + static A10 a; | ||
1195 | + return 0; | ||
1196 | + } | ||
1197 | + }; | ||
1198 | + L::foo(); | ||
1199 | +} | ||
1200 | +void f11_test() { | ||
1201 | + f13(); | ||
1202 | +} | ||
1203 | +// f13()::L::foo[abi:C][abi:D]() | ||
1204 | +// CHECK: define linkonce_odr %struct.E* @_ZZ3f13vEN1L3fooB1CB1DEv( | ||
1205 | Index: test/SemaCXX/attr-abi-tag-syntax.cpp | ||
1206 | =================================================================== | ||
1207 | --- test/SemaCXX/attr-abi-tag-syntax.cpp | ||
1208 | +++ test/SemaCXX/attr-abi-tag-syntax.cpp | ||
1209 | @@ -16,28 +16,18 @@ | ||
1210 | // expected-warning@-1 {{'abi_tag' attribute on anonymous namespace ignored}} | ||
1211 | |||
1212 | inline namespace N __attribute__((__abi_tag__)) {} | ||
1213 | -// FIXME: remove this warning as soon as attribute fully supported. | ||
1214 | -// expected-warning@-2 {{'__abi_tag__' attribute ignored}} | ||
1215 | |||
1216 | } // namespcace N2 | ||
1217 | |||
1218 | __attribute__((abi_tag("B", "A"))) extern int a1; | ||
1219 | -// FIXME: remove this warning as soon as attribute fully supported. | ||
1220 | -// expected-warning@-2 {{'abi_tag' attribute ignored}} | ||
1221 | |||
1222 | __attribute__((abi_tag("A", "B"))) extern int a1; | ||
1223 | // expected-note@-1 {{previous declaration is here}} | ||
1224 | -// FIXME: remove this warning as soon as attribute fully supported. | ||
1225 | -// expected-warning@-3 {{'abi_tag' attribute ignored}} | ||
1226 | |||
1227 | __attribute__((abi_tag("A", "C"))) extern int a1; | ||
1228 | // expected-error@-1 {{'abi_tag' C missing in original declaration}} | ||
1229 | -// FIXME: remove this warning as soon as attribute fully supported. | ||
1230 | -// expected-warning@-3 {{'abi_tag' attribute ignored}} | ||
1231 | |||
1232 | extern int a2; | ||
1233 | // expected-note@-1 {{previous declaration is here}} | ||
1234 | __attribute__((abi_tag("A")))extern int a2; | ||
1235 | // expected-error@-1 {{cannot add 'abi_tag' attribute in a redeclaration}} | ||
1236 | -// FIXME: remove this warning as soon as attribute fully supported. | ||
1237 | -// expected-warning@-3 {{'abi_tag' attribute ignored}} |