]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/AST/QualTypeNames.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / AST / QualTypeNames.cpp
1 //===------- QualTypeNames.cpp - Generate Complete QualType Names ---------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 //===----------------------------------------------------------------------===//
6 //
7 // This file is distributed under the University of Illinois Open Source
8 // License. See LICENSE.TXT for details.
9 //
10 //===----------------------------------------------------------------------===//
11
12 #include "clang/AST/DeclTemplate.h"
13 #include "clang/AST/DeclarationName.h"
14 #include "clang/AST/GlobalDecl.h"
15 #include "clang/AST/Mangle.h"
16 #include "clang/AST/QualTypeNames.h"
17
18 #include <stdio.h>
19 #include <memory>
20
21 namespace clang {
22
23 namespace TypeName {
24
25 /// Create a NestedNameSpecifier for Namesp and its enclosing
26 /// scopes.
27 ///
28 /// \param[in] Ctx - the AST Context to be used.
29 /// \param[in] Namesp - the NamespaceDecl for which a NestedNameSpecifier
30 /// is requested.
31 /// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
32 /// specifier "::" should be prepended or not.
33 static NestedNameSpecifier *createNestedNameSpecifier(
34     const ASTContext &Ctx,
35     const NamespaceDecl *Namesp,
36     bool WithGlobalNsPrefix);
37
38 /// Create a NestedNameSpecifier for TagDecl and its enclosing
39 /// scopes.
40 ///
41 /// \param[in] Ctx - the AST Context to be used.
42 /// \param[in] TD - the TagDecl for which a NestedNameSpecifier is
43 /// requested.
44 /// \param[in] FullyQualify - Convert all template arguments into fully
45 /// qualified names.
46 /// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
47 /// specifier "::" should be prepended or not.
48 static NestedNameSpecifier *createNestedNameSpecifier(
49     const ASTContext &Ctx, const TypeDecl *TD,
50     bool FullyQualify, bool WithGlobalNsPrefix);
51
52 static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
53     const ASTContext &Ctx, const Decl *decl,
54     bool FullyQualified, bool WithGlobalNsPrefix);
55
56 static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
57     const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix);
58
59 static bool getFullyQualifiedTemplateName(const ASTContext &Ctx,
60                                           TemplateName &TName,
61                                           bool WithGlobalNsPrefix) {
62   bool Changed = false;
63   NestedNameSpecifier *NNS = nullptr;
64
65   TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
66   // ArgTDecl won't be NULL because we asserted that this isn't a
67   // dependent context very early in the call chain.
68   assert(ArgTDecl != nullptr);
69   QualifiedTemplateName *QTName = TName.getAsQualifiedTemplateName();
70
71   if (QTName && !QTName->hasTemplateKeyword()) {
72     NNS = QTName->getQualifier();
73     NestedNameSpecifier *QNNS = getFullyQualifiedNestedNameSpecifier(
74         Ctx, NNS, WithGlobalNsPrefix);
75     if (QNNS != NNS) {
76       Changed = true;
77       NNS = QNNS;
78     } else {
79       NNS = nullptr;
80     }
81   } else {
82     NNS = createNestedNameSpecifierForScopeOf(
83         Ctx, ArgTDecl, true, WithGlobalNsPrefix);
84   }
85   if (NNS) {
86     TName = Ctx.getQualifiedTemplateName(NNS,
87                                          /*TemplateKeyword=*/false, ArgTDecl);
88     Changed = true;
89   }
90   return Changed;
91 }
92
93 static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx,
94                                               TemplateArgument &Arg,
95                                               bool WithGlobalNsPrefix) {
96   bool Changed = false;
97
98   // Note: we do not handle TemplateArgument::Expression, to replace it
99   // we need the information for the template instance decl.
100
101   if (Arg.getKind() == TemplateArgument::Template) {
102     TemplateName TName = Arg.getAsTemplate();
103     Changed = getFullyQualifiedTemplateName(Ctx, TName, WithGlobalNsPrefix);
104     if (Changed) {
105       Arg = TemplateArgument(TName);
106     }
107   } else if (Arg.getKind() == TemplateArgument::Type) {
108     QualType SubTy = Arg.getAsType();
109     // Check if the type needs more desugaring and recurse.
110     QualType QTFQ = getFullyQualifiedType(SubTy, Ctx, WithGlobalNsPrefix);
111     if (QTFQ != SubTy) {
112       Arg = TemplateArgument(QTFQ);
113       Changed = true;
114     }
115   }
116   return Changed;
117 }
118
119 static const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx,
120                                                  const Type *TypePtr,
121                                                  bool WithGlobalNsPrefix) {
122   // DependentTemplateTypes exist within template declarations and
123   // definitions. Therefore we shouldn't encounter them at the end of
124   // a translation unit. If we do, the caller has made an error.
125   assert(!isa<DependentTemplateSpecializationType>(TypePtr));
126   // In case of template specializations, iterate over the arguments
127   // and fully qualify them as well.
128   if (const auto *TST = dyn_cast<const TemplateSpecializationType>(TypePtr)) {
129     bool MightHaveChanged = false;
130     SmallVector<TemplateArgument, 4> FQArgs;
131     for (TemplateSpecializationType::iterator I = TST->begin(), E = TST->end();
132          I != E; ++I) {
133       // Cheap to copy and potentially modified by
134       // getFullyQualifedTemplateArgument.
135       TemplateArgument Arg(*I);
136       MightHaveChanged |= getFullyQualifiedTemplateArgument(
137           Ctx, Arg, WithGlobalNsPrefix);
138       FQArgs.push_back(Arg);
139     }
140
141     // If a fully qualified arg is different from the unqualified arg,
142     // allocate new type in the AST.
143     if (MightHaveChanged) {
144       QualType QT = Ctx.getTemplateSpecializationType(
145           TST->getTemplateName(), FQArgs,
146           TST->getCanonicalTypeInternal());
147       // getTemplateSpecializationType returns a fully qualified
148       // version of the specialization itself, so no need to qualify
149       // it.
150       return QT.getTypePtr();
151     }
152   } else if (const auto *TSTRecord = dyn_cast<const RecordType>(TypePtr)) {
153     // We are asked to fully qualify and we have a Record Type,
154     // which can point to a template instantiation with no sugar in any of
155     // its template argument, however we still need to fully qualify them.
156
157     if (const auto *TSTDecl =
158         dyn_cast<ClassTemplateSpecializationDecl>(TSTRecord->getDecl())) {
159       const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
160
161       bool MightHaveChanged = false;
162       SmallVector<TemplateArgument, 4> FQArgs;
163       for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
164         // cheap to copy and potentially modified by
165         // getFullyQualifedTemplateArgument
166         TemplateArgument Arg(TemplateArgs[I]);
167         MightHaveChanged |= getFullyQualifiedTemplateArgument(
168             Ctx, Arg, WithGlobalNsPrefix);
169         FQArgs.push_back(Arg);
170       }
171
172       // If a fully qualified arg is different from the unqualified arg,
173       // allocate new type in the AST.
174       if (MightHaveChanged) {
175         TemplateName TN(TSTDecl->getSpecializedTemplate());
176         QualType QT = Ctx.getTemplateSpecializationType(
177             TN, FQArgs,
178             TSTRecord->getCanonicalTypeInternal());
179         // getTemplateSpecializationType returns a fully qualified
180         // version of the specialization itself, so no need to qualify
181         // it.
182         return QT.getTypePtr();
183       }
184     }
185   }
186   return TypePtr;
187 }
188
189 static NestedNameSpecifier *createOuterNNS(const ASTContext &Ctx, const Decl *D,
190                                            bool FullyQualify,
191                                            bool WithGlobalNsPrefix) {
192   const DeclContext *DC = D->getDeclContext();
193   if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
194     while (NS && NS->isInline()) {
195       // Ignore inline namespace;
196       NS = dyn_cast<NamespaceDecl>(NS->getDeclContext());
197     }
198     if (NS->getDeclName()) {
199       return createNestedNameSpecifier(Ctx, NS, WithGlobalNsPrefix);
200     }
201     return nullptr;  // no starting '::', no anonymous
202   } else if (const auto *TD = dyn_cast<TagDecl>(DC)) {
203     return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
204   } else if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC)) {
205     return createNestedNameSpecifier(
206         Ctx, TDD, FullyQualify, WithGlobalNsPrefix);
207   } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
208     return NestedNameSpecifier::GlobalSpecifier(Ctx);
209   }
210   return nullptr;  // no starting '::' if |WithGlobalNsPrefix| is false
211 }
212
213 /// Return a fully qualified version of this name specifier.
214 static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
215     const ASTContext &Ctx, NestedNameSpecifier *Scope,
216     bool WithGlobalNsPrefix) {
217   switch (Scope->getKind()) {
218     case NestedNameSpecifier::Global:
219       // Already fully qualified
220       return Scope;
221     case NestedNameSpecifier::Namespace:
222       return TypeName::createNestedNameSpecifier(
223           Ctx, Scope->getAsNamespace(), WithGlobalNsPrefix);
224     case NestedNameSpecifier::NamespaceAlias:
225       // Namespace aliases are only valid for the duration of the
226       // scope where they were introduced, and therefore are often
227       // invalid at the end of the TU.  So use the namespace name more
228       // likely to be valid at the end of the TU.
229       return TypeName::createNestedNameSpecifier(
230           Ctx,
231           Scope->getAsNamespaceAlias()->getNamespace()->getCanonicalDecl(),
232           WithGlobalNsPrefix);
233     case NestedNameSpecifier::Identifier:
234       // A function or some other construct that makes it un-namable
235       // at the end of the TU. Skip the current component of the name,
236       // but use the name of it's prefix.
237       return getFullyQualifiedNestedNameSpecifier(
238           Ctx, Scope->getPrefix(), WithGlobalNsPrefix);
239     case NestedNameSpecifier::Super:
240     case NestedNameSpecifier::TypeSpec:
241     case NestedNameSpecifier::TypeSpecWithTemplate: {
242       const Type *Type = Scope->getAsType();
243       // Find decl context.
244       const TagDecl *TD = nullptr;
245       if (const TagType *TagDeclType = Type->getAs<TagType>()) {
246         TD = TagDeclType->getDecl();
247       } else {
248         TD = Type->getAsCXXRecordDecl();
249       }
250       if (TD) {
251         return TypeName::createNestedNameSpecifier(Ctx, TD,
252                                                    true /*FullyQualified*/,
253                                                    WithGlobalNsPrefix);
254       } else if (const auto *TDD = dyn_cast<TypedefType>(Type)) {
255         return TypeName::createNestedNameSpecifier(Ctx, TDD->getDecl(),
256                                                    true /*FullyQualified*/,
257                                                    WithGlobalNsPrefix);
258       }
259       return Scope;
260     }
261   }
262   llvm_unreachable("bad NNS kind");
263 }
264
265 /// Create a nested name specifier for the declaring context of
266 /// the type.
267 static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
268     const ASTContext &Ctx, const Decl *Decl,
269     bool FullyQualified, bool WithGlobalNsPrefix) {
270   assert(Decl);
271
272   const DeclContext *DC = Decl->getDeclContext()->getRedeclContext();
273   const auto *Outer = dyn_cast_or_null<NamedDecl>(DC);
274   const auto *OuterNS = dyn_cast_or_null<NamespaceDecl>(DC);
275   if (Outer && !(OuterNS && OuterNS->isAnonymousNamespace())) {
276     if (const auto *CxxDecl = dyn_cast<CXXRecordDecl>(DC)) {
277       if (ClassTemplateDecl *ClassTempl =
278               CxxDecl->getDescribedClassTemplate()) {
279         // We are in the case of a type(def) that was declared in a
280         // class template but is *not* type dependent.  In clang, it
281         // gets attached to the class template declaration rather than
282         // any specific class template instantiation.  This result in
283         // 'odd' fully qualified typename:
284         //
285         //    vector<_Tp,_Alloc>::size_type
286         //
287         // Make the situation is 'useable' but looking a bit odd by
288         // picking a random instance as the declaring context.
289         if (ClassTempl->spec_begin() != ClassTempl->spec_end()) {
290           Decl = *(ClassTempl->spec_begin());
291           Outer = dyn_cast<NamedDecl>(Decl);
292           OuterNS = dyn_cast<NamespaceDecl>(Decl);
293         }
294       }
295     }
296
297     if (OuterNS) {
298       return createNestedNameSpecifier(Ctx, OuterNS, WithGlobalNsPrefix);
299     } else if (const auto *TD = dyn_cast<TagDecl>(Outer)) {
300       return createNestedNameSpecifier(
301           Ctx, TD, FullyQualified, WithGlobalNsPrefix);
302     } else if (dyn_cast<TranslationUnitDecl>(Outer)) {
303       // Context is the TU. Nothing needs to be done.
304       return nullptr;
305     } else {
306       // Decl's context was neither the TU, a namespace, nor a
307       // TagDecl, which means it is a type local to a scope, and not
308       // accessible at the end of the TU.
309       return nullptr;
310     }
311   } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
312     return NestedNameSpecifier::GlobalSpecifier(Ctx);
313   }
314   return nullptr;
315 }
316
317 /// Create a nested name specifier for the declaring context of
318 /// the type.
319 static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
320     const ASTContext &Ctx, const Type *TypePtr,
321     bool FullyQualified, bool WithGlobalNsPrefix) {
322   if (!TypePtr) return nullptr;
323
324   Decl *Decl = nullptr;
325   // There are probably other cases ...
326   if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
327     Decl = TDT->getDecl();
328   } else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
329     Decl = TagDeclType->getDecl();
330   } else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
331     Decl = TST->getTemplateName().getAsTemplateDecl();
332   } else {
333     Decl = TypePtr->getAsCXXRecordDecl();
334   }
335
336   if (!Decl) return nullptr;
337
338   return createNestedNameSpecifierForScopeOf(
339       Ctx, Decl, FullyQualified, WithGlobalNsPrefix);
340 }
341
342 NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
343                                                const NamespaceDecl *Namespace,
344                                                bool WithGlobalNsPrefix) {
345   while (Namespace && Namespace->isInline()) {
346     // Ignore inline namespace;
347     Namespace = dyn_cast<NamespaceDecl>(Namespace->getDeclContext());
348   }
349   if (!Namespace) return nullptr;
350
351   bool FullyQualified = true;  // doesn't matter, DeclContexts are namespaces
352   return NestedNameSpecifier::Create(
353       Ctx,
354       createOuterNNS(Ctx, Namespace, FullyQualified, WithGlobalNsPrefix),
355       Namespace);
356 }
357
358 NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
359                                                const TypeDecl *TD,
360                                                bool FullyQualify,
361                                                bool WithGlobalNsPrefix) {
362   return NestedNameSpecifier::Create(
363       Ctx,
364       createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
365       false /*No TemplateKeyword*/,
366       TD->getTypeForDecl());
367 }
368
369 /// Return the fully qualified type, including fully-qualified
370 /// versions of any template parameters.
371 QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
372                                bool WithGlobalNsPrefix) {
373   // In case of myType* we need to strip the pointer first, fully
374   // qualify and attach the pointer once again.
375   if (isa<PointerType>(QT.getTypePtr())) {
376     // Get the qualifiers.
377     Qualifiers Quals = QT.getQualifiers();
378     QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
379     QT = Ctx.getPointerType(QT);
380     // Add back the qualifiers.
381     QT = Ctx.getQualifiedType(QT, Quals);
382     return QT;
383   }
384
385   // In case of myType& we need to strip the reference first, fully
386   // qualify and attach the reference once again.
387   if (isa<ReferenceType>(QT.getTypePtr())) {
388     // Get the qualifiers.
389     bool IsLValueRefTy = isa<LValueReferenceType>(QT.getTypePtr());
390     Qualifiers Quals = QT.getQualifiers();
391     QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
392     // Add the r- or l-value reference type back to the fully
393     // qualified one.
394     if (IsLValueRefTy)
395       QT = Ctx.getLValueReferenceType(QT);
396     else
397       QT = Ctx.getRValueReferenceType(QT);
398     // Add back the qualifiers.
399     QT = Ctx.getQualifiedType(QT, Quals);
400     return QT;
401   }
402
403   // Remove the part of the type related to the type being a template
404   // parameter (we won't report it as part of the 'type name' and it
405   // is actually make the code below to be more complex (to handle
406   // those)
407   while (isa<SubstTemplateTypeParmType>(QT.getTypePtr())) {
408     // Get the qualifiers.
409     Qualifiers Quals = QT.getQualifiers();
410
411     QT = cast<SubstTemplateTypeParmType>(QT.getTypePtr())->desugar();
412
413     // Add back the qualifiers.
414     QT = Ctx.getQualifiedType(QT, Quals);
415   }
416
417   NestedNameSpecifier *Prefix = nullptr;
418   // Local qualifiers are attached to the QualType outside of the
419   // elaborated type.  Retrieve them before descending into the
420   // elaborated type.
421   Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
422   QT = QualType(QT.getTypePtr(), 0);
423   ElaboratedTypeKeyword Keyword = ETK_None;
424   if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
425     QT = ETypeInput->getNamedType();
426     assert(!QT.hasLocalQualifiers());
427     Keyword = ETypeInput->getKeyword();
428   }
429   // Create a nested name specifier if needed.
430   Prefix = createNestedNameSpecifierForScopeOf(Ctx, QT.getTypePtr(),
431                                                true /*FullyQualified*/,
432                                                WithGlobalNsPrefix);
433
434   // In case of template specializations iterate over the arguments and
435   // fully qualify them as well.
436   if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
437       isa<const RecordType>(QT.getTypePtr())) {
438     // We are asked to fully qualify and we have a Record Type (which
439     // may point to a template specialization) or Template
440     // Specialization Type. We need to fully qualify their arguments.
441
442     const Type *TypePtr = getFullyQualifiedTemplateType(
443         Ctx, QT.getTypePtr(), WithGlobalNsPrefix);
444     QT = QualType(TypePtr, 0);
445   }
446   if (Prefix || Keyword != ETK_None) {
447     QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
448   }
449   QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
450   return QT;
451 }
452
453 std::string getFullyQualifiedName(QualType QT,
454                                   const ASTContext &Ctx,
455                                   const PrintingPolicy &Policy,
456                                   bool WithGlobalNsPrefix) {
457   QualType FQQT = getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
458   return FQQT.getAsString(Policy);
459 }
460
461 }  // end namespace TypeName
462 }  // end namespace clang