Coverage Report

Created: 2023-05-31 04:38

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/include/clang/ExtractAPI/ExtractAPIVisitor.h
Line
Count
Source (jump to first uncovered line)
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 "llvm/ADT/FunctionExtras.h"
18
19
#include "clang/AST/ASTContext.h"
20
#include "clang/AST/ParentMapContext.h"
21
#include "clang/AST/RecursiveASTVisitor.h"
22
#include "clang/Basic/SourceManager.h"
23
#include "clang/ExtractAPI/API.h"
24
#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
25
#include "llvm/ADT/StringRef.h"
26
#include <type_traits>
27
28
namespace clang {
29
namespace extractapi {
30
namespace impl {
31
32
template <typename Derived>
33
class ExtractAPIVisitorBase : public RecursiveASTVisitor<Derived> {
34
protected:
35
  ExtractAPIVisitorBase(ASTContext &Context, APISet &API)
36
45
      : Context(Context), API(API) {}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::ExtractAPIVisitorBase(clang::ASTContext&, clang::extractapi::APISet&)
Line
Count
Source
36
26
      : Context(Context), API(API) {}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::ExtractAPIVisitorBase(clang::ASTContext&, clang::extractapi::APISet&)
Line
Count
Source
36
19
      : Context(Context), API(API) {}
37
38
public:
39
  const APISet &getAPI() const { return API; }
40
41
  bool VisitVarDecl(const VarDecl *Decl);
42
43
  bool VisitFunctionDecl(const FunctionDecl *Decl);
44
45
  bool VisitEnumDecl(const EnumDecl *Decl);
46
47
  bool VisitRecordDecl(const RecordDecl *Decl);
48
49
  bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl);
50
51
  bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl);
52
53
  bool VisitTypedefNameDecl(const TypedefNameDecl *Decl);
54
55
  bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl);
56
57
  bool shouldDeclBeIncluded(const Decl *Decl) const;
58
59
  const RawComment *fetchRawCommentForDecl(const Decl *Decl) const;
60
61
protected:
62
  /// Collect API information for the enum constants and associate with the
63
  /// parent enum.
64
  void recordEnumConstants(EnumRecord *EnumRecord,
65
                           const EnumDecl::enumerator_range Constants);
66
67
  /// Collect API information for the struct fields and associate with the
68
  /// parent struct.
69
  void recordStructFields(StructRecord *StructRecord,
70
                          const RecordDecl::field_range Fields);
71
72
  /// Collect API information for the Objective-C methods and associate with the
73
  /// parent container.
74
  void recordObjCMethods(ObjCContainerRecord *Container,
75
                         const ObjCContainerDecl::method_range Methods);
76
77
  void recordObjCProperties(ObjCContainerRecord *Container,
78
                            const ObjCContainerDecl::prop_range Properties);
79
80
  void recordObjCInstanceVariables(
81
      ObjCContainerRecord *Container,
82
      const llvm::iterator_range<
83
          DeclContext::specific_decl_iterator<ObjCIvarDecl>>
84
          Ivars);
85
86
  void recordObjCProtocols(ObjCContainerRecord *Container,
87
                           ObjCInterfaceDecl::protocol_range Protocols);
88
89
  ASTContext &Context;
90
  APISet &API;
91
92
7
  StringRef getTypedefName(const TagDecl *Decl) {
93
7
    if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
94
3
      return TypedefDecl->getName();
95
96
4
    return {};
97
7
  }
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::getTypedefName(clang::TagDecl const*)
Line
Count
Source
92
7
  StringRef getTypedefName(const TagDecl *Decl) {
93
7
    if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl())
94
3
      return TypedefDecl->getName();
95
96
4
    return {};
97
7
  }
Unexecuted instantiation: CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::getTypedefName(clang::TagDecl const*)
98
99
225
  bool isInSystemHeader(const Decl *D) {
100
225
    return Context.getSourceManager().isInSystemHeader(D->getLocation());
101
225
  }
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::isInSystemHeader(clang::Decl const*)
Line
Count
Source
99
114
  bool isInSystemHeader(const Decl *D) {
100
114
    return Context.getSourceManager().isInSystemHeader(D->getLocation());
101
114
  }
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::isInSystemHeader(clang::Decl const*)
Line
Count
Source
99
111
  bool isInSystemHeader(const Decl *D) {
100
111
    return Context.getSourceManager().isInSystemHeader(D->getLocation());
101
111
  }
102
103
private:
104
559
  Derived &getDerivedExtractAPIVisitor() {
105
559
    return *static_cast<Derived *>(this);
106
559
  }
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::getDerivedExtractAPIVisitor()
Line
Count
Source
104
253
  Derived &getDerivedExtractAPIVisitor() {
105
253
    return *static_cast<Derived *>(this);
106
253
  }
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::getDerivedExtractAPIVisitor()
Line
Count
Source
104
306
  Derived &getDerivedExtractAPIVisitor() {
105
306
    return *static_cast<Derived *>(this);
106
306
  }
107
};
108
109
template <typename T>
110
2
static void modifyRecords(const T &Records, const StringRef &Name) {
111
2
  for (const auto &Record : Records) {
112
2
    if (Name == Record.second.get()->Name) {
113
2
      auto &DeclFragment = Record.second->Declaration;
114
2
      DeclFragment.insert(DeclFragment.begin(), " ",
115
2
                          DeclarationFragments::FragmentKind::Text);
116
2
      DeclFragment.insert(DeclFragment.begin(), "typedef",
117
2
                          DeclarationFragments::FragmentKind::Keyword, "",
118
2
                          nullptr);
119
2
      DeclFragment.insert(--DeclFragment.end(), " { ... } ",
120
2
                          DeclarationFragments::FragmentKind::Text);
121
2
      DeclFragment.insert(--DeclFragment.end(), Name,
122
2
                          DeclarationFragments::FragmentKind::Identifier);
123
2
      break;
124
2
    }
125
2
  }
126
2
}
ExtractAPIConsumer.cpp:void clang::extractapi::impl::modifyRecords<llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > > > > > >(llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > > > > > const&, llvm::StringRef const&)
Line
Count
Source
110
1
static void modifyRecords(const T &Records, const StringRef &Name) {
111
1
  for (const auto &Record : Records) {
112
1
    if (Name == Record.second.get()->Name) {
113
1
      auto &DeclFragment = Record.second->Declaration;
114
1
      DeclFragment.insert(DeclFragment.begin(), " ",
115
1
                          DeclarationFragments::FragmentKind::Text);
116
1
      DeclFragment.insert(DeclFragment.begin(), "typedef",
117
1
                          DeclarationFragments::FragmentKind::Keyword, "",
118
1
                          nullptr);
119
1
      DeclFragment.insert(--DeclFragment.end(), " { ... } ",
120
1
                          DeclarationFragments::FragmentKind::Text);
121
1
      DeclFragment.insert(--DeclFragment.end(), Name,
122
1
                          DeclarationFragments::FragmentKind::Identifier);
123
1
      break;
124
1
    }
125
1
  }
126
1
}
ExtractAPIConsumer.cpp:void clang::extractapi::impl::modifyRecords<llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > > > > > >(llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > > > > > const&, llvm::StringRef const&)
Line
Count
Source
110
1
static void modifyRecords(const T &Records, const StringRef &Name) {
111
1
  for (const auto &Record : Records) {
112
1
    if (Name == Record.second.get()->Name) {
113
1
      auto &DeclFragment = Record.second->Declaration;
114
1
      DeclFragment.insert(DeclFragment.begin(), " ",
115
1
                          DeclarationFragments::FragmentKind::Text);
116
1
      DeclFragment.insert(DeclFragment.begin(), "typedef",
117
1
                          DeclarationFragments::FragmentKind::Keyword, "",
118
1
                          nullptr);
119
1
      DeclFragment.insert(--DeclFragment.end(), " { ... } ",
120
1
                          DeclarationFragments::FragmentKind::Text);
121
1
      DeclFragment.insert(--DeclFragment.end(), Name,
122
1
                          DeclarationFragments::FragmentKind::Identifier);
123
1
      break;
124
1
    }
125
1
  }
126
1
}
Unexecuted instantiation: CXExtractAPI.cpp:void clang::extractapi::impl::modifyRecords<llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > > > > > >(llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::StructRecord, std::__1::default_delete<clang::extractapi::StructRecord> > > > > > const&, llvm::StringRef const&)
Unexecuted instantiation: CXExtractAPI.cpp:void clang::extractapi::impl::modifyRecords<llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > > > > > >(llvm::MapVector<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> >, llvm::DenseMap<llvm::StringRef, unsigned int, llvm::DenseMapInfo<llvm::StringRef, void>, llvm::detail::DenseMapPair<llvm::StringRef, unsigned int> >, std::__1::vector<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > >, std::__1::allocator<std::__1::pair<llvm::StringRef, std::__1::unique_ptr<clang::extractapi::EnumRecord, std::__1::default_delete<clang::extractapi::EnumRecord> > > > > > const&, llvm::StringRef const&)
127
128
template <typename Derived>
129
43
bool ExtractAPIVisitorBase<Derived>::VisitVarDecl(const VarDecl *Decl) {
130
  // skip function parameters.
131
43
  if (isa<ParmVarDecl>(Decl))
132
30
    return true;
133
134
  // Skip non-global variables in records (struct/union/class).
135
13
  if (Decl->getDeclContext()->isRecord())
136
0
    return true;
137
138
  // Skip local variables inside function or method.
139
13
  if (!Decl->isDefinedOutsideFunctionOrMethod())
140
0
    return true;
141
142
  // If this is a template but not specialization or instantiation, skip.
143
13
  if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) &&
144
13
      
Decl->getTemplateSpecializationKind() == TSK_Undeclared0
)
145
0
    return true;
146
147
13
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
148
2
    return true;
149
150
  // Collect symbol information.
151
11
  StringRef Name = Decl->getName();
152
11
  StringRef USR = API.recordUSR(Decl);
153
11
  PresumedLoc Loc =
154
11
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
155
11
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
156
11
  DocComment Comment;
157
11
  if (auto *RawComment =
158
11
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
159
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
160
0
                                            Context.getDiagnostics());
161
162
  // Build declaration fragments and sub-heading for the variable.
163
11
  DeclarationFragments Declaration =
164
11
      DeclarationFragmentsBuilder::getFragmentsForVar(Decl);
165
11
  DeclarationFragments SubHeading =
166
11
      DeclarationFragmentsBuilder::getSubHeading(Decl);
167
168
  // Add the global variable record to the API set.
169
11
  API.addGlobalVar(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
170
11
                   Declaration, SubHeading, isInSystemHeader(Decl));
171
11
  return true;
172
13
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitVarDecl(clang::VarDecl const*)
Line
Count
Source
129
25
bool ExtractAPIVisitorBase<Derived>::VisitVarDecl(const VarDecl *Decl) {
130
  // skip function parameters.
131
25
  if (isa<ParmVarDecl>(Decl))
132
12
    return true;
133
134
  // Skip non-global variables in records (struct/union/class).
135
13
  if (Decl->getDeclContext()->isRecord())
136
0
    return true;
137
138
  // Skip local variables inside function or method.
139
13
  if (!Decl->isDefinedOutsideFunctionOrMethod())
140
0
    return true;
141
142
  // If this is a template but not specialization or instantiation, skip.
143
13
  if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) &&
144
13
      
Decl->getTemplateSpecializationKind() == TSK_Undeclared0
)
145
0
    return true;
146
147
13
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
148
2
    return true;
149
150
  // Collect symbol information.
151
11
  StringRef Name = Decl->getName();
152
11
  StringRef USR = API.recordUSR(Decl);
153
11
  PresumedLoc Loc =
154
11
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
155
11
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
156
11
  DocComment Comment;
157
11
  if (auto *RawComment =
158
11
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
159
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
160
0
                                            Context.getDiagnostics());
161
162
  // Build declaration fragments and sub-heading for the variable.
163
11
  DeclarationFragments Declaration =
164
11
      DeclarationFragmentsBuilder::getFragmentsForVar(Decl);
165
11
  DeclarationFragments SubHeading =
166
11
      DeclarationFragmentsBuilder::getSubHeading(Decl);
167
168
  // Add the global variable record to the API set.
169
11
  API.addGlobalVar(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
170
11
                   Declaration, SubHeading, isInSystemHeader(Decl));
171
11
  return true;
172
13
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitVarDecl(clang::VarDecl const*)
Line
Count
Source
129
18
bool ExtractAPIVisitorBase<Derived>::VisitVarDecl(const VarDecl *Decl) {
130
  // skip function parameters.
131
18
  if (isa<ParmVarDecl>(Decl))
132
18
    return true;
133
134
  // Skip non-global variables in records (struct/union/class).
135
0
  if (Decl->getDeclContext()->isRecord())
136
0
    return true;
137
138
  // Skip local variables inside function or method.
139
0
  if (!Decl->isDefinedOutsideFunctionOrMethod())
140
0
    return true;
141
142
  // If this is a template but not specialization or instantiation, skip.
143
0
  if (Decl->getASTContext().getTemplateOrSpecializationInfo(Decl) &&
144
0
      Decl->getTemplateSpecializationKind() == TSK_Undeclared)
145
0
    return true;
146
147
0
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
148
0
    return true;
149
150
  // Collect symbol information.
151
0
  StringRef Name = Decl->getName();
152
0
  StringRef USR = API.recordUSR(Decl);
153
0
  PresumedLoc Loc =
154
0
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
155
0
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
156
0
  DocComment Comment;
157
0
  if (auto *RawComment =
158
0
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
159
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
160
0
                                            Context.getDiagnostics());
161
162
  // Build declaration fragments and sub-heading for the variable.
163
0
  DeclarationFragments Declaration =
164
0
      DeclarationFragmentsBuilder::getFragmentsForVar(Decl);
165
0
  DeclarationFragments SubHeading =
166
0
      DeclarationFragmentsBuilder::getSubHeading(Decl);
167
168
  // Add the global variable record to the API set.
169
0
  API.addGlobalVar(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
170
0
                   Declaration, SubHeading, isInSystemHeader(Decl));
171
0
  return true;
172
0
}
173
174
template <typename Derived>
175
bool ExtractAPIVisitorBase<Derived>::VisitFunctionDecl(
176
14
    const FunctionDecl *Decl) {
177
14
  if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
178
    // Skip member function in class templates.
179
0
    if (Method->getParent()->getDescribedClassTemplate() != nullptr)
180
0
      return true;
181
182
    // Skip methods in records.
183
0
    for (const auto &P : Context.getParents(*Method)) {
184
0
      if (P.template get<CXXRecordDecl>())
185
0
        return true;
186
0
    }
187
188
    // Skip ConstructorDecl and DestructorDecl.
189
0
    if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
190
0
      return true;
191
0
  }
192
193
  // Skip templated functions.
194
14
  switch (Decl->getTemplatedKind()) {
195
14
  case FunctionDecl::TK_NonTemplate:
196
14
  case FunctionDecl::TK_DependentNonTemplate:
197
14
    break;
198
0
  case FunctionDecl::TK_MemberSpecialization:
199
0
  case FunctionDecl::TK_FunctionTemplateSpecialization:
200
0
    if (auto *TemplateInfo = Decl->getTemplateSpecializationInfo()) {
201
0
      if (!TemplateInfo->isExplicitInstantiationOrSpecialization())
202
0
        return true;
203
0
    }
204
0
    break;
205
0
  case FunctionDecl::TK_FunctionTemplate:
206
0
  case FunctionDecl::TK_DependentFunctionTemplateSpecialization:
207
0
    return true;
208
14
  }
209
210
14
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
211
1
    return true;
212
213
  // Collect symbol information.
214
13
  StringRef Name = Decl->getName();
215
13
  StringRef USR = API.recordUSR(Decl);
216
13
  PresumedLoc Loc =
217
13
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
218
13
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
219
13
  DocComment Comment;
220
13
  if (auto *RawComment =
221
13
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
222
2
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
223
2
                                            Context.getDiagnostics());
224
225
  // Build declaration fragments, sub-heading, and signature of the function.
226
13
  DeclarationFragments Declaration =
227
13
      DeclarationFragmentsBuilder::getFragmentsForFunction(Decl);
228
13
  DeclarationFragments SubHeading =
229
13
      DeclarationFragmentsBuilder::getSubHeading(Decl);
230
13
  FunctionSignature Signature =
231
13
      DeclarationFragmentsBuilder::getFunctionSignature(Decl);
232
233
  // Add the function record to the API set.
234
13
  API.addGlobalFunction(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
235
13
                        Declaration, SubHeading, Signature,
236
13
                        isInSystemHeader(Decl));
237
13
  return true;
238
14
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitFunctionDecl(clang::FunctionDecl const*)
Line
Count
Source
176
14
    const FunctionDecl *Decl) {
177
14
  if (const auto *Method = dyn_cast<CXXMethodDecl>(Decl)) {
178
    // Skip member function in class templates.
179
0
    if (Method->getParent()->getDescribedClassTemplate() != nullptr)
180
0
      return true;
181
182
    // Skip methods in records.
183
0
    for (const auto &P : Context.getParents(*Method)) {
184
0
      if (P.template get<CXXRecordDecl>())
185
0
        return true;
186
0
    }
187
188
    // Skip ConstructorDecl and DestructorDecl.
189
0
    if (isa<CXXConstructorDecl>(Method) || isa<CXXDestructorDecl>(Method))
190
0
      return true;
191
0
  }
192
193
  // Skip templated functions.
194
14
  switch (Decl->getTemplatedKind()) {
195
14
  case FunctionDecl::TK_NonTemplate:
196
14
  case FunctionDecl::TK_DependentNonTemplate:
197
14
    break;
198
0
  case FunctionDecl::TK_MemberSpecialization:
199
0
  case FunctionDecl::TK_FunctionTemplateSpecialization:
200
0
    if (auto *TemplateInfo = Decl->getTemplateSpecializationInfo()) {
201
0
      if (!TemplateInfo->isExplicitInstantiationOrSpecialization())
202
0
        return true;
203
0
    }
204
0
    break;
205
0
  case FunctionDecl::TK_FunctionTemplate:
206
0
  case FunctionDecl::TK_DependentFunctionTemplateSpecialization:
207
0
    return true;
208
14
  }
209
210
14
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
211
1
    return true;
212
213
  // Collect symbol information.
214
13
  StringRef Name = Decl->getName();
215
13
  StringRef USR = API.recordUSR(Decl);
216
13
  PresumedLoc Loc =
217
13
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
218
13
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
219
13
  DocComment Comment;
220
13
  if (auto *RawComment =
221
13
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
222
2
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
223
2
                                            Context.getDiagnostics());
224
225
  // Build declaration fragments, sub-heading, and signature of the function.
226
13
  DeclarationFragments Declaration =
227
13
      DeclarationFragmentsBuilder::getFragmentsForFunction(Decl);
228
13
  DeclarationFragments SubHeading =
229
13
      DeclarationFragmentsBuilder::getSubHeading(Decl);
230
13
  FunctionSignature Signature =
231
13
      DeclarationFragmentsBuilder::getFunctionSignature(Decl);
232
233
  // Add the function record to the API set.
234
13
  API.addGlobalFunction(Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment,
235
13
                        Declaration, SubHeading, Signature,
236
13
                        isInSystemHeader(Decl));
237
13
  return true;
238
14
}
Unexecuted instantiation: CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitFunctionDecl(clang::FunctionDecl const*)
239
240
template <typename Derived>
241
7
bool ExtractAPIVisitorBase<Derived>::VisitEnumDecl(const EnumDecl *Decl) {
242
7
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
243
0
    return true;
244
245
7
  SmallString<128> QualifiedNameBuffer;
246
  // Collect symbol information.
247
7
  StringRef Name = Decl->getName();
248
7
  if (Name.empty())
249
4
    Name = getTypedefName(Decl);
250
7
  if (Name.empty()) {
251
3
    llvm::raw_svector_ostream OS(QualifiedNameBuffer);
252
3
    Decl->printQualifiedName(OS);
253
3
    Name = QualifiedNameBuffer.str();
254
3
  }
255
256
7
  StringRef USR = API.recordUSR(Decl);
257
7
  PresumedLoc Loc =
258
7
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
259
7
  DocComment Comment;
260
7
  if (auto *RawComment =
261
7
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
262
2
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
263
2
                                            Context.getDiagnostics());
264
265
  // Build declaration fragments and sub-heading for the enum.
266
7
  DeclarationFragments Declaration =
267
7
      DeclarationFragmentsBuilder::getFragmentsForEnum(Decl);
268
7
  DeclarationFragments SubHeading =
269
7
      DeclarationFragmentsBuilder::getSubHeading(Decl);
270
271
7
  EnumRecord *EnumRecord =
272
7
      API.addEnum(API.copyString(Name), USR, Loc, AvailabilitySet(Decl),
273
7
                  Comment, Declaration, SubHeading, isInSystemHeader(Decl));
274
275
  // Now collect information about the enumerators in this enum.
276
7
  getDerivedExtractAPIVisitor().recordEnumConstants(EnumRecord,
277
7
                                                    Decl->enumerators());
278
279
7
  return true;
280
7
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitEnumDecl(clang::EnumDecl const*)
Line
Count
Source
241
7
bool ExtractAPIVisitorBase<Derived>::VisitEnumDecl(const EnumDecl *Decl) {
242
7
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
243
0
    return true;
244
245
7
  SmallString<128> QualifiedNameBuffer;
246
  // Collect symbol information.
247
7
  StringRef Name = Decl->getName();
248
7
  if (Name.empty())
249
4
    Name = getTypedefName(Decl);
250
7
  if (Name.empty()) {
251
3
    llvm::raw_svector_ostream OS(QualifiedNameBuffer);
252
3
    Decl->printQualifiedName(OS);
253
3
    Name = QualifiedNameBuffer.str();
254
3
  }
255
256
7
  StringRef USR = API.recordUSR(Decl);
257
7
  PresumedLoc Loc =
258
7
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
259
7
  DocComment Comment;
260
7
  if (auto *RawComment =
261
7
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
262
2
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
263
2
                                            Context.getDiagnostics());
264
265
  // Build declaration fragments and sub-heading for the enum.
266
7
  DeclarationFragments Declaration =
267
7
      DeclarationFragmentsBuilder::getFragmentsForEnum(Decl);
268
7
  DeclarationFragments SubHeading =
269
7
      DeclarationFragmentsBuilder::getSubHeading(Decl);
270
271
7
  EnumRecord *EnumRecord =
272
7
      API.addEnum(API.copyString(Name), USR, Loc, AvailabilitySet(Decl),
273
7
                  Comment, Declaration, SubHeading, isInSystemHeader(Decl));
274
275
  // Now collect information about the enumerators in this enum.
276
7
  getDerivedExtractAPIVisitor().recordEnumConstants(EnumRecord,
277
7
                                                    Decl->enumerators());
278
279
7
  return true;
280
7
}
Unexecuted instantiation: CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitEnumDecl(clang::EnumDecl const*)
281
282
template <typename Derived>
283
24
bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
284
  // Skip C++ structs/classes/unions
285
  // TODO: support C++ records
286
24
  if (isa<CXXRecordDecl>(Decl))
287
0
    return true;
288
289
24
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
290
2
    return true;
291
292
  // Collect symbol information.
293
22
  StringRef Name = Decl->getName();
294
22
  if (Name.empty())
295
3
    Name = getTypedefName(Decl);
296
22
  if (Name.empty())
297
1
    return true;
298
299
21
  StringRef USR = API.recordUSR(Decl);
300
21
  PresumedLoc Loc =
301
21
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
302
21
  DocComment Comment;
303
21
  if (auto *RawComment =
304
21
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
305
15
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
306
15
                                            Context.getDiagnostics());
307
308
  // Build declaration fragments and sub-heading for the struct.
309
21
  DeclarationFragments Declaration =
310
21
      DeclarationFragmentsBuilder::getFragmentsForStruct(Decl);
311
21
  DeclarationFragments SubHeading =
312
21
      DeclarationFragmentsBuilder::getSubHeading(Decl);
313
314
21
  StructRecord *StructRecord =
315
21
      API.addStruct(Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
316
21
                    SubHeading, isInSystemHeader(Decl));
317
318
  // Now collect information about the fields in this struct.
319
21
  getDerivedExtractAPIVisitor().recordStructFields(StructRecord,
320
21
                                                   Decl->fields());
321
322
21
  return true;
323
22
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitRecordDecl(clang::RecordDecl const*)
Line
Count
Source
283
11
bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
284
  // Skip C++ structs/classes/unions
285
  // TODO: support C++ records
286
11
  if (isa<CXXRecordDecl>(Decl))
287
0
    return true;
288
289
11
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
290
2
    return true;
291
292
  // Collect symbol information.
293
9
  StringRef Name = Decl->getName();
294
9
  if (Name.empty())
295
3
    Name = getTypedefName(Decl);
296
9
  if (Name.empty())
297
1
    return true;
298
299
8
  StringRef USR = API.recordUSR(Decl);
300
8
  PresumedLoc Loc =
301
8
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
302
8
  DocComment Comment;
303
8
  if (auto *RawComment =
304
8
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
305
2
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
306
2
                                            Context.getDiagnostics());
307
308
  // Build declaration fragments and sub-heading for the struct.
309
8
  DeclarationFragments Declaration =
310
8
      DeclarationFragmentsBuilder::getFragmentsForStruct(Decl);
311
8
  DeclarationFragments SubHeading =
312
8
      DeclarationFragmentsBuilder::getSubHeading(Decl);
313
314
8
  StructRecord *StructRecord =
315
8
      API.addStruct(Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
316
8
                    SubHeading, isInSystemHeader(Decl));
317
318
  // Now collect information about the fields in this struct.
319
8
  getDerivedExtractAPIVisitor().recordStructFields(StructRecord,
320
8
                                                   Decl->fields());
321
322
8
  return true;
323
9
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitRecordDecl(clang::RecordDecl const*)
Line
Count
Source
283
13
bool ExtractAPIVisitorBase<Derived>::VisitRecordDecl(const RecordDecl *Decl) {
284
  // Skip C++ structs/classes/unions
285
  // TODO: support C++ records
286
13
  if (isa<CXXRecordDecl>(Decl))
287
0
    return true;
288
289
13
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
290
0
    return true;
291
292
  // Collect symbol information.
293
13
  StringRef Name = Decl->getName();
294
13
  if (Name.empty())
295
0
    Name = getTypedefName(Decl);
296
13
  if (Name.empty())
297
0
    return true;
298
299
13
  StringRef USR = API.recordUSR(Decl);
300
13
  PresumedLoc Loc =
301
13
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
302
13
  DocComment Comment;
303
13
  if (auto *RawComment =
304
13
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
305
13
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
306
13
                                            Context.getDiagnostics());
307
308
  // Build declaration fragments and sub-heading for the struct.
309
13
  DeclarationFragments Declaration =
310
13
      DeclarationFragmentsBuilder::getFragmentsForStruct(Decl);
311
13
  DeclarationFragments SubHeading =
312
13
      DeclarationFragmentsBuilder::getSubHeading(Decl);
313
314
13
  StructRecord *StructRecord =
315
13
      API.addStruct(Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration,
316
13
                    SubHeading, isInSystemHeader(Decl));
317
318
  // Now collect information about the fields in this struct.
319
13
  getDerivedExtractAPIVisitor().recordStructFields(StructRecord,
320
13
                                                   Decl->fields());
321
322
13
  return true;
323
13
}
324
325
template <typename Derived>
326
bool ExtractAPIVisitorBase<Derived>::VisitObjCInterfaceDecl(
327
31
    const ObjCInterfaceDecl *Decl) {
328
31
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
329
0
    return true;
330
331
  // Collect symbol information.
332
31
  StringRef Name = Decl->getName();
333
31
  StringRef USR = API.recordUSR(Decl);
334
31
  PresumedLoc Loc =
335
31
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
336
31
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
337
31
  DocComment Comment;
338
31
  if (auto *RawComment =
339
31
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
340
25
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
341
25
                                            Context.getDiagnostics());
342
343
  // Build declaration fragments and sub-heading for the interface.
344
31
  DeclarationFragments Declaration =
345
31
      DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Decl);
346
31
  DeclarationFragments SubHeading =
347
31
      DeclarationFragmentsBuilder::getSubHeading(Decl);
348
349
  // Collect super class information.
350
31
  SymbolReference SuperClass;
351
31
  if (const auto *SuperClassDecl = Decl->getSuperClass()) {
352
13
    SuperClass.Name = SuperClassDecl->getObjCRuntimeNameAsString();
353
13
    SuperClass.USR = API.recordUSR(SuperClassDecl);
354
13
  }
355
356
31
  ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface(
357
31
      Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment, Declaration,
358
31
      SubHeading, SuperClass, isInSystemHeader(Decl));
359
360
  // Record all methods (selectors). This doesn't include automatically
361
  // synthesized property methods.
362
31
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCInterfaceRecord,
363
31
                                                  Decl->methods());
364
31
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCInterfaceRecord,
365
31
                                                     Decl->properties());
366
31
  getDerivedExtractAPIVisitor().recordObjCInstanceVariables(ObjCInterfaceRecord,
367
31
                                                            Decl->ivars());
368
31
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCInterfaceRecord,
369
31
                                                    Decl->protocols());
370
371
31
  return true;
372
31
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitObjCInterfaceDecl(clang::ObjCInterfaceDecl const*)
Line
Count
Source
327
6
    const ObjCInterfaceDecl *Decl) {
328
6
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
329
0
    return true;
330
331
  // Collect symbol information.
332
6
  StringRef Name = Decl->getName();
333
6
  StringRef USR = API.recordUSR(Decl);
334
6
  PresumedLoc Loc =
335
6
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
336
6
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
337
6
  DocComment Comment;
338
6
  if (auto *RawComment =
339
6
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
340
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
341
0
                                            Context.getDiagnostics());
342
343
  // Build declaration fragments and sub-heading for the interface.
344
6
  DeclarationFragments Declaration =
345
6
      DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Decl);
346
6
  DeclarationFragments SubHeading =
347
6
      DeclarationFragmentsBuilder::getSubHeading(Decl);
348
349
  // Collect super class information.
350
6
  SymbolReference SuperClass;
351
6
  if (const auto *SuperClassDecl = Decl->getSuperClass()) {
352
1
    SuperClass.Name = SuperClassDecl->getObjCRuntimeNameAsString();
353
1
    SuperClass.USR = API.recordUSR(SuperClassDecl);
354
1
  }
355
356
6
  ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface(
357
6
      Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment, Declaration,
358
6
      SubHeading, SuperClass, isInSystemHeader(Decl));
359
360
  // Record all methods (selectors). This doesn't include automatically
361
  // synthesized property methods.
362
6
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCInterfaceRecord,
363
6
                                                  Decl->methods());
364
6
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCInterfaceRecord,
365
6
                                                     Decl->properties());
366
6
  getDerivedExtractAPIVisitor().recordObjCInstanceVariables(ObjCInterfaceRecord,
367
6
                                                            Decl->ivars());
368
6
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCInterfaceRecord,
369
6
                                                    Decl->protocols());
370
371
6
  return true;
372
6
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitObjCInterfaceDecl(clang::ObjCInterfaceDecl const*)
Line
Count
Source
327
25
    const ObjCInterfaceDecl *Decl) {
328
25
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
329
0
    return true;
330
331
  // Collect symbol information.
332
25
  StringRef Name = Decl->getName();
333
25
  StringRef USR = API.recordUSR(Decl);
334
25
  PresumedLoc Loc =
335
25
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
336
25
  LinkageInfo Linkage = Decl->getLinkageAndVisibility();
337
25
  DocComment Comment;
338
25
  if (auto *RawComment =
339
25
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
340
25
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
341
25
                                            Context.getDiagnostics());
342
343
  // Build declaration fragments and sub-heading for the interface.
344
25
  DeclarationFragments Declaration =
345
25
      DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Decl);
346
25
  DeclarationFragments SubHeading =
347
25
      DeclarationFragmentsBuilder::getSubHeading(Decl);
348
349
  // Collect super class information.
350
25
  SymbolReference SuperClass;
351
25
  if (const auto *SuperClassDecl = Decl->getSuperClass()) {
352
12
    SuperClass.Name = SuperClassDecl->getObjCRuntimeNameAsString();
353
12
    SuperClass.USR = API.recordUSR(SuperClassDecl);
354
12
  }
355
356
25
  ObjCInterfaceRecord *ObjCInterfaceRecord = API.addObjCInterface(
357
25
      Name, USR, Loc, AvailabilitySet(Decl), Linkage, Comment, Declaration,
358
25
      SubHeading, SuperClass, isInSystemHeader(Decl));
359
360
  // Record all methods (selectors). This doesn't include automatically
361
  // synthesized property methods.
362
25
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCInterfaceRecord,
363
25
                                                  Decl->methods());
364
25
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCInterfaceRecord,
365
25
                                                     Decl->properties());
366
25
  getDerivedExtractAPIVisitor().recordObjCInstanceVariables(ObjCInterfaceRecord,
367
25
                                                            Decl->ivars());
368
25
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCInterfaceRecord,
369
25
                                                    Decl->protocols());
370
371
25
  return true;
372
25
}
373
374
template <typename Derived>
375
bool ExtractAPIVisitorBase<Derived>::VisitObjCProtocolDecl(
376
17
    const ObjCProtocolDecl *Decl) {
377
17
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
378
2
    return true;
379
380
  // Collect symbol information.
381
15
  StringRef Name = Decl->getName();
382
15
  StringRef USR = API.recordUSR(Decl);
383
15
  PresumedLoc Loc =
384
15
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
385
15
  DocComment Comment;
386
15
  if (auto *RawComment =
387
15
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
388
11
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
389
11
                                            Context.getDiagnostics());
390
391
  // Build declaration fragments and sub-heading for the protocol.
392
15
  DeclarationFragments Declaration =
393
15
      DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(Decl);
394
15
  DeclarationFragments SubHeading =
395
15
      DeclarationFragmentsBuilder::getSubHeading(Decl);
396
397
15
  ObjCProtocolRecord *ObjCProtocolRecord =
398
15
      API.addObjCProtocol(Name, USR, Loc, AvailabilitySet(Decl), Comment,
399
15
                          Declaration, SubHeading, isInSystemHeader(Decl));
400
401
15
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCProtocolRecord,
402
15
                                                  Decl->methods());
403
15
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCProtocolRecord,
404
15
                                                     Decl->properties());
405
15
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCProtocolRecord,
406
15
                                                    Decl->protocols());
407
408
15
  return true;
409
17
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitObjCProtocolDecl(clang::ObjCProtocolDecl const*)
Line
Count
Source
376
6
    const ObjCProtocolDecl *Decl) {
377
6
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
378
2
    return true;
379
380
  // Collect symbol information.
381
4
  StringRef Name = Decl->getName();
382
4
  StringRef USR = API.recordUSR(Decl);
383
4
  PresumedLoc Loc =
384
4
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
385
4
  DocComment Comment;
386
4
  if (auto *RawComment =
387
4
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
388
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
389
0
                                            Context.getDiagnostics());
390
391
  // Build declaration fragments and sub-heading for the protocol.
392
4
  DeclarationFragments Declaration =
393
4
      DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(Decl);
394
4
  DeclarationFragments SubHeading =
395
4
      DeclarationFragmentsBuilder::getSubHeading(Decl);
396
397
4
  ObjCProtocolRecord *ObjCProtocolRecord =
398
4
      API.addObjCProtocol(Name, USR, Loc, AvailabilitySet(Decl), Comment,
399
4
                          Declaration, SubHeading, isInSystemHeader(Decl));
400
401
4
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCProtocolRecord,
402
4
                                                  Decl->methods());
403
4
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCProtocolRecord,
404
4
                                                     Decl->properties());
405
4
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCProtocolRecord,
406
4
                                                    Decl->protocols());
407
408
4
  return true;
409
6
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitObjCProtocolDecl(clang::ObjCProtocolDecl const*)
Line
Count
Source
376
11
    const ObjCProtocolDecl *Decl) {
377
11
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
378
0
    return true;
379
380
  // Collect symbol information.
381
11
  StringRef Name = Decl->getName();
382
11
  StringRef USR = API.recordUSR(Decl);
383
11
  PresumedLoc Loc =
384
11
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
385
11
  DocComment Comment;
386
11
  if (auto *RawComment =
387
11
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
388
11
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
389
11
                                            Context.getDiagnostics());
390
391
  // Build declaration fragments and sub-heading for the protocol.
392
11
  DeclarationFragments Declaration =
393
11
      DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(Decl);
394
11
  DeclarationFragments SubHeading =
395
11
      DeclarationFragmentsBuilder::getSubHeading(Decl);
396
397
11
  ObjCProtocolRecord *ObjCProtocolRecord =
398
11
      API.addObjCProtocol(Name, USR, Loc, AvailabilitySet(Decl), Comment,
399
11
                          Declaration, SubHeading, isInSystemHeader(Decl));
400
401
11
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCProtocolRecord,
402
11
                                                  Decl->methods());
403
11
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCProtocolRecord,
404
11
                                                     Decl->properties());
405
11
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCProtocolRecord,
406
11
                                                    Decl->protocols());
407
408
11
  return true;
409
11
}
410
411
template <typename Derived>
412
bool ExtractAPIVisitorBase<Derived>::VisitTypedefNameDecl(
413
21
    const TypedefNameDecl *Decl) {
414
  // Skip ObjC Type Parameter for now.
415
21
  if (isa<ObjCTypeParamDecl>(Decl))
416
0
    return true;
417
418
21
  if (!Decl->isDefinedOutsideFunctionOrMethod())
419
0
    return true;
420
421
21
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
422
0
    return true;
423
424
  // Add the notion of typedef for tag type (struct or enum) of the same name.
425
21
  if (const ElaboratedType *ET =
426
21
          dyn_cast<ElaboratedType>(Decl->getUnderlyingType())) {
427
13
    if (const TagType *TagTy = dyn_cast<TagType>(ET->desugar())) {
428
6
      if (Decl->getName() == TagTy->getDecl()->getName()) {
429
2
        if (TagTy->getDecl()->isStruct()) {
430
1
          modifyRecords(API.getStructs(), Decl->getName());
431
1
        }
432
2
        if (TagTy->getDecl()->isEnum()) {
433
1
          modifyRecords(API.getEnums(), Decl->getName());
434
1
        }
435
2
      }
436
6
    }
437
13
  }
438
439
21
  PresumedLoc Loc =
440
21
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
441
21
  StringRef Name = Decl->getName();
442
21
  StringRef USR = API.recordUSR(Decl);
443
21
  DocComment Comment;
444
21
  if (auto *RawComment =
445
21
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
446
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
447
0
                                            Context.getDiagnostics());
448
449
21
  QualType Type = Decl->getUnderlyingType();
450
21
  SymbolReference SymRef =
451
21
      TypedefUnderlyingTypeResolver(Context).getSymbolReferenceForType(Type,
452
21
                                                                       API);
453
454
21
  API.addTypedef(Name, USR, Loc, AvailabilitySet(Decl), Comment,
455
21
                 DeclarationFragmentsBuilder::getFragmentsForTypedef(Decl),
456
21
                 DeclarationFragmentsBuilder::getSubHeading(Decl), SymRef,
457
21
                 isInSystemHeader(Decl));
458
459
21
  return true;
460
21
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitTypedefNameDecl(clang::TypedefNameDecl const*)
Line
Count
Source
413
21
    const TypedefNameDecl *Decl) {
414
  // Skip ObjC Type Parameter for now.
415
21
  if (isa<ObjCTypeParamDecl>(Decl))
416
0
    return true;
417
418
21
  if (!Decl->isDefinedOutsideFunctionOrMethod())
419
0
    return true;
420
421
21
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
422
0
    return true;
423
424
  // Add the notion of typedef for tag type (struct or enum) of the same name.
425
21
  if (const ElaboratedType *ET =
426
21
          dyn_cast<ElaboratedType>(Decl->getUnderlyingType())) {
427
13
    if (const TagType *TagTy = dyn_cast<TagType>(ET->desugar())) {
428
6
      if (Decl->getName() == TagTy->getDecl()->getName()) {
429
2
        if (TagTy->getDecl()->isStruct()) {
430
1
          modifyRecords(API.getStructs(), Decl->getName());
431
1
        }
432
2
        if (TagTy->getDecl()->isEnum()) {
433
1
          modifyRecords(API.getEnums(), Decl->getName());
434
1
        }
435
2
      }
436
6
    }
437
13
  }
438
439
21
  PresumedLoc Loc =
440
21
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
441
21
  StringRef Name = Decl->getName();
442
21
  StringRef USR = API.recordUSR(Decl);
443
21
  DocComment Comment;
444
21
  if (auto *RawComment =
445
21
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
446
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
447
0
                                            Context.getDiagnostics());
448
449
21
  QualType Type = Decl->getUnderlyingType();
450
21
  SymbolReference SymRef =
451
21
      TypedefUnderlyingTypeResolver(Context).getSymbolReferenceForType(Type,
452
21
                                                                       API);
453
454
21
  API.addTypedef(Name, USR, Loc, AvailabilitySet(Decl), Comment,
455
21
                 DeclarationFragmentsBuilder::getFragmentsForTypedef(Decl),
456
21
                 DeclarationFragmentsBuilder::getSubHeading(Decl), SymRef,
457
21
                 isInSystemHeader(Decl));
458
459
21
  return true;
460
21
}
Unexecuted instantiation: CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitTypedefNameDecl(clang::TypedefNameDecl const*)
461
462
template <typename Derived>
463
bool ExtractAPIVisitorBase<Derived>::VisitObjCCategoryDecl(
464
2
    const ObjCCategoryDecl *Decl) {
465
2
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
466
0
    return true;
467
468
2
  StringRef Name = Decl->getName();
469
2
  StringRef USR = API.recordUSR(Decl);
470
2
  PresumedLoc Loc =
471
2
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
472
2
  DocComment Comment;
473
2
  if (auto *RawComment =
474
2
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
475
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
476
0
                                            Context.getDiagnostics());
477
  // Build declaration fragments and sub-heading for the category.
478
2
  DeclarationFragments Declaration =
479
2
      DeclarationFragmentsBuilder::getFragmentsForObjCCategory(Decl);
480
2
  DeclarationFragments SubHeading =
481
2
      DeclarationFragmentsBuilder::getSubHeading(Decl);
482
483
2
  const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
484
2
  SymbolReference Interface(InterfaceDecl->getName(),
485
2
                            API.recordUSR(InterfaceDecl));
486
487
2
  ObjCCategoryRecord *ObjCCategoryRecord = API.addObjCCategory(
488
2
      Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration, SubHeading,
489
2
      Interface, isInSystemHeader(Decl));
490
491
2
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCCategoryRecord,
492
2
                                                  Decl->methods());
493
2
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCCategoryRecord,
494
2
                                                     Decl->properties());
495
2
  getDerivedExtractAPIVisitor().recordObjCInstanceVariables(ObjCCategoryRecord,
496
2
                                                            Decl->ivars());
497
2
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCCategoryRecord,
498
2
                                                    Decl->protocols());
499
500
2
  return true;
501
2
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::VisitObjCCategoryDecl(clang::ObjCCategoryDecl const*)
Line
Count
Source
464
2
    const ObjCCategoryDecl *Decl) {
465
2
  if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl))
466
0
    return true;
467
468
2
  StringRef Name = Decl->getName();
469
2
  StringRef USR = API.recordUSR(Decl);
470
2
  PresumedLoc Loc =
471
2
      Context.getSourceManager().getPresumedLoc(Decl->getLocation());
472
2
  DocComment Comment;
473
2
  if (auto *RawComment =
474
2
          getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl))
475
0
    Comment = RawComment->getFormattedLines(Context.getSourceManager(),
476
0
                                            Context.getDiagnostics());
477
  // Build declaration fragments and sub-heading for the category.
478
2
  DeclarationFragments Declaration =
479
2
      DeclarationFragmentsBuilder::getFragmentsForObjCCategory(Decl);
480
2
  DeclarationFragments SubHeading =
481
2
      DeclarationFragmentsBuilder::getSubHeading(Decl);
482
483
2
  const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface();
484
2
  SymbolReference Interface(InterfaceDecl->getName(),
485
2
                            API.recordUSR(InterfaceDecl));
486
487
2
  ObjCCategoryRecord *ObjCCategoryRecord = API.addObjCCategory(
488
2
      Name, USR, Loc, AvailabilitySet(Decl), Comment, Declaration, SubHeading,
489
2
      Interface, isInSystemHeader(Decl));
490
491
2
  getDerivedExtractAPIVisitor().recordObjCMethods(ObjCCategoryRecord,
492
2
                                                  Decl->methods());
493
2
  getDerivedExtractAPIVisitor().recordObjCProperties(ObjCCategoryRecord,
494
2
                                                     Decl->properties());
495
2
  getDerivedExtractAPIVisitor().recordObjCInstanceVariables(ObjCCategoryRecord,
496
2
                                                            Decl->ivars());
497
2
  getDerivedExtractAPIVisitor().recordObjCProtocols(ObjCCategoryRecord,
498
2
                                                    Decl->protocols());
499
500
2
  return true;
501
2
}
Unexecuted instantiation: CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::VisitObjCCategoryDecl(clang::ObjCCategoryDecl const*)
502
503
/// Collect API information for the enum constants and associate with the
504
/// parent enum.
505
template <typename Derived>
506
void ExtractAPIVisitorBase<Derived>::recordEnumConstants(
507
7
    EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) {
508
15
  for (const auto *Constant : Constants) {
509
    // Collect symbol information.
510
15
    StringRef Name = Constant->getName();
511
15
    StringRef USR = API.recordUSR(Constant);
512
15
    PresumedLoc Loc =
513
15
        Context.getSourceManager().getPresumedLoc(Constant->getLocation());
514
15
    DocComment Comment;
515
15
    if (auto *RawComment =
516
15
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
517
1
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
518
1
                                              Context.getDiagnostics());
519
520
    // Build declaration fragments and sub-heading for the enum constant.
521
15
    DeclarationFragments Declaration =
522
15
        DeclarationFragmentsBuilder::getFragmentsForEnumConstant(Constant);
523
15
    DeclarationFragments SubHeading =
524
15
        DeclarationFragmentsBuilder::getSubHeading(Constant);
525
526
15
    API.addEnumConstant(EnumRecord, Name, USR, Loc, AvailabilitySet(Constant),
527
15
                        Comment, Declaration, SubHeading,
528
15
                        isInSystemHeader(Constant));
529
15
  }
530
7
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::recordEnumConstants(clang::extractapi::EnumRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::EnumConstantDecl> >)
Line
Count
Source
507
7
    EnumRecord *EnumRecord, const EnumDecl::enumerator_range Constants) {
508
15
  for (const auto *Constant : Constants) {
509
    // Collect symbol information.
510
15
    StringRef Name = Constant->getName();
511
15
    StringRef USR = API.recordUSR(Constant);
512
15
    PresumedLoc Loc =
513
15
        Context.getSourceManager().getPresumedLoc(Constant->getLocation());
514
15
    DocComment Comment;
515
15
    if (auto *RawComment =
516
15
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant))
517
1
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
518
1
                                              Context.getDiagnostics());
519
520
    // Build declaration fragments and sub-heading for the enum constant.
521
15
    DeclarationFragments Declaration =
522
15
        DeclarationFragmentsBuilder::getFragmentsForEnumConstant(Constant);
523
15
    DeclarationFragments SubHeading =
524
15
        DeclarationFragmentsBuilder::getSubHeading(Constant);
525
526
15
    API.addEnumConstant(EnumRecord, Name, USR, Loc, AvailabilitySet(Constant),
527
15
                        Comment, Declaration, SubHeading,
528
15
                        isInSystemHeader(Constant));
529
15
  }
530
7
}
Unexecuted instantiation: CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::recordEnumConstants(clang::extractapi::EnumRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::EnumConstantDecl> >)
531
532
/// Collect API information for the struct fields and associate with the
533
/// parent struct.
534
template <typename Derived>
535
void ExtractAPIVisitorBase<Derived>::recordStructFields(
536
21
    StructRecord *StructRecord, const RecordDecl::field_range Fields) {
537
22
  for (const auto *Field : Fields) {
538
    // Collect symbol information.
539
22
    StringRef Name = Field->getName();
540
22
    StringRef USR = API.recordUSR(Field);
541
22
    PresumedLoc Loc =
542
22
        Context.getSourceManager().getPresumedLoc(Field->getLocation());
543
22
    DocComment Comment;
544
22
    if (auto *RawComment =
545
22
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Field))
546
14
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
547
14
                                              Context.getDiagnostics());
548
549
    // Build declaration fragments and sub-heading for the struct field.
550
22
    DeclarationFragments Declaration =
551
22
        DeclarationFragmentsBuilder::getFragmentsForField(Field);
552
22
    DeclarationFragments SubHeading =
553
22
        DeclarationFragmentsBuilder::getSubHeading(Field);
554
555
22
    API.addStructField(StructRecord, Name, USR, Loc, AvailabilitySet(Field),
556
22
                       Comment, Declaration, SubHeading,
557
22
                       isInSystemHeader(Field));
558
22
  }
559
21
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::recordStructFields(clang::extractapi::StructRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::FieldDecl> >)
Line
Count
Source
536
8
    StructRecord *StructRecord, const RecordDecl::field_range Fields) {
537
9
  for (const auto *Field : Fields) {
538
    // Collect symbol information.
539
9
    StringRef Name = Field->getName();
540
9
    StringRef USR = API.recordUSR(Field);
541
9
    PresumedLoc Loc =
542
9
        Context.getSourceManager().getPresumedLoc(Field->getLocation());
543
9
    DocComment Comment;
544
9
    if (auto *RawComment =
545
9
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Field))
546
1
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
547
1
                                              Context.getDiagnostics());
548
549
    // Build declaration fragments and sub-heading for the struct field.
550
9
    DeclarationFragments Declaration =
551
9
        DeclarationFragmentsBuilder::getFragmentsForField(Field);
552
9
    DeclarationFragments SubHeading =
553
9
        DeclarationFragmentsBuilder::getSubHeading(Field);
554
555
9
    API.addStructField(StructRecord, Name, USR, Loc, AvailabilitySet(Field),
556
9
                       Comment, Declaration, SubHeading,
557
9
                       isInSystemHeader(Field));
558
9
  }
559
8
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::recordStructFields(clang::extractapi::StructRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::FieldDecl> >)
Line
Count
Source
536
13
    StructRecord *StructRecord, const RecordDecl::field_range Fields) {
537
13
  for (const auto *Field : Fields) {
538
    // Collect symbol information.
539
13
    StringRef Name = Field->getName();
540
13
    StringRef USR = API.recordUSR(Field);
541
13
    PresumedLoc Loc =
542
13
        Context.getSourceManager().getPresumedLoc(Field->getLocation());
543
13
    DocComment Comment;
544
13
    if (auto *RawComment =
545
13
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Field))
546
13
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
547
13
                                              Context.getDiagnostics());
548
549
    // Build declaration fragments and sub-heading for the struct field.
550
13
    DeclarationFragments Declaration =
551
13
        DeclarationFragmentsBuilder::getFragmentsForField(Field);
552
13
    DeclarationFragments SubHeading =
553
13
        DeclarationFragmentsBuilder::getSubHeading(Field);
554
555
13
    API.addStructField(StructRecord, Name, USR, Loc, AvailabilitySet(Field),
556
13
                       Comment, Declaration, SubHeading,
557
13
                       isInSystemHeader(Field));
558
13
  }
559
13
}
560
561
/// Collect API information for the Objective-C methods and associate with the
562
/// parent container.
563
template <typename Derived>
564
void ExtractAPIVisitorBase<Derived>::recordObjCMethods(
565
    ObjCContainerRecord *Container,
566
48
    const ObjCContainerDecl::method_range Methods) {
567
99
  for (const auto *Method : Methods) {
568
    // Don't record selectors for properties.
569
99
    if (Method->isPropertyAccessor())
570
67
      continue;
571
572
32
    StringRef Name = API.copyString(Method->getSelector().getAsString());
573
32
    StringRef USR = API.recordUSR(Method);
574
32
    PresumedLoc Loc =
575
32
        Context.getSourceManager().getPresumedLoc(Method->getLocation());
576
32
    DocComment Comment;
577
32
    if (auto *RawComment =
578
32
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
579
25
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
580
25
                                              Context.getDiagnostics());
581
582
    // Build declaration fragments, sub-heading, and signature for the method.
583
32
    DeclarationFragments Declaration =
584
32
        DeclarationFragmentsBuilder::getFragmentsForObjCMethod(Method);
585
32
    DeclarationFragments SubHeading =
586
32
        DeclarationFragmentsBuilder::getSubHeading(Method);
587
32
    FunctionSignature Signature =
588
32
        DeclarationFragmentsBuilder::getFunctionSignature(Method);
589
590
32
    API.addObjCMethod(Container, Name, USR, Loc, AvailabilitySet(Method),
591
32
                      Comment, Declaration, SubHeading, Signature,
592
32
                      Method->isInstanceMethod(), isInSystemHeader(Method));
593
32
  }
594
48
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::recordObjCMethods(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::ObjCMethodDecl> >)
Line
Count
Source
566
12
    const ObjCContainerDecl::method_range Methods) {
567
26
  for (const auto *Method : Methods) {
568
    // Don't record selectors for properties.
569
26
    if (Method->isPropertyAccessor())
570
19
      continue;
571
572
7
    StringRef Name = API.copyString(Method->getSelector().getAsString());
573
7
    StringRef USR = API.recordUSR(Method);
574
7
    PresumedLoc Loc =
575
7
        Context.getSourceManager().getPresumedLoc(Method->getLocation());
576
7
    DocComment Comment;
577
7
    if (auto *RawComment =
578
7
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
579
0
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
580
0
                                              Context.getDiagnostics());
581
582
    // Build declaration fragments, sub-heading, and signature for the method.
583
7
    DeclarationFragments Declaration =
584
7
        DeclarationFragmentsBuilder::getFragmentsForObjCMethod(Method);
585
7
    DeclarationFragments SubHeading =
586
7
        DeclarationFragmentsBuilder::getSubHeading(Method);
587
7
    FunctionSignature Signature =
588
7
        DeclarationFragmentsBuilder::getFunctionSignature(Method);
589
590
7
    API.addObjCMethod(Container, Name, USR, Loc, AvailabilitySet(Method),
591
7
                      Comment, Declaration, SubHeading, Signature,
592
7
                      Method->isInstanceMethod(), isInSystemHeader(Method));
593
7
  }
594
12
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::recordObjCMethods(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::ObjCMethodDecl> >)
Line
Count
Source
566
36
    const ObjCContainerDecl::method_range Methods) {
567
73
  for (const auto *Method : Methods) {
568
    // Don't record selectors for properties.
569
73
    if (Method->isPropertyAccessor())
570
48
      continue;
571
572
25
    StringRef Name = API.copyString(Method->getSelector().getAsString());
573
25
    StringRef USR = API.recordUSR(Method);
574
25
    PresumedLoc Loc =
575
25
        Context.getSourceManager().getPresumedLoc(Method->getLocation());
576
25
    DocComment Comment;
577
25
    if (auto *RawComment =
578
25
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method))
579
25
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
580
25
                                              Context.getDiagnostics());
581
582
    // Build declaration fragments, sub-heading, and signature for the method.
583
25
    DeclarationFragments Declaration =
584
25
        DeclarationFragmentsBuilder::getFragmentsForObjCMethod(Method);
585
25
    DeclarationFragments SubHeading =
586
25
        DeclarationFragmentsBuilder::getSubHeading(Method);
587
25
    FunctionSignature Signature =
588
25
        DeclarationFragmentsBuilder::getFunctionSignature(Method);
589
590
25
    API.addObjCMethod(Container, Name, USR, Loc, AvailabilitySet(Method),
591
25
                      Comment, Declaration, SubHeading, Signature,
592
25
                      Method->isInstanceMethod(), isInSystemHeader(Method));
593
25
  }
594
36
}
595
596
template <typename Derived>
597
void ExtractAPIVisitorBase<Derived>::recordObjCProperties(
598
    ObjCContainerRecord *Container,
599
48
    const ObjCContainerDecl::prop_range Properties) {
600
48
  for (const auto *Property : Properties) {
601
34
    StringRef Name = Property->getName();
602
34
    StringRef USR = API.recordUSR(Property);
603
34
    PresumedLoc Loc =
604
34
        Context.getSourceManager().getPresumedLoc(Property->getLocation());
605
34
    DocComment Comment;
606
34
    if (auto *RawComment =
607
34
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
608
24
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
609
24
                                              Context.getDiagnostics());
610
611
    // Build declaration fragments and sub-heading for the property.
612
34
    DeclarationFragments Declaration =
613
34
        DeclarationFragmentsBuilder::getFragmentsForObjCProperty(Property);
614
34
    DeclarationFragments SubHeading =
615
34
        DeclarationFragmentsBuilder::getSubHeading(Property);
616
617
34
    StringRef GetterName =
618
34
        API.copyString(Property->getGetterName().getAsString());
619
34
    StringRef SetterName =
620
34
        API.copyString(Property->getSetterName().getAsString());
621
622
    // Get the attributes for property.
623
34
    unsigned Attributes = ObjCPropertyRecord::NoAttr;
624
34
    if (Property->getPropertyAttributes() &
625
34
        ObjCPropertyAttribute::kind_readonly)
626
1
      Attributes |= ObjCPropertyRecord::ReadOnly;
627
628
34
    API.addObjCProperty(
629
34
        Container, Name, USR, Loc, AvailabilitySet(Property), Comment,
630
34
        Declaration, SubHeading,
631
34
        static_cast<ObjCPropertyRecord::AttributeKind>(Attributes), GetterName,
632
34
        SetterName, Property->isOptional(),
633
34
        !(Property->getPropertyAttributes() &
634
34
          ObjCPropertyAttribute::kind_class),
635
34
        isInSystemHeader(Property));
636
34
  }
637
48
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::recordObjCProperties(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::ObjCPropertyDecl> >)
Line
Count
Source
599
12
    const ObjCContainerDecl::prop_range Properties) {
600
12
  for (const auto *Property : Properties) {
601
10
    StringRef Name = Property->getName();
602
10
    StringRef USR = API.recordUSR(Property);
603
10
    PresumedLoc Loc =
604
10
        Context.getSourceManager().getPresumedLoc(Property->getLocation());
605
10
    DocComment Comment;
606
10
    if (auto *RawComment =
607
10
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
608
0
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
609
0
                                              Context.getDiagnostics());
610
611
    // Build declaration fragments and sub-heading for the property.
612
10
    DeclarationFragments Declaration =
613
10
        DeclarationFragmentsBuilder::getFragmentsForObjCProperty(Property);
614
10
    DeclarationFragments SubHeading =
615
10
        DeclarationFragmentsBuilder::getSubHeading(Property);
616
617
10
    StringRef GetterName =
618
10
        API.copyString(Property->getGetterName().getAsString());
619
10
    StringRef SetterName =
620
10
        API.copyString(Property->getSetterName().getAsString());
621
622
    // Get the attributes for property.
623
10
    unsigned Attributes = ObjCPropertyRecord::NoAttr;
624
10
    if (Property->getPropertyAttributes() &
625
10
        ObjCPropertyAttribute::kind_readonly)
626
1
      Attributes |= ObjCPropertyRecord::ReadOnly;
627
628
10
    API.addObjCProperty(
629
10
        Container, Name, USR, Loc, AvailabilitySet(Property), Comment,
630
10
        Declaration, SubHeading,
631
10
        static_cast<ObjCPropertyRecord::AttributeKind>(Attributes), GetterName,
632
10
        SetterName, Property->isOptional(),
633
10
        !(Property->getPropertyAttributes() &
634
10
          ObjCPropertyAttribute::kind_class),
635
10
        isInSystemHeader(Property));
636
10
  }
637
12
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::recordObjCProperties(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::ObjCPropertyDecl> >)
Line
Count
Source
599
36
    const ObjCContainerDecl::prop_range Properties) {
600
36
  for (const auto *Property : Properties) {
601
24
    StringRef Name = Property->getName();
602
24
    StringRef USR = API.recordUSR(Property);
603
24
    PresumedLoc Loc =
604
24
        Context.getSourceManager().getPresumedLoc(Property->getLocation());
605
24
    DocComment Comment;
606
24
    if (auto *RawComment =
607
24
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property))
608
24
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
609
24
                                              Context.getDiagnostics());
610
611
    // Build declaration fragments and sub-heading for the property.
612
24
    DeclarationFragments Declaration =
613
24
        DeclarationFragmentsBuilder::getFragmentsForObjCProperty(Property);
614
24
    DeclarationFragments SubHeading =
615
24
        DeclarationFragmentsBuilder::getSubHeading(Property);
616
617
24
    StringRef GetterName =
618
24
        API.copyString(Property->getGetterName().getAsString());
619
24
    StringRef SetterName =
620
24
        API.copyString(Property->getSetterName().getAsString());
621
622
    // Get the attributes for property.
623
24
    unsigned Attributes = ObjCPropertyRecord::NoAttr;
624
24
    if (Property->getPropertyAttributes() &
625
24
        ObjCPropertyAttribute::kind_readonly)
626
0
      Attributes |= ObjCPropertyRecord::ReadOnly;
627
628
24
    API.addObjCProperty(
629
24
        Container, Name, USR, Loc, AvailabilitySet(Property), Comment,
630
24
        Declaration, SubHeading,
631
24
        static_cast<ObjCPropertyRecord::AttributeKind>(Attributes), GetterName,
632
24
        SetterName, Property->isOptional(),
633
24
        !(Property->getPropertyAttributes() &
634
24
          ObjCPropertyAttribute::kind_class),
635
24
        isInSystemHeader(Property));
636
24
  }
637
36
}
638
639
template <typename Derived>
640
void ExtractAPIVisitorBase<Derived>::recordObjCInstanceVariables(
641
    ObjCContainerRecord *Container,
642
    const llvm::iterator_range<
643
        DeclContext::specific_decl_iterator<ObjCIvarDecl>>
644
33
        Ivars) {
645
33
  for (const auto *Ivar : Ivars) {
646
1
    StringRef Name = Ivar->getName();
647
1
    StringRef USR = API.recordUSR(Ivar);
648
1
    PresumedLoc Loc =
649
1
        Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
650
1
    DocComment Comment;
651
1
    if (auto *RawComment =
652
1
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
653
0
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
654
0
                                              Context.getDiagnostics());
655
656
    // Build declaration fragments and sub-heading for the instance variable.
657
1
    DeclarationFragments Declaration =
658
1
        DeclarationFragmentsBuilder::getFragmentsForField(Ivar);
659
1
    DeclarationFragments SubHeading =
660
1
        DeclarationFragmentsBuilder::getSubHeading(Ivar);
661
662
1
    ObjCInstanceVariableRecord::AccessControl Access =
663
1
        Ivar->getCanonicalAccessControl();
664
665
1
    API.addObjCInstanceVariable(Container, Name, USR, Loc,
666
1
                                AvailabilitySet(Ivar), Comment, Declaration,
667
1
                                SubHeading, Access, isInSystemHeader(Ivar));
668
1
  }
669
33
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::recordObjCInstanceVariables(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::ObjCIvarDecl> >)
Line
Count
Source
644
8
        Ivars) {
645
8
  for (const auto *Ivar : Ivars) {
646
1
    StringRef Name = Ivar->getName();
647
1
    StringRef USR = API.recordUSR(Ivar);
648
1
    PresumedLoc Loc =
649
1
        Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
650
1
    DocComment Comment;
651
1
    if (auto *RawComment =
652
1
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
653
0
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
654
0
                                              Context.getDiagnostics());
655
656
    // Build declaration fragments and sub-heading for the instance variable.
657
1
    DeclarationFragments Declaration =
658
1
        DeclarationFragmentsBuilder::getFragmentsForField(Ivar);
659
1
    DeclarationFragments SubHeading =
660
1
        DeclarationFragmentsBuilder::getSubHeading(Ivar);
661
662
1
    ObjCInstanceVariableRecord::AccessControl Access =
663
1
        Ivar->getCanonicalAccessControl();
664
665
1
    API.addObjCInstanceVariable(Container, Name, USR, Loc,
666
1
                                AvailabilitySet(Ivar), Comment, Declaration,
667
1
                                SubHeading, Access, isInSystemHeader(Ivar));
668
1
  }
669
8
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::recordObjCInstanceVariables(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::DeclContext::specific_decl_iterator<clang::ObjCIvarDecl> >)
Line
Count
Source
644
25
        Ivars) {
645
25
  for (const auto *Ivar : Ivars) {
646
0
    StringRef Name = Ivar->getName();
647
0
    StringRef USR = API.recordUSR(Ivar);
648
0
    PresumedLoc Loc =
649
0
        Context.getSourceManager().getPresumedLoc(Ivar->getLocation());
650
0
    DocComment Comment;
651
0
    if (auto *RawComment =
652
0
            getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar))
653
0
      Comment = RawComment->getFormattedLines(Context.getSourceManager(),
654
0
                                              Context.getDiagnostics());
655
656
    // Build declaration fragments and sub-heading for the instance variable.
657
0
    DeclarationFragments Declaration =
658
0
        DeclarationFragmentsBuilder::getFragmentsForField(Ivar);
659
0
    DeclarationFragments SubHeading =
660
0
        DeclarationFragmentsBuilder::getSubHeading(Ivar);
661
662
0
    ObjCInstanceVariableRecord::AccessControl Access =
663
0
        Ivar->getCanonicalAccessControl();
664
665
0
    API.addObjCInstanceVariable(Container, Name, USR, Loc,
666
0
                                AvailabilitySet(Ivar), Comment, Declaration,
667
0
                                SubHeading, Access, isInSystemHeader(Ivar));
668
0
  }
669
25
}
670
671
template <typename Derived>
672
void ExtractAPIVisitorBase<Derived>::recordObjCProtocols(
673
    ObjCContainerRecord *Container,
674
48
    ObjCInterfaceDecl::protocol_range Protocols) {
675
48
  for (const auto *Protocol : Protocols)
676
4
    Container->Protocols.emplace_back(Protocol->getName(),
677
4
                                      API.recordUSR(Protocol));
678
48
}
ExtractAPIConsumer.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::BatchExtractAPIVisitor>::recordObjCProtocols(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::ObjCProtocolDecl* const*>)
Line
Count
Source
674
12
    ObjCInterfaceDecl::protocol_range Protocols) {
675
12
  for (const auto *Protocol : Protocols)
676
4
    Container->Protocols.emplace_back(Protocol->getName(),
677
4
                                      API.recordUSR(Protocol));
678
12
}
CXExtractAPI.cpp:clang::extractapi::impl::ExtractAPIVisitorBase<(anonymous namespace)::LibClangExtractAPIVisitor>::recordObjCProtocols(clang::extractapi::ObjCContainerRecord*, llvm::iterator_range<clang::ObjCProtocolDecl* const*>)
Line
Count
Source
674
36
    ObjCInterfaceDecl::protocol_range Protocols) {
675
36
  for (const auto *Protocol : Protocols)
676
0
    Container->Protocols.emplace_back(Protocol->getName(),
677
0
                                      API.recordUSR(Protocol));
678
36
}
679
680
} // namespace impl
681
682
/// The RecursiveASTVisitor to traverse symbol declarations and collect API
683
/// information.
684
template <typename Derived = void>
685
class ExtractAPIVisitor
686
    : public impl::ExtractAPIVisitorBase<std::conditional_t<
687
          std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> {
688
  using Base = impl::ExtractAPIVisitorBase<std::conditional_t<
689
      std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>;
690
691
public:
692
45
  ExtractAPIVisitor(ASTContext &Context, APISet &API) : Base(Context, API) {}
ExtractAPIConsumer.cpp:clang::extractapi::ExtractAPIVisitor<(anonymous namespace)::BatchExtractAPIVisitor>::ExtractAPIVisitor(clang::ASTContext&, clang::extractapi::APISet&)
Line
Count
Source
692
26
  ExtractAPIVisitor(ASTContext &Context, APISet &API) : Base(Context, API) {}
CXExtractAPI.cpp:clang::extractapi::ExtractAPIVisitor<(anonymous namespace)::LibClangExtractAPIVisitor>::ExtractAPIVisitor(clang::ASTContext&, clang::extractapi::APISet&)
Line
Count
Source
692
19
  ExtractAPIVisitor(ASTContext &Context, APISet &API) : Base(Context, API) {}
693
694
49
  bool shouldDeclBeIncluded(const Decl *D) const { return true; }
695
114
  const RawComment *fetchRawCommentForDecl(const Decl *D) const {
696
114
    return this->Context.getRawCommentForDeclNoCache(D);
697
114
  }
698
};
699
700
} // namespace extractapi
701
} // namespace clang
702
703
#endif // LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H