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