/[pkg-src]/trunk/llvm/patches/llvm-3.8.0-D18035-PR23529-Mangler-part-of-attrbute-abi_tag-support.patch |
Contents of /trunk/llvm/patches/llvm-3.8.0-D18035-PR23529-Mangler-part-of-attrbute-abi_tag-support.patch
Parent Directory | Revision Log
Revision 2804 -
(show 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 | 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}} |