1 //===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines routines for manipulating CXCursors. It should be the
11 // only file that has internal knowledge of the encoding of the data in
12 // CXCursor.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "CXTranslationUnit.h"
17 #include "CXCursor.h"
18 #include "CXString.h"
19 #include "CXType.h"
20 #include "clang-c/Index.h"
21 #include "clang/AST/Attr.h"
22 #include "clang/AST/Decl.h"
23 #include "clang/AST/DeclCXX.h"
24 #include "clang/AST/DeclObjC.h"
25 #include "clang/AST/DeclTemplate.h"
26 #include "clang/AST/Expr.h"
27 #include "clang/AST/ExprCXX.h"
28 #include "clang/AST/ExprObjC.h"
29 #include "clang/Frontend/ASTUnit.h"
30 #include "llvm/Support/ErrorHandling.h"
31
32 using namespace clang;
33 using namespace cxcursor;
34
MakeCXCursorInvalid(CXCursorKind K,CXTranslationUnit TU)35 CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU) {
36 assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
37 CXCursor C = { K, 0, { nullptr, nullptr, TU } };
38 return C;
39 }
40
GetCursorKind(const Attr * A)41 static CXCursorKind GetCursorKind(const Attr *A) {
42 assert(A && "Invalid arguments!");
43 switch (A->getKind()) {
44 default: break;
45 case attr::IBAction: return CXCursor_IBActionAttr;
46 case attr::IBOutlet: return CXCursor_IBOutletAttr;
47 case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr;
48 case attr::Final: return CXCursor_CXXFinalAttr;
49 case attr::Override: return CXCursor_CXXOverrideAttr;
50 case attr::Annotate: return CXCursor_AnnotateAttr;
51 case attr::AsmLabel: return CXCursor_AsmLabelAttr;
52 case attr::Packed: return CXCursor_PackedAttr;
53 case attr::Pure: return CXCursor_PureAttr;
54 case attr::Const: return CXCursor_ConstAttr;
55 case attr::NoDuplicate: return CXCursor_NoDuplicateAttr;
56 case attr::CUDAConstant: return CXCursor_CUDAConstantAttr;
57 case attr::CUDADevice: return CXCursor_CUDADeviceAttr;
58 case attr::CUDAGlobal: return CXCursor_CUDAGlobalAttr;
59 case attr::CUDAHost: return CXCursor_CUDAHostAttr;
60 case attr::CUDAShared: return CXCursor_CUDASharedAttr;
61 case attr::Visibility: return CXCursor_VisibilityAttr;
62 case attr::DLLExport: return CXCursor_DLLExport;
63 case attr::DLLImport: return CXCursor_DLLImport;
64 }
65
66 return CXCursor_UnexposedAttr;
67 }
68
MakeCXCursor(const Attr * A,const Decl * Parent,CXTranslationUnit TU)69 CXCursor cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent,
70 CXTranslationUnit TU) {
71 assert(A && Parent && TU && "Invalid arguments!");
72 CXCursor C = { GetCursorKind(A), 0, { Parent, A, TU } };
73 return C;
74 }
75
MakeCXCursor(const Decl * D,CXTranslationUnit TU,SourceRange RegionOfInterest,bool FirstInDeclGroup)76 CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
77 SourceRange RegionOfInterest,
78 bool FirstInDeclGroup) {
79 assert(D && TU && "Invalid arguments!");
80
81 CXCursorKind K = getCursorKindForDecl(D);
82
83 if (K == CXCursor_ObjCClassMethodDecl ||
84 K == CXCursor_ObjCInstanceMethodDecl) {
85 int SelectorIdIndex = -1;
86 // Check if cursor points to a selector id.
87 if (RegionOfInterest.isValid() &&
88 RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
89 SmallVector<SourceLocation, 16> SelLocs;
90 cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
91 SmallVectorImpl<SourceLocation>::iterator
92 I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
93 if (I != SelLocs.end())
94 SelectorIdIndex = I - SelLocs.begin();
95 }
96 CXCursor C = { K, SelectorIdIndex,
97 { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
98 return C;
99 }
100
101 CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
102 return C;
103 }
104
MakeCXCursor(const Stmt * S,const Decl * Parent,CXTranslationUnit TU,SourceRange RegionOfInterest)105 CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
106 CXTranslationUnit TU,
107 SourceRange RegionOfInterest) {
108 assert(S && TU && "Invalid arguments!");
109 CXCursorKind K = CXCursor_NotImplemented;
110
111 switch (S->getStmtClass()) {
112 case Stmt::NoStmtClass:
113 break;
114
115 case Stmt::CaseStmtClass:
116 K = CXCursor_CaseStmt;
117 break;
118
119 case Stmt::DefaultStmtClass:
120 K = CXCursor_DefaultStmt;
121 break;
122
123 case Stmt::IfStmtClass:
124 K = CXCursor_IfStmt;
125 break;
126
127 case Stmt::SwitchStmtClass:
128 K = CXCursor_SwitchStmt;
129 break;
130
131 case Stmt::WhileStmtClass:
132 K = CXCursor_WhileStmt;
133 break;
134
135 case Stmt::DoStmtClass:
136 K = CXCursor_DoStmt;
137 break;
138
139 case Stmt::ForStmtClass:
140 K = CXCursor_ForStmt;
141 break;
142
143 case Stmt::GotoStmtClass:
144 K = CXCursor_GotoStmt;
145 break;
146
147 case Stmt::IndirectGotoStmtClass:
148 K = CXCursor_IndirectGotoStmt;
149 break;
150
151 case Stmt::ContinueStmtClass:
152 K = CXCursor_ContinueStmt;
153 break;
154
155 case Stmt::BreakStmtClass:
156 K = CXCursor_BreakStmt;
157 break;
158
159 case Stmt::ReturnStmtClass:
160 K = CXCursor_ReturnStmt;
161 break;
162
163 case Stmt::GCCAsmStmtClass:
164 K = CXCursor_GCCAsmStmt;
165 break;
166
167 case Stmt::MSAsmStmtClass:
168 K = CXCursor_MSAsmStmt;
169 break;
170
171 case Stmt::ObjCAtTryStmtClass:
172 K = CXCursor_ObjCAtTryStmt;
173 break;
174
175 case Stmt::ObjCAtCatchStmtClass:
176 K = CXCursor_ObjCAtCatchStmt;
177 break;
178
179 case Stmt::ObjCAtFinallyStmtClass:
180 K = CXCursor_ObjCAtFinallyStmt;
181 break;
182
183 case Stmt::ObjCAtThrowStmtClass:
184 K = CXCursor_ObjCAtThrowStmt;
185 break;
186
187 case Stmt::ObjCAtSynchronizedStmtClass:
188 K = CXCursor_ObjCAtSynchronizedStmt;
189 break;
190
191 case Stmt::ObjCAutoreleasePoolStmtClass:
192 K = CXCursor_ObjCAutoreleasePoolStmt;
193 break;
194
195 case Stmt::ObjCForCollectionStmtClass:
196 K = CXCursor_ObjCForCollectionStmt;
197 break;
198
199 case Stmt::CXXCatchStmtClass:
200 K = CXCursor_CXXCatchStmt;
201 break;
202
203 case Stmt::CXXTryStmtClass:
204 K = CXCursor_CXXTryStmt;
205 break;
206
207 case Stmt::CXXForRangeStmtClass:
208 K = CXCursor_CXXForRangeStmt;
209 break;
210
211 case Stmt::SEHTryStmtClass:
212 K = CXCursor_SEHTryStmt;
213 break;
214
215 case Stmt::SEHExceptStmtClass:
216 K = CXCursor_SEHExceptStmt;
217 break;
218
219 case Stmt::SEHFinallyStmtClass:
220 K = CXCursor_SEHFinallyStmt;
221 break;
222
223 case Stmt::SEHLeaveStmtClass:
224 K = CXCursor_SEHLeaveStmt;
225 break;
226
227 case Stmt::ArrayTypeTraitExprClass:
228 case Stmt::AsTypeExprClass:
229 case Stmt::AtomicExprClass:
230 case Stmt::BinaryConditionalOperatorClass:
231 case Stmt::TypeTraitExprClass:
232 case Stmt::CoroutineBodyStmtClass:
233 case Stmt::CoawaitExprClass:
234 case Stmt::CoreturnStmtClass:
235 case Stmt::CoyieldExprClass:
236 case Stmt::CXXBindTemporaryExprClass:
237 case Stmt::CXXDefaultArgExprClass:
238 case Stmt::CXXDefaultInitExprClass:
239 case Stmt::CXXFoldExprClass:
240 case Stmt::CXXStdInitializerListExprClass:
241 case Stmt::CXXScalarValueInitExprClass:
242 case Stmt::CXXUuidofExprClass:
243 case Stmt::ChooseExprClass:
244 case Stmt::DesignatedInitExprClass:
245 case Stmt::DesignatedInitUpdateExprClass:
246 case Stmt::ExprWithCleanupsClass:
247 case Stmt::ExpressionTraitExprClass:
248 case Stmt::ExtVectorElementExprClass:
249 case Stmt::ImplicitCastExprClass:
250 case Stmt::ImplicitValueInitExprClass:
251 case Stmt::NoInitExprClass:
252 case Stmt::MaterializeTemporaryExprClass:
253 case Stmt::ObjCIndirectCopyRestoreExprClass:
254 case Stmt::OffsetOfExprClass:
255 case Stmt::ParenListExprClass:
256 case Stmt::PredefinedExprClass:
257 case Stmt::ShuffleVectorExprClass:
258 case Stmt::ConvertVectorExprClass:
259 case Stmt::VAArgExprClass:
260 case Stmt::ObjCArrayLiteralClass:
261 case Stmt::ObjCDictionaryLiteralClass:
262 case Stmt::ObjCBoxedExprClass:
263 case Stmt::ObjCSubscriptRefExprClass:
264 K = CXCursor_UnexposedExpr;
265 break;
266
267 case Stmt::OpaqueValueExprClass:
268 if (Expr *Src = cast<OpaqueValueExpr>(S)->getSourceExpr())
269 return MakeCXCursor(Src, Parent, TU, RegionOfInterest);
270 K = CXCursor_UnexposedExpr;
271 break;
272
273 case Stmt::PseudoObjectExprClass:
274 return MakeCXCursor(cast<PseudoObjectExpr>(S)->getSyntacticForm(),
275 Parent, TU, RegionOfInterest);
276
277 case Stmt::CompoundStmtClass:
278 K = CXCursor_CompoundStmt;
279 break;
280
281 case Stmt::NullStmtClass:
282 K = CXCursor_NullStmt;
283 break;
284
285 case Stmt::LabelStmtClass:
286 K = CXCursor_LabelStmt;
287 break;
288
289 case Stmt::AttributedStmtClass:
290 K = CXCursor_UnexposedStmt;
291 break;
292
293 case Stmt::DeclStmtClass:
294 K = CXCursor_DeclStmt;
295 break;
296
297 case Stmt::CapturedStmtClass:
298 K = CXCursor_UnexposedStmt;
299 break;
300
301 case Stmt::IntegerLiteralClass:
302 K = CXCursor_IntegerLiteral;
303 break;
304
305 case Stmt::FloatingLiteralClass:
306 K = CXCursor_FloatingLiteral;
307 break;
308
309 case Stmt::ImaginaryLiteralClass:
310 K = CXCursor_ImaginaryLiteral;
311 break;
312
313 case Stmt::StringLiteralClass:
314 K = CXCursor_StringLiteral;
315 break;
316
317 case Stmt::CharacterLiteralClass:
318 K = CXCursor_CharacterLiteral;
319 break;
320
321 case Stmt::ParenExprClass:
322 K = CXCursor_ParenExpr;
323 break;
324
325 case Stmt::UnaryOperatorClass:
326 K = CXCursor_UnaryOperator;
327 break;
328
329 case Stmt::UnaryExprOrTypeTraitExprClass:
330 case Stmt::CXXNoexceptExprClass:
331 K = CXCursor_UnaryExpr;
332 break;
333
334 case Stmt::MSPropertySubscriptExprClass:
335 case Stmt::ArraySubscriptExprClass:
336 K = CXCursor_ArraySubscriptExpr;
337 break;
338
339 case Stmt::OMPArraySectionExprClass:
340 K = CXCursor_OMPArraySectionExpr;
341 break;
342
343 case Stmt::BinaryOperatorClass:
344 K = CXCursor_BinaryOperator;
345 break;
346
347 case Stmt::CompoundAssignOperatorClass:
348 K = CXCursor_CompoundAssignOperator;
349 break;
350
351 case Stmt::ConditionalOperatorClass:
352 K = CXCursor_ConditionalOperator;
353 break;
354
355 case Stmt::CStyleCastExprClass:
356 K = CXCursor_CStyleCastExpr;
357 break;
358
359 case Stmt::CompoundLiteralExprClass:
360 K = CXCursor_CompoundLiteralExpr;
361 break;
362
363 case Stmt::InitListExprClass:
364 K = CXCursor_InitListExpr;
365 break;
366
367 case Stmt::AddrLabelExprClass:
368 K = CXCursor_AddrLabelExpr;
369 break;
370
371 case Stmt::StmtExprClass:
372 K = CXCursor_StmtExpr;
373 break;
374
375 case Stmt::GenericSelectionExprClass:
376 K = CXCursor_GenericSelectionExpr;
377 break;
378
379 case Stmt::GNUNullExprClass:
380 K = CXCursor_GNUNullExpr;
381 break;
382
383 case Stmt::CXXStaticCastExprClass:
384 K = CXCursor_CXXStaticCastExpr;
385 break;
386
387 case Stmt::CXXDynamicCastExprClass:
388 K = CXCursor_CXXDynamicCastExpr;
389 break;
390
391 case Stmt::CXXReinterpretCastExprClass:
392 K = CXCursor_CXXReinterpretCastExpr;
393 break;
394
395 case Stmt::CXXConstCastExprClass:
396 K = CXCursor_CXXConstCastExpr;
397 break;
398
399 case Stmt::CXXFunctionalCastExprClass:
400 K = CXCursor_CXXFunctionalCastExpr;
401 break;
402
403 case Stmt::CXXTypeidExprClass:
404 K = CXCursor_CXXTypeidExpr;
405 break;
406
407 case Stmt::CXXBoolLiteralExprClass:
408 K = CXCursor_CXXBoolLiteralExpr;
409 break;
410
411 case Stmt::CXXNullPtrLiteralExprClass:
412 K = CXCursor_CXXNullPtrLiteralExpr;
413 break;
414
415 case Stmt::CXXThisExprClass:
416 K = CXCursor_CXXThisExpr;
417 break;
418
419 case Stmt::CXXThrowExprClass:
420 K = CXCursor_CXXThrowExpr;
421 break;
422
423 case Stmt::CXXNewExprClass:
424 K = CXCursor_CXXNewExpr;
425 break;
426
427 case Stmt::CXXDeleteExprClass:
428 K = CXCursor_CXXDeleteExpr;
429 break;
430
431 case Stmt::ObjCStringLiteralClass:
432 K = CXCursor_ObjCStringLiteral;
433 break;
434
435 case Stmt::ObjCEncodeExprClass:
436 K = CXCursor_ObjCEncodeExpr;
437 break;
438
439 case Stmt::ObjCSelectorExprClass:
440 K = CXCursor_ObjCSelectorExpr;
441 break;
442
443 case Stmt::ObjCProtocolExprClass:
444 K = CXCursor_ObjCProtocolExpr;
445 break;
446
447 case Stmt::ObjCBoolLiteralExprClass:
448 K = CXCursor_ObjCBoolLiteralExpr;
449 break;
450
451 case Stmt::ObjCBridgedCastExprClass:
452 K = CXCursor_ObjCBridgedCastExpr;
453 break;
454
455 case Stmt::BlockExprClass:
456 K = CXCursor_BlockExpr;
457 break;
458
459 case Stmt::PackExpansionExprClass:
460 K = CXCursor_PackExpansionExpr;
461 break;
462
463 case Stmt::SizeOfPackExprClass:
464 K = CXCursor_SizeOfPackExpr;
465 break;
466
467 case Stmt::DeclRefExprClass:
468 if (const ImplicitParamDecl *IPD =
469 dyn_cast_or_null<ImplicitParamDecl>(cast<DeclRefExpr>(S)->getDecl())) {
470 if (const ObjCMethodDecl *MD =
471 dyn_cast<ObjCMethodDecl>(IPD->getDeclContext())) {
472 if (MD->getSelfDecl() == IPD) {
473 K = CXCursor_ObjCSelfExpr;
474 break;
475 }
476 }
477 }
478
479 K = CXCursor_DeclRefExpr;
480 break;
481
482 case Stmt::DependentScopeDeclRefExprClass:
483 case Stmt::SubstNonTypeTemplateParmExprClass:
484 case Stmt::SubstNonTypeTemplateParmPackExprClass:
485 case Stmt::FunctionParmPackExprClass:
486 case Stmt::UnresolvedLookupExprClass:
487 case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef
488 K = CXCursor_DeclRefExpr;
489 break;
490
491 case Stmt::CXXDependentScopeMemberExprClass:
492 case Stmt::CXXPseudoDestructorExprClass:
493 case Stmt::MemberExprClass:
494 case Stmt::MSPropertyRefExprClass:
495 case Stmt::ObjCIsaExprClass:
496 case Stmt::ObjCIvarRefExprClass:
497 case Stmt::ObjCPropertyRefExprClass:
498 case Stmt::UnresolvedMemberExprClass:
499 K = CXCursor_MemberRefExpr;
500 break;
501
502 case Stmt::CallExprClass:
503 case Stmt::CXXOperatorCallExprClass:
504 case Stmt::CXXMemberCallExprClass:
505 case Stmt::CUDAKernelCallExprClass:
506 case Stmt::CXXConstructExprClass:
507 case Stmt::CXXInheritedCtorInitExprClass:
508 case Stmt::CXXTemporaryObjectExprClass:
509 case Stmt::CXXUnresolvedConstructExprClass:
510 case Stmt::UserDefinedLiteralClass:
511 K = CXCursor_CallExpr;
512 break;
513
514 case Stmt::LambdaExprClass:
515 K = CXCursor_LambdaExpr;
516 break;
517
518 case Stmt::ObjCMessageExprClass: {
519 K = CXCursor_ObjCMessageExpr;
520 int SelectorIdIndex = -1;
521 // Check if cursor points to a selector id.
522 if (RegionOfInterest.isValid() &&
523 RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
524 SmallVector<SourceLocation, 16> SelLocs;
525 cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
526 SmallVectorImpl<SourceLocation>::iterator
527 I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
528 if (I != SelLocs.end())
529 SelectorIdIndex = I - SelLocs.begin();
530 }
531 CXCursor C = { K, 0, { Parent, S, TU } };
532 return getSelectorIdentifierCursor(SelectorIdIndex, C);
533 }
534
535 case Stmt::MSDependentExistsStmtClass:
536 K = CXCursor_UnexposedStmt;
537 break;
538 case Stmt::OMPParallelDirectiveClass:
539 K = CXCursor_OMPParallelDirective;
540 break;
541 case Stmt::OMPSimdDirectiveClass:
542 K = CXCursor_OMPSimdDirective;
543 break;
544 case Stmt::OMPForDirectiveClass:
545 K = CXCursor_OMPForDirective;
546 break;
547 case Stmt::OMPForSimdDirectiveClass:
548 K = CXCursor_OMPForSimdDirective;
549 break;
550 case Stmt::OMPSectionsDirectiveClass:
551 K = CXCursor_OMPSectionsDirective;
552 break;
553 case Stmt::OMPSectionDirectiveClass:
554 K = CXCursor_OMPSectionDirective;
555 break;
556 case Stmt::OMPSingleDirectiveClass:
557 K = CXCursor_OMPSingleDirective;
558 break;
559 case Stmt::OMPMasterDirectiveClass:
560 K = CXCursor_OMPMasterDirective;
561 break;
562 case Stmt::OMPCriticalDirectiveClass:
563 K = CXCursor_OMPCriticalDirective;
564 break;
565 case Stmt::OMPParallelForDirectiveClass:
566 K = CXCursor_OMPParallelForDirective;
567 break;
568 case Stmt::OMPParallelForSimdDirectiveClass:
569 K = CXCursor_OMPParallelForSimdDirective;
570 break;
571 case Stmt::OMPParallelSectionsDirectiveClass:
572 K = CXCursor_OMPParallelSectionsDirective;
573 break;
574 case Stmt::OMPTaskDirectiveClass:
575 K = CXCursor_OMPTaskDirective;
576 break;
577 case Stmt::OMPTaskyieldDirectiveClass:
578 K = CXCursor_OMPTaskyieldDirective;
579 break;
580 case Stmt::OMPBarrierDirectiveClass:
581 K = CXCursor_OMPBarrierDirective;
582 break;
583 case Stmt::OMPTaskwaitDirectiveClass:
584 K = CXCursor_OMPTaskwaitDirective;
585 break;
586 case Stmt::OMPTaskgroupDirectiveClass:
587 K = CXCursor_OMPTaskgroupDirective;
588 break;
589 case Stmt::OMPFlushDirectiveClass:
590 K = CXCursor_OMPFlushDirective;
591 break;
592 case Stmt::OMPOrderedDirectiveClass:
593 K = CXCursor_OMPOrderedDirective;
594 break;
595 case Stmt::OMPAtomicDirectiveClass:
596 K = CXCursor_OMPAtomicDirective;
597 break;
598 case Stmt::OMPTargetDirectiveClass:
599 K = CXCursor_OMPTargetDirective;
600 break;
601 case Stmt::OMPTargetDataDirectiveClass:
602 K = CXCursor_OMPTargetDataDirective;
603 break;
604 case Stmt::OMPTargetEnterDataDirectiveClass:
605 K = CXCursor_OMPTargetEnterDataDirective;
606 break;
607 case Stmt::OMPTargetExitDataDirectiveClass:
608 K = CXCursor_OMPTargetExitDataDirective;
609 break;
610 case Stmt::OMPTargetParallelDirectiveClass:
611 K = CXCursor_OMPTargetParallelDirective;
612 break;
613 case Stmt::OMPTargetParallelForDirectiveClass:
614 K = CXCursor_OMPTargetParallelForDirective;
615 break;
616 case Stmt::OMPTargetUpdateDirectiveClass:
617 K = CXCursor_OMPTargetUpdateDirective;
618 break;
619 case Stmt::OMPTeamsDirectiveClass:
620 K = CXCursor_OMPTeamsDirective;
621 break;
622 case Stmt::OMPCancellationPointDirectiveClass:
623 K = CXCursor_OMPCancellationPointDirective;
624 break;
625 case Stmt::OMPCancelDirectiveClass:
626 K = CXCursor_OMPCancelDirective;
627 break;
628 case Stmt::OMPTaskLoopDirectiveClass:
629 K = CXCursor_OMPTaskLoopDirective;
630 break;
631 case Stmt::OMPTaskLoopSimdDirectiveClass:
632 K = CXCursor_OMPTaskLoopSimdDirective;
633 break;
634 case Stmt::OMPDistributeDirectiveClass:
635 K = CXCursor_OMPDistributeDirective;
636 break;
637 case Stmt::OMPDistributeParallelForDirectiveClass:
638 K = CXCursor_OMPDistributeParallelForDirective;
639 break;
640 case Stmt::OMPDistributeParallelForSimdDirectiveClass:
641 K = CXCursor_OMPDistributeParallelForSimdDirective;
642 break;
643 case Stmt::OMPDistributeSimdDirectiveClass:
644 K = CXCursor_OMPDistributeSimdDirective;
645 break;
646 case Stmt::OMPTargetParallelForSimdDirectiveClass:
647 K = CXCursor_OMPTargetParallelForSimdDirective;
648 break;
649 }
650
651 CXCursor C = { K, 0, { Parent, S, TU } };
652 return C;
653 }
654
MakeCursorObjCSuperClassRef(ObjCInterfaceDecl * Super,SourceLocation Loc,CXTranslationUnit TU)655 CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
656 SourceLocation Loc,
657 CXTranslationUnit TU) {
658 assert(Super && TU && "Invalid arguments!");
659 void *RawLoc = Loc.getPtrEncoding();
660 CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
661 return C;
662 }
663
664 std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCSuperClassRef(CXCursor C)665 cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
666 assert(C.kind == CXCursor_ObjCSuperClassRef);
667 return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
668 SourceLocation::getFromPtrEncoding(C.data[1]));
669 }
670
MakeCursorObjCProtocolRef(const ObjCProtocolDecl * Proto,SourceLocation Loc,CXTranslationUnit TU)671 CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
672 SourceLocation Loc,
673 CXTranslationUnit TU) {
674 assert(Proto && TU && "Invalid arguments!");
675 void *RawLoc = Loc.getPtrEncoding();
676 CXCursor C = { CXCursor_ObjCProtocolRef, 0, { Proto, RawLoc, TU } };
677 return C;
678 }
679
680 std::pair<const ObjCProtocolDecl *, SourceLocation>
getCursorObjCProtocolRef(CXCursor C)681 cxcursor::getCursorObjCProtocolRef(CXCursor C) {
682 assert(C.kind == CXCursor_ObjCProtocolRef);
683 return std::make_pair(static_cast<const ObjCProtocolDecl *>(C.data[0]),
684 SourceLocation::getFromPtrEncoding(C.data[1]));
685 }
686
MakeCursorObjCClassRef(const ObjCInterfaceDecl * Class,SourceLocation Loc,CXTranslationUnit TU)687 CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
688 SourceLocation Loc,
689 CXTranslationUnit TU) {
690 // 'Class' can be null for invalid code.
691 if (!Class)
692 return MakeCXCursorInvalid(CXCursor_InvalidCode);
693 assert(TU && "Invalid arguments!");
694 void *RawLoc = Loc.getPtrEncoding();
695 CXCursor C = { CXCursor_ObjCClassRef, 0, { Class, RawLoc, TU } };
696 return C;
697 }
698
699 std::pair<const ObjCInterfaceDecl *, SourceLocation>
getCursorObjCClassRef(CXCursor C)700 cxcursor::getCursorObjCClassRef(CXCursor C) {
701 assert(C.kind == CXCursor_ObjCClassRef);
702 return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
703 SourceLocation::getFromPtrEncoding(C.data[1]));
704 }
705
MakeCursorTypeRef(const TypeDecl * Type,SourceLocation Loc,CXTranslationUnit TU)706 CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
707 CXTranslationUnit TU) {
708 assert(Type && TU && "Invalid arguments!");
709 void *RawLoc = Loc.getPtrEncoding();
710 CXCursor C = { CXCursor_TypeRef, 0, { Type, RawLoc, TU } };
711 return C;
712 }
713
714 std::pair<const TypeDecl *, SourceLocation>
getCursorTypeRef(CXCursor C)715 cxcursor::getCursorTypeRef(CXCursor C) {
716 assert(C.kind == CXCursor_TypeRef);
717 return std::make_pair(static_cast<const TypeDecl *>(C.data[0]),
718 SourceLocation::getFromPtrEncoding(C.data[1]));
719 }
720
MakeCursorTemplateRef(const TemplateDecl * Template,SourceLocation Loc,CXTranslationUnit TU)721 CXCursor cxcursor::MakeCursorTemplateRef(const TemplateDecl *Template,
722 SourceLocation Loc,
723 CXTranslationUnit TU) {
724 assert(Template && TU && "Invalid arguments!");
725 void *RawLoc = Loc.getPtrEncoding();
726 CXCursor C = { CXCursor_TemplateRef, 0, { Template, RawLoc, TU } };
727 return C;
728 }
729
730 std::pair<const TemplateDecl *, SourceLocation>
getCursorTemplateRef(CXCursor C)731 cxcursor::getCursorTemplateRef(CXCursor C) {
732 assert(C.kind == CXCursor_TemplateRef);
733 return std::make_pair(static_cast<const TemplateDecl *>(C.data[0]),
734 SourceLocation::getFromPtrEncoding(C.data[1]));
735 }
736
MakeCursorNamespaceRef(const NamedDecl * NS,SourceLocation Loc,CXTranslationUnit TU)737 CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
738 SourceLocation Loc,
739 CXTranslationUnit TU) {
740
741 assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
742 "Invalid arguments!");
743 void *RawLoc = Loc.getPtrEncoding();
744 CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
745 return C;
746 }
747
748 std::pair<const NamedDecl *, SourceLocation>
getCursorNamespaceRef(CXCursor C)749 cxcursor::getCursorNamespaceRef(CXCursor C) {
750 assert(C.kind == CXCursor_NamespaceRef);
751 return std::make_pair(static_cast<const NamedDecl *>(C.data[0]),
752 SourceLocation::getFromPtrEncoding(C.data[1]));
753 }
754
MakeCursorVariableRef(const VarDecl * Var,SourceLocation Loc,CXTranslationUnit TU)755 CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
756 CXTranslationUnit TU) {
757
758 assert(Var && TU && "Invalid arguments!");
759 void *RawLoc = Loc.getPtrEncoding();
760 CXCursor C = { CXCursor_VariableRef, 0, { Var, RawLoc, TU } };
761 return C;
762 }
763
764 std::pair<const VarDecl *, SourceLocation>
getCursorVariableRef(CXCursor C)765 cxcursor::getCursorVariableRef(CXCursor C) {
766 assert(C.kind == CXCursor_VariableRef);
767 return std::make_pair(static_cast<const VarDecl *>(C.data[0]),
768 SourceLocation::getFromPtrEncoding(C.data[1]));
769 }
770
MakeCursorMemberRef(const FieldDecl * Field,SourceLocation Loc,CXTranslationUnit TU)771 CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field, SourceLocation Loc,
772 CXTranslationUnit TU) {
773
774 assert(Field && TU && "Invalid arguments!");
775 void *RawLoc = Loc.getPtrEncoding();
776 CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
777 return C;
778 }
779
780 std::pair<const FieldDecl *, SourceLocation>
getCursorMemberRef(CXCursor C)781 cxcursor::getCursorMemberRef(CXCursor C) {
782 assert(C.kind == CXCursor_MemberRef);
783 return std::make_pair(static_cast<const FieldDecl *>(C.data[0]),
784 SourceLocation::getFromPtrEncoding(C.data[1]));
785 }
786
MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier * B,CXTranslationUnit TU)787 CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
788 CXTranslationUnit TU){
789 CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, nullptr, TU } };
790 return C;
791 }
792
getCursorCXXBaseSpecifier(CXCursor C)793 const CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
794 assert(C.kind == CXCursor_CXXBaseSpecifier);
795 return static_cast<const CXXBaseSpecifier*>(C.data[0]);
796 }
797
MakePreprocessingDirectiveCursor(SourceRange Range,CXTranslationUnit TU)798 CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
799 CXTranslationUnit TU) {
800 CXCursor C = { CXCursor_PreprocessingDirective, 0,
801 { Range.getBegin().getPtrEncoding(),
802 Range.getEnd().getPtrEncoding(),
803 TU }
804 };
805 return C;
806 }
807
getCursorPreprocessingDirective(CXCursor C)808 SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
809 assert(C.kind == CXCursor_PreprocessingDirective);
810 SourceRange Range(SourceLocation::getFromPtrEncoding(C.data[0]),
811 SourceLocation::getFromPtrEncoding(C.data[1]));
812 ASTUnit *TU = getCursorASTUnit(C);
813 return TU->mapRangeFromPreamble(Range);
814 }
815
MakeMacroDefinitionCursor(const MacroDefinitionRecord * MI,CXTranslationUnit TU)816 CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinitionRecord *MI,
817 CXTranslationUnit TU) {
818 CXCursor C = {CXCursor_MacroDefinition, 0, {MI, nullptr, TU}};
819 return C;
820 }
821
getCursorMacroDefinition(CXCursor C)822 const MacroDefinitionRecord *cxcursor::getCursorMacroDefinition(CXCursor C) {
823 assert(C.kind == CXCursor_MacroDefinition);
824 return static_cast<const MacroDefinitionRecord *>(C.data[0]);
825 }
826
MakeMacroExpansionCursor(MacroExpansion * MI,CXTranslationUnit TU)827 CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
828 CXTranslationUnit TU) {
829 CXCursor C = { CXCursor_MacroExpansion, 0, { MI, nullptr, TU } };
830 return C;
831 }
832
MakeMacroExpansionCursor(MacroDefinitionRecord * MI,SourceLocation Loc,CXTranslationUnit TU)833 CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinitionRecord *MI,
834 SourceLocation Loc,
835 CXTranslationUnit TU) {
836 assert(Loc.isValid());
837 CXCursor C = {CXCursor_MacroExpansion, 0, {MI, Loc.getPtrEncoding(), TU}};
838 return C;
839 }
840
getName() const841 const IdentifierInfo *cxcursor::MacroExpansionCursor::getName() const {
842 if (isPseudo())
843 return getAsMacroDefinition()->getName();
844 return getAsMacroExpansion()->getName();
845 }
846 const MacroDefinitionRecord *
getDefinition() const847 cxcursor::MacroExpansionCursor::getDefinition() const {
848 if (isPseudo())
849 return getAsMacroDefinition();
850 return getAsMacroExpansion()->getDefinition();
851 }
getSourceRange() const852 SourceRange cxcursor::MacroExpansionCursor::getSourceRange() const {
853 if (isPseudo())
854 return getPseudoLoc();
855 return getAsMacroExpansion()->getSourceRange();
856 }
857
MakeInclusionDirectiveCursor(InclusionDirective * ID,CXTranslationUnit TU)858 CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
859 CXTranslationUnit TU) {
860 CXCursor C = { CXCursor_InclusionDirective, 0, { ID, nullptr, TU } };
861 return C;
862 }
863
getCursorInclusionDirective(CXCursor C)864 const InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
865 assert(C.kind == CXCursor_InclusionDirective);
866 return static_cast<const InclusionDirective *>(C.data[0]);
867 }
868
MakeCursorLabelRef(LabelStmt * Label,SourceLocation Loc,CXTranslationUnit TU)869 CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
870 CXTranslationUnit TU) {
871
872 assert(Label && TU && "Invalid arguments!");
873 void *RawLoc = Loc.getPtrEncoding();
874 CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
875 return C;
876 }
877
878 std::pair<const LabelStmt *, SourceLocation>
getCursorLabelRef(CXCursor C)879 cxcursor::getCursorLabelRef(CXCursor C) {
880 assert(C.kind == CXCursor_LabelRef);
881 return std::make_pair(static_cast<const LabelStmt *>(C.data[0]),
882 SourceLocation::getFromPtrEncoding(C.data[1]));
883 }
884
MakeCursorOverloadedDeclRef(const OverloadExpr * E,CXTranslationUnit TU)885 CXCursor cxcursor::MakeCursorOverloadedDeclRef(const OverloadExpr *E,
886 CXTranslationUnit TU) {
887 assert(E && TU && "Invalid arguments!");
888 OverloadedDeclRefStorage Storage(E);
889 void *RawLoc = E->getNameLoc().getPtrEncoding();
890 CXCursor C = {
891 CXCursor_OverloadedDeclRef, 0,
892 { Storage.getOpaqueValue(), RawLoc, TU }
893 };
894 return C;
895 }
896
MakeCursorOverloadedDeclRef(const Decl * D,SourceLocation Loc,CXTranslationUnit TU)897 CXCursor cxcursor::MakeCursorOverloadedDeclRef(const Decl *D,
898 SourceLocation Loc,
899 CXTranslationUnit TU) {
900 assert(D && TU && "Invalid arguments!");
901 void *RawLoc = Loc.getPtrEncoding();
902 OverloadedDeclRefStorage Storage(D);
903 CXCursor C = {
904 CXCursor_OverloadedDeclRef, 0,
905 { Storage.getOpaqueValue(), RawLoc, TU }
906 };
907 return C;
908 }
909
MakeCursorOverloadedDeclRef(TemplateName Name,SourceLocation Loc,CXTranslationUnit TU)910 CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
911 SourceLocation Loc,
912 CXTranslationUnit TU) {
913 assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
914 void *RawLoc = Loc.getPtrEncoding();
915 OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
916 CXCursor C = {
917 CXCursor_OverloadedDeclRef, 0,
918 { Storage.getOpaqueValue(), RawLoc, TU }
919 };
920 return C;
921 }
922
923 std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
getCursorOverloadedDeclRef(CXCursor C)924 cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
925 assert(C.kind == CXCursor_OverloadedDeclRef);
926 return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(
927 const_cast<void *>(C.data[0])),
928 SourceLocation::getFromPtrEncoding(C.data[1]));
929 }
930
getCursorDecl(CXCursor Cursor)931 const Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
932 return static_cast<const Decl *>(Cursor.data[0]);
933 }
934
getCursorExpr(CXCursor Cursor)935 const Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
936 return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
937 }
938
getCursorStmt(CXCursor Cursor)939 const Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
940 if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
941 Cursor.kind == CXCursor_ObjCProtocolRef ||
942 Cursor.kind == CXCursor_ObjCClassRef)
943 return nullptr;
944
945 return static_cast<const Stmt *>(Cursor.data[1]);
946 }
947
getCursorAttr(CXCursor Cursor)948 const Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
949 return static_cast<const Attr *>(Cursor.data[1]);
950 }
951
getCursorParentDecl(CXCursor Cursor)952 const Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
953 return static_cast<const Decl *>(Cursor.data[0]);
954 }
955
getCursorContext(CXCursor Cursor)956 ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
957 return getCursorASTUnit(Cursor)->getASTContext();
958 }
959
getCursorASTUnit(CXCursor Cursor)960 ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
961 CXTranslationUnit TU = getCursorTU(Cursor);
962 if (!TU)
963 return nullptr;
964 return cxtu::getASTUnit(TU);
965 }
966
getCursorTU(CXCursor Cursor)967 CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
968 return static_cast<CXTranslationUnit>(const_cast<void*>(Cursor.data[2]));
969 }
970
getOverriddenCursors(CXCursor cursor,SmallVectorImpl<CXCursor> & overridden)971 void cxcursor::getOverriddenCursors(CXCursor cursor,
972 SmallVectorImpl<CXCursor> &overridden) {
973 assert(clang_isDeclaration(cursor.kind));
974 const NamedDecl *D = dyn_cast_or_null<NamedDecl>(getCursorDecl(cursor));
975 if (!D)
976 return;
977
978 CXTranslationUnit TU = getCursorTU(cursor);
979 SmallVector<const NamedDecl *, 8> OverDecls;
980 D->getASTContext().getOverriddenMethods(D, OverDecls);
981
982 for (SmallVectorImpl<const NamedDecl *>::iterator
983 I = OverDecls.begin(), E = OverDecls.end(); I != E; ++I) {
984 overridden.push_back(MakeCXCursor(*I, TU));
985 }
986 }
987
988 std::pair<int, SourceLocation>
getSelectorIdentifierIndexAndLoc(CXCursor cursor)989 cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
990 if (cursor.kind == CXCursor_ObjCMessageExpr) {
991 if (cursor.xdata != -1)
992 return std::make_pair(cursor.xdata,
993 cast<ObjCMessageExpr>(getCursorExpr(cursor))
994 ->getSelectorLoc(cursor.xdata));
995 } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
996 cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
997 if (cursor.xdata != -1)
998 return std::make_pair(cursor.xdata,
999 cast<ObjCMethodDecl>(getCursorDecl(cursor))
1000 ->getSelectorLoc(cursor.xdata));
1001 }
1002
1003 return std::make_pair(-1, SourceLocation());
1004 }
1005
getSelectorIdentifierCursor(int SelIdx,CXCursor cursor)1006 CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
1007 CXCursor newCursor = cursor;
1008
1009 if (cursor.kind == CXCursor_ObjCMessageExpr) {
1010 if (SelIdx == -1 ||
1011 unsigned(SelIdx) >= cast<ObjCMessageExpr>(getCursorExpr(cursor))
1012 ->getNumSelectorLocs())
1013 newCursor.xdata = -1;
1014 else
1015 newCursor.xdata = SelIdx;
1016 } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
1017 cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
1018 if (SelIdx == -1 ||
1019 unsigned(SelIdx) >= cast<ObjCMethodDecl>(getCursorDecl(cursor))
1020 ->getNumSelectorLocs())
1021 newCursor.xdata = -1;
1022 else
1023 newCursor.xdata = SelIdx;
1024 }
1025
1026 return newCursor;
1027 }
1028
getTypeRefCursor(CXCursor cursor)1029 CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
1030 if (cursor.kind != CXCursor_CallExpr)
1031 return cursor;
1032
1033 if (cursor.xdata == 0)
1034 return cursor;
1035
1036 const Expr *E = getCursorExpr(cursor);
1037 TypeSourceInfo *Type = nullptr;
1038 if (const CXXUnresolvedConstructExpr *
1039 UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
1040 Type = UnCtor->getTypeSourceInfo();
1041 } else if (const CXXTemporaryObjectExpr *Tmp =
1042 dyn_cast<CXXTemporaryObjectExpr>(E)){
1043 Type = Tmp->getTypeSourceInfo();
1044 }
1045
1046 if (!Type)
1047 return cursor;
1048
1049 CXTranslationUnit TU = getCursorTU(cursor);
1050 QualType Ty = Type->getType();
1051 TypeLoc TL = Type->getTypeLoc();
1052 SourceLocation Loc = TL.getBeginLoc();
1053
1054 if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
1055 Ty = ElabT->getNamedType();
1056 ElaboratedTypeLoc ElabTL = TL.castAs<ElaboratedTypeLoc>();
1057 Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
1058 }
1059
1060 if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
1061 return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
1062 if (const TagType *Tag = Ty->getAs<TagType>())
1063 return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
1064 if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
1065 return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
1066
1067 return cursor;
1068 }
1069
operator ==(CXCursor X,CXCursor Y)1070 bool cxcursor::operator==(CXCursor X, CXCursor Y) {
1071 return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
1072 X.data[2] == Y.data[2];
1073 }
1074
1075 // FIXME: Remove once we can model DeclGroups and their appropriate ranges
1076 // properly in the ASTs.
isFirstInDeclGroup(CXCursor C)1077 bool cxcursor::isFirstInDeclGroup(CXCursor C) {
1078 assert(clang_isDeclaration(C.kind));
1079 return ((uintptr_t) (C.data[1])) != 0;
1080 }
1081
1082 //===----------------------------------------------------------------------===//
1083 // libclang CXCursor APIs
1084 //===----------------------------------------------------------------------===//
1085
1086 extern "C" {
1087
clang_Cursor_isNull(CXCursor cursor)1088 int clang_Cursor_isNull(CXCursor cursor) {
1089 return clang_equalCursors(cursor, clang_getNullCursor());
1090 }
1091
clang_Cursor_getTranslationUnit(CXCursor cursor)1092 CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
1093 return getCursorTU(cursor);
1094 }
1095
clang_Cursor_getNumArguments(CXCursor C)1096 int clang_Cursor_getNumArguments(CXCursor C) {
1097 if (clang_isDeclaration(C.kind)) {
1098 const Decl *D = cxcursor::getCursorDecl(C);
1099 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
1100 return MD->param_size();
1101 if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
1102 return FD->param_size();
1103 }
1104
1105 if (clang_isExpression(C.kind)) {
1106 const Expr *E = cxcursor::getCursorExpr(C);
1107 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1108 return CE->getNumArgs();
1109 }
1110 }
1111
1112 return -1;
1113 }
1114
clang_Cursor_getArgument(CXCursor C,unsigned i)1115 CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
1116 if (clang_isDeclaration(C.kind)) {
1117 const Decl *D = cxcursor::getCursorDecl(C);
1118 if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
1119 if (i < MD->param_size())
1120 return cxcursor::MakeCXCursor(MD->parameters()[i],
1121 cxcursor::getCursorTU(C));
1122 } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
1123 if (i < FD->param_size())
1124 return cxcursor::MakeCXCursor(FD->parameters()[i],
1125 cxcursor::getCursorTU(C));
1126 }
1127 }
1128
1129 if (clang_isExpression(C.kind)) {
1130 const Expr *E = cxcursor::getCursorExpr(C);
1131 if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
1132 if (i < CE->getNumArgs()) {
1133 return cxcursor::MakeCXCursor(CE->getArg(i),
1134 getCursorDecl(C),
1135 cxcursor::getCursorTU(C));
1136 }
1137 }
1138 }
1139
1140 return clang_getNullCursor();
1141 }
1142
clang_Cursor_getNumTemplateArguments(CXCursor C)1143 int clang_Cursor_getNumTemplateArguments(CXCursor C) {
1144 if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
1145 return -1;
1146 }
1147
1148 const FunctionDecl *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(
1149 getCursorDecl(C));
1150 if (!FD) {
1151 return -1;
1152 }
1153
1154 const FunctionTemplateSpecializationInfo* SpecInfo =
1155 FD->getTemplateSpecializationInfo();
1156 if (!SpecInfo) {
1157 return -1;
1158 }
1159
1160 return SpecInfo->TemplateArguments->size();
1161 }
1162
1163 enum CXGetTemplateArgumentStatus {
1164 /** \brief The operation completed successfully */
1165 CXGetTemplateArgumentStatus_Success = 0,
1166
1167 /** \brief The specified cursor did not represent a FunctionDecl. */
1168 CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1,
1169
1170 /** \brief The specified cursor was not castable to a FunctionDecl. */
1171 CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2,
1172
1173 /** \brief A NULL FunctionTemplateSpecializationInfo was retrieved. */
1174 CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3,
1175
1176 /** \brief An invalid (OOB) argument index was specified */
1177 CXGetTemplateArgumentStatus_InvalidIndex = -4
1178 };
1179
clang_Cursor_getTemplateArgument(CXCursor C,unsigned I,TemplateArgument * TA)1180 static int clang_Cursor_getTemplateArgument(
1181 CXCursor C, unsigned I, TemplateArgument *TA) {
1182 if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
1183 return CXGetTemplateArgumentStatus_CursorNotFunctionDecl;
1184 }
1185
1186 const FunctionDecl *FD = llvm::dyn_cast_or_null<clang::FunctionDecl>(
1187 getCursorDecl(C));
1188 if (!FD) {
1189 return CXGetTemplateArgumentStatus_BadFunctionDeclCast;
1190 }
1191
1192 const FunctionTemplateSpecializationInfo* SpecInfo =
1193 FD->getTemplateSpecializationInfo();
1194 if (!SpecInfo) {
1195 return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
1196 }
1197
1198 if (I >= SpecInfo->TemplateArguments->size()) {
1199 return CXGetTemplateArgumentStatus_InvalidIndex;
1200 }
1201
1202 *TA = SpecInfo->TemplateArguments->get(I);
1203 return 0;
1204 }
1205
clang_Cursor_getTemplateArgumentKind(CXCursor C,unsigned I)1206 enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
1207 unsigned I) {
1208 TemplateArgument TA;
1209 if (clang_Cursor_getTemplateArgument(C, I, &TA)) {
1210 return CXTemplateArgumentKind_Invalid;
1211 }
1212
1213 switch (TA.getKind()) {
1214 case TemplateArgument::Null: return CXTemplateArgumentKind_Null;
1215 case TemplateArgument::Type: return CXTemplateArgumentKind_Type;
1216 case TemplateArgument::Declaration:
1217 return CXTemplateArgumentKind_Declaration;
1218 case TemplateArgument::NullPtr: return CXTemplateArgumentKind_NullPtr;
1219 case TemplateArgument::Integral: return CXTemplateArgumentKind_Integral;
1220 case TemplateArgument::Template: return CXTemplateArgumentKind_Template;
1221 case TemplateArgument::TemplateExpansion:
1222 return CXTemplateArgumentKind_TemplateExpansion;
1223 case TemplateArgument::Expression: return CXTemplateArgumentKind_Expression;
1224 case TemplateArgument::Pack: return CXTemplateArgumentKind_Pack;
1225 }
1226
1227 return CXTemplateArgumentKind_Invalid;
1228 }
1229
clang_Cursor_getTemplateArgumentType(CXCursor C,unsigned I)1230 CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) {
1231 TemplateArgument TA;
1232 if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
1233 CXGetTemplateArgumentStatus_Success) {
1234 return cxtype::MakeCXType(QualType(), getCursorTU(C));
1235 }
1236
1237 if (TA.getKind() != TemplateArgument::Type) {
1238 return cxtype::MakeCXType(QualType(), getCursorTU(C));
1239 }
1240
1241 return cxtype::MakeCXType(TA.getAsType(), getCursorTU(C));
1242 }
1243
clang_Cursor_getTemplateArgumentValue(CXCursor C,unsigned I)1244 long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) {
1245 TemplateArgument TA;
1246 if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
1247 CXGetTemplateArgumentStatus_Success) {
1248 assert(0 && "Unable to retrieve TemplateArgument");
1249 return 0;
1250 }
1251
1252 if (TA.getKind() != TemplateArgument::Integral) {
1253 assert(0 && "Passed template argument is not Integral");
1254 return 0;
1255 }
1256
1257 return TA.getAsIntegral().getSExtValue();
1258 }
1259
clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C,unsigned I)1260 unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C,
1261 unsigned I) {
1262 TemplateArgument TA;
1263 if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
1264 CXGetTemplateArgumentStatus_Success) {
1265 assert(0 && "Unable to retrieve TemplateArgument");
1266 return 0;
1267 }
1268
1269 if (TA.getKind() != TemplateArgument::Integral) {
1270 assert(0 && "Passed template argument is not Integral");
1271 return 0;
1272 }
1273
1274 return TA.getAsIntegral().getZExtValue();
1275 }
1276
1277 } // end: extern "C"
1278
1279 //===----------------------------------------------------------------------===//
1280 // CXCursorSet.
1281 //===----------------------------------------------------------------------===//
1282
1283 typedef llvm::DenseMap<CXCursor, unsigned> CXCursorSet_Impl;
1284
packCXCursorSet(CXCursorSet_Impl * setImpl)1285 static inline CXCursorSet packCXCursorSet(CXCursorSet_Impl *setImpl) {
1286 return (CXCursorSet) setImpl;
1287 }
unpackCXCursorSet(CXCursorSet set)1288 static inline CXCursorSet_Impl *unpackCXCursorSet(CXCursorSet set) {
1289 return (CXCursorSet_Impl*) set;
1290 }
1291 namespace llvm {
1292 template<> struct DenseMapInfo<CXCursor> {
1293 public:
getEmptyKeyllvm::DenseMapInfo1294 static inline CXCursor getEmptyKey() {
1295 return MakeCXCursorInvalid(CXCursor_InvalidFile);
1296 }
getTombstoneKeyllvm::DenseMapInfo1297 static inline CXCursor getTombstoneKey() {
1298 return MakeCXCursorInvalid(CXCursor_NoDeclFound);
1299 }
getHashValuellvm::DenseMapInfo1300 static inline unsigned getHashValue(const CXCursor &cursor) {
1301 return llvm::DenseMapInfo<std::pair<const void *, const void *> >
1302 ::getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
1303 }
isEqualllvm::DenseMapInfo1304 static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
1305 return x.kind == y.kind &&
1306 x.data[0] == y.data[0] &&
1307 x.data[1] == y.data[1];
1308 }
1309 };
1310 }
1311
1312 extern "C" {
clang_createCXCursorSet()1313 CXCursorSet clang_createCXCursorSet() {
1314 return packCXCursorSet(new CXCursorSet_Impl());
1315 }
1316
clang_disposeCXCursorSet(CXCursorSet set)1317 void clang_disposeCXCursorSet(CXCursorSet set) {
1318 delete unpackCXCursorSet(set);
1319 }
1320
clang_CXCursorSet_contains(CXCursorSet set,CXCursor cursor)1321 unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) {
1322 CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
1323 if (!setImpl)
1324 return 0;
1325 return setImpl->find(cursor) != setImpl->end();
1326 }
1327
clang_CXCursorSet_insert(CXCursorSet set,CXCursor cursor)1328 unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
1329 // Do not insert invalid cursors into the set.
1330 if (cursor.kind >= CXCursor_FirstInvalid &&
1331 cursor.kind <= CXCursor_LastInvalid)
1332 return 1;
1333
1334 CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
1335 if (!setImpl)
1336 return 1;
1337 unsigned &entry = (*setImpl)[cursor];
1338 unsigned flag = entry == 0 ? 1 : 0;
1339 entry = 1;
1340 return flag;
1341 }
1342
clang_getCursorCompletionString(CXCursor cursor)1343 CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
1344 enum CXCursorKind kind = clang_getCursorKind(cursor);
1345 if (clang_isDeclaration(kind)) {
1346 const Decl *decl = getCursorDecl(cursor);
1347 if (const NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
1348 ASTUnit *unit = getCursorASTUnit(cursor);
1349 CodeCompletionResult Result(namedDecl, CCP_Declaration);
1350 CodeCompletionString *String
1351 = Result.CreateCodeCompletionString(unit->getASTContext(),
1352 unit->getPreprocessor(),
1353 CodeCompletionContext::CCC_Other,
1354 unit->getCodeCompletionTUInfo().getAllocator(),
1355 unit->getCodeCompletionTUInfo(),
1356 true);
1357 return String;
1358 }
1359 } else if (kind == CXCursor_MacroDefinition) {
1360 const MacroDefinitionRecord *definition = getCursorMacroDefinition(cursor);
1361 const IdentifierInfo *MacroInfo = definition->getName();
1362 ASTUnit *unit = getCursorASTUnit(cursor);
1363 CodeCompletionResult Result(MacroInfo);
1364 CodeCompletionString *String
1365 = Result.CreateCodeCompletionString(unit->getASTContext(),
1366 unit->getPreprocessor(),
1367 CodeCompletionContext::CCC_Other,
1368 unit->getCodeCompletionTUInfo().getAllocator(),
1369 unit->getCodeCompletionTUInfo(),
1370 false);
1371 return String;
1372 }
1373 return nullptr;
1374 }
1375 } // end: extern C.
1376
1377 namespace {
1378 struct OverridenCursorsPool {
1379 typedef SmallVector<CXCursor, 2> CursorVec;
1380 std::vector<CursorVec*> AllCursors;
1381 std::vector<CursorVec*> AvailableCursors;
1382
~OverridenCursorsPool__anon813e07f70111::OverridenCursorsPool1383 ~OverridenCursorsPool() {
1384 for (std::vector<CursorVec*>::iterator I = AllCursors.begin(),
1385 E = AllCursors.end(); I != E; ++I) {
1386 delete *I;
1387 }
1388 }
1389 };
1390 }
1391
createOverridenCXCursorsPool()1392 void *cxcursor::createOverridenCXCursorsPool() {
1393 return new OverridenCursorsPool();
1394 }
1395
disposeOverridenCXCursorsPool(void * pool)1396 void cxcursor::disposeOverridenCXCursorsPool(void *pool) {
1397 delete static_cast<OverridenCursorsPool*>(pool);
1398 }
1399
1400 extern "C" {
clang_getOverriddenCursors(CXCursor cursor,CXCursor ** overridden,unsigned * num_overridden)1401 void clang_getOverriddenCursors(CXCursor cursor,
1402 CXCursor **overridden,
1403 unsigned *num_overridden) {
1404 if (overridden)
1405 *overridden = nullptr;
1406 if (num_overridden)
1407 *num_overridden = 0;
1408
1409 CXTranslationUnit TU = cxcursor::getCursorTU(cursor);
1410
1411 if (!overridden || !num_overridden || !TU)
1412 return;
1413
1414 if (!clang_isDeclaration(cursor.kind))
1415 return;
1416
1417 OverridenCursorsPool &pool =
1418 *static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
1419
1420 OverridenCursorsPool::CursorVec *Vec = nullptr;
1421
1422 if (!pool.AvailableCursors.empty()) {
1423 Vec = pool.AvailableCursors.back();
1424 pool.AvailableCursors.pop_back();
1425 }
1426 else {
1427 Vec = new OverridenCursorsPool::CursorVec();
1428 pool.AllCursors.push_back(Vec);
1429 }
1430
1431 // Clear out the vector, but don't free the memory contents. This
1432 // reduces malloc() traffic.
1433 Vec->clear();
1434
1435 // Use the first entry to contain a back reference to the vector.
1436 // This is a complete hack.
1437 CXCursor backRefCursor = MakeCXCursorInvalid(CXCursor_InvalidFile, TU);
1438 backRefCursor.data[0] = Vec;
1439 assert(cxcursor::getCursorTU(backRefCursor) == TU);
1440 Vec->push_back(backRefCursor);
1441
1442 // Get the overriden cursors.
1443 cxcursor::getOverriddenCursors(cursor, *Vec);
1444
1445 // Did we get any overriden cursors? If not, return Vec to the pool
1446 // of available cursor vectors.
1447 if (Vec->size() == 1) {
1448 pool.AvailableCursors.push_back(Vec);
1449 return;
1450 }
1451
1452 // Now tell the caller about the overriden cursors.
1453 assert(Vec->size() > 1);
1454 *overridden = &((*Vec)[1]);
1455 *num_overridden = Vec->size() - 1;
1456 }
1457
clang_disposeOverriddenCursors(CXCursor * overridden)1458 void clang_disposeOverriddenCursors(CXCursor *overridden) {
1459 if (!overridden)
1460 return;
1461
1462 // Use pointer arithmetic to get back the first faux entry
1463 // which has a back-reference to the TU and the vector.
1464 --overridden;
1465 OverridenCursorsPool::CursorVec *Vec =
1466 static_cast<OverridenCursorsPool::CursorVec *>(
1467 const_cast<void *>(overridden->data[0]));
1468 CXTranslationUnit TU = getCursorTU(*overridden);
1469
1470 assert(Vec && TU);
1471
1472 OverridenCursorsPool &pool =
1473 *static_cast<OverridenCursorsPool*>(TU->OverridenCursorsPool);
1474
1475 pool.AvailableCursors.push_back(Vec);
1476 }
1477
clang_Cursor_isDynamicCall(CXCursor C)1478 int clang_Cursor_isDynamicCall(CXCursor C) {
1479 const Expr *E = nullptr;
1480 if (clang_isExpression(C.kind))
1481 E = getCursorExpr(C);
1482 if (!E)
1483 return 0;
1484
1485 if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
1486 if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
1487 return false;
1488 if (auto *RecE = dyn_cast<ObjCMessageExpr>(
1489 MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
1490 if (RecE->getMethodFamily() == OMF_alloc)
1491 return false;
1492 }
1493 return true;
1494 }
1495
1496 const MemberExpr *ME = nullptr;
1497 if (isa<MemberExpr>(E))
1498 ME = cast<MemberExpr>(E);
1499 else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
1500 ME = dyn_cast_or_null<MemberExpr>(CE->getCallee());
1501
1502 if (ME) {
1503 if (const CXXMethodDecl *
1504 MD = dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
1505 return MD->isVirtual() && !ME->hasQualifier();
1506 }
1507
1508 return 0;
1509 }
1510
clang_Cursor_getReceiverType(CXCursor C)1511 CXType clang_Cursor_getReceiverType(CXCursor C) {
1512 CXTranslationUnit TU = cxcursor::getCursorTU(C);
1513 const Expr *E = nullptr;
1514 if (clang_isExpression(C.kind))
1515 E = getCursorExpr(C);
1516
1517 if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(E))
1518 return cxtype::MakeCXType(MsgE->getReceiverType(), TU);
1519
1520 return cxtype::MakeCXType(QualType(), TU);
1521 }
1522
1523 } // end: extern "C"
1524