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 // Mangle in type information for the arguments.
271 for (auto *PD : D->parameters()) {
272 Out << '#';
273 VisitType(PD->getType());
274 }
275 if (D->isVariadic())
276 Out << '.';
277 if (IsTemplate) {
278 // Function templates can be overloaded by return type, for example:
279 // \code
280 // template <class T> typename T::A foo() {}
281 // template <class T> typename T::B foo() {}
282 // \endcode
283 Out << '#';
284 VisitType(D->getReturnType());
285 }
286 Out << '#';
287 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
288 if (MD->isStatic())
289 Out << 'S';
290 // FIXME: OpenCL: Need to consider address spaces
291 if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
292 Out << (char)('0' + quals);
293 switch (MD->getRefQualifier()) {
294 case RQ_None: break;
295 case RQ_LValue: Out << '&'; break;
296 case RQ_RValue: Out << "&&"; break;
297 }
298 }
299}
300
301void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
302 VisitDeclContext(D->getDeclContext());
303 Out << "@";
304
305 if (EmitDeclName(D)) {
306 // The string can be empty if the declaration has no name; e.g., it is
307 // the ParmDecl with no name for declaration of a function pointer type,
308 // e.g.: void (*f)(void *);
309 // In this case, don't generate a USR.
310 IgnoreResults = true;
311 }
312}
313
314void USRGenerator::VisitVarDecl(const VarDecl *D) {
315 // VarDecls can be declared 'extern' within a function or method body,
316 // but their enclosing DeclContext is the function, not the TU. We need
317 // to check the storage class to correctly generate the USR.
318 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
319 return;
320
321 VisitDeclContext(D->getDeclContext());
322
323 if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
324 Out << "@VT";
325 VisitTemplateParameterList(VarTmpl->getTemplateParameters());
326 } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
327 = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
328 Out << "@VP";
329 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
330 }
331
332 // Variables always have simple names.
333 StringRef s = D->getName();
334
335 // The string can be empty if the declaration has no name; e.g., it is
336 // the ParmDecl with no name for declaration of a function pointer type, e.g.:
337 // void (*f)(void *);
338 // In this case, don't generate a USR.
339 if (s.empty())
340 IgnoreResults = true;
341 else
342 Out << '@' << s;
343
344 // For a template specialization, mangle the template arguments.
345 if (const VarTemplateSpecializationDecl *Spec
346 = dyn_cast<VarTemplateSpecializationDecl>(D)) {
347 const TemplateArgumentList &Args = Spec->getTemplateArgs();
348 Out << '>';
349 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
350 Out << '#';
351 VisitTemplateArgument(Args.get(I));
352 }
353 }
354}
355
356void USRGenerator::VisitBindingDecl(const BindingDecl *D) {
357 if (isLocal(D) && GenLoc(D, /*IncludeOffset=*/true))
358 return;
359 VisitNamedDecl(D);
360}
361
362void USRGenerator::VisitNonTypeTemplateParmDecl(
363 const NonTypeTemplateParmDecl *D) {
364 GenLoc(D, /*IncludeOffset=*/true);
365}
366
367void USRGenerator::VisitTemplateTemplateParmDecl(
368 const TemplateTemplateParmDecl *D) {
369 GenLoc(D, /*IncludeOffset=*/true);
370}
371
372void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
373 if (IgnoreResults)
374 return;
375 VisitDeclContext(D->getDeclContext());
376 if (D->isAnonymousNamespace()) {
377 Out << "@aN";
378 return;
379 }
380 Out << "@N@" << D->getName();
381}
382
383void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
384 VisitFunctionDecl(D->getTemplatedDecl());
385}
386
387void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
388 VisitTagDecl(D->getTemplatedDecl());
389}
390
391void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
392 VisitDeclContext(D->getDeclContext());
393 if (!IgnoreResults)
394 Out << "@NA@" << D->getName();
395}
396
398 if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
399 return CD;
400 if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
401 return ICD->getCategoryDecl();
402 return nullptr;
403}
404
405void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
406 const DeclContext *container = D->getDeclContext();
407 if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
408 Visit(pd);
409 }
410 else {
411 // The USR for a method declared in a class extension or category is based on
412 // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
414 if (!ID) {
415 IgnoreResults = true;
416 return;
417 }
418 auto *CD = getCategoryContext(D);
419 VisitObjCContainerDecl(ID, CD);
420 }
421 // Ideally we would use 'GenObjCMethod', but this is such a hot path
422 // for Objective-C code that we don't want to use
423 // DeclarationName::getAsString().
424 Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
426}
427
428void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
429 const ObjCCategoryDecl *CatD) {
430 switch (D->getKind()) {
431 default:
432 llvm_unreachable("Invalid ObjC container.");
433 case Decl::ObjCInterface:
434 case Decl::ObjCImplementation:
435 GenObjCClass(D->getName(), GetExternalSourceContainer(D),
437 break;
438 case Decl::ObjCCategory: {
439 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
441 if (!ID) {
442 // Handle invalid code where the @interface might not
443 // have been specified.
444 // FIXME: We should be able to generate this USR even if the
445 // @interface isn't available.
446 IgnoreResults = true;
447 return;
448 }
449 // Specially handle class extensions, which are anonymous categories.
450 // We want to mangle in the location to uniquely distinguish them.
451 if (CD->IsClassExtension()) {
452 Out << "objc(ext)" << ID->getName() << '@';
453 GenLoc(CD, /*IncludeOffset=*/true);
454 }
455 else
456 GenObjCCategory(ID->getName(), CD->getName(),
459
460 break;
461 }
462 case Decl::ObjCCategoryImpl: {
463 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
465 if (!ID) {
466 // Handle invalid code where the @interface might not
467 // have been specified.
468 // FIXME: We should be able to generate this USR even if the
469 // @interface isn't available.
470 IgnoreResults = true;
471 return;
472 }
473 GenObjCCategory(ID->getName(), CD->getName(),
476 break;
477 }
478 case Decl::ObjCProtocol: {
479 const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
480 GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
481 break;
482 }
483 }
484}
485
486void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
487 // The USR for a property declared in a class extension or category is based
488 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
489 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
490 VisitObjCContainerDecl(ID, getCategoryContext(D));
491 else
492 Visit(cast<Decl>(D->getDeclContext()));
493 GenObjCProperty(D->getName(), D->isClassProperty());
494}
495
496void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
497 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
498 VisitObjCPropertyDecl(PD);
499 return;
500 }
501
502 IgnoreResults = true;
503}
504
505void USRGenerator::VisitTagDecl(const TagDecl *D) {
506 // Add the location of the tag decl to handle resolution across
507 // translation units.
508 if (!isa<EnumDecl>(D) &&
509 ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
510 return;
511
512 GenExtSymbolContainer(D);
513
514 D = D->getCanonicalDecl();
515 VisitDeclContext(D->getDeclContext());
516
517 bool AlreadyStarted = false;
518 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
519 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
520 AlreadyStarted = true;
521
522 switch (D->getTagKind()) {
523 case TagTypeKind::Interface:
524 case TagTypeKind::Class:
525 case TagTypeKind::Struct:
526 Out << "@ST";
527 break;
528 case TagTypeKind::Union:
529 Out << "@UT";
530 break;
531 case TagTypeKind::Enum:
532 llvm_unreachable("enum template");
533 }
534 VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
535 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
536 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
537 AlreadyStarted = true;
538
539 switch (D->getTagKind()) {
540 case TagTypeKind::Interface:
541 case TagTypeKind::Class:
542 case TagTypeKind::Struct:
543 Out << "@SP";
544 break;
545 case TagTypeKind::Union:
546 Out << "@UP";
547 break;
548 case TagTypeKind::Enum:
549 llvm_unreachable("enum partial specialization");
550 }
551 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
552 }
553 }
554
555 if (!AlreadyStarted) {
556 switch (D->getTagKind()) {
557 case TagTypeKind::Interface:
558 case TagTypeKind::Class:
559 case TagTypeKind::Struct:
560 Out << "@S";
561 break;
562 case TagTypeKind::Union:
563 Out << "@U";
564 break;
565 case TagTypeKind::Enum:
566 Out << "@E";
567 break;
568 }
569 }
570
571 Out << '@';
572 assert(Buf.size() > 0);
573 const unsigned off = Buf.size() - 1;
574
575 if (EmitDeclName(D)) {
576 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
577 Buf[off] = 'A';
578 Out << '@' << *TD;
579 } else {
580 if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
581 printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
582 } else {
583 Buf[off] = 'a';
584 if (auto *ED = dyn_cast<EnumDecl>(D)) {
585 // Distinguish USRs of anonymous enums by using their first
586 // enumerator.
587 auto enum_range = ED->enumerators();
588 if (enum_range.begin() != enum_range.end()) {
589 Out << '@' << **enum_range.begin();
590 }
591 }
592 }
593 }
594 }
595
596 // For a class template specialization, mangle the template arguments.
597 if (const ClassTemplateSpecializationDecl *Spec
598 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
599 const TemplateArgumentList &Args = Spec->getTemplateArgs();
600 Out << '>';
601 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
602 Out << '#';
603 VisitTemplateArgument(Args.get(I));
604 }
605 }
606}
607
608void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
609 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
610 return;
611 const DeclContext *DC = D->getDeclContext();
612 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
613 Visit(DCN);
614 Out << "@T@";
615 Out << D->getName();
616}
617
618void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
619 GenLoc(D, /*IncludeOffset=*/true);
620}
621
622void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
623 StringRef Container = GetExternalSourceContainer(D);
624 if (!Container.empty())
625 Out << "@M@" << Container;
626}
627
628bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
629 if (generatedLoc)
630 return IgnoreResults;
631 generatedLoc = true;
632
633 // Guard against null declarations in invalid code.
634 if (!D) {
635 IgnoreResults = true;
636 return true;
637 }
638
639 // Use the location of canonical decl.
640 D = D->getCanonicalDecl();
641
642 IgnoreResults =
643 IgnoreResults || printLoc(Out, D->getBeginLoc(),
644 Context->getSourceManager(), IncludeOffset);
645
646 return IgnoreResults;
647}
648
649static void printQualifier(llvm::raw_ostream &Out, ASTContext &Ctx, NestedNameSpecifier *NNS) {
650 // FIXME: Encode the qualifier, don't just print it.
651 PrintingPolicy PO(Ctx.getLangOpts());
652 PO.SuppressTagKeyword = true;
653 PO.SuppressUnwrittenScope = true;
655 PO.AnonymousTagLocations = false;
656 NNS->print(Out, PO);
657}
658
659void USRGenerator::VisitType(QualType T) {
660 // This method mangles in USR information for types. It can possibly
661 // just reuse the naming-mangling logic used by codegen, although the
662 // requirements for USRs might not be the same.
663 ASTContext &Ctx = *Context;
664
665 do {
666 T = Ctx.getCanonicalType(T);
668 unsigned qVal = 0;
669 if (Q.hasConst())
670 qVal |= 0x1;
671 if (Q.hasVolatile())
672 qVal |= 0x2;
673 if (Q.hasRestrict())
674 qVal |= 0x4;
675 if(qVal)
676 Out << ((char) ('0' + qVal));
677
678 // Mangle in ObjC GC qualifiers?
679
680 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
681 Out << 'P';
682 T = Expansion->getPattern();
683 }
684
685 if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
686 switch (BT->getKind()) {
687 case BuiltinType::Void:
688 Out << 'v'; break;
689 case BuiltinType::Bool:
690 Out << 'b'; break;
691 case BuiltinType::UChar:
692 Out << 'c'; break;
693 case BuiltinType::Char8:
694 Out << 'u'; break;
695 case BuiltinType::Char16:
696 Out << 'q'; break;
697 case BuiltinType::Char32:
698 Out << 'w'; break;
699 case BuiltinType::UShort:
700 Out << 's'; break;
701 case BuiltinType::UInt:
702 Out << 'i'; break;
703 case BuiltinType::ULong:
704 Out << 'l'; break;
705 case BuiltinType::ULongLong:
706 Out << 'k'; break;
707 case BuiltinType::UInt128:
708 Out << 'j'; break;
709 case BuiltinType::Char_U:
710 case BuiltinType::Char_S:
711 Out << 'C'; break;
712 case BuiltinType::SChar:
713 Out << 'r'; break;
714 case BuiltinType::WChar_S:
715 case BuiltinType::WChar_U:
716 Out << 'W'; break;
717 case BuiltinType::Short:
718 Out << 'S'; break;
719 case BuiltinType::Int:
720 Out << 'I'; break;
721 case BuiltinType::Long:
722 Out << 'L'; break;
723 case BuiltinType::LongLong:
724 Out << 'K'; break;
725 case BuiltinType::Int128:
726 Out << 'J'; break;
727 case BuiltinType::Float16:
728 case BuiltinType::Half:
729 Out << 'h'; break;
730 case BuiltinType::Float:
731 Out << 'f'; break;
732 case BuiltinType::Double:
733 Out << 'd'; break;
734 case BuiltinType::LongDouble:
735 Out << 'D'; break;
736 case BuiltinType::Float128:
737 Out << 'Q'; break;
738 case BuiltinType::NullPtr:
739 Out << 'n'; break;
740#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
741 case BuiltinType::Id: \
742 Out << "@BT@" << #Suffix << "_" << #ImgType; break;
743#include "clang/Basic/OpenCLImageTypes.def"
744#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
745 case BuiltinType::Id: \
746 Out << "@BT@" << #ExtType; break;
747#include "clang/Basic/OpenCLExtensionTypes.def"
748 case BuiltinType::OCLEvent:
749 Out << "@BT@OCLEvent"; break;
750 case BuiltinType::OCLClkEvent:
751 Out << "@BT@OCLClkEvent"; break;
752 case BuiltinType::OCLQueue:
753 Out << "@BT@OCLQueue"; break;
754 case BuiltinType::OCLReserveID:
755 Out << "@BT@OCLReserveID"; break;
756 case BuiltinType::OCLSampler:
757 Out << "@BT@OCLSampler"; break;
758#define SVE_TYPE(Name, Id, SingletonId) \
759 case BuiltinType::Id: \
760 Out << "@BT@" << Name; break;
761#include "clang/Basic/AArch64SVEACLETypes.def"
762#define PPC_VECTOR_TYPE(Name, Id, Size) \
763 case BuiltinType::Id: \
764 Out << "@BT@" << #Name; break;
765#include "clang/Basic/PPCTypes.def"
766#define RVV_TYPE(Name, Id, SingletonId) \
767 case BuiltinType::Id: \
768 Out << "@BT@" << Name; break;
769#include "clang/Basic/RISCVVTypes.def"
770#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
771#include "clang/Basic/WebAssemblyReferenceTypes.def"
772 case BuiltinType::ShortAccum:
773 Out << "@BT@ShortAccum"; break;
774 case BuiltinType::Accum:
775 Out << "@BT@Accum"; break;
776 case BuiltinType::LongAccum:
777 Out << "@BT@LongAccum"; break;
778 case BuiltinType::UShortAccum:
779 Out << "@BT@UShortAccum"; break;
780 case BuiltinType::UAccum:
781 Out << "@BT@UAccum"; break;
782 case BuiltinType::ULongAccum:
783 Out << "@BT@ULongAccum"; break;
784 case BuiltinType::ShortFract:
785 Out << "@BT@ShortFract"; break;
786 case BuiltinType::Fract:
787 Out << "@BT@Fract"; break;
788 case BuiltinType::LongFract:
789 Out << "@BT@LongFract"; break;
790 case BuiltinType::UShortFract:
791 Out << "@BT@UShortFract"; break;
792 case BuiltinType::UFract:
793 Out << "@BT@UFract"; break;
794 case BuiltinType::ULongFract:
795 Out << "@BT@ULongFract"; break;
796 case BuiltinType::SatShortAccum:
797 Out << "@BT@SatShortAccum"; break;
798 case BuiltinType::SatAccum:
799 Out << "@BT@SatAccum"; break;
800 case BuiltinType::SatLongAccum:
801 Out << "@BT@SatLongAccum"; break;
802 case BuiltinType::SatUShortAccum:
803 Out << "@BT@SatUShortAccum"; break;
804 case BuiltinType::SatUAccum:
805 Out << "@BT@SatUAccum"; break;
806 case BuiltinType::SatULongAccum:
807 Out << "@BT@SatULongAccum"; break;
808 case BuiltinType::SatShortFract:
809 Out << "@BT@SatShortFract"; break;
810 case BuiltinType::SatFract:
811 Out << "@BT@SatFract"; break;
812 case BuiltinType::SatLongFract:
813 Out << "@BT@SatLongFract"; break;
814 case BuiltinType::SatUShortFract:
815 Out << "@BT@SatUShortFract"; break;
816 case BuiltinType::SatUFract:
817 Out << "@BT@SatUFract"; break;
818 case BuiltinType::SatULongFract:
819 Out << "@BT@SatULongFract"; break;
820 case BuiltinType::BFloat16:
821 Out << "@BT@__bf16"; break;
822 case BuiltinType::Ibm128:
823 Out << "@BT@__ibm128"; break;
824 case BuiltinType::ObjCId:
825 Out << 'o'; break;
826 case BuiltinType::ObjCClass:
827 Out << 'O'; break;
828 case BuiltinType::ObjCSel:
829 Out << 'e'; break;
830#define BUILTIN_TYPE(Id, SingletonId)
831#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
832#include "clang/AST/BuiltinTypes.def"
833 case BuiltinType::Dependent:
834 // If you're adding a new builtin type, please add its name prefixed
835 // with "@BT@" to `Out` (see cases above).
836 IgnoreResults = true;
837 break;
838 }
839 return;
840 }
841
842 // If we have already seen this (non-built-in) type, use a substitution
843 // encoding.
844 llvm::DenseMap<const Type *, unsigned>::iterator Substitution
845 = TypeSubstitutions.find(T.getTypePtr());
846 if (Substitution != TypeSubstitutions.end()) {
847 Out << 'S' << Substitution->second << '_';
848 return;
849 } else {
850 // Record this as a substitution.
851 unsigned Number = TypeSubstitutions.size();
852 TypeSubstitutions[T.getTypePtr()] = Number;
853 }
854
855 if (const PointerType *PT = T->getAs<PointerType>()) {
856 Out << '*';
857 T = PT->getPointeeType();
858 continue;
859 }
860 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
861 Out << '*';
862 T = OPT->getPointeeType();
863 continue;
864 }
865 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
866 Out << "&&";
867 T = RT->getPointeeType();
868 continue;
869 }
870 if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
871 Out << '&';
872 T = RT->getPointeeType();
873 continue;
874 }
875 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
876 Out << 'F';
877 VisitType(FT->getReturnType());
878 Out << '(';
879 for (const auto &I : FT->param_types()) {
880 Out << '#';
881 VisitType(I);
882 }
883 Out << ')';
884 if (FT->isVariadic())
885 Out << '.';
886 return;
887 }
888 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
889 Out << 'B';
890 T = BT->getPointeeType();
891 continue;
892 }
893 if (const ComplexType *CT = T->getAs<ComplexType>()) {
894 Out << '<';
895 T = CT->getElementType();
896 continue;
897 }
898 if (const TagType *TT = T->getAs<TagType>()) {
899 Out << '$';
900 VisitTagDecl(TT->getDecl());
901 return;
902 }
903 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
904 Out << '$';
905 VisitObjCInterfaceDecl(OIT->getDecl());
906 return;
907 }
908 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
909 Out << 'Q';
910 VisitType(OIT->getBaseType());
911 for (auto *Prot : OIT->getProtocols())
912 VisitObjCProtocolDecl(Prot);
913 return;
914 }
915 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
916 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
917 return;
918 }
919 if (const TemplateSpecializationType *Spec
921 Out << '>';
922 VisitTemplateName(Spec->getTemplateName());
923 Out << Spec->template_arguments().size();
924 for (const auto &Arg : Spec->template_arguments())
925 VisitTemplateArgument(Arg);
926 return;
927 }
928 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
929 Out << '^';
930 printQualifier(Out, Ctx, DNT->getQualifier());
931 Out << ':' << DNT->getIdentifier()->getName();
932 return;
933 }
934 if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) {
935 T = InjT->getInjectedSpecializationType();
936 continue;
937 }
938 if (const auto *VT = T->getAs<VectorType>()) {
939 Out << (T->isExtVectorType() ? ']' : '[');
940 Out << VT->getNumElements();
941 T = VT->getElementType();
942 continue;
943 }
944 if (const auto *const AT = dyn_cast<ArrayType>(T)) {
945 Out << '{';
946 switch (AT->getSizeModifier()) {
947 case ArraySizeModifier::Static:
948 Out << 's';
949 break;
950 case ArraySizeModifier::Star:
951 Out << '*';
952 break;
953 case ArraySizeModifier::Normal:
954 Out << 'n';
955 break;
956 }
957 if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
958 Out << CAT->getSize();
959
960 T = AT->getElementType();
961 continue;
962 }
963
964 // Unhandled type.
965 Out << ' ';
966 break;
967 } while (true);
968}
969
970void USRGenerator::VisitTemplateParameterList(
971 const TemplateParameterList *Params) {
972 if (!Params)
973 return;
974 Out << '>' << Params->size();
976 PEnd = Params->end();
977 P != PEnd; ++P) {
978 Out << '#';
979 if (isa<TemplateTypeParmDecl>(*P)) {
980 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
981 Out<< 'p';
982 Out << 'T';
983 continue;
984 }
985
986 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
987 if (NTTP->isParameterPack())
988 Out << 'p';
989 Out << 'N';
990 VisitType(NTTP->getType());
991 continue;
992 }
993
994 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
995 if (TTP->isParameterPack())
996 Out << 'p';
997 Out << 't';
998 VisitTemplateParameterList(TTP->getTemplateParameters());
999 }
1000}
1001
1002void USRGenerator::VisitTemplateName(TemplateName Name) {
1003 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1005 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
1006 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1007 return;
1008 }
1009
1010 Visit(Template);
1011 return;
1012 }
1013
1014 // FIXME: Visit dependent template names.
1015}
1016
1017void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
1018 switch (Arg.getKind()) {
1020 break;
1021
1023 Visit(Arg.getAsDecl());
1024 break;
1025
1027 break;
1028
1030 Out << 'P'; // pack expansion of...
1031 [[fallthrough]];
1033 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1034 break;
1035
1037 // FIXME: Visit expressions.
1038 break;
1039
1041 Out << 'p' << Arg.pack_size();
1042 for (const auto &P : Arg.pack_elements())
1043 VisitTemplateArgument(P);
1044 break;
1045
1047 VisitType(Arg.getAsType());
1048 break;
1049
1051 Out << 'V';
1052 VisitType(Arg.getIntegralType());
1053 Out << Arg.getAsIntegral();
1054 break;
1055
1057 Out << 'S';
1058 VisitType(Arg.getStructuralValueType());
1059 ODRHash Hash{};
1061 Out << Hash.CalculateHash();
1062 break;
1063 }
1064 }
1065}
1066
1067void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1068 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1069 return;
1070 VisitDeclContext(D->getDeclContext());
1071 Out << "@UUV@";
1072 printQualifier(Out, D->getASTContext(), D->getQualifier());
1073 EmitDeclName(D);
1074}
1075
1076void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
1077 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1078 return;
1079 VisitDeclContext(D->getDeclContext());
1080 Out << "@UUT@";
1081 printQualifier(Out, D->getASTContext(), D->getQualifier());
1082 Out << D->getName(); // Simple name.
1083}
1084
1085void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
1086 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1087 return;
1088 VisitDeclContext(D->getDeclContext());
1089 Out << "@CT@";
1090 EmitDeclName(D);
1091}
1092
1093void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
1094 VisitDeclContext(D->getDeclContext());
1095 Out << "@MG@";
1096 D->NamedDecl::printName(Out);
1097}
1098
1099//===----------------------------------------------------------------------===//
1100// USR generation functions.
1101//===----------------------------------------------------------------------===//
1102
1103static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
1104 StringRef CatSymDefinedIn,
1105 raw_ostream &OS) {
1106 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
1107 return;
1108 if (CatSymDefinedIn.empty()) {
1109 OS << "@M@" << ClsSymDefinedIn << '@';
1110 return;
1111 }
1112 OS << "@CM@" << CatSymDefinedIn << '@';
1113 if (ClsSymDefinedIn != CatSymDefinedIn) {
1114 OS << ClsSymDefinedIn << '@';
1115 }
1116}
1117
1118void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
1119 StringRef ExtSymDefinedIn,
1120 StringRef CategoryContextExtSymbolDefinedIn) {
1122 CategoryContextExtSymbolDefinedIn, OS);
1123 OS << "objc(cs)" << Cls;
1124}
1125
1126void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
1127 raw_ostream &OS,
1128 StringRef ClsSymDefinedIn,
1129 StringRef CatSymDefinedIn) {
1130 combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
1131 OS << "objc(cy)" << Cls << '@' << Cat;
1132}
1133
1134void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
1135 OS << '@' << Ivar;
1136}
1137
1139 bool IsInstanceMethod,
1140 raw_ostream &OS) {
1141 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
1142}
1143
1144void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
1145 raw_ostream &OS) {
1146 OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
1147}
1148
1149void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
1150 StringRef ExtSymDefinedIn) {
1151 if (!ExtSymDefinedIn.empty())
1152 OS << "@M@" << ExtSymDefinedIn << '@';
1153 OS << "objc(pl)" << Prot;
1154}
1155
1156void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
1157 StringRef ExtSymDefinedIn) {
1158 if (!ExtSymDefinedIn.empty())
1159 OS << "@M@" << ExtSymDefinedIn;
1160 OS << "@E@" << EnumName;
1161}
1162
1163void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
1164 raw_ostream &OS) {
1165 OS << '@' << EnumConstantName;
1166}
1167
1169 SmallVectorImpl<char> &Buf) {
1170 if (!D)
1171 return true;
1172 // We don't ignore decls with invalid source locations. Implicit decls, like
1173 // C++'s operator new function, can have invalid locations but it is fine to
1174 // create USRs that can identify them.
1175
1176 // Check if the declaration has explicit external USR specified.
1177 auto *CD = D->getCanonicalDecl();
1178 if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
1179 if (!ExternalSymAttr->getUSR().empty()) {
1180 llvm::raw_svector_ostream Out(Buf);
1181 Out << ExternalSymAttr->getUSR();
1182 return false;
1183 }
1184 }
1185 USRGenerator UG(&D->getASTContext(), Buf);
1186 UG.Visit(D);
1187 return UG.ignoreResults();
1188}
1189
1191 const SourceManager &SM,
1192 SmallVectorImpl<char> &Buf) {
1193 if (!MD)
1194 return true;
1195 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1196 SM, Buf);
1197
1198}
1199
1201 const SourceManager &SM,
1202 SmallVectorImpl<char> &Buf) {
1203 if (MacroName.empty())
1204 return true;
1205
1206 llvm::raw_svector_ostream Out(Buf);
1207
1208 // Assume that system headers are sane. Don't put source location
1209 // information into the USR if the macro comes from a system header.
1210 bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
1211
1212 Out << getUSRSpacePrefix();
1213 if (ShouldGenerateLocation)
1214 printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1215 Out << "@macro@";
1216 Out << MacroName;
1217 return false;
1218}
1219
1221 SmallVectorImpl<char> &Buf) {
1222 if (T.isNull())
1223 return true;
1224 T = T.getCanonicalType();
1225
1226 USRGenerator UG(&Ctx, Buf);
1227 UG.VisitType(T);
1228 return UG.ignoreResults();
1229}
1230
1232 raw_ostream &OS) {
1233 if (!Mod->Parent)
1235 if (generateFullUSRForModule(Mod->Parent, OS))
1236 return true;
1237 return generateUSRFragmentForModule(Mod, OS);
1238}
1239
1241 raw_ostream &OS) {
1242 OS << getUSRSpacePrefix();
1243 return generateUSRFragmentForModuleName(ModName, OS);
1244}
1245
1247 raw_ostream &OS) {
1248 return generateUSRFragmentForModuleName(Mod->Name, OS);
1249}
1250
1252 raw_ostream &OS) {
1253 OS << "@M@" << ModName;
1254 return false;
1255}
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:702
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2556
const LangOptions & getLangOpts() const
Definition: ASTContext.h:772
const ObjCInterfaceDecl * getObjContainingInterface(const NamedDecl *ND) const
Returns the Objective-C interface that ND belongs to if it is an Objective-C method/property/ivar etc...
A binding in a decomposition declaration.
Definition: DeclCXX.h:4100
Pointer to a block type.
Definition: Type.h:3138
This class is used for builtin types like 'int'.
Definition: Type.h:2770
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2053
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
Represents a class template specialization, which refers to a class template with a given set of temp...
Complex values, per C99 6.2.5p11.
Definition: Type.h:2875
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:1446
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2076
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:85
const DeclContext * getParentFunctionOrMethod(bool LexicalParent=false) const
If this decl is defined inside a function/method/block it returns the corresponding DeclContext,...
Definition: DeclBase.cpp:295
T * getAttr() const
Definition: DeclBase.h:578
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
Definition: DeclBase.cpp:567
SourceLocation getLocation() const
Definition: DeclBase.h:444
DeclContext * getDeclContext()
Definition: DeclBase.h:453
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:436
bool hasAttr() const
Definition: DeclBase.h:582
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:978
Kind getKind() const
Definition: DeclBase.h:447
The name of a declaration.
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
bool isEmpty() const
Evaluates true when this declaration name is empty.
Represents a qualified type name for which the type name is dependent.
Definition: Type.h:6212
Represents a member of a struct/union/class.
Definition: Decl.h:3025
StringRef getName() const
The name of this FileEntry.
Definition: FileEntry.h:61
Represents a function declaration or definition.
Definition: Decl.h:1959
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:4007
QualType getReturnType() const
Definition: Decl.h:2722
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2651
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:4143
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition: Decl.cpp:3457
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4416
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:5981
Represents a linkage specification.
Definition: DeclCXX.h:2927
A global _GUID constant.
Definition: DeclCXX.h:4282
Record the location of a macro definition.
SourceLocation getLocation() const
Retrieve the location of the macro name in the definition.
const IdentifierInfo * getName() const
Retrieve the name of the macro being defined.
Describes a module or submodule.
Definition: Module.h:105
Module * Parent
The parent of this module.
Definition: Module.h:154
std::string Name
The name of this module.
Definition: Module.h:108
This represents a decl that may have a name.
Definition: Decl.h: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:3113
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:1257
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2323
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2368
bool IsClassExtension() const
Definition: DeclObjC.h:2433
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2542
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:944
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2483
Represents an ObjC class declaration.
Definition: DeclObjC.h:1150
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:6712
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:6768
Represents a class type in Objective C.
Definition: Type.h:6514
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:729
bool isClassProperty() const
Definition: DeclObjC.h:851
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2802
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2866
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2079
Represents a pack expansion of types.
Definition: Type.h:6329
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2928
A (possibly-)qualified type.
Definition: Type.h:738
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:805
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7119
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition: Type.h:7159
QualType getCanonicalType() const
Definition: Type.h:7171
The collection of all-type qualifiers we support.
Definition: Type.h:148
bool hasConst() const
Definition: Type.h:265
bool hasRestrict() const
Definition: Type.h:285
bool hasVolatile() const
Definition: Type.h:275
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3231
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3169
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:3549
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:3676
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition: Decl.h:3777
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition: Decl.cpp:4693
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
Definition: Decl.h:3687
TagKind getTagKind() const
Definition: Decl.h:3744
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:5849
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:7477
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7878
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3501
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3399
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3952
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3989
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3855
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3899
Represents a C++ using-declaration.
Definition: DeclCXX.h:3505
Represents C++ using-directive.
Definition: DeclCXX.h:3008
QualType getType() const
Definition: Decl.h: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:3729
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:1556
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1559
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1562
#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.