clang  19.0.0git
ExtractAPIVisitor.h
Go to the documentation of this file.
1 //===- ExtractAPI/ExtractAPIVisitor.h ---------------------------*- C++ -*-===//
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 ///
9 /// \file
10 /// This file defines the ExtractAPVisitor AST visitation interface.
11 ///
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
15 #define LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
16 
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/Decl.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/AST/DeclObjC.h"
21 #include "clang/AST/DeclTemplate.h"
24 #include "clang/Basic/Module.h"
26 #include "clang/Basic/Specifiers.h"
27 #include "clang/ExtractAPI/API.h"
31 #include "llvm/ADT/SmallString.h"
32 #include "llvm/ADT/StringRef.h"
33 #include "llvm/Support/Casting.h"
34 #include <type_traits>
35 
36 namespace clang {
37 namespace extractapi {
38 namespace impl {
39 
40 template <typename Derived>
41 class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
42 protected:
44  : Context(Context), API(API) {}
45 
46 public:
47  const APISet &getAPI() const { return API; }
48 
49  bool VisitVarDecl(const VarDecl *Decl);
50 
52 
53  bool VisitEnumDecl(const EnumDecl *Decl);
54 
56 
58 
60 
62 
65 
68 
70 
73 
76 
78 
80 
82 
84 
86 
88 
90 
92 
94 
96 
98 
101 
104 
106 
107  bool
109 
112 
114 
116 
118 
120 
122 
123  bool shouldDeclBeIncluded(const Decl *Decl) const;
124 
126 
127 protected:
128  /// Collect API information for the enum constants and associate with the
129  /// parent enum.
131  const EnumDecl::enumerator_range Constants);
132 
133  /// Collect API information for the Objective-C methods and associate with the
134  /// parent container.
136  const ObjCContainerDecl::method_range Methods);
137 
139  const ObjCContainerDecl::prop_range Properties);
140 
142  ObjCContainerRecord *Container,
143  const llvm::iterator_range<
145  Ivars);
146 
149 
152 
153  StringRef getTypedefName(const TagDecl *Decl) {
154  if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
155  return TypedefDecl->getName();
156 
157  return {};
158  }
159 
160  bool isInSystemHeader(const Decl *D) {
162  }
163 
164 private:
165  Derived &getDerivedExtractAPIVisitor() {
166  return *static_cast<Derived *>(this);
167  }
168 
169 protected:
171  // FIXME: store AccessSpecifier given by inheritance
173  for (const auto &BaseSpecifier : Decl->bases()) {
174  // skip classes not inherited as public
175  if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public)
176  continue;
177  SymbolReference BaseClass;
178  if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) {
179  BaseClass.Name = API.copyString(BaseSpecifier.getType().getAsString());
180  if (auto *TTPTD = BaseSpecifier.getType()
181  ->getAs<TemplateTypeParmType>()
182  ->getDecl()) {
183  SmallString<128> USR;
184  index::generateUSRForDecl(TTPTD, USR);
185  BaseClass.USR = API.copyString(USR);
186  BaseClass.Source = API.copyString(getOwningModuleName(*TTPTD));
187  }
188  } else {
189  BaseClass = createSymbolReferenceForDecl(
190  *BaseSpecifier.getType().getTypePtr()->getAsCXXRecordDecl());
191  }
192  Bases.emplace_back(BaseClass);
193  }
194  return Bases;
195  }
196 
198  if (Decl->isUnion())
199  return APIRecord::RK_Union;
200  if (Decl->isStruct())
201  return APIRecord::RK_Struct;
202 
203  return APIRecord::RK_CXXClass;
204  }
205 
206  StringRef getOwningModuleName(const Decl &D) {
207  if (auto *OwningModule = D.getImportedOwningModule())
208  return OwningModule->Name;
209 
210  return {};
211  }
212 
214  const auto *Context = cast_if_present<Decl>(D.getDeclContext());
215 
216  if (!Context || isa<TranslationUnitDecl>(Context))
217  return {};
218 
220  }
221 
223  SmallString<128> USR;
224  index::generateUSRForDecl(&D, USR);
225 
227  if (Record)
228  return SymbolReference(Record);
229 
230  StringRef Name;
231  if (auto *ND = dyn_cast<NamedDecl>(&D))
232  Name = ND->getName();
233 
234  return API.createSymbolReference(Name, USR, getOwningModuleName(D));
235  }
236 
238  return D.getName().empty() && getTypedefName(&D).empty() &&
240  }
241 
243  RecordContext *NewRecordContext) {
244  if (!NewRecordContext)
245  return;
246  auto *Tag = D.getType()->getAsTagDecl();
247  SmallString<128> TagUSR;
249  if (auto *Record = llvm::dyn_cast_if_present<TagRecord>(
250  API.findRecordForUSR(TagUSR))) {
251  if (Record->IsEmbeddedInVarDeclarator) {
252  NewRecordContext->stealRecordChain(*Record);
253  auto *NewRecord = cast<APIRecord>(NewRecordContext);
254  if (NewRecord->Comment.empty())
255  NewRecord->Comment = Record->Comment;
256  }
257  }
258  }
259 };
260 
261 template <typename Derived>
263  // skip function parameters.
264  if (isa<ParmVarDecl>(Decl))
265  return true;
266 
267  // Skip non-global variables in records (struct/union/class) but not static
268  // members.
269  if (Decl->getDeclContext()->isRecord() && !Decl->isStaticDataMember())
270  return true;
271 
272  // Skip local variables inside function or method.
274  return true;
275 
276  // If this is a template but not specialization or instantiation, skip.
278  Decl->getTemplateSpecializationKind() == TSK_Undeclared)
279  return true;
280 
281  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
282  return true;
283 
284  // Collect symbol information.
285  StringRef Name = Decl->getName();
286  SmallString<128> USR;
288  PresumedLoc Loc =
289  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
290  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
291  DocComment Comment;
292  if (auto *RawComment =
293  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
294  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
295  Context.getDiagnostics());
296 
297  // Build declaration fragments and sub-heading for the variable.
298  DeclarationFragments Declaration =
300  DeclarationFragments SubHeading =
302  if (Decl->isStaticDataMember()) {
304  API.createRecord<StaticFieldRecord>(
305  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
306  AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration,
307  SubHeading, Access, isInSystemHeader(Decl));
308  } else {
309  // Add the global variable record to the API set.
310  auto *NewRecord = API.createRecord<GlobalVariableRecord>(
311  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
312  AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration,
313  SubHeading, isInSystemHeader(Decl));
314 
315  // If this global variable has a non typedef'd anonymous tag type let's
316  // pretend the type's child records are under us in the hierarchy.
317  maybeMergeWithAnonymousTag(*Decl, NewRecord);
318  }
319 
320  return true;
321 }
322 
323 template <typename Derived>
325  const FunctionDecl *Decl) {
326  if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
327  // Skip member function in class templates.
328  if (Method->getParent()->getDescribedClassTemplate() != nullptr)
329  return true;
330 
331  // Skip methods in records.
332  for (const auto &P : Context.getParents(*Method)) {
333  if (P.template get<CXXRecordDecl>())
334  return true;
335  }
336 
337  // Skip ConstructorDecl and DestructorDecl.
338  if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
339  return true;
340  }
341 
342  // Skip templated functions that aren't processed here.
343  switch (Decl->getTemplatedKind()) {
347  break;
351  return true;
352  }
353 
354  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
355  return true;
356 
357  // Collect symbol information.
358  StringRef Name = Decl->getName();
359  SmallString<128> USR;
361  PresumedLoc Loc =
362  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
363  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
364  DocComment Comment;
365  if (auto *RawComment =
366  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
367  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
368  Context.getDiagnostics());
369 
370  // Build declaration fragments, sub-heading, and signature of the function.
371  DeclarationFragments SubHeading =
373  FunctionSignature Signature =
375  if (Decl->getTemplateSpecializationInfo())
377  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
381  SubHeading, Signature, isInSystemHeader(Decl));
382  else
383  // Add the function record to the API set.
384  API.createRecord<GlobalFunctionRecord>(
385  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
388  Signature, isInSystemHeader(Decl));
389  return true;
390 }
391 
392 template <typename Derived>
394  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
395  return true;
396 
397  SmallString<128> QualifiedNameBuffer;
398  // Collect symbol information.
399  StringRef Name = Decl->getName();
400  if (Name.empty())
401  Name = getTypedefName(Decl);
402  if (Name.empty()) {
403  llvm::raw_svector_ostream OS(QualifiedNameBuffer);
404  Decl->printQualifiedName(OS);
405  Name = QualifiedNameBuffer;
406  }
407 
408  SmallString<128> USR;
410  PresumedLoc Loc =
411  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
412  DocComment Comment;
413  if (auto *RawComment =
414  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
415  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
416  Context.getDiagnostics());
417 
418  // Build declaration fragments and sub-heading for the enum.
419  DeclarationFragments Declaration =
421  DeclarationFragments SubHeading =
423  auto *ER = API.createRecord<EnumRecord>(
424  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
425  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
426  isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
427 
428  // Now collect information about the enumerators in this enum.
429  getDerivedExtractAPIVisitor().recordEnumConstants(ER, Decl->enumerators());
430 
431  return true;
432 }
433 
434 template <typename Derived>
436  const FunctionDecl *Decl) {
437  getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl);
438  return true;
439 }
440 
441 template <typename Derived>
443  const RecordDecl *Decl) {
444  getDerivedExtractAPIVisitor().VisitRecordDecl(Decl);
445  return true;
446 }
447 
448 template <typename Derived>
450  const CXXRecordDecl *Decl) {
451  getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl);
452  return true;
453 }
454 
455 template <typename Derived>
457  const CXXMethodDecl *Decl) {
458  getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl);
459  return true;
460 }
461 
462 template <typename Derived>
465  getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl);
466  return true;
467 }
468 
469 template <typename Derived>
473  getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl(
474  Decl);
475  return true;
476 }
477 
478 template <typename Derived>
480  const VarTemplateDecl *Decl) {
481  getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl);
482  return true;
483 }
484 
485 template <typename Derived>
488  getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl);
489  return true;
490 }
491 
492 template <typename Derived>
496  getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl);
497  return true;
498 }
499 
500 template <typename Derived>
502  const FunctionTemplateDecl *Decl) {
503  getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl);
504  return true;
505 }
506 
507 template <typename Derived>
509  const NamespaceDecl *Decl) {
510  getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl);
511  return true;
512 }
513 
514 template <typename Derived>
516  const NamespaceDecl *Decl) {
517  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
518  return true;
519  if (Decl->isAnonymousNamespace())
520  return true;
521  StringRef Name = Decl->getName();
522  SmallString<128> USR;
524  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
525  PresumedLoc Loc =
526  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
527  DocComment Comment;
528  if (auto *RawComment =
529  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
530  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
531  Context.getDiagnostics());
532 
533  // Build declaration fragments and sub-heading for the struct.
534  DeclarationFragments Declaration =
536  DeclarationFragments SubHeading =
538  API.createRecord<NamespaceRecord>(
539  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
540  AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration,
541  SubHeading, isInSystemHeader(Decl));
542 
543  return true;
544 }
545 
546 template <typename Derived>
548  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
549  return true;
550 
551  // Collect symbol information.
552  StringRef Name = Decl->getName();
553  if (Name.empty())
554  Name = getTypedefName(Decl);
555 
556  SmallString<128> USR;
558  PresumedLoc Loc =
559  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
560  DocComment Comment;
561  if (auto *RawComment =
562  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
563  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
564  Context.getDiagnostics());
565 
566  // Build declaration fragments and sub-heading for the struct.
567  DeclarationFragments Declaration =
569  DeclarationFragments SubHeading =
571 
572  if (Decl->isUnion())
573  API.createRecord<UnionRecord>(
574  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
575  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
576  SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
577  else
578  API.createRecord<StructRecord>(
579  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
580  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
581  SubHeading, isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
582 
583  return true;
584 }
585 
586 template <typename Derived>
588  const CXXRecordDecl *Decl) {
589  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
590  Decl->isImplicit())
591  return true;
592 
593  StringRef Name = Decl->getName();
594  if (Name.empty())
595  Name = getTypedefName(Decl);
596 
597  SmallString<128> USR;
599  PresumedLoc Loc =
600  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
601  DocComment Comment;
602  if (auto *RawComment =
603  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
604  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
605  Context.getDiagnostics());
606  DeclarationFragments Declaration =
608  DeclarationFragments SubHeading =
610 
612 
614  if (Decl->getDescribedClassTemplate()) {
615  // Inject template fragments before class fragments.
616  Declaration.prepend(
618  Decl->getDescribedClassTemplate()));
619  Record = API.createRecord<ClassTemplateRecord>(
620  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
621  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
622  SubHeading, Template(Decl->getDescribedClassTemplate()), Access,
623  isInSystemHeader(Decl));
624  } else {
625  Record = API.createRecord<CXXClassRecord>(
626  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
627  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
628  SubHeading, APIRecord::RecordKind::RK_CXXClass, Access,
629  isInSystemHeader(Decl), isEmbeddedInVarDeclarator(*Decl));
630  }
631 
632  Record->KindForDisplay = getKindForDisplay(Decl);
633  Record->Bases = getBases(Decl);
634 
635  return true;
636 }
637 
638 template <typename Derived>
640  const CXXMethodDecl *Decl) {
641  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
642  Decl->isImplicit())
643  return true;
644 
645  if (isa<CXXConversionDecl>(Decl))
646  return true;
647  if (isa<CXXConstructorDecl>(Decl) || isa<CXXDestructorDecl>(Decl))
648  return true;
649 
650  SmallString<128> USR;
652  PresumedLoc Loc =
653  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
654  DocComment Comment;
655  if (auto *RawComment =
656  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
657  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
658  Context.getDiagnostics());
659  DeclarationFragments SubHeading =
663 
665  Decl->getDescribedFunctionTemplate()) {
666  API.createRecord<CXXMethodTemplateRecord>(
667  USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
670  TemplateDecl),
673  Template(TemplateDecl), isInSystemHeader(Decl));
674  } else if (Decl->getTemplateSpecializationInfo())
675  API.createRecord<CXXMethodTemplateSpecializationRecord>(
676  USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
680  SubHeading, Signature, Access, isInSystemHeader(Decl));
681  else if (Decl->isOverloadedOperator())
682  API.createRecord<CXXInstanceMethodRecord>(
683  USR, Decl->getNameAsString(), createHierarchyInformationForDecl(*Decl),
686  SubHeading, Signature, Access, isInSystemHeader(Decl));
687  else if (Decl->isStatic())
688  API.createRecord<CXXStaticMethodRecord>(
689  USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
692  Signature, Access, isInSystemHeader(Decl));
693  else
694  API.createRecord<CXXInstanceMethodRecord>(
695  USR, Decl->getName(), createHierarchyInformationForDecl(*Decl), Loc,
698  Signature, Access, isInSystemHeader(Decl));
699 
700  return true;
701 }
702 
703 template <typename Derived>
705  const CXXConstructorDecl *Decl) {
706  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
707  Decl->isImplicit())
708  return true;
709 
710  auto Name = Decl->getNameAsString();
711  SmallString<128> USR;
713  PresumedLoc Loc =
714  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
715  DocComment Comment;
716  if (auto *RawComment =
717  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
718  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
719  Context.getDiagnostics());
720 
721  // Build declaration fragments, sub-heading, and signature for the method.
722  DeclarationFragments Declaration =
724  DeclarationFragments SubHeading =
726  FunctionSignature Signature =
729 
730  API.createRecord<CXXConstructorRecord>(
731  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
732  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
733  Signature, Access, isInSystemHeader(Decl));
734  return true;
735 }
736 
737 template <typename Derived>
739  const CXXDestructorDecl *Decl) {
740  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
741  Decl->isImplicit())
742  return true;
743 
744  auto Name = Decl->getNameAsString();
745  SmallString<128> USR;
747  PresumedLoc Loc =
748  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
749  DocComment Comment;
750  if (auto *RawComment =
751  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
752  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
753  Context.getDiagnostics());
754 
755  // Build declaration fragments, sub-heading, and signature for the method.
756  DeclarationFragments Declaration =
758  DeclarationFragments SubHeading =
760  FunctionSignature Signature =
763  API.createRecord<CXXDestructorRecord>(
764  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
765  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
766  Signature, Access, isInSystemHeader(Decl));
767  return true;
768 }
769 
770 template <typename Derived>
772  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
773  return true;
774 
775  StringRef Name = Decl->getName();
776  SmallString<128> USR;
778  PresumedLoc Loc =
779  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
780  DocComment Comment;
781  if (auto *RawComment =
782  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
783  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
784  Context.getDiagnostics());
785  DeclarationFragments Declaration =
787  DeclarationFragments SubHeading =
789  API.createRecord<ConceptRecord>(
790  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
791  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
792  Template(Decl), isInSystemHeader(Decl));
793  return true;
794 }
795 
796 template <typename Derived>
799  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
800  return true;
801 
802  StringRef Name = Decl->getName();
803  SmallString<128> USR;
805  PresumedLoc Loc =
806  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
807  DocComment Comment;
808  if (auto *RawComment =
809  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
810  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
811  Context.getDiagnostics());
812  DeclarationFragments Declaration =
814  Decl);
815  DeclarationFragments SubHeading =
817 
818  auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>(
819  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
820  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
822  isInSystemHeader(Decl));
823 
824  CTSR->Bases = getBases(Decl);
825 
826  return true;
827 }
828 
829 template <typename Derived>
833  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
834  return true;
835 
836  StringRef Name = Decl->getName();
837  SmallString<128> USR;
839  PresumedLoc Loc =
840  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
841  DocComment Comment;
842  if (auto *RawComment =
843  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
844  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
845  Context.getDiagnostics());
848  DeclarationFragments SubHeading =
850  auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>(
851  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
852  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
854  isInSystemHeader(Decl));
855 
856  CTPSR->KindForDisplay = getKindForDisplay(Decl);
857  CTPSR->Bases = getBases(Decl);
858 
859  return true;
860 }
861 
862 template <typename Derived>
864  const VarTemplateDecl *Decl) {
865  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
866  return true;
867 
868  // Collect symbol information.
869  StringRef Name = Decl->getName();
870  SmallString<128> USR;
872  PresumedLoc Loc =
873  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
874  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
875  DocComment Comment;
876  if (auto *RawComment =
877  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
878  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
879  Context.getDiagnostics());
880 
881  // Build declaration fragments and sub-heading for the variable.
882  DeclarationFragments Declaration;
883  Declaration
885  Decl))
887  Decl->getTemplatedDecl()));
888  // Inject template fragments before var fragments.
889  DeclarationFragments SubHeading =
891 
892  if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord)
893  API.createRecord<CXXFieldTemplateRecord>(
894  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
895  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
897  Template(Decl), isInSystemHeader(Decl));
898  else
899  API.createRecord<GlobalVariableTemplateRecord>(
900  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
901  AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration,
902  SubHeading, Template(Decl), isInSystemHeader(Decl));
903  return true;
904 }
905 
906 template <typename Derived>
909  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
910  return true;
911 
912  // Collect symbol information.
913  StringRef Name = Decl->getName();
914  SmallString<128> USR;
916  PresumedLoc Loc =
917  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
918  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
919  DocComment Comment;
920  if (auto *RawComment =
921  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
922  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
923  Context.getDiagnostics());
924 
925  // Build declaration fragments and sub-heading for the variable.
926  DeclarationFragments Declaration =
928  Decl);
929  DeclarationFragments SubHeading =
932  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
933  AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration,
934  SubHeading, isInSystemHeader(Decl));
935  return true;
936 }
937 
938 template <typename Derived>
941  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
942  return true;
943 
944  // Collect symbol information.
945  StringRef Name = Decl->getName();
946  SmallString<128> USR;
948  PresumedLoc Loc =
949  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
950  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
951  DocComment Comment;
952  if (auto *RawComment =
953  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
954  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
955  Context.getDiagnostics());
956 
957  // Build declaration fragments and sub-heading for the variable.
960  DeclarationFragments SubHeading =
963  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
964  AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration,
965  SubHeading, Template(Decl), isInSystemHeader(Decl));
966  return true;
967 }
968 
969 template <typename Derived>
971  const FunctionTemplateDecl *Decl) {
972  if (isa<CXXMethodDecl>(Decl->getTemplatedDecl()))
973  return true;
974  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
975  return true;
976 
977  // Collect symbol information.
978  StringRef Name = Decl->getName();
979  SmallString<128> USR;
981  PresumedLoc Loc =
982  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
983  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
984  DocComment Comment;
985  if (auto *RawComment =
986  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
987  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
988  Context.getDiagnostics());
989 
990  DeclarationFragments SubHeading =
992  FunctionSignature Signature =
994  Decl->getTemplatedDecl());
995  API.createRecord<GlobalFunctionTemplateRecord>(
996  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
999  SubHeading, Signature, Template(Decl), isInSystemHeader(Decl));
1000 
1001  return true;
1002 }
1003 
1004 template <typename Derived>
1006  const ObjCInterfaceDecl *Decl) {
1007  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1008  return true;
1009 
1010  // Collect symbol information.
1011  StringRef Name = Decl->getName();
1012  SmallString<128> USR;
1014  PresumedLoc Loc =
1015  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1016  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
1017  DocComment Comment;
1018  if (auto *RawComment =
1019  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1020  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1021  Context.getDiagnostics());
1022 
1023  // Build declaration fragments and sub-heading for the interface.
1024  DeclarationFragments Declaration =
1026  DeclarationFragments SubHeading =
1028 
1029  // Collect super class information.
1030  SymbolReference SuperClass;
1031  if (const auto *SuperClassDecl = Decl->getSuperClass())
1032  SuperClass = createSymbolReferenceForDecl(*SuperClassDecl);
1033 
1034  auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>(
1035  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1036  AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration,
1037  SubHeading, SuperClass, isInSystemHeader(Decl));
1038 
1039  // Record all methods (selectors). This doesn't include automatically
1040  // synthesized property methods.
1041  getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord,
1042  Decl->methods());
1043  getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord,
1044  Decl->properties());
1045  getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord,
1046  Decl->ivars());
1047  getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord,
1048  Decl->protocols());
1049 
1050  return true;
1051 }
1052 
1053 template <typename Derived>
1055  const ObjCProtocolDecl *Decl) {
1056  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1057  return true;
1058 
1059  // Collect symbol information.
1060  StringRef Name = Decl->getName();
1061  SmallString<128> USR;
1063  PresumedLoc Loc =
1064  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1065  DocComment Comment;
1066  if (auto *RawComment =
1067  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1068  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1069  Context.getDiagnostics());
1070 
1071  // Build declaration fragments and sub-heading for the protocol.
1072  DeclarationFragments Declaration =
1074  DeclarationFragments SubHeading =
1076 
1077  auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>(
1078  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1079  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1080  isInSystemHeader(Decl));
1081 
1082  getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods());
1083  getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord,
1084  Decl->properties());
1085  getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord,
1086  Decl->protocols());
1087 
1088  return true;
1089 }
1090 
1091 template <typename Derived>
1093  const TypedefNameDecl *Decl) {
1094  // Skip ObjC Type Parameter for now.
1095  if (isa<ObjCTypeParamDecl>(Decl))
1096  return true;
1097 
1099  return true;
1100 
1101  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1102  return true;
1103 
1104  StringRef Name = Decl->getName();
1105 
1106  // If the underlying type was defined as part of the typedef modify it's
1107  // fragments directly and pretend the typedef doesn't exist.
1108  if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) {
1110  Decl->getName() == TagDecl->getName()) {
1111  SmallString<128> TagUSR;
1113  if (auto *Record = API.findRecordForUSR(TagUSR)) {
1114  DeclarationFragments LeadingFragments;
1115  LeadingFragments.append("typedef",
1117  LeadingFragments.appendSpace();
1118  Record->Declaration.removeTrailingSemicolon()
1119  .prepend(std::move(LeadingFragments))
1122  .appendSemicolon();
1123 
1124  return true;
1125  }
1126  }
1127  }
1128 
1129  PresumedLoc Loc =
1130  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1131  SmallString<128> USR;
1133  DocComment Comment;
1134  if (auto *RawComment =
1135  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1136  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1137  Context.getDiagnostics());
1138 
1139  QualType Type = Decl->getUnderlyingType();
1140  SymbolReference SymRef =
1142  API);
1143 
1144  API.createRecord<TypedefRecord>(
1145  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1149  isInSystemHeader(Decl));
1150 
1151  return true;
1152 }
1153 
1154 template <typename Derived>
1156  const ObjCCategoryDecl *Decl) {
1157  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1158  return true;
1159 
1160  StringRef Name = Decl->getName();
1161  SmallString<128> USR;
1163  PresumedLoc Loc =
1164  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1165  DocComment Comment;
1166  if (auto *RawComment =
1167  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1168  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1169  Context.getDiagnostics());
1170  // Build declaration fragments and sub-heading for the category.
1171  DeclarationFragments Declaration =
1173  DeclarationFragments SubHeading =
1175 
1176  const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
1177  SymbolReference Interface = createSymbolReferenceForDecl(*InterfaceDecl);
1178 
1179  auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>(
1180  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1181  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading,
1182  Interface, isInSystemHeader(Decl));
1183 
1184  getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord,
1185  Decl->methods());
1186  getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord,
1187  Decl->properties());
1188  getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord,
1189  Decl->ivars());
1190  getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord,
1191  Decl->protocols());
1192 
1193  return true;
1194 }
1195 
1196 /// Collect API information for the enum constants and associate with the
1197 /// parent enum.
1198 template <typename Derived>
1200  EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) {
1201  for (const auto *Constant : Constants) {
1202  // Collect symbol information.
1203  StringRef Name = Constant->getName();
1204  SmallString<128> USR;
1205  index::generateUSRForDecl(Constant, USR);
1206  PresumedLoc Loc =
1207  Context.getSourceManager().getPresumedLoc(Constant->getLocation());
1208  DocComment Comment;
1209  if (auto *RawComment =
1210  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
1211  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1212  Context.getDiagnostics());
1213 
1214  // Build declaration fragments and sub-heading for the enum constant.
1215  DeclarationFragments Declaration =
1217  DeclarationFragments SubHeading =
1219 
1220  API.createRecord<EnumConstantRecord>(
1221  USR, Name, createHierarchyInformationForDecl(*Constant), Loc,
1222  AvailabilityInfo::createFromDecl(Constant), Comment, Declaration,
1223  SubHeading, isInSystemHeader(Constant));
1224  }
1225 }
1226 
1227 template <typename Derived>
1229  // ObjCIvars are handled separately
1230  if (isa<ObjCIvarDecl>(Decl) || isa<ObjCAtDefsFieldDecl>(Decl))
1231  return true;
1232 
1233  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
1234  return true;
1235 
1236  // Collect symbol information.
1237  StringRef Name = Decl->getName();
1238  SmallString<128> USR;
1240  PresumedLoc Loc =
1241  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1242  DocComment Comment;
1243  if (auto *RawComment =
1244  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1245  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1246  Context.getDiagnostics());
1247 
1248  // Build declaration fragments and sub-heading for the struct field.
1249  DeclarationFragments Declaration =
1251  DeclarationFragments SubHeading =
1253 
1254  RecordContext *NewRecord = nullptr;
1255  if (isa<CXXRecordDecl>(Decl->getDeclContext())) {
1257 
1258  NewRecord = API.createRecord<CXXFieldRecord>(
1259  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1260  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
1261  SubHeading, Access, isInSystemHeader(Decl));
1262  } else if (auto *RD = dyn_cast<RecordDecl>(Decl->getDeclContext())) {
1263  if (RD->isUnion())
1264  NewRecord = API.createRecord<UnionFieldRecord>(
1265  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1266  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
1267  SubHeading, isInSystemHeader(Decl));
1268  else
1269  NewRecord = API.createRecord<StructFieldRecord>(
1270  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1271  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
1272  SubHeading, isInSystemHeader(Decl));
1273  }
1274 
1275  // If this field has a non typedef'd anonymous tag type let's pretend the
1276  // type's child records are under us in the hierarchy.
1277  maybeMergeWithAnonymousTag(*Decl, NewRecord);
1278 
1279  return true;
1280 }
1281 
1282 template <typename Derived>
1284  const CXXConversionDecl *Decl) {
1285  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) ||
1286  Decl->isImplicit())
1287  return true;
1288 
1289  auto Name = Decl->getNameAsString();
1290  SmallString<128> USR;
1292  PresumedLoc Loc =
1293  Context.getSourceManager().getPresumedLoc(Decl->getLocation());
1294  DocComment Comment;
1295  if (auto *RawComment =
1296  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
1297  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1298  Context.getDiagnostics());
1299 
1300  // Build declaration fragments, sub-heading, and signature for the method.
1301  DeclarationFragments Declaration =
1303  DeclarationFragments SubHeading =
1305  FunctionSignature Signature =
1308 
1309  if (Decl->isStatic())
1310  API.createRecord<CXXStaticMethodRecord>(
1311  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1312  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
1313  SubHeading, Signature, Access, isInSystemHeader(Decl));
1314  else
1315  API.createRecord<CXXInstanceMethodRecord>(
1316  USR, Name, createHierarchyInformationForDecl(*Decl), Loc,
1317  AvailabilityInfo::createFromDecl(Decl), Comment, Declaration,
1318  SubHeading, Signature, Access, isInSystemHeader(Decl));
1319 
1320  return true;
1321 }
1322 
1323 /// Collect API information for the Objective-C methods and associate with the
1324 /// parent container.
1325 template <typename Derived>
1327  ObjCContainerRecord *Container,
1328  const ObjCContainerDecl::method_range Methods) {
1329  for (const auto *Method : Methods) {
1330  // Don't record selectors for properties.
1331  if (Method->isPropertyAccessor())
1332  continue;
1333 
1334  auto Name = Method->getSelector().getAsString();
1335  SmallString<128> USR;
1336  index::generateUSRForDecl(Method, USR);
1337  PresumedLoc Loc =
1338  Context.getSourceManager().getPresumedLoc(Method->getLocation());
1339  DocComment Comment;
1340  if (auto *RawComment =
1341  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
1342  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1343  Context.getDiagnostics());
1344 
1345  // Build declaration fragments, sub-heading, and signature for the method.
1346  DeclarationFragments Declaration =
1348  DeclarationFragments SubHeading =
1350  FunctionSignature Signature =
1352 
1353  if (Method->isInstanceMethod())
1354  API.createRecord<ObjCInstanceMethodRecord>(
1355  USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1356  AvailabilityInfo::createFromDecl(Method), Comment, Declaration,
1357  SubHeading, Signature, isInSystemHeader(Method));
1358  else
1359  API.createRecord<ObjCClassMethodRecord>(
1360  USR, Name, createHierarchyInformationForDecl(*Method), Loc,
1361  AvailabilityInfo::createFromDecl(Method), Comment, Declaration,
1362  SubHeading, Signature, isInSystemHeader(Method));
1363  }
1364 }
1365 
1366 template <typename Derived>
1368  ObjCContainerRecord *Container,
1369  const ObjCContainerDecl::prop_range Properties) {
1370  for (const auto *Property : Properties) {
1371  StringRef Name = Property->getName();
1372  SmallString<128> USR;
1374  PresumedLoc Loc =
1375  Context.getSourceManager().getPresumedLoc(Property->getLocation());
1376  DocComment Comment;
1377  if (auto *RawComment =
1378  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
1379  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1380  Context.getDiagnostics());
1381 
1382  // Build declaration fragments and sub-heading for the property.
1383  DeclarationFragments Declaration =
1385  DeclarationFragments SubHeading =
1387 
1388  auto GetterName = Property->getGetterName().getAsString();
1389  auto SetterName = Property->getSetterName().getAsString();
1390 
1391  // Get the attributes for property.
1392  unsigned Attributes = ObjCPropertyRecord::NoAttr;
1393  if (Property->getPropertyAttributes() &
1395  Attributes |= ObjCPropertyRecord::ReadOnly;
1396 
1397  if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class)
1398  API.createRecord<ObjCClassPropertyRecord>(
1399  USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1400  AvailabilityInfo::createFromDecl(Property), Comment, Declaration,
1401  SubHeading,
1402  static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1403  GetterName, SetterName, Property->isOptional(),
1404  isInSystemHeader(Property));
1405  else
1406  API.createRecord<ObjCInstancePropertyRecord>(
1407  USR, Name, createHierarchyInformationForDecl(*Property), Loc,
1408  AvailabilityInfo::createFromDecl(Property), Comment, Declaration,
1409  SubHeading,
1410  static_cast<ObjCPropertyRecord::AttributeKind>(Attributes),
1411  GetterName, SetterName, Property->isOptional(),
1412  isInSystemHeader(Property));
1413  }
1414 }
1415 
1416 template <typename Derived>
1418  ObjCContainerRecord *Container,
1419  const llvm::iterator_range<
1421  Ivars) {
1422  for (const auto *Ivar : Ivars) {
1423  StringRef Name = Ivar->getName();
1424  SmallString<128> USR;
1425  index::generateUSRForDecl(Ivar, USR);
1426 
1427  PresumedLoc Loc =
1428  Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
1429  DocComment Comment;
1430  if (auto *RawComment =
1431  getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
1432  Comment = RawComment->getFormattedLines(Context.getSourceManager(),
1433  Context.getDiagnostics());
1434 
1435  // Build declaration fragments and sub-heading for the instance variable.
1436  DeclarationFragments Declaration =
1438  DeclarationFragments SubHeading =
1440 
1441  API.createRecord<ObjCInstanceVariableRecord>(
1442  USR, Name, createHierarchyInformationForDecl(*Ivar), Loc,
1443  AvailabilityInfo::createFromDecl(Ivar), Comment, Declaration,
1444  SubHeading, isInSystemHeader(Ivar));
1445  }
1446 }
1447 
1448 template <typename Derived>
1450  ObjCContainerRecord *Container,
1452  for (const auto *Protocol : Protocols)
1453  Container->Protocols.emplace_back(createSymbolReferenceForDecl(*Protocol));
1454 }
1455 
1456 } // namespace impl
1457 
1458 /// The RecursiveASTVisitor to traverse symbol declarations and collect API
1459 /// information.
1460 template <typename Derived = void>
1462  : public impl::ExtractAPIVisitorBase<std::conditional_t<
1463  std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
1464  using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
1465  std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
1466 
1467 public:
1469 
1470  bool shouldDeclBeIncluded(const Decl *D) const { return true; }
1471  const RawComment *fetchRawCommentForDecl(const Decl *D) const {
1472  return this->Context.getRawCommentForDeclNoCache(D);
1473  }
1474 };
1475 
1476 } // namespace extractapi
1477 } // namespace clang
1478 
1479 #endif // LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H
This file defines the APIRecord-based structs and the APISet class.
Defines the clang::ASTContext interface.
StringRef P
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
This file defines the Declaration Fragments related classes.
llvm::MachO::Record Record
Definition: MachO.h:31
Defines the clang::Module class, which describes a module in the source code.
SourceLocation Loc
Definition: SemaObjC.cpp:755
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
This file defines the UnderlyingTypeResolver which is a helper type for resolving the undelrying type...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:185
SourceManager & getSourceManager()
Definition: ASTContext.h:708
TemplateOrSpecializationInfo getTemplateOrSpecializationInfo(const VarDecl *Var)
RawComment * getRawCommentForDeclNoCache(const Decl *D) const
Return the documentation comment attached to a given declaration, without looking into cache.
Definition: ASTContext.cpp:293
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2535
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2862
Represents a C++ destructor within a class.
Definition: DeclCXX.h:2799
Represents a static or instance method of a struct/union/class.
Definition: DeclCXX.h:2060
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Represents a class template specialization, which refers to a class template with a given set of temp...
Declaration of a C++20 concept.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
Definition: DeclBase.h:2342
bool isRecord() const
Definition: DeclBase.h:2146
Decl::Kind getDeclKind() const
Definition: DeclBase.h:2059
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:501
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:599
SourceLocation getLocation() const
Definition: DeclBase.h:445
bool isDefinedOutsideFunctionOrMethod() const
isDefinedOutsideFunctionOrMethod - This predicate returns true if this scoped decl is defined outside...
Definition: DeclBase.h:939
Module * getImportedOwningModule() const
Get the imported owning module, if this decl is from an imported (non-local) module.
Definition: DeclBase.h:803
DeclContext * getDeclContext()
Definition: DeclBase.h:454
Represents a ValueDecl that came out of a declarator.
Definition: Decl.h:771
Represents an enum.
Definition: Decl.h:3870
llvm::iterator_range< specific_decl_iterator< EnumConstantDecl > > enumerator_range
Definition: Decl.h:4001
Represents a member of a struct/union/class.
Definition: Decl.h:3060
Represents a function declaration or definition.
Definition: Decl.h:1972
@ TK_MemberSpecialization
Definition: Decl.h:1984
@ TK_DependentNonTemplate
Definition: Decl.h:1993
@ TK_FunctionTemplateSpecialization
Definition: Decl.h:1988
@ TK_DependentFunctionTemplateSpecialization
Definition: Decl.h:1991
Declaration of a template function.
Definition: DeclTemplate.h:957
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
Represent a C++ namespace.
Definition: Decl.h:548
ObjCCategoryDecl - Represents a category declaration.
Definition: DeclObjC.h:2326
llvm::iterator_range< specific_decl_iterator< ObjCMethodDecl > > method_range
Definition: DeclObjC.h:1013
llvm::iterator_range< specific_decl_iterator< ObjCPropertyDecl > > prop_range
Definition: DeclObjC.h:964
Represents an ObjC class declaration.
Definition: DeclObjC.h:1153
llvm::iterator_range< protocol_iterator > protocol_range
Definition: DeclObjC.h:1356
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
Represents an unpacked "presumed" location which can be presented to the user.
A (possibly-)qualified type.
Definition: Type.h:940
std::vector< CommentLine > getFormattedLines(const SourceManager &SourceMgr, DiagnosticsEngine &Diags) const
Returns sanitized comment text as separated lines with locations in source, suitable for further proc...
Represents a struct/union/class.
Definition: Decl.h:4171
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3587
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:3714
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3690
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
TemplateTypeParmDecl * getDecl() const
Definition: Type.h:5794
The base class of the type hierarchy.
Definition: Type.h:1813
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
Definition: Type.cpp:1889
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3537
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3435
QualType getType() const
Definition: Decl.h:718
Represents a variable declaration or definition.
Definition: Decl.h:919
Declaration of a variable template.
Represents a variable template specialization, which refers to a variable template with a given set o...
APISet holds the set of API records collected from given inputs.
Definition: API.h:1400
SymbolReference createSymbolReference(StringRef Name, StringRef USR, StringRef Source="")
Definition: API.cpp:113
StringRef copyString(StringRef String)
Copy String into the Allocator in this APISet.
Definition: API.cpp:100
APIRecord * findRecordForUSR(StringRef USR) const
Finds the APIRecord for a given USR.
Definition: API.cpp:89
static DeclarationFragments getFragmentsForRedeclarableTemplate(const RedeclarableTemplateDecl *)
static DeclarationFragments getFragmentsForCXXClass(const CXXRecordDecl *)
static DeclarationFragments getFragmentsForEnumConstant(const EnumConstantDecl *)
Build DeclarationFragments for an enum constant declaration EnumConstantDecl.
static DeclarationFragments getFragmentsForObjCCategory(const ObjCCategoryDecl *)
Build DeclarationFragments for an Objective-C category declaration ObjCCategoryDecl.
static DeclarationFragments getFragmentsForTypedef(const TypedefNameDecl *Decl)
Build DeclarationFragments for a typedef TypedefNameDecl.
static DeclarationFragments getFragmentsForEnum(const EnumDecl *)
Build DeclarationFragments for an enum declaration EnumDecl.
static DeclarationFragments getFragmentsForConversionFunction(const CXXConversionDecl *)
static DeclarationFragments getFragmentsForClassTemplateSpecialization(const ClassTemplateSpecializationDecl *)
static DeclarationFragments getFragmentsForObjCProtocol(const ObjCProtocolDecl *)
Build DeclarationFragments for an Objective-C protocol declaration ObjCProtocolDecl.
static DeclarationFragments getFragmentsForConcept(const ConceptDecl *)
static DeclarationFragments getFragmentsForField(const FieldDecl *)
Build DeclarationFragments for a field declaration FieldDecl.
static DeclarationFragments getFragmentsForVar(const VarDecl *)
Build DeclarationFragments for a variable declaration VarDecl.
static DeclarationFragments getFragmentsForClassTemplatePartialSpecialization(const ClassTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForObjCMethod(const ObjCMethodDecl *)
Build DeclarationFragments for an Objective-C method declaration ObjCMethodDecl.
static DeclarationFragments getFragmentsForFunction(const FunctionDecl *)
Build DeclarationFragments for a function declaration FunctionDecl.
static AccessControl getAccessControl(const Decl *Decl)
static DeclarationFragments getFragmentsForObjCProperty(const ObjCPropertyDecl *)
Build DeclarationFragments for an Objective-C property declaration ObjCPropertyDecl.
static DeclarationFragments getFragmentsForSpecialCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForCXXMethod(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForNamespace(const NamespaceDecl *Decl)
static DeclarationFragments getFragmentsForVarTemplatePartialSpecialization(const VarTemplatePartialSpecializationDecl *)
static DeclarationFragments getFragmentsForFunctionTemplate(const FunctionTemplateDecl *Decl)
static DeclarationFragments getFragmentsForVarTemplateSpecialization(const VarTemplateSpecializationDecl *)
static FunctionSignature getFunctionSignature(const FunctionT *Function)
Build FunctionSignature for a function-like declaration FunctionT like FunctionDecl,...
static DeclarationFragments getSubHeading(const NamedDecl *)
Build sub-heading fragments for a NamedDecl.
static DeclarationFragments getFragmentsForVarTemplate(const VarDecl *)
static DeclarationFragments getFragmentsForOverloadedOperator(const CXXMethodDecl *)
static DeclarationFragments getFragmentsForFunctionTemplateSpecialization(const FunctionDecl *Decl)
static DeclarationFragments getFragmentsForRecordDecl(const RecordDecl *)
Build DeclarationFragments for a struct/union record declaration RecordDecl.
static DeclarationFragments getFragmentsForObjCInterface(const ObjCInterfaceDecl *)
Build DeclarationFragments for an Objective-C interface declaration ObjCInterfaceDecl.
DeclarationFragments is a vector of tagged important parts of a symbol's declaration.
DeclarationFragments & prepend(DeclarationFragments Other)
Prepend another DeclarationFragments to the beginning.
DeclarationFragments & appendSpace()
Append a text Fragment of a space character.
DeclarationFragments & append(DeclarationFragments Other)
Append another DeclarationFragments to the end.
DeclarationFragments & removeTrailingSemicolon()
Removes a trailing semicolon character if present.
DeclarationFragments & appendSemicolon()
Append a text Fragment of a semicolon character.
The RecursiveASTVisitor to traverse symbol declarations and collect API information.
ExtractAPIVisitor(ASTContext &Context, APISet &API)
const RawComment * fetchRawCommentForDecl(const Decl *D) const
bool shouldDeclBeIncluded(const Decl *D) const
Store function signature information with DeclarationFragments of the return type and parameters.
Base class used for specific record types that have children records this is analogous to the DeclCon...
Definition: API.h:313
void stealRecordChain(RecordContext &Other)
Append Other children chain into ours and empty out Other's record chain.
Definition: API.cpp:62
ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl)
bool WalkUpFromClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl *Decl)
bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *Decl)
bool VisitFunctionDecl(const FunctionDecl *Decl)
bool VisitClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *Decl)
void maybeMergeWithAnonymousTag(const DeclaratorDecl &D, RecordContext *NewRecordContext)
bool VisitCXXMethodDecl(const CXXMethodDecl *Decl)
bool VisitVarTemplateDecl(const VarTemplateDecl *Decl)
bool WalkUpFromCXXMethodDecl(const CXXMethodDecl *Decl)
StringRef getTypedefName(const TagDecl *Decl)
bool VisitCXXRecordDecl(const CXXRecordDecl *Decl)
APIRecord::RecordKind getKindForDisplay(const CXXRecordDecl *Decl)
void recordObjCMethods(ObjCContainerRecord *Container, const ObjCContainerDecl::method_range Methods)
Collect API information for the Objective-C methods and associate with the parent container.
void recordObjCProperties(ObjCContainerRecord *Container, const ObjCContainerDecl::prop_range Properties)
bool WalkUpFromNamespaceDecl(const NamespaceDecl *Decl)
void recordObjCInstanceVariables(ObjCContainerRecord *Container, const llvm::iterator_range< DeclContext::specific_decl_iterator< ObjCIvarDecl >> Ivars)
const RawComment * fetchRawCommentForDecl(const Decl *Decl) const
SymbolReference createHierarchyInformationForDecl(const Decl &D)
SmallVector< SymbolReference > getBases(const CXXRecordDecl *Decl)
bool WalkUpFromRecordDecl(const RecordDecl *Decl)
bool VisitCXXDestructorDecl(const CXXDestructorDecl *Decl)
bool VisitClassTemplatePartialSpecializationDecl(const ClassTemplatePartialSpecializationDecl *Decl)
bool WalkUpFromCXXRecordDecl(const CXXRecordDecl *Decl)
bool VisitVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl *Decl)
bool VisitTypedefNameDecl(const TypedefNameDecl *Decl)
void recordEnumConstants(EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants)
Collect API information for the enum constants and associate with the parent enum.
bool VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl)
bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl)
SymbolReference createSymbolReferenceForDecl(const Decl &D)
bool WalkUpFromVarTemplateDecl(const VarTemplateDecl *Decl)
bool shouldDeclBeIncluded(const Decl *Decl) const
bool VisitNamespaceDecl(const NamespaceDecl *Decl)
bool WalkUpFromFunctionTemplateDecl(const FunctionTemplateDecl *Decl)
bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl)
bool WalkUpFromFunctionDecl(const FunctionDecl *Decl)
bool VisitCXXConstructorDecl(const CXXConstructorDecl *Decl)
void recordObjCProtocols(ObjCContainerRecord *Container, ObjCInterfaceDecl::protocol_range Protocols)
bool VisitCXXConversionDecl(const CXXConversionDecl *Decl)
bool VisitConceptDecl(const ConceptDecl *Decl)
bool WalkUpFromVarTemplatePartialSpecializationDecl(const VarTemplatePartialSpecializationDecl *Decl)
bool WalkUpFromVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl)
bool WalkUpFromClassTemplateSpecializationDecl(const ClassTemplateSpecializationDecl *Decl)
std::vector< RawComment::CommentLine > DocComment
DocComment is a vector of RawComment::CommentLine.
Definition: API.h:158
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.
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
Definition: Linkage.h:24
@ Property
The type of a property.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:188
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
@ AS_public
Definition: Specifiers.h:121
static AvailabilityInfo createFromDecl(const Decl *Decl)
The base representation of an API record. Holds common symbol information.
Definition: API.h:192
RecordKind KindForDisplay
Definition: API.h:269
RecordKind
Discriminator for LLVM-style RTTI (dyn_cast<> et al.)
Definition: API.h:194
SmallVector< SymbolReference > Bases
Definition: API.h:1172
This holds information associated with enum constants.
Definition: API.h:588
This holds information associated with enums.
Definition: API.h:633
This holds information associated with global functions.
Definition: API.h:405
This holds information associated with global functions.
Definition: API.h:486
This holds information associated with Objective-C categories.
Definition: API.h:1276
The base representation of an Objective-C container record.
Definition: API.h:1152
This holds information associated with Objective-C instance variables.
Definition: API.h:1052
This holds information associated with Objective-C interfaces/classes.
Definition: API.h:1309
AttributeKind
The attributes associated with an Objective-C property.
Definition: API.h:977
This holds information associated with Objective-C protocols.
Definition: API.h:1333
StringRef Source
The source project/module/product of the referred symbol.
Definition: API.h:169
This holds information associated with typedefs.
Definition: API.h:1377
SymbolReference getSymbolReferenceForType(QualType Type, APISet &API) const
Get a SymbolReference for the given type.