clang 20.0.0git
USRGeneration.cpp
Go to the documentation of this file.
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
11#include "clang/AST/Attr.h"
12#include "clang/AST/DeclCXX.h"
15#include "clang/AST/ODRHash.h"
18#include "llvm/Support/Path.h"
19#include "llvm/Support/raw_ostream.h"
20
21using namespace clang;
22using namespace clang::index;
23
24//===----------------------------------------------------------------------===//
25// USR generation.
26//===----------------------------------------------------------------------===//
27
28/// \returns true on error.
29static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
30 const SourceManager &SM, bool IncludeOffset) {
31 if (Loc.isInvalid()) {
32 return true;
33 }
34 Loc = SM.getExpansionLoc(Loc);
35 const std::pair<FileID, unsigned> &Decomposed = SM.getDecomposedLoc(Loc);
36 OptionalFileEntryRef FE = SM.getFileEntryRefForID(Decomposed.first);
37 if (FE) {
38 OS << llvm::sys::path::filename(FE->getName());
39 } else {
40 // This case really isn't interesting.
41 return true;
42 }
43 if (IncludeOffset) {
44 // Use the offest into the FileID to represent the location. Using
45 // a line/column can cause us to look back at the original source file,
46 // which is expensive.
47 OS << '@' << Decomposed.second;
48 }
49 return false;
50}
51
52static StringRef GetExternalSourceContainer(const NamedDecl *D) {
53 if (!D)
54 return StringRef();
55 if (auto *attr = D->getExternalSourceSymbolAttr()) {
56 return attr->getDefinedIn();
57 }
58 return StringRef();
59}
60
61namespace {
62class USRGenerator : public ConstDeclVisitor<USRGenerator> {
64 llvm::raw_svector_ostream Out;
65 ASTContext *Context;
66 const LangOptions &LangOpts;
67 bool IgnoreResults = false;
68 bool generatedLoc = false;
69
70 llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
71
72public:
73 USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf,
74 const LangOptions &LangOpts)
75 : Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) {
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 VisitBindingDecl(const BindingDecl *D);
101 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
102 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
103 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
104 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
105 void VisitConceptDecl(const ConceptDecl *D);
106
107 void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
108 IgnoreResults = true; // No USRs for linkage specs themselves.
109 }
110
111 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
112 IgnoreResults = true;
113 }
114
115 void VisitUsingDecl(const UsingDecl *D) {
116 VisitDeclContext(D->getDeclContext());
117 Out << "@UD@";
118
119 bool EmittedDeclName = !EmitDeclName(D);
120 assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls");
121 (void)EmittedDeclName;
122 }
123
124 bool ShouldGenerateLocation(const NamedDecl *D);
125
126 bool isLocal(const NamedDecl *D) {
127 return D->getParentFunctionOrMethod() != nullptr;
128 }
129
130 void GenExtSymbolContainer(const NamedDecl *D);
131
132 /// Generate the string component containing the location of the
133 /// declaration.
134 bool GenLoc(const Decl *D, bool IncludeOffset);
135
136 /// String generation methods used both by the visitation methods
137 /// and from other clients that want to directly generate USRs. These
138 /// methods do not construct complete USRs (which incorporate the parents
139 /// of an AST element), but only the fragments concerning the AST element
140 /// itself.
141
142 /// Generate a USR for an Objective-C class.
143 void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
144 StringRef CategoryContextExtSymbolDefinedIn) {
145 generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
146 CategoryContextExtSymbolDefinedIn);
147 }
148
149 /// Generate a USR for an Objective-C class category.
150 void GenObjCCategory(StringRef cls, StringRef cat,
151 StringRef clsExt, StringRef catExt) {
152 generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
153 }
154
155 /// Generate a USR fragment for an Objective-C property.
156 void GenObjCProperty(StringRef prop, bool isClassProp) {
157 generateUSRForObjCProperty(prop, isClassProp, Out);
158 }
159
160 /// Generate a USR for an Objective-C protocol.
161 void GenObjCProtocol(StringRef prot, StringRef ext) {
162 generateUSRForObjCProtocol(prot, Out, ext);
163 }
164
165 void VisitType(QualType T);
166 void VisitTemplateParameterList(const TemplateParameterList *Params);
167 void VisitTemplateName(TemplateName Name);
168 void VisitTemplateArgument(const TemplateArgument &Arg);
169
170 void VisitMSGuidDecl(const MSGuidDecl *D);
171
172 /// Emit a Decl's name using NamedDecl::printName() and return true if
173 /// the decl had no name.
174 bool EmitDeclName(const NamedDecl *D);
175};
176} // end anonymous namespace
177
178//===----------------------------------------------------------------------===//
179// Generating USRs from ASTS.
180//===----------------------------------------------------------------------===//
181
182bool USRGenerator::EmitDeclName(const NamedDecl *D) {
183 DeclarationName N = D->getDeclName();
184 if (N.isEmpty())
185 return true;
186 Out << N;
187 return false;
188}
189
190bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
191 if (D->isExternallyVisible())
192 return false;
194 return true;
196 if (Loc.isInvalid())
197 return false;
198 const SourceManager &SM = Context->getSourceManager();
199 return !SM.isInSystemHeader(Loc);
200}
201
202void USRGenerator::VisitDeclContext(const DeclContext *DC) {
203 if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
204 Visit(D);
205 else if (isa<LinkageSpecDecl>(DC)) // Linkage specs are transparent in USRs.
206 VisitDeclContext(DC->getParent());
207}
208
209void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
210 // The USR for an ivar declared in a class extension is based on the
211 // ObjCInterfaceDecl, not the ObjCCategoryDecl.
212 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
213 Visit(ID);
214 else
215 VisitDeclContext(D->getDeclContext());
216 Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
217 if (EmitDeclName(D)) {
218 // Bit fields can be anonymous.
219 IgnoreResults = true;
220 return;
221 }
222}
223
224void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
225 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
226 return;
227
228 if (D->getType().isNull()) {
229 IgnoreResults = true;
230 return;
231 }
232
233 const unsigned StartSize = Buf.size();
234 VisitDeclContext(D->getDeclContext());
235 if (Buf.size() == StartSize)
236 GenExtSymbolContainer(D);
237
238 bool IsTemplate = false;
239 if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
240 IsTemplate = true;
241 Out << "@FT@";
242 VisitTemplateParameterList(FunTmpl->getTemplateParameters());
243 } else
244 Out << "@F@";
245
246 PrintingPolicy Policy(LangOpts);
247 // Forward references can have different template argument names. Suppress the
248 // template argument names in constructors to make their USR more stable.
249 Policy.SuppressTemplateArgsInCXXConstructors = true;
250 D->getDeclName().print(Out, Policy);
251
252 if ((!LangOpts.CPlusPlus || D->isExternC()) &&
253 !D->hasAttr<OverloadableAttr>())
254 return;
255
256 if (D->isFunctionTemplateSpecialization()) {
257 Out << '<';
258 if (const TemplateArgumentList *SpecArgs =
259 D->getTemplateSpecializationArgs()) {
260 for (const auto &Arg : SpecArgs->asArray()) {
261 Out << '#';
262 VisitTemplateArgument(Arg);
263 }
264 } else if (const ASTTemplateArgumentListInfo *SpecArgsWritten =
265 D->getTemplateSpecializationArgsAsWritten()) {
266 for (const auto &ArgLoc : SpecArgsWritten->arguments()) {
267 Out << '#';
268 VisitTemplateArgument(ArgLoc.getArgument());
269 }
270 }
271 Out << '>';
272 }
273
274 QualType CanonicalType = D->getType().getCanonicalType();
275 // Mangle in type information for the arguments.
276 if (const auto *FPT = CanonicalType->getAs<FunctionProtoType>()) {
277 for (QualType PT : FPT->param_types()) {
278 Out << '#';
279 VisitType(PT);
280 }
281 }
282 if (D->isVariadic())
283 Out << '.';
284 if (IsTemplate) {
285 // Function templates can be overloaded by return type, for example:
286 // \code
287 // template <class T> typename T::A foo() {}
288 // template <class T> typename T::B foo() {}
289 // \endcode
290 Out << '#';
291 VisitType(D->getReturnType());
292 }
293 Out << '#';
294 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
295 if (MD->isStatic())
296 Out << 'S';
297 // FIXME: OpenCL: Need to consider address spaces
298 if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
299 Out << (char)('0' + quals);
300 switch (MD->getRefQualifier()) {
301 case RQ_None: break;
302 case RQ_LValue: Out << '&'; break;
303 case RQ_RValue: Out << "&&"; break;
304 }
305 }
306}
307
308void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
309 VisitDeclContext(D->getDeclContext());
310 Out << "@";
311
312 if (EmitDeclName(D)) {
313 // The string can be empty if the declaration has no name; e.g., it is
314 // the ParmDecl with no name for declaration of a function pointer type,
315 // e.g.: void (*f)(void *);
316 // In this case, don't generate a USR.
317 IgnoreResults = true;
318 }
319}
320
321void USRGenerator::VisitVarDecl(const VarDecl *D) {
322 // VarDecls can be declared 'extern' within a function or method body,
323 // but their enclosing DeclContext is the function, not the TU. We need
324 // to check the storage class to correctly generate the USR.
325 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
326 return;
327
328 VisitDeclContext(D->getDeclContext());
329
330 if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
331 Out << "@VT";
332 VisitTemplateParameterList(VarTmpl->getTemplateParameters());
333 } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
334 = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
335 Out << "@VP";
336 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
337 }
338
339 // Variables always have simple names.
340 StringRef s = D->getName();
341
342 // The string can be empty if the declaration has no name; e.g., it is
343 // the ParmDecl with no name for declaration of a function pointer type, e.g.:
344 // void (*f)(void *);
345 // In this case, don't generate a USR.
346 if (s.empty())
347 IgnoreResults = true;
348 else
349 Out << '@' << s;
350
351 // For a template specialization, mangle the template arguments.
352 if (const VarTemplateSpecializationDecl *Spec
353 = dyn_cast<VarTemplateSpecializationDecl>(D)) {
354 const TemplateArgumentList &Args = Spec->getTemplateArgs();
355 Out << '>';
356 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
357 Out << '#';
358 VisitTemplateArgument(Args.get(I));
359 }
360 }
361}
362
363void USRGenerator::VisitBindingDecl(const BindingDecl *D) {
364 if (isLocal(D) && GenLoc(D, /*IncludeOffset=*/true))
365 return;
366 VisitNamedDecl(D);
367}
368
369void USRGenerator::VisitNonTypeTemplateParmDecl(
370 const NonTypeTemplateParmDecl *D) {
371 GenLoc(D, /*IncludeOffset=*/true);
372}
373
374void USRGenerator::VisitTemplateTemplateParmDecl(
376 GenLoc(D, /*IncludeOffset=*/true);
377}
378
379void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
380 if (IgnoreResults)
381 return;
382 VisitDeclContext(D->getDeclContext());
383 if (D->isAnonymousNamespace()) {
384 Out << "@aN";
385 return;
386 }
387 Out << "@N@" << D->getName();
388}
389
390void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
391 VisitFunctionDecl(D->getTemplatedDecl());
392}
393
394void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
395 VisitTagDecl(D->getTemplatedDecl());
396}
397
398void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
399 VisitDeclContext(D->getDeclContext());
400 if (!IgnoreResults)
401 Out << "@NA@" << D->getName();
402}
403
405 if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
406 return CD;
407 if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
408 return ICD->getCategoryDecl();
409 return nullptr;
410}
411
412void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
413 const DeclContext *container = D->getDeclContext();
414 if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
415 Visit(pd);
416 }
417 else {
418 // The USR for a method declared in a class extension or category is based on
419 // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
420 const ObjCInterfaceDecl *ID = D->getClassInterface();
421 if (!ID) {
422 IgnoreResults = true;
423 return;
424 }
425 auto *CD = getCategoryContext(D);
426 VisitObjCContainerDecl(ID, CD);
427 }
428 // Ideally we would use 'GenObjCMethod', but this is such a hot path
429 // for Objective-C code that we don't want to use
430 // DeclarationName::getAsString().
431 Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
432 << DeclarationName(D->getSelector());
433}
434
435void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
436 const ObjCCategoryDecl *CatD) {
437 switch (D->getKind()) {
438 default:
439 llvm_unreachable("Invalid ObjC container.");
440 case Decl::ObjCInterface:
441 case Decl::ObjCImplementation:
442 GenObjCClass(D->getName(), GetExternalSourceContainer(D),
444 break;
445 case Decl::ObjCCategory: {
446 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
448 if (!ID) {
449 // Handle invalid code where the @interface might not
450 // have been specified.
451 // FIXME: We should be able to generate this USR even if the
452 // @interface isn't available.
453 IgnoreResults = true;
454 return;
455 }
456 // Specially handle class extensions, which are anonymous categories.
457 // We want to mangle in the location to uniquely distinguish them.
458 if (CD->IsClassExtension()) {
459 Out << "objc(ext)" << ID->getName() << '@';
460 GenLoc(CD, /*IncludeOffset=*/true);
461 }
462 else
463 GenObjCCategory(ID->getName(), CD->getName(),
466
467 break;
468 }
469 case Decl::ObjCCategoryImpl: {
470 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
472 if (!ID) {
473 // Handle invalid code where the @interface might not
474 // have been specified.
475 // FIXME: We should be able to generate this USR even if the
476 // @interface isn't available.
477 IgnoreResults = true;
478 return;
479 }
480 GenObjCCategory(ID->getName(), CD->getName(),
483 break;
484 }
485 case Decl::ObjCProtocol: {
486 const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
487 GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
488 break;
489 }
490 }
491}
492
493void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
494 // The USR for a property declared in a class extension or category is based
495 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
496 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
497 VisitObjCContainerDecl(ID, getCategoryContext(D));
498 else
499 Visit(cast<Decl>(D->getDeclContext()));
500 GenObjCProperty(D->getName(), D->isClassProperty());
501}
502
503void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
504 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
505 VisitObjCPropertyDecl(PD);
506 return;
507 }
508
509 IgnoreResults = true;
510}
511
512void USRGenerator::VisitTagDecl(const TagDecl *D) {
513 // Add the location of the tag decl to handle resolution across
514 // translation units.
515 if (!isa<EnumDecl>(D) &&
516 ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
517 return;
518
519 GenExtSymbolContainer(D);
520
521 D = D->getCanonicalDecl();
522 VisitDeclContext(D->getDeclContext());
523
524 bool AlreadyStarted = false;
525 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
526 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
527 AlreadyStarted = true;
528
529 switch (D->getTagKind()) {
530 case TagTypeKind::Interface:
531 case TagTypeKind::Class:
532 case TagTypeKind::Struct:
533 Out << "@ST";
534 break;
535 case TagTypeKind::Union:
536 Out << "@UT";
537 break;
538 case TagTypeKind::Enum:
539 llvm_unreachable("enum template");
540 }
541 VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
542 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
543 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
544 AlreadyStarted = true;
545
546 switch (D->getTagKind()) {
547 case TagTypeKind::Interface:
548 case TagTypeKind::Class:
549 case TagTypeKind::Struct:
550 Out << "@SP";
551 break;
552 case TagTypeKind::Union:
553 Out << "@UP";
554 break;
555 case TagTypeKind::Enum:
556 llvm_unreachable("enum partial specialization");
557 }
558 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
559 }
560 }
561
562 if (!AlreadyStarted) {
563 switch (D->getTagKind()) {
564 case TagTypeKind::Interface:
565 case TagTypeKind::Class:
566 case TagTypeKind::Struct:
567 Out << "@S";
568 break;
569 case TagTypeKind::Union:
570 Out << "@U";
571 break;
572 case TagTypeKind::Enum:
573 Out << "@E";
574 break;
575 }
576 }
577
578 Out << '@';
579 assert(Buf.size() > 0);
580 const unsigned off = Buf.size() - 1;
581
582 if (EmitDeclName(D)) {
583 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
584 Buf[off] = 'A';
585 Out << '@' << *TD;
586 } else {
587 if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
588 printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
589 } else {
590 Buf[off] = 'a';
591 if (auto *ED = dyn_cast<EnumDecl>(D)) {
592 // Distinguish USRs of anonymous enums by using their first
593 // enumerator.
594 auto enum_range = ED->enumerators();
595 if (enum_range.begin() != enum_range.end()) {
596 Out << '@' << **enum_range.begin();
597 }
598 }
599 }
600 }
601 }
602
603 // For a class template specialization, mangle the template arguments.
604 if (const ClassTemplateSpecializationDecl *Spec
605 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
606 const TemplateArgumentList &Args = Spec->getTemplateArgs();
607 Out << '>';
608 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
609 Out << '#';
610 VisitTemplateArgument(Args.get(I));
611 }
612 }
613}
614
615void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
616 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
617 return;
618 const DeclContext *DC = D->getDeclContext();
619 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
620 Visit(DCN);
621 Out << "@T@";
622 Out << D->getName();
623}
624
625void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
626 GenLoc(D, /*IncludeOffset=*/true);
627}
628
629void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
630 StringRef Container = GetExternalSourceContainer(D);
631 if (!Container.empty())
632 Out << "@M@" << Container;
633}
634
635bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
636 if (generatedLoc)
637 return IgnoreResults;
638 generatedLoc = true;
639
640 // Guard against null declarations in invalid code.
641 if (!D) {
642 IgnoreResults = true;
643 return true;
644 }
645
646 // Use the location of canonical decl.
647 D = D->getCanonicalDecl();
648
649 IgnoreResults =
650 IgnoreResults || printLoc(Out, D->getBeginLoc(),
651 Context->getSourceManager(), IncludeOffset);
652
653 return IgnoreResults;
654}
655
656static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts,
657 NestedNameSpecifier *NNS) {
658 // FIXME: Encode the qualifier, don't just print it.
659 PrintingPolicy PO(LangOpts);
660 PO.SuppressTagKeyword = true;
661 PO.SuppressUnwrittenScope = true;
663 PO.AnonymousTagLocations = false;
664 NNS->print(Out, PO);
665}
666
667void USRGenerator::VisitType(QualType T) {
668 // This method mangles in USR information for types. It can possibly
669 // just reuse the naming-mangling logic used by codegen, although the
670 // requirements for USRs might not be the same.
671 ASTContext &Ctx = *Context;
672
673 do {
674 T = Ctx.getCanonicalType(T);
675 Qualifiers Q = T.getQualifiers();
676 unsigned qVal = 0;
677 if (Q.hasConst())
678 qVal |= 0x1;
679 if (Q.hasVolatile())
680 qVal |= 0x2;
681 if (Q.hasRestrict())
682 qVal |= 0x4;
683 if(qVal)
684 Out << ((char) ('0' + qVal));
685
686 // Mangle in ObjC GC qualifiers?
687
688 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
689 Out << 'P';
690 T = Expansion->getPattern();
691 }
692
693 if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
694 switch (BT->getKind()) {
695 case BuiltinType::Void:
696 Out << 'v'; break;
697 case BuiltinType::Bool:
698 Out << 'b'; break;
699 case BuiltinType::UChar:
700 Out << 'c'; break;
701 case BuiltinType::Char8:
702 Out << 'u'; break;
703 case BuiltinType::Char16:
704 Out << 'q'; break;
705 case BuiltinType::Char32:
706 Out << 'w'; break;
707 case BuiltinType::UShort:
708 Out << 's'; break;
709 case BuiltinType::UInt:
710 Out << 'i'; break;
711 case BuiltinType::ULong:
712 Out << 'l'; break;
713 case BuiltinType::ULongLong:
714 Out << 'k'; break;
715 case BuiltinType::UInt128:
716 Out << 'j'; break;
717 case BuiltinType::Char_U:
718 case BuiltinType::Char_S:
719 Out << 'C'; break;
720 case BuiltinType::SChar:
721 Out << 'r'; break;
722 case BuiltinType::WChar_S:
723 case BuiltinType::WChar_U:
724 Out << 'W'; break;
725 case BuiltinType::Short:
726 Out << 'S'; break;
727 case BuiltinType::Int:
728 Out << 'I'; break;
729 case BuiltinType::Long:
730 Out << 'L'; break;
731 case BuiltinType::LongLong:
732 Out << 'K'; break;
733 case BuiltinType::Int128:
734 Out << 'J'; break;
735 case BuiltinType::Float16:
736 case BuiltinType::Half:
737 Out << 'h'; break;
738 case BuiltinType::Float:
739 Out << 'f'; break;
740 case BuiltinType::Double:
741 Out << 'd'; break;
742 case BuiltinType::LongDouble:
743 Out << 'D'; break;
744 case BuiltinType::Float128:
745 Out << 'Q'; break;
746 case BuiltinType::NullPtr:
747 Out << 'n'; break;
748#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
749 case BuiltinType::Id: \
750 Out << "@BT@" << #Suffix << "_" << #ImgType; break;
751#include "clang/Basic/OpenCLImageTypes.def"
752#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
753 case BuiltinType::Id: \
754 Out << "@BT@" << #ExtType; break;
755#include "clang/Basic/OpenCLExtensionTypes.def"
756 case BuiltinType::OCLEvent:
757 Out << "@BT@OCLEvent"; break;
758 case BuiltinType::OCLClkEvent:
759 Out << "@BT@OCLClkEvent"; break;
760 case BuiltinType::OCLQueue:
761 Out << "@BT@OCLQueue"; break;
762 case BuiltinType::OCLReserveID:
763 Out << "@BT@OCLReserveID"; break;
764 case BuiltinType::OCLSampler:
765 Out << "@BT@OCLSampler"; break;
766#define SVE_TYPE(Name, Id, SingletonId) \
767 case BuiltinType::Id: \
768 Out << "@BT@" << Name; break;
769#include "clang/Basic/AArch64SVEACLETypes.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 // If you're adding a new builtin type, please add its name prefixed
853 // with "@BT@" to `Out` (see cases above).
854 IgnoreResults = true;
855 break;
856 }
857 return;
858 }
859
860 // If we have already seen this (non-built-in) type, use a substitution
861 // encoding.
862 llvm::DenseMap<const Type *, unsigned>::iterator Substitution
863 = TypeSubstitutions.find(T.getTypePtr());
864 if (Substitution != TypeSubstitutions.end()) {
865 Out << 'S' << Substitution->second << '_';
866 return;
867 } else {
868 // Record this as a substitution.
869 unsigned Number = TypeSubstitutions.size();
870 TypeSubstitutions[T.getTypePtr()] = Number;
871 }
872
873 if (const PointerType *PT = T->getAs<PointerType>()) {
874 Out << '*';
875 T = PT->getPointeeType();
876 continue;
877 }
878 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
879 Out << '*';
880 T = OPT->getPointeeType();
881 continue;
882 }
883 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
884 Out << "&&";
885 T = RT->getPointeeType();
886 continue;
887 }
888 if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
889 Out << '&';
890 T = RT->getPointeeType();
891 continue;
892 }
893 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
894 Out << 'F';
895 VisitType(FT->getReturnType());
896 Out << '(';
897 for (const auto &I : FT->param_types()) {
898 Out << '#';
899 VisitType(I);
900 }
901 Out << ')';
902 if (FT->isVariadic())
903 Out << '.';
904 return;
905 }
906 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
907 Out << 'B';
908 T = BT->getPointeeType();
909 continue;
910 }
911 if (const ComplexType *CT = T->getAs<ComplexType>()) {
912 Out << '<';
913 T = CT->getElementType();
914 continue;
915 }
916 if (const TagType *TT = T->getAs<TagType>()) {
917 Out << '$';
918 VisitTagDecl(TT->getDecl());
919 return;
920 }
921 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
922 Out << '$';
923 VisitObjCInterfaceDecl(OIT->getDecl());
924 return;
925 }
926 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
927 Out << 'Q';
928 VisitType(OIT->getBaseType());
929 for (auto *Prot : OIT->getProtocols())
930 VisitObjCProtocolDecl(Prot);
931 return;
932 }
933 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
934 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
935 return;
936 }
937 if (const TemplateSpecializationType *Spec
939 Out << '>';
940 VisitTemplateName(Spec->getTemplateName());
941 Out << Spec->template_arguments().size();
942 for (const auto &Arg : Spec->template_arguments())
943 VisitTemplateArgument(Arg);
944 return;
945 }
946 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
947 Out << '^';
948 printQualifier(Out, LangOpts, DNT->getQualifier());
949 Out << ':' << DNT->getIdentifier()->getName();
950 return;
951 }
952 if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) {
953 T = InjT->getInjectedSpecializationType();
954 continue;
955 }
956 if (const auto *VT = T->getAs<VectorType>()) {
957 Out << (T->isExtVectorType() ? ']' : '[');
958 Out << VT->getNumElements();
959 T = VT->getElementType();
960 continue;
961 }
962 if (const auto *const AT = dyn_cast<ArrayType>(T)) {
963 Out << '{';
964 switch (AT->getSizeModifier()) {
965 case ArraySizeModifier::Static:
966 Out << 's';
967 break;
968 case ArraySizeModifier::Star:
969 Out << '*';
970 break;
971 case ArraySizeModifier::Normal:
972 Out << 'n';
973 break;
974 }
975 if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
976 Out << CAT->getSize();
977
978 T = AT->getElementType();
979 continue;
980 }
981
982 // Unhandled type.
983 Out << ' ';
984 break;
985 } while (true);
986}
987
988void USRGenerator::VisitTemplateParameterList(
989 const TemplateParameterList *Params) {
990 if (!Params)
991 return;
992 Out << '>' << Params->size();
994 PEnd = Params->end();
995 P != PEnd; ++P) {
996 Out << '#';
997 if (isa<TemplateTypeParmDecl>(*P)) {
998 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
999 Out<< 'p';
1000 Out << 'T';
1001 continue;
1002 }
1003
1004 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1005 if (NTTP->isParameterPack())
1006 Out << 'p';
1007 Out << 'N';
1008 VisitType(NTTP->getType());
1009 continue;
1010 }
1011
1012 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1013 if (TTP->isParameterPack())
1014 Out << 'p';
1015 Out << 't';
1016 VisitTemplateParameterList(TTP->getTemplateParameters());
1017 }
1018}
1019
1020void USRGenerator::VisitTemplateName(TemplateName Name) {
1021 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1023 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
1024 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1025 return;
1026 }
1027
1028 Visit(Template);
1029 return;
1030 }
1031
1032 // FIXME: Visit dependent template names.
1033}
1034
1035void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
1036 switch (Arg.getKind()) {
1038 break;
1039
1041 Visit(Arg.getAsDecl());
1042 break;
1043
1045 break;
1046
1048 Out << 'P'; // pack expansion of...
1049 [[fallthrough]];
1051 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1052 break;
1053
1055 // FIXME: Visit expressions.
1056 break;
1057
1059 Out << 'p' << Arg.pack_size();
1060 for (const auto &P : Arg.pack_elements())
1061 VisitTemplateArgument(P);
1062 break;
1063
1065 VisitType(Arg.getAsType());
1066 break;
1067
1069 Out << 'V';
1070 VisitType(Arg.getIntegralType());
1071 Out << Arg.getAsIntegral();
1072 break;
1073
1075 Out << 'S';
1076 VisitType(Arg.getStructuralValueType());
1077 ODRHash Hash{};
1079 Out << Hash.CalculateHash();
1080 break;
1081 }
1082 }
1083}
1084
1085void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1086 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1087 return;
1088 VisitDeclContext(D->getDeclContext());
1089 Out << "@UUV@";
1090 printQualifier(Out, LangOpts, D->getQualifier());
1091 EmitDeclName(D);
1092}
1093
1094void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
1095 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1096 return;
1097 VisitDeclContext(D->getDeclContext());
1098 Out << "@UUT@";
1099 printQualifier(Out, LangOpts, D->getQualifier());
1100 Out << D->getName(); // Simple name.
1101}
1102
1103void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
1104 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1105 return;
1106 VisitDeclContext(D->getDeclContext());
1107 Out << "@CT@";
1108 EmitDeclName(D);
1109}
1110
1111void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
1112 VisitDeclContext(D->getDeclContext());
1113 Out << "@MG@";
1114 D->NamedDecl::printName(Out);
1115}
1116
1117//===----------------------------------------------------------------------===//
1118// USR generation functions.
1119//===----------------------------------------------------------------------===//
1120
1121static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
1122 StringRef CatSymDefinedIn,
1123 raw_ostream &OS) {
1124 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
1125 return;
1126 if (CatSymDefinedIn.empty()) {
1127 OS << "@M@" << ClsSymDefinedIn << '@';
1128 return;
1129 }
1130 OS << "@CM@" << CatSymDefinedIn << '@';
1131 if (ClsSymDefinedIn != CatSymDefinedIn) {
1132 OS << ClsSymDefinedIn << '@';
1133 }
1134}
1135
1136void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
1137 StringRef ExtSymDefinedIn,
1138 StringRef CategoryContextExtSymbolDefinedIn) {
1140 CategoryContextExtSymbolDefinedIn, OS);
1141 OS << "objc(cs)" << Cls;
1142}
1143
1144void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
1145 raw_ostream &OS,
1146 StringRef ClsSymDefinedIn,
1147 StringRef CatSymDefinedIn) {
1148 combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
1149 OS << "objc(cy)" << Cls << '@' << Cat;
1150}
1151
1152void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
1153 OS << '@' << Ivar;
1154}
1155
1157 bool IsInstanceMethod,
1158 raw_ostream &OS) {
1159 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
1160}
1161
1162void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
1163 raw_ostream &OS) {
1164 OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
1165}
1166
1167void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
1168 StringRef ExtSymDefinedIn) {
1169 if (!ExtSymDefinedIn.empty())
1170 OS << "@M@" << ExtSymDefinedIn << '@';
1171 OS << "objc(pl)" << Prot;
1172}
1173
1174void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
1175 StringRef ExtSymDefinedIn) {
1176 if (!ExtSymDefinedIn.empty())
1177 OS << "@M@" << ExtSymDefinedIn;
1178 OS << "@E@" << EnumName;
1179}
1180
1181void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
1182 raw_ostream &OS) {
1183 OS << '@' << EnumConstantName;
1184}
1185
1187 SmallVectorImpl<char> &Buf) {
1188 if (!D)
1189 return true;
1190 return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts());
1191}
1192
1194 const LangOptions &LangOpts) {
1195 if (!D)
1196 return true;
1197 // We don't ignore decls with invalid source locations. Implicit decls, like
1198 // C++'s operator new function, can have invalid locations but it is fine to
1199 // create USRs that can identify them.
1200
1201 // Check if the declaration has explicit external USR specified.
1202 auto *CD = D->getCanonicalDecl();
1203 if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
1204 if (!ExternalSymAttr->getUSR().empty()) {
1205 llvm::raw_svector_ostream Out(Buf);
1206 Out << ExternalSymAttr->getUSR();
1207 return false;
1208 }
1209 }
1210 USRGenerator UG(&D->getASTContext(), Buf, LangOpts);
1211 UG.Visit(D);
1212 return UG.ignoreResults();
1213}
1214
1216 const SourceManager &SM,
1217 SmallVectorImpl<char> &Buf) {
1218 if (!MD)
1219 return true;
1220 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1221 SM, Buf);
1222
1223}
1224
1226 const SourceManager &SM,
1227 SmallVectorImpl<char> &Buf) {
1228 if (MacroName.empty())
1229 return true;
1230
1231 llvm::raw_svector_ostream Out(Buf);
1232
1233 // Assume that system headers are sane. Don't put source location
1234 // information into the USR if the macro comes from a system header.
1235 bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
1236
1237 Out << getUSRSpacePrefix();
1238 if (ShouldGenerateLocation)
1239 printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1240 Out << "@macro@";
1241 Out << MacroName;
1242 return false;
1243}
1244
1246 SmallVectorImpl<char> &Buf) {
1247 return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts());
1248}
1249
1252 const LangOptions &LangOpts) {
1253 if (T.isNull())
1254 return true;
1255 T = T.getCanonicalType();
1256
1257 USRGenerator UG(&Ctx, Buf, LangOpts);
1258 UG.VisitType(T);
1259 return UG.ignoreResults();
1260}
1261
1263 raw_ostream &OS) {
1264 if (!Mod->Parent)
1266 if (generateFullUSRForModule(Mod->Parent, OS))
1267 return true;
1268 return generateUSRFragmentForModule(Mod, OS);
1269}
1270
1272 raw_ostream &OS) {
1273 OS << getUSRSpacePrefix();
1274 return generateUSRFragmentForModuleName(ModName, OS);
1275}
1276
1278 raw_ostream &OS) {
1279 return generateUSRFragmentForModuleName(Mod->Name, OS);
1280}
1281
1283 raw_ostream &OS) {
1284 OS << "@M@" << ModName;
1285 return false;
1286}
Defines the clang::ASTContext interface.
StringRef P
#define SM(sm)
Definition: Cuda.cpp:84
const Decl * D
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
Defines the clang::FileManager interface and associated types.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
SourceLocation Loc
Definition: SemaObjC.cpp:759
static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn, StringRef CatSymDefinedIn, raw_ostream &OS)
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, const SourceManager &SM, bool IncludeOffset)
static const ObjCCategoryDecl * getCategoryContext(const NamedDecl *D)
static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts, NestedNameSpecifier *NNS)
static StringRef GetExternalSourceContainer(const NamedDecl *D)
__device__ __2f16 float __ockl_bool s
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
SourceManager & getSourceManager()
Definition: ASTContext.h:741
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2716
const LangOptions & getLangOpts() const
Definition: ASTContext.h:834
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...
A binding in a decomposition declaration.
Definition: DeclCXX.h:4125
Pointer to a block type.
Definition: Type.h:3408
This class is used for builtin types like 'int'.
Definition: Type.h:3034
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2078
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Declaration of a class template.
Represents a class template specialization, which refers to a class template with a given set of temp...
Complex values, per C99 6.2.5p11.
Definition: Type.h:3145
Declaration of a C++20 concept.
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:74
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2089
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
Definition: DeclBase.cpp:314
T * getAttr() const
Definition: DeclBase.h:576
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:520
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
Definition: DeclBase.cpp:586
SourceLocation getLocation() const
Definition: DeclBase.h:442
DeclContext * getDeclContext()
Definition: DeclBase.h:451
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:434
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
bool hasAttr() const
Definition: DeclBase.h:580
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:967
Kind getKind() const
Definition: DeclBase.h:445
The name of a declaration.
bool isEmpty() const
Evaluates true when this declaration name is empty.
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:7024
Represents a member of a struct/union/class.
Definition: Decl.h:3033
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
Represents a function declaration or definition.
Definition: Decl.h:1935
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5102
Declaration of a template function.
Definition: DeclTemplate.h:959
StringRef getName() const
Return the actual identifier string.
The injected class name of a C++ class template or class template partial specialization.
Definition: Type.h:6793
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:499
Represents a linkage specification.
Definition: DeclCXX.h:2952
A global _GUID constant.
Definition: DeclCXX.h:4307
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.
Describes a module or submodule.
Definition: Module.h:115
Module * Parent
The parent of this module.
Definition: Module.h:164
std::string Name
The name of this module.
Definition: Module.h:118
This represents a decl that may have a name.
Definition: Decl.h:253
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:280
Represents a C++ namespace alias.
Definition: DeclCXX.h:3138
Represent a C++ namespace.
Definition: Decl.h:551
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) const
Print this nested name specifier to the given output stream.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
void AddStructuralValue(const APValue &)
Definition: ODRHash.cpp:1281
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2328
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2371
bool IsClassExtension() const
Definition: DeclObjC.h:2436
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2544
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:947
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2485
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:7524
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition: Type.h:7580
Represents a class type in Objective C.
Definition: Type.h:7326
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:730
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2804
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2083
Represents a pack expansion of types.
Definition: Type.h:7141
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3198
A (possibly-)qualified type.
Definition: Type.h:929
The collection of all-type qualifiers we support.
Definition: Type.h:324
bool hasConst() const
Definition: Type.h:450
bool hasRestrict() const
Definition: Type.h:470
bool hasVolatile() const
Definition: Type.h:460
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3501
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3439
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.
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3564
A template argument list.
Definition: DeclTemplate.h:250
unsigned size() const
Retrieve the number of template arguments in this template argument list.
Definition: DeclTemplate.h:286
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
Definition: DeclTemplate.h:271
Represents a template argument.
Definition: TemplateBase.h:61
QualType getStructuralValueType() const
Get the type of a StructuralValue.
Definition: TemplateBase.h:399
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:363
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:438
QualType getIntegralType() const
Retrieve the type of the integral value.
Definition: TemplateBase.h:377
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:326
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:432
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
Definition: TemplateBase.h:89
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:350
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Definition: TemplateBase.h:396
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:399
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:418
Represents a C++ template name within the type system.
Definition: TemplateName.h:220
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
NamedDecl *const * const_iterator
Iterates through the template parameters in this list.
Definition: DeclTemplate.h:132
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: Type.h:6661
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
Declaration of a template type parameter.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:738
bool isExtVectorType() const
Definition: Type.h:8302
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8731
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3514
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3413
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3977
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3880
Represents a C++ using-declaration.
Definition: DeclCXX.h:3530
Represents C++ using-directive.
Definition: DeclCXX.h:3033
Represents a variable declaration or definition.
Definition: Decl.h:882
Declaration of a variable template.
Represents a variable template specialization, which refers to a variable template with a given set o...
Represents a GCC generic vector type.
Definition: Type.h:4034
const internal::VariadicAllOfMatcher< Attr > attr
Matches attributes.
bool generateFullUSRForTopLevelModuleName(StringRef ModName, raw_ostream &OS)
Generate a USR for a top-level module name, including the USR prefix.
static StringRef getUSRSpacePrefix()
Definition: USRGeneration.h:27
void generateUSRForObjCCategory(StringRef Cls, StringRef Cat, raw_ostream &OS, StringRef ClsExtSymbolDefinedIn="", StringRef CatExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C class category.
bool generateFullUSRForModule(const Module *Mod, raw_ostream &OS)
Generate a USR for a module, including the USR prefix.
bool generateUSRFragmentForModuleName(StringRef ModName, raw_ostream &OS)
Generate a USR fragment for a module name.
bool generateUSRForMacro(const MacroDefinitionRecord *MD, const SourceManager &SM, SmallVectorImpl< char > &Buf)
Generate a USR for a macro, including the USR prefix.
void generateUSRForObjCProperty(StringRef Prop, bool isClassProp, raw_ostream &OS)
Generate a USR fragment for an Objective-C property.
void generateUSRForEnumConstant(StringRef EnumConstantName, raw_ostream &OS)
Generate a USR fragment for an enum constant.
void generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS)
Generate a USR fragment for an Objective-C instance variable.
void generateUSRForObjCMethod(StringRef Sel, bool IsInstanceMethod, raw_ostream &OS)
Generate a USR fragment for an Objective-C method.
bool generateUSRForType(QualType T, ASTContext &Ctx, SmallVectorImpl< char > &Buf)
Generates a USR for a type.
void generateUSRForObjCClass(StringRef Cls, raw_ostream &OS, StringRef ExtSymbolDefinedIn="", StringRef CategoryContextExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C class.
void generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS, StringRef ExtSymbolDefinedIn="")
Generate USR fragment for a global (non-nested) enum.
void generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS, StringRef ExtSymbolDefinedIn="")
Generate a USR fragment for an Objective-C protocol.
bool generateUSRFragmentForModule(const Module *Mod, raw_ostream &OS)
Generate a USR fragment for a module.
bool generateUSRForDecl(const Decl *D, SmallVectorImpl< char > &Buf)
Generate a USR for a Decl, including the USR prefix.
The JSON file list parser is used to communicate input to InstallAPI.
@ RQ_None
No ref-qualifier was provided.
Definition: Type.h:1768
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1771
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1774
const FunctionProtoType * T
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:676
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57
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.