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