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