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