clang  5.0.0
USRGeneration.cpp
Go to the documentation of this file.
1 //===- USRGeneration.cpp - Routines for USR generation --------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
11 #include "clang/AST/ASTContext.h"
12 #include "clang/AST/DeclTemplate.h"
13 #include "clang/AST/DeclVisitor.h"
15 #include "llvm/Support/Path.h"
16 #include "llvm/Support/raw_ostream.h"
17 
18 using namespace clang;
19 using namespace clang::index;
20 
21 //===----------------------------------------------------------------------===//
22 // USR generation.
23 //===----------------------------------------------------------------------===//
24 
25 /// \returns true on error.
26 static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
27  const SourceManager &SM, bool IncludeOffset) {
28  if (Loc.isInvalid()) {
29  return true;
30  }
31  Loc = SM.getExpansionLoc(Loc);
32  const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
33  const FileEntry *FE = SM.getFileEntryForID(Decomposed.first);
34  if (FE) {
35  OS << llvm::sys::path::filename(FE->getName());
36  } else {
37  // This case really isn't interesting.
38  return true;
39  }
40  if (IncludeOffset) {
41  // Use the offest into the FileID to represent the location. Using
42  // a line/column can cause us to look back at the original source file,
43  // which is expensive.
44  OS << '@' << Decomposed.second;
45  }
46  return false;
47 }
48 
49 static StringRef GetExternalSourceContainer(const NamedDecl *D) {
50  if (!D)
51  return StringRef();
52  if (auto *attr = D->getExternalSourceSymbolAttr()) {
53  return attr->getDefinedIn();
54  }
55  return StringRef();
56 }
57 
58 namespace {
59 class USRGenerator : public ConstDeclVisitor<USRGenerator> {
61  llvm::raw_svector_ostream Out;
62  bool IgnoreResults;
64  bool generatedLoc;
65 
66  llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
67 
68 public:
69  explicit USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf)
70  : Buf(Buf),
71  Out(Buf),
72  IgnoreResults(false),
73  Context(Ctx),
74  generatedLoc(false)
75  {
76  // Add the USR space prefix.
77  Out << getUSRSpacePrefix();
78  }
79 
80  bool ignoreResults() const { return IgnoreResults; }
81 
82  // Visitation methods from generating USRs from AST elements.
83  void VisitDeclContext(const DeclContext *D);
84  void VisitFieldDecl(const FieldDecl *D);
85  void VisitFunctionDecl(const FunctionDecl *D);
86  void VisitNamedDecl(const NamedDecl *D);
87  void VisitNamespaceDecl(const NamespaceDecl *D);
88  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
89  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
90  void VisitClassTemplateDecl(const ClassTemplateDecl *D);
91  void VisitObjCContainerDecl(const ObjCContainerDecl *CD,
92  const ObjCCategoryDecl *CatD = nullptr);
93  void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
94  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
95  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
96  void VisitTagDecl(const TagDecl *D);
97  void VisitTypedefDecl(const TypedefDecl *D);
98  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
99  void VisitVarDecl(const VarDecl *D);
100  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
101  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
102 
103  void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
104  IgnoreResults = true;
105  }
106 
107  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
108  IgnoreResults = true;
109  }
110 
111  void VisitUsingDecl(const UsingDecl *D) {
112  IgnoreResults = true;
113  }
114 
115  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
116  IgnoreResults = true;
117  }
118 
119  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
120  IgnoreResults = true;
121  }
122 
123  bool ShouldGenerateLocation(const NamedDecl *D);
124 
125  bool isLocal(const NamedDecl *D) {
126  return D->getParentFunctionOrMethod() != nullptr;
127  }
128 
129  void GenExtSymbolContainer(const NamedDecl *D);
130 
131  /// Generate the string component containing the location of the
132  /// declaration.
133  bool GenLoc(const Decl *D, bool IncludeOffset);
134 
135  /// String generation methods used both by the visitation methods
136  /// and from other clients that want to directly generate USRs. These
137  /// methods do not construct complete USRs (which incorporate the parents
138  /// of an AST element), but only the fragments concerning the AST element
139  /// itself.
140 
141  /// Generate a USR for an Objective-C class.
142  void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
143  StringRef CategoryContextExtSymbolDefinedIn) {
144  generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
145  CategoryContextExtSymbolDefinedIn);
146  }
147 
148  /// Generate a USR for an Objective-C class category.
149  void GenObjCCategory(StringRef cls, StringRef cat,
150  StringRef clsExt, StringRef catExt) {
151  generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
152  }
153 
154  /// Generate a USR fragment for an Objective-C property.
155  void GenObjCProperty(StringRef prop, bool isClassProp) {
156  generateUSRForObjCProperty(prop, isClassProp, Out);
157  }
158 
159  /// Generate a USR for an Objective-C protocol.
160  void GenObjCProtocol(StringRef prot, StringRef ext) {
161  generateUSRForObjCProtocol(prot, Out, ext);
162  }
163 
164  void VisitType(QualType T);
165  void VisitTemplateParameterList(const TemplateParameterList *Params);
166  void VisitTemplateName(TemplateName Name);
167  void VisitTemplateArgument(const TemplateArgument &Arg);
168 
169  /// Emit a Decl's name using NamedDecl::printName() and return true if
170  /// the decl had no name.
171  bool EmitDeclName(const NamedDecl *D);
172 };
173 } // end anonymous namespace
174 
175 //===----------------------------------------------------------------------===//
176 // Generating USRs from ASTS.
177 //===----------------------------------------------------------------------===//
178 
179 bool USRGenerator::EmitDeclName(const NamedDecl *D) {
180  const unsigned startSize = Buf.size();
181  D->printName(Out);
182  const unsigned endSize = Buf.size();
183  return startSize == endSize;
184 }
185 
186 bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
187  if (D->isExternallyVisible())
188  return false;
189  if (D->getParentFunctionOrMethod())
190  return true;
191  SourceLocation Loc = D->getLocation();
192  if (Loc.isInvalid())
193  return false;
195  return !SM.isInSystemHeader(Loc);
196 }
197 
198 void USRGenerator::VisitDeclContext(const DeclContext *DC) {
199  if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
200  Visit(D);
201 }
202 
203 void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
204  // The USR for an ivar declared in a class extension is based on the
205  // ObjCInterfaceDecl, not the ObjCCategoryDecl.
207  Visit(ID);
208  else
209  VisitDeclContext(D->getDeclContext());
210  Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
211  if (EmitDeclName(D)) {
212  // Bit fields can be anonymous.
213  IgnoreResults = true;
214  return;
215  }
216 }
217 
218 void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
219  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
220  return;
221 
222  const unsigned StartSize = Buf.size();
223  VisitDeclContext(D->getDeclContext());
224  if (Buf.size() == StartSize)
225  GenExtSymbolContainer(D);
226 
227  bool IsTemplate = false;
229  IsTemplate = true;
230  Out << "@FT@";
231  VisitTemplateParameterList(FunTmpl->getTemplateParameters());
232  } else
233  Out << "@F@";
234 
236  // Forward references can have different template argument names. Suppress the
237  // template argument names in constructors to make their USR more stable.
239  D->getDeclName().print(Out, Policy);
240 
241  ASTContext &Ctx = *Context;
242  if ((!Ctx.getLangOpts().CPlusPlus || D->isExternC()) &&
243  !D->hasAttr<OverloadableAttr>())
244  return;
245 
246  if (const TemplateArgumentList *
247  SpecArgs = D->getTemplateSpecializationArgs()) {
248  Out << '<';
249  for (unsigned I = 0, N = SpecArgs->size(); I != N; ++I) {
250  Out << '#';
251  VisitTemplateArgument(SpecArgs->get(I));
252  }
253  Out << '>';
254  }
255 
256  // Mangle in type information for the arguments.
257  for (auto PD : D->parameters()) {
258  Out << '#';
259  VisitType(PD->getType());
260  }
261  if (D->isVariadic())
262  Out << '.';
263  if (IsTemplate) {
264  // Function templates can be overloaded by return type, for example:
265  // \code
266  // template <class T> typename T::A foo() {}
267  // template <class T> typename T::B foo() {}
268  // \endcode
269  Out << '#';
270  VisitType(D->getReturnType());
271  }
272  Out << '#';
273  if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
274  if (MD->isStatic())
275  Out << 'S';
276  if (unsigned quals = MD->getTypeQualifiers())
277  Out << (char)('0' + quals);
278  switch (MD->getRefQualifier()) {
279  case RQ_None: break;
280  case RQ_LValue: Out << '&'; break;
281  case RQ_RValue: Out << "&&"; break;
282  }
283  }
284 }
285 
286 void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
287  VisitDeclContext(D->getDeclContext());
288  Out << "@";
289 
290  if (EmitDeclName(D)) {
291  // The string can be empty if the declaration has no name; e.g., it is
292  // the ParmDecl with no name for declaration of a function pointer type,
293  // e.g.: void (*f)(void *);
294  // In this case, don't generate a USR.
295  IgnoreResults = true;
296  }
297 }
298 
299 void USRGenerator::VisitVarDecl(const VarDecl *D) {
300  // VarDecls can be declared 'extern' within a function or method body,
301  // but their enclosing DeclContext is the function, not the TU. We need
302  // to check the storage class to correctly generate the USR.
303  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
304  return;
305 
306  VisitDeclContext(D->getDeclContext());
307 
308  if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
309  Out << "@VT";
310  VisitTemplateParameterList(VarTmpl->getTemplateParameters());
311  } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
312  = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
313  Out << "@VP";
314  VisitTemplateParameterList(PartialSpec->getTemplateParameters());
315  }
316 
317  // Variables always have simple names.
318  StringRef s = D->getName();
319 
320  // The string can be empty if the declaration has no name; e.g., it is
321  // the ParmDecl with no name for declaration of a function pointer type, e.g.:
322  // void (*f)(void *);
323  // In this case, don't generate a USR.
324  if (s.empty())
325  IgnoreResults = true;
326  else
327  Out << '@' << s;
328 
329  // For a template specialization, mangle the template arguments.
330  if (const VarTemplateSpecializationDecl *Spec
331  = dyn_cast<VarTemplateSpecializationDecl>(D)) {
332  const TemplateArgumentList &Args = Spec->getTemplateArgs();
333  Out << '>';
334  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
335  Out << '#';
336  VisitTemplateArgument(Args.get(I));
337  }
338  }
339 }
340 
341 void USRGenerator::VisitNonTypeTemplateParmDecl(
342  const NonTypeTemplateParmDecl *D) {
343  GenLoc(D, /*IncludeOffset=*/true);
344 }
345 
346 void USRGenerator::VisitTemplateTemplateParmDecl(
347  const TemplateTemplateParmDecl *D) {
348  GenLoc(D, /*IncludeOffset=*/true);
349 }
350 
351 void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
352  if (D->isAnonymousNamespace()) {
353  Out << "@aN";
354  return;
355  }
356 
357  VisitDeclContext(D->getDeclContext());
358  if (!IgnoreResults)
359  Out << "@N@" << D->getName();
360 }
361 
362 void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
363  VisitFunctionDecl(D->getTemplatedDecl());
364 }
365 
366 void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
367  VisitTagDecl(D->getTemplatedDecl());
368 }
369 
370 void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
371  VisitDeclContext(D->getDeclContext());
372  if (!IgnoreResults)
373  Out << "@NA@" << D->getName();
374 }
375 
376 void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
377  const DeclContext *container = D->getDeclContext();
378  if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
379  Visit(pd);
380  }
381  else {
382  // The USR for a method declared in a class extension or category is based on
383  // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
384  const ObjCInterfaceDecl *ID = D->getClassInterface();
385  if (!ID) {
386  IgnoreResults = true;
387  return;
388  }
389  auto getCategoryContext = [](const ObjCMethodDecl *D) ->
390  const ObjCCategoryDecl * {
391  if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
392  return CD;
393  if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
394  return ICD->getCategoryDecl();
395  return nullptr;
396  };
397  auto *CD = getCategoryContext(D);
398  VisitObjCContainerDecl(ID, CD);
399  }
400  // Ideally we would use 'GenObjCMethod', but this is such a hot path
401  // for Objective-C code that we don't want to use
402  // DeclarationName::getAsString().
403  Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
404  << DeclarationName(D->getSelector());
405 }
406 
407 void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
408  const ObjCCategoryDecl *CatD) {
409  switch (D->getKind()) {
410  default:
411  llvm_unreachable("Invalid ObjC container.");
412  case Decl::ObjCInterface:
413  case Decl::ObjCImplementation:
414  GenObjCClass(D->getName(), GetExternalSourceContainer(D),
416  break;
417  case Decl::ObjCCategory: {
418  const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
419  const ObjCInterfaceDecl *ID = CD->getClassInterface();
420  if (!ID) {
421  // Handle invalid code where the @interface might not
422  // have been specified.
423  // FIXME: We should be able to generate this USR even if the
424  // @interface isn't available.
425  IgnoreResults = true;
426  return;
427  }
428  // Specially handle class extensions, which are anonymous categories.
429  // We want to mangle in the location to uniquely distinguish them.
430  if (CD->IsClassExtension()) {
431  Out << "objc(ext)" << ID->getName() << '@';
432  GenLoc(CD, /*IncludeOffset=*/true);
433  }
434  else
435  GenObjCCategory(ID->getName(), CD->getName(),
438 
439  break;
440  }
441  case Decl::ObjCCategoryImpl: {
442  const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
443  const ObjCInterfaceDecl *ID = CD->getClassInterface();
444  if (!ID) {
445  // Handle invalid code where the @interface might not
446  // have been specified.
447  // FIXME: We should be able to generate this USR even if the
448  // @interface isn't available.
449  IgnoreResults = true;
450  return;
451  }
452  GenObjCCategory(ID->getName(), CD->getName(),
455  break;
456  }
457  case Decl::ObjCProtocol: {
458  const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
459  GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
460  break;
461  }
462  }
463 }
464 
465 void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
466  // The USR for a property declared in a class extension or category is based
467  // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
469  Visit(ID);
470  else
471  Visit(cast<Decl>(D->getDeclContext()));
472  GenObjCProperty(D->getName(), D->isClassProperty());
473 }
474 
475 void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
476  if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
477  VisitObjCPropertyDecl(PD);
478  return;
479  }
480 
481  IgnoreResults = true;
482 }
483 
484 void USRGenerator::VisitTagDecl(const TagDecl *D) {
485  // Add the location of the tag decl to handle resolution across
486  // translation units.
487  if (!isa<EnumDecl>(D) &&
488  ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
489  return;
490 
491  GenExtSymbolContainer(D);
492 
493  D = D->getCanonicalDecl();
494  VisitDeclContext(D->getDeclContext());
495 
496  bool AlreadyStarted = false;
497  if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
498  if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
499  AlreadyStarted = true;
500 
501  switch (D->getTagKind()) {
502  case TTK_Interface:
503  case TTK_Class:
504  case TTK_Struct: Out << "@ST"; break;
505  case TTK_Union: Out << "@UT"; break;
506  case TTK_Enum: llvm_unreachable("enum template");
507  }
508  VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
509  } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
510  = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
511  AlreadyStarted = true;
512 
513  switch (D->getTagKind()) {
514  case TTK_Interface:
515  case TTK_Class:
516  case TTK_Struct: Out << "@SP"; break;
517  case TTK_Union: Out << "@UP"; break;
518  case TTK_Enum: llvm_unreachable("enum partial specialization");
519  }
520  VisitTemplateParameterList(PartialSpec->getTemplateParameters());
521  }
522  }
523 
524  if (!AlreadyStarted) {
525  switch (D->getTagKind()) {
526  case TTK_Interface:
527  case TTK_Class:
528  case TTK_Struct: Out << "@S"; break;
529  case TTK_Union: Out << "@U"; break;
530  case TTK_Enum: Out << "@E"; break;
531  }
532  }
533 
534  Out << '@';
535  assert(Buf.size() > 0);
536  const unsigned off = Buf.size() - 1;
537 
538  if (EmitDeclName(D)) {
539  if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
540  Buf[off] = 'A';
541  Out << '@' << *TD;
542  }
543  else {
544  if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
545  printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
546  } else {
547  Buf[off] = 'a';
548  if (auto *ED = dyn_cast<EnumDecl>(D)) {
549  // Distinguish USRs of anonymous enums by using their first enumerator.
550  auto enum_range = ED->enumerators();
551  if (enum_range.begin() != enum_range.end()) {
552  Out << '@' << **enum_range.begin();
553  }
554  }
555  }
556  }
557  }
558 
559  // For a class template specialization, mangle the template arguments.
560  if (const ClassTemplateSpecializationDecl *Spec
561  = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
562  const TemplateArgumentList &Args = Spec->getTemplateArgs();
563  Out << '>';
564  for (unsigned I = 0, N = Args.size(); I != N; ++I) {
565  Out << '#';
566  VisitTemplateArgument(Args.get(I));
567  }
568  }
569 }
570 
571 void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
572  if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
573  return;
574  const DeclContext *DC = D->getDeclContext();
575  if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
576  Visit(DCN);
577  Out << "@T@";
578  Out << D->getName();
579 }
580 
581 void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
582  GenLoc(D, /*IncludeOffset=*/true);
583 }
584 
585 void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
586  StringRef Container = GetExternalSourceContainer(D);
587  if (!Container.empty())
588  Out << "@M@" << Container;
589 }
590 
591 bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
592  if (generatedLoc)
593  return IgnoreResults;
594  generatedLoc = true;
595 
596  // Guard against null declarations in invalid code.
597  if (!D) {
598  IgnoreResults = true;
599  return true;
600  }
601 
602  // Use the location of canonical decl.
603  D = D->getCanonicalDecl();
604 
605  IgnoreResults =
606  IgnoreResults || printLoc(Out, D->getLocStart(),
607  Context->getSourceManager(), IncludeOffset);
608 
609  return IgnoreResults;
610 }
611 
612 void USRGenerator::VisitType(QualType T) {
613  // This method mangles in USR information for types. It can possibly
614  // just reuse the naming-mangling logic used by codegen, although the
615  // requirements for USRs might not be the same.
616  ASTContext &Ctx = *Context;
617 
618  do {
619  T = Ctx.getCanonicalType(T);
620  Qualifiers Q = T.getQualifiers();
621  unsigned qVal = 0;
622  if (Q.hasConst())
623  qVal |= 0x1;
624  if (Q.hasVolatile())
625  qVal |= 0x2;
626  if (Q.hasRestrict())
627  qVal |= 0x4;
628  if(qVal)
629  Out << ((char) ('0' + qVal));
630 
631  // Mangle in ObjC GC qualifiers?
632 
633  if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
634  Out << 'P';
635  T = Expansion->getPattern();
636  }
637 
638  if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
639  unsigned char c = '\0';
640  switch (BT->getKind()) {
641  case BuiltinType::Void:
642  c = 'v'; break;
643  case BuiltinType::Bool:
644  c = 'b'; break;
645  case BuiltinType::UChar:
646  c = 'c'; break;
647  case BuiltinType::Char16:
648  c = 'q'; break;
649  case BuiltinType::Char32:
650  c = 'w'; break;
651  case BuiltinType::UShort:
652  c = 's'; break;
653  case BuiltinType::UInt:
654  c = 'i'; break;
655  case BuiltinType::ULong:
656  c = 'l'; break;
657  case BuiltinType::ULongLong:
658  c = 'k'; break;
659  case BuiltinType::UInt128:
660  c = 'j'; break;
661  case BuiltinType::Char_U:
662  case BuiltinType::Char_S:
663  c = 'C'; break;
664  case BuiltinType::SChar:
665  c = 'r'; break;
666  case BuiltinType::WChar_S:
667  case BuiltinType::WChar_U:
668  c = 'W'; break;
669  case BuiltinType::Short:
670  c = 'S'; break;
671  case BuiltinType::Int:
672  c = 'I'; break;
673  case BuiltinType::Long:
674  c = 'L'; break;
675  case BuiltinType::LongLong:
676  c = 'K'; break;
677  case BuiltinType::Int128:
678  c = 'J'; break;
679  case BuiltinType::Half:
680  c = 'h'; break;
681  case BuiltinType::Float:
682  c = 'f'; break;
683  case BuiltinType::Double:
684  c = 'd'; break;
685  case BuiltinType::LongDouble:
686  c = 'D'; break;
687  case BuiltinType::Float128:
688  c = 'Q'; break;
689  case BuiltinType::NullPtr:
690  c = 'n'; break;
691 #define BUILTIN_TYPE(Id, SingletonId)
692 #define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
693 #include "clang/AST/BuiltinTypes.def"
694  case BuiltinType::Dependent:
695 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
696  case BuiltinType::Id:
697 #include "clang/Basic/OpenCLImageTypes.def"
698  case BuiltinType::OCLEvent:
699  case BuiltinType::OCLClkEvent:
700  case BuiltinType::OCLQueue:
701  case BuiltinType::OCLReserveID:
702  case BuiltinType::OCLSampler:
703  IgnoreResults = true;
704  return;
705  case BuiltinType::ObjCId:
706  c = 'o'; break;
707  case BuiltinType::ObjCClass:
708  c = 'O'; break;
709  case BuiltinType::ObjCSel:
710  c = 'e'; break;
711  }
712  Out << c;
713  return;
714  }
715 
716  // If we have already seen this (non-built-in) type, use a substitution
717  // encoding.
718  llvm::DenseMap<const Type *, unsigned>::iterator Substitution
719  = TypeSubstitutions.find(T.getTypePtr());
720  if (Substitution != TypeSubstitutions.end()) {
721  Out << 'S' << Substitution->second << '_';
722  return;
723  } else {
724  // Record this as a substitution.
725  unsigned Number = TypeSubstitutions.size();
726  TypeSubstitutions[T.getTypePtr()] = Number;
727  }
728 
729  if (const PointerType *PT = T->getAs<PointerType>()) {
730  Out << '*';
731  T = PT->getPointeeType();
732  continue;
733  }
734  if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
735  Out << '*';
736  T = OPT->getPointeeType();
737  continue;
738  }
739  if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
740  Out << "&&";
741  T = RT->getPointeeType();
742  continue;
743  }
744  if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
745  Out << '&';
746  T = RT->getPointeeType();
747  continue;
748  }
749  if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
750  Out << 'F';
751  VisitType(FT->getReturnType());
752  for (const auto &I : FT->param_types())
753  VisitType(I);
754  if (FT->isVariadic())
755  Out << '.';
756  return;
757  }
758  if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
759  Out << 'B';
760  T = BT->getPointeeType();
761  continue;
762  }
763  if (const ComplexType *CT = T->getAs<ComplexType>()) {
764  Out << '<';
765  T = CT->getElementType();
766  continue;
767  }
768  if (const TagType *TT = T->getAs<TagType>()) {
769  Out << '$';
770  VisitTagDecl(TT->getDecl());
771  return;
772  }
773  if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
774  Out << '$';
775  VisitObjCInterfaceDecl(OIT->getDecl());
776  return;
777  }
778  if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
779  Out << 'Q';
780  VisitType(OIT->getBaseType());
781  for (auto *Prot : OIT->getProtocols())
782  VisitObjCProtocolDecl(Prot);
783  return;
784  }
785  if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
786  Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
787  return;
788  }
789  if (const TemplateSpecializationType *Spec
790  = T->getAs<TemplateSpecializationType>()) {
791  Out << '>';
792  VisitTemplateName(Spec->getTemplateName());
793  Out << Spec->getNumArgs();
794  for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
795  VisitTemplateArgument(Spec->getArg(I));
796  return;
797  }
798  if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
799  Out << '^';
800  // FIXME: Encode the qualifier, don't just print it.
801  PrintingPolicy PO(Ctx.getLangOpts());
802  PO.SuppressTagKeyword = true;
803  PO.SuppressUnwrittenScope = true;
804  PO.ConstantArraySizeAsWritten = false;
805  PO.AnonymousTagLocations = false;
806  DNT->getQualifier()->print(Out, PO);
807  Out << ':' << DNT->getIdentifier()->getName();
808  return;
809  }
810  if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) {
811  T = InjT->getInjectedSpecializationType();
812  continue;
813  }
814  if (const auto *VT = T->getAs<VectorType>()) {
815  Out << (T->isExtVectorType() ? ']' : '[');
816  Out << VT->getNumElements();
817  T = VT->getElementType();
818  continue;
819  }
820 
821  // Unhandled type.
822  Out << ' ';
823  break;
824  } while (true);
825 }
826 
827 void USRGenerator::VisitTemplateParameterList(
828  const TemplateParameterList *Params) {
829  if (!Params)
830  return;
831  Out << '>' << Params->size();
832  for (TemplateParameterList::const_iterator P = Params->begin(),
833  PEnd = Params->end();
834  P != PEnd; ++P) {
835  Out << '#';
836  if (isa<TemplateTypeParmDecl>(*P)) {
837  if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
838  Out<< 'p';
839  Out << 'T';
840  continue;
841  }
842 
843  if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
844  if (NTTP->isParameterPack())
845  Out << 'p';
846  Out << 'N';
847  VisitType(NTTP->getType());
848  continue;
849  }
850 
851  TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
852  if (TTP->isParameterPack())
853  Out << 'p';
854  Out << 't';
855  VisitTemplateParameterList(TTP->getTemplateParameters());
856  }
857 }
858 
859 void USRGenerator::VisitTemplateName(TemplateName Name) {
860  if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
861  if (TemplateTemplateParmDecl *TTP
862  = dyn_cast<TemplateTemplateParmDecl>(Template)) {
863  Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
864  return;
865  }
866 
867  Visit(Template);
868  return;
869  }
870 
871  // FIXME: Visit dependent template names.
872 }
873 
874 void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
875  switch (Arg.getKind()) {
876  case TemplateArgument::Null:
877  break;
878 
879  case TemplateArgument::Declaration:
880  Visit(Arg.getAsDecl());
881  break;
882 
883  case TemplateArgument::NullPtr:
884  break;
885 
886  case TemplateArgument::TemplateExpansion:
887  Out << 'P'; // pack expansion of...
888  // Fall through
889  case TemplateArgument::Template:
890  VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
891  break;
892 
893  case TemplateArgument::Expression:
894  // FIXME: Visit expressions.
895  break;
896 
897  case TemplateArgument::Pack:
898  Out << 'p' << Arg.pack_size();
899  for (const auto &P : Arg.pack_elements())
900  VisitTemplateArgument(P);
901  break;
902 
903  case TemplateArgument::Type:
904  VisitType(Arg.getAsType());
905  break;
906 
907  case TemplateArgument::Integral:
908  Out << 'V';
909  VisitType(Arg.getIntegralType());
910  Out << Arg.getAsIntegral();
911  break;
912  }
913 }
914 
915 //===----------------------------------------------------------------------===//
916 // USR generation functions.
917 //===----------------------------------------------------------------------===//
918 
919 static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
920  StringRef CatSymDefinedIn,
921  raw_ostream &OS) {
922  if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
923  return;
924  if (CatSymDefinedIn.empty()) {
925  OS << "@M@" << ClsSymDefinedIn << '@';
926  return;
927  }
928  OS << "@CM@" << CatSymDefinedIn << '@';
929  if (ClsSymDefinedIn != CatSymDefinedIn) {
930  OS << ClsSymDefinedIn << '@';
931  }
932 }
933 
934 void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
935  StringRef ExtSymDefinedIn,
936  StringRef CategoryContextExtSymbolDefinedIn) {
937  combineClassAndCategoryExtContainers(ExtSymDefinedIn,
938  CategoryContextExtSymbolDefinedIn, OS);
939  OS << "objc(cs)" << Cls;
940 }
941 
942 void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
943  raw_ostream &OS,
944  StringRef ClsSymDefinedIn,
945  StringRef CatSymDefinedIn) {
946  combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
947  OS << "objc(cy)" << Cls << '@' << Cat;
948 }
949 
950 void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
951  OS << '@' << Ivar;
952 }
953 
954 void clang::index::generateUSRForObjCMethod(StringRef Sel,
955  bool IsInstanceMethod,
956  raw_ostream &OS) {
957  OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
958 }
959 
960 void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
961  raw_ostream &OS) {
962  OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
963 }
964 
965 void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
966  StringRef ExtSymDefinedIn) {
967  if (!ExtSymDefinedIn.empty())
968  OS << "@M@" << ExtSymDefinedIn << '@';
969  OS << "objc(pl)" << Prot;
970 }
971 
972 void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
973  StringRef ExtSymDefinedIn) {
974  if (!ExtSymDefinedIn.empty())
975  OS << "@M@" << ExtSymDefinedIn;
976  OS << "@E@" << EnumName;
977 }
978 
979 void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
980  raw_ostream &OS) {
981  OS << '@' << EnumConstantName;
982 }
983 
984 bool clang::index::generateUSRForDecl(const Decl *D,
985  SmallVectorImpl<char> &Buf) {
986  if (!D)
987  return true;
988  // We don't ignore decls with invalid source locations. Implicit decls, like
989  // C++'s operator new function, can have invalid locations but it is fine to
990  // create USRs that can identify them.
991 
992  USRGenerator UG(&D->getASTContext(), Buf);
993  UG.Visit(D);
994  return UG.ignoreResults();
995 }
996 
998  const SourceManager &SM,
999  SmallVectorImpl<char> &Buf) {
1000  if (!MD)
1001  return true;
1002  return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1003  SM, Buf);
1004 
1005 }
1006 
1008  const SourceManager &SM,
1009  SmallVectorImpl<char> &Buf) {
1010  // Don't generate USRs for things with invalid locations.
1011  if (MacroName.empty() || Loc.isInvalid())
1012  return true;
1013 
1014  llvm::raw_svector_ostream Out(Buf);
1015 
1016  // Assume that system headers are sane. Don't put source location
1017  // information into the USR if the macro comes from a system header.
1018  bool ShouldGenerateLocation = !SM.isInSystemHeader(Loc);
1019 
1020  Out << getUSRSpacePrefix();
1021  if (ShouldGenerateLocation)
1022  printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1023  Out << "@macro@";
1024  Out << MacroName;
1025  return false;
1026 }
Defines the clang::ASTContext interface.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
Definition: Decl.h:1618
StringRef getName() const
getName - Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:237
bool generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl< char > &Buf)
Generate a USR for a macro, including the USR prefix.
A (possibly-)qualified type.
Definition: Type.h:616
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2232
void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS, StringRef ClsExtSymbolDefinedIn="", StringRef CatExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C class category.
bool isClassProperty() const
Definition: DeclObjC.h:836
TypedefDecl - Represents the declaration of a typedef-name via the 'typedef' type specifier...
Definition: Decl.h:2770
const DeclContext * getParentFunctionOrMethod() const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext...
Definition: DeclBase.cpp:222
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:81
Defines the C++ template declaration subclasses.
StringRef P
Declaration of a variable template.
NamespaceDecl - Represent a C++ namespace.
Definition: Decl.h:461
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS, StringRef ExtSymbolDefinedIn="", StringRef CategoryContextExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C class.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
Definition: Decl.h:758
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
Definition: DeclBase.cpp:420
The "union" keyword.
Definition: Type.h:4494
The "__interface" keyword.
Definition: Type.h:4492
Represents a variable template specialization, which refers to a variable template with a given set o...
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:113
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:50
Describes how types, statements, expressions, and declarations should be printed. ...
Definition: PrettyPrinter.h:38
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition: Decl.cpp:2754
Represents a class template specialization, which refers to a class template with a given set of temp...
bool hasAttr() const
Definition: DeclBase.h:521
static StringRef getUSRSpacePrefix()
Definition: USRGeneration.h:24
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition: Decl.cpp:3314
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:128
Record the location of a macro definition.
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, const SourceManager &SM, bool IncludeOffset)
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
Definition: Decl.h:2366
void print(raw_ostream &OS, const PrintingPolicy &Policy)
TagKind getTagKind() const
Definition: Decl.h:3019
bool IsClassExtension() const
Definition: DeclObjC.h:2292
Represents a C++ using-declaration.
Definition: DeclCXX.h:3183
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:919
const LangOptions & getLangOpts() const
Definition: ASTContext.h:659
virtual void printName(raw_ostream &os) const
Definition: Decl.cpp:1447
StringRef getName() const
Definition: FileManager.h:84
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:1985
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:3193
Represents an ObjC class declaration.
Definition: DeclObjC.h:1108
Represents a linkage specification.
Definition: DeclCXX.h:2666
detail::InMemoryDirectory::const_iterator I
bool isInvalid() const
unsigned SuppressTemplateArgsInCXXConstructors
When true, suppresses printing template arguments in names of C++ constructors.
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2645
const FileEntry * getFileEntryForID(FileID FID) const
Returns the FileEntry record for the provided FileID.
ASTContext * Context
VarTemplateDecl * getDescribedVarTemplate() const
Retrieves the variable template that is described by this variable declaration.
Definition: Decl.cpp:2383
StringRef getName() const
Return the actual identifier string.
Declaration of a template type parameter.
Kind getKind() const
Definition: DeclBase.h:410
DeclContext * getDeclContext()
Definition: DeclBase.h:416
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
Represents a C++ template name within the type system.
Definition: TemplateName.h:176
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isExternallyVisible() const
Definition: Decl.h:338
Represents a GCC generic vector type.
Definition: Type.h:2797
DeclarationName getDeclName() const
getDeclName - Get the actual, stored name of the declaration, which may be a special name...
Definition: Decl.h:258
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
do v
Definition: arm_acle.h:78
const SourceManager & SM
Definition: Format.cpp:1293
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3050
static StringRef GetExternalSourceContainer(const NamedDecl *D)
bool isEmbeddedInDeclarator() const
Definition: Decl.h:2975
#define false
Definition: stdbool.h:33
The "struct" keyword.
Definition: Type.h:4490
Encodes a location in the source.
const std::string ID
TagDecl - Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:2816
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:346
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:3664
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3400
Cached information about one file (either on disk or in the virtual file system). ...
Definition: FileManager.h:59
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2189
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2341
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:704
bool SuppressTagKeyword
Whether type printing should skip printing the tag keyword.
Definition: PrettyPrinter.h:92
const IdentifierInfo * getName() const
Retrieve the name of the macro being defined.
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:4437
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:2682
Represents a template argument.
Definition: TemplateBase.h:40
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1215
StringRef Name
Definition: USRFinder.cpp:123
bool isFreeStanding() const
Definition: Decl.h:2982
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3497
DeclarationName - The name of a declaration.
void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS, StringRef ExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C protocol.
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:6042
The "class" keyword.
Definition: Type.h:4496
SourceManager & getSourceManager()
Definition: ASTContext.h:616
A template argument list.
Definition: DeclTemplate.h:195
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2702
Represents a C++ struct/union/class.
Definition: DeclCXX.h:267
void generateUSRForObjCProperty(StringRef Prop, bool isClassProp, raw_ostream &OS)
Generate a USR fragment for an Objective-C property.
The "enum" keyword.
Definition: Type.h:4498
Declaration of a class template.
SourceLocation getLocation() const
Retrieve the location of the macro name in the definition.
const ObjCInterfaceDecl * getObjContainingInterface(const NamedDecl *ND) const
Returns the Objective-C interface that ND belongs to if it is an Objective-C method/property/ivar etc...
SourceLocation getLocation() const
Definition: DeclBase.h:407
NamedDecl - This represents a decl with a name.
Definition: Decl.h:213
SourceLocation getExpansionLoc(SourceLocation Loc) const
Given a SourceLocation object Loc, return the expansion location referenced by the ID...
Represents a C++ namespace alias.
Definition: DeclCXX.h:2861
std::pair< FileID, unsigned > getDecomposedLoc(SourceLocation Loc) const
Decompose the specified location into a raw FileID + Offset pair.
Represents C++ using-directive.
Definition: DeclCXX.h:2758
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:74
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration...
Definition: DeclObjC.h:2396
This class handles loading and caching of source files into memory.
Declaration of a template function.
Definition: DeclTemplate.h:939