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