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 case BuiltinType::ShortAccum:
789 Out << "@BT@ShortAccum"; break;
790 case BuiltinType::Accum:
791 Out << "@BT@Accum"; break;
792 case BuiltinType::LongAccum:
793 Out << "@BT@LongAccum"; break;
794 case BuiltinType::UShortAccum:
795 Out << "@BT@UShortAccum"; break;
796 case BuiltinType::UAccum:
797 Out << "@BT@UAccum"; break;
798 case BuiltinType::ULongAccum:
799 Out << "@BT@ULongAccum"; break;
800 case BuiltinType::ShortFract:
801 Out << "@BT@ShortFract"; break;
802 case BuiltinType::Fract:
803 Out << "@BT@Fract"; break;
804 case BuiltinType::LongFract:
805 Out << "@BT@LongFract"; break;
806 case BuiltinType::UShortFract:
807 Out << "@BT@UShortFract"; break;
808 case BuiltinType::UFract:
809 Out << "@BT@UFract"; break;
810 case BuiltinType::ULongFract:
811 Out << "@BT@ULongFract"; break;
812 case BuiltinType::SatShortAccum:
813 Out << "@BT@SatShortAccum"; break;
814 case BuiltinType::SatAccum:
815 Out << "@BT@SatAccum"; break;
816 case BuiltinType::SatLongAccum:
817 Out << "@BT@SatLongAccum"; break;
818 case BuiltinType::SatUShortAccum:
819 Out << "@BT@SatUShortAccum"; break;
820 case BuiltinType::SatUAccum:
821 Out << "@BT@SatUAccum"; break;
822 case BuiltinType::SatULongAccum:
823 Out << "@BT@SatULongAccum"; break;
824 case BuiltinType::SatShortFract:
825 Out << "@BT@SatShortFract"; break;
826 case BuiltinType::SatFract:
827 Out << "@BT@SatFract"; break;
828 case BuiltinType::SatLongFract:
829 Out << "@BT@SatLongFract"; break;
830 case BuiltinType::SatUShortFract:
831 Out << "@BT@SatUShortFract"; break;
832 case BuiltinType::SatUFract:
833 Out << "@BT@SatUFract"; break;
834 case BuiltinType::SatULongFract:
835 Out << "@BT@SatULongFract"; break;
836 case BuiltinType::BFloat16:
837 Out << "@BT@__bf16"; break;
838 case BuiltinType::Ibm128:
839 Out << "@BT@__ibm128"; break;
840 case BuiltinType::ObjCId:
841 Out << 'o'; break;
842 case BuiltinType::ObjCClass:
843 Out << 'O'; break;
844 case BuiltinType::ObjCSel:
845 Out << 'e'; break;
846#define BUILTIN_TYPE(Id, SingletonId)
847#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
848#include "clang/AST/BuiltinTypes.def"
849 case BuiltinType::Dependent:
850 // If you're adding a new builtin type, please add its name prefixed
851 // with "@BT@" to `Out` (see cases above).
852 IgnoreResults = true;
853 break;
854 }
855 return;
856 }
857
858 // If we have already seen this (non-built-in) type, use a substitution
859 // encoding.
860 llvm::DenseMap<const Type *, unsigned>::iterator Substitution
861 = TypeSubstitutions.find(T.getTypePtr());
862 if (Substitution != TypeSubstitutions.end()) {
863 Out << 'S' << Substitution->second << '_';
864 return;
865 } else {
866 // Record this as a substitution.
867 unsigned Number = TypeSubstitutions.size();
868 TypeSubstitutions[T.getTypePtr()] = Number;
869 }
870
871 if (const PointerType *PT = T->getAs<PointerType>()) {
872 Out << '*';
873 T = PT->getPointeeType();
874 continue;
875 }
876 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
877 Out << '*';
878 T = OPT->getPointeeType();
879 continue;
880 }
881 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
882 Out << "&&";
883 T = RT->getPointeeType();
884 continue;
885 }
886 if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
887 Out << '&';
888 T = RT->getPointeeType();
889 continue;
890 }
891 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
892 Out << 'F';
893 VisitType(FT->getReturnType());
894 Out << '(';
895 for (const auto &I : FT->param_types()) {
896 Out << '#';
897 VisitType(I);
898 }
899 Out << ')';
900 if (FT->isVariadic())
901 Out << '.';
902 return;
903 }
904 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
905 Out << 'B';
906 T = BT->getPointeeType();
907 continue;
908 }
909 if (const ComplexType *CT = T->getAs<ComplexType>()) {
910 Out << '<';
911 T = CT->getElementType();
912 continue;
913 }
914 if (const TagType *TT = T->getAs<TagType>()) {
915 Out << '$';
916 VisitTagDecl(TT->getDecl());
917 return;
918 }
919 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
920 Out << '$';
921 VisitObjCInterfaceDecl(OIT->getDecl());
922 return;
923 }
924 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
925 Out << 'Q';
926 VisitType(OIT->getBaseType());
927 for (auto *Prot : OIT->getProtocols())
928 VisitObjCProtocolDecl(Prot);
929 return;
930 }
931 if (const TemplateTypeParmType *TTP = T->getAs<TemplateTypeParmType>()) {
932 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
933 return;
934 }
935 if (const TemplateSpecializationType *Spec
937 Out << '>';
938 VisitTemplateName(Spec->getTemplateName());
939 Out << Spec->template_arguments().size();
940 for (const auto &Arg : Spec->template_arguments())
941 VisitTemplateArgument(Arg);
942 return;
943 }
944 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
945 Out << '^';
946 printQualifier(Out, Ctx, DNT->getQualifier());
947 Out << ':' << DNT->getIdentifier()->getName();
948 return;
949 }
950 if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) {
951 T = InjT->getInjectedSpecializationType();
952 continue;
953 }
954 if (const auto *VT = T->getAs<VectorType>()) {
955 Out << (T->isExtVectorType() ? ']' : '[');
956 Out << VT->getNumElements();
957 T = VT->getElementType();
958 continue;
959 }
960 if (const auto *const AT = dyn_cast<ArrayType>(T)) {
961 Out << '{';
962 switch (AT->getSizeModifier()) {
963 case ArraySizeModifier::Static:
964 Out << 's';
965 break;
966 case ArraySizeModifier::Star:
967 Out << '*';
968 break;
969 case ArraySizeModifier::Normal:
970 Out << 'n';
971 break;
972 }
973 if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
974 Out << CAT->getSize();
975
976 T = AT->getElementType();
977 continue;
978 }
979
980 // Unhandled type.
981 Out << ' ';
982 break;
983 } while (true);
984}
985
986void USRGenerator::VisitTemplateParameterList(
987 const TemplateParameterList *Params) {
988 if (!Params)
989 return;
990 Out << '>' << Params->size();
992 PEnd = Params->end();
993 P != PEnd; ++P) {
994 Out << '#';
995 if (isa<TemplateTypeParmDecl>(*P)) {
996 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
997 Out<< 'p';
998 Out << 'T';
999 continue;
1000 }
1001
1002 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1003 if (NTTP->isParameterPack())
1004 Out << 'p';
1005 Out << 'N';
1006 VisitType(NTTP->getType());
1007 continue;
1008 }
1009
1010 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1011 if (TTP->isParameterPack())
1012 Out << 'p';
1013 Out << 't';
1014 VisitTemplateParameterList(TTP->getTemplateParameters());
1015 }
1016}
1017
1018void USRGenerator::VisitTemplateName(TemplateName Name) {
1019 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1021 = dyn_cast<TemplateTemplateParmDecl>(Template)) {
1022 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1023 return;
1024 }
1025
1026 Visit(Template);
1027 return;
1028 }
1029
1030 // FIXME: Visit dependent template names.
1031}
1032
1033void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
1034 switch (Arg.getKind()) {
1036 break;
1037
1039 Visit(Arg.getAsDecl());
1040 break;
1041
1043 break;
1044
1046 Out << 'P'; // pack expansion of...
1047 [[fallthrough]];
1049 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1050 break;
1051
1053 // FIXME: Visit expressions.
1054 break;
1055
1057 Out << 'p' << Arg.pack_size();
1058 for (const auto &P : Arg.pack_elements())
1059 VisitTemplateArgument(P);
1060 break;
1061
1063 VisitType(Arg.getAsType());
1064 break;
1065
1067 Out << 'V';
1068 VisitType(Arg.getIntegralType());
1069 Out << Arg.getAsIntegral();
1070 break;
1071
1073 Out << 'S';
1074 VisitType(Arg.getStructuralValueType());
1075 ODRHash Hash{};
1077 Out << Hash.CalculateHash();
1078 break;
1079 }
1080 }
1081}
1082
1083void USRGenerator::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) {
1084 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1085 return;
1086 VisitDeclContext(D->getDeclContext());
1087 Out << "@UUV@";
1088 printQualifier(Out, D->getASTContext(), D->getQualifier());
1089 EmitDeclName(D);
1090}
1091
1092void USRGenerator::VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D) {
1093 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1094 return;
1095 VisitDeclContext(D->getDeclContext());
1096 Out << "@UUT@";
1097 printQualifier(Out, D->getASTContext(), D->getQualifier());
1098 Out << D->getName(); // Simple name.
1099}
1100
1101void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
1102 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1103 return;
1104 VisitDeclContext(D->getDeclContext());
1105 Out << "@CT@";
1106 EmitDeclName(D);
1107}
1108
1109void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
1110 VisitDeclContext(D->getDeclContext());
1111 Out << "@MG@";
1112 D->NamedDecl::printName(Out);
1113}
1114
1115//===----------------------------------------------------------------------===//
1116// USR generation functions.
1117//===----------------------------------------------------------------------===//
1118
1119static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
1120 StringRef CatSymDefinedIn,
1121 raw_ostream &OS) {
1122 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
1123 return;
1124 if (CatSymDefinedIn.empty()) {
1125 OS << "@M@" << ClsSymDefinedIn << '@';
1126 return;
1127 }
1128 OS << "@CM@" << CatSymDefinedIn << '@';
1129 if (ClsSymDefinedIn != CatSymDefinedIn) {
1130 OS << ClsSymDefinedIn << '@';
1131 }
1132}
1133
1134void clang::index::generateUSRForObjCClass(StringRef Cls, raw_ostream &OS,
1135 StringRef ExtSymDefinedIn,
1136 StringRef CategoryContextExtSymbolDefinedIn) {
1138 CategoryContextExtSymbolDefinedIn, OS);
1139 OS << "objc(cs)" << Cls;
1140}
1141
1142void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
1143 raw_ostream &OS,
1144 StringRef ClsSymDefinedIn,
1145 StringRef CatSymDefinedIn) {
1146 combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
1147 OS << "objc(cy)" << Cls << '@' << Cat;
1148}
1149
1150void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
1151 OS << '@' << Ivar;
1152}
1153
1155 bool IsInstanceMethod,
1156 raw_ostream &OS) {
1157 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
1158}
1159
1160void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
1161 raw_ostream &OS) {
1162 OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
1163}
1164
1165void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
1166 StringRef ExtSymDefinedIn) {
1167 if (!ExtSymDefinedIn.empty())
1168 OS << "@M@" << ExtSymDefinedIn << '@';
1169 OS << "objc(pl)" << Prot;
1170}
1171
1172void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
1173 StringRef ExtSymDefinedIn) {
1174 if (!ExtSymDefinedIn.empty())
1175 OS << "@M@" << ExtSymDefinedIn;
1176 OS << "@E@" << EnumName;
1177}
1178
1179void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
1180 raw_ostream &OS) {
1181 OS << '@' << EnumConstantName;
1182}
1183
1185 SmallVectorImpl<char> &Buf) {
1186 if (!D)
1187 return true;
1188 // We don't ignore decls with invalid source locations. Implicit decls, like
1189 // C++'s operator new function, can have invalid locations but it is fine to
1190 // create USRs that can identify them.
1191
1192 // Check if the declaration has explicit external USR specified.
1193 auto *CD = D->getCanonicalDecl();
1194 if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
1195 if (!ExternalSymAttr->getUSR().empty()) {
1196 llvm::raw_svector_ostream Out(Buf);
1197 Out << ExternalSymAttr->getUSR();
1198 return false;
1199 }
1200 }
1201 USRGenerator UG(&D->getASTContext(), Buf);
1202 UG.Visit(D);
1203 return UG.ignoreResults();
1204}
1205
1207 const SourceManager &SM,
1208 SmallVectorImpl<char> &Buf) {
1209 if (!MD)
1210 return true;
1211 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1212 SM, Buf);
1213
1214}
1215
1217 const SourceManager &SM,
1218 SmallVectorImpl<char> &Buf) {
1219 if (MacroName.empty())
1220 return true;
1221
1222 llvm::raw_svector_ostream Out(Buf);
1223
1224 // Assume that system headers are sane. Don't put source location
1225 // information into the USR if the macro comes from a system header.
1226 bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
1227
1228 Out << getUSRSpacePrefix();
1229 if (ShouldGenerateLocation)
1230 printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1231 Out << "@macro@";
1232 Out << MacroName;
1233 return false;
1234}
1235
1237 SmallVectorImpl<char> &Buf) {
1238 if (T.isNull())
1239 return true;
1240 T = T.getCanonicalType();
1241
1242 USRGenerator UG(&Ctx, Buf);
1243 UG.VisitType(T);
1244 return UG.ignoreResults();
1245}
1246
1248 raw_ostream &OS) {
1249 if (!Mod->Parent)
1251 if (generateFullUSRForModule(Mod->Parent, OS))
1252 return true;
1253 return generateUSRFragmentForModule(Mod, OS);
1254}
1255
1257 raw_ostream &OS) {
1258 OS << getUSRSpacePrefix();
1259 return generateUSRFragmentForModuleName(ModName, OS);
1260}
1261
1263 raw_ostream &OS) {
1264 return generateUSRFragmentForModuleName(Mod->Name, OS);
1265}
1266
1268 raw_ostream &OS) {
1269 OS << "@M@" << ModName;
1270 return false;
1271}
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:758
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:186
SourceManager & getSourceManager()
Definition: ASTContext.h:720
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2625
const LangOptions & getLangOpts() const
Definition: ASTContext.h:796
const ObjCInterfaceDecl * getObjContainingInterface(const NamedDecl *ND) const
Returns the Objective-C interface that ND belongs to if it is an Objective-C method/property/ivar etc...
A binding in a decomposition declaration.
Definition: DeclCXX.h:4107
Pointer to a block type.
Definition: Type.h:3371
This class is used for builtin types like 'int'.
Definition: Type.h:3000
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Declaration of a class template.
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:3108
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:1425
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2079
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:579
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:445
DeclContext * getDeclContext()
Definition: DeclBase.h:454
SourceLocation getBeginLoc() const LLVM_READONLY
Definition: DeclBase.h:437
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
bool hasAttr() const
Definition: DeclBase.h:583
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition: DeclBase.h:957
Kind getKind() const
Definition: DeclBase.h:448
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:6836
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:4973
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:6605
Represents a linkage specification.
Definition: DeclCXX.h:2934
A global _GUID constant.
Definition: DeclCXX.h:4289
Record the location of a macro definition.
SourceLocation getLocation() const
Retrieve the location of the macro name in the definition.
const IdentifierInfo * getName() const
Retrieve the name of the macro being defined.
Describes a module or submodule.
Definition: Module.h:105
Module * Parent
The parent of this module.
Definition: Module.h:154
std::string Name
The name of this module.
Definition: Module.h:108
This represents a decl that may have a name.
Definition: Decl.h:249
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
Represents a C++ namespace alias.
Definition: DeclCXX.h:3120
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:1274
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2326
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2369
bool IsClassExtension() const
Definition: DeclObjC.h:2434
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2542
ObjCContainerDecl - Represents a container for method declarations.
Definition: DeclObjC.h:947
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2483
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
Interfaces are the core concept in Objective-C for object oriented design.
Definition: Type.h:7336
ObjCMethodDecl - Represents an instance or class method declaration.
Definition: DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition: Type.h:7392
Represents a class type in Objective C.
Definition: Type.h:7138
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:2802
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
Represents a pack expansion of types.
Definition: Type.h:6953
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3161
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:3464
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3402
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:3557
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:6473
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:8108
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8516
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3507
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3405
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3959
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3862
Represents a C++ using-declaration.
Definition: DeclCXX.h:3512
Represents C++ using-directive.
Definition: DeclCXX.h:3015
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:3991
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.