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 |
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" |
22 | #include "clang/AST/ParentMapContext.h" |
23 | #include "clang/AST/RecursiveASTVisitor.h" |
24 | #include "clang/Basic/LLVM.h" |
25 | #include "clang/Basic/Module.h" |
26 | #include "clang/Basic/SourceManager.h" |
27 | #include "clang/Basic/Specifiers.h" |
28 | #include "clang/ExtractAPI/API.h" |
29 | #include "clang/ExtractAPI/DeclarationFragments.h" |
30 | #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" |
31 | #include "clang/Index/USRGeneration.h" |
32 | #include "llvm/ADT/SmallString.h" |
33 | #include "llvm/ADT/StringRef.h" |
34 | #include "llvm/Support/Casting.h" |
35 | #include <type_traits> |
36 | |
37 | namespace clang { |
38 | namespace extractapi { |
39 | namespace impl { |
40 | |
41 | template <typename Derived> |
42 | class : public RecursiveASTVisitor<Derived> { |
43 | protected: |
44 | (ASTContext &Context, APISet &API) |
45 | : Context(Context), API(API) {} |
46 | |
47 | public: |
48 | const APISet &() const { return API; } |
49 | |
50 | bool VisitVarDecl(const VarDecl *Decl); |
51 | |
52 | bool VisitFunctionDecl(const FunctionDecl *Decl); |
53 | |
54 | bool VisitEnumDecl(const EnumDecl *Decl); |
55 | |
56 | bool WalkUpFromFunctionDecl(const FunctionDecl *Decl); |
57 | |
58 | bool WalkUpFromRecordDecl(const RecordDecl *Decl); |
59 | |
60 | bool WalkUpFromCXXRecordDecl(const CXXRecordDecl *Decl); |
61 | |
62 | bool WalkUpFromCXXMethodDecl(const CXXMethodDecl *Decl); |
63 | |
64 | bool WalkUpFromClassTemplateSpecializationDecl( |
65 | const ClassTemplateSpecializationDecl *Decl); |
66 | |
67 | bool WalkUpFromClassTemplatePartialSpecializationDecl( |
68 | const ClassTemplatePartialSpecializationDecl *Decl); |
69 | |
70 | bool WalkUpFromVarTemplateDecl(const VarTemplateDecl *Decl); |
71 | |
72 | bool WalkUpFromVarTemplateSpecializationDecl( |
73 | const VarTemplateSpecializationDecl *Decl); |
74 | |
75 | bool WalkUpFromVarTemplatePartialSpecializationDecl( |
76 | const VarTemplatePartialSpecializationDecl *Decl); |
77 | |
78 | bool WalkUpFromFunctionTemplateDecl(const FunctionTemplateDecl *Decl); |
79 | |
80 | bool WalkUpFromNamespaceDecl(const NamespaceDecl *Decl); |
81 | |
82 | bool VisitNamespaceDecl(const NamespaceDecl *Decl); |
83 | |
84 | bool VisitRecordDecl(const RecordDecl *Decl); |
85 | |
86 | bool VisitCXXRecordDecl(const CXXRecordDecl *Decl); |
87 | |
88 | bool VisitCXXMethodDecl(const CXXMethodDecl *Decl); |
89 | |
90 | bool VisitFieldDecl(const FieldDecl *Decl); |
91 | |
92 | bool VisitCXXConversionDecl(const CXXConversionDecl *Decl); |
93 | |
94 | bool VisitCXXConstructorDecl(const CXXConstructorDecl *Decl); |
95 | |
96 | bool VisitCXXDestructorDecl(const CXXDestructorDecl *Decl); |
97 | |
98 | bool VisitConceptDecl(const ConceptDecl *Decl); |
99 | |
100 | bool VisitClassTemplateSpecializationDecl( |
101 | const ClassTemplateSpecializationDecl *Decl); |
102 | |
103 | bool VisitClassTemplatePartialSpecializationDecl( |
104 | const ClassTemplatePartialSpecializationDecl *Decl); |
105 | |
106 | bool VisitVarTemplateDecl(const VarTemplateDecl *Decl); |
107 | |
108 | bool |
109 | VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *Decl); |
110 | |
111 | bool VisitVarTemplatePartialSpecializationDecl( |
112 | const VarTemplatePartialSpecializationDecl *Decl); |
113 | |
114 | bool VisitFunctionTemplateDecl(const FunctionTemplateDecl *Decl); |
115 | |
116 | bool VisitObjCInterfaceDecl(const ObjCInterfaceDecl *Decl); |
117 | |
118 | bool VisitObjCProtocolDecl(const ObjCProtocolDecl *Decl); |
119 | |
120 | bool VisitTypedefNameDecl(const TypedefNameDecl *Decl); |
121 | |
122 | bool VisitObjCCategoryDecl(const ObjCCategoryDecl *Decl); |
123 | |
124 | bool (const Decl *Decl) const; |
125 | |
126 | const RawComment *(const Decl *Decl) const; |
127 | |
128 | protected: |
129 | /// Collect API information for the enum constants and associate with the |
130 | /// parent enum. |
131 | void recordEnumConstants(SymbolReference Container, |
132 | const EnumDecl::enumerator_range Constants); |
133 | |
134 | /// Collect API information for the Objective-C methods and associate with the |
135 | /// parent container. |
136 | void recordObjCMethods(ObjCContainerRecord *Container, |
137 | const ObjCContainerDecl::method_range Methods); |
138 | |
139 | void recordObjCProperties(ObjCContainerRecord *Container, |
140 | const ObjCContainerDecl::prop_range Properties); |
141 | |
142 | void recordObjCInstanceVariables( |
143 | ObjCContainerRecord *Container, |
144 | const llvm::iterator_range< |
145 | DeclContext::specific_decl_iterator<ObjCIvarDecl>> |
146 | Ivars); |
147 | |
148 | void recordObjCProtocols(ObjCContainerRecord *Container, |
149 | ObjCInterfaceDecl::protocol_range Protocols); |
150 | |
151 | ASTContext &; |
152 | APISet &; |
153 | |
154 | StringRef (const TagDecl *Decl) { |
155 | if (const auto *TypedefDecl = Decl->getTypedefNameForAnonDecl()) |
156 | return TypedefDecl->getName(); |
157 | |
158 | return {}; |
159 | } |
160 | |
161 | bool (const Decl *D) { |
162 | return Context.getSourceManager().isInSystemHeader(Loc: D->getLocation()); |
163 | } |
164 | |
165 | private: |
166 | Derived &() { |
167 | return *static_cast<Derived *>(this); |
168 | } |
169 | |
170 | protected: |
171 | SmallVector<SymbolReference> (const CXXRecordDecl *Decl) { |
172 | // FIXME: store AccessSpecifier given by inheritance |
173 | SmallVector<SymbolReference> Bases; |
174 | for (const auto &BaseSpecifier : Decl->bases()) { |
175 | // skip classes not inherited as public |
176 | if (BaseSpecifier.getAccessSpecifier() != AccessSpecifier::AS_public) |
177 | continue; |
178 | if (auto *BaseDecl = BaseSpecifier.getType()->getAsTagDecl()) { |
179 | Bases.emplace_back(createSymbolReferenceForDecl(D: *BaseDecl)); |
180 | } else { |
181 | SymbolReference BaseClass; |
182 | BaseClass.Name = API.copyString(String: BaseSpecifier.getType().getAsString( |
183 | Policy: Decl->getASTContext().getPrintingPolicy())); |
184 | |
185 | if (BaseSpecifier.getType().getTypePtr()->isTemplateTypeParmType()) { |
186 | if (auto *TTPTD = BaseSpecifier.getType() |
187 | ->getAs<TemplateTypeParmType>() |
188 | ->getDecl()) { |
189 | SmallString<128> USR; |
190 | index::generateUSRForDecl(D: TTPTD, Buf&: USR); |
191 | BaseClass.USR = API.copyString(String: USR); |
192 | BaseClass.Source = API.copyString(String: getOwningModuleName(D: *TTPTD)); |
193 | } |
194 | } |
195 | Bases.emplace_back(Args&: BaseClass); |
196 | } |
197 | } |
198 | return Bases; |
199 | } |
200 | |
201 | APIRecord::RecordKind (const CXXRecordDecl *Decl) { |
202 | if (Decl->isUnion()) |
203 | return APIRecord::RK_Union; |
204 | if (Decl->isStruct()) |
205 | return APIRecord::RK_Struct; |
206 | |
207 | return APIRecord::RK_CXXClass; |
208 | } |
209 | |
210 | StringRef (const Decl &D) { |
211 | if (auto *OwningModule = D.getImportedOwningModule()) |
212 | return OwningModule->Name; |
213 | |
214 | return {}; |
215 | } |
216 | |
217 | SymbolReference (const Decl &D) { |
218 | const auto *Context = cast_if_present<Decl>(Val: D.getDeclContext()); |
219 | |
220 | if (!Context || isa<TranslationUnitDecl>(Val: Context)) |
221 | return {}; |
222 | |
223 | return createSymbolReferenceForDecl(D: *Context); |
224 | } |
225 | |
226 | SymbolReference (const Decl &D) { |
227 | SmallString<128> USR; |
228 | index::generateUSRForDecl(D: &D, Buf&: USR); |
229 | |
230 | APIRecord *Record = API.findRecordForUSR(USR); |
231 | if (Record) |
232 | return SymbolReference(Record); |
233 | |
234 | StringRef Name; |
235 | if (auto *ND = dyn_cast<NamedDecl>(Val: &D)) |
236 | Name = ND->getName(); |
237 | |
238 | return API.createSymbolReference(Name, USR, Source: getOwningModuleName(D)); |
239 | } |
240 | |
241 | bool (const TagDecl &D) { |
242 | return D.getName().empty() && getTypedefName(Decl: &D).empty() && |
243 | D.isEmbeddedInDeclarator(); |
244 | } |
245 | |
246 | void (const DeclaratorDecl &D, |
247 | RecordContext *NewRecordContext) { |
248 | if (!NewRecordContext) |
249 | return; |
250 | auto *Tag = D.getType()->getAsTagDecl(); |
251 | SmallString<128> TagUSR; |
252 | clang::index::generateUSRForDecl(D: Tag, Buf&: TagUSR); |
253 | if (auto *Record = llvm::dyn_cast_if_present<TagRecord>( |
254 | Val: API.findRecordForUSR(USR: TagUSR))) { |
255 | if (Record->IsEmbeddedInVarDeclarator) |
256 | NewRecordContext->stealRecordChain(Other&: *Record); |
257 | } |
258 | } |
259 | }; |
260 | |
261 | template <typename Derived> |
262 | bool ExtractAPIVisitorBase<Derived>::(const VarDecl *Decl) { |
263 | // skip function parameters. |
264 | if (isa<ParmVarDecl>(Val: 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. |
273 | if (!Decl->isDefinedOutsideFunctionOrMethod()) |
274 | return true; |
275 | |
276 | // If this is a template but not specialization or instantiation, skip. |
277 | if (Decl->getASTContext().getTemplateOrSpecializationInfo(Var: Decl) && |
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; |
287 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
288 | PresumedLoc Loc = |
289 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
290 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
291 | DocComment ; |
292 | if (auto * = |
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 = |
299 | DeclarationFragmentsBuilder::getFragmentsForVar(Decl); |
300 | DeclarationFragments SubHeading = |
301 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
302 | if (Decl->isStaticDataMember()) { |
303 | auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl); |
304 | API.createRecord<StaticFieldRecord>( |
305 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
306 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, |
307 | SubHeading, Access, isInSystemHeader(D: Decl)); |
308 | } else { |
309 | // Add the global variable record to the API set. |
310 | auto *NewRecord = API.createRecord<GlobalVariableRecord>( |
311 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
312 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, |
313 | SubHeading, isInSystemHeader(D: 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(D: *Decl, NewRecordContext: NewRecord); |
318 | } |
319 | |
320 | return true; |
321 | } |
322 | |
323 | template <typename Derived> |
324 | bool ExtractAPIVisitorBase<Derived>::( |
325 | const FunctionDecl *Decl) { |
326 | if (const auto *Method = dyn_cast<CXXMethodDecl>(Val: 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(Node: *Method)) { |
333 | if (P.template get<CXXRecordDecl>()) |
334 | return true; |
335 | } |
336 | |
337 | // Skip ConstructorDecl and DestructorDecl. |
338 | if (isa<CXXConstructorDecl>(Val: Method) || isa<CXXDestructorDecl>(Val: Method)) |
339 | return true; |
340 | } |
341 | |
342 | // Skip templated functions that aren't processed here. |
343 | switch (Decl->getTemplatedKind()) { |
344 | case FunctionDecl::TK_NonTemplate: |
345 | case FunctionDecl::TK_DependentNonTemplate: |
346 | case FunctionDecl::TK_FunctionTemplateSpecialization: |
347 | break; |
348 | case FunctionDecl::TK_FunctionTemplate: |
349 | case FunctionDecl::TK_DependentFunctionTemplateSpecialization: |
350 | case FunctionDecl::TK_MemberSpecialization: |
351 | return true; |
352 | } |
353 | |
354 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
355 | return true; |
356 | |
357 | // Collect symbol information. |
358 | auto Name = Decl->getNameAsString(); |
359 | SmallString<128> USR; |
360 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
361 | PresumedLoc Loc = |
362 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
363 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
364 | DocComment ; |
365 | if (auto * = |
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 = |
372 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
373 | FunctionSignature Signature = |
374 | DeclarationFragmentsBuilder::getFunctionSignature(Function: Decl); |
375 | if (Decl->getTemplateSpecializationInfo()) |
376 | API.createRecord<GlobalFunctionTemplateSpecializationRecord>( |
377 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
378 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, |
379 | DeclarationFragmentsBuilder:: |
380 | getFragmentsForFunctionTemplateSpecialization(Decl), |
381 | SubHeading, Signature, isInSystemHeader(D: Decl)); |
382 | else |
383 | // Add the function record to the API set. |
384 | API.createRecord<GlobalFunctionRecord>( |
385 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
386 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, |
387 | DeclarationFragmentsBuilder::getFragmentsForFunction(Decl), SubHeading, |
388 | Signature, isInSystemHeader(D: Decl)); |
389 | return true; |
390 | } |
391 | |
392 | template <typename Derived> |
393 | bool ExtractAPIVisitorBase<Derived>::(const EnumDecl *Decl) { |
394 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
395 | return true; |
396 | |
397 | SmallString<128> USR; |
398 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
399 | PresumedLoc Loc = |
400 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
401 | DocComment ; |
402 | if (auto * = |
403 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
404 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
405 | Context.getDiagnostics()); |
406 | |
407 | // Build declaration fragments and sub-heading for the enum. |
408 | DeclarationFragments Declaration = |
409 | DeclarationFragmentsBuilder::getFragmentsForEnum(Decl); |
410 | DeclarationFragments SubHeading = |
411 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
412 | |
413 | // Collect symbol information. |
414 | SymbolReference ParentContainer; |
415 | |
416 | if (Decl->hasNameForLinkage()) { |
417 | StringRef Name = Decl->getName(); |
418 | if (Name.empty()) |
419 | Name = getTypedefName(Decl); |
420 | |
421 | auto *ER = API.createRecord<EnumRecord>( |
422 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
423 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
424 | SubHeading, isInSystemHeader(D: Decl), false); |
425 | ParentContainer = SymbolReference(ER); |
426 | } else { |
427 | // If this an anonymous enum then the parent scope of the constants is the |
428 | // top level namespace. |
429 | ParentContainer = {}; |
430 | } |
431 | |
432 | // Now collect information about the enumerators in this enum. |
433 | getDerivedExtractAPIVisitor().recordEnumConstants(ParentContainer, |
434 | Decl->enumerators()); |
435 | |
436 | return true; |
437 | } |
438 | |
439 | template <typename Derived> |
440 | bool ExtractAPIVisitorBase<Derived>::( |
441 | const FunctionDecl *Decl) { |
442 | getDerivedExtractAPIVisitor().VisitFunctionDecl(Decl); |
443 | return true; |
444 | } |
445 | |
446 | template <typename Derived> |
447 | bool ExtractAPIVisitorBase<Derived>::( |
448 | const RecordDecl *Decl) { |
449 | getDerivedExtractAPIVisitor().VisitRecordDecl(Decl); |
450 | return true; |
451 | } |
452 | |
453 | template <typename Derived> |
454 | bool ExtractAPIVisitorBase<Derived>::( |
455 | const CXXRecordDecl *Decl) { |
456 | getDerivedExtractAPIVisitor().VisitCXXRecordDecl(Decl); |
457 | return true; |
458 | } |
459 | |
460 | template <typename Derived> |
461 | bool ExtractAPIVisitorBase<Derived>::( |
462 | const CXXMethodDecl *Decl) { |
463 | getDerivedExtractAPIVisitor().VisitCXXMethodDecl(Decl); |
464 | return true; |
465 | } |
466 | |
467 | template <typename Derived> |
468 | bool ExtractAPIVisitorBase<Derived>::( |
469 | const ClassTemplateSpecializationDecl *Decl) { |
470 | getDerivedExtractAPIVisitor().VisitClassTemplateSpecializationDecl(Decl); |
471 | return true; |
472 | } |
473 | |
474 | template <typename Derived> |
475 | bool ExtractAPIVisitorBase<Derived>:: |
476 | ( |
477 | const ClassTemplatePartialSpecializationDecl *Decl) { |
478 | getDerivedExtractAPIVisitor().VisitClassTemplatePartialSpecializationDecl( |
479 | Decl); |
480 | return true; |
481 | } |
482 | |
483 | template <typename Derived> |
484 | bool ExtractAPIVisitorBase<Derived>::( |
485 | const VarTemplateDecl *Decl) { |
486 | getDerivedExtractAPIVisitor().VisitVarTemplateDecl(Decl); |
487 | return true; |
488 | } |
489 | |
490 | template <typename Derived> |
491 | bool ExtractAPIVisitorBase<Derived>::( |
492 | const VarTemplateSpecializationDecl *Decl) { |
493 | getDerivedExtractAPIVisitor().VisitVarTemplateSpecializationDecl(Decl); |
494 | return true; |
495 | } |
496 | |
497 | template <typename Derived> |
498 | bool ExtractAPIVisitorBase<Derived>:: |
499 | ( |
500 | const VarTemplatePartialSpecializationDecl *Decl) { |
501 | getDerivedExtractAPIVisitor().VisitVarTemplatePartialSpecializationDecl(Decl); |
502 | return true; |
503 | } |
504 | |
505 | template <typename Derived> |
506 | bool ExtractAPIVisitorBase<Derived>::( |
507 | const FunctionTemplateDecl *Decl) { |
508 | getDerivedExtractAPIVisitor().VisitFunctionTemplateDecl(Decl); |
509 | return true; |
510 | } |
511 | |
512 | template <typename Derived> |
513 | bool ExtractAPIVisitorBase<Derived>::( |
514 | const NamespaceDecl *Decl) { |
515 | getDerivedExtractAPIVisitor().VisitNamespaceDecl(Decl); |
516 | return true; |
517 | } |
518 | |
519 | template <typename Derived> |
520 | bool ExtractAPIVisitorBase<Derived>::( |
521 | const NamespaceDecl *Decl) { |
522 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
523 | return true; |
524 | if (Decl->isAnonymousNamespace()) |
525 | return true; |
526 | StringRef Name = Decl->getName(); |
527 | SmallString<128> USR; |
528 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
529 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
530 | PresumedLoc Loc = |
531 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
532 | DocComment ; |
533 | if (auto * = |
534 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
535 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
536 | Context.getDiagnostics()); |
537 | |
538 | // Build declaration fragments and sub-heading for the struct. |
539 | DeclarationFragments Declaration = |
540 | DeclarationFragmentsBuilder::getFragmentsForNamespace(Decl); |
541 | DeclarationFragments SubHeading = |
542 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
543 | API.createRecord<NamespaceRecord>( |
544 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
545 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, |
546 | SubHeading, isInSystemHeader(D: Decl)); |
547 | |
548 | return true; |
549 | } |
550 | |
551 | template <typename Derived> |
552 | bool ExtractAPIVisitorBase<Derived>::(const RecordDecl *Decl) { |
553 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
554 | return true; |
555 | |
556 | // Collect symbol information. |
557 | StringRef Name = Decl->getName(); |
558 | if (Name.empty()) |
559 | Name = getTypedefName(Decl); |
560 | |
561 | SmallString<128> USR; |
562 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
563 | PresumedLoc Loc = |
564 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
565 | DocComment ; |
566 | if (auto * = |
567 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
568 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
569 | Context.getDiagnostics()); |
570 | |
571 | // Build declaration fragments and sub-heading for the struct. |
572 | DeclarationFragments Declaration = |
573 | DeclarationFragmentsBuilder::getFragmentsForRecordDecl(Decl); |
574 | DeclarationFragments SubHeading = |
575 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
576 | |
577 | if (Decl->isUnion()) |
578 | API.createRecord<UnionRecord>( |
579 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
580 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
581 | SubHeading, isInSystemHeader(D: Decl), isEmbeddedInVarDeclarator(D: *Decl)); |
582 | else |
583 | API.createRecord<StructRecord>( |
584 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
585 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
586 | SubHeading, isInSystemHeader(D: Decl), isEmbeddedInVarDeclarator(D: *Decl)); |
587 | |
588 | return true; |
589 | } |
590 | |
591 | template <typename Derived> |
592 | bool ExtractAPIVisitorBase<Derived>::( |
593 | const CXXRecordDecl *Decl) { |
594 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) || |
595 | Decl->isImplicit()) |
596 | return true; |
597 | |
598 | StringRef Name = Decl->getName(); |
599 | if (Name.empty()) |
600 | Name = getTypedefName(Decl); |
601 | |
602 | SmallString<128> USR; |
603 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
604 | PresumedLoc Loc = |
605 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
606 | DocComment ; |
607 | if (auto * = |
608 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
609 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
610 | Context.getDiagnostics()); |
611 | DeclarationFragments Declaration = |
612 | DeclarationFragmentsBuilder::getFragmentsForCXXClass(Decl); |
613 | DeclarationFragments SubHeading = |
614 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
615 | |
616 | auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl); |
617 | |
618 | CXXClassRecord *Record; |
619 | if (Decl->getDescribedClassTemplate()) { |
620 | // Inject template fragments before class fragments. |
621 | Declaration.prepend( |
622 | Other: DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate( |
623 | Decl->getDescribedClassTemplate())); |
624 | Record = API.createRecord<ClassTemplateRecord>( |
625 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
626 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
627 | SubHeading, Template(Decl->getDescribedClassTemplate()), Access, |
628 | isInSystemHeader(D: Decl)); |
629 | } else { |
630 | Record = API.createRecord<CXXClassRecord>( |
631 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
632 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
633 | SubHeading, APIRecord::RecordKind::RK_CXXClass, Access, |
634 | isInSystemHeader(D: Decl), isEmbeddedInVarDeclarator(D: *Decl)); |
635 | } |
636 | |
637 | Record->KindForDisplay = getKindForDisplay(Decl); |
638 | Record->Bases = getBases(Decl); |
639 | |
640 | return true; |
641 | } |
642 | |
643 | template <typename Derived> |
644 | bool ExtractAPIVisitorBase<Derived>::( |
645 | const CXXMethodDecl *Decl) { |
646 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) || |
647 | Decl->isImplicit()) |
648 | return true; |
649 | |
650 | if (isa<CXXConversionDecl>(Val: Decl)) |
651 | return true; |
652 | if (isa<CXXConstructorDecl>(Val: Decl) || isa<CXXDestructorDecl>(Val: Decl)) |
653 | return true; |
654 | |
655 | SmallString<128> USR; |
656 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
657 | PresumedLoc Loc = |
658 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
659 | DocComment ; |
660 | if (auto * = |
661 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
662 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
663 | Context.getDiagnostics()); |
664 | DeclarationFragments SubHeading = |
665 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
666 | auto Access = DeclarationFragmentsBuilder::getAccessControl(Decl); |
667 | auto Signature = DeclarationFragmentsBuilder::getFunctionSignature(Function: Decl); |
668 | |
669 | if (FunctionTemplateDecl *TemplateDecl = |
670 | Decl->getDescribedFunctionTemplate()) { |
671 | API.createRecord<CXXMethodTemplateRecord>( |
672 | USR, Decl->getNameAsString(), createHierarchyInformationForDecl(D: *Decl), |
673 | Loc, AvailabilityInfo::createFromDecl(Decl), Comment, |
674 | DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate( |
675 | Decl: TemplateDecl), |
676 | SubHeading, DeclarationFragmentsBuilder::getFunctionSignature(Function: Decl), |
677 | DeclarationFragmentsBuilder::getAccessControl(Decl: TemplateDecl), |
678 | Template(TemplateDecl), isInSystemHeader(D: Decl)); |
679 | } else if (Decl->getTemplateSpecializationInfo()) |
680 | API.createRecord<CXXMethodTemplateSpecializationRecord>( |
681 | USR, Decl->getNameAsString(), createHierarchyInformationForDecl(D: *Decl), |
682 | Loc, AvailabilityInfo::createFromDecl(Decl), Comment, |
683 | DeclarationFragmentsBuilder:: |
684 | getFragmentsForFunctionTemplateSpecialization(Decl), |
685 | SubHeading, Signature, Access, isInSystemHeader(D: Decl)); |
686 | else if (Decl->isOverloadedOperator()) |
687 | API.createRecord<CXXInstanceMethodRecord>( |
688 | USR, Decl->getNameAsString(), createHierarchyInformationForDecl(D: *Decl), |
689 | Loc, AvailabilityInfo::createFromDecl(Decl), Comment, |
690 | DeclarationFragmentsBuilder::getFragmentsForOverloadedOperator(Decl), |
691 | SubHeading, Signature, Access, isInSystemHeader(D: Decl)); |
692 | else if (Decl->isStatic()) |
693 | API.createRecord<CXXStaticMethodRecord>( |
694 | USR, Decl->getNameAsString(), createHierarchyInformationForDecl(D: *Decl), |
695 | Loc, AvailabilityInfo::createFromDecl(Decl), Comment, |
696 | DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading, |
697 | Signature, Access, isInSystemHeader(D: Decl)); |
698 | else |
699 | API.createRecord<CXXInstanceMethodRecord>( |
700 | USR, Decl->getNameAsString(), createHierarchyInformationForDecl(D: *Decl), |
701 | Loc, AvailabilityInfo::createFromDecl(Decl), Comment, |
702 | DeclarationFragmentsBuilder::getFragmentsForCXXMethod(Decl), SubHeading, |
703 | Signature, Access, isInSystemHeader(D: Decl)); |
704 | |
705 | return true; |
706 | } |
707 | |
708 | template <typename Derived> |
709 | bool ExtractAPIVisitorBase<Derived>::( |
710 | const CXXConstructorDecl *Decl) { |
711 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) || |
712 | Decl->isImplicit()) |
713 | return true; |
714 | |
715 | auto Name = Decl->getNameAsString(); |
716 | SmallString<128> USR; |
717 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
718 | PresumedLoc Loc = |
719 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
720 | DocComment ; |
721 | if (auto * = |
722 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
723 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
724 | Context.getDiagnostics()); |
725 | |
726 | // Build declaration fragments, sub-heading, and signature for the method. |
727 | DeclarationFragments Declaration = |
728 | DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(Decl); |
729 | DeclarationFragments SubHeading = |
730 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
731 | FunctionSignature Signature = |
732 | DeclarationFragmentsBuilder::getFunctionSignature(Function: Decl); |
733 | AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); |
734 | |
735 | API.createRecord<CXXConstructorRecord>( |
736 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
737 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, |
738 | Signature, Access, isInSystemHeader(D: Decl)); |
739 | return true; |
740 | } |
741 | |
742 | template <typename Derived> |
743 | bool ExtractAPIVisitorBase<Derived>::( |
744 | const CXXDestructorDecl *Decl) { |
745 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) || |
746 | Decl->isImplicit()) |
747 | return true; |
748 | |
749 | auto Name = Decl->getNameAsString(); |
750 | SmallString<128> USR; |
751 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
752 | PresumedLoc Loc = |
753 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
754 | DocComment ; |
755 | if (auto * = |
756 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
757 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
758 | Context.getDiagnostics()); |
759 | |
760 | // Build declaration fragments, sub-heading, and signature for the method. |
761 | DeclarationFragments Declaration = |
762 | DeclarationFragmentsBuilder::getFragmentsForSpecialCXXMethod(Decl); |
763 | DeclarationFragments SubHeading = |
764 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
765 | FunctionSignature Signature = |
766 | DeclarationFragmentsBuilder::getFunctionSignature(Function: Decl); |
767 | AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); |
768 | API.createRecord<CXXDestructorRecord>( |
769 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
770 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, |
771 | Signature, Access, isInSystemHeader(D: Decl)); |
772 | return true; |
773 | } |
774 | |
775 | template <typename Derived> |
776 | bool ExtractAPIVisitorBase<Derived>::(const ConceptDecl *Decl) { |
777 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
778 | return true; |
779 | |
780 | StringRef Name = Decl->getName(); |
781 | SmallString<128> USR; |
782 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
783 | PresumedLoc Loc = |
784 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
785 | DocComment ; |
786 | if (auto * = |
787 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
788 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
789 | Context.getDiagnostics()); |
790 | DeclarationFragments Declaration = |
791 | DeclarationFragmentsBuilder::getFragmentsForConcept(Decl); |
792 | DeclarationFragments SubHeading = |
793 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
794 | API.createRecord<ConceptRecord>( |
795 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
796 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, |
797 | Template(Decl), isInSystemHeader(D: Decl)); |
798 | return true; |
799 | } |
800 | |
801 | template <typename Derived> |
802 | bool ExtractAPIVisitorBase<Derived>::( |
803 | const ClassTemplateSpecializationDecl *Decl) { |
804 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
805 | return true; |
806 | |
807 | StringRef Name = Decl->getName(); |
808 | SmallString<128> USR; |
809 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
810 | PresumedLoc Loc = |
811 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
812 | DocComment ; |
813 | if (auto * = |
814 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
815 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
816 | Context.getDiagnostics()); |
817 | DeclarationFragments Declaration = |
818 | DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization( |
819 | Decl); |
820 | DeclarationFragments SubHeading = |
821 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
822 | |
823 | auto *CTSR = API.createRecord<ClassTemplateSpecializationRecord>( |
824 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
825 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, |
826 | DeclarationFragmentsBuilder::getAccessControl(Decl), |
827 | isInSystemHeader(D: Decl)); |
828 | |
829 | CTSR->Bases = getBases(Decl); |
830 | |
831 | return true; |
832 | } |
833 | |
834 | template <typename Derived> |
835 | bool ExtractAPIVisitorBase<Derived>:: |
836 | ( |
837 | const ClassTemplatePartialSpecializationDecl *Decl) { |
838 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
839 | return true; |
840 | |
841 | StringRef Name = Decl->getName(); |
842 | SmallString<128> USR; |
843 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
844 | PresumedLoc Loc = |
845 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
846 | DocComment ; |
847 | if (auto * = |
848 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
849 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
850 | Context.getDiagnostics()); |
851 | DeclarationFragments Declaration = DeclarationFragmentsBuilder:: |
852 | getFragmentsForClassTemplatePartialSpecialization(Decl); |
853 | DeclarationFragments SubHeading = |
854 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
855 | auto *CTPSR = API.createRecord<ClassTemplatePartialSpecializationRecord>( |
856 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
857 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, |
858 | Template(Decl), DeclarationFragmentsBuilder::getAccessControl(Decl), |
859 | isInSystemHeader(D: Decl)); |
860 | |
861 | CTPSR->KindForDisplay = getKindForDisplay(Decl); |
862 | CTPSR->Bases = getBases(Decl); |
863 | |
864 | return true; |
865 | } |
866 | |
867 | template <typename Derived> |
868 | bool ExtractAPIVisitorBase<Derived>::( |
869 | const VarTemplateDecl *Decl) { |
870 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
871 | return true; |
872 | |
873 | // Collect symbol information. |
874 | StringRef Name = Decl->getName(); |
875 | SmallString<128> USR; |
876 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
877 | PresumedLoc Loc = |
878 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
879 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
880 | DocComment ; |
881 | if (auto * = |
882 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
883 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
884 | Context.getDiagnostics()); |
885 | |
886 | // Build declaration fragments and sub-heading for the variable. |
887 | DeclarationFragments Declaration; |
888 | Declaration |
889 | .append(Other: DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate( |
890 | Decl)) |
891 | .append(Other: DeclarationFragmentsBuilder::getFragmentsForVarTemplate( |
892 | Decl->getTemplatedDecl())); |
893 | // Inject template fragments before var fragments. |
894 | DeclarationFragments SubHeading = |
895 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
896 | |
897 | if (Decl->getDeclContext()->getDeclKind() == Decl::CXXRecord) |
898 | API.createRecord<CXXFieldTemplateRecord>( |
899 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
900 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
901 | SubHeading, DeclarationFragmentsBuilder::getAccessControl(Decl), |
902 | Template(Decl), isInSystemHeader(D: Decl)); |
903 | else |
904 | API.createRecord<GlobalVariableTemplateRecord>( |
905 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
906 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, |
907 | SubHeading, Template(Decl), isInSystemHeader(D: Decl)); |
908 | return true; |
909 | } |
910 | |
911 | template <typename Derived> |
912 | bool ExtractAPIVisitorBase<Derived>::( |
913 | const VarTemplateSpecializationDecl *Decl) { |
914 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
915 | return true; |
916 | |
917 | // Collect symbol information. |
918 | StringRef Name = Decl->getName(); |
919 | SmallString<128> USR; |
920 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
921 | PresumedLoc Loc = |
922 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
923 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
924 | DocComment ; |
925 | if (auto * = |
926 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
927 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
928 | Context.getDiagnostics()); |
929 | |
930 | // Build declaration fragments and sub-heading for the variable. |
931 | DeclarationFragments Declaration = |
932 | DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization( |
933 | Decl); |
934 | DeclarationFragments SubHeading = |
935 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
936 | API.createRecord<GlobalVariableTemplateSpecializationRecord>( |
937 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
938 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, |
939 | SubHeading, isInSystemHeader(D: Decl)); |
940 | return true; |
941 | } |
942 | |
943 | template <typename Derived> |
944 | bool ExtractAPIVisitorBase<Derived>::( |
945 | const VarTemplatePartialSpecializationDecl *Decl) { |
946 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
947 | return true; |
948 | |
949 | // Collect symbol information. |
950 | StringRef Name = Decl->getName(); |
951 | SmallString<128> USR; |
952 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
953 | PresumedLoc Loc = |
954 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
955 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
956 | DocComment ; |
957 | if (auto * = |
958 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
959 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
960 | Context.getDiagnostics()); |
961 | |
962 | // Build declaration fragments and sub-heading for the variable. |
963 | DeclarationFragments Declaration = DeclarationFragmentsBuilder:: |
964 | getFragmentsForVarTemplatePartialSpecialization(Decl); |
965 | DeclarationFragments SubHeading = |
966 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
967 | API.createRecord<GlobalVariableTemplatePartialSpecializationRecord>( |
968 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
969 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, |
970 | SubHeading, Template(Decl), isInSystemHeader(D: Decl)); |
971 | return true; |
972 | } |
973 | |
974 | template <typename Derived> |
975 | bool ExtractAPIVisitorBase<Derived>::( |
976 | const FunctionTemplateDecl *Decl) { |
977 | if (isa<CXXMethodDecl>(Val: Decl->getTemplatedDecl())) |
978 | return true; |
979 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
980 | return true; |
981 | |
982 | // Collect symbol information. |
983 | auto Name = Decl->getNameAsString(); |
984 | SmallString<128> USR; |
985 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
986 | PresumedLoc Loc = |
987 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
988 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
989 | DocComment ; |
990 | if (auto * = |
991 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
992 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
993 | Context.getDiagnostics()); |
994 | |
995 | DeclarationFragments SubHeading = |
996 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
997 | FunctionSignature Signature = |
998 | DeclarationFragmentsBuilder::getFunctionSignature( |
999 | Function: Decl->getTemplatedDecl()); |
1000 | API.createRecord<GlobalFunctionTemplateRecord>( |
1001 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1002 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, |
1003 | DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate(Decl), |
1004 | SubHeading, Signature, Template(Decl), isInSystemHeader(D: Decl)); |
1005 | |
1006 | return true; |
1007 | } |
1008 | |
1009 | template <typename Derived> |
1010 | bool ExtractAPIVisitorBase<Derived>::( |
1011 | const ObjCInterfaceDecl *Decl) { |
1012 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
1013 | return true; |
1014 | |
1015 | // Collect symbol information. |
1016 | StringRef Name = Decl->getName(); |
1017 | SmallString<128> USR; |
1018 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
1019 | PresumedLoc Loc = |
1020 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
1021 | LinkageInfo Linkage = Decl->getLinkageAndVisibility(); |
1022 | DocComment ; |
1023 | if (auto * = |
1024 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
1025 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1026 | Context.getDiagnostics()); |
1027 | |
1028 | // Build declaration fragments and sub-heading for the interface. |
1029 | DeclarationFragments Declaration = |
1030 | DeclarationFragmentsBuilder::getFragmentsForObjCInterface(Decl); |
1031 | DeclarationFragments SubHeading = |
1032 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
1033 | |
1034 | // Collect super class information. |
1035 | SymbolReference SuperClass; |
1036 | if (const auto *SuperClassDecl = Decl->getSuperClass()) |
1037 | SuperClass = createSymbolReferenceForDecl(D: *SuperClassDecl); |
1038 | |
1039 | auto *InterfaceRecord = API.createRecord<ObjCInterfaceRecord>( |
1040 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1041 | AvailabilityInfo::createFromDecl(Decl), Linkage, Comment, Declaration, |
1042 | SubHeading, SuperClass, isInSystemHeader(D: Decl)); |
1043 | |
1044 | // Record all methods (selectors). This doesn't include automatically |
1045 | // synthesized property methods. |
1046 | getDerivedExtractAPIVisitor().recordObjCMethods(InterfaceRecord, |
1047 | Decl->methods()); |
1048 | getDerivedExtractAPIVisitor().recordObjCProperties(InterfaceRecord, |
1049 | Decl->properties()); |
1050 | getDerivedExtractAPIVisitor().recordObjCInstanceVariables(InterfaceRecord, |
1051 | Decl->ivars()); |
1052 | getDerivedExtractAPIVisitor().recordObjCProtocols(InterfaceRecord, |
1053 | Decl->protocols()); |
1054 | |
1055 | return true; |
1056 | } |
1057 | |
1058 | template <typename Derived> |
1059 | bool ExtractAPIVisitorBase<Derived>::( |
1060 | const ObjCProtocolDecl *Decl) { |
1061 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
1062 | return true; |
1063 | |
1064 | // Collect symbol information. |
1065 | StringRef Name = Decl->getName(); |
1066 | SmallString<128> USR; |
1067 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
1068 | PresumedLoc Loc = |
1069 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
1070 | DocComment ; |
1071 | if (auto * = |
1072 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
1073 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1074 | Context.getDiagnostics()); |
1075 | |
1076 | // Build declaration fragments and sub-heading for the protocol. |
1077 | DeclarationFragments Declaration = |
1078 | DeclarationFragmentsBuilder::getFragmentsForObjCProtocol(Decl); |
1079 | DeclarationFragments SubHeading = |
1080 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
1081 | |
1082 | auto *ProtoRecord = API.createRecord<ObjCProtocolRecord>( |
1083 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1084 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, |
1085 | isInSystemHeader(D: Decl)); |
1086 | |
1087 | getDerivedExtractAPIVisitor().recordObjCMethods(ProtoRecord, Decl->methods()); |
1088 | getDerivedExtractAPIVisitor().recordObjCProperties(ProtoRecord, |
1089 | Decl->properties()); |
1090 | getDerivedExtractAPIVisitor().recordObjCProtocols(ProtoRecord, |
1091 | Decl->protocols()); |
1092 | |
1093 | return true; |
1094 | } |
1095 | |
1096 | template <typename Derived> |
1097 | bool ExtractAPIVisitorBase<Derived>::( |
1098 | const TypedefNameDecl *Decl) { |
1099 | // Skip ObjC Type Parameter for now. |
1100 | if (isa<ObjCTypeParamDecl>(Val: Decl)) |
1101 | return true; |
1102 | |
1103 | if (!Decl->isDefinedOutsideFunctionOrMethod()) |
1104 | return true; |
1105 | |
1106 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
1107 | return true; |
1108 | |
1109 | StringRef Name = Decl->getName(); |
1110 | |
1111 | // If the underlying type was defined as part of the typedef modify it's |
1112 | // fragments directly and pretend the typedef doesn't exist. |
1113 | if (auto *TagDecl = Decl->getUnderlyingType()->getAsTagDecl()) { |
1114 | if (TagDecl->isEmbeddedInDeclarator() && TagDecl->isCompleteDefinition() && |
1115 | Decl->getName() == TagDecl->getName()) { |
1116 | SmallString<128> TagUSR; |
1117 | index::generateUSRForDecl(D: TagDecl, Buf&: TagUSR); |
1118 | if (auto *Record = API.findRecordForUSR(USR: TagUSR)) { |
1119 | DeclarationFragments LeadingFragments; |
1120 | LeadingFragments.append(Spelling: "typedef" , |
1121 | Kind: DeclarationFragments::FragmentKind::Keyword); |
1122 | LeadingFragments.appendSpace(); |
1123 | Record->Declaration.removeTrailingSemicolon() |
1124 | .prepend(Other: std::move(LeadingFragments)) |
1125 | .append(Spelling: " { ... } " , Kind: DeclarationFragments::FragmentKind::Text) |
1126 | .append(Spelling: Name, Kind: DeclarationFragments::FragmentKind::Identifier) |
1127 | .appendSemicolon(); |
1128 | |
1129 | return true; |
1130 | } |
1131 | } |
1132 | } |
1133 | |
1134 | PresumedLoc Loc = |
1135 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
1136 | SmallString<128> USR; |
1137 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
1138 | DocComment ; |
1139 | if (auto * = |
1140 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
1141 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1142 | Context.getDiagnostics()); |
1143 | |
1144 | QualType Type = Decl->getUnderlyingType(); |
1145 | SymbolReference SymRef = |
1146 | TypedefUnderlyingTypeResolver(Context).getSymbolReferenceForType(Type, |
1147 | API); |
1148 | |
1149 | API.createRecord<TypedefRecord>( |
1150 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1151 | AvailabilityInfo::createFromDecl(Decl), Comment, |
1152 | DeclarationFragmentsBuilder::getFragmentsForTypedef(Decl), |
1153 | DeclarationFragmentsBuilder::getSubHeading(Decl), SymRef, |
1154 | isInSystemHeader(D: Decl)); |
1155 | |
1156 | return true; |
1157 | } |
1158 | |
1159 | template <typename Derived> |
1160 | bool ExtractAPIVisitorBase<Derived>::( |
1161 | const ObjCCategoryDecl *Decl) { |
1162 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
1163 | return true; |
1164 | |
1165 | StringRef Name = Decl->getName(); |
1166 | SmallString<128> USR; |
1167 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
1168 | PresumedLoc Loc = |
1169 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
1170 | DocComment ; |
1171 | if (auto * = |
1172 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
1173 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1174 | Context.getDiagnostics()); |
1175 | // Build declaration fragments and sub-heading for the category. |
1176 | DeclarationFragments Declaration = |
1177 | DeclarationFragmentsBuilder::getFragmentsForObjCCategory(Decl); |
1178 | DeclarationFragments SubHeading = |
1179 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
1180 | |
1181 | const ObjCInterfaceDecl *InterfaceDecl = Decl->getClassInterface(); |
1182 | SymbolReference Interface = createSymbolReferenceForDecl(D: *InterfaceDecl); |
1183 | |
1184 | auto *CategoryRecord = API.createRecord<ObjCCategoryRecord>( |
1185 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1186 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, SubHeading, |
1187 | Interface, isInSystemHeader(D: Decl)); |
1188 | |
1189 | getDerivedExtractAPIVisitor().recordObjCMethods(CategoryRecord, |
1190 | Decl->methods()); |
1191 | getDerivedExtractAPIVisitor().recordObjCProperties(CategoryRecord, |
1192 | Decl->properties()); |
1193 | getDerivedExtractAPIVisitor().recordObjCInstanceVariables(CategoryRecord, |
1194 | Decl->ivars()); |
1195 | getDerivedExtractAPIVisitor().recordObjCProtocols(CategoryRecord, |
1196 | Decl->protocols()); |
1197 | |
1198 | return true; |
1199 | } |
1200 | |
1201 | /// Collect API information for the enum constants and associate with the |
1202 | /// parent enum. |
1203 | template <typename Derived> |
1204 | void ExtractAPIVisitorBase<Derived>::( |
1205 | SymbolReference Container, const EnumDecl::enumerator_range Constants) { |
1206 | for (const auto *Constant : Constants) { |
1207 | // Collect symbol information. |
1208 | StringRef Name = Constant->getName(); |
1209 | SmallString<128> USR; |
1210 | index::generateUSRForDecl(D: Constant, Buf&: USR); |
1211 | PresumedLoc Loc = |
1212 | Context.getSourceManager().getPresumedLoc(Loc: Constant->getLocation()); |
1213 | DocComment ; |
1214 | if (auto * = |
1215 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Constant)) |
1216 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1217 | Context.getDiagnostics()); |
1218 | |
1219 | // Build declaration fragments and sub-heading for the enum constant. |
1220 | DeclarationFragments Declaration = |
1221 | DeclarationFragmentsBuilder::getFragmentsForEnumConstant(Constant); |
1222 | DeclarationFragments SubHeading = |
1223 | DeclarationFragmentsBuilder::getSubHeading(Constant); |
1224 | |
1225 | API.createRecord<EnumConstantRecord>( |
1226 | USR, Name, Container, Loc, AvailabilityInfo::createFromDecl(Decl: Constant), |
1227 | Comment, Declaration, SubHeading, isInSystemHeader(D: Constant)); |
1228 | } |
1229 | } |
1230 | |
1231 | template <typename Derived> |
1232 | bool ExtractAPIVisitorBase<Derived>::(const FieldDecl *Decl) { |
1233 | // ObjCIvars are handled separately |
1234 | if (isa<ObjCIvarDecl>(Val: Decl) || isa<ObjCAtDefsFieldDecl>(Val: Decl)) |
1235 | return true; |
1236 | |
1237 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl)) |
1238 | return true; |
1239 | |
1240 | // Collect symbol information. |
1241 | StringRef Name = Decl->getName(); |
1242 | SmallString<128> USR; |
1243 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
1244 | PresumedLoc Loc = |
1245 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
1246 | DocComment ; |
1247 | if (auto * = |
1248 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
1249 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1250 | Context.getDiagnostics()); |
1251 | |
1252 | // Build declaration fragments and sub-heading for the struct field. |
1253 | DeclarationFragments Declaration = |
1254 | DeclarationFragmentsBuilder::getFragmentsForField(Decl); |
1255 | DeclarationFragments SubHeading = |
1256 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
1257 | |
1258 | RecordContext *NewRecord = nullptr; |
1259 | if (isa<CXXRecordDecl>(Val: Decl->getDeclContext())) { |
1260 | AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); |
1261 | |
1262 | NewRecord = API.createRecord<CXXFieldRecord>( |
1263 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1264 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
1265 | SubHeading, Access, isInSystemHeader(D: Decl)); |
1266 | } else if (auto *RD = dyn_cast<RecordDecl>(Val: Decl->getDeclContext())) { |
1267 | if (RD->isUnion()) |
1268 | NewRecord = API.createRecord<UnionFieldRecord>( |
1269 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1270 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
1271 | SubHeading, isInSystemHeader(D: Decl)); |
1272 | else |
1273 | NewRecord = API.createRecord<StructFieldRecord>( |
1274 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1275 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
1276 | SubHeading, isInSystemHeader(D: Decl)); |
1277 | } |
1278 | |
1279 | // If this field has a non typedef'd anonymous tag type let's pretend the |
1280 | // type's child records are under us in the hierarchy. |
1281 | maybeMergeWithAnonymousTag(D: *Decl, NewRecordContext: NewRecord); |
1282 | |
1283 | return true; |
1284 | } |
1285 | |
1286 | template <typename Derived> |
1287 | bool ExtractAPIVisitorBase<Derived>::( |
1288 | const CXXConversionDecl *Decl) { |
1289 | if (!getDerivedExtractAPIVisitor().shouldDeclBeIncluded(Decl) || |
1290 | Decl->isImplicit()) |
1291 | return true; |
1292 | |
1293 | auto Name = Decl->getNameAsString(); |
1294 | SmallString<128> USR; |
1295 | index::generateUSRForDecl(D: Decl, Buf&: USR); |
1296 | PresumedLoc Loc = |
1297 | Context.getSourceManager().getPresumedLoc(Loc: Decl->getLocation()); |
1298 | DocComment ; |
1299 | if (auto * = |
1300 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Decl)) |
1301 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1302 | Context.getDiagnostics()); |
1303 | |
1304 | // Build declaration fragments, sub-heading, and signature for the method. |
1305 | DeclarationFragments Declaration = |
1306 | DeclarationFragmentsBuilder::getFragmentsForConversionFunction(Decl); |
1307 | DeclarationFragments SubHeading = |
1308 | DeclarationFragmentsBuilder::getSubHeading(Decl); |
1309 | FunctionSignature Signature = |
1310 | DeclarationFragmentsBuilder::getFunctionSignature(Function: Decl); |
1311 | AccessControl Access = DeclarationFragmentsBuilder::getAccessControl(Decl); |
1312 | |
1313 | if (Decl->isStatic()) |
1314 | API.createRecord<CXXStaticMethodRecord>( |
1315 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1316 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
1317 | SubHeading, Signature, Access, isInSystemHeader(D: Decl)); |
1318 | else |
1319 | API.createRecord<CXXInstanceMethodRecord>( |
1320 | USR, Name, createHierarchyInformationForDecl(D: *Decl), Loc, |
1321 | AvailabilityInfo::createFromDecl(Decl), Comment, Declaration, |
1322 | SubHeading, Signature, Access, isInSystemHeader(D: Decl)); |
1323 | |
1324 | return true; |
1325 | } |
1326 | |
1327 | /// Collect API information for the Objective-C methods and associate with the |
1328 | /// parent container. |
1329 | template <typename Derived> |
1330 | void ExtractAPIVisitorBase<Derived>::( |
1331 | ObjCContainerRecord *Container, |
1332 | const ObjCContainerDecl::method_range Methods) { |
1333 | for (const auto *Method : Methods) { |
1334 | // Don't record selectors for properties. |
1335 | if (Method->isPropertyAccessor()) |
1336 | continue; |
1337 | |
1338 | auto Name = Method->getSelector().getAsString(); |
1339 | SmallString<128> USR; |
1340 | index::generateUSRForDecl(D: Method, Buf&: USR); |
1341 | PresumedLoc Loc = |
1342 | Context.getSourceManager().getPresumedLoc(Loc: Method->getLocation()); |
1343 | DocComment ; |
1344 | if (auto * = |
1345 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Method)) |
1346 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1347 | Context.getDiagnostics()); |
1348 | |
1349 | // Build declaration fragments, sub-heading, and signature for the method. |
1350 | DeclarationFragments Declaration = |
1351 | DeclarationFragmentsBuilder::getFragmentsForObjCMethod(Method); |
1352 | DeclarationFragments SubHeading = |
1353 | DeclarationFragmentsBuilder::getSubHeading(Method); |
1354 | FunctionSignature Signature = |
1355 | DeclarationFragmentsBuilder::getFunctionSignature(Function: Method); |
1356 | |
1357 | if (Method->isInstanceMethod()) |
1358 | API.createRecord<ObjCInstanceMethodRecord>( |
1359 | USR, Name, createHierarchyInformationForDecl(D: *Method), Loc, |
1360 | AvailabilityInfo::createFromDecl(Decl: Method), Comment, Declaration, |
1361 | SubHeading, Signature, isInSystemHeader(D: Method)); |
1362 | else |
1363 | API.createRecord<ObjCClassMethodRecord>( |
1364 | USR, Name, createHierarchyInformationForDecl(D: *Method), Loc, |
1365 | AvailabilityInfo::createFromDecl(Decl: Method), Comment, Declaration, |
1366 | SubHeading, Signature, isInSystemHeader(D: Method)); |
1367 | } |
1368 | } |
1369 | |
1370 | template <typename Derived> |
1371 | void ExtractAPIVisitorBase<Derived>::( |
1372 | ObjCContainerRecord *Container, |
1373 | const ObjCContainerDecl::prop_range Properties) { |
1374 | for (const auto *Property : Properties) { |
1375 | StringRef Name = Property->getName(); |
1376 | SmallString<128> USR; |
1377 | index::generateUSRForDecl(D: Property, Buf&: USR); |
1378 | PresumedLoc Loc = |
1379 | Context.getSourceManager().getPresumedLoc(Loc: Property->getLocation()); |
1380 | DocComment ; |
1381 | if (auto * = |
1382 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Property)) |
1383 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1384 | Context.getDiagnostics()); |
1385 | |
1386 | // Build declaration fragments and sub-heading for the property. |
1387 | DeclarationFragments Declaration = |
1388 | DeclarationFragmentsBuilder::getFragmentsForObjCProperty(Property); |
1389 | DeclarationFragments SubHeading = |
1390 | DeclarationFragmentsBuilder::getSubHeading(Property); |
1391 | |
1392 | auto GetterName = Property->getGetterName().getAsString(); |
1393 | auto SetterName = Property->getSetterName().getAsString(); |
1394 | |
1395 | // Get the attributes for property. |
1396 | unsigned Attributes = ObjCPropertyRecord::NoAttr; |
1397 | if (Property->getPropertyAttributes() & |
1398 | ObjCPropertyAttribute::kind_readonly) |
1399 | Attributes |= ObjCPropertyRecord::ReadOnly; |
1400 | |
1401 | if (Property->getPropertyAttributes() & ObjCPropertyAttribute::kind_class) |
1402 | API.createRecord<ObjCClassPropertyRecord>( |
1403 | USR, Name, createHierarchyInformationForDecl(D: *Property), Loc, |
1404 | AvailabilityInfo::createFromDecl(Decl: Property), Comment, Declaration, |
1405 | SubHeading, |
1406 | static_cast<ObjCPropertyRecord::AttributeKind>(Attributes), |
1407 | GetterName, SetterName, Property->isOptional(), |
1408 | isInSystemHeader(D: Property)); |
1409 | else |
1410 | API.createRecord<ObjCInstancePropertyRecord>( |
1411 | USR, Name, createHierarchyInformationForDecl(D: *Property), Loc, |
1412 | AvailabilityInfo::createFromDecl(Decl: Property), Comment, Declaration, |
1413 | SubHeading, |
1414 | static_cast<ObjCPropertyRecord::AttributeKind>(Attributes), |
1415 | GetterName, SetterName, Property->isOptional(), |
1416 | isInSystemHeader(D: Property)); |
1417 | } |
1418 | } |
1419 | |
1420 | template <typename Derived> |
1421 | void ExtractAPIVisitorBase<Derived>::( |
1422 | ObjCContainerRecord *Container, |
1423 | const llvm::iterator_range< |
1424 | DeclContext::specific_decl_iterator<ObjCIvarDecl>> |
1425 | Ivars) { |
1426 | for (const auto *Ivar : Ivars) { |
1427 | StringRef Name = Ivar->getName(); |
1428 | SmallString<128> USR; |
1429 | index::generateUSRForDecl(D: Ivar, Buf&: USR); |
1430 | |
1431 | PresumedLoc Loc = |
1432 | Context.getSourceManager().getPresumedLoc(Loc: Ivar->getLocation()); |
1433 | DocComment ; |
1434 | if (auto * = |
1435 | getDerivedExtractAPIVisitor().fetchRawCommentForDecl(Ivar)) |
1436 | Comment = RawComment->getFormattedLines(Context.getSourceManager(), |
1437 | Context.getDiagnostics()); |
1438 | |
1439 | // Build declaration fragments and sub-heading for the instance variable. |
1440 | DeclarationFragments Declaration = |
1441 | DeclarationFragmentsBuilder::getFragmentsForField(Ivar); |
1442 | DeclarationFragments SubHeading = |
1443 | DeclarationFragmentsBuilder::getSubHeading(Ivar); |
1444 | |
1445 | API.createRecord<ObjCInstanceVariableRecord>( |
1446 | USR, Name, createHierarchyInformationForDecl(D: *Ivar), Loc, |
1447 | AvailabilityInfo::createFromDecl(Decl: Ivar), Comment, Declaration, |
1448 | SubHeading, isInSystemHeader(D: Ivar)); |
1449 | } |
1450 | } |
1451 | |
1452 | template <typename Derived> |
1453 | void ExtractAPIVisitorBase<Derived>::( |
1454 | ObjCContainerRecord *Container, |
1455 | ObjCInterfaceDecl::protocol_range Protocols) { |
1456 | for (const auto *Protocol : Protocols) |
1457 | Container->Protocols.emplace_back(createSymbolReferenceForDecl(D: *Protocol)); |
1458 | } |
1459 | |
1460 | } // namespace impl |
1461 | |
1462 | /// The RecursiveASTVisitor to traverse symbol declarations and collect API |
1463 | /// information. |
1464 | template <typename Derived = void> |
1465 | class |
1466 | : public impl::ExtractAPIVisitorBase<std::conditional_t< |
1467 | std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>> { |
1468 | using = impl::ExtractAPIVisitorBase<std::conditional_t< |
1469 | std::is_same_v<Derived, void>, ExtractAPIVisitor<>, Derived>>; |
1470 | |
1471 | public: |
1472 | (ASTContext &Context, APISet &API) : Base(Context, API) {} |
1473 | |
1474 | bool (const Decl *D) const { return true; } |
1475 | const RawComment *(const Decl *D) const { |
1476 | if (const auto * = this->Context.getRawCommentForDeclNoCache(D)) |
1477 | return Comment; |
1478 | |
1479 | if (const auto *Declarator = dyn_cast<DeclaratorDecl>(Val: D)) { |
1480 | const auto *TagTypeDecl = Declarator->getType()->getAsTagDecl(); |
1481 | if (TagTypeDecl && TagTypeDecl->isEmbeddedInDeclarator() && |
1482 | TagTypeDecl->isCompleteDefinition()) |
1483 | return this->Context.getRawCommentForDeclNoCache(TagTypeDecl); |
1484 | } |
1485 | |
1486 | return nullptr; |
1487 | } |
1488 | }; |
1489 | |
1490 | } // namespace extractapi |
1491 | } // namespace clang |
1492 | |
1493 | #endif // LLVM_CLANG_EXTRACTAPI_EXTRACT_API_VISITOR_H |
1494 | |