1//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
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// This file defines routines for manipulating CXCursors. It should be the
10// only file that has internal knowledge of the encoding of the data in
11// CXCursor.
12//
13//===----------------------------------------------------------------------===//
14
15#include "CXCursor.h"
16#include "CXString.h"
17#include "CXTranslationUnit.h"
18#include "CXType.h"
19#include "clang-c/Index.h"
20#include "clang/AST/Attr.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclCXX.h"
23#include "clang/AST/DeclObjC.h"
24#include "clang/AST/DeclTemplate.h"
25#include "clang/AST/Expr.h"
26#include "clang/AST/ExprCXX.h"
27#include "clang/AST/ExprObjC.h"
28#include "clang/Frontend/ASTUnit.h"
29#include "llvm/Support/ErrorHandling.h"
30
31using namespace clang;
32using namespace cxcursor;
33
34CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU) {
35 assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
36 CXCursor C = {.kind: K, .xdata: 0, .data: {nullptr, nullptr, TU}};
37 return C;
38}
39
40static CXCursorKind GetCursorKind(const Attr *A) {
41 assert(A && "Invalid arguments!");
42 switch (A->getKind()) {
43 default:
44 break;
45 case attr::IBAction:
46 return CXCursor_IBActionAttr;
47 case attr::IBOutlet:
48 return CXCursor_IBOutletAttr;
49 case attr::IBOutletCollection:
50 return CXCursor_IBOutletCollectionAttr;
51 case attr::Final:
52 return CXCursor_CXXFinalAttr;
53 case attr::Override:
54 return CXCursor_CXXOverrideAttr;
55 case attr::Annotate:
56 return CXCursor_AnnotateAttr;
57 case attr::AsmLabel:
58 return CXCursor_AsmLabelAttr;
59 case attr::Packed:
60 return CXCursor_PackedAttr;
61 case attr::Pure:
62 return CXCursor_PureAttr;
63 case attr::Const:
64 return CXCursor_ConstAttr;
65 case attr::NoDuplicate:
66 return CXCursor_NoDuplicateAttr;
67 case attr::CUDAConstant:
68 return CXCursor_CUDAConstantAttr;
69 case attr::CUDADevice:
70 return CXCursor_CUDADeviceAttr;
71 case attr::CUDAGlobal:
72 return CXCursor_CUDAGlobalAttr;
73 case attr::CUDAHost:
74 return CXCursor_CUDAHostAttr;
75 case attr::CUDAShared:
76 return CXCursor_CUDASharedAttr;
77 case attr::Visibility:
78 return CXCursor_VisibilityAttr;
79 case attr::DLLExport:
80 return CXCursor_DLLExport;
81 case attr::DLLImport:
82 return CXCursor_DLLImport;
83 case attr::NSReturnsRetained:
84 return CXCursor_NSReturnsRetained;
85 case attr::NSReturnsNotRetained:
86 return CXCursor_NSReturnsNotRetained;
87 case attr::NSReturnsAutoreleased:
88 return CXCursor_NSReturnsAutoreleased;
89 case attr::NSConsumesSelf:
90 return CXCursor_NSConsumesSelf;
91 case attr::NSConsumed:
92 return CXCursor_NSConsumed;
93 case attr::ObjCException:
94 return CXCursor_ObjCException;
95 case attr::ObjCNSObject:
96 return CXCursor_ObjCNSObject;
97 case attr::ObjCIndependentClass:
98 return CXCursor_ObjCIndependentClass;
99 case attr::ObjCPreciseLifetime:
100 return CXCursor_ObjCPreciseLifetime;
101 case attr::ObjCReturnsInnerPointer:
102 return CXCursor_ObjCReturnsInnerPointer;
103 case attr::ObjCRequiresSuper:
104 return CXCursor_ObjCRequiresSuper;
105 case attr::ObjCRootClass:
106 return CXCursor_ObjCRootClass;
107 case attr::ObjCSubclassingRestricted:
108 return CXCursor_ObjCSubclassingRestricted;
109 case attr::ObjCExplicitProtocolImpl:
110 return CXCursor_ObjCExplicitProtocolImpl;
111 case attr::ObjCDesignatedInitializer:
112 return CXCursor_ObjCDesignatedInitializer;
113 case attr::ObjCRuntimeVisible:
114 return CXCursor_ObjCRuntimeVisible;
115 case attr::ObjCBoxable:
116 return CXCursor_ObjCBoxable;
117 case attr::FlagEnum:
118 return CXCursor_FlagEnum;
119 case attr::Convergent:
120 return CXCursor_ConvergentAttr;
121 case attr::WarnUnused:
122 return CXCursor_WarnUnusedAttr;
123 case attr::WarnUnusedResult:
124 return CXCursor_WarnUnusedResultAttr;
125 case attr::Aligned:
126 return CXCursor_AlignedAttr;
127 }
128
129 return CXCursor_UnexposedAttr;
130}
131
132CXCursor cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent,
133 CXTranslationUnit TU) {
134 assert(A && Parent && TU && "Invalid arguments!");
135 CXCursor C = {.kind: GetCursorKind(A), .xdata: 0, .data: {Parent, A, TU}};
136 return C;
137}
138
139CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
140 SourceRange RegionOfInterest,
141 bool FirstInDeclGroup) {
142 assert(D && TU && "Invalid arguments!");
143
144 CXCursorKind K = getCursorKindForDecl(D);
145
146 if (K == CXCursor_ObjCClassMethodDecl ||
147 K == CXCursor_ObjCInstanceMethodDecl) {
148 int SelectorIdIndex = -1;
149 // Check if cursor points to a selector id.
150 if (RegionOfInterest.isValid() &&
151 RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
152 SmallVector<SourceLocation, 16> SelLocs;
153 cast<ObjCMethodDecl>(Val: D)->getSelectorLocs(SelLocs);
154 SmallVectorImpl<SourceLocation>::iterator I =
155 llvm::find(Range&: SelLocs, Val: RegionOfInterest.getBegin());
156 if (I != SelLocs.end())
157 SelectorIdIndex = I - SelLocs.begin();
158 }
159 CXCursor C = {.kind: K,
160 .xdata: SelectorIdIndex,
161 .data: {D, (void *)(intptr_t)(FirstInDeclGroup ? 1 : 0), TU}};
162 return C;
163 }
164
165 CXCursor C = {.kind: K, .xdata: 0, .data: {D, (void *)(intptr_t)(FirstInDeclGroup ? 1 : 0), TU}};
166 return C;
167}
168
169CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
170 CXTranslationUnit TU,
171 SourceRange RegionOfInterest) {
172 assert(S && TU && "Invalid arguments!");
173 CXCursorKind K = CXCursor_NotImplemented;
174
175 switch (S->getStmtClass()) {
176 case Stmt::NoStmtClass:
177 break;
178
179 case Stmt::CaseStmtClass:
180 K = CXCursor_CaseStmt;
181 break;
182
183 case Stmt::DefaultStmtClass:
184 K = CXCursor_DefaultStmt;
185 break;
186
187 case Stmt::IfStmtClass:
188 K = CXCursor_IfStmt;
189 break;
190
191 case Stmt::SwitchStmtClass:
192 K = CXCursor_SwitchStmt;
193 break;
194
195 case Stmt::WhileStmtClass:
196 K = CXCursor_WhileStmt;
197 break;
198
199 case Stmt::DoStmtClass:
200 K = CXCursor_DoStmt;
201 break;
202
203 case Stmt::ForStmtClass:
204 K = CXCursor_ForStmt;
205 break;
206
207 case Stmt::GotoStmtClass:
208 K = CXCursor_GotoStmt;
209 break;
210
211 case Stmt::IndirectGotoStmtClass:
212 K = CXCursor_IndirectGotoStmt;
213 break;
214
215 case Stmt::ContinueStmtClass:
216 K = CXCursor_ContinueStmt;
217 break;
218
219 case Stmt::BreakStmtClass:
220 K = CXCursor_BreakStmt;
221 break;
222
223 case Stmt::ReturnStmtClass:
224 K = CXCursor_ReturnStmt;
225 break;
226
227 // Not exposed for now because '_Defer' is currently just a TS.
228 case Stmt::DeferStmtClass:
229 K = CXCursor_UnexposedStmt;
230 break;
231
232 case Stmt::GCCAsmStmtClass:
233 K = CXCursor_GCCAsmStmt;
234 break;
235
236 case Stmt::MSAsmStmtClass:
237 K = CXCursor_MSAsmStmt;
238 break;
239
240 case Stmt::ObjCAtTryStmtClass:
241 K = CXCursor_ObjCAtTryStmt;
242 break;
243
244 case Stmt::ObjCAtCatchStmtClass:
245 K = CXCursor_ObjCAtCatchStmt;
246 break;
247
248 case Stmt::ObjCAtFinallyStmtClass:
249 K = CXCursor_ObjCAtFinallyStmt;
250 break;
251
252 case Stmt::ObjCAtThrowStmtClass:
253 K = CXCursor_ObjCAtThrowStmt;
254 break;
255
256 case Stmt::ObjCAtSynchronizedStmtClass:
257 K = CXCursor_ObjCAtSynchronizedStmt;
258 break;
259
260 case Stmt::ObjCAutoreleasePoolStmtClass:
261 K = CXCursor_ObjCAutoreleasePoolStmt;
262 break;
263
264 case Stmt::ObjCForCollectionStmtClass:
265 K = CXCursor_ObjCForCollectionStmt;
266 break;
267
268 case Stmt::CXXCatchStmtClass:
269 K = CXCursor_CXXCatchStmt;
270 break;
271
272 case Stmt::CXXTryStmtClass:
273 K = CXCursor_CXXTryStmt;
274 break;
275
276 case Stmt::CXXForRangeStmtClass:
277 K = CXCursor_CXXForRangeStmt;
278 break;
279
280 case Stmt::SEHTryStmtClass:
281 K = CXCursor_SEHTryStmt;
282 break;
283
284 case Stmt::SEHExceptStmtClass:
285 K = CXCursor_SEHExceptStmt;
286 break;
287
288 case Stmt::SEHFinallyStmtClass:
289 K = CXCursor_SEHFinallyStmt;
290 break;
291
292 case Stmt::SEHLeaveStmtClass:
293 K = CXCursor_SEHLeaveStmt;
294 break;
295
296 case Stmt::CoroutineBodyStmtClass:
297 case Stmt::CoreturnStmtClass:
298 K = CXCursor_UnexposedStmt;
299 break;
300
301 case Stmt::ArrayTypeTraitExprClass:
302 case Stmt::AsTypeExprClass:
303 case Stmt::AtomicExprClass:
304 case Stmt::BinaryConditionalOperatorClass:
305 case Stmt::TypeTraitExprClass:
306 case Stmt::CoawaitExprClass:
307 case Stmt::DependentCoawaitExprClass:
308 case Stmt::CoyieldExprClass:
309 case Stmt::CXXBindTemporaryExprClass:
310 case Stmt::CXXDefaultArgExprClass:
311 case Stmt::CXXDefaultInitExprClass:
312 case Stmt::CXXFoldExprClass:
313 case Stmt::CXXRewrittenBinaryOperatorClass:
314 case Stmt::CXXStdInitializerListExprClass:
315 case Stmt::CXXScalarValueInitExprClass:
316 case Stmt::CXXUuidofExprClass:
317 case Stmt::ChooseExprClass:
318 case Stmt::DesignatedInitExprClass:
319 case Stmt::DesignatedInitUpdateExprClass:
320 case Stmt::ArrayInitLoopExprClass:
321 case Stmt::ArrayInitIndexExprClass:
322 case Stmt::ExprWithCleanupsClass:
323 case Stmt::ExpressionTraitExprClass:
324 case Stmt::ExtVectorElementExprClass:
325 case Stmt::ImplicitCastExprClass:
326 case Stmt::ImplicitValueInitExprClass:
327 case Stmt::NoInitExprClass:
328 case Stmt::MaterializeTemporaryExprClass:
329 case Stmt::ObjCIndirectCopyRestoreExprClass:
330 case Stmt::OffsetOfExprClass:
331 case Stmt::ParenListExprClass:
332 case Stmt::PredefinedExprClass:
333 case Stmt::ShuffleVectorExprClass:
334 case Stmt::SourceLocExprClass:
335 case Stmt::ConvertVectorExprClass:
336 case Stmt::VAArgExprClass:
337 case Stmt::ObjCArrayLiteralClass:
338 case Stmt::ObjCDictionaryLiteralClass:
339 case Stmt::ObjCBoxedExprClass:
340 case Stmt::ObjCSubscriptRefExprClass:
341 case Stmt::RecoveryExprClass:
342 case Stmt::SYCLUniqueStableNameExprClass:
343 case Stmt::EmbedExprClass:
344 case Stmt::HLSLOutArgExprClass:
345 case Stmt::OpenACCAsteriskSizeExprClass:
346 K = CXCursor_UnexposedExpr;
347 break;
348
349 case Stmt::OpaqueValueExprClass:
350 if (Expr *Src = cast<OpaqueValueExpr>(Val: S)->getSourceExpr())
351 return MakeCXCursor(S: Src, Parent, TU, RegionOfInterest);
352 K = CXCursor_UnexposedExpr;
353 break;
354
355 case Stmt::PseudoObjectExprClass:
356 return MakeCXCursor(S: cast<PseudoObjectExpr>(Val: S)->getSyntacticForm(), Parent,
357 TU, RegionOfInterest);
358
359 case Stmt::CompoundStmtClass:
360 K = CXCursor_CompoundStmt;
361 break;
362
363 case Stmt::NullStmtClass:
364 K = CXCursor_NullStmt;
365 break;
366
367 case Stmt::LabelStmtClass:
368 K = CXCursor_LabelStmt;
369 break;
370
371 case Stmt::AttributedStmtClass:
372 K = CXCursor_UnexposedStmt;
373 break;
374
375 case Stmt::DeclStmtClass:
376 K = CXCursor_DeclStmt;
377 break;
378
379 case Stmt::CapturedStmtClass:
380 K = CXCursor_UnexposedStmt;
381 break;
382
383 case Stmt::SYCLKernelCallStmtClass:
384 K = CXCursor_UnexposedStmt;
385 break;
386
387 case Stmt::IntegerLiteralClass:
388 K = CXCursor_IntegerLiteral;
389 break;
390
391 case Stmt::FixedPointLiteralClass:
392 K = CXCursor_FixedPointLiteral;
393 break;
394
395 case Stmt::FloatingLiteralClass:
396 K = CXCursor_FloatingLiteral;
397 break;
398
399 case Stmt::ImaginaryLiteralClass:
400 K = CXCursor_ImaginaryLiteral;
401 break;
402
403 case Stmt::StringLiteralClass:
404 K = CXCursor_StringLiteral;
405 break;
406
407 case Stmt::CharacterLiteralClass:
408 K = CXCursor_CharacterLiteral;
409 break;
410
411 case Stmt::ConstantExprClass:
412 return MakeCXCursor(S: cast<ConstantExpr>(Val: S)->getSubExpr(), Parent, TU,
413 RegionOfInterest);
414
415 case Stmt::ParenExprClass:
416 K = CXCursor_ParenExpr;
417 break;
418
419 case Stmt::UnaryOperatorClass:
420 K = CXCursor_UnaryOperator;
421 break;
422
423 case Stmt::UnaryExprOrTypeTraitExprClass:
424 case Stmt::CXXNoexceptExprClass:
425 K = CXCursor_UnaryExpr;
426 break;
427
428 case Stmt::MSPropertySubscriptExprClass:
429 case Stmt::ArraySubscriptExprClass:
430 K = CXCursor_ArraySubscriptExpr;
431 break;
432
433 case Stmt::MatrixSingleSubscriptExprClass:
434 // TODO: add support for MatrixSingleSubscriptExpr.
435 K = CXCursor_UnexposedExpr;
436 break;
437
438 case Stmt::MatrixSubscriptExprClass:
439 // TODO: add support for MatrixSubscriptExpr.
440 K = CXCursor_UnexposedExpr;
441 break;
442
443 case Stmt::ArraySectionExprClass:
444 K = CXCursor_ArraySectionExpr;
445 break;
446
447 case Stmt::OMPArrayShapingExprClass:
448 K = CXCursor_OMPArrayShapingExpr;
449 break;
450
451 case Stmt::OMPIteratorExprClass:
452 K = CXCursor_OMPIteratorExpr;
453 break;
454
455 case Stmt::BinaryOperatorClass:
456 K = CXCursor_BinaryOperator;
457 break;
458
459 case Stmt::CompoundAssignOperatorClass:
460 K = CXCursor_CompoundAssignOperator;
461 break;
462
463 case Stmt::ConditionalOperatorClass:
464 K = CXCursor_ConditionalOperator;
465 break;
466
467 case Stmt::CStyleCastExprClass:
468 K = CXCursor_CStyleCastExpr;
469 break;
470
471 case Stmt::CompoundLiteralExprClass:
472 K = CXCursor_CompoundLiteralExpr;
473 break;
474
475 case Stmt::InitListExprClass:
476 K = CXCursor_InitListExpr;
477 break;
478
479 case Stmt::AddrLabelExprClass:
480 K = CXCursor_AddrLabelExpr;
481 break;
482
483 case Stmt::StmtExprClass:
484 K = CXCursor_StmtExpr;
485 break;
486
487 case Stmt::GenericSelectionExprClass:
488 K = CXCursor_GenericSelectionExpr;
489 break;
490
491 case Stmt::GNUNullExprClass:
492 K = CXCursor_GNUNullExpr;
493 break;
494
495 case Stmt::CXXStaticCastExprClass:
496 K = CXCursor_CXXStaticCastExpr;
497 break;
498
499 case Stmt::CXXDynamicCastExprClass:
500 K = CXCursor_CXXDynamicCastExpr;
501 break;
502
503 case Stmt::CXXReinterpretCastExprClass:
504 K = CXCursor_CXXReinterpretCastExpr;
505 break;
506
507 case Stmt::CXXConstCastExprClass:
508 K = CXCursor_CXXConstCastExpr;
509 break;
510
511 case Stmt::CXXFunctionalCastExprClass:
512 K = CXCursor_CXXFunctionalCastExpr;
513 break;
514
515 case Stmt::CXXAddrspaceCastExprClass:
516 K = CXCursor_CXXAddrspaceCastExpr;
517 break;
518
519 case Stmt::CXXTypeidExprClass:
520 K = CXCursor_CXXTypeidExpr;
521 break;
522
523 case Stmt::CXXBoolLiteralExprClass:
524 K = CXCursor_CXXBoolLiteralExpr;
525 break;
526
527 case Stmt::CXXNullPtrLiteralExprClass:
528 K = CXCursor_CXXNullPtrLiteralExpr;
529 break;
530
531 case Stmt::CXXThisExprClass:
532 K = CXCursor_CXXThisExpr;
533 break;
534
535 case Stmt::CXXThrowExprClass:
536 K = CXCursor_CXXThrowExpr;
537 break;
538
539 case Stmt::CXXNewExprClass:
540 K = CXCursor_CXXNewExpr;
541 break;
542
543 case Stmt::CXXDeleteExprClass:
544 K = CXCursor_CXXDeleteExpr;
545 break;
546
547 case Stmt::ObjCStringLiteralClass:
548 K = CXCursor_ObjCStringLiteral;
549 break;
550
551 case Stmt::ObjCEncodeExprClass:
552 K = CXCursor_ObjCEncodeExpr;
553 break;
554
555 case Stmt::ObjCSelectorExprClass:
556 K = CXCursor_ObjCSelectorExpr;
557 break;
558
559 case Stmt::ObjCProtocolExprClass:
560 K = CXCursor_ObjCProtocolExpr;
561 break;
562
563 case Stmt::ObjCBoolLiteralExprClass:
564 K = CXCursor_ObjCBoolLiteralExpr;
565 break;
566
567 case Stmt::ObjCAvailabilityCheckExprClass:
568 K = CXCursor_ObjCAvailabilityCheckExpr;
569 break;
570
571 case Stmt::ObjCBridgedCastExprClass:
572 K = CXCursor_ObjCBridgedCastExpr;
573 break;
574
575 case Stmt::BlockExprClass:
576 K = CXCursor_BlockExpr;
577 break;
578
579 case Stmt::PackExpansionExprClass:
580 K = CXCursor_PackExpansionExpr;
581 break;
582
583 case Stmt::SizeOfPackExprClass:
584 K = CXCursor_SizeOfPackExpr;
585 break;
586
587 case Stmt::PackIndexingExprClass:
588 K = CXCursor_PackIndexingExpr;
589 break;
590
591 case Stmt::DeclRefExprClass:
592 if (const ImplicitParamDecl *IPD = dyn_cast_or_null<ImplicitParamDecl>(
593 Val: cast<DeclRefExpr>(Val: S)->getDecl())) {
594 if (const ObjCMethodDecl *MD =
595 dyn_cast<ObjCMethodDecl>(Val: IPD->getDeclContext())) {
596 if (MD->getSelfDecl() == IPD) {
597 K = CXCursor_ObjCSelfExpr;
598 break;
599 }
600 }
601 }
602
603 K = CXCursor_DeclRefExpr;
604 break;
605
606 case Stmt::DependentScopeDeclRefExprClass:
607 case Stmt::SubstNonTypeTemplateParmExprClass:
608 case Stmt::SubstNonTypeTemplateParmPackExprClass:
609 case Stmt::FunctionParmPackExprClass:
610 case Stmt::UnresolvedLookupExprClass:
611 K = CXCursor_DeclRefExpr;
612 break;
613
614 case Stmt::CXXDependentScopeMemberExprClass:
615 case Stmt::CXXPseudoDestructorExprClass:
616 case Stmt::MemberExprClass:
617 case Stmt::MSPropertyRefExprClass:
618 case Stmt::ObjCIsaExprClass:
619 case Stmt::ObjCIvarRefExprClass:
620 case Stmt::ObjCPropertyRefExprClass:
621 case Stmt::UnresolvedMemberExprClass:
622 K = CXCursor_MemberRefExpr;
623 break;
624
625 case Stmt::CallExprClass:
626 case Stmt::CXXOperatorCallExprClass:
627 case Stmt::CXXMemberCallExprClass:
628 case Stmt::CUDAKernelCallExprClass:
629 case Stmt::CXXConstructExprClass:
630 case Stmt::CXXInheritedCtorInitExprClass:
631 case Stmt::CXXTemporaryObjectExprClass:
632 case Stmt::CXXUnresolvedConstructExprClass:
633 case Stmt::UserDefinedLiteralClass:
634 K = CXCursor_CallExpr;
635 break;
636
637 case Stmt::LambdaExprClass:
638 K = CXCursor_LambdaExpr;
639 break;
640
641 case Stmt::ObjCMessageExprClass: {
642 K = CXCursor_ObjCMessageExpr;
643 int SelectorIdIndex = -1;
644 // Check if cursor points to a selector id.
645 if (RegionOfInterest.isValid() &&
646 RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
647 SmallVector<SourceLocation, 16> SelLocs;
648 cast<ObjCMessageExpr>(Val: S)->getSelectorLocs(SelLocs);
649 SmallVectorImpl<SourceLocation>::iterator I =
650 llvm::find(Range&: SelLocs, Val: RegionOfInterest.getBegin());
651 if (I != SelLocs.end())
652 SelectorIdIndex = I - SelLocs.begin();
653 }
654 CXCursor C = {.kind: K, .xdata: 0, .data: {Parent, S, TU}};
655 return getSelectorIdentifierCursor(SelIdx: SelectorIdIndex, cursor: C);
656 }
657
658 case Stmt::ConceptSpecializationExprClass:
659 K = CXCursor_ConceptSpecializationExpr;
660 break;
661
662 case Stmt::RequiresExprClass:
663 K = CXCursor_RequiresExpr;
664 break;
665
666 case Stmt::CXXParenListInitExprClass:
667 K = CXCursor_CXXParenListInitExpr;
668 break;
669
670 case Stmt::MSDependentExistsStmtClass:
671 K = CXCursor_UnexposedStmt;
672 break;
673 case Stmt::OMPCanonicalLoopClass:
674 K = CXCursor_OMPCanonicalLoop;
675 break;
676 case Stmt::OMPMetaDirectiveClass:
677 K = CXCursor_OMPMetaDirective;
678 break;
679 case Stmt::OMPParallelDirectiveClass:
680 K = CXCursor_OMPParallelDirective;
681 break;
682 case Stmt::OMPSimdDirectiveClass:
683 K = CXCursor_OMPSimdDirective;
684 break;
685 case Stmt::OMPTileDirectiveClass:
686 K = CXCursor_OMPTileDirective;
687 break;
688 case Stmt::OMPStripeDirectiveClass:
689 K = CXCursor_OMPStripeDirective;
690 break;
691 case Stmt::OMPUnrollDirectiveClass:
692 K = CXCursor_OMPUnrollDirective;
693 break;
694 case Stmt::OMPReverseDirectiveClass:
695 K = CXCursor_OMPReverseDirective;
696 break;
697 case Stmt::OMPInterchangeDirectiveClass:
698 K = CXCursor_OMPInterchangeDirective;
699 break;
700 case Stmt::OMPFuseDirectiveClass:
701 K = CXCursor_OMPFuseDirective;
702 break;
703 case Stmt::OMPForDirectiveClass:
704 K = CXCursor_OMPForDirective;
705 break;
706 case Stmt::OMPForSimdDirectiveClass:
707 K = CXCursor_OMPForSimdDirective;
708 break;
709 case Stmt::OMPSectionsDirectiveClass:
710 K = CXCursor_OMPSectionsDirective;
711 break;
712 case Stmt::OMPSectionDirectiveClass:
713 K = CXCursor_OMPSectionDirective;
714 break;
715 case Stmt::OMPScopeDirectiveClass:
716 K = CXCursor_OMPScopeDirective;
717 break;
718 case Stmt::OMPSingleDirectiveClass:
719 K = CXCursor_OMPSingleDirective;
720 break;
721 case Stmt::OMPMasterDirectiveClass:
722 K = CXCursor_OMPMasterDirective;
723 break;
724 case Stmt::OMPCriticalDirectiveClass:
725 K = CXCursor_OMPCriticalDirective;
726 break;
727 case Stmt::OMPParallelForDirectiveClass:
728 K = CXCursor_OMPParallelForDirective;
729 break;
730 case Stmt::OMPParallelForSimdDirectiveClass:
731 K = CXCursor_OMPParallelForSimdDirective;
732 break;
733 case Stmt::OMPParallelMasterDirectiveClass:
734 K = CXCursor_OMPParallelMasterDirective;
735 break;
736 case Stmt::OMPParallelMaskedDirectiveClass:
737 K = CXCursor_OMPParallelMaskedDirective;
738 break;
739 case Stmt::OMPParallelSectionsDirectiveClass:
740 K = CXCursor_OMPParallelSectionsDirective;
741 break;
742 case Stmt::OMPTaskDirectiveClass:
743 K = CXCursor_OMPTaskDirective;
744 break;
745 case Stmt::OMPTaskyieldDirectiveClass:
746 K = CXCursor_OMPTaskyieldDirective;
747 break;
748 case Stmt::OMPBarrierDirectiveClass:
749 K = CXCursor_OMPBarrierDirective;
750 break;
751 case Stmt::OMPTaskwaitDirectiveClass:
752 K = CXCursor_OMPTaskwaitDirective;
753 break;
754 case Stmt::OMPErrorDirectiveClass:
755 K = CXCursor_OMPErrorDirective;
756 break;
757 case Stmt::OMPTaskgroupDirectiveClass:
758 K = CXCursor_OMPTaskgroupDirective;
759 break;
760 case Stmt::OMPFlushDirectiveClass:
761 K = CXCursor_OMPFlushDirective;
762 break;
763 case Stmt::OMPDepobjDirectiveClass:
764 K = CXCursor_OMPDepobjDirective;
765 break;
766 case Stmt::OMPScanDirectiveClass:
767 K = CXCursor_OMPScanDirective;
768 break;
769 case Stmt::OMPOrderedDirectiveClass:
770 K = CXCursor_OMPOrderedDirective;
771 break;
772 case Stmt::OMPAtomicDirectiveClass:
773 K = CXCursor_OMPAtomicDirective;
774 break;
775 case Stmt::OMPTargetDirectiveClass:
776 K = CXCursor_OMPTargetDirective;
777 break;
778 case Stmt::OMPTargetDataDirectiveClass:
779 K = CXCursor_OMPTargetDataDirective;
780 break;
781 case Stmt::OMPTargetEnterDataDirectiveClass:
782 K = CXCursor_OMPTargetEnterDataDirective;
783 break;
784 case Stmt::OMPTargetExitDataDirectiveClass:
785 K = CXCursor_OMPTargetExitDataDirective;
786 break;
787 case Stmt::OMPTargetParallelDirectiveClass:
788 K = CXCursor_OMPTargetParallelDirective;
789 break;
790 case Stmt::OMPTargetParallelForDirectiveClass:
791 K = CXCursor_OMPTargetParallelForDirective;
792 break;
793 case Stmt::OMPTargetUpdateDirectiveClass:
794 K = CXCursor_OMPTargetUpdateDirective;
795 break;
796 case Stmt::OMPTeamsDirectiveClass:
797 K = CXCursor_OMPTeamsDirective;
798 break;
799 case Stmt::OMPCancellationPointDirectiveClass:
800 K = CXCursor_OMPCancellationPointDirective;
801 break;
802 case Stmt::OMPCancelDirectiveClass:
803 K = CXCursor_OMPCancelDirective;
804 break;
805 case Stmt::OMPTaskLoopDirectiveClass:
806 K = CXCursor_OMPTaskLoopDirective;
807 break;
808 case Stmt::OMPTaskLoopSimdDirectiveClass:
809 K = CXCursor_OMPTaskLoopSimdDirective;
810 break;
811 case Stmt::OMPMasterTaskLoopDirectiveClass:
812 K = CXCursor_OMPMasterTaskLoopDirective;
813 break;
814 case Stmt::OMPMaskedTaskLoopDirectiveClass:
815 K = CXCursor_OMPMaskedTaskLoopDirective;
816 break;
817 case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
818 K = CXCursor_OMPMasterTaskLoopSimdDirective;
819 break;
820 case Stmt::OMPMaskedTaskLoopSimdDirectiveClass:
821 K = CXCursor_OMPMaskedTaskLoopSimdDirective;
822 break;
823 case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
824 K = CXCursor_OMPParallelMasterTaskLoopDirective;
825 break;
826 case Stmt::OMPParallelMaskedTaskLoopDirectiveClass:
827 K = CXCursor_OMPParallelMaskedTaskLoopDirective;
828 break;
829 case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
830 K = CXCursor_OMPParallelMasterTaskLoopSimdDirective;
831 break;
832 case Stmt::OMPParallelMaskedTaskLoopSimdDirectiveClass:
833 K = CXCursor_OMPParallelMaskedTaskLoopSimdDirective;
834 break;
835 case Stmt::OMPDistributeDirectiveClass:
836 K = CXCursor_OMPDistributeDirective;
837 break;
838 case Stmt::OMPDistributeParallelForDirectiveClass:
839 K = CXCursor_OMPDistributeParallelForDirective;
840 break;
841 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
842 K = CXCursor_OMPDistributeParallelForSimdDirective;
843 break;
844 case Stmt::OMPDistributeSimdDirectiveClass:
845 K = CXCursor_OMPDistributeSimdDirective;
846 break;
847 case Stmt::OMPTargetParallelForSimdDirectiveClass:
848 K = CXCursor_OMPTargetParallelForSimdDirective;
849 break;
850 case Stmt::OMPTargetSimdDirectiveClass:
851 K = CXCursor_OMPTargetSimdDirective;
852 break;
853 case Stmt::OMPTeamsDistributeDirectiveClass:
854 K = CXCursor_OMPTeamsDistributeDirective;
855 break;
856 case Stmt::OMPTeamsDistributeSimdDirectiveClass:
857 K = CXCursor_OMPTeamsDistributeSimdDirective;
858 break;
859 case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
860 K = CXCursor_OMPTeamsDistributeParallelForSimdDirective;
861 break;
862 case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
863 K = CXCursor_OMPTeamsDistributeParallelForDirective;
864 break;
865 case Stmt::OMPTargetTeamsDirectiveClass:
866 K = CXCursor_OMPTargetTeamsDirective;
867 break;
868 case Stmt::OMPTargetTeamsDistributeDirectiveClass:
869 K = CXCursor_OMPTargetTeamsDistributeDirective;
870 break;
871 case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
872 K = CXCursor_OMPTargetTeamsDistributeParallelForDirective;
873 break;
874 case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
875 K = CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective;
876 break;
877 case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
878 K = CXCursor_OMPTargetTeamsDistributeSimdDirective;
879 break;
880 case Stmt::OMPInteropDirectiveClass:
881 K = CXCursor_OMPInteropDirective;
882 break;
883 case Stmt::OMPDispatchDirectiveClass:
884 K = CXCursor_OMPDispatchDirective;
885 break;
886 case Stmt::OMPMaskedDirectiveClass:
887 K = CXCursor_OMPMaskedDirective;
888 break;
889 case Stmt::OMPGenericLoopDirectiveClass:
890 K = CXCursor_OMPGenericLoopDirective;
891 break;
892 case Stmt::OMPTeamsGenericLoopDirectiveClass:
893 K = CXCursor_OMPTeamsGenericLoopDirective;
894 break;
895 case Stmt::OMPTargetTeamsGenericLoopDirectiveClass:
896 K = CXCursor_OMPTargetTeamsGenericLoopDirective;
897 break;
898 case Stmt::OMPParallelGenericLoopDirectiveClass:
899 K = CXCursor_OMPParallelGenericLoopDirective;
900 break;
901 case Stmt::OpenACCComputeConstructClass:
902 K = CXCursor_OpenACCComputeConstruct;
903 break;
904 case Stmt::OpenACCLoopConstructClass:
905 K = CXCursor_OpenACCLoopConstruct;
906 break;
907 case Stmt::OpenACCCombinedConstructClass:
908 K = CXCursor_OpenACCCombinedConstruct;
909 break;
910 case Stmt::OpenACCDataConstructClass:
911 K = CXCursor_OpenACCDataConstruct;
912 break;
913 case Stmt::OpenACCEnterDataConstructClass:
914 K = CXCursor_OpenACCEnterDataConstruct;
915 break;
916 case Stmt::OpenACCExitDataConstructClass:
917 K = CXCursor_OpenACCExitDataConstruct;
918 break;
919 case Stmt::OpenACCHostDataConstructClass:
920 K = CXCursor_OpenACCHostDataConstruct;
921 break;
922 case Stmt::OpenACCWaitConstructClass:
923 K = CXCursor_OpenACCWaitConstruct;
924 break;
925 case Stmt::OpenACCCacheConstructClass:
926 K = CXCursor_OpenACCCacheConstruct;
927 break;
928 case Stmt::OpenACCInitConstructClass:
929 K = CXCursor_OpenACCInitConstruct;
930 break;
931 case Stmt::OpenACCShutdownConstructClass:
932 K = CXCursor_OpenACCShutdownConstruct;
933 break;
934 case Stmt::OpenACCSetConstructClass:
935 K = CXCursor_OpenACCSetConstruct;
936 break;
937 case Stmt::OpenACCUpdateConstructClass:
938 K = CXCursor_OpenACCUpdateConstruct;
939 break;
940 case Stmt::OpenACCAtomicConstructClass:
941 K = CXCursor_OpenACCAtomicConstruct;
942 break;
943 case Stmt::OMPTargetParallelGenericLoopDirectiveClass:
944 K = CXCursor_OMPTargetParallelGenericLoopDirective;
945 break;
946 case Stmt::BuiltinBitCastExprClass:
947 K = CXCursor_BuiltinBitCastExpr;
948 break;
949 case Stmt::OMPAssumeDirectiveClass:
950 K = CXCursor_OMPAssumeDirective;
951 break;
952 }
953
954 CXCursor C = {.kind: K, .xdata: 0, .data: {Parent, S, TU}};
955 return C;
956}
957
958CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
959 SourceLocation Loc,
960 CXTranslationUnit TU) {
961 assert(Super && TU && "Invalid arguments!");
962 void *RawLoc = Loc.getPtrEncoding();
963 CXCursor C = {.kind: CXCursor_ObjCSuperClassRef, .xdata: 0, .data: {Super, RawLoc, TU}};
964 return C;
965}
966
967std::pair<const ObjCInterfaceDecl *, SourceLocation>
968cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
969 assert(C.kind == CXCursor_ObjCSuperClassRef);
970 return std::make_pair(x: static_cast<const ObjCInterfaceDecl *>(C.data[0]),
971 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
972}
973
974CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
975 SourceLocation Loc,
976 CXTranslationUnit TU) {
977 assert(Proto && TU && "Invalid arguments!");
978 void *RawLoc = Loc.getPtrEncoding();
979 CXCursor C = {.kind: CXCursor_ObjCProtocolRef, .xdata: 0, .data: {Proto, RawLoc, TU}};
980 return C;
981}
982
983std::pair<const ObjCProtocolDecl *, SourceLocation>
984cxcursor::getCursorObjCProtocolRef(CXCursor C) {
985 assert(C.kind == CXCursor_ObjCProtocolRef);
986 return std::make_pair(x: static_cast<const ObjCProtocolDecl *>(C.data[0]),
987 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
988}
989
990CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
991 SourceLocation Loc,
992 CXTranslationUnit TU) {
993 // 'Class' can be null for invalid code.
994 if (!Class)
995 return MakeCXCursorInvalid(K: CXCursor_InvalidCode);
996 assert(TU && "Invalid arguments!");
997 void *RawLoc = Loc.getPtrEncoding();
998 CXCursor C = {.kind: CXCursor_ObjCClassRef, .xdata: 0, .data: {Class, RawLoc, TU}};
999 return C;
1000}
1001
1002std::pair<const ObjCInterfaceDecl *, SourceLocation>
1003cxcursor::getCursorObjCClassRef(CXCursor C) {
1004 assert(C.kind == CXCursor_ObjCClassRef);
1005 return std::make_pair(x: static_cast<const ObjCInterfaceDecl *>(C.data[0]),
1006 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1007}
1008
1009CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
1010 CXTranslationUnit TU) {
1011 assert(Type && TU && "Invalid arguments!");
1012 void *RawLoc = Loc.getPtrEncoding();
1013 CXCursor C = {.kind: CXCursor_TypeRef, .xdata: 0, .data: {Type, RawLoc, TU}};
1014 return C;
1015}
1016
1017std::pair<const TypeDecl *, SourceLocation>
1018cxcursor::getCursorTypeRef(CXCursor C) {
1019 assert(C.kind == CXCursor_TypeRef);
1020 return std::make_pair(x: static_cast<const TypeDecl *>(C.data[0]),
1021 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1022}
1023
1024CXCursor cxcursor::MakeCursorTemplateRef(const TemplateDecl *Template,
1025 SourceLocation Loc,
1026 CXTranslationUnit TU) {
1027 assert(Template && TU && "Invalid arguments!");
1028 void *RawLoc = Loc.getPtrEncoding();
1029 CXCursor C = {.kind: CXCursor_TemplateRef, .xdata: 0, .data: {Template, RawLoc, TU}};
1030 return C;
1031}
1032
1033std::pair<const TemplateDecl *, SourceLocation>
1034cxcursor::getCursorTemplateRef(CXCursor C) {
1035 assert(C.kind == CXCursor_TemplateRef);
1036 return std::make_pair(x: static_cast<const TemplateDecl *>(C.data[0]),
1037 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1038}
1039
1040CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
1041 SourceLocation Loc,
1042 CXTranslationUnit TU) {
1043
1044 assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
1045 "Invalid arguments!");
1046 void *RawLoc = Loc.getPtrEncoding();
1047 CXCursor C = {.kind: CXCursor_NamespaceRef, .xdata: 0, .data: {NS, RawLoc, TU}};
1048 return C;
1049}
1050
1051std::pair<const NamedDecl *, SourceLocation>
1052cxcursor::getCursorNamespaceRef(CXCursor C) {
1053 assert(C.kind == CXCursor_NamespaceRef);
1054 return std::make_pair(x: static_cast<const NamedDecl *>(C.data[0]),
1055 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1056}
1057
1058CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
1059 CXTranslationUnit TU) {
1060
1061 assert(Var && TU && "Invalid arguments!");
1062 void *RawLoc = Loc.getPtrEncoding();
1063 CXCursor C = {.kind: CXCursor_VariableRef, .xdata: 0, .data: {Var, RawLoc, TU}};
1064 return C;
1065}
1066
1067std::pair<const VarDecl *, SourceLocation>
1068cxcursor::getCursorVariableRef(CXCursor C) {
1069 assert(C.kind == CXCursor_VariableRef);
1070 return std::make_pair(x: static_cast<const VarDecl *>(C.data[0]),
1071 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1072}
1073
1074CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field,
1075 SourceLocation Loc,
1076 CXTranslationUnit TU) {
1077
1078 assert(Field && TU && "Invalid arguments!");
1079 void *RawLoc = Loc.getPtrEncoding();
1080 CXCursor C = {.kind: CXCursor_MemberRef, .xdata: 0, .data: {Field, RawLoc, TU}};
1081 return C;
1082}
1083
1084std::pair<const FieldDecl *, SourceLocation>
1085cxcursor::getCursorMemberRef(CXCursor C) {
1086 assert(C.kind == CXCursor_MemberRef);
1087 return std::make_pair(x: static_cast<const FieldDecl *>(C.data[0]),
1088 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1089}
1090
1091CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
1092 CXTranslationUnit TU) {
1093 CXCursor C = {.kind: CXCursor_CXXBaseSpecifier, .xdata: 0, .data: {B, nullptr, TU}};
1094 return C;
1095}
1096
1097const CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
1098 assert(C.kind == CXCursor_CXXBaseSpecifier);
1099 return static_cast<const CXXBaseSpecifier *>(C.data[0]);
1100}
1101
1102CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
1103 CXTranslationUnit TU) {
1104 CXCursor C = {
1105 .kind: CXCursor_PreprocessingDirective,
1106 .xdata: 0,
1107 .data: {Range.getBegin().getPtrEncoding(), Range.getEnd().getPtrEncoding(), TU}};
1108 return C;
1109}
1110
1111SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
1112 assert(C.kind == CXCursor_PreprocessingDirective);
1113 SourceRange Range(SourceLocation::getFromPtrEncoding(Encoding: C.data[0]),
1114 SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1115 ASTUnit *TU = getCursorASTUnit(Cursor: C);
1116 return TU->mapRangeFromPreamble(R: Range);
1117}
1118
1119CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinitionRecord *MI,
1120 CXTranslationUnit TU) {
1121 CXCursor C = {.kind: CXCursor_MacroDefinition, .xdata: 0, .data: {MI, nullptr, TU}};
1122 return C;
1123}
1124
1125const MacroDefinitionRecord *cxcursor::getCursorMacroDefinition(CXCursor C) {
1126 assert(C.kind == CXCursor_MacroDefinition);
1127 return static_cast<const MacroDefinitionRecord *>(C.data[0]);
1128}
1129
1130CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
1131 CXTranslationUnit TU) {
1132 CXCursor C = {.kind: CXCursor_MacroExpansion, .xdata: 0, .data: {MI, nullptr, TU}};
1133 return C;
1134}
1135
1136CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinitionRecord *MI,
1137 SourceLocation Loc,
1138 CXTranslationUnit TU) {
1139 assert(Loc.isValid());
1140 CXCursor C = {.kind: CXCursor_MacroExpansion, .xdata: 0, .data: {MI, Loc.getPtrEncoding(), TU}};
1141 return C;
1142}
1143
1144const IdentifierInfo *cxcursor::MacroExpansionCursor::getName() const {
1145 if (isPseudo())
1146 return getAsMacroDefinition()->getName();
1147 return getAsMacroExpansion()->getName();
1148}
1149const MacroDefinitionRecord *
1150cxcursor::MacroExpansionCursor::getDefinition() const {
1151 if (isPseudo())
1152 return getAsMacroDefinition();
1153 return getAsMacroExpansion()->getDefinition();
1154}
1155SourceRange cxcursor::MacroExpansionCursor::getSourceRange() const {
1156 if (isPseudo())
1157 return getPseudoLoc();
1158 return getAsMacroExpansion()->getSourceRange();
1159}
1160
1161CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
1162 CXTranslationUnit TU) {
1163 CXCursor C = {.kind: CXCursor_InclusionDirective, .xdata: 0, .data: {ID, nullptr, TU}};
1164 return C;
1165}
1166
1167const InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
1168 assert(C.kind == CXCursor_InclusionDirective);
1169 return static_cast<const InclusionDirective *>(C.data[0]);
1170}
1171
1172CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
1173 CXTranslationUnit TU) {
1174
1175 assert(Label && TU && "Invalid arguments!");
1176 void *RawLoc = Loc.getPtrEncoding();
1177 CXCursor C = {.kind: CXCursor_LabelRef, .xdata: 0, .data: {Label, RawLoc, TU}};
1178 return C;
1179}
1180
1181std::pair<const LabelStmt *, SourceLocation>
1182cxcursor::getCursorLabelRef(CXCursor C) {
1183 assert(C.kind == CXCursor_LabelRef);
1184 return std::make_pair(x: static_cast<const LabelStmt *>(C.data[0]),
1185 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1186}
1187
1188CXCursor cxcursor::MakeCursorOverloadedDeclRef(const OverloadExpr *E,
1189 CXTranslationUnit TU) {
1190 assert(E && TU && "Invalid arguments!");
1191 OverloadedDeclRefStorage Storage(E);
1192 void *RawLoc = E->getNameLoc().getPtrEncoding();
1193 CXCursor C = {
1194 .kind: CXCursor_OverloadedDeclRef, .xdata: 0, .data: {Storage.getOpaqueValue(), RawLoc, TU}};
1195 return C;
1196}
1197
1198CXCursor cxcursor::MakeCursorOverloadedDeclRef(const Decl *D,
1199 SourceLocation Loc,
1200 CXTranslationUnit TU) {
1201 assert(D && TU && "Invalid arguments!");
1202 void *RawLoc = Loc.getPtrEncoding();
1203 OverloadedDeclRefStorage Storage(D);
1204 CXCursor C = {
1205 .kind: CXCursor_OverloadedDeclRef, .xdata: 0, .data: {Storage.getOpaqueValue(), RawLoc, TU}};
1206 return C;
1207}
1208
1209CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
1210 SourceLocation Loc,
1211 CXTranslationUnit TU) {
1212 assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
1213 void *RawLoc = Loc.getPtrEncoding();
1214 OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
1215 CXCursor C = {
1216 .kind: CXCursor_OverloadedDeclRef, .xdata: 0, .data: {Storage.getOpaqueValue(), RawLoc, TU}};
1217 return C;
1218}
1219
1220std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
1221cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
1222 assert(C.kind == CXCursor_OverloadedDeclRef);
1223 return std::make_pair(x: OverloadedDeclRefStorage::getFromOpaqueValue(
1224 VP: const_cast<void *>(C.data[0])),
1225 y: SourceLocation::getFromPtrEncoding(Encoding: C.data[1]));
1226}
1227
1228const Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
1229 return static_cast<const Decl *>(Cursor.data[0]);
1230}
1231
1232const Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
1233 return dyn_cast_or_null<Expr>(Val: getCursorStmt(Cursor));
1234}
1235
1236const Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
1237 if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
1238 Cursor.kind == CXCursor_ObjCProtocolRef ||
1239 Cursor.kind == CXCursor_ObjCClassRef)
1240 return nullptr;
1241
1242 return static_cast<const Stmt *>(Cursor.data[1]);
1243}
1244
1245const Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
1246 return static_cast<const Attr *>(Cursor.data[1]);
1247}
1248
1249ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
1250 return getCursorASTUnit(Cursor)->getASTContext();
1251}
1252
1253ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
1254 CXTranslationUnit TU = getCursorTU(Cursor);
1255 if (!TU)
1256 return nullptr;
1257 return cxtu::getASTUnit(TU);
1258}
1259
1260CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
1261 return static_cast<CXTranslationUnit>(const_cast<void *>(Cursor.data[2]));
1262}
1263
1264void cxcursor::getOverriddenCursors(CXCursor cursor,
1265 SmallVectorImpl<CXCursor> &overridden) {
1266 assert(clang_isDeclaration(cursor.kind));
1267 const NamedDecl *D = dyn_cast_or_null<NamedDecl>(Val: getCursorDecl(Cursor: cursor));
1268 if (!D)
1269 return;
1270
1271 CXTranslationUnit TU = getCursorTU(Cursor: cursor);
1272 SmallVector<const NamedDecl *, 8> OverDecls;
1273 D->getASTContext().getOverriddenMethods(Method: D, Overridden&: OverDecls);
1274
1275 for (SmallVectorImpl<const NamedDecl *>::iterator I = OverDecls.begin(),
1276 E = OverDecls.end();
1277 I != E; ++I) {
1278 overridden.push_back(Elt: MakeCXCursor(D: *I, TU));
1279 }
1280}
1281
1282std::pair<int, SourceLocation>
1283cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
1284 if (cursor.kind == CXCursor_ObjCMessageExpr) {
1285 if (cursor.xdata != -1)
1286 return std::make_pair(x&: cursor.xdata,
1287 y: cast<ObjCMessageExpr>(Val: getCursorExpr(Cursor: cursor))
1288 ->getSelectorLoc(Index: cursor.xdata));
1289 } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
1290 cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
1291 if (cursor.xdata != -1)
1292 return std::make_pair(x&: cursor.xdata,
1293 y: cast<ObjCMethodDecl>(Val: getCursorDecl(Cursor: cursor))
1294 ->getSelectorLoc(Index: cursor.xdata));
1295 }
1296
1297 return std::make_pair(x: -1, y: SourceLocation());
1298}
1299
1300CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
1301 CXCursor newCursor = cursor;
1302
1303 if (cursor.kind == CXCursor_ObjCMessageExpr) {
1304 if (SelIdx == -1 ||
1305 unsigned(SelIdx) >=
1306 cast<ObjCMessageExpr>(Val: getCursorExpr(Cursor: cursor))->getNumSelectorLocs())
1307 newCursor.xdata = -1;
1308 else
1309 newCursor.xdata = SelIdx;
1310 } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
1311 cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
1312 if (SelIdx == -1 ||
1313 unsigned(SelIdx) >=
1314 cast<ObjCMethodDecl>(Val: getCursorDecl(Cursor: cursor))->getNumSelectorLocs())
1315 newCursor.xdata = -1;
1316 else
1317 newCursor.xdata = SelIdx;
1318 }
1319
1320 return newCursor;
1321}
1322
1323CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
1324 if (cursor.kind != CXCursor_CallExpr)
1325 return cursor;
1326
1327 if (cursor.xdata == 0)
1328 return cursor;
1329
1330 const Expr *E = getCursorExpr(Cursor: cursor);
1331 TypeSourceInfo *Type = nullptr;
1332 if (const CXXUnresolvedConstructExpr *UnCtor =
1333 dyn_cast<CXXUnresolvedConstructExpr>(Val: E)) {
1334 Type = UnCtor->getTypeSourceInfo();
1335 } else if (const CXXTemporaryObjectExpr *Tmp =
1336 dyn_cast<CXXTemporaryObjectExpr>(Val: E)) {
1337 Type = Tmp->getTypeSourceInfo();
1338 }
1339
1340 if (!Type)
1341 return cursor;
1342
1343 CXTranslationUnit TU = getCursorTU(Cursor: cursor);
1344 QualType Ty = Type->getType();
1345 TypeLoc TL = Type->getTypeLoc();
1346 SourceLocation Loc = TL.getBeginLoc();
1347
1348 if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
1349 return MakeCursorTypeRef(Type: Typedef->getDecl(), Loc, TU);
1350 if (const TagType *Tag = Ty->getAs<TagType>())
1351 return MakeCursorTypeRef(Type: Tag->getDecl(), Loc, TU);
1352 if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
1353 return MakeCursorTypeRef(Type: TemplP->getDecl(), Loc, TU);
1354
1355 return cursor;
1356}
1357
1358bool cxcursor::operator==(CXCursor X, CXCursor Y) {
1359 return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
1360 X.data[2] == Y.data[2];
1361}
1362
1363// FIXME: Remove once we can model DeclGroups and their appropriate ranges
1364// properly in the ASTs.
1365bool cxcursor::isFirstInDeclGroup(CXCursor C) {
1366 assert(clang_isDeclaration(C.kind));
1367 return ((uintptr_t)(C.data[1])) != 0;
1368}
1369
1370//===----------------------------------------------------------------------===//
1371// libclang CXCursor APIs
1372//===----------------------------------------------------------------------===//
1373
1374int clang_Cursor_isNull(CXCursor cursor) {
1375 return clang_equalCursors(cursor, clang_getNullCursor());
1376}
1377
1378CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
1379 return getCursorTU(Cursor: cursor);
1380}
1381
1382int clang_Cursor_getNumArguments(CXCursor C) {
1383 if (clang_isDeclaration(C.kind)) {
1384 const Decl *D = cxcursor::getCursorDecl(Cursor: C);
1385 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Val: D))
1386 return MD->param_size();
1387 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Val: D))
1388 return FD->param_size();
1389 }
1390
1391 if (clang_isExpression(C.kind)) {
1392 const Expr *E = cxcursor::getCursorExpr(Cursor: C);
1393 if (const CallExpr *CE = dyn_cast<CallExpr>(Val: E)) {
1394 return CE->getNumArgs();
1395 }
1396 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(Val: E)) {
1397 return CE->getNumArgs();
1398 }
1399 }
1400
1401 return -1;
1402}
1403
1404CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
1405 if (clang_isDeclaration(C.kind)) {
1406 const Decl *D = cxcursor::getCursorDecl(Cursor: C);
1407 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(Val: D)) {
1408 if (i < MD->param_size())
1409 return cxcursor::MakeCXCursor(D: MD->parameters()[i],
1410 TU: cxcursor::getCursorTU(Cursor: C));
1411 } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(Val: D)) {
1412 if (i < FD->param_size())
1413 return cxcursor::MakeCXCursor(D: FD->parameters()[i],
1414 TU: cxcursor::getCursorTU(Cursor: C));
1415 }
1416 }
1417
1418 if (clang_isExpression(C.kind)) {
1419 const Expr *E = cxcursor::getCursorExpr(Cursor: C);
1420 if (const CallExpr *CE = dyn_cast<CallExpr>(Val: E)) {
1421 if (i < CE->getNumArgs()) {
1422 return cxcursor::MakeCXCursor(S: CE->getArg(Arg: i), Parent: getCursorDecl(Cursor: C),
1423 TU: cxcursor::getCursorTU(Cursor: C));
1424 }
1425 }
1426 if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(Val: E)) {
1427 if (i < CE->getNumArgs()) {
1428 return cxcursor::MakeCXCursor(S: CE->getArg(Arg: i), Parent: getCursorDecl(Cursor: C),
1429 TU: cxcursor::getCursorTU(Cursor: C));
1430 }
1431 }
1432 }
1433
1434 return clang_getNullCursor();
1435}
1436
1437int clang_Cursor_getNumTemplateArguments(CXCursor C) {
1438 CXCursorKind kind = clang_getCursorKind(C);
1439 if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl &&
1440 kind != CXCursor_ClassDecl &&
1441 kind != CXCursor_ClassTemplatePartialSpecialization) {
1442 return -1;
1443 }
1444
1445 if (const auto *FD =
1446 llvm::dyn_cast_if_present<clang::FunctionDecl>(Val: getCursorDecl(Cursor: C))) {
1447 const FunctionTemplateSpecializationInfo *SpecInfo =
1448 FD->getTemplateSpecializationInfo();
1449 if (!SpecInfo) {
1450 return -1;
1451 }
1452 return SpecInfo->TemplateArguments->size();
1453 }
1454
1455 if (const auto *SD =
1456 llvm::dyn_cast_if_present<clang::ClassTemplateSpecializationDecl>(
1457 Val: getCursorDecl(Cursor: C))) {
1458 return SD->getTemplateArgs().size();
1459 }
1460
1461 return -1;
1462}
1463
1464enum CXGetTemplateArgumentStatus {
1465 /** The operation completed successfully */
1466 CXGetTemplateArgumentStatus_Success = 0,
1467
1468 /** The specified cursor did not represent a FunctionDecl or
1469 ClassTemplateSpecializationDecl. */
1470 CXGetTemplateArgumentStatus_CursorNotCompatibleDecl = -1,
1471
1472 /** The specified cursor was not castable to a FunctionDecl or
1473 ClassTemplateSpecializationDecl. */
1474 CXGetTemplateArgumentStatus_BadDeclCast = -2,
1475
1476 /** A NULL FunctionTemplateSpecializationInfo was retrieved. */
1477 CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3,
1478
1479 /** An invalid (OOB) argument index was specified */
1480 CXGetTemplateArgumentStatus_InvalidIndex = -4
1481};
1482
1483static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I,
1484 TemplateArgument *TA) {
1485 CXCursorKind kind = clang_getCursorKind(C);
1486 if (kind != CXCursor_FunctionDecl && kind != CXCursor_StructDecl &&
1487 kind != CXCursor_ClassDecl &&
1488 kind != CXCursor_ClassTemplatePartialSpecialization) {
1489 return -1;
1490 }
1491
1492 if (const auto *FD =
1493 llvm::dyn_cast_if_present<clang::FunctionDecl>(Val: getCursorDecl(Cursor: C))) {
1494
1495 const FunctionTemplateSpecializationInfo *SpecInfo =
1496 FD->getTemplateSpecializationInfo();
1497 if (!SpecInfo) {
1498 return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
1499 }
1500
1501 if (I >= SpecInfo->TemplateArguments->size()) {
1502 return CXGetTemplateArgumentStatus_InvalidIndex;
1503 }
1504
1505 *TA = SpecInfo->TemplateArguments->get(Idx: I);
1506 return 0;
1507 }
1508
1509 if (const auto *SD =
1510 llvm::dyn_cast_if_present<clang::ClassTemplateSpecializationDecl>(
1511 Val: getCursorDecl(Cursor: C))) {
1512 if (I >= SD->getTemplateArgs().size()) {
1513 return CXGetTemplateArgumentStatus_InvalidIndex;
1514 }
1515
1516 *TA = SD->getTemplateArgs()[I];
1517 return 0;
1518 }
1519
1520 return CXGetTemplateArgumentStatus_BadDeclCast;
1521}
1522
1523enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
1524 unsigned I) {
1525 TemplateArgument TA;
1526 if (clang_Cursor_getTemplateArgument(C, I, TA: &TA)) {
1527 return CXTemplateArgumentKind_Invalid;
1528 }
1529
1530 switch (TA.getKind()) {
1531 case TemplateArgument::Null:
1532 return CXTemplateArgumentKind_Null;
1533 case TemplateArgument::Type:
1534 return CXTemplateArgumentKind_Type;
1535 case TemplateArgument::Declaration:
1536 return CXTemplateArgumentKind_Declaration;
1537 case TemplateArgument::NullPtr:
1538 return CXTemplateArgumentKind_NullPtr;
1539 case TemplateArgument::Integral:
1540 return CXTemplateArgumentKind_Integral;
1541 case TemplateArgument::StructuralValue:
1542 // FIXME: Expose these values.
1543 return CXTemplateArgumentKind_Invalid;
1544 case TemplateArgument::Template:
1545 return CXTemplateArgumentKind_Template;
1546 case TemplateArgument::TemplateExpansion:
1547 return CXTemplateArgumentKind_TemplateExpansion;
1548 case TemplateArgument::Expression:
1549 return CXTemplateArgumentKind_Expression;
1550 case TemplateArgument::Pack:
1551 return CXTemplateArgumentKind_Pack;
1552 }
1553
1554 return CXTemplateArgumentKind_Invalid;
1555}
1556
1557CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) {
1558 TemplateArgument TA;
1559 if (clang_Cursor_getTemplateArgument(C, I, TA: &TA) !=
1560 CXGetTemplateArgumentStatus_Success) {
1561 return cxtype::MakeCXType(T: QualType(), TU: getCursorTU(Cursor: C));
1562 }
1563
1564 if (TA.getKind() != TemplateArgument::Type) {
1565 return cxtype::MakeCXType(T: QualType(), TU: getCursorTU(Cursor: C));
1566 }
1567
1568 return cxtype::MakeCXType(T: TA.getAsType(), TU: getCursorTU(Cursor: C));
1569}
1570
1571long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) {
1572 TemplateArgument TA;
1573 if (clang_Cursor_getTemplateArgument(C, I, TA: &TA) !=
1574 CXGetTemplateArgumentStatus_Success) {
1575 assert(0 && "Unable to retrieve TemplateArgument");
1576 return 0;
1577 }
1578
1579 if (TA.getKind() != TemplateArgument::Integral) {
1580 assert(0 && "Passed template argument is not Integral");
1581 return 0;
1582 }
1583
1584 return TA.getAsIntegral().getSExtValue();
1585}
1586
1587unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C,
1588 unsigned I) {
1589 TemplateArgument TA;
1590 if (clang_Cursor_getTemplateArgument(C, I, TA: &TA) !=
1591 CXGetTemplateArgumentStatus_Success) {
1592 assert(0 && "Unable to retrieve TemplateArgument");
1593 return 0;
1594 }
1595
1596 if (TA.getKind() != TemplateArgument::Integral) {
1597 assert(0 && "Passed template argument is not Integral");
1598 return 0;
1599 }
1600
1601 return TA.getAsIntegral().getZExtValue();
1602}
1603
1604//===----------------------------------------------------------------------===//
1605// CXCursorSet.
1606//===----------------------------------------------------------------------===//
1607
1608typedef llvm::DenseMap<CXCursor, unsigned> CXCursorSet_Impl;
1609
1610static inline CXCursorSet packCXCursorSet(CXCursorSet_Impl *setImpl) {
1611 return (CXCursorSet)setImpl;
1612}
1613static inline CXCursorSet_Impl *unpackCXCursorSet(CXCursorSet set) {
1614 return (CXCursorSet_Impl *)set;
1615}
1616namespace llvm {
1617template <> struct DenseMapInfo<CXCursor> {
1618public:
1619 static inline CXCursor getEmptyKey() {
1620 return MakeCXCursorInvalid(K: CXCursor_InvalidFile);
1621 }
1622 static inline CXCursor getTombstoneKey() {
1623 return MakeCXCursorInvalid(K: CXCursor_NoDeclFound);
1624 }
1625 static inline unsigned getHashValue(const CXCursor &cursor) {
1626 return llvm::DenseMapInfo<std::pair<const void *, const void *>>::
1627 getHashValue(PairVal: std::make_pair(x: cursor.data[0], y: cursor.data[1]));
1628 }
1629 static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
1630 return x.kind == y.kind && x.data[0] == y.data[0] && x.data[1] == y.data[1];
1631 }
1632};
1633} // namespace llvm
1634
1635CXCursorSet clang_createCXCursorSet() {
1636 return packCXCursorSet(setImpl: new CXCursorSet_Impl());
1637}
1638
1639void clang_disposeCXCursorSet(CXCursorSet set) {
1640 delete unpackCXCursorSet(set);
1641}
1642
1643unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) {
1644 CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
1645 if (!setImpl)
1646 return 0;
1647 return setImpl->contains(Val: cursor);
1648}
1649
1650unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
1651 // Do not insert invalid cursors into the set.
1652 if (cursor.kind >= CXCursor_FirstInvalid &&
1653 cursor.kind <= CXCursor_LastInvalid)
1654 return 1;
1655
1656 CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
1657 if (!setImpl)
1658 return 1;
1659 unsigned &entry = (*setImpl)[cursor];
1660 unsigned flag = entry == 0 ? 1 : 0;
1661 entry = 1;
1662 return flag;
1663}
1664
1665CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
1666 enum CXCursorKind kind = clang_getCursorKind(cursor);
1667 if (clang_isDeclaration(kind)) {
1668 const Decl *decl = getCursorDecl(Cursor: cursor);
1669 if (const NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(Val: decl)) {
1670 ASTUnit *unit = getCursorASTUnit(Cursor: cursor);
1671 CodeCompletionResult Result(namedDecl, CCP_Declaration);
1672 CodeCompletionString *String = Result.CreateCodeCompletionString(
1673 Ctx&: unit->getASTContext(), PP&: unit->getPreprocessor(),
1674 CCContext: CodeCompletionContext::CCC_Other,
1675 Allocator&: unit->getCodeCompletionTUInfo().getAllocator(),
1676 CCTUInfo&: unit->getCodeCompletionTUInfo(), IncludeBriefComments: true);
1677 return String;
1678 }
1679 } else if (kind == CXCursor_MacroDefinition) {
1680 const MacroDefinitionRecord *definition = getCursorMacroDefinition(C: cursor);
1681 const IdentifierInfo *Macro = definition->getName();
1682 ASTUnit *unit = getCursorASTUnit(Cursor: cursor);
1683 CodeCompletionResult Result(
1684 Macro,
1685 unit->getPreprocessor().getMacroDefinition(II: Macro).getMacroInfo());
1686 CodeCompletionString *String = Result.CreateCodeCompletionString(
1687 Ctx&: unit->getASTContext(), PP&: unit->getPreprocessor(),
1688 CCContext: CodeCompletionContext::CCC_Other,
1689 Allocator&: unit->getCodeCompletionTUInfo().getAllocator(),
1690 CCTUInfo&: unit->getCodeCompletionTUInfo(), IncludeBriefComments: false);
1691 return String;
1692 }
1693 return nullptr;
1694}
1695
1696namespace {
1697struct OverridenCursorsPool {
1698 typedef SmallVector<CXCursor, 2> CursorVec;
1699 std::vector<CursorVec *> AllCursors;
1700 std::vector<CursorVec *> AvailableCursors;
1701
1702 ~OverridenCursorsPool() {
1703 for (std::vector<CursorVec *>::iterator I = AllCursors.begin(),
1704 E = AllCursors.end();
1705 I != E; ++I) {
1706 delete *I;
1707 }
1708 }
1709};
1710} // namespace
1711
1712void *cxcursor::createOverridenCXCursorsPool() {
1713 return new OverridenCursorsPool();
1714}
1715
1716void cxcursor::disposeOverridenCXCursorsPool(void *pool) {
1717 delete static_cast<OverridenCursorsPool *>(pool);
1718}
1719
1720void clang_getOverriddenCursors(CXCursor cursor, CXCursor **overridden,
1721 unsigned *num_overridden) {
1722 if (overridden)
1723 *overridden = nullptr;
1724 if (num_overridden)
1725 *num_overridden = 0;
1726
1727 CXTranslationUnit TU = cxcursor::getCursorTU(Cursor: cursor);
1728
1729 if (!overridden || !num_overridden || !TU)
1730 return;
1731
1732 if (!clang_isDeclaration(cursor.kind))
1733 return;
1734
1735 OverridenCursorsPool &pool =
1736 *static_cast<OverridenCursorsPool *>(TU->OverridenCursorsPool);
1737
1738 OverridenCursorsPool::CursorVec *Vec = nullptr;
1739
1740 if (!pool.AvailableCursors.empty()) {
1741 Vec = pool.AvailableCursors.back();
1742 pool.AvailableCursors.pop_back();
1743 } else {
1744 Vec = new OverridenCursorsPool::CursorVec();
1745 pool.AllCursors.push_back(x: Vec);
1746 }
1747
1748 // Clear out the vector, but don't free the memory contents. This
1749 // reduces malloc() traffic.
1750 Vec->clear();
1751
1752 // Use the first entry to contain a back reference to the vector.
1753 // This is a complete hack.
1754 CXCursor backRefCursor = MakeCXCursorInvalid(K: CXCursor_InvalidFile, TU);
1755 backRefCursor.data[0] = Vec;
1756 assert(cxcursor::getCursorTU(backRefCursor) == TU);
1757 Vec->push_back(Elt: backRefCursor);
1758
1759 // Get the overridden cursors.
1760 cxcursor::getOverriddenCursors(cursor, overridden&: *Vec);
1761
1762 // Did we get any overridden cursors? If not, return Vec to the pool
1763 // of available cursor vectors.
1764 if (Vec->size() == 1) {
1765 pool.AvailableCursors.push_back(x: Vec);
1766 return;
1767 }
1768
1769 // Now tell the caller about the overridden cursors.
1770 assert(Vec->size() > 1);
1771 *overridden = &((*Vec)[1]);
1772 *num_overridden = Vec->size() - 1;
1773}
1774
1775void clang_disposeOverriddenCursors(CXCursor *overridden) {
1776 if (!overridden)
1777 return;
1778
1779 // Use pointer arithmetic to get back the first faux entry
1780 // which has a back-reference to the TU and the vector.
1781 --overridden;
1782 OverridenCursorsPool::CursorVec *Vec =
1783 static_cast<OverridenCursorsPool::CursorVec *>(
1784 const_cast<void *>(overridden->data[0]));
1785 CXTranslationUnit TU = getCursorTU(Cursor: *overridden);
1786
1787 assert(Vec && TU);
1788
1789 OverridenCursorsPool &pool =
1790 *static_cast<OverridenCursorsPool *>(TU->OverridenCursorsPool);
1791
1792 pool.AvailableCursors.push_back(x: Vec);
1793}
1794
1795int clang_Cursor_isDynamicCall(CXCursor C) {
1796 const Expr *E = nullptr;
1797 if (clang_isExpression(C.kind))
1798 E = getCursorExpr(Cursor: C);
1799 if (!E)
1800 return 0;
1801
1802 if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(Val: E)) {
1803 if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
1804 return false;
1805 if (auto *RecE = dyn_cast<ObjCMessageExpr>(
1806 Val: MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
1807 if (RecE->getMethodFamily() == OMF_alloc)
1808 return false;
1809 }
1810 return true;
1811 }
1812
1813 if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(Val: E)) {
1814 return !PropRefE->isSuperReceiver();
1815 }
1816
1817 const MemberExpr *ME = nullptr;
1818 if (isa<MemberExpr>(Val: E))
1819 ME = cast<MemberExpr>(Val: E);
1820 else if (const CallExpr *CE = dyn_cast<CallExpr>(Val: E))
1821 ME = dyn_cast_or_null<MemberExpr>(Val: CE->getCallee());
1822
1823 if (ME) {
1824 if (const CXXMethodDecl *MD =
1825 dyn_cast_or_null<CXXMethodDecl>(Val: ME->getMemberDecl()))
1826 return MD->isVirtual() &&
1827 ME->performsVirtualDispatch(
1828 LO: cxcursor::getCursorContext(Cursor: C).getLangOpts());
1829 }
1830
1831 return 0;
1832}
1833
1834CXType clang_Cursor_getReceiverType(CXCursor C) {
1835 CXTranslationUnit TU = cxcursor::getCursorTU(Cursor: C);
1836 const Expr *E = nullptr;
1837 if (clang_isExpression(C.kind))
1838 E = getCursorExpr(Cursor: C);
1839
1840 if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(Val: E))
1841 return cxtype::MakeCXType(T: MsgE->getReceiverType(), TU);
1842
1843 if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(Val: E)) {
1844 return cxtype::MakeCXType(
1845 T: PropRefE->getReceiverType(ctx: cxcursor::getCursorContext(Cursor: C)), TU);
1846 }
1847
1848 const MemberExpr *ME = nullptr;
1849 if (isa<MemberExpr>(Val: E))
1850 ME = cast<MemberExpr>(Val: E);
1851 else if (const CallExpr *CE = dyn_cast<CallExpr>(Val: E))
1852 ME = dyn_cast_or_null<MemberExpr>(Val: CE->getCallee());
1853
1854 if (ME) {
1855 if (isa_and_nonnull<CXXMethodDecl>(Val: ME->getMemberDecl())) {
1856 auto receiverTy = ME->getBase()->IgnoreImpCasts()->getType();
1857 return cxtype::MakeCXType(T: receiverTy, TU);
1858 }
1859 }
1860
1861 return cxtype::MakeCXType(T: QualType(), TU);
1862}
1863