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