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