clang 22.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"
17#include "llvm/Support/Path.h"
18#include "llvm/Support/raw_ostream.h"
19
20using namespace clang;
21using namespace clang::index;
22
23//===----------------------------------------------------------------------===//
24// USR generation.
25//===----------------------------------------------------------------------===//
26
27/// \returns true on error.
28static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
29 const SourceManager &SM, bool IncludeOffset) {
30 if (Loc.isInvalid()) {
31 return true;
32 }
33 Loc = SM.getExpansionLoc(Loc);
34 const FileIDAndOffset &Decomposed = SM.getDecomposedLoc(Loc);
35 OptionalFileEntryRef FE = SM.getFileEntryRefForID(Decomposed.first);
36 if (FE) {
37 OS << llvm::sys::path::filename(FE->getName());
38 } else {
39 // This case really isn't interesting.
40 return true;
41 }
42 if (IncludeOffset) {
43 // Use the offest into the FileID to represent the location. Using
44 // a line/column can cause us to look back at the original source file,
45 // which is expensive.
46 OS << '@' << Decomposed.second;
47 }
48 return false;
49}
50
51static StringRef GetExternalSourceContainer(const NamedDecl *D) {
52 if (!D)
53 return StringRef();
54 if (auto *attr = D->getExternalSourceSymbolAttr()) {
55 return attr->getDefinedIn();
56 }
57 return StringRef();
58}
59
60namespace {
61class USRGenerator : public ConstDeclVisitor<USRGenerator> {
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<char> &Buf,
73 const LangOptions &LangOpts)
74 : Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) {
75 // Add the USR space prefix.
76 Out << getUSRSpacePrefix();
77 }
78
79 bool ignoreResults() const { return IgnoreResults; }
80
81 // Visitation methods from generating USRs from AST elements.
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; // No USRs for linkage specs themselves.
108 }
109
110 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
111 IgnoreResults = true;
112 }
113
114 void VisitUsingDecl(const UsingDecl *D) {
115 VisitDeclContext(D->getDeclContext());
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) {
126 return D->getParentFunctionOrMethod() != nullptr;
127 }
128
129 void GenExtSymbolContainer(const NamedDecl *D);
130
131 /// Generate the string component containing the location of the
132 /// declaration.
133 bool GenLoc(const Decl *D, bool IncludeOffset);
134
135 /// String generation methods used both by the visitation methods
136 /// and from other clients that want to directly generate USRs. These
137 /// methods do not construct complete USRs (which incorporate the parents
138 /// of an AST element), but only the fragments concerning the AST element
139 /// itself.
140
141 /// Generate a USR for an Objective-C class.
142 void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
143 StringRef CategoryContextExtSymbolDefinedIn) {
144 generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
145 CategoryContextExtSymbolDefinedIn);
146 }
147
148 /// Generate a USR for an Objective-C class category.
149 void GenObjCCategory(StringRef cls, StringRef cat,
150 StringRef clsExt, StringRef catExt) {
151 generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
152 }
153
154 /// Generate a USR fragment for an Objective-C property.
155 void GenObjCProperty(StringRef prop, bool isClassProp) {
156 generateUSRForObjCProperty(prop, isClassProp, Out);
157 }
158
159 /// Generate a USR for an Objective-C protocol.
160 void GenObjCProtocol(StringRef prot, StringRef ext) {
161 generateUSRForObjCProtocol(prot, Out, ext);
162 }
163
164 void VisitType(QualType T);
165 void VisitTemplateParameterList(const TemplateParameterList *Params);
166 void VisitTemplateName(TemplateName Name);
167 void VisitTemplateArgument(const TemplateArgument &Arg);
168
169 void VisitMSGuidDecl(const MSGuidDecl *D);
170
171 /// Emit a Decl's name using NamedDecl::printName() and return true if
172 /// the decl had no name.
173 bool EmitDeclName(const NamedDecl *D);
174};
175} // end anonymous namespace
176
177//===----------------------------------------------------------------------===//
178// Generating USRs from ASTS.
179//===----------------------------------------------------------------------===//
180
181bool USRGenerator::EmitDeclName(const NamedDecl *D) {
182 DeclarationName N = D->getDeclName();
183 if (N.isEmpty())
184 return true;
185 Out << N;
186 return false;
187}
188
189bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
190 if (D->isExternallyVisible())
191 return false;
193 return true;
195 if (Loc.isInvalid())
196 return false;
197 const SourceManager &SM = Context->getSourceManager();
198 return !SM.isInSystemHeader(Loc);
199}
200
201void USRGenerator::VisitDeclContext(const DeclContext *DC) {
202 if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
203 Visit(D);
204 else if (isa<LinkageSpecDecl>(DC)) // Linkage specs are transparent in USRs.
205 VisitDeclContext(DC->getParent());
206}
207
208void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
209 // The USR for an ivar declared in a class extension is based on the
210 // ObjCInterfaceDecl, not the ObjCCategoryDecl.
211 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
212 Visit(ID);
213 else
214 VisitDeclContext(D->getDeclContext());
215 Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
216 if (EmitDeclName(D)) {
217 // Bit fields can be anonymous.
218 IgnoreResults = true;
219 return;
220 }
221}
222
223void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
224 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
225 return;
226
227 if (D->getType().isNull()) {
228 IgnoreResults = true;
229 return;
230 }
231
232 const unsigned StartSize = Buf.size();
233 VisitDeclContext(D->getDeclContext());
234 if (Buf.size() == StartSize)
235 GenExtSymbolContainer(D);
236
237 bool IsTemplate = false;
238 if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
239 IsTemplate = true;
240 Out << "@FT@";
241 VisitTemplateParameterList(FunTmpl->getTemplateParameters());
242 } else
243 Out << "@F@";
244
245 PrintingPolicy Policy(LangOpts);
246 // Forward references can have different template argument names. Suppress the
247 // template argument names in constructors to make their USR more stable.
248 Policy.SuppressTemplateArgsInCXXConstructors = true;
249 D->getDeclName().print(Out, Policy);
250
251 if ((!LangOpts.CPlusPlus || D->isExternC()) &&
252 !D->hasAttr<OverloadableAttr>())
253 return;
254
255 if (D->isFunctionTemplateSpecialization()) {
256 Out << '<';
257 if (const TemplateArgumentList *SpecArgs =
258 D->getTemplateSpecializationArgs()) {
259 for (const auto &Arg : SpecArgs->asArray()) {
260 Out << '#';
261 VisitTemplateArgument(Arg);
262 }
263 } else if (const ASTTemplateArgumentListInfo *SpecArgsWritten =
264 D->getTemplateSpecializationArgsAsWritten()) {
265 for (const auto &ArgLoc : SpecArgsWritten->arguments()) {
266 Out << '#';
267 VisitTemplateArgument(ArgLoc.getArgument());
268 }
269 }
270 Out << '>';
271 }
272
273 QualType CanonicalType = D->getType().getCanonicalType();
274 // Mangle in type information for the arguments.
275 if (const auto *FPT = CanonicalType->getAs<FunctionProtoType>()) {
276 for (QualType PT : FPT->param_types()) {
277 Out << '#';
278 VisitType(PT);
279 }
280 }
281 if (D->isVariadic())
282 Out << '.';
283 if (IsTemplate) {
284 // Function templates can be overloaded by return type, for example:
285 // \code
286 // template <class T> typename T::A foo() {}
287 // template <class T> typename T::B foo() {}
288 // \endcode
289 Out << '#';
290 VisitType(D->getReturnType());
291 }
292 Out << '#';
293 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
294 if (MD->isStatic())
295 Out << 'S';
296 // FIXME: OpenCL: Need to consider address spaces
297 if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
298 Out << (char)('0' + quals);
299 switch (MD->getRefQualifier()) {
300 case RQ_None: break;
301 case RQ_LValue: Out << '&'; break;
302 case RQ_RValue: Out << "&&"; break;
303 }
304 }
305}
306
307void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
308 VisitDeclContext(D->getDeclContext());
309 Out << "@";
310
311 if (EmitDeclName(D)) {
312 // The string can be empty if the declaration has no name; e.g., it is
313 // the ParmDecl with no name for declaration of a function pointer type,
314 // e.g.: void (*f)(void *);
315 // In this case, don't generate a USR.
316 IgnoreResults = true;
317 }
318}
319
320void USRGenerator::VisitVarDecl(const VarDecl *D) {
321 // VarDecls can be declared 'extern' within a function or method body,
322 // but their enclosing DeclContext is the function, not the TU. We need
323 // to check the storage class to correctly generate the USR.
324 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
325 return;
326
327 VisitDeclContext(D->getDeclContext());
328
329 if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
330 Out << "@VT";
331 VisitTemplateParameterList(VarTmpl->getTemplateParameters());
332 } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
333 = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
334 Out << "@VP";
335 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
336 }
337
338 // Variables always have simple names.
339 StringRef s = D->getName();
340
341 // The string can be empty if the declaration has no name; e.g., it is
342 // the ParmDecl with no name for declaration of a function pointer type, e.g.:
343 // void (*f)(void *);
344 // In this case, don't generate a USR.
345 if (s.empty())
346 IgnoreResults = true;
347 else
348 Out << '@' << s;
349
350 // For a template specialization, mangle the template arguments.
351 if (const VarTemplateSpecializationDecl *Spec
352 = dyn_cast<VarTemplateSpecializationDecl>(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, /*IncludeOffset=*/true))
364 return;
365 VisitNamedDecl(D);
366}
367
368void USRGenerator::VisitNonTypeTemplateParmDecl(
369 const NonTypeTemplateParmDecl *D) {
370 GenLoc(D, /*IncludeOffset=*/true);
371}
372
373void USRGenerator::VisitTemplateTemplateParmDecl(
375 GenLoc(D, /*IncludeOffset=*/true);
376}
377
378void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
379 if (IgnoreResults)
380 return;
381 VisitDeclContext(D->getDeclContext());
382 if (D->isAnonymousNamespace()) {
383 Out << "@aN";
384 return;
385 }
386 Out << "@N@" << D->getName();
387}
388
389void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
390 VisitFunctionDecl(D->getTemplatedDecl());
391}
392
393void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
394 VisitTagDecl(D->getTemplatedDecl());
395}
396
397void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
398 VisitDeclContext(D->getDeclContext());
399 if (!IgnoreResults)
400 Out << "@NA@" << D->getName();
401}
402
404 if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
405 return CD;
406 if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
407 return ICD->getCategoryDecl();
408 return nullptr;
409}
410
411void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
412 const DeclContext *container = D->getDeclContext();
413 if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
414 Visit(pd);
415 }
416 else {
417 // The USR for a method declared in a class extension or category is based on
418 // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
419 const ObjCInterfaceDecl *ID = D->getClassInterface();
420 if (!ID) {
421 IgnoreResults = true;
422 return;
423 }
424 auto *CD = getCategoryContext(D);
425 VisitObjCContainerDecl(ID, CD);
426 }
427 // Ideally we would use 'GenObjCMethod', but this is such a hot path
428 // for Objective-C code that we don't want to use
429 // DeclarationName::getAsString().
430 Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
431 << DeclarationName(D->getSelector());
432}
433
434void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
435 const ObjCCategoryDecl *CatD) {
436 switch (D->getKind()) {
437 default:
438 llvm_unreachable("Invalid ObjC container.");
439 case Decl::ObjCInterface:
440 case Decl::ObjCImplementation:
441 GenObjCClass(D->getName(), GetExternalSourceContainer(D),
443 break;
444 case Decl::ObjCCategory: {
445 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
447 if (!ID) {
448 // Handle invalid code where the @interface might not
449 // have been specified.
450 // FIXME: We should be able to generate this USR even if the
451 // @interface isn't available.
452 IgnoreResults = true;
453 return;
454 }
455 // Specially handle class extensions, which are anonymous categories.
456 // We want to mangle in the location to uniquely distinguish them.
457 if (CD->IsClassExtension()) {
458 Out << "objc(ext)" << ID->getName() << '@';
459 GenLoc(CD, /*IncludeOffset=*/true);
460 }
461 else
462 GenObjCCategory(ID->getName(), CD->getName(),
465
466 break;
467 }
468 case Decl::ObjCCategoryImpl: {
469 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
471 if (!ID) {
472 // Handle invalid code where the @interface might not
473 // have been specified.
474 // FIXME: We should be able to generate this USR even if the
475 // @interface isn't available.
476 IgnoreResults = true;
477 return;
478 }
479 GenObjCCategory(ID->getName(), CD->getName(),
482 break;
483 }
484 case Decl::ObjCProtocol: {
485 const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
486 GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
487 break;
488 }
489 }
490}
491
492void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
493 // The USR for a property declared in a class extension or category is based
494 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
495 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
496 VisitObjCContainerDecl(ID, getCategoryContext(D));
497 else
498 Visit(cast<Decl>(D->getDeclContext()));
499 GenObjCProperty(D->getName(), D->isClassProperty());
500}
501
502void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
503 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
504 VisitObjCPropertyDecl(PD);
505 return;
506 }
507
508 IgnoreResults = true;
509}
510
511void USRGenerator::VisitTagDecl(const TagDecl *D) {
512 // Add the location of the tag decl to handle resolution across
513 // translation units.
514 if (!isa<EnumDecl>(D) &&
515 ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
516 return;
517
518 GenExtSymbolContainer(D);
519
520 D = D->getCanonicalDecl();
521 VisitDeclContext(D->getDeclContext());
522
523 bool AlreadyStarted = false;
524 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
525 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
526 AlreadyStarted = true;
527
528 switch (D->getTagKind()) {
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<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
543 AlreadyStarted = true;
544
545 switch (D->getTagKind()) {
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) {
562 switch (D->getTagKind()) {
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)) {
582 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
583 Buf[off] = 'A';
584 Out << '@' << *TD;
585 } else {
586 if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
587 printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
588 } else {
589 Buf[off] = 'a';
590 if (auto *ED = dyn_cast<EnumDecl>(D)) {
591 // Distinguish USRs of anonymous enums by using their first
592 // enumerator.
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 // For a class template specialization, mangle the template arguments.
603 if (const ClassTemplateSpecializationDecl *Spec
604 = dyn_cast<ClassTemplateSpecializationDecl>(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, /*IncludeOffset=*/isLocal(D)))
616 return;
617 const DeclContext *DC = D->getDeclContext();
618 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
619 Visit(DCN);
620 Out << "@T@";
621 Out << D->getName();
622}
623
624void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
625 GenLoc(D, /*IncludeOffset=*/true);
626}
627
628void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
629 StringRef Container = GetExternalSourceContainer(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 // Guard against null declarations in invalid code.
640 if (!D) {
641 IgnoreResults = true;
642 return true;
643 }
644
645 // Use the location of canonical decl.
646 D = D->getCanonicalDecl();
647
648 IgnoreResults =
649 IgnoreResults || printLoc(Out, D->getBeginLoc(),
650 Context->getSourceManager(), IncludeOffset);
651
652 return IgnoreResults;
653}
654
655static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts,
657 // FIXME: Encode the qualifier, don't just print it.
658 PrintingPolicy PO(LangOpts);
659 PO.SuppressTagKeyword = true;
660 PO.SuppressUnwrittenScope = true;
662 PO.AnonymousTagLocations = false;
663 NNS.print(Out, PO);
664}
665
666void USRGenerator::VisitType(QualType T) {
667 // This method mangles in USR information for types. It can possibly
668 // just reuse the naming-mangling logic used by codegen, although the
669 // requirements for USRs might not be the same.
670 ASTContext &Ctx = *Context;
671
672 do {
673 T = Ctx.getCanonicalType(T);
674 Qualifiers Q = T.getQualifiers();
675 unsigned qVal = 0;
676 if (Q.hasConst())
677 qVal |= 0x1;
678 if (Q.hasVolatile())
679 qVal |= 0x2;
680 if (Q.hasRestrict())
681 qVal |= 0x4;
682 if(qVal)
683 Out << ((char) ('0' + qVal));
684
685 // Mangle in ObjC GC qualifiers?
686
687 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
688 Out << 'P';
689 T = Expansion->getPattern();
690 }
691
692 if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
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 // 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. Otherwise, record this as a substitution.
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<PointerType>()) {
870 Out << '*';
871 T = PT->getPointeeType();
872 continue;
873 }
874 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
875 Out << '*';
876 T = OPT->getPointeeType();
877 continue;
878 }
879 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
880 Out << "&&";
881 T = RT->getPointeeType();
882 continue;
883 }
884 if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
885 Out << '&';
886 T = RT->getPointeeType();
887 continue;
888 }
889 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
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<BlockPointerType>()) {
903 Out << 'B';
904 T = BT->getPointeeType();
905 continue;
906 }
907 if (const ComplexType *CT = T->getAs<ComplexType>()) {
908 Out << '<';
909 T = CT->getElementType();
910 continue;
911 }
912 if (const TagType *TT = T->getAs<TagType>()) {
913 if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TT)) {
914 T = ICNT->getOriginalDecl()->getCanonicalTemplateSpecializationType(
915 Ctx);
916 } else {
917 Out << '$';
918 VisitTagDecl(TT->getOriginalDecl());
919 return;
920 }
921 }
922 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
923 Out << '$';
924 VisitObjCInterfaceDecl(OIT->getDecl());
925 return;
926 }
927 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
928 Out << 'Q';
929 VisitType(OIT->getBaseType());
930 for (auto *Prot : OIT->getProtocols())
931 VisitObjCProtocolDecl(Prot);
932 return;
933 }
934 if (const TemplateTypeParmType *TTP =
936 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
937 return;
938 }
939 if (const TemplateSpecializationType *Spec
941 Out << '>';
942 VisitTemplateName(Spec->getTemplateName());
943 Out << Spec->template_arguments().size();
944 for (const auto &Arg : Spec->template_arguments())
945 VisitTemplateArgument(Arg);
946 return;
947 }
948 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
949 Out << '^';
950 printQualifier(Out, LangOpts, DNT->getQualifier());
951 Out << ':' << DNT->getIdentifier()->getName();
952 return;
953 }
954 if (const auto *VT = T->getAs<VectorType>()) {
955 Out << (T->isExtVectorType() ? ']' : '[');
956 Out << VT->getNumElements();
957 T = VT->getElementType();
958 continue;
959 }
960 if (const auto *const AT = dyn_cast<ArrayType>(T)) {
961 Out << '{';
962 switch (AT->getSizeModifier()) {
963 case ArraySizeModifier::Static:
964 Out << 's';
965 break;
966 case ArraySizeModifier::Star:
967 Out << '*';
968 break;
969 case ArraySizeModifier::Normal:
970 Out << 'n';
971 break;
972 }
973 if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
974 Out << CAT->getSize();
975
976 T = AT->getElementType();
977 continue;
978 }
979
980 // Unhandled type.
981 Out << ' ';
982 break;
983 } while (true);
984}
985
986void USRGenerator::VisitTemplateParameterList(
987 const TemplateParameterList *Params) {
988 if (!Params)
989 return;
990 Out << '>' << Params->size();
992 PEnd = Params->end();
993 P != PEnd; ++P) {
994 Out << '#';
995 if (isa<TemplateTypeParmDecl>(*P)) {
996 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
997 Out<< 'p';
998 Out << 'T';
999 continue;
1000 }
1001
1002 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1003 if (NTTP->isParameterPack())
1004 Out << 'p';
1005 Out << 'N';
1006 VisitType(NTTP->getType());
1007 continue;
1008 }
1009
1010 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1011 if (TTP->isParameterPack())
1012 Out << 'p';
1013 Out << 't';
1014 VisitTemplateParameterList(TTP->getTemplateParameters());
1015 }
1016}
1017
1018void USRGenerator::VisitTemplateName(TemplateName Name) {
1019 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1021 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
1022 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1023 return;
1024 }
1025
1026 Visit(Template);
1027 return;
1028 }
1029
1030 // FIXME: Visit dependent template names.
1031}
1032
1033void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
1034 switch (Arg.getKind()) {
1036 break;
1037
1039 Visit(Arg.getAsDecl());
1040 break;
1041
1043 break;
1044
1046 Out << 'P'; // pack expansion of...
1047 [[fallthrough]];
1049 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1050 break;
1051
1053 // FIXME: Visit expressions.
1054 break;
1055
1057 Out << 'p' << Arg.pack_size();
1058 for (const auto &P : Arg.pack_elements())
1059 VisitTemplateArgument(P);
1060 break;
1061
1063 VisitType(Arg.getAsType());
1064 break;
1065
1067 Out << 'V';
1068 VisitType(Arg.getIntegralType());
1069 Out << Arg.getAsIntegral();
1070 break;
1071
1073 Out << 'S';
1074 VisitType(Arg.getStructuralValueType());
1075 ODRHash Hash{};
1077 Out << Hash.CalculateHash();
1078 break;
1079 }
1080 }
1081}
1082
1083void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1084 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1085 return;
1086 VisitDeclContext(D->getDeclContext());
1087 Out << "@UUV@";
1088 printQualifier(Out, LangOpts, D->getQualifier());
1089 EmitDeclName(D);
1090}
1091
1092void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
1093 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1094 return;
1095 VisitDeclContext(D->getDeclContext());
1096 Out << "@UUT@";
1097 printQualifier(Out, LangOpts, D->getQualifier());
1098 Out << D->getName(); // Simple name.
1099}
1100
1101void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
1102 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1103 return;
1104 VisitDeclContext(D->getDeclContext());
1105 Out << "@CT@";
1106 EmitDeclName(D);
1107}
1108
1109void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
1110 VisitDeclContext(D->getDeclContext());
1111 Out << "@MG@";
1112 D->NamedDecl::printName(Out);
1113}
1114
1115//===----------------------------------------------------------------------===//
1116// USR generation functions.
1117//===----------------------------------------------------------------------===//
1118
1119static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
1120 StringRef CatSymDefinedIn,
1121 raw_ostream &OS) {
1122 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
1123 return;
1124 if (CatSymDefinedIn.empty()) {
1125 OS << "@M@" << ClsSymDefinedIn << '@';
1126 return;
1127 }
1128 OS << "@CM@" << CatSymDefinedIn << '@';
1129 if (ClsSymDefinedIn != CatSymDefinedIn) {
1130 OS << ClsSymDefinedIn << '@';
1131 }
1132}
1133
1134void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
1135 StringRef ExtSymDefinedIn,
1136 StringRef CategoryContextExtSymbolDefinedIn) {
1138 CategoryContextExtSymbolDefinedIn, OS);
1139 OS << "objc(cs)" << Cls;
1140}
1141
1142void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
1143 raw_ostream &OS,
1144 StringRef ClsSymDefinedIn,
1145 StringRef CatSymDefinedIn) {
1146 combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
1147 OS << "objc(cy)" << Cls << '@' << Cat;
1148}
1149
1150void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
1151 OS << '@' << Ivar;
1152}
1153
1155 bool IsInstanceMethod,
1156 raw_ostream &OS) {
1157 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
1158}
1159
1160void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
1161 raw_ostream &OS) {
1162 OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
1163}
1164
1165void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
1166 StringRef ExtSymDefinedIn) {
1167 if (!ExtSymDefinedIn.empty())
1168 OS << "@M@" << ExtSymDefinedIn << '@';
1169 OS << "objc(pl)" << Prot;
1170}
1171
1172void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
1173 StringRef ExtSymDefinedIn) {
1174 if (!ExtSymDefinedIn.empty())
1175 OS << "@M@" << ExtSymDefinedIn;
1176 OS << "@E@" << EnumName;
1177}
1178
1179void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
1180 raw_ostream &OS) {
1181 OS << '@' << EnumConstantName;
1182}
1183
1185 SmallVectorImpl<char> &Buf) {
1186 if (!D)
1187 return true;
1188 return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts());
1189}
1190
1192 const LangOptions &LangOpts) {
1193 if (!D)
1194 return true;
1195 // We don't ignore decls with invalid source locations. Implicit decls, like
1196 // C++'s operator new function, can have invalid locations but it is fine to
1197 // create USRs that can identify them.
1198
1199 // Check if the declaration has explicit external USR specified.
1200 auto *CD = D->getCanonicalDecl();
1201 if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
1202 if (!ExternalSymAttr->getUSR().empty()) {
1203 llvm::raw_svector_ostream Out(Buf);
1204 Out << ExternalSymAttr->getUSR();
1205 return false;
1206 }
1207 }
1208 USRGenerator UG(&D->getASTContext(), Buf, LangOpts);
1209 UG.Visit(D);
1210 return UG.ignoreResults();
1211}
1212
1214 const SourceManager &SM,
1215 SmallVectorImpl<char> &Buf) {
1216 if (!MD)
1217 return true;
1218 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1219 SM, Buf);
1220
1221}
1222
1224 const SourceManager &SM,
1225 SmallVectorImpl<char> &Buf) {
1226 if (MacroName.empty())
1227 return true;
1228
1229 llvm::raw_svector_ostream Out(Buf);
1230
1231 // Assume that system headers are sane. Don't put source location
1232 // information into the USR if the macro comes from a system header.
1233 bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
1234
1235 Out << getUSRSpacePrefix();
1236 if (ShouldGenerateLocation)
1237 printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1238 Out << "@macro@";
1239 Out << MacroName;
1240 return false;
1241}
1242
1244 SmallVectorImpl<char> &Buf) {
1245 return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts());
1246}
1247
1250 const LangOptions &LangOpts) {
1251 if (T.isNull())
1252 return true;
1253 T = T.getCanonicalType();
1254
1255 USRGenerator UG(&Ctx, Buf, LangOpts);
1256 UG.VisitType(T);
1257 return UG.ignoreResults();
1258}
1259
1261 raw_ostream &OS) {
1262 if (!Mod->Parent)
1264 if (generateFullUSRForModule(Mod->Parent, OS))
1265 return true;
1266 return generateUSRFragmentForModule(Mod, OS);
1267}
1268
1270 raw_ostream &OS) {
1271 OS << getUSRSpacePrefix();
1272 return generateUSRFragmentForModuleName(ModName, OS);
1273}
1274
1276 raw_ostream &OS) {
1277 return generateUSRFragmentForModuleName(Mod->Name, OS);
1278}
1279
1281 raw_ostream &OS) {
1282 OS << "@M@" << ModName;
1283 return false;
1284}
Defines the clang::ASTContext interface.
StringRef P
const Decl * D
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,...
#define SM(sm)
Definition: OffloadArch.cpp:16
SourceLocation Loc
Definition: SemaObjC.cpp:754
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:801
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2851
const LangOptions & getLangOpts() const
Definition: ASTContext.h:894
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:4179
Pointer to a block type.
Definition: TypeBase.h:3558
This class is used for builtin types like 'int'.
Definition: TypeBase.h:3182
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2129
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: TypeBase.h:3293
Declaration of a C++20 concept.
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:75
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1449
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2109
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:319
T * getAttr() const
Definition: DeclBase.h:573
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:524
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
Definition: DeclBase.cpp:590
SourceLocation getLocation() const
Definition: DeclBase.h:439
DeclContext * getDeclContext()
Definition: DeclBase.h:448
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:431
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
bool hasAttr() const
Definition: DeclBase.h:577
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:978
Kind getKind() const
Definition: DeclBase.h:442
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: TypeBase.h:7414
Represents a member of a struct/union/class.
Definition: Decl.h:3153
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
Represents a function declaration or definition.
Definition: Decl.h:1999
Represents a prototype with parameter type info, e.g.
Definition: TypeBase.h:5282
Declaration of a template function.
Definition: DeclTemplate.h:952
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...
Definition: LangOptions.h:434
Represents a linkage specification.
Definition: DeclCXX.h:3009
A global _GUID constant.
Definition: DeclCXX.h:4392
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:144
Module * Parent
The parent of this module.
Definition: Module.h:193
std::string Name
The name of this module.
Definition: Module.h:147
This represents a decl that may have a name.
Definition: Decl.h:273
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:300
Represents a C++ namespace alias.
Definition: DeclCXX.h:3195
Represent a C++ namespace.
Definition: Decl.h:591
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
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.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
void AddStructuralValue(const APValue &)
Definition: ODRHash.cpp:1268
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2329
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2372
bool IsClassExtension() const
Definition: DeclObjC.h:2437
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2545
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:948
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2486
Represents an ObjC class declaration.
Definition: DeclObjC.h:1154
Interfaces are the core concept in Objective-C for object oriented design.
Definition: TypeBase.h:7905
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition: TypeBase.h:7961
Represents a class type in Objective C.
Definition: TypeBase.h:7707
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:731
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2805
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2084
Represents a pack expansion of types.
Definition: TypeBase.h:7524
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: TypeBase.h:3346
A (possibly-)qualified type.
Definition: TypeBase.h:937
The collection of all-type qualifiers we support.
Definition: TypeBase.h:331
bool hasConst() const
Definition: TypeBase.h:457
bool hasRestrict() const
Definition: TypeBase.h:477
bool hasVolatile() const
Definition: TypeBase.h:467
An rvalue reference type, per C++11 [dcl.ref].
Definition: TypeBase.h:3651
Base for LValueReferenceType and RValueReferenceType.
Definition: TypeBase.h:3589
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:3710
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:402
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:322
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
Definition: TemplateBase.h:366
unsigned pack_size() const
The number of template arguments in the given template argument pack.
Definition: TemplateBase.h:446
QualType getIntegralType() const
Retrieve the type of the integral value.
Definition: TemplateBase.h:380
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
Definition: TemplateBase.h:329
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:440
@ 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:296
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:353
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
Definition: TemplateBase.h:399
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:396
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:415
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:74
NamedDecl *const * const_iterator
Iterates through the template parameters in this list.
Definition: DeclTemplate.h:133
Represents a type template specialization; the template must be a class template, a type alias templa...
Definition: TypeBase.h:7290
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:752
bool isExtVectorType() const
Definition: TypeBase.h:8723
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition: TypeBase.h:2939
const T * getAs() const
Member-template getAs<specific type>'.
Definition: TypeBase.h:9159
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3660
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3555
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:4031
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3934
Represents a C++ using-declaration.
Definition: DeclCXX.h:3585
Represents C++ using-directive.
Definition: DeclCXX.h:3090
Represents a variable declaration or definition.
Definition: Decl.h:925
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: TypeBase.h:4191
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.
std::pair< FileID, unsigned > FileIDAndOffset
@ RQ_None
No ref-qualifier was provided.
Definition: TypeBase.h:1782
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: TypeBase.h:1785
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: TypeBase.h:1788
@ Template
We are parsing a template declaration.
const FunctionProtoType * T
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
Definition: TemplateBase.h:678
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.