clang: lib/Index/USRGeneration.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
17#include "llvm/Support/Path.h"
18#include "llvm/Support/raw_ostream.h"
19
20using namespace clang;
22
23
24
25
26
27
31 return true;
32 }
33 Loc = SM.getExpansionLoc(Loc);
36 if (FE) {
37 OS << llvm::sys::path::filename(FE->getName());
38 } else {
39
40 return true;
41 }
42 if (IncludeOffset) {
43
44
45
46 OS << '@' << Decomposed.second;
47 }
48 return false;
49}
50
52 if (!D)
53 return StringRef();
55 return attr->getDefinedIn();
56 }
57 return StringRef();
58}
59
60namespace {
62 SmallVectorImpl &Buf;
63 llvm::raw_svector_ostream Out;
64 ASTContext *Context;
65 const LangOptions &LangOpts;
66 bool IgnoreResults = false;
67 bool generatedLoc = false;
68
69 llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
70
71public:
72 USRGenerator(ASTContext *Ctx, SmallVectorImpl &Buf,
73 const LangOptions &LangOpts)
74 : Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) {
75
77 }
78
79 bool ignoreResults() const { return IgnoreResults; }
80
81
82 void VisitDeclContext(const DeclContext *D);
83 void VisitFieldDecl(const FieldDecl *D);
84 void VisitFunctionDecl(const FunctionDecl *D);
85 void VisitNamedDecl(const NamedDecl *D);
86 void VisitNamespaceDecl(const NamespaceDecl *D);
87 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
88 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
89 void VisitClassTemplateDecl(const ClassTemplateDecl *D);
90 void VisitObjCContainerDecl(const ObjCContainerDecl *CD,
91 const ObjCCategoryDecl *CatD = nullptr);
92 void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
93 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
94 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
95 void VisitTagDecl(const TagDecl *D);
96 void VisitTypedefDecl(const TypedefDecl *D);
97 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
98 void VisitVarDecl(const VarDecl *D);
99 void VisitBindingDecl(const BindingDecl *D);
100 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
101 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
102 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
103 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
104 void VisitConceptDecl(const ConceptDecl *D);
105
106 void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
107 IgnoreResults = true;
108 }
109
110 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
111 IgnoreResults = true;
112 }
113
114 void VisitUsingDecl(const UsingDecl *D) {
116 Out << "@UD@";
117
118 bool EmittedDeclName = !EmitDeclName(D);
119 assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls");
120 (void)EmittedDeclName;
121 }
122
123 bool ShouldGenerateLocation(const NamedDecl *D);
124
125 bool isLocal(const NamedDecl *D) {
127 }
128
129 void GenExtSymbolContainer(const NamedDecl *D);
130
131
132
133 bool GenLoc(const Decl *D, bool IncludeOffset);
134
135
136
137
138
139
140
141
142 void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
143 StringRef CategoryContextExtSymbolDefinedIn) {
145 CategoryContextExtSymbolDefinedIn);
146 }
147
148
149 void GenObjCCategory(StringRef cls, StringRef cat,
150 StringRef clsExt, StringRef catExt) {
152 }
153
154
155 void GenObjCProperty(StringRef prop, bool isClassProp) {
157 }
158
159
160 void GenObjCProtocol(StringRef prot, StringRef ext) {
162 }
163
164 void VisitType(QualType T);
165 void VisitTemplateParameterList(const TemplateParameterList *Params);
167 void VisitTemplateArgument(const TemplateArgument &Arg);
168
169 void VisitMSGuidDecl(const MSGuidDecl *D);
170
171
172
173 bool EmitDeclName(const NamedDecl *D);
174};
175}
176
177
178
179
180
181bool USRGenerator::EmitDeclName(const NamedDecl *D) {
184 return true;
185 Out << N;
186 return false;
187}
188
189bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
191 return false;
193 return true;
196 return false;
199}
200
201void USRGenerator::VisitDeclContext(const DeclContext *DC) {
202 if (const NamedDecl *D = dyn_cast(DC))
203 Visit(D);
205 VisitDeclContext(DC->getParent());
206}
207
208void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
209
210
212 Visit(ID);
213 else
215 Out << (isa(D) ? "@" : "@FI@");
216 if (EmitDeclName(D)) {
217
218 IgnoreResults = true;
219 return;
220 }
221}
222
223void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
224 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
225 return;
226
228 IgnoreResults = true;
229 return;
230 }
231
232 const unsigned StartSize = Buf.size();
234 if (Buf.size() == StartSize)
235 GenExtSymbolContainer(D);
236
237 bool IsTemplate = false;
239 IsTemplate = true;
240 Out << "@FT@";
241 VisitTemplateParameterList(FunTmpl->getTemplateParameters());
242 } else
243 Out << "@F@";
244
245 PrintingPolicy Policy(LangOpts);
246
247
248 Policy.SuppressTemplateArgsInCXXConstructors = true;
250
251 if ((!LangOpts.CPlusPlus || D->isExternC()) &&
252 !D->hasAttr())
253 return;
254
256 Out << '<';
257 if (const TemplateArgumentList *SpecArgs =
259 for (const auto &Arg : SpecArgs->asArray()) {
260 Out << '#';
261 VisitTemplateArgument(Arg);
262 }
263 } else if (const ASTTemplateArgumentListInfo *SpecArgsWritten =
265 for (const auto &ArgLoc : SpecArgsWritten->arguments()) {
266 Out << '#';
267 VisitTemplateArgument(ArgLoc.getArgument());
268 }
269 }
270 Out << '>';
271 }
272
274
275 if (const auto *FPT = CanonicalType->getAs()) {
276 for (QualType PT : FPT->param_types()) {
277 Out << '#';
278 VisitType(PT);
279 }
280 }
282 Out << '.';
283 if (IsTemplate) {
284
285
286
287
288
289 Out << '#';
291 }
292 Out << '#';
293 if (const CXXMethodDecl *MD = dyn_cast(D)) {
294 if (MD->isStatic())
295 Out << 'S';
296
297 if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
298 Out << (char)('0' + quals);
299 switch (MD->getRefQualifier()) {
301 case RQ_LValue: Out << '&'; break;
302 case RQ_RValue: Out << "&&"; break;
303 }
304 }
305}
306
307void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
309 Out << "@";
310
311 if (EmitDeclName(D)) {
312
313
314
315
316 IgnoreResults = true;
317 }
318}
319
320void USRGenerator::VisitVarDecl(const VarDecl *D) {
321
322
323
324 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
325 return;
326
328
330 Out << "@VT";
331 VisitTemplateParameterList(VarTmpl->getTemplateParameters());
332 } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
333 = dyn_cast(D)) {
334 Out << "@VP";
335 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
336 }
337
338
340
341
342
343
344
345 if (s.empty())
346 IgnoreResults = true;
347 else
348 Out << '@' << s;
349
350
351 if (const VarTemplateSpecializationDecl *Spec
352 = dyn_cast(D)) {
353 const TemplateArgumentList &Args = Spec->getTemplateArgs();
354 Out << '>';
355 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
356 Out << '#';
357 VisitTemplateArgument(Args.get(I));
358 }
359 }
360}
361
362void USRGenerator::VisitBindingDecl(const BindingDecl *D) {
363 if (isLocal(D) && GenLoc(D, true))
364 return;
365 VisitNamedDecl(D);
366}
367
368void USRGenerator::VisitNonTypeTemplateParmDecl(
369 const NonTypeTemplateParmDecl *D) {
370 GenLoc(D, true);
371}
372
373void USRGenerator::VisitTemplateTemplateParmDecl(
374 const TemplateTemplateParmDecl *D) {
375 GenLoc(D, true);
376}
377
378void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
379 if (IgnoreResults)
380 return;
383 Out << "@aN";
384 return;
385 }
386 Out << "@N@" << D->getName();
387}
388
389void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
391}
392
393void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
395}
396
397void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
399 if (!IgnoreResults)
400 Out << "@NA@" << D->getName();
401}
402
404 if (auto *CD = dyn_cast(D->getDeclContext()))
405 return CD;
406 if (auto *ICD = dyn_cast(D->getDeclContext()))
407 return ICD->getCategoryDecl();
408 return nullptr;
409}
410
411void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
413 if (const ObjCProtocolDecl *pd = dyn_cast(container)) {
414 Visit(pd);
415 }
416 else {
417
418
420 if (!ID) {
421 IgnoreResults = true;
422 return;
423 }
425 VisitObjCContainerDecl(ID, CD);
426 }
427
428
429
432}
433
434void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
435 const ObjCCategoryDecl *CatD) {
437 default:
438 llvm_unreachable("Invalid ObjC container.");
439 case Decl::ObjCInterface:
440 case Decl::ObjCImplementation:
443 break;
444 case Decl::ObjCCategory: {
447 if (!ID) {
448
449
450
451
452 IgnoreResults = true;
453 return;
454 }
455
456
458 Out << "objc(ext)" << ID->getName() << '@';
459 GenLoc(CD, true);
460 }
461 else
462 GenObjCCategory(ID->getName(), CD->getName(),
465
466 break;
467 }
468 case Decl::ObjCCategoryImpl: {
471 if (!ID) {
472
473
474
475
476 IgnoreResults = true;
477 return;
478 }
479 GenObjCCategory(ID->getName(), CD->getName(),
482 break;
483 }
484 case Decl::ObjCProtocol: {
487 break;
488 }
489 }
490}
491
492void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
493
494
497 else
500}
501
502void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
504 VisitObjCPropertyDecl(PD);
505 return;
506 }
507
508 IgnoreResults = true;
509}
510
511void USRGenerator::VisitTagDecl(const TagDecl *D) {
512
513
515 ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
516 return;
517
518 GenExtSymbolContainer(D);
519
522
523 bool AlreadyStarted = false;
524 if (const CXXRecordDecl *CXXRecord = dyn_cast(D)) {
525 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
526 AlreadyStarted = true;
527
529 case TagTypeKind::Interface:
530 case TagTypeKind::Class:
531 case TagTypeKind::Struct:
532 Out << "@ST";
533 break;
534 case TagTypeKind::Union:
535 Out << "@UT";
536 break;
537 case TagTypeKind::Enum:
538 llvm_unreachable("enum template");
539 }
540 VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
541 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
542 = dyn_cast(CXXRecord)) {
543 AlreadyStarted = true;
544
546 case TagTypeKind::Interface:
547 case TagTypeKind::Class:
548 case TagTypeKind::Struct:
549 Out << "@SP";
550 break;
551 case TagTypeKind::Union:
552 Out << "@UP";
553 break;
554 case TagTypeKind::Enum:
555 llvm_unreachable("enum partial specialization");
556 }
557 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
558 }
559 }
560
561 if (!AlreadyStarted) {
563 case TagTypeKind::Interface:
564 case TagTypeKind::Class:
565 case TagTypeKind::Struct:
566 Out << "@S";
567 break;
568 case TagTypeKind::Union:
569 Out << "@U";
570 break;
571 case TagTypeKind::Enum:
572 Out << "@E";
573 break;
574 }
575 }
576
577 Out << '@';
578 assert(Buf.size() > 0);
579 const unsigned off = Buf.size() - 1;
580
581 if (EmitDeclName(D)) {
583 Buf[off] = 'A';
584 Out << '@' << *TD;
585 } else {
588 } else {
589 Buf[off] = 'a';
590 if (auto *ED = dyn_cast(D)) {
591
592
593 auto enum_range = ED->enumerators();
594 if (enum_range.begin() != enum_range.end()) {
595 Out << '@' << **enum_range.begin();
596 }
597 }
598 }
599 }
600 }
601
602
603 if (const ClassTemplateSpecializationDecl *Spec
604 = dyn_cast(D)) {
605 const TemplateArgumentList &Args = Spec->getTemplateArgs();
606 Out << '>';
607 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
608 Out << '#';
609 VisitTemplateArgument(Args.get(I));
610 }
611 }
612}
613
614void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
615 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
616 return;
618 if (const NamedDecl *DCN = dyn_cast(DC))
619 Visit(DCN);
620 Out << "@T@";
622}
623
624void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
625 GenLoc(D, true);
626}
627
628void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
630 if (!Container.empty())
631 Out << "@M@" << Container;
632}
633
634bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
635 if (generatedLoc)
636 return IgnoreResults;
637 generatedLoc = true;
638
639
640 if (!D) {
641 IgnoreResults = true;
642 return true;
643 }
644
645
647
648 IgnoreResults =
651
652 return IgnoreResults;
653}
654
657
663 NNS.print(Out, PO);
664}
665
666void USRGenerator::VisitType(QualType T) {
667
668
669
670 ASTContext &Ctx = *Context;
671
672 do {
674 Qualifiers Q = T.getQualifiers();
675 unsigned qVal = 0;
677 qVal |= 0x1;
679 qVal |= 0x2;
681 qVal |= 0x4;
682 if(qVal)
683 Out << ((char) ('0' + qVal));
684
685
686
687 if (const PackExpansionType *Expansion = T->getAs()) {
688 Out << 'P';
689 T = Expansion->getPattern();
690 }
691
692 if (const BuiltinType *BT = T->getAs()) {
693 switch (BT->getKind()) {
694 case BuiltinType::Void:
695 Out << 'v'; break;
696 case BuiltinType::Bool:
697 Out << 'b'; break;
698 case BuiltinType::UChar:
699 Out << 'c'; break;
700 case BuiltinType::Char8:
701 Out << 'u'; break;
702 case BuiltinType::Char16:
703 Out << 'q'; break;
704 case BuiltinType::Char32:
705 Out << 'w'; break;
706 case BuiltinType::UShort:
707 Out << 's'; break;
708 case BuiltinType::UInt:
709 Out << 'i'; break;
710 case BuiltinType::ULong:
711 Out << 'l'; break;
712 case BuiltinType::ULongLong:
713 Out << 'k'; break;
714 case BuiltinType::UInt128:
715 Out << 'j'; break;
716 case BuiltinType::Char_U:
717 case BuiltinType::Char_S:
718 Out << 'C'; break;
719 case BuiltinType::SChar:
720 Out << 'r'; break;
721 case BuiltinType::WChar_S:
722 case BuiltinType::WChar_U:
723 Out << 'W'; break;
724 case BuiltinType::Short:
725 Out << 'S'; break;
726 case BuiltinType::Int:
727 Out << 'I'; break;
728 case BuiltinType::Long:
729 Out << 'L'; break;
730 case BuiltinType::LongLong:
731 Out << 'K'; break;
732 case BuiltinType::Int128:
733 Out << 'J'; break;
734 case BuiltinType::Float16:
735 case BuiltinType::Half:
736 Out << 'h'; break;
737 case BuiltinType::Float:
738 Out << 'f'; break;
739 case BuiltinType::Double:
740 Out << 'd'; break;
741 case BuiltinType::LongDouble:
742 Out << 'D'; break;
743 case BuiltinType::Float128:
744 Out << 'Q'; break;
745 case BuiltinType::NullPtr:
746 Out << 'n'; break;
747#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
748 case BuiltinType::Id: \
749 Out << "@BT@" << #Suffix << "_" << #ImgType; break;
750#include "clang/Basic/OpenCLImageTypes.def"
751#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
752 case BuiltinType::Id: \
753 Out << "@BT@" << #ExtType; break;
754#include "clang/Basic/OpenCLExtensionTypes.def"
755 case BuiltinType::OCLEvent:
756 Out << "@BT@OCLEvent"; break;
757 case BuiltinType::OCLClkEvent:
758 Out << "@BT@OCLClkEvent"; break;
759 case BuiltinType::OCLQueue:
760 Out << "@BT@OCLQueue"; break;
761 case BuiltinType::OCLReserveID:
762 Out << "@BT@OCLReserveID"; break;
763 case BuiltinType::OCLSampler:
764 Out << "@BT@OCLSampler"; break;
765#define SVE_TYPE(Name, Id, SingletonId) \
766 case BuiltinType::Id: \
767 Out << "@BT@" << #Name; \
768 break;
769#include "clang/Basic/AArch64ACLETypes.def"
770#define PPC_VECTOR_TYPE(Name, Id, Size) \
771 case BuiltinType::Id: \
772 Out << "@BT@" << #Name; break;
773#include "clang/Basic/PPCTypes.def"
774#define RVV_TYPE(Name, Id, SingletonId) \
775 case BuiltinType::Id: \
776 Out << "@BT@" << Name; break;
777#include "clang/Basic/RISCVVTypes.def"
778#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
779#include "clang/Basic/WebAssemblyReferenceTypes.def"
780#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) \
781 case BuiltinType::Id: \
782 Out << "@BT@" << #Name; \
783 break;
784#include "clang/Basic/AMDGPUTypes.def"
785#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
786 case BuiltinType::Id: \
787 Out << "@BT@" << #Name; \
788 break;
789#include "clang/Basic/HLSLIntangibleTypes.def"
790 case BuiltinType::ShortAccum:
791 Out << "@BT@ShortAccum"; break;
792 case BuiltinType::Accum:
793 Out << "@BT@Accum"; break;
794 case BuiltinType::LongAccum:
795 Out << "@BT@LongAccum"; break;
796 case BuiltinType::UShortAccum:
797 Out << "@BT@UShortAccum"; break;
798 case BuiltinType::UAccum:
799 Out << "@BT@UAccum"; break;
800 case BuiltinType::ULongAccum:
801 Out << "@BT@ULongAccum"; break;
802 case BuiltinType::ShortFract:
803 Out << "@BT@ShortFract"; break;
804 case BuiltinType::Fract:
805 Out << "@BT@Fract"; break;
806 case BuiltinType::LongFract:
807 Out << "@BT@LongFract"; break;
808 case BuiltinType::UShortFract:
809 Out << "@BT@UShortFract"; break;
810 case BuiltinType::UFract:
811 Out << "@BT@UFract"; break;
812 case BuiltinType::ULongFract:
813 Out << "@BT@ULongFract"; break;
814 case BuiltinType::SatShortAccum:
815 Out << "@BT@SatShortAccum"; break;
816 case BuiltinType::SatAccum:
817 Out << "@BT@SatAccum"; break;
818 case BuiltinType::SatLongAccum:
819 Out << "@BT@SatLongAccum"; break;
820 case BuiltinType::SatUShortAccum:
821 Out << "@BT@SatUShortAccum"; break;
822 case BuiltinType::SatUAccum:
823 Out << "@BT@SatUAccum"; break;
824 case BuiltinType::SatULongAccum:
825 Out << "@BT@SatULongAccum"; break;
826 case BuiltinType::SatShortFract:
827 Out << "@BT@SatShortFract"; break;
828 case BuiltinType::SatFract:
829 Out << "@BT@SatFract"; break;
830 case BuiltinType::SatLongFract:
831 Out << "@BT@SatLongFract"; break;
832 case BuiltinType::SatUShortFract:
833 Out << "@BT@SatUShortFract"; break;
834 case BuiltinType::SatUFract:
835 Out << "@BT@SatUFract"; break;
836 case BuiltinType::SatULongFract:
837 Out << "@BT@SatULongFract"; break;
838 case BuiltinType::BFloat16:
839 Out << "@BT@__bf16"; break;
840 case BuiltinType::Ibm128:
841 Out << "@BT@__ibm128"; break;
842 case BuiltinType::ObjCId:
843 Out << 'o'; break;
844 case BuiltinType::ObjCClass:
845 Out << 'O'; break;
846 case BuiltinType::ObjCSel:
847 Out << 'e'; break;
848#define BUILTIN_TYPE(Id, SingletonId)
849#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
850#include "clang/AST/BuiltinTypes.def"
851 case BuiltinType::Dependent:
852
853
854 IgnoreResults = true;
855 break;
856 }
857 return;
858 }
859
860
861
862 auto [Substitution, Inserted] =
863 TypeSubstitutions.try_emplace(T.getTypePtr(), TypeSubstitutions.size());
864 if (!Inserted) {
865 Out << 'S' << Substitution->second << '_';
866 return;
867 }
868
869 if (const PointerType *PT = T->getAs()) {
870 Out << '*';
872 continue;
873 }
874 if (const ObjCObjectPointerType *OPT = T->getAs()) {
875 Out << '*';
877 continue;
878 }
879 if (const RValueReferenceType *RT = T->getAs()) {
880 Out << "&&";
882 continue;
883 }
884 if (const ReferenceType *RT = T->getAs()) {
885 Out << '&';
887 continue;
888 }
889 if (const FunctionProtoType *FT = T->getAs()) {
890 Out << 'F';
891 VisitType(FT->getReturnType());
892 Out << '(';
893 for (const auto &I : FT->param_types()) {
894 Out << '#';
895 VisitType(I);
896 }
897 Out << ')';
898 if (FT->isVariadic())
899 Out << '.';
900 return;
901 }
902 if (const BlockPointerType *BT = T->getAs()) {
903 Out << 'B';
905 continue;
906 }
907 if (const ComplexType *CT = T->getAs()) {
908 Out << '<';
909 T = CT->getElementType();
910 continue;
911 }
912 if (const TagType *TT = T->getAs()) {
913 if (const auto *ICNT = dyn_cast(TT)) {
914 T = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Ctx);
915 } else {
916 Out << '$';
917 VisitTagDecl(TT->getDecl());
918 return;
919 }
920 }
921 if (const ObjCInterfaceType *OIT = T->getAs()) {
922 Out << '$';
923 VisitObjCInterfaceDecl(OIT->getDecl());
924 return;
925 }
926 if (const ObjCObjectType *OIT = T->getAs()) {
927 Out << 'Q';
928 VisitType(OIT->getBaseType());
929 for (auto *Prot : OIT->getProtocols())
930 VisitObjCProtocolDecl(Prot);
931 return;
932 }
933 if (const TemplateTypeParmType *TTP =
935 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
936 return;
937 }
938 if (const TemplateSpecializationType *Spec
940 Out << '>';
941 VisitTemplateName(Spec->getTemplateName());
942 Out << Spec->template_arguments().size();
943 for (const auto &Arg : Spec->template_arguments())
944 VisitTemplateArgument(Arg);
945 return;
946 }
947 if (const DependentNameType *DNT = T->getAs()) {
948 Out << '^';
950 Out << ':' << DNT->getIdentifier()->getName();
951 return;
952 }
953 if (const auto *VT = T->getAs()) {
955 Out << VT->getNumElements();
956 T = VT->getElementType();
957 continue;
958 }
959 if (const auto *const AT = dyn_cast(T)) {
960 Out << '{';
961 switch (AT->getSizeModifier()) {
962 case ArraySizeModifier::Static:
963 Out << 's';
964 break;
965 case ArraySizeModifier::Star:
966 Out << '*';
967 break;
968 case ArraySizeModifier::Normal:
969 Out << 'n';
970 break;
971 }
972 if (const auto *const CAT = dyn_cast(T))
973 Out << CAT->getSize();
974
975 T = AT->getElementType();
976 continue;
977 }
978
979
980 Out << ' ';
981 break;
982 } while (true);
983}
984
985void USRGenerator::VisitTemplateParameterList(
986 const TemplateParameterList *Params) {
987 if (!Params)
988 return;
989 Out << '>' << Params->size();
990 for (TemplateParameterList::const_iterator P = Params->begin(),
991 PEnd = Params->end();
992 P != PEnd; ++P) {
993 Out << '#';
996 Out<< 'p';
997 Out << 'T';
998 continue;
999 }
1000
1001 if (NonTypeTemplateParmDecl *NTTP = dyn_cast(*P)) {
1002 if (NTTP->isParameterPack())
1003 Out << 'p';
1004 Out << 'N';
1005 VisitType(NTTP->getType());
1006 continue;
1007 }
1008
1011 Out << 'p';
1012 Out << 't';
1014 }
1015}
1016
1017void USRGenerator::VisitTemplateName(TemplateName Name) {
1019 if (TemplateTemplateParmDecl *TTP
1020 = dyn_cast(Template)) {
1021 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1022 return;
1023 }
1024
1026 return;
1027 }
1028
1029
1030}
1031
1032void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
1033 switch (Arg.getKind()) {
1035 break;
1036
1039 break;
1040
1042 break;
1043
1045 Out << 'P';
1046 [[fallthrough]];
1049 break;
1050
1052
1053 break;
1054
1058 VisitTemplateArgument(P);
1059 break;
1060
1063 break;
1064
1066 Out << 'V';
1069 break;
1070
1072 Out << 'S';
1074 ODRHash Hash{};
1077 break;
1078 }
1079 }
1080}
1081
1082void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1083 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
1084 return;
1086 Out << "@UUV@";
1088 EmitDeclName(D);
1089}
1090
1091void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
1092 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
1093 return;
1095 Out << "@UUT@";
1097 Out << D->getName();
1098}
1099
1100void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
1101 if (ShouldGenerateLocation(D) && GenLoc(D, isLocal(D)))
1102 return;
1104 Out << "@CT@";
1105 EmitDeclName(D);
1106}
1107
1108void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
1110 Out << "@MG@";
1111 D->NamedDecl::printName(Out);
1112}
1113
1114
1115
1116
1117
1119 StringRef CatSymDefinedIn,
1120 raw_ostream &OS) {
1121 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
1122 return;
1123 if (CatSymDefinedIn.empty()) {
1124 OS << "@M@" << ClsSymDefinedIn << '@';
1125 return;
1126 }
1127 OS << "@CM@" << CatSymDefinedIn << '@';
1128 if (ClsSymDefinedIn != CatSymDefinedIn) {
1129 OS << ClsSymDefinedIn << '@';
1130 }
1131}
1132
1134 StringRef ExtSymDefinedIn,
1135 StringRef CategoryContextExtSymbolDefinedIn) {
1137 CategoryContextExtSymbolDefinedIn, OS);
1138 OS << "objc(cs)" << Cls;
1139}
1140
1142 raw_ostream &OS,
1143 StringRef ClsSymDefinedIn,
1144 StringRef CatSymDefinedIn) {
1146 OS << "objc(cy)" << Cls << '@' << Cat;
1147}
1148
1150 OS << '@' << Ivar;
1151}
1152
1154 bool IsInstanceMethod,
1155 raw_ostream &OS) {
1156 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
1157}
1158
1160 raw_ostream &OS) {
1161 OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
1162}
1163
1165 StringRef ExtSymDefinedIn) {
1166 if (!ExtSymDefinedIn.empty())
1167 OS << "@M@" << ExtSymDefinedIn << '@';
1168 OS << "objc(pl)" << Prot;
1169}
1170
1172 StringRef ExtSymDefinedIn) {
1173 if (!ExtSymDefinedIn.empty())
1174 OS << "@M@" << ExtSymDefinedIn;
1175 OS << "@E@" << EnumName;
1176}
1177
1179 raw_ostream &OS) {
1180 OS << '@' << EnumConstantName;
1181}
1182
1185 if (!D)
1186 return true;
1188}
1189
1192 if (!D)
1193 return true;
1194
1195
1196
1197
1198
1200 if (auto *ExternalSymAttr = CD->getAttr()) {
1201 if (!ExternalSymAttr->getUSR().empty()) {
1202 llvm::raw_svector_ostream Out(Buf);
1203 Out << ExternalSymAttr->getUSR();
1204 return false;
1205 }
1206 }
1207 USRGenerator UG(&D->getASTContext(), Buf, LangOpts);
1208 UG.Visit(D);
1209 return UG.ignoreResults();
1210}
1211
1215 if (!MD)
1216 return true;
1218 SM, Buf);
1219
1220}
1221
1225 if (MacroName.empty())
1226 return true;
1227
1228 llvm::raw_svector_ostream Out(Buf);
1229
1230
1231
1232 bool ShouldGenerateLocation = Loc.isValid() && .isInSystemHeader(Loc);
1233
1235 if (ShouldGenerateLocation)
1236 printLoc(Out, Loc, SM, true);
1237 Out << "@macro@";
1238 Out << MacroName;
1239 return false;
1240}
1241
1246
1250 if (T.isNull())
1251 return true;
1252 T = T.getCanonicalType();
1253
1254 USRGenerator UG(&Ctx, Buf, LangOpts);
1255 UG.VisitType(T);
1256 return UG.ignoreResults();
1257}
1258
1260 raw_ostream &OS) {
1264 return true;
1266}
1267
1269 raw_ostream &OS) {
1272}
1273
1275 raw_ostream &OS) {
1277}
1278
1280 raw_ostream &OS) {
1281 OS << "@M@" << ModName;
1282 return false;
1283}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn, StringRef CatSymDefinedIn, raw_ostream &OS)
Definition USRGeneration.cpp:1118
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, const SourceManager &SM, bool IncludeOffset)
Definition USRGeneration.cpp:28
static const ObjCCategoryDecl * getCategoryContext(const NamedDecl *D)
Definition USRGeneration.cpp:403
static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts, NestedNameSpecifier NNS)
Definition USRGeneration.cpp:655
static StringRef GetExternalSourceContainer(const NamedDecl *D)
Definition USRGeneration.cpp:51
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
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...
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
A simple visitor class that helps create declaration visitors.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Decl - This represents one declaration (or definition), e.g.
const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
ASTContext & getASTContext() const LLVM_READONLY
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
SourceLocation getLocation() const
DeclContext * getDeclContext()
SourceLocation getBeginLoc() const LLVM_READONLY
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
bool isEmpty() const
Evaluates true when this declaration name is empty.
StringRef getName() const
The name of this FileEntry.
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
QualType getReturnType() const
bool isVariadic() const
Whether this function is variadic.
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isExternC() const
Determines whether this function is a function with external, C linkage.
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Record the location of a macro definition.
SourceLocation getLocation() const
Retrieve the location of the macro name in the definition.
const IdentifierInfo * getName() const
Retrieve the name of the macro being defined.
Module * Parent
The parent of this module.
std::string Name
The name of this module.
This represents a decl that may have a name.
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
bool isExternallyVisible() const
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
Represents a C++ nested name specifier, such as "\::std::vector::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
void AddStructuralValue(const APValue &)
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
bool IsClassExtension() const
const ObjCInterfaceDecl * getClassInterface() const
Selector getSelector() const
bool isInstanceMethod() const
ObjCInterfaceDecl * getClassInterface()
bool isClassProperty() const
ObjCPropertyDecl * getPropertyDecl() const
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getCanonicalType() const
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
This class handles loading and caching of source files into memory.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isEmbeddedInDeclarator() const
True if this tag declaration is "embedded" (i.e., defined or declared for the very first time) in the...
TypedefNameDecl * getTypedefNameForAnonDecl() const
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
TagKind getTagKind() const
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
const T * getAs() const
Member-template getAs'.
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
VarTemplateDecl * getDescribedVarTemplate() const
Retrieves the variable template that is described by this variable declaration.
bool generateFullUSRForTopLevelModuleName(StringRef ModName, raw_ostream &OS)
Generate a USR for a top-level module name, including the USR prefix.
Definition USRGeneration.cpp:1268
static StringRef getUSRSpacePrefix()
void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS, StringRef ClsExtSymbolDefinedIn="", StringRef CatExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C class category.
Definition USRGeneration.cpp:1141
bool generateFullUSRForModule(const Module *Mod, raw_ostream &OS)
Generate a USR for a module, including the USR prefix.
Definition USRGeneration.cpp:1259
bool generateUSRFragmentForModuleName(StringRef ModName, raw_ostream &OS)
Generate a USR fragment for a module name.
Definition USRGeneration.cpp:1279
bool generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl< char > &Buf)
Generate a USR for a macro, including the USR prefix.
Definition USRGeneration.cpp:1212
void generateUSRForObjCProperty(StringRef Prop, bool isClassProp, raw_ostream &OS)
Generate a USR fragment for an Objective-C property.
Definition USRGeneration.cpp:1159
void generateUSRForEnumConstant(StringRef EnumConstantName, raw_ostream &OS)
Generate a USR fragment for an enum constant.
Definition USRGeneration.cpp:1178
void generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS)
Generate a USR fragment for an Objective-C instance variable.
Definition USRGeneration.cpp:1149
void generateUSRForObjCMethod(StringRef Sel, bool IsInstanceMethod, raw_ostream &OS)
Generate a USR fragment for an Objective-C method.
Definition USRGeneration.cpp:1153
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl< char > &Buf)
Generates a USR for a type.
Definition USRGeneration.cpp:1242
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS, StringRef ExtSymbolDefinedIn="", StringRef CategoryContextExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C class.
Definition USRGeneration.cpp:1133
void generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS, StringRef ExtSymbolDefinedIn="")
Generate USR fragment for a global (non-nested) enum.
Definition USRGeneration.cpp:1171
void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS, StringRef ExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C protocol.
Definition USRGeneration.cpp:1164
bool generateUSRFragmentForModule(const Module *Mod, raw_ostream &OS)
Generate a USR fragment for a module.
Definition USRGeneration.cpp:1274
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
Definition USRGeneration.cpp:1183
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
@ RQ_None
No ref-qualifier was provided.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
std::pair< FileID, unsigned > FileIDAndOffset
const FunctionProtoType * T
@ Template
We are parsing a template declaration.
U cast(CodeGen::Address addr)
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressUnwrittenScope
Suppress printing parts of scope specifiers that are never written, e.g., for anonymous namespaces.
unsigned AnonymousTagLocations
When printing an anonymous tag name, also print the location of that entity (e.g.,...
unsigned ConstantArraySizeAsWritten
Whether we should print the sizes of constant array expressions as written in the sources.
unsigned SuppressTagKeyword
Whether type printing should skip printing the tag keyword.