xref: /freebsd-src/contrib/llvm-project/clang/lib/Index/USRGeneration.cpp (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
1 //===- USRGeneration.cpp - Routines for USR generation --------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "clang/Index/USRGeneration.h"
10 #include "clang/AST/ASTContext.h"
11 #include "clang/AST/Attr.h"
12 #include "clang/AST/DeclCXX.h"
13 #include "clang/AST/DeclTemplate.h"
14 #include "clang/AST/DeclVisitor.h"
15 #include "clang/Basic/FileManager.h"
16 #include "clang/Lex/PreprocessingRecord.h"
17 #include "llvm/Support/Path.h"
18 #include "llvm/Support/raw_ostream.h"
19 
20 using namespace clang;
21 using namespace clang::index;
22 
23 //===----------------------------------------------------------------------===//
24 // USR generation.
25 //===----------------------------------------------------------------------===//
26 
27 /// \returns true on error.
28 static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
29                      const SourceManager &SM, bool IncludeOffset) {
30   if (Loc.isInvalid()) {
31     return true;
32   }
33   Loc = SM.getExpansionLoc(Loc);
34   const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
35   OptionalFileEntryRef FE = SM.getFileEntryRefForID(Decomposed.first);
36   if (FE) {
37     OS << llvm::sys::path::filename(FE->getName());
38   } else {
39     // This case really isn't interesting.
40     return true;
41   }
42   if (IncludeOffset) {
43     // Use the offest into the FileID to represent the location.  Using
44     // a line/column can cause us to look back at the original source file,
45     // which is expensive.
46     OS << '@' << Decomposed.second;
47   }
48   return false;
49 }
50 
51 static StringRef GetExternalSourceContainer(const NamedDecl *D) {
52   if (!D)
53     return StringRef();
54   if (auto *attr = D->getExternalSourceSymbolAttr()) {
55     return attr->getDefinedIn();
56   }
57   return StringRef();
58 }
59 
60 namespace {
61 class USRGenerator : public ConstDeclVisitor<USRGenerator> {
62   SmallVectorImpl<char> &Buf;
63   llvm::raw_svector_ostream Out;
64   bool IgnoreResults;
65   ASTContext *Context;
66   bool generatedLoc;
67 
68   llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
69 
70 public:
71   explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf)
72   : Buf(Buf),
73     Out(Buf),
74     IgnoreResults(false),
75     Context(Ctx),
76     generatedLoc(false)
77   {
78     // Add the USR space prefix.
79     Out << getUSRSpacePrefix();
80   }
81 
82   bool ignoreResults() const { return IgnoreResults; }
83 
84   // Visitation methods from generating USRs from AST elements.
85   void VisitDeclContext(const DeclContext *D);
86   void VisitFieldDecl(const FieldDecl *D);
87   void VisitFunctionDecl(const FunctionDecl *D);
88   void VisitNamedDecl(const NamedDecl *D);
89   void VisitNamespaceDecl(const NamespaceDecl *D);
90   void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
91   void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
92   void VisitClassTemplateDecl(const ClassTemplateDecl *D);
93   void VisitObjCContainerDecl(const ObjCContainerDecl *CD,
94                               const ObjCCategoryDecl *CatD = nullptr);
95   void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
96   void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
97   void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
98   void VisitTagDecl(const TagDecl *D);
99   void VisitTypedefDecl(const TypedefDecl *D);
100   void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
101   void VisitVarDecl(const VarDecl *D);
102   void VisitBindingDecl(const BindingDecl *D);
103   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
104   void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
105   void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
106   void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
107   void VisitConceptDecl(const ConceptDecl *D);
108 
109   void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
110     IgnoreResults = true; // No USRs for linkage specs themselves.
111   }
112 
113   void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
114     IgnoreResults = true;
115   }
116 
117   void VisitUsingDecl(const UsingDecl *D) {
118     VisitDeclContext(D->getDeclContext());
119     Out << "@UD@";
120 
121     bool EmittedDeclName = !EmitDeclName(D);
122     assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls");
123     (void)EmittedDeclName;
124   }
125 
126   bool ShouldGenerateLocation(const NamedDecl *D);
127 
128   bool isLocal(const NamedDecl *D) {
129     return D->getParentFunctionOrMethod() != nullptr;
130   }
131 
132   void GenExtSymbolContainer(const NamedDecl *D);
133 
134   /// Generate the string component containing the location of the
135   ///  declaration.
136   bool GenLoc(const Decl *D, bool IncludeOffset);
137 
138   /// String generation methods used both by the visitation methods
139   /// and from other clients that want to directly generate USRs.  These
140   /// methods do not construct complete USRs (which incorporate the parents
141   /// of an AST element), but only the fragments concerning the AST element
142   /// itself.
143 
144   /// Generate a USR for an Objective-C class.
145   void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
146                     StringRef CategoryContextExtSymbolDefinedIn) {
147     generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
148                             CategoryContextExtSymbolDefinedIn);
149   }
150 
151   /// Generate a USR for an Objective-C class category.
152   void GenObjCCategory(StringRef cls, StringRef cat,
153                        StringRef clsExt, StringRef catExt) {
154     generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
155   }
156 
157   /// Generate a USR fragment for an Objective-C property.
158   void GenObjCProperty(StringRef prop, bool isClassProp) {
159     generateUSRForObjCProperty(prop, isClassProp, Out);
160   }
161 
162   /// Generate a USR for an Objective-C protocol.
163   void GenObjCProtocol(StringRef prot, StringRef ext) {
164     generateUSRForObjCProtocol(prot, Out, ext);
165   }
166 
167   void VisitType(QualType T);
168   void VisitTemplateParameterList(const TemplateParameterList *Params);
169   void VisitTemplateName(TemplateName Name);
170   void VisitTemplateArgument(const TemplateArgument &Arg);
171 
172   void VisitMSGuidDecl(const MSGuidDecl *D);
173 
174   /// Emit a Decl's name using NamedDecl::printName() and return true if
175   ///  the decl had no name.
176   bool EmitDeclName(const NamedDecl *D);
177 };
178 } // end anonymous namespace
179 
180 //===----------------------------------------------------------------------===//
181 // Generating USRs from ASTS.
182 //===----------------------------------------------------------------------===//
183 
184 bool USRGenerator::EmitDeclName(const NamedDecl *D) {
185   DeclarationName N = D->getDeclName();
186   if (N.isEmpty())
187     return true;
188   Out << N;
189   return false;
190 }
191 
192 bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
193   if (D->isExternallyVisible())
194     return false;
195   if (D->getParentFunctionOrMethod())
196     return true;
197   SourceLocation Loc = D->getLocation();
198   if (Loc.isInvalid())
199     return false;
200   const SourceManager &SM = Context->getSourceManager();
201   return !SM.isInSystemHeader(Loc);
202 }
203 
204 void USRGenerator::VisitDeclContext(const DeclContext *DC) {
205   if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
206     Visit(D);
207   else if (isa<LinkageSpecDecl>(DC)) // Linkage specs are transparent in USRs.
208     VisitDeclContext(DC->getParent());
209 }
210 
211 void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
212   // The USR for an ivar declared in a class extension is based on the
213   // ObjCInterfaceDecl, not the ObjCCategoryDecl.
214   if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
215     Visit(ID);
216   else
217     VisitDeclContext(D->getDeclContext());
218   Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
219   if (EmitDeclName(D)) {
220     // Bit fields can be anonymous.
221     IgnoreResults = true;
222     return;
223   }
224 }
225 
226 void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
227   if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
228     return;
229 
230   if (D->getType().isNull()) {
231     IgnoreResults = true;
232     return;
233   }
234 
235   const unsigned StartSize = Buf.size();
236   VisitDeclContext(D->getDeclContext());
237   if (Buf.size() == StartSize)
238     GenExtSymbolContainer(D);
239 
240   bool IsTemplate = false;
241   if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
242     IsTemplate = true;
243     Out << "@FT@";
244     VisitTemplateParameterList(FunTmpl->getTemplateParameters());
245   } else
246     Out << "@F@";
247 
248   PrintingPolicy Policy(Context->getLangOpts());
249   // Forward references can have different template argument names. Suppress the
250   // template argument names in constructors to make their USR more stable.
251   Policy.SuppressTemplateArgsInCXXConstructors = true;
252   D->getDeclName().print(Out, Policy);
253 
254   ASTContext &Ctx = *Context;
255   if ((!Ctx.getLangOpts().CPlusPlus || D->isExternC()) &&
256       !D->hasAttr<OverloadableAttr>())
257     return;
258 
259   if (const TemplateArgumentList *
260         SpecArgs = D->getTemplateSpecializationArgs()) {
261     Out << '<';
262     for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
263       Out << '#';
264       VisitTemplateArgument(SpecArgs->get(I));
265     }
266     Out << '>';
267   }
268 
269   // Mangle in type information for the arguments.
270   for (auto *PD : D->parameters()) {
271     Out << '#';
272     VisitType(PD->getType());
273   }
274   if (D->isVariadic())
275     Out << '.';
276   if (IsTemplate) {
277     // Function templates can be overloaded by return type, for example:
278     // \code
279     //   template <class T> typename T::A foo() {}
280     //   template <class T> typename T::B foo() {}
281     // \endcode
282     Out << '#';
283     VisitType(D->getReturnType());
284   }
285   Out << '#';
286   if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
287     if (MD->isStatic())
288       Out << 'S';
289     // FIXME: OpenCL: Need to consider address spaces
290     if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
291       Out << (char)('0' + quals);
292     switch (MD->getRefQualifier()) {
293     case RQ_None: break;
294     case RQ_LValue: Out << '&'; break;
295     case RQ_RValue: Out << "&&"; break;
296     }
297   }
298 }
299 
300 void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
301   VisitDeclContext(D->getDeclContext());
302   Out << "@";
303 
304   if (EmitDeclName(D)) {
305     // The string can be empty if the declaration has no name; e.g., it is
306     // the ParmDecl with no name for declaration of a function pointer type,
307     // e.g.: void  (*f)(void *);
308     // In this case, don't generate a USR.
309     IgnoreResults = true;
310   }
311 }
312 
313 void USRGenerator::VisitVarDecl(const VarDecl *D) {
314   // VarDecls can be declared 'extern' within a function or method body,
315   // but their enclosing DeclContext is the function, not the TU.  We need
316   // to check the storage class to correctly generate the USR.
317   if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
318     return;
319 
320   VisitDeclContext(D->getDeclContext());
321 
322   if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
323     Out << "@VT";
324     VisitTemplateParameterList(VarTmpl->getTemplateParameters());
325   } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
326              = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
327     Out << "@VP";
328     VisitTemplateParameterList(PartialSpec->getTemplateParameters());
329   }
330 
331   // Variables always have simple names.
332   StringRef s = D->getName();
333 
334   // The string can be empty if the declaration has no name; e.g., it is
335   // the ParmDecl with no name for declaration of a function pointer type, e.g.:
336   //    void  (*f)(void *);
337   // In this case, don't generate a USR.
338   if (s.empty())
339     IgnoreResults = true;
340   else
341     Out << '@' << s;
342 
343   // For a template specialization, mangle the template arguments.
344   if (const VarTemplateSpecializationDecl *Spec
345                               = dyn_cast<VarTemplateSpecializationDecl>(D)) {
346     const TemplateArgumentList &Args = Spec->getTemplateArgs();
347     Out << '>';
348     for (unsigned I = 0, N = Args.size(); I != N; ++I) {
349       Out << '#';
350       VisitTemplateArgument(Args.get(I));
351     }
352   }
353 }
354 
355 void USRGenerator::VisitBindingDecl(const BindingDecl *D) {
356   if (isLocal(D) && GenLoc(D, /*IncludeOffset=*/true))
357     return;
358   VisitNamedDecl(D);
359 }
360 
361 void USRGenerator::VisitNonTypeTemplateParmDecl(
362                                         const NonTypeTemplateParmDecl *D) {
363   GenLoc(D, /*IncludeOffset=*/true);
364 }
365 
366 void USRGenerator::VisitTemplateTemplateParmDecl(
367                                         const TemplateTemplateParmDecl *D) {
368   GenLoc(D, /*IncludeOffset=*/true);
369 }
370 
371 void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
372   if (IgnoreResults)
373     return;
374   VisitDeclContext(D->getDeclContext());
375   if (D->isAnonymousNamespace()) {
376     Out << "@aN";
377     return;
378   }
379   Out << "@N@" << D->getName();
380 }
381 
382 void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
383   VisitFunctionDecl(D->getTemplatedDecl());
384 }
385 
386 void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
387   VisitTagDecl(D->getTemplatedDecl());
388 }
389 
390 void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
391   VisitDeclContext(D->getDeclContext());
392   if (!IgnoreResults)
393     Out << "@NA@" << D->getName();
394 }
395 
396 static const ObjCCategoryDecl *getCategoryContext(const NamedDecl *D) {
397   if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
398     return CD;
399   if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
400     return ICD->getCategoryDecl();
401   return nullptr;
402 }
403 
404 void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
405   const DeclContext *container = D->getDeclContext();
406   if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
407     Visit(pd);
408   }
409   else {
410     // The USR for a method declared in a class extension or category is based on
411     // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
412     const ObjCInterfaceDecl *ID = D->getClassInterface();
413     if (!ID) {
414       IgnoreResults = true;
415       return;
416     }
417     auto *CD = getCategoryContext(D);
418     VisitObjCContainerDecl(ID, CD);
419   }
420   // Ideally we would use 'GenObjCMethod', but this is such a hot path
421   // for Objective-C code that we don't want to use
422   // DeclarationName::getAsString().
423   Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
424       << DeclarationName(D->getSelector());
425 }
426 
427 void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
428                                           const ObjCCategoryDecl *CatD) {
429   switch (D->getKind()) {
430     default:
431       llvm_unreachable("Invalid ObjC container.");
432     case Decl::ObjCInterface:
433     case Decl::ObjCImplementation:
434       GenObjCClass(D->getName(), GetExternalSourceContainer(D),
435                    GetExternalSourceContainer(CatD));
436       break;
437     case Decl::ObjCCategory: {
438       const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
439       const ObjCInterfaceDecl *ID = CD->getClassInterface();
440       if (!ID) {
441         // Handle invalid code where the @interface might not
442         // have been specified.
443         // FIXME: We should be able to generate this USR even if the
444         // @interface isn't available.
445         IgnoreResults = true;
446         return;
447       }
448       // Specially handle class extensions, which are anonymous categories.
449       // We want to mangle in the location to uniquely distinguish them.
450       if (CD->IsClassExtension()) {
451         Out << "objc(ext)" << ID->getName() << '@';
452         GenLoc(CD, /*IncludeOffset=*/true);
453       }
454       else
455         GenObjCCategory(ID->getName(), CD->getName(),
456                         GetExternalSourceContainer(ID),
457                         GetExternalSourceContainer(CD));
458 
459       break;
460     }
461     case Decl::ObjCCategoryImpl: {
462       const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
463       const ObjCInterfaceDecl *ID = CD->getClassInterface();
464       if (!ID) {
465         // Handle invalid code where the @interface might not
466         // have been specified.
467         // FIXME: We should be able to generate this USR even if the
468         // @interface isn't available.
469         IgnoreResults = true;
470         return;
471       }
472       GenObjCCategory(ID->getName(), CD->getName(),
473                       GetExternalSourceContainer(ID),
474                       GetExternalSourceContainer(CD));
475       break;
476     }
477     case Decl::ObjCProtocol: {
478       const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
479       GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
480       break;
481     }
482   }
483 }
484 
485 void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
486   // The USR for a property declared in a class extension or category is based
487   // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
488   if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
489     VisitObjCContainerDecl(ID, getCategoryContext(D));
490   else
491     Visit(cast<Decl>(D->getDeclContext()));
492   GenObjCProperty(D->getName(), D->isClassProperty());
493 }
494 
495 void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
496   if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
497     VisitObjCPropertyDecl(PD);
498     return;
499   }
500 
501   IgnoreResults = true;
502 }
503 
504 void USRGenerator::VisitTagDecl(const TagDecl *D) {
505   // Add the location of the tag decl to handle resolution across
506   // translation units.
507   if (!isa<EnumDecl>(D) &&
508       ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
509     return;
510 
511   GenExtSymbolContainer(D);
512 
513   D = D->getCanonicalDecl();
514   VisitDeclContext(D->getDeclContext());
515 
516   bool AlreadyStarted = false;
517   if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
518     if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
519       AlreadyStarted = true;
520 
521       switch (D->getTagKind()) {
522       case TagTypeKind::Interface:
523       case TagTypeKind::Class:
524       case TagTypeKind::Struct:
525         Out << "@ST";
526         break;
527       case TagTypeKind::Union:
528         Out << "@UT";
529         break;
530       case TagTypeKind::Enum:
531         llvm_unreachable("enum template");
532       }
533       VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
534     } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
535                 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
536       AlreadyStarted = true;
537 
538       switch (D->getTagKind()) {
539       case TagTypeKind::Interface:
540       case TagTypeKind::Class:
541       case TagTypeKind::Struct:
542         Out << "@SP";
543         break;
544       case TagTypeKind::Union:
545         Out << "@UP";
546         break;
547       case TagTypeKind::Enum:
548         llvm_unreachable("enum partial specialization");
549       }
550       VisitTemplateParameterList(PartialSpec->getTemplateParameters());
551     }
552   }
553 
554   if (!AlreadyStarted) {
555     switch (D->getTagKind()) {
556     case TagTypeKind::Interface:
557     case TagTypeKind::Class:
558     case TagTypeKind::Struct:
559       Out << "@S";
560       break;
561     case TagTypeKind::Union:
562       Out << "@U";
563       break;
564     case TagTypeKind::Enum:
565       Out << "@E";
566       break;
567     }
568   }
569 
570   Out << '@';
571   assert(Buf.size() > 0);
572   const unsigned off = Buf.size() - 1;
573 
574   if (EmitDeclName(D)) {
575     if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
576       Buf[off] = 'A';
577       Out << '@' << *TD;
578     } else {
579       if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
580         printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
581       } else {
582         Buf[off] = 'a';
583         if (auto *ED = dyn_cast<EnumDecl>(D)) {
584           // Distinguish USRs of anonymous enums by using their first
585           // enumerator.
586           auto enum_range = ED->enumerators();
587           if (enum_range.begin() != enum_range.end()) {
588             Out << '@' << **enum_range.begin();
589           }
590         }
591       }
592     }
593   }
594 
595   // For a class template specialization, mangle the template arguments.
596   if (const ClassTemplateSpecializationDecl *Spec
597                               = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
598     const TemplateArgumentList &Args = Spec->getTemplateArgs();
599     Out << '>';
600     for (unsigned I = 0, N = Args.size(); I != N; ++I) {
601       Out << '#';
602       VisitTemplateArgument(Args.get(I));
603     }
604   }
605 }
606 
607 void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
608   if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
609     return;
610   const DeclContext *DC = D->getDeclContext();
611   if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
612     Visit(DCN);
613   Out << "@T@";
614   Out << D->getName();
615 }
616 
617 void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
618   GenLoc(D, /*IncludeOffset=*/true);
619 }
620 
621 void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
622   StringRef Container = GetExternalSourceContainer(D);
623   if (!Container.empty())
624     Out << "@M@" << Container;
625 }
626 
627 bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
628   if (generatedLoc)
629     return IgnoreResults;
630   generatedLoc = true;
631 
632   // Guard against null declarations in invalid code.
633   if (!D) {
634     IgnoreResults = true;
635     return true;
636   }
637 
638   // Use the location of canonical decl.
639   D = D->getCanonicalDecl();
640 
641   IgnoreResults =
642       IgnoreResults || printLoc(Out, D->getBeginLoc(),
643                                 Context->getSourceManager(), IncludeOffset);
644 
645   return IgnoreResults;
646 }
647 
648 static void printQualifier(llvm::raw_ostream &Out, ASTContext &Ctx, NestedNameSpecifier *NNS) {
649   // FIXME: Encode the qualifier, don't just print it.
650   PrintingPolicy PO(Ctx.getLangOpts());
651   PO.SuppressTagKeyword = true;
652   PO.SuppressUnwrittenScope = true;
653   PO.ConstantArraySizeAsWritten = false;
654   PO.AnonymousTagLocations = false;
655   NNS->print(Out, PO);
656 }
657 
658 void USRGenerator::VisitType(QualType T) {
659   // This method mangles in USR information for types.  It can possibly
660   // just reuse the naming-mangling logic used by codegen, although the
661   // requirements for USRs might not be the same.
662   ASTContext &Ctx = *Context;
663 
664   do {
665     T = Ctx.getCanonicalType(T);
666     Qualifiers Q = T.getQualifiers();
667     unsigned qVal = 0;
668     if (Q.hasConst())
669       qVal |= 0x1;
670     if (Q.hasVolatile())
671       qVal |= 0x2;
672     if (Q.hasRestrict())
673       qVal |= 0x4;
674     if(qVal)
675       Out << ((char) ('0' + qVal));
676 
677     // Mangle in ObjC GC qualifiers?
678 
679     if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
680       Out << 'P';
681       T = Expansion->getPattern();
682     }
683 
684     if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
685       switch (BT->getKind()) {
686         case BuiltinType::Void:
687           Out << 'v'; break;
688         case BuiltinType::Bool:
689           Out << 'b'; break;
690         case BuiltinType::UChar:
691           Out << 'c'; break;
692         case BuiltinType::Char8:
693           Out << 'u'; break;
694         case BuiltinType::Char16:
695           Out << 'q'; break;
696         case BuiltinType::Char32:
697           Out << 'w'; break;
698         case BuiltinType::UShort:
699           Out << 's'; break;
700         case BuiltinType::UInt:
701           Out << 'i'; break;
702         case BuiltinType::ULong:
703           Out << 'l'; break;
704         case BuiltinType::ULongLong:
705           Out << 'k'; break;
706         case BuiltinType::UInt128:
707           Out << 'j'; break;
708         case BuiltinType::Char_U:
709         case BuiltinType::Char_S:
710           Out << 'C'; break;
711         case BuiltinType::SChar:
712           Out << 'r'; break;
713         case BuiltinType::WChar_S:
714         case BuiltinType::WChar_U:
715           Out << 'W'; break;
716         case BuiltinType::Short:
717           Out << 'S'; break;
718         case BuiltinType::Int:
719           Out << 'I'; break;
720         case BuiltinType::Long:
721           Out << 'L'; break;
722         case BuiltinType::LongLong:
723           Out << 'K'; break;
724         case BuiltinType::Int128:
725           Out << 'J'; break;
726         case BuiltinType::Float16:
727         case BuiltinType::Half:
728           Out << 'h'; break;
729         case BuiltinType::Float:
730           Out << 'f'; break;
731         case BuiltinType::Double:
732           Out << 'd'; break;
733         case BuiltinType::LongDouble:
734           Out << 'D'; break;
735         case BuiltinType::Float128:
736           Out << 'Q'; break;
737         case BuiltinType::NullPtr:
738           Out << 'n'; break;
739 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
740         case BuiltinType::Id: \
741           Out << "@BT@" << #Suffix << "_" << #ImgType; break;
742 #include "clang/Basic/OpenCLImageTypes.def"
743 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
744         case BuiltinType::Id: \
745           Out << "@BT@" << #ExtType; break;
746 #include "clang/Basic/OpenCLExtensionTypes.def"
747         case BuiltinType::OCLEvent:
748           Out << "@BT@OCLEvent"; break;
749         case BuiltinType::OCLClkEvent:
750           Out << "@BT@OCLClkEvent"; break;
751         case BuiltinType::OCLQueue:
752           Out << "@BT@OCLQueue"; break;
753         case BuiltinType::OCLReserveID:
754           Out << "@BT@OCLReserveID"; break;
755         case BuiltinType::OCLSampler:
756           Out << "@BT@OCLSampler"; break;
757 #define SVE_TYPE(Name, Id, SingletonId) \
758         case BuiltinType::Id: \
759           Out << "@BT@" << Name; break;
760 #include "clang/Basic/AArch64SVEACLETypes.def"
761 #define PPC_VECTOR_TYPE(Name, Id, Size) \
762         case BuiltinType::Id: \
763           Out << "@BT@" << #Name; break;
764 #include "clang/Basic/PPCTypes.def"
765 #define RVV_TYPE(Name, Id, SingletonId) \
766         case BuiltinType::Id: \
767           Out << "@BT@" << Name; break;
768 #include "clang/Basic/RISCVVTypes.def"
769 #define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
770 #include "clang/Basic/WebAssemblyReferenceTypes.def"
771         case BuiltinType::ShortAccum:
772           Out << "@BT@ShortAccum"; break;
773         case BuiltinType::Accum:
774           Out << "@BT@Accum"; break;
775         case BuiltinType::LongAccum:
776           Out << "@BT@LongAccum"; break;
777         case BuiltinType::UShortAccum:
778           Out << "@BT@UShortAccum"; break;
779         case BuiltinType::UAccum:
780           Out << "@BT@UAccum"; break;
781         case BuiltinType::ULongAccum:
782           Out << "@BT@ULongAccum"; break;
783         case BuiltinType::ShortFract:
784           Out << "@BT@ShortFract"; break;
785         case BuiltinType::Fract:
786           Out << "@BT@Fract"; break;
787         case BuiltinType::LongFract:
788           Out << "@BT@LongFract"; break;
789         case BuiltinType::UShortFract:
790           Out << "@BT@UShortFract"; break;
791         case BuiltinType::UFract:
792           Out << "@BT@UFract"; break;
793         case BuiltinType::ULongFract:
794           Out << "@BT@ULongFract"; break;
795         case BuiltinType::SatShortAccum:
796           Out << "@BT@SatShortAccum"; break;
797         case BuiltinType::SatAccum:
798           Out << "@BT@SatAccum"; break;
799         case BuiltinType::SatLongAccum:
800           Out << "@BT@SatLongAccum"; break;
801         case BuiltinType::SatUShortAccum:
802           Out << "@BT@SatUShortAccum"; break;
803         case BuiltinType::SatUAccum:
804           Out << "@BT@SatUAccum"; break;
805         case BuiltinType::SatULongAccum:
806           Out << "@BT@SatULongAccum"; break;
807         case BuiltinType::SatShortFract:
808           Out << "@BT@SatShortFract"; break;
809         case BuiltinType::SatFract:
810           Out << "@BT@SatFract"; break;
811         case BuiltinType::SatLongFract:
812           Out << "@BT@SatLongFract"; break;
813         case BuiltinType::SatUShortFract:
814           Out << "@BT@SatUShortFract"; break;
815         case BuiltinType::SatUFract:
816           Out << "@BT@SatUFract"; break;
817         case BuiltinType::SatULongFract:
818           Out << "@BT@SatULongFract"; break;
819         case BuiltinType::BFloat16:
820           Out << "@BT@__bf16"; break;
821         case BuiltinType::Ibm128:
822           Out << "@BT@__ibm128"; break;
823         case BuiltinType::ObjCId:
824           Out << 'o'; break;
825         case BuiltinType::ObjCClass:
826           Out << 'O'; break;
827         case BuiltinType::ObjCSel:
828           Out << 'e'; break;
829 #define BUILTIN_TYPE(Id, SingletonId)
830 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
831 #include "clang/AST/BuiltinTypes.def"
832         case BuiltinType::Dependent:
833           // If you're adding a new builtin type, please add its name prefixed
834           // with "@BT@" to `Out` (see cases above).
835           IgnoreResults = true;
836           break;
837       }
838       return;
839     }
840 
841     // If we have already seen this (non-built-in) type, use a substitution
842     // encoding.
843     llvm::DenseMap<const Type *, unsigned>::iterator Substitution
844       = TypeSubstitutions.find(T.getTypePtr());
845     if (Substitution != TypeSubstitutions.end()) {
846       Out << 'S' << Substitution->second << '_';
847       return;
848     } else {
849       // Record this as a substitution.
850       unsigned Number = TypeSubstitutions.size();
851       TypeSubstitutions[T.getTypePtr()] = Number;
852     }
853 
854     if (const PointerType *PT = T->getAs<PointerType>()) {
855       Out << '*';
856       T = PT->getPointeeType();
857       continue;
858     }
859     if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
860       Out << '*';
861       T = OPT->getPointeeType();
862       continue;
863     }
864     if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
865       Out << "&&";
866       T = RT->getPointeeType();
867       continue;
868     }
869     if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
870       Out << '&';
871       T = RT->getPointeeType();
872       continue;
873     }
874     if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
875       Out << 'F';
876       VisitType(FT->getReturnType());
877       Out << '(';
878       for (const auto &I : FT->param_types()) {
879         Out << '#';
880         VisitType(I);
881       }
882       Out << ')';
883       if (FT->isVariadic())
884         Out << '.';
885       return;
886     }
887     if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
888       Out << 'B';
889       T = BT->getPointeeType();
890       continue;
891     }
892     if (const ComplexType *CT = T->getAs<ComplexType>()) {
893       Out << '<';
894       T = CT->getElementType();
895       continue;
896     }
897     if (const TagType *TT = T->getAs<TagType>()) {
898       Out << '$';
899       VisitTagDecl(TT->getDecl());
900       return;
901     }
902     if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
903       Out << '$';
904       VisitObjCInterfaceDecl(OIT->getDecl());
905       return;
906     }
907     if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
908       Out << 'Q';
909       VisitType(OIT->getBaseType());
910       for (auto *Prot : OIT->getProtocols())
911         VisitObjCProtocolDecl(Prot);
912       return;
913     }
914     if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
915       Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
916       return;
917     }
918     if (const TemplateSpecializationType *Spec
919                                     = T->getAs<TemplateSpecializationType>()) {
920       Out << '>';
921       VisitTemplateName(Spec->getTemplateName());
922       Out << Spec->template_arguments().size();
923       for (const auto &Arg : Spec->template_arguments())
924         VisitTemplateArgument(Arg);
925       return;
926     }
927     if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
928       Out << '^';
929       printQualifier(Out, Ctx, DNT->getQualifier());
930       Out << ':' << DNT->getIdentifier()->getName();
931       return;
932     }
933     if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) {
934       T = InjT->getInjectedSpecializationType();
935       continue;
936     }
937     if (const auto *VT = T->getAs<VectorType>()) {
938       Out << (T->isExtVectorType() ? ']' : '[');
939       Out << VT->getNumElements();
940       T = VT->getElementType();
941       continue;
942     }
943     if (const auto *const AT = dyn_cast<ArrayType>(T)) {
944       Out << '{';
945       switch (AT->getSizeModifier()) {
946       case ArraySizeModifier::Static:
947         Out << 's';
948         break;
949       case ArraySizeModifier::Star:
950         Out << '*';
951         break;
952       case ArraySizeModifier::Normal:
953         Out << 'n';
954         break;
955       }
956       if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
957         Out << CAT->getSize();
958 
959       T = AT->getElementType();
960       continue;
961     }
962 
963     // Unhandled type.
964     Out << ' ';
965     break;
966   } while (true);
967 }
968 
969 void USRGenerator::VisitTemplateParameterList(
970                                          const TemplateParameterList *Params) {
971   if (!Params)
972     return;
973   Out << '>' << Params->size();
974   for (TemplateParameterList::const_iterator P = Params->begin(),
975                                           PEnd = Params->end();
976        P != PEnd; ++P) {
977     Out << '#';
978     if (isa<TemplateTypeParmDecl>(*P)) {
979       if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
980         Out<< 'p';
981       Out << 'T';
982       continue;
983     }
984 
985     if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
986       if (NTTP->isParameterPack())
987         Out << 'p';
988       Out << 'N';
989       VisitType(NTTP->getType());
990       continue;
991     }
992 
993     TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
994     if (TTP->isParameterPack())
995       Out << 'p';
996     Out << 't';
997     VisitTemplateParameterList(TTP->getTemplateParameters());
998   }
999 }
1000 
1001 void USRGenerator::VisitTemplateName(TemplateName Name) {
1002   if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1003     if (TemplateTemplateParmDecl *TTP
1004                               = dyn_cast<TemplateTemplateParmDecl>(Template)) {
1005       Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1006       return;
1007     }
1008 
1009     Visit(Template);
1010     return;
1011   }
1012 
1013   // FIXME: Visit dependent template names.
1014 }
1015 
1016 void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
1017   switch (Arg.getKind()) {
1018   case TemplateArgument::Null:
1019     break;
1020 
1021   case TemplateArgument::Declaration:
1022     Visit(Arg.getAsDecl());
1023     break;
1024 
1025   case TemplateArgument::NullPtr:
1026     break;
1027 
1028   case TemplateArgument::TemplateExpansion:
1029     Out << 'P'; // pack expansion of...
1030     [[fallthrough]];
1031   case TemplateArgument::Template:
1032     VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1033     break;
1034 
1035   case TemplateArgument::Expression:
1036     // FIXME: Visit expressions.
1037     break;
1038 
1039   case TemplateArgument::Pack:
1040     Out << 'p' << Arg.pack_size();
1041     for (const auto &P : Arg.pack_elements())
1042       VisitTemplateArgument(P);
1043     break;
1044 
1045   case TemplateArgument::Type:
1046     VisitType(Arg.getAsType());
1047     break;
1048 
1049   case TemplateArgument::Integral:
1050     Out << 'V';
1051     VisitType(Arg.getIntegralType());
1052     Out << Arg.getAsIntegral();
1053     break;
1054   }
1055 }
1056 
1057 void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1058   if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1059     return;
1060   VisitDeclContext(D->getDeclContext());
1061   Out << "@UUV@";
1062   printQualifier(Out, D->getASTContext(), D->getQualifier());
1063   EmitDeclName(D);
1064 }
1065 
1066 void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
1067   if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1068     return;
1069   VisitDeclContext(D->getDeclContext());
1070   Out << "@UUT@";
1071   printQualifier(Out, D->getASTContext(), D->getQualifier());
1072   Out << D->getName(); // Simple name.
1073 }
1074 
1075 void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
1076   if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1077     return;
1078   VisitDeclContext(D->getDeclContext());
1079   Out << "@CT@";
1080   EmitDeclName(D);
1081 }
1082 
1083 void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
1084   VisitDeclContext(D->getDeclContext());
1085   Out << "@MG@";
1086   D->NamedDecl::printName(Out);
1087 }
1088 
1089 //===----------------------------------------------------------------------===//
1090 // USR generation functions.
1091 //===----------------------------------------------------------------------===//
1092 
1093 static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
1094                                                  StringRef CatSymDefinedIn,
1095                                                  raw_ostream &OS) {
1096   if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
1097     return;
1098   if (CatSymDefinedIn.empty()) {
1099     OS << "@M@" << ClsSymDefinedIn << '@';
1100     return;
1101   }
1102   OS << "@CM@" << CatSymDefinedIn << '@';
1103   if (ClsSymDefinedIn != CatSymDefinedIn) {
1104     OS << ClsSymDefinedIn << '@';
1105   }
1106 }
1107 
1108 void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
1109                                            StringRef ExtSymDefinedIn,
1110                                   StringRef CategoryContextExtSymbolDefinedIn) {
1111   combineClassAndCategoryExtContainers(ExtSymDefinedIn,
1112                                        CategoryContextExtSymbolDefinedIn, OS);
1113   OS << "objc(cs)" << Cls;
1114 }
1115 
1116 void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
1117                                               raw_ostream &OS,
1118                                               StringRef ClsSymDefinedIn,
1119                                               StringRef CatSymDefinedIn) {
1120   combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
1121   OS << "objc(cy)" << Cls << '@' << Cat;
1122 }
1123 
1124 void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
1125   OS << '@' << Ivar;
1126 }
1127 
1128 void clang::index::generateUSRForObjCMethod(StringRef Sel,
1129                                             bool IsInstanceMethod,
1130                                             raw_ostream &OS) {
1131   OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
1132 }
1133 
1134 void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
1135                                               raw_ostream &OS) {
1136   OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
1137 }
1138 
1139 void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
1140                                               StringRef ExtSymDefinedIn) {
1141   if (!ExtSymDefinedIn.empty())
1142     OS << "@M@" << ExtSymDefinedIn << '@';
1143   OS << "objc(pl)" << Prot;
1144 }
1145 
1146 void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
1147                                             StringRef ExtSymDefinedIn) {
1148   if (!ExtSymDefinedIn.empty())
1149     OS << "@M@" << ExtSymDefinedIn;
1150   OS << "@E@" << EnumName;
1151 }
1152 
1153 void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
1154                                               raw_ostream &OS) {
1155   OS << '@' << EnumConstantName;
1156 }
1157 
1158 bool clang::index::generateUSRForDecl(const Decl *D,
1159                                       SmallVectorImpl<char> &Buf) {
1160   if (!D)
1161     return true;
1162   // We don't ignore decls with invalid source locations. Implicit decls, like
1163   // C++'s operator new function, can have invalid locations but it is fine to
1164   // create USRs that can identify them.
1165 
1166   // Check if the declaration has explicit external USR specified.
1167   auto *CD = D->getCanonicalDecl();
1168   if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
1169     if (!ExternalSymAttr->getUSR().empty()) {
1170       llvm::raw_svector_ostream Out(Buf);
1171       Out << ExternalSymAttr->getUSR();
1172       return false;
1173     }
1174   }
1175   USRGenerator UG(&D->getASTContext(), Buf);
1176   UG.Visit(D);
1177   return UG.ignoreResults();
1178 }
1179 
1180 bool clang::index::generateUSRForMacro(const MacroDefinitionRecord *MD,
1181                                        const SourceManager &SM,
1182                                        SmallVectorImpl<char> &Buf) {
1183   if (!MD)
1184     return true;
1185   return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1186                              SM, Buf);
1187 
1188 }
1189 
1190 bool clang::index::generateUSRForMacro(StringRef MacroName, SourceLocation Loc,
1191                                        const SourceManager &SM,
1192                                        SmallVectorImpl<char> &Buf) {
1193   if (MacroName.empty())
1194     return true;
1195 
1196   llvm::raw_svector_ostream Out(Buf);
1197 
1198   // Assume that system headers are sane.  Don't put source location
1199   // information into the USR if the macro comes from a system header.
1200   bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
1201 
1202   Out << getUSRSpacePrefix();
1203   if (ShouldGenerateLocation)
1204     printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1205   Out << "@macro@";
1206   Out << MacroName;
1207   return false;
1208 }
1209 
1210 bool clang::index::generateUSRForType(QualType T, ASTContext &Ctx,
1211                                       SmallVectorImpl<char> &Buf) {
1212   if (T.isNull())
1213     return true;
1214   T = T.getCanonicalType();
1215 
1216   USRGenerator UG(&Ctx, Buf);
1217   UG.VisitType(T);
1218   return UG.ignoreResults();
1219 }
1220 
1221 bool clang::index::generateFullUSRForModule(const Module *Mod,
1222                                             raw_ostream &OS) {
1223   if (!Mod->Parent)
1224     return generateFullUSRForTopLevelModuleName(Mod->Name, OS);
1225   if (generateFullUSRForModule(Mod->Parent, OS))
1226     return true;
1227   return generateUSRFragmentForModule(Mod, OS);
1228 }
1229 
1230 bool clang::index::generateFullUSRForTopLevelModuleName(StringRef ModName,
1231                                                         raw_ostream &OS) {
1232   OS << getUSRSpacePrefix();
1233   return generateUSRFragmentForModuleName(ModName, OS);
1234 }
1235 
1236 bool clang::index::generateUSRFragmentForModule(const Module *Mod,
1237                                                 raw_ostream &OS) {
1238   return generateUSRFragmentForModuleName(Mod->Name, OS);
1239 }
1240 
1241 bool clang::index::generateUSRFragmentForModuleName(StringRef ModName,
1242                                                     raw_ostream &OS) {
1243   OS << "@M@" << ModName;
1244   return false;
1245 }
1246