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, StringRef clsExt,
150 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:
301 break;
302 case RQ_LValue:
303 Out << '&';
304 break;
305 case RQ_RValue:
306 Out << "&&";
307 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(
379 const TemplateTemplateParmDecl *D) {
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 } else {
421 // The USR for a method declared in a class extension or category is based
422 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
423 const ObjCInterfaceDecl *ID = D->getClassInterface();
424 if (!ID) {
425 IgnoreResults = true;
426 return;
427 }
428 auto *CD = getCategoryContext(D);
429 VisitObjCContainerDecl(ID, CD);
430 }
431 // Ideally we would use 'GenObjCMethod', but this is such a hot path
432 // for Objective-C code that we don't want to use
433 // DeclarationName::getAsString().
434 Out << (D->isInstanceMethod() ? "(im)" : "(cm)")
435 << DeclarationName(D->getSelector());
436}
437
438void USRGenerator::VisitObjCContainerDecl(const ObjCContainerDecl *D,
439 const ObjCCategoryDecl *CatD) {
440 switch (D->getKind()) {
441 default:
442 llvm_unreachable("Invalid ObjC container.");
443 case Decl::ObjCInterface:
444 case Decl::ObjCImplementation:
445 GenObjCClass(D->getName(), GetExternalSourceContainer(D),
447 break;
448 case Decl::ObjCCategory: {
449 const ObjCCategoryDecl *CD = cast<ObjCCategoryDecl>(D);
450 const ObjCInterfaceDecl *ID = CD->getClassInterface();
451 if (!ID) {
452 // Handle invalid code where the @interface might not
453 // have been specified.
454 // FIXME: We should be able to generate this USR even if the
455 // @interface isn't available.
456 IgnoreResults = true;
457 return;
458 }
459 // Specially handle class extensions, which are anonymous categories.
460 // We want to mangle in the location to uniquely distinguish them.
461 if (CD->IsClassExtension()) {
462 Out << "objc(ext)" << ID->getName() << '@';
463 GenLoc(CD, /*IncludeOffset=*/true);
464 } else
465 GenObjCCategory(ID->getName(), CD->getName(),
468
469 break;
470 }
471 case Decl::ObjCCategoryImpl: {
472 const ObjCCategoryImplDecl *CD = cast<ObjCCategoryImplDecl>(D);
473 const ObjCInterfaceDecl *ID = CD->getClassInterface();
474 if (!ID) {
475 // Handle invalid code where the @interface might not
476 // have been specified.
477 // FIXME: We should be able to generate this USR even if the
478 // @interface isn't available.
479 IgnoreResults = true;
480 return;
481 }
482 GenObjCCategory(ID->getName(), CD->getName(),
485 break;
486 }
487 case Decl::ObjCProtocol: {
488 const ObjCProtocolDecl *PD = cast<ObjCProtocolDecl>(D);
489 GenObjCProtocol(PD->getName(), GetExternalSourceContainer(PD));
490 break;
491 }
492 }
493}
494
495void USRGenerator::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) {
496 // The USR for a property declared in a class extension or category is based
497 // on the ObjCInterfaceDecl, not the ObjCCategoryDecl.
498 if (const ObjCInterfaceDecl *ID = Context->getObjContainingInterface(D))
499 VisitObjCContainerDecl(ID, getCategoryContext(D));
500 else
501 Visit(cast<Decl>(D->getDeclContext()));
502 GenObjCProperty(D->getName(), D->isClassProperty());
503}
504
505void USRGenerator::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) {
506 if (ObjCPropertyDecl *PD = D->getPropertyDecl()) {
507 VisitObjCPropertyDecl(PD);
508 return;
509 }
510
511 IgnoreResults = true;
512}
513
514void USRGenerator::VisitTagDecl(const TagDecl *D) {
515 // Add the location of the tag decl to handle resolution across
516 // translation units.
517 if (!isa<EnumDecl>(D) && ShouldGenerateLocation(D) &&
518 GenLoc(D, /*IncludeOffset=*/isLocal(D)))
519 return;
520
521 GenExtSymbolContainer(D);
522
523 D = D->getCanonicalDecl();
524 VisitDeclContext(D->getDeclContext());
525
526 bool AlreadyStarted = false;
527 if (const CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(D)) {
528 if (ClassTemplateDecl *ClassTmpl = CXXRecord->getDescribedClassTemplate()) {
529 AlreadyStarted = true;
530
531 switch (D->getTagKind()) {
532 case TagTypeKind::Interface:
533 case TagTypeKind::Class:
534 case TagTypeKind::Struct:
535 Out << "@ST";
536 break;
537 case TagTypeKind::Union:
538 Out << "@UT";
539 break;
540 case TagTypeKind::Enum:
541 llvm_unreachable("enum template");
542 }
543 VisitTemplateParameterList(ClassTmpl->getTemplateParameters());
544 } else if (const ClassTemplatePartialSpecializationDecl *PartialSpec =
545 dyn_cast<ClassTemplatePartialSpecializationDecl>(
546 CXXRecord)) {
547 AlreadyStarted = true;
548
549 switch (D->getTagKind()) {
550 case TagTypeKind::Interface:
551 case TagTypeKind::Class:
552 case TagTypeKind::Struct:
553 Out << "@SP";
554 break;
555 case TagTypeKind::Union:
556 Out << "@UP";
557 break;
558 case TagTypeKind::Enum:
559 llvm_unreachable("enum partial specialization");
560 }
561 VisitTemplateParameterList(PartialSpec->getTemplateParameters());
562 }
563 }
564
565 if (!AlreadyStarted) {
566 switch (D->getTagKind()) {
567 case TagTypeKind::Interface:
568 case TagTypeKind::Class:
569 case TagTypeKind::Struct:
570 Out << "@S";
571 break;
572 case TagTypeKind::Union:
573 Out << "@U";
574 break;
575 case TagTypeKind::Enum:
576 Out << "@E";
577 break;
578 }
579 }
580
581 Out << '@';
582 assert(Buf.size() > 0);
583 const unsigned off = Buf.size() - 1;
584
585 if (EmitDeclName(D)) {
586 if (const TypedefNameDecl *TD = D->getTypedefNameForAnonDecl()) {
587 Buf[off] = 'A';
588 Out << '@' << *TD;
589 } else {
590 if (D->isEmbeddedInDeclarator() && !D->isFreeStanding()) {
591 printLoc(Out, D->getLocation(), Context->getSourceManager(), true);
592 } else {
593 Buf[off] = 'a';
594 if (auto *ED = dyn_cast<EnumDecl>(D)) {
595 // Distinguish USRs of anonymous enums by using their first
596 // enumerator.
597 auto enum_range = ED->enumerators();
598 if (enum_range.begin() != enum_range.end()) {
599 Out << '@' << **enum_range.begin();
600 }
601 }
602 }
603 }
604 }
605
606 // For a class template specialization, mangle the template arguments.
607 if (const ClassTemplateSpecializationDecl *Spec =
608 dyn_cast<ClassTemplateSpecializationDecl>(D)) {
609 const TemplateArgumentList &Args = Spec->getTemplateArgs();
610 Out << '>';
611 for (unsigned I = 0, N = Args.size(); I != N; ++I) {
612 Out << '#';
613 VisitTemplateArgument(Args.get(I));
614 }
615 }
616}
617
618void USRGenerator::VisitTypedefDecl(const TypedefDecl *D) {
619 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
620 return;
621 const DeclContext *DC = D->getDeclContext();
622 if (const NamedDecl *DCN = dyn_cast<NamedDecl>(DC))
623 Visit(DCN);
624 Out << "@T@";
625 Out << D->getName();
626}
627
628void USRGenerator::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
629 GenLoc(D, /*IncludeOffset=*/true);
630}
631
632void USRGenerator::GenExtSymbolContainer(const NamedDecl *D) {
633 StringRef Container = GetExternalSourceContainer(D);
634 if (!Container.empty())
635 Out << "@M@" << Container;
636}
637
638bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
639 if (generatedLoc)
640 return IgnoreResults;
641 generatedLoc = true;
642
643 // Guard against null declarations in invalid code.
644 if (!D) {
645 IgnoreResults = true;
646 return true;
647 }
648
649 // Use the location of canonical decl.
650 D = D->getCanonicalDecl();
651
652 IgnoreResults =
653 IgnoreResults || printLoc(Out, D->getBeginLoc(),
654 Context->getSourceManager(), IncludeOffset);
655
656 return IgnoreResults;
657}
658
659static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts,
661 // FIXME: Encode the qualifier, don't just print it.
662 PrintingPolicy PO(LangOpts);
663 PO.SuppressTagKeyword = true;
664 PO.SuppressUnwrittenScope = true;
667 llvm::to_underlying(PrintingPolicy::AnonymousTagMode::Plain);
668 NNS.print(Out, PO);
669}
670
671void USRGenerator::VisitType(QualType T) {
672 // This method mangles in USR information for types. It can possibly
673 // just reuse the naming-mangling logic used by codegen, although the
674 // requirements for USRs might not be the same.
675 ASTContext &Ctx = *Context;
676
677 do {
678 T = Ctx.getCanonicalType(T);
679 Qualifiers Q = T.getQualifiers();
680 unsigned qVal = 0;
681 if (Q.hasConst())
682 qVal |= 0x1;
683 if (Q.hasVolatile())
684 qVal |= 0x2;
685 if (Q.hasRestrict())
686 qVal |= 0x4;
687 if (qVal)
688 Out << ((char)('0' + qVal));
689
690 // Mangle in ObjC GC qualifiers?
691
692 if (const PackExpansionType *Expansion = T->getAs<PackExpansionType>()) {
693 Out << 'P';
694 T = Expansion->getPattern();
695 }
696
697 if (const BuiltinType *BT = T->getAs<BuiltinType>()) {
698 switch (BT->getKind()) {
699 case BuiltinType::Void:
700 Out << 'v';
701 break;
702 case BuiltinType::Bool:
703 Out << 'b';
704 break;
705 case BuiltinType::UChar:
706 Out << 'c';
707 break;
708 case BuiltinType::Char8:
709 Out << 'u';
710 break;
711 case BuiltinType::Char16:
712 Out << 'q';
713 break;
714 case BuiltinType::Char32:
715 Out << 'w';
716 break;
717 case BuiltinType::UShort:
718 Out << 's';
719 break;
720 case BuiltinType::UInt:
721 Out << 'i';
722 break;
723 case BuiltinType::ULong:
724 Out << 'l';
725 break;
726 case BuiltinType::ULongLong:
727 Out << 'k';
728 break;
729 case BuiltinType::UInt128:
730 Out << 'j';
731 break;
732 case BuiltinType::Char_U:
733 case BuiltinType::Char_S:
734 Out << 'C';
735 break;
736 case BuiltinType::SChar:
737 Out << 'r';
738 break;
739 case BuiltinType::WChar_S:
740 case BuiltinType::WChar_U:
741 Out << 'W';
742 break;
743 case BuiltinType::Short:
744 Out << 'S';
745 break;
746 case BuiltinType::Int:
747 Out << 'I';
748 break;
749 case BuiltinType::Long:
750 Out << 'L';
751 break;
752 case BuiltinType::LongLong:
753 Out << 'K';
754 break;
755 case BuiltinType::Int128:
756 Out << 'J';
757 break;
758 case BuiltinType::Float16:
759 case BuiltinType::Half:
760 Out << 'h';
761 break;
762 case BuiltinType::Float:
763 Out << 'f';
764 break;
765 case BuiltinType::Double:
766 Out << 'd';
767 break;
768 case BuiltinType::LongDouble:
769 Out << 'D';
770 break;
771 case BuiltinType::Float128:
772 Out << 'Q';
773 break;
774 case BuiltinType::NullPtr:
775 Out << 'n';
776 break;
777#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
778 case BuiltinType::Id: \
779 Out << "@BT@" << #Suffix << "_" << #ImgType; \
780 break;
781#include "clang/Basic/OpenCLImageTypes.def"
782#define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
783 case BuiltinType::Id: \
784 Out << "@BT@" << #ExtType; \
785 break;
786#include "clang/Basic/OpenCLExtensionTypes.def"
787 case BuiltinType::OCLEvent:
788 Out << "@BT@OCLEvent";
789 break;
790 case BuiltinType::OCLClkEvent:
791 Out << "@BT@OCLClkEvent";
792 break;
793 case BuiltinType::OCLQueue:
794 Out << "@BT@OCLQueue";
795 break;
796 case BuiltinType::OCLReserveID:
797 Out << "@BT@OCLReserveID";
798 break;
799 case BuiltinType::OCLSampler:
800 Out << "@BT@OCLSampler";
801 break;
802#define SVE_TYPE(Name, Id, SingletonId) \
803 case BuiltinType::Id: \
804 Out << "@BT@" << #Name; \
805 break;
806#include "clang/Basic/AArch64ACLETypes.def"
807#define PPC_VECTOR_TYPE(Name, Id, Size) \
808 case BuiltinType::Id: \
809 Out << "@BT@" << #Name; \
810 break;
811#include "clang/Basic/PPCTypes.def"
812#define RVV_TYPE(Name, Id, SingletonId) \
813 case BuiltinType::Id: \
814 Out << "@BT@" << Name; \
815 break;
816#include "clang/Basic/RISCVVTypes.def"
817#define WASM_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
818#include "clang/Basic/WebAssemblyReferenceTypes.def"
819#define AMDGPU_TYPE(Name, Id, SingletonId, Width, Align) \
820 case BuiltinType::Id: \
821 Out << "@BT@" << #Name; \
822 break;
823#include "clang/Basic/AMDGPUTypes.def"
824#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
825 case BuiltinType::Id: \
826 Out << "@BT@" << #Name; \
827 break;
828#include "clang/Basic/HLSLIntangibleTypes.def"
829 case BuiltinType::ShortAccum:
830 Out << "@BT@ShortAccum";
831 break;
832 case BuiltinType::Accum:
833 Out << "@BT@Accum";
834 break;
835 case BuiltinType::LongAccum:
836 Out << "@BT@LongAccum";
837 break;
838 case BuiltinType::UShortAccum:
839 Out << "@BT@UShortAccum";
840 break;
841 case BuiltinType::UAccum:
842 Out << "@BT@UAccum";
843 break;
844 case BuiltinType::ULongAccum:
845 Out << "@BT@ULongAccum";
846 break;
847 case BuiltinType::ShortFract:
848 Out << "@BT@ShortFract";
849 break;
850 case BuiltinType::Fract:
851 Out << "@BT@Fract";
852 break;
853 case BuiltinType::LongFract:
854 Out << "@BT@LongFract";
855 break;
856 case BuiltinType::UShortFract:
857 Out << "@BT@UShortFract";
858 break;
859 case BuiltinType::UFract:
860 Out << "@BT@UFract";
861 break;
862 case BuiltinType::ULongFract:
863 Out << "@BT@ULongFract";
864 break;
865 case BuiltinType::SatShortAccum:
866 Out << "@BT@SatShortAccum";
867 break;
868 case BuiltinType::SatAccum:
869 Out << "@BT@SatAccum";
870 break;
871 case BuiltinType::SatLongAccum:
872 Out << "@BT@SatLongAccum";
873 break;
874 case BuiltinType::SatUShortAccum:
875 Out << "@BT@SatUShortAccum";
876 break;
877 case BuiltinType::SatUAccum:
878 Out << "@BT@SatUAccum";
879 break;
880 case BuiltinType::SatULongAccum:
881 Out << "@BT@SatULongAccum";
882 break;
883 case BuiltinType::SatShortFract:
884 Out << "@BT@SatShortFract";
885 break;
886 case BuiltinType::SatFract:
887 Out << "@BT@SatFract";
888 break;
889 case BuiltinType::SatLongFract:
890 Out << "@BT@SatLongFract";
891 break;
892 case BuiltinType::SatUShortFract:
893 Out << "@BT@SatUShortFract";
894 break;
895 case BuiltinType::SatUFract:
896 Out << "@BT@SatUFract";
897 break;
898 case BuiltinType::SatULongFract:
899 Out << "@BT@SatULongFract";
900 break;
901 case BuiltinType::BFloat16:
902 Out << "@BT@__bf16";
903 break;
904 case BuiltinType::Ibm128:
905 Out << "@BT@__ibm128";
906 break;
907 case BuiltinType::ObjCId:
908 Out << 'o';
909 break;
910 case BuiltinType::ObjCClass:
911 Out << 'O';
912 break;
913 case BuiltinType::ObjCSel:
914 Out << 'e';
915 break;
916#define BUILTIN_TYPE(Id, SingletonId)
917#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
918#include "clang/AST/BuiltinTypes.def"
919 case BuiltinType::Dependent:
920 // If you're adding a new builtin type, please add its name prefixed
921 // with "@BT@" to `Out` (see cases above).
922 IgnoreResults = true;
923 break;
924 }
925 return;
926 }
927
928 // If we have already seen this (non-built-in) type, use a substitution
929 // encoding. Otherwise, record this as a substitution.
930 auto [Substitution, Inserted] =
931 TypeSubstitutions.try_emplace(T.getTypePtr(), TypeSubstitutions.size());
932 if (!Inserted) {
933 Out << 'S' << Substitution->second << '_';
934 return;
935 }
936
937 if (const PointerType *PT = T->getAs<PointerType>()) {
938 Out << '*';
939 T = PT->getPointeeType();
940 continue;
941 }
942 if (const ObjCObjectPointerType *OPT = T->getAs<ObjCObjectPointerType>()) {
943 Out << '*';
944 T = OPT->getPointeeType();
945 continue;
946 }
947 if (const RValueReferenceType *RT = T->getAs<RValueReferenceType>()) {
948 Out << "&&";
949 T = RT->getPointeeType();
950 continue;
951 }
952 if (const ReferenceType *RT = T->getAs<ReferenceType>()) {
953 Out << '&';
954 T = RT->getPointeeType();
955 continue;
956 }
957 if (const FunctionProtoType *FT = T->getAs<FunctionProtoType>()) {
958 Out << 'F';
959 VisitType(FT->getReturnType());
960 Out << '(';
961 for (const auto &I : FT->param_types()) {
962 Out << '#';
963 VisitType(I);
964 }
965 Out << ')';
966 if (FT->isVariadic())
967 Out << '.';
968 return;
969 }
970 if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) {
971 Out << 'B';
972 T = BT->getPointeeType();
973 continue;
974 }
975 if (const ComplexType *CT = T->getAs<ComplexType>()) {
976 Out << '<';
977 T = CT->getElementType();
978 continue;
979 }
980 if (const TagType *TT = T->getAs<TagType>()) {
981 if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TT)) {
982 T = ICNT->getDecl()->getCanonicalTemplateSpecializationType(Ctx);
983 } else {
984 Out << '$';
985 VisitTagDecl(TT->getDecl());
986 return;
987 }
988 }
989 if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
990 Out << '$';
991 VisitObjCInterfaceDecl(OIT->getDecl());
992 return;
993 }
994 if (const ObjCObjectType *OIT = T->getAs<ObjCObjectType>()) {
995 Out << 'Q';
996 VisitType(OIT->getBaseType());
997 for (auto *Prot : OIT->getProtocols())
998 VisitObjCProtocolDecl(Prot);
999 return;
1000 }
1001 if (const TemplateTypeParmType *TTP =
1002 T->getAsCanonical<TemplateTypeParmType>()) {
1003 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1004 return;
1005 }
1006 if (const TemplateSpecializationType *Spec =
1007 T->getAs<TemplateSpecializationType>()) {
1008 Out << '>';
1009 VisitTemplateName(Spec->getTemplateName());
1010 Out << Spec->template_arguments().size();
1011 for (const auto &Arg : Spec->template_arguments())
1012 VisitTemplateArgument(Arg);
1013 return;
1014 }
1015 if (const DependentNameType *DNT = T->getAs<DependentNameType>()) {
1016 Out << '^';
1017 printQualifier(Out, LangOpts, DNT->getQualifier());
1018 Out << ':' << DNT->getIdentifier()->getName();
1019 return;
1020 }
1021 if (const auto *VT = T->getAs<VectorType>()) {
1022 Out << (T->isExtVectorType() ? ']' : '[');
1023 Out << VT->getNumElements();
1024 T = VT->getElementType();
1025 continue;
1026 }
1027 if (const auto *const AT = dyn_cast<ArrayType>(T)) {
1028 Out << '{';
1029 switch (AT->getSizeModifier()) {
1030 case ArraySizeModifier::Static:
1031 Out << 's';
1032 break;
1033 case ArraySizeModifier::Star:
1034 Out << '*';
1035 break;
1036 case ArraySizeModifier::Normal:
1037 Out << 'n';
1038 break;
1039 }
1040 if (const auto *const CAT = dyn_cast<ConstantArrayType>(T))
1041 Out << CAT->getSize();
1042
1043 T = AT->getElementType();
1044 continue;
1045 }
1046
1047 // Unhandled type.
1048 Out << ' ';
1049 break;
1050 } while (true);
1051}
1052
1053void USRGenerator::VisitTemplateParameterList(
1054 const TemplateParameterList *Params) {
1055 if (!Params)
1056 return;
1057 Out << '>' << Params->size();
1058 for (TemplateParameterList::const_iterator P = Params->begin(),
1059 PEnd = Params->end();
1060 P != PEnd; ++P) {
1061 Out << '#';
1062 if (isa<TemplateTypeParmDecl>(*P)) {
1063 if (cast<TemplateTypeParmDecl>(*P)->isParameterPack())
1064 Out << 'p';
1065 Out << 'T';
1066 continue;
1067 }
1068
1069 if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1070 if (NTTP->isParameterPack())
1071 Out << 'p';
1072 Out << 'N';
1073 VisitType(NTTP->getType());
1074 continue;
1075 }
1076
1077 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1078 if (TTP->isParameterPack())
1079 Out << 'p';
1080 Out << 't';
1081 VisitTemplateParameterList(TTP->getTemplateParameters());
1082 }
1083}
1084
1085void USRGenerator::VisitTemplateName(TemplateName Name) {
1086 if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
1087 if (TemplateTemplateParmDecl *TTP =
1088 dyn_cast<TemplateTemplateParmDecl>(Template)) {
1089 Out << 't' << TTP->getDepth() << '.' << TTP->getIndex();
1090 return;
1091 }
1092
1093 Visit(Template);
1094 return;
1095 }
1096
1097 // FIXME: Visit dependent template names.
1098}
1099
1100void USRGenerator::VisitTemplateArgument(const TemplateArgument &Arg) {
1101 switch (Arg.getKind()) {
1103 break;
1104
1106 Visit(Arg.getAsDecl());
1107 break;
1108
1110 break;
1111
1113 Out << 'P'; // pack expansion of...
1114 [[fallthrough]];
1116 VisitTemplateName(Arg.getAsTemplateOrTemplatePattern());
1117 break;
1118
1120 // FIXME: Visit expressions.
1121 break;
1122
1124 Out << 'p' << Arg.pack_size();
1125 for (const auto &P : Arg.pack_elements())
1126 VisitTemplateArgument(P);
1127 break;
1128
1130 VisitType(Arg.getAsType());
1131 break;
1132
1134 Out << 'V';
1135 VisitType(Arg.getIntegralType());
1136 Out << Arg.getAsIntegral();
1137 break;
1138
1140 Out << 'S';
1141 VisitType(Arg.getStructuralValueType());
1142 ODRHash Hash{};
1144 Out << Hash.CalculateHash();
1145 break;
1146 }
1147 }
1148}
1149
1150void USRGenerator::VisitUnresolvedUsingValueDecl(
1151 const UnresolvedUsingValueDecl *D) {
1152 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1153 return;
1154 VisitDeclContext(D->getDeclContext());
1155 Out << "@UUV@";
1156 printQualifier(Out, LangOpts, D->getQualifier());
1157 EmitDeclName(D);
1158}
1159
1160void USRGenerator::VisitUnresolvedUsingTypenameDecl(
1161 const UnresolvedUsingTypenameDecl *D) {
1162 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1163 return;
1164 VisitDeclContext(D->getDeclContext());
1165 Out << "@UUT@";
1166 printQualifier(Out, LangOpts, D->getQualifier());
1167 Out << D->getName(); // Simple name.
1168}
1169
1170void USRGenerator::VisitConceptDecl(const ConceptDecl *D) {
1171 if (ShouldGenerateLocation(D) && GenLoc(D, /*IncludeOffset=*/isLocal(D)))
1172 return;
1173 VisitDeclContext(D->getDeclContext());
1174 Out << "@CT@";
1175 EmitDeclName(D);
1176}
1177
1178void USRGenerator::VisitMSGuidDecl(const MSGuidDecl *D) {
1179 VisitDeclContext(D->getDeclContext());
1180 Out << "@MG@";
1181 D->NamedDecl::printName(Out);
1182}
1183
1184//===----------------------------------------------------------------------===//
1185// USR generation functions.
1186//===----------------------------------------------------------------------===//
1187
1188static void combineClassAndCategoryExtContainers(StringRef ClsSymDefinedIn,
1189 StringRef CatSymDefinedIn,
1190 raw_ostream &OS) {
1191 if (ClsSymDefinedIn.empty() && CatSymDefinedIn.empty())
1192 return;
1193 if (CatSymDefinedIn.empty()) {
1194 OS << "@M@" << ClsSymDefinedIn << '@';
1195 return;
1196 }
1197 OS << "@CM@" << CatSymDefinedIn << '@';
1198 if (ClsSymDefinedIn != CatSymDefinedIn) {
1199 OS << ClsSymDefinedIn << '@';
1200 }
1201}
1202
1204 StringRef Cls, raw_ostream &OS, StringRef ExtSymDefinedIn,
1205 StringRef CategoryContextExtSymbolDefinedIn) {
1207 CategoryContextExtSymbolDefinedIn, OS);
1208 OS << "objc(cs)" << Cls;
1209}
1210
1211void clang::index::generateUSRForObjCCategory(StringRef Cls, StringRef Cat,
1212 raw_ostream &OS,
1213 StringRef ClsSymDefinedIn,
1214 StringRef CatSymDefinedIn) {
1215 combineClassAndCategoryExtContainers(ClsSymDefinedIn, CatSymDefinedIn, OS);
1216 OS << "objc(cy)" << Cls << '@' << Cat;
1217}
1218
1219void clang::index::generateUSRForObjCIvar(StringRef Ivar, raw_ostream &OS) {
1220 OS << '@' << Ivar;
1221}
1222
1224 bool IsInstanceMethod,
1225 raw_ostream &OS) {
1226 OS << (IsInstanceMethod ? "(im)" : "(cm)") << Sel;
1227}
1228
1229void clang::index::generateUSRForObjCProperty(StringRef Prop, bool isClassProp,
1230 raw_ostream &OS) {
1231 OS << (isClassProp ? "(cpy)" : "(py)") << Prop;
1232}
1233
1234void clang::index::generateUSRForObjCProtocol(StringRef Prot, raw_ostream &OS,
1235 StringRef ExtSymDefinedIn) {
1236 if (!ExtSymDefinedIn.empty())
1237 OS << "@M@" << ExtSymDefinedIn << '@';
1238 OS << "objc(pl)" << Prot;
1239}
1240
1241void clang::index::generateUSRForGlobalEnum(StringRef EnumName, raw_ostream &OS,
1242 StringRef ExtSymDefinedIn) {
1243 if (!ExtSymDefinedIn.empty())
1244 OS << "@M@" << ExtSymDefinedIn;
1245 OS << "@E@" << EnumName;
1246}
1247
1248void clang::index::generateUSRForEnumConstant(StringRef EnumConstantName,
1249 raw_ostream &OS) {
1250 OS << '@' << EnumConstantName;
1251}
1252
1254 SmallVectorImpl<char> &Buf) {
1255 if (!D)
1256 return true;
1257 return generateUSRForDecl(D, Buf, D->getASTContext().getLangOpts());
1258}
1259
1261 const LangOptions &LangOpts) {
1262 if (!D)
1263 return true;
1264 // We don't ignore decls with invalid source locations. Implicit decls, like
1265 // C++'s operator new function, can have invalid locations but it is fine to
1266 // create USRs that can identify them.
1267
1268 // Check if the declaration has explicit external USR specified.
1269 auto *CD = D->getCanonicalDecl();
1270 if (auto *ExternalSymAttr = CD->getAttr<ExternalSourceSymbolAttr>()) {
1271 if (!ExternalSymAttr->getUSR().empty()) {
1272 llvm::raw_svector_ostream Out(Buf);
1273 Out << ExternalSymAttr->getUSR();
1274 return false;
1275 }
1276 }
1277 USRGenerator UG(&D->getASTContext(), Buf, LangOpts);
1278 UG.Visit(D);
1279 return UG.ignoreResults();
1280}
1281
1283 const SourceManager &SM,
1284 SmallVectorImpl<char> &Buf) {
1285 if (!MD)
1286 return true;
1287 return generateUSRForMacro(MD->getName()->getName(), MD->getLocation(), SM,
1288 Buf);
1289}
1290
1292 const SourceManager &SM,
1293 SmallVectorImpl<char> &Buf) {
1294 if (MacroName.empty())
1295 return true;
1296
1297 llvm::raw_svector_ostream Out(Buf);
1298
1299 // Assume that system headers are sane. Don't put source location
1300 // information into the USR if the macro comes from a system header.
1301 bool ShouldGenerateLocation = Loc.isValid() && !SM.isInSystemHeader(Loc);
1302
1303 Out << getUSRSpacePrefix();
1304 if (ShouldGenerateLocation)
1305 printLoc(Out, Loc, SM, /*IncludeOffset=*/true);
1306 Out << "@macro@";
1307 Out << MacroName;
1308 return false;
1309}
1310
1312 SmallVectorImpl<char> &Buf) {
1313 return generateUSRForType(T, Ctx, Buf, Ctx.getLangOpts());
1314}
1315
1318 const LangOptions &LangOpts) {
1319 if (T.isNull())
1320 return true;
1321 T = T.getCanonicalType();
1322
1323 USRGenerator UG(&Ctx, Buf, LangOpts);
1324 UG.VisitType(T);
1325 return UG.ignoreResults();
1326}
1327
1329 raw_ostream &OS) {
1330 if (!Mod->Parent)
1332 if (generateFullUSRForModule(Mod->Parent, OS))
1333 return true;
1334 return generateUSRFragmentForModule(Mod, OS);
1335}
1336
1338 raw_ostream &OS) {
1339 OS << getUSRSpacePrefix();
1340 return generateUSRFragmentForModuleName(ModName, OS);
1341}
1342
1344 raw_ostream &OS) {
1345 return generateUSRFragmentForModuleName(Mod->Name, OS);
1346}
1347
1349 raw_ostream &OS) {
1350 OS << "@M@" << ModName;
1351 return false;
1352}
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:859
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:952
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:2860
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:295
std::string Name
The name of this module.
Definition Module.h:249
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:8431
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Definition TypeBase.h:8471
QualType getCanonicalType() const
Definition TypeBase.h:8483
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:3857
TypedefNameDecl * getTypedefNameForAnonDecl() const
Definition Decl.h:3969
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:3868
TagKind getTagKind() const
Definition Decl.h:3932
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:754
bool isExtVectorType() const
Definition TypeBase.h:8811
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2971
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9261
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.