clang 23.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"
17#include "llvm/Support/Path.h"
18#include "llvm/Support/raw_ostream.h"
19
20using namespace clang;
21using namespace clang::index;
22
23//===----------------------------------------------------------------------===//
24// USR generation.
25//===----------------------------------------------------------------------===//
26
27/// \returns true on error.
28static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc,
29 const SourceManager &SM, bool IncludeOffset) {
30 if (Loc.isInvalid()) {
31 return true;
32 }
33 Loc = SM.getExpansionLoc(Loc);
34 const FileIDAndOffset &Decomposed = SM.getDecomposedLoc(Loc);
35 OptionalFileEntryRef FE = SM.getFileEntryRefForID(Decomposed.first);
36 if (FE) {
37 OS << llvm::sys::path::filename(FE->getName());
38 } else {
39 // This case really isn't interesting.
40 return true;
41 }
42 if (IncludeOffset) {
43 // Use the offest into the FileID to represent the location. Using
44 // a line/column can cause us to look back at the original source file,
45 // which is expensive.
46 OS << '@' << Decomposed.second;
47 }
48 return false;
49}
50
51static StringRef GetExternalSourceContainer(const NamedDecl *D) {
52 if (!D)
53 return StringRef();
54 if (auto *attr = D->getExternalSourceSymbolAttr()) {
55 return attr->getDefinedIn();
56 }
57 return StringRef();
58}
59
60namespace {
61class USRGenerator : public ConstDeclVisitor<USRGenerator> {
62 SmallVectorImpl<char> &Buf;
63 llvm::raw_svector_ostream Out;
64 ASTContext *Context;
65 const LangOptions &LangOpts;
66 bool IgnoreResults = false;
67 bool generatedLoc = false;
68
69 llvm::DenseMap<const Type *, unsigned> TypeSubstitutions;
70
71public:
72 USRGenerator(ASTContext *Ctx, SmallVectorImpl<char> &Buf,
73 const LangOptions &LangOpts)
74 : Buf(Buf), Out(Buf), Context(Ctx), LangOpts(LangOpts) {
75 // Add the USR space prefix.
76 Out << getUSRSpacePrefix();
77 }
78
79 bool ignoreResults() const { return IgnoreResults; }
80
81 // Visitation methods from generating USRs from AST elements.
82 void VisitDeclContext(const DeclContext *D);
83 void VisitFieldDecl(const FieldDecl *D);
84 void VisitFunctionDecl(const FunctionDecl *D);
85 void VisitNamedDecl(const NamedDecl *D);
86 void VisitNamespaceDecl(const NamespaceDecl *D);
87 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
88 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
89 void VisitClassTemplateDecl(const ClassTemplateDecl *D);
90 void VisitObjCContainerDecl(const ObjCContainerDecl *CD,
91 const ObjCCategoryDecl *CatD = nullptr);
92 void VisitObjCMethodDecl(const ObjCMethodDecl *MD);
93 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
94 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
95 void VisitTagDecl(const TagDecl *D);
96 void VisitTypedefDecl(const TypedefDecl *D);
97 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
98 void VisitVarDecl(const VarDecl *D);
99 void VisitBindingDecl(const BindingDecl *D);
100 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
101 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
102 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
103 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
104 void VisitConceptDecl(const ConceptDecl *D);
105
106 void VisitLinkageSpecDecl(const LinkageSpecDecl *D) {
107 IgnoreResults = true; // No USRs for linkage specs themselves.
108 }
109
110 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) {
111 IgnoreResults = true;
112 }
113
114 void VisitUsingDecl(const UsingDecl *D) {
115 VisitDeclContext(D->getDeclContext());
116 Out << "@UD@";
117
118 bool EmittedDeclName = !EmitDeclName(D);
119 assert(EmittedDeclName && "EmitDeclName can not fail for UsingDecls");
120 (void)EmittedDeclName;
121 }
122
123 bool ShouldGenerateLocation(const NamedDecl *D);
124
125 bool isLocal(const NamedDecl *D) {
126 return D->getParentFunctionOrMethod() != nullptr;
127 }
128
129 void GenExtSymbolContainer(const NamedDecl *D);
130
131 /// Generate the string component containing the location of the
132 /// declaration.
133 bool GenLoc(const Decl *D, bool IncludeOffset);
134
135 /// String generation methods used both by the visitation methods
136 /// and from other clients that want to directly generate USRs. These
137 /// methods do not construct complete USRs (which incorporate the parents
138 /// of an AST element), but only the fragments concerning the AST element
139 /// itself.
140
141 /// Generate a USR for an Objective-C class.
142 void GenObjCClass(StringRef cls, StringRef ExtSymDefinedIn,
143 StringRef CategoryContextExtSymbolDefinedIn) {
144 generateUSRForObjCClass(cls, Out, ExtSymDefinedIn,
145 CategoryContextExtSymbolDefinedIn);
146 }
147
148 /// Generate a USR for an Objective-C class category.
149 void GenObjCCategory(StringRef cls, StringRef cat,
150 StringRef clsExt, StringRef catExt) {
151 generateUSRForObjCCategory(cls, cat, Out, clsExt, catExt);
152 }
153
154 /// Generate a USR fragment for an Objective-C property.
155 void GenObjCProperty(StringRef prop, bool isClassProp) {
156 generateUSRForObjCProperty(prop, isClassProp, Out);
157 }
158
159 /// Generate a USR for an Objective-C protocol.
160 void GenObjCProtocol(StringRef prot, StringRef ext) {
161 generateUSRForObjCProtocol(prot, Out, ext);
162 }
163
164 void VisitType(QualType T);
165 void VisitTemplateParameterList(const TemplateParameterList *Params);
166 void VisitTemplateName(TemplateName Name);
167 void VisitTemplateArgument(const TemplateArgument &Arg);
168
169 void VisitMSGuidDecl(const MSGuidDecl *D);
170
171 /// Emit a Decl's name using NamedDecl::printName() and return true if
172 /// the decl had no name.
173 bool EmitDeclName(const NamedDecl *D);
174};
175} // end anonymous namespace
176
177//===----------------------------------------------------------------------===//
178// Generating USRs from ASTS.
179//===----------------------------------------------------------------------===//
180
181bool USRGenerator::EmitDeclName(const NamedDecl *D) {
182 DeclarationName N = D->getDeclName();
183 if (N.isEmpty())
184 return true;
185 Out << N;
186 return false;
187}
188
189bool USRGenerator::ShouldGenerateLocation(const NamedDecl *D) {
190 if (D->isExternallyVisible())
191 return false;
193 return true;
194 SourceLocation Loc = D->getLocation();
195 if (Loc.isInvalid())
196 return false;
197 const SourceManager &SM = Context->getSourceManager();
198 return !SM.isInSystemHeader(Loc);
199}
200
201void USRGenerator::VisitDeclContext(const DeclContext *DC) {
202 if (const NamedDecl *D = dyn_cast<NamedDecl>(DC))
203 Visit(D);
204 else if (isa<LinkageSpecDecl>(DC)) // Linkage specs are transparent in USRs.
205 VisitDeclContext(DC->getParent());
206}
207
208void USRGenerator::VisitFieldDecl(const FieldDecl *D) {
209 // The USR for an ivar declared in a class extension is based on the
210 // ObjCInterfaceDecl, not the ObjCCategoryDecl.
211 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
212 Visit(ID);
213 else
214 VisitDeclContext(D->getDeclContext());
215 Out << (isa<ObjCIvarDecl>(D) ? "@" : "@FI@");
216 if (EmitDeclName(D)) {
217 // Bit fields can be anonymous.
218 IgnoreResults = true;
219 return;
220 }
221}
222
223void USRGenerator::VisitFunctionDecl(const FunctionDecl *D) {
224 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
225 return;
226
227 if (D->getType().isNull()) {
228 IgnoreResults = true;
229 return;
230 }
231
232 const unsigned StartSize = Buf.size();
233 VisitDeclContext(D->getDeclContext());
234 if (Buf.size() == StartSize)
235 GenExtSymbolContainer(D);
236
237 bool IsTemplate = false;
238 if (FunctionTemplateDecl *FunTmpl = D->getDescribedFunctionTemplate()) {
239 IsTemplate = true;
240 Out << "@FT@";
241 VisitTemplateParameterList(FunTmpl->getTemplateParameters());
242 } else
243 Out << "@F@";
244
245 PrintingPolicy Policy(LangOpts);
246 // Forward references can have different template argument names. Suppress the
247 // template argument names in constructors to make their USR more stable.
248 Policy.SuppressTemplateArgsInCXXConstructors = true;
249 D->getDeclName().print(Out, Policy);
250
251 if ((!LangOpts.CPlusPlus || D->isExternC()) &&
252 !D->hasAttr<OverloadableAttr>())
253 return;
254
256 Out << '<';
257 if (const TemplateArgumentList *SpecArgs =
259 for (const auto &Arg : SpecArgs->asArray()) {
260 Out << '#';
261 VisitTemplateArgument(Arg);
262 }
263 } else if (const ASTTemplateArgumentListInfo *SpecArgsWritten =
265 for (const auto &ArgLoc : SpecArgsWritten->arguments()) {
266 Out << '#';
267 VisitTemplateArgument(ArgLoc.getArgument());
268 }
269 }
270 Out << '>';
271 }
272
273 QualType CanonicalType = D->getType().getCanonicalType();
274 // Mangle in type information for the arguments.
275 if (const auto *FPT = CanonicalType->getAs<FunctionProtoType>()) {
276 for (QualType PT : FPT->param_types()) {
277 Out << '#';
278 VisitType(PT);
279 }
280 }
281 if (D->isVariadic())
282 Out << '.';
283 if (IsTemplate) {
284 // Function templates can be overloaded by return type, for example:
285 // \code
286 // template <class T> typename T::A foo() {}
287 // template <class T> typename T::B foo() {}
288 // \endcode
289 Out << '#';
290 VisitType(D->getReturnType());
291 }
292 Out << '#';
293 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
294 if (MD->isStatic())
295 Out << 'S';
296 // FIXME: OpenCL: Need to consider address spaces
297 if (unsigned quals = MD->getMethodQualifiers().getCVRUQualifiers())
298 Out << (char)('0' + quals);
299 switch (MD->getRefQualifier()) {
300 case RQ_None: break;
301 case RQ_LValue: Out << '&'; break;
302 case RQ_RValue: Out << "&&"; break;
303 }
304 }
305}
306
307void USRGenerator::VisitNamedDecl(const NamedDecl *D) {
308 VisitDeclContext(D->getDeclContext());
309 Out << "@";
310
311 if (EmitDeclName(D)) {
312 // The string can be empty if the declaration has no name; e.g., it is
313 // the ParmDecl with no name for declaration of a function pointer type,
314 // e.g.: void (*f)(void *);
315 // In this case, don't generate a USR.
316 IgnoreResults = true;
317 }
318}
319
320void USRGenerator::VisitVarDecl(const VarDecl *D) {
321 // VarDecls can be declared 'extern' within a function or method body,
322 // but their enclosing DeclContext is the function, not the TU. We need
323 // to check the storage class to correctly generate the USR.
324 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
325 return;
326
327 VisitDeclContext(D->getDeclContext());
328
329 if (VarTemplateDecl *VarTmpl = D->getDescribedVarTemplate()) {
330 Out << "@VT";
331 VisitTemplateParameterList(VarTmpl->getTemplateParameters());
332 } else if (const VarTemplatePartialSpecializationDecl *PartialSpec
333 = dyn_cast<VarTemplatePartialSpecializationDecl>(D)) {
334 Out << "@VP";
335 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
336 }
337
338 // Variables always have simple names.
339 StringRef s = D->getName();
340
341 // The string can be empty if the declaration has no name; e.g., it is
342 // the ParmDecl with no name for declaration of a function pointer type, e.g.:
343 // void (*f)(void *);
344 // In this case, don't generate a USR.
345 if (s.empty())
346 IgnoreResults = true;
347 else
348 Out << '@' << s;
349
350 // For a template specialization, mangle the template arguments.
351 if (const VarTemplateSpecializationDecl *Spec
352 = dyn_cast<VarTemplateSpecializationDecl>(D)) {
353 const TemplateArgumentList &Args = Spec->getTemplateArgs();
354 Out << '>';
355 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
356 Out << '#';
357 VisitTemplateArgument(Args.get(I));
358 }
359 }
360}
361
362void USRGenerator::VisitBindingDecl(const BindingDecl *D) {
363 if (isLocal(D) && GenLoc(D, /*IncludeOffset=*/true))
364 return;
365 VisitNamedDecl(D);
366}
367
368void USRGenerator::VisitNonTypeTemplateParmDecl(
369 const NonTypeTemplateParmDecl *D) {
370 GenLoc(D, /*IncludeOffset=*/true);
371}
372
373void USRGenerator::VisitTemplateTemplateParmDecl(
374 const TemplateTemplateParmDecl *D) {
375 GenLoc(D, /*IncludeOffset=*/true);
376}
377
378void USRGenerator::VisitNamespaceDecl(const NamespaceDecl *D) {
379 if (IgnoreResults)
380 return;
381 VisitDeclContext(D->getDeclContext());
382 if (D->isAnonymousNamespace()) {
383 Out << "@aN";
384 return;
385 }
386 Out << "@N@" << D->getName();
387}
388
389void USRGenerator::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
390 VisitFunctionDecl(D->getTemplatedDecl());
391}
392
393void USRGenerator::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
394 VisitTagDecl(D->getTemplatedDecl());
395}
396
397void USRGenerator::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
398 VisitDeclContext(D->getDeclContext());
399 if (!IgnoreResults)
400 Out << "@NA@" << D->getName();
401}
402
404 if (auto *CD = dyn_cast<ObjCCategoryDecl>(D->getDeclContext()))
405 return CD;
406 if (auto *ICD = dyn_cast<ObjCCategoryImplDecl>(D->getDeclContext()))
407 return ICD->getCategoryDecl();
408 return nullptr;
409}
410
411void USRGenerator::VisitObjCMethodDecl(const ObjCMethodDecl *D) {
412 const DeclContext *container = D->getDeclContext();
413 if (const ObjCProtocolDecl *pd = dyn_cast<ObjCProtocolDecl>(container)) {
414 Visit(pd);
415 }
416 else {
417 // The USR for a method declared in a class extension or category is based on
418 // the ObjCInterfaceDecl, not the ObjCCategoryDecl.
419 const ObjCInterfaceDecl *ID = D->getClassInterface();
420 if (!ID) {
421 IgnoreResults = true;
422 return;
423 }
424 auto *CD = getCategoryContext(D);
425 VisitObjCContainerDecl(ID, CD);
426 }
427 // Ideally we would use 'GenObjCMethod', but this is such a hot path
428 // for Objective-C code that we don't want to use
429 // DeclarationName::getAsString().
430 Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
431 << DeclarationName(D->getSelector());
432}
433
434void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
435 const ObjCCategoryDecl *CatD) {
436 switch (D->getKind()) {
437 default:
438 llvm_unreachable("Invalid ObjC container.");
439 case Decl::ObjCInterface:
440 case Decl::ObjCImplementation:
441 GenObjCClass(D->getName(), GetExternalSourceContainer(D),
443 break;
444 case Decl::ObjCCategory: {
445 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
446 const ObjCInterfaceDecl *ID = CD->getClassInterface();
447 if (!ID) {
448 // Handle invalid code where the @interface might not
449 // have been specified.
450 // FIXME: We should be able to generate this USR even if the
451 // @interface isn't available.
452 IgnoreResults = true;
453 return;
454 }
455 // Specially handle class extensions, which are anonymous categories.
456 // We want to mangle in the location to uniquely distinguish them.
457 if (CD->IsClassExtension()) {
458 Out << "objc(ext)" << ID->getName() << '@';
459 GenLoc(CD, /*IncludeOffset=*/true);
460 }
461 else
462 GenObjCCategory(ID->getName(), CD->getName(),
465
466 break;
467 }
468 case Decl::ObjCCategoryImpl: {
469 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
470 const ObjCInterfaceDecl *ID = CD->getClassInterface();
471 if (!ID) {
472 // Handle invalid code where the @interface might not
473 // have been specified.
474 // FIXME: We should be able to generate this USR even if the
475 // @interface isn't available.
476 IgnoreResults = true;
477 return;
478 }
479 GenObjCCategory(ID->getName(), CD->getName(),
482 break;
483 }
484 case Decl::ObjCProtocol: {
485 const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
486 GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
487 break;
488 }
489 }
490}
491
492void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
493 // The USR for a property declared in a class extension or category is based
494 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
495 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
496 VisitObjCContainerDecl(ID, getCategoryContext(D));
497 else
498 Visit(cast<Decl>(D->getDeclContext()));
499 GenObjCProperty(D->getName(), D->isClassProperty());
500}
501
502void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
503 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
504 VisitObjCPropertyDecl(PD);
505 return;
506 }
507
508 IgnoreResults = true;
509}
510
511void USRGenerator::VisitTagDecl(const TagDecl *D) {
512 // Add the location of the tag decl to handle resolution across
513 // translation units.
514 if (!isa<EnumDecl>(D) &&
515 ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
516 return;
517
518 GenExtSymbolContainer(D);
519
520 D = D->getCanonicalDecl();
521 VisitDeclContext(D->getDeclContext());
522
523 bool AlreadyStarted = false;
524 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
525 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
526 AlreadyStarted = true;
527
528 switch (D->getTagKind()) {
529 case TagTypeKind::Interface:
530 case TagTypeKind::Class:
531 case TagTypeKind::Struct:
532 Out << "@ST";
533 break;
534 case TagTypeKind::Union:
535 Out << "@UT";
536 break;
537 case TagTypeKind::Enum:
538 llvm_unreachable("enum template");
539 }
540 VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
541 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec
542 = dyn_cast<ClassTemplatePartialSpecializationDecl>(CXXRecord)) {
543 AlreadyStarted = true;
544
545 switch (D->getTagKind()) {
546 case TagTypeKind::Interface:
547 case TagTypeKind::Class:
548 case TagTypeKind::Struct:
549 Out << "@SP";
550 break;
551 case TagTypeKind::Union:
552 Out << "@UP";
553 break;
554 case TagTypeKind::Enum:
555 llvm_unreachable("enum partial specialization");
556 }
557 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
558 }
559 }
560
561 if (!AlreadyStarted) {
562 switch (D->getTagKind()) {
563 case TagTypeKind::Interface:
564 case TagTypeKind::Class:
565 case TagTypeKind::Struct:
566 Out << "@S";
567 break;
568 case TagTypeKind::Union:
569 Out << "@U";
570 break;
571 case TagTypeKind::Enum:
572 Out << "@E";
573 break;
574 }
575 }
576
577 Out << '@';
578 assert(Buf.size() > 0);
579 const unsigned off = Buf.size() - 1;
580
581 if (EmitDeclName(D)) {
582 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
583 Buf[off] = 'A';
584 Out << '@' << *TD;
585 } else {
586 if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
587 printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
588 } else {
589 Buf[off] = 'a';
590 if (auto *ED = dyn_cast<EnumDecl>(D)) {
591 // Distinguish USRs of anonymous enums by using their first
592 // enumerator.
593 auto enum_range = ED->enumerators();
594 if (enum_range.begin() != enum_range.end()) {
595 Out << '@' << **enum_range.begin();
596 }
597 }
598 }
599 }
600 }
601
602 // For a class template specialization, mangle the template arguments.
603 if (const ClassTemplateSpecializationDecl *Spec
604 = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
605 const TemplateArgumentList &Args = Spec->getTemplateArgs();
606 Out << '>';
607 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
608 Out << '#';
609 VisitTemplateArgument(Args.get(I));
610 }
611 }
612}
613
614void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
615 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
616 return;
617 const DeclContext *DC = D->getDeclContext();
618 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
619 Visit(DCN);
620 Out << "@T@";
621 Out << D->getName();
622}
623
624void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
625 GenLoc(D, /*IncludeOffset=*/true);
626}
627
628void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
629 StringRef Container = GetExternalSourceContainer(D);
630 if (!Container.empty())
631 Out << "@M@" << Container;
632}
633
634bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
635 if (generatedLoc)
636 return IgnoreResults;
637 generatedLoc = true;
638
639 // Guard against null declarations in invalid code.
640 if (!D) {
641 IgnoreResults = true;
642 return true;
643 }
644
645 // Use the location of canonical decl.
646 D = D->getCanonicalDecl();
647
648 IgnoreResults =
649 IgnoreResults || printLoc(Out, D->getBeginLoc(),
650 Context->getSourceManager(), IncludeOffset);
651
652 return IgnoreResults;
653}
654
655static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts,
657 // FIXME: Encode the qualifier, don't just print it.
658 PrintingPolicy PO(LangOpts);
659 PO.SuppressTagKeyword = true;
660 PO.SuppressUnwrittenScope = true;
663 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
664 NNS.print(Out, PO);
665}
666
667void USRGenerator::VisitType(QualType T) {
668 // This method mangles in USR information for types. It can possibly
669 // just reuse the naming-mangling logic used by codegen, although the
670 // requirements for USRs might not be the same.
671 ASTContext &Ctx = *Context;
672
673 do {
674 T = Ctx.getCanonicalType(T);
675 Qualifiers Q = T.getQualifiers();
676 unsigned qVal = 0;
677 if (Q.hasConst())
678 qVal |= 0x1;
679 if (Q.hasVolatile())
680 qVal |= 0x2;
681 if (Q.hasRestrict())
682 qVal |= 0x4;
683 if(qVal)
684 Out << ((char) ('0' + qVal));
685
686 // Mangle in ObjC GC qualifiers?
687
688 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
689 Out << 'P';
690 T = Expansion->getPattern();
691 }
692
693 if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
694 switch (BT->getKind()) {
695 case BuiltinType::Void:
696 Out << 'v'; break;
697 case BuiltinType::Bool:
698 Out << 'b'; break;
699 case BuiltinType::UChar:
700 Out << 'c'; break;
701 case BuiltinType::Char8:
702 Out << 'u'; break;
703 case BuiltinType::Char16:
704 Out << 'q'; break;
705 case BuiltinType::Char32:
706 Out << 'w'; break;
707 case BuiltinType::UShort:
708 Out << 's'; break;
709 case BuiltinType::UInt:
710 Out << 'i'; break;
711 case BuiltinType::ULong:
712 Out << 'l'; break;
713 case BuiltinType::ULongLong:
714 Out << 'k'; break;
715 case BuiltinType::UInt128:
716 Out << 'j'; break;
717 case BuiltinType::Char_U:
718 case BuiltinType::Char_S:
719 Out << 'C'; break;
720 case BuiltinType::SChar:
721 Out << 'r'; break;
722 case BuiltinType::WChar_S:
723 case BuiltinType::WChar_U:
724 Out << 'W'; break;
725 case BuiltinType::Short:
726 Out << 'S'; break;
727 case BuiltinType::Int:
728 Out << 'I'; break;
729 case BuiltinType::Long:
730 Out << 'L'; break;
731 case BuiltinType::LongLong:
732 Out << 'K'; break;
733 case BuiltinType::Int128:
734 Out << 'J'; break;
735 case BuiltinType::Float16:
736 case BuiltinType::Half:
737 Out << 'h'; break;
738 case BuiltinType::Float:
739 Out << 'f'; break;
740 case BuiltinType::Double:
741 Out << 'd'; break;
742 case BuiltinType::LongDouble:
743 Out << 'D'; break;
744 case BuiltinType::Float128:
745 Out << 'Q'; break;
746 case BuiltinType::NullPtr:
747 Out << 'n'; break;
748#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
749 case BuiltinType::Id: \
750 Out << "@BT@" << #Suffix << "_" << #ImgType; break;
751#include "clang/Basic/OpenCLImageTypes.def"
752#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
753 case BuiltinType::Id: \
754 Out << "@BT@" << #ExtType; break;
755#include "clang/Basic/OpenCLExtensionTypes.def"
756 case BuiltinType::OCLEvent:
757 Out << "@BT@OCLEvent"; break;
758 case BuiltinType::OCLClkEvent:
759 Out << "@BT@OCLClkEvent"; break;
760 case BuiltinType::OCLQueue:
761 Out << "@BT@OCLQueue"; break;
762 case BuiltinType::OCLReserveID:
763 Out << "@BT@OCLReserveID"; break;
764 case BuiltinType::OCLSampler:
765 Out << "@BT@OCLSampler"; break;
766#define SVE_TYPE(Name, Id, SingletonId) \
767 case BuiltinType::Id: \
768 Out << "@BT@" << #Name; \
769 break;
770#include "clang/Basic/AArch64ACLETypes.def"
771#define PPC_VECTOR_TYPE(Name, Id, Size) \
772 case BuiltinType::Id: \
773 Out << "@BT@" << #Name; break;
774#include "clang/Basic/PPCTypes.def"
775#define RVV_TYPE(Name, Id, SingletonId) \
776 case BuiltinType::Id: \
777 Out << "@BT@" << Name; break;
778#include "clang/Basic/RISCVVTypes.def"
779#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
780#include "clang/Basic/WebAssemblyReferenceTypes.def"
781#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) \
782 case BuiltinType::Id: \
783 Out << "@BT@" << #Name; \
784 break;
785#include "clang/Basic/AMDGPUTypes.def"
786#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
787 case BuiltinType::Id: \
788 Out << "@BT@" << #Name; \
789 break;
790#include "clang/Basic/HLSLIntangibleTypes.def"
791 case BuiltinType::ShortAccum:
792 Out << "@BT@ShortAccum"; break;
793 case BuiltinType::Accum:
794 Out << "@BT@Accum"; break;
795 case BuiltinType::LongAccum:
796 Out << "@BT@LongAccum"; break;
797 case BuiltinType::UShortAccum:
798 Out << "@BT@UShortAccum"; break;
799 case BuiltinType::UAccum:
800 Out << "@BT@UAccum"; break;
801 case BuiltinType::ULongAccum:
802 Out << "@BT@ULongAccum"; break;
803 case BuiltinType::ShortFract:
804 Out << "@BT@ShortFract"; break;
805 case BuiltinType::Fract:
806 Out << "@BT@Fract"; break;
807 case BuiltinType::LongFract:
808 Out << "@BT@LongFract"; break;
809 case BuiltinType::UShortFract:
810 Out << "@BT@UShortFract"; break;
811 case BuiltinType::UFract:
812 Out << "@BT@UFract"; break;
813 case BuiltinType::ULongFract:
814 Out << "@BT@ULongFract"; break;
815 case BuiltinType::SatShortAccum:
816 Out << "@BT@SatShortAccum"; break;
817 case BuiltinType::SatAccum:
818 Out << "@BT@SatAccum"; break;
819 case BuiltinType::SatLongAccum:
820 Out << "@BT@SatLongAccum"; break;
821 case BuiltinType::SatUShortAccum:
822 Out << "@BT@SatUShortAccum"; break;
823 case BuiltinType::SatUAccum:
824 Out << "@BT@SatUAccum"; break;
825 case BuiltinType::SatULongAccum:
826 Out << "@BT@SatULongAccum"; break;
827 case BuiltinType::SatShortFract:
828 Out << "@BT@SatShortFract"; break;
829 case BuiltinType::SatFract:
830 Out << "@BT@SatFract"; break;
831 case BuiltinType::SatLongFract:
832 Out << "@BT@SatLongFract"; break;
833 case BuiltinType::SatUShortFract:
834 Out << "@BT@SatUShortFract"; break;
835 case BuiltinType::SatUFract:
836 Out << "@BT@SatUFract"; break;
837 case BuiltinType::SatULongFract:
838 Out << "@BT@SatULongFract"; break;
839 case BuiltinType::BFloat16:
840 Out << "@BT@__bf16"; break;
841 case BuiltinType::Ibm128:
842 Out << "@BT@__ibm128"; break;
843 case BuiltinType::ObjCId:
844 Out << 'o'; break;
845 case BuiltinType::ObjCClass:
846 Out << 'O'; break;
847 case BuiltinType::ObjCSel:
848 Out << 'e'; break;
849#define BUILTIN_TYPE(Id, SingletonId)
850#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
851#include "clang/AST/BuiltinTypes.def"
852 case BuiltinType::Dependent:
853 // If you're adding a new builtin type, please add its name prefixed
854 // with "@BT@" to `Out` (see cases above).
855 IgnoreResults = true;
856 break;
857 }
858 return;
859 }
860
861 // If we have already seen this (non-built-in) type, use a substitution
862 // encoding. Otherwise, record this as a substitution.
863 auto [Substitution, Inserted] =
864 TypeSubstitutions.try_emplace(T.getTypePtr(), TypeSubstitutions.size());
865 if (!Inserted) {
866 Out << 'S' << Substitution->second << '_';
867 return;
868 }
869
870 if (const PointerType *PT = T->getAs<PointerType>()) {
871 Out << '*';
872 T = PT->getPointeeType();
873 continue;
874 }
875 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
876 Out << '*';
877 T = OPT->getPointeeType();
878 continue;
879 }
880 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
881 Out << "&&";
882 T = RT->getPointeeType();
883 continue;
884 }
885 if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
886 Out << '&';
887 T = RT->getPointeeType();
888 continue;
889 }
890 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
891 Out << 'F';
892 VisitType(FT->getReturnType());
893 Out << '(';
894 for (const auto &I : FT->param_types()) {
895 Out << '#';
896 VisitType(I);
897 }
898 Out << ')';
899 if (FT->isVariadic())
900 Out << '.';
901 return;
902 }
903 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
904 Out << 'B';
905 T = BT->getPointeeType();
906 continue;
907 }
908 if (const ComplexType *CT = T->getAs<ComplexType>()) {
909 Out << '<';
910 T = CT->getElementType();
911 continue;
912 }
913 if (const TagType *TT = T->getAs<TagType>()) {
914 if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TT)) {
915 T = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Ctx);
916 } else {
917 Out << '$';
918 VisitTagDecl(TT->getDecl());
919 return;
920 }
921 }
922 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
923 Out << '$';
924 VisitObjCInterfaceDecl(OIT->getDecl());
925 return;
926 }
927 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
928 Out << 'Q';
929 VisitType(OIT->getBaseType());
930 for (auto *Prot : OIT->getProtocols())
931 VisitObjCProtocolDecl(Prot);
932 return;
933 }
934 if (const TemplateTypeParmType *TTP =
935 T->getAsCanonical<TemplateTypeParmType>()) {
936 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
937 return;
938 }
939 if (const TemplateSpecializationType *Spec
940 = T->getAs<TemplateSpecializationType>()) {
941 Out << '>';
942 VisitTemplateName(Spec->getTemplateName());
943 Out << Spec->template_arguments().size();
944 for (const auto &Arg : Spec->template_arguments())
945 VisitTemplateArgument(Arg);
946 return;
947 }
948 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
949 Out << '^';
950 printQualifier(Out, LangOpts, DNT->getQualifier());
951 Out << ':' << DNT->getIdentifier()->getName();
952 return;
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();
991 for (TemplateParameterList::const_iterator P = Params->begin(),
992 PEnd = Params->end();
993 P != PEnd; ++P) {
994 Out << '#';
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()) {
1020 if (TemplateTemplateParmDecl *TTP
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, LangOpts, 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, LangOpts, 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 return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts());
1189}
1190
1192 const LangOptions &LangOpts) {
1193 if (!D)
1194 return true;
1195 // We don't ignore decls with invalid source locations. Implicit decls, like
1196 // C++'s operator new function, can have invalid locations but it is fine to
1197 // create USRs that can identify them.
1198
1199 // Check if the declaration has explicit external USR specified.
1200 auto *CD = D->getCanonicalDecl();
1201 if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
1202 if (!ExternalSymAttr->getUSR().empty()) {
1203 llvm::raw_svector_ostream Out(Buf);
1204 Out << ExternalSymAttr->getUSR();
1205 return false;
1206 }
1207 }
1208 USRGenerator UG(&D->getASTContext(), Buf, LangOpts);
1209 UG.Visit(D);
1210 return UG.ignoreResults();
1211}
1212
1214 const SourceManager &SM,
1215 SmallVectorImpl<char> &Buf) {
1216 if (!MD)
1217 return true;
1218 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(),
1219 SM, Buf);
1220
1221}
1222
1224 const SourceManager &SM,
1225 SmallVectorImpl<char> &Buf) {
1226 if (MacroName.empty())
1227 return true;
1228
1229 llvm::raw_svector_ostream Out(Buf);
1230
1231 // Assume that system headers are sane. Don't put source location
1232 // information into the USR if the macro comes from a system header.
1233 bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
1234
1235 Out << getUSRSpacePrefix();
1236 if (ShouldGenerateLocation)
1237 printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1238 Out << "@macro@";
1239 Out << MacroName;
1240 return false;
1241}
1242
1244 SmallVectorImpl<char> &Buf) {
1245 return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts());
1246}
1247
1250 const LangOptions &LangOpts) {
1251 if (T.isNull())
1252 return true;
1253 T = T.getCanonicalType();
1254
1255 USRGenerator UG(&Ctx, Buf, LangOpts);
1256 UG.VisitType(T);
1257 return UG.ignoreResults();
1258}
1259
1261 raw_ostream &OS) {
1262 if (!Mod->Parent)
1264 if (generateFullUSRForModule(Mod->Parent, OS))
1265 return true;
1266 return generateUSRFragmentForModule(Mod, OS);
1267}
1268
1270 raw_ostream &OS) {
1271 OS << getUSRSpacePrefix();
1272 return generateUSRFragmentForModuleName(ModName, OS);
1273}
1274
1276 raw_ostream &OS) {
1277 return generateUSRFragmentForModuleName(Mod->Name, OS);
1278}
1279
1281 raw_ostream &OS) {
1282 OS << "@M@" << ModName;
1283 return false;
1284}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
This file contains the declaration of the ODRHash class, which calculates a hash based on AST nodes,...
#define SM(sm)
static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn, StringRef CatSymDefinedIn, raw_ostream &OS)
static bool printLoc(llvm::raw_ostream &OS, SourceLocation Loc, const SourceManager &SM, bool IncludeOffset)
static const ObjCCategoryDecl * getCategoryContext(const NamedDecl *D)
static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts, NestedNameSpecifier NNS)
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:226
SourceManager & getSourceManager()
Definition ASTContext.h:858
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
Definition ASTContext.h:951
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...
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
A simple visitor class that helps create declaration visitors.
Definition DeclVisitor.h:75
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
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:341
T * getAttr() const
Definition DeclBase.h:573
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:546
ExternalSourceSymbolAttr * getExternalSourceSymbolAttr() const
Looks on this and related declarations for an applicable external source symbol attribute.
Definition DeclBase.cpp:612
SourceLocation getLocation() const
Definition DeclBase.h:439
DeclContext * getDeclContext()
Definition DeclBase.h:448
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:431
bool hasAttr() const
Definition DeclBase.h:577
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:978
Kind getKind() const
Definition DeclBase.h:442
void print(raw_ostream &OS, const PrintingPolicy &Policy) const
bool isEmpty() const
Evaluates true when this declaration name is empty.
StringRef getName() const
The name of this FileEntry.
Definition FileEntry.h:61
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4206
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4194
QualType getReturnType() const
Definition Decl.h:2845
bool isVariadic() const
Whether this function is variadic.
Definition Decl.cpp:3134
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4330
bool isExternC() const
Determines whether this function is a function with external, C linkage.
Definition Decl.cpp:3619
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition Decl.cpp:4340
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
StringRef getName() const
Return the actual identifier string.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
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.
Module * Parent
The parent of this module.
Definition Module.h:193
std::string Name
The name of this module.
Definition Module.h:147
This represents a decl that may have a name.
Definition Decl.h:274
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
bool isExternallyVisible() const
Definition Decl.h:433
bool isAnonymousNamespace() const
Returns true if this is an anonymous namespace declaration.
Definition Decl.h:643
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
void AddStructuralValue(const APValue &)
Definition ODRHash.cpp:1258
unsigned CalculateHash()
Definition ODRHash.cpp:231
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2329
ObjCInterfaceDecl * getClassInterface()
Definition DeclObjC.h:2372
bool IsClassExtension() const
Definition DeclObjC.h:2437
const ObjCInterfaceDecl * getClassInterface() const
Definition DeclObjC.h:2486
Selector getSelector() const
Definition DeclObjC.h:327
bool isInstanceMethod() const
Definition DeclObjC.h:426
ObjCInterfaceDecl * getClassInterface()
bool isClassProperty() const
Definition DeclObjC.h:855
ObjCPropertyDecl * getPropertyDecl() const
Definition DeclObjC.h:2870
A (possibly-)qualified type.
Definition TypeBase.h:937
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1004
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8388
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8428
QualType getCanonicalType() const
Definition TypeBase.h:8440
bool hasConst() const
Definition TypeBase.h:457
bool hasRestrict() const
Definition TypeBase.h:477
bool hasVolatile() const
Definition TypeBase.h:467
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.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
bool isEmbeddedInDeclarator() const
True if this tag declaration is "embedded" (i.e., defined or declared for the very first time) in the...
Definition Decl.h:3842
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:3954
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
Definition Decl.cpp:4900
bool isFreeStanding() const
True if this tag is free standing, e.g. "struct foo;".
Definition Decl.h:3853
TagKind getTagKind() const
Definition Decl.h:3917
unsigned size() const
Retrieve the number of template arguments in this template argument list.
const TemplateArgument & get(unsigned Idx) const
Retrieve the template argument at a given index.
QualType getStructuralValueType() const
Get the type of a StructuralValue.
QualType getAsType() const
Retrieve the type for a type template argument.
llvm::APSInt getAsIntegral() const
Retrieve the template argument as an integral value.
unsigned pack_size() const
The number of template arguments in the given template argument pack.
QualType getIntegralType() const
Retrieve the type of the integral value.
ValueDecl * getAsDecl() const
Retrieve the declaration for a declaration non-type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
const APValue & getAsStructuralValue() const
Get the value of a StructuralValue.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
bool isParameterPack() const
Whether this template template parameter is a template parameter pack.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition Type.cpp:753
bool isExtVectorType() const
Definition TypeBase.h:8768
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2929
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9218
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition DeclCXX.h:4077
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition DeclCXX.h:3987
QualType getType() const
Definition Decl.h:723
VarTemplateDecl * getDescribedVarTemplate() const
Retrieves the variable template that is described by this variable declaration.
Definition Decl.cpp:2822
bool generateFullUSRForTopLevelModuleName(StringRef ModName, raw_ostream &OS)
Generate a USR for a top-level module name, including the USR prefix.
static StringRef getUSRSpacePrefix()
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.
bool isa(CodeGen::Address addr)
Definition Address.h:330
CustomizableOptional< FileEntryRef > OptionalFileEntryRef
Definition FileEntry.h:208
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1788
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1791
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1794
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
std::pair< FileID, unsigned > FileIDAndOffset
@ Template
We are parsing a template declaration.
Definition Parser.h:81
U cast(CodeGen::Address addr)
Definition Address.h:327
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressUnwrittenScope
Suppress printing parts of scope specifiers that are never written, e.g., for anonymous namespaces.
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.
@ Plain
E.g., (anonymous enum)/(unnamed struct)/etc.