CXCursor.cpp revision 4e7064fa7e344e8f87a5b8457e96dfdd252c4a9e
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 "clang/Frontend/ASTUnit.h"
20#include "clang/AST/Decl.h"
21#include "clang/AST/DeclCXX.h"
22#include "clang/AST/DeclObjC.h"
23#include "clang/AST/DeclTemplate.h"
24#include "clang/AST/Expr.h"
25#include "clang/AST/ExprCXX.h"
26#include "clang/AST/ExprObjC.h"
27#include "clang-c/Index.h"
28#include "llvm/Support/ErrorHandling.h"
29
30using namespace clang;
31using namespace cxcursor;
32
33CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K) {
34  assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
35  CXCursor C = { K, 0, { 0, 0, 0 } };
36  return C;
37}
38
39static CXCursorKind GetCursorKind(const Attr *A) {
40  assert(A && "Invalid arguments!");
41  switch (A->getKind()) {
42    default: break;
43    case attr::IBAction: return CXCursor_IBActionAttr;
44    case attr::IBOutlet: return CXCursor_IBOutletAttr;
45    case attr::IBOutletCollection: return CXCursor_IBOutletCollectionAttr;
46    case attr::Final: return CXCursor_CXXFinalAttr;
47    case attr::Override: return CXCursor_CXXOverrideAttr;
48    case attr::Annotate: return CXCursor_AnnotateAttr;
49  }
50
51  return CXCursor_UnexposedAttr;
52}
53
54CXCursor cxcursor::MakeCXCursor(const Attr *A, Decl *Parent,
55                                CXTranslationUnit TU) {
56  assert(A && Parent && TU && "Invalid arguments!");
57  CXCursor C = { GetCursorKind(A), 0, { Parent, (void*)A, TU } };
58  return C;
59}
60
61CXCursor cxcursor::MakeCXCursor(Decl *D, CXTranslationUnit TU,
62                                SourceRange RegionOfInterest,
63                                bool FirstInDeclGroup) {
64  assert(D && TU && "Invalid arguments!");
65
66  CXCursorKind K = getCursorKindForDecl(D);
67
68  if (K == CXCursor_ObjCClassMethodDecl ||
69      K == CXCursor_ObjCInstanceMethodDecl) {
70    int SelectorIdIndex = -1;
71    // Check if cursor points to a selector id.
72    if (RegionOfInterest.isValid() &&
73        RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
74      SmallVector<SourceLocation, 16> SelLocs;
75      cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
76      SmallVector<SourceLocation, 16>::iterator
77        I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
78      if (I != SelLocs.end())
79        SelectorIdIndex = I - SelLocs.begin();
80    }
81    CXCursor C = { K, SelectorIdIndex,
82                   { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
83    return C;
84  }
85
86  CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
87  return C;
88}
89
90CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent, CXTranslationUnit TU,
91                                SourceRange RegionOfInterest) {
92  assert(S && TU && "Invalid arguments!");
93  CXCursorKind K = CXCursor_NotImplemented;
94
95  switch (S->getStmtClass()) {
96  case Stmt::NoStmtClass:
97    break;
98
99  case Stmt::CaseStmtClass:
100    K = CXCursor_CaseStmt;
101    break;
102
103  case Stmt::DefaultStmtClass:
104    K = CXCursor_DefaultStmt;
105    break;
106
107  case Stmt::IfStmtClass:
108    K = CXCursor_IfStmt;
109    break;
110
111  case Stmt::SwitchStmtClass:
112    K = CXCursor_SwitchStmt;
113    break;
114
115  case Stmt::WhileStmtClass:
116    K = CXCursor_WhileStmt;
117    break;
118
119  case Stmt::DoStmtClass:
120    K = CXCursor_DoStmt;
121    break;
122
123  case Stmt::ForStmtClass:
124    K = CXCursor_ForStmt;
125    break;
126
127  case Stmt::GotoStmtClass:
128    K = CXCursor_GotoStmt;
129    break;
130
131  case Stmt::IndirectGotoStmtClass:
132    K = CXCursor_IndirectGotoStmt;
133    break;
134
135  case Stmt::ContinueStmtClass:
136    K = CXCursor_ContinueStmt;
137    break;
138
139  case Stmt::BreakStmtClass:
140    K = CXCursor_BreakStmt;
141    break;
142
143  case Stmt::ReturnStmtClass:
144    K = CXCursor_ReturnStmt;
145    break;
146
147  case Stmt::AsmStmtClass:
148    K = CXCursor_AsmStmt;
149    break;
150
151  case Stmt::ObjCAtTryStmtClass:
152    K = CXCursor_ObjCAtTryStmt;
153    break;
154
155  case Stmt::ObjCAtCatchStmtClass:
156    K = CXCursor_ObjCAtCatchStmt;
157    break;
158
159  case Stmt::ObjCAtFinallyStmtClass:
160    K = CXCursor_ObjCAtFinallyStmt;
161    break;
162
163  case Stmt::ObjCAtThrowStmtClass:
164    K = CXCursor_ObjCAtThrowStmt;
165    break;
166
167  case Stmt::ObjCAtSynchronizedStmtClass:
168    K = CXCursor_ObjCAtSynchronizedStmt;
169    break;
170
171  case Stmt::ObjCAutoreleasePoolStmtClass:
172    K = CXCursor_ObjCAutoreleasePoolStmt;
173    break;
174
175  case Stmt::ObjCForCollectionStmtClass:
176    K = CXCursor_ObjCForCollectionStmt;
177    break;
178
179  case Stmt::CXXCatchStmtClass:
180    K = CXCursor_CXXCatchStmt;
181    break;
182
183  case Stmt::CXXTryStmtClass:
184    K = CXCursor_CXXTryStmt;
185    break;
186
187  case Stmt::CXXForRangeStmtClass:
188    K = CXCursor_CXXForRangeStmt;
189    break;
190
191  case Stmt::SEHTryStmtClass:
192    K = CXCursor_SEHTryStmt;
193    break;
194
195  case Stmt::SEHExceptStmtClass:
196    K = CXCursor_SEHExceptStmt;
197    break;
198
199  case Stmt::SEHFinallyStmtClass:
200    K = CXCursor_SEHFinallyStmt;
201    break;
202
203  case Stmt::ArrayTypeTraitExprClass:
204  case Stmt::AsTypeExprClass:
205  case Stmt::AtomicExprClass:
206  case Stmt::BinaryConditionalOperatorClass:
207  case Stmt::BinaryTypeTraitExprClass:
208  case Stmt::CXXBindTemporaryExprClass:
209  case Stmt::CXXDefaultArgExprClass:
210  case Stmt::CXXScalarValueInitExprClass:
211  case Stmt::CXXUuidofExprClass:
212  case Stmt::ChooseExprClass:
213  case Stmt::DesignatedInitExprClass:
214  case Stmt::ExprWithCleanupsClass:
215  case Stmt::ExpressionTraitExprClass:
216  case Stmt::ExtVectorElementExprClass:
217  case Stmt::ImplicitCastExprClass:
218  case Stmt::ImplicitValueInitExprClass:
219  case Stmt::MaterializeTemporaryExprClass:
220  case Stmt::ObjCIndirectCopyRestoreExprClass:
221  case Stmt::OffsetOfExprClass:
222  case Stmt::OpaqueValueExprClass:
223  case Stmt::ParenListExprClass:
224  case Stmt::PredefinedExprClass:
225  case Stmt::ShuffleVectorExprClass:
226  case Stmt::UnaryExprOrTypeTraitExprClass:
227  case Stmt::UnaryTypeTraitExprClass:
228  case Stmt::VAArgExprClass:
229    K = CXCursor_UnexposedExpr;
230    break;
231
232  case Stmt::CompoundStmtClass:
233    K = CXCursor_CompoundStmt;
234    break;
235
236  case Stmt::NullStmtClass:
237    K = CXCursor_NullStmt;
238    break;
239
240  case Stmt::LabelStmtClass:
241    K = CXCursor_LabelStmt;
242    break;
243
244  case Stmt::DeclStmtClass:
245    K = CXCursor_DeclStmt;
246    break;
247
248  case Stmt::IntegerLiteralClass:
249    K = CXCursor_IntegerLiteral;
250    break;
251
252  case Stmt::FloatingLiteralClass:
253    K = CXCursor_FloatingLiteral;
254    break;
255
256  case Stmt::ImaginaryLiteralClass:
257    K = CXCursor_ImaginaryLiteral;
258    break;
259
260  case Stmt::StringLiteralClass:
261    K = CXCursor_StringLiteral;
262    break;
263
264  case Stmt::CharacterLiteralClass:
265    K = CXCursor_CharacterLiteral;
266    break;
267
268  case Stmt::ParenExprClass:
269    K = CXCursor_ParenExpr;
270    break;
271
272  case Stmt::UnaryOperatorClass:
273    K = CXCursor_UnaryOperator;
274    break;
275
276  case Stmt::CXXNoexceptExprClass:
277    K = CXCursor_UnaryExpr;
278    break;
279
280  case Stmt::ArraySubscriptExprClass:
281    K = CXCursor_ArraySubscriptExpr;
282    break;
283
284  case Stmt::BinaryOperatorClass:
285    K = CXCursor_BinaryOperator;
286    break;
287
288  case Stmt::CompoundAssignOperatorClass:
289    K = CXCursor_CompoundAssignOperator;
290    break;
291
292  case Stmt::ConditionalOperatorClass:
293    K = CXCursor_ConditionalOperator;
294    break;
295
296  case Stmt::CStyleCastExprClass:
297    K = CXCursor_CStyleCastExpr;
298    break;
299
300  case Stmt::CompoundLiteralExprClass:
301    K = CXCursor_CompoundLiteralExpr;
302    break;
303
304  case Stmt::InitListExprClass:
305    K = CXCursor_InitListExpr;
306    break;
307
308  case Stmt::AddrLabelExprClass:
309    K = CXCursor_AddrLabelExpr;
310    break;
311
312  case Stmt::StmtExprClass:
313    K = CXCursor_StmtExpr;
314    break;
315
316  case Stmt::GenericSelectionExprClass:
317    K = CXCursor_GenericSelectionExpr;
318    break;
319
320  case Stmt::GNUNullExprClass:
321    K = CXCursor_GNUNullExpr;
322    break;
323
324  case Stmt::CXXStaticCastExprClass:
325    K = CXCursor_CXXStaticCastExpr;
326    break;
327
328  case Stmt::CXXDynamicCastExprClass:
329    K = CXCursor_CXXDynamicCastExpr;
330    break;
331
332  case Stmt::CXXReinterpretCastExprClass:
333    K = CXCursor_CXXReinterpretCastExpr;
334    break;
335
336  case Stmt::CXXConstCastExprClass:
337    K = CXCursor_CXXConstCastExpr;
338    break;
339
340  case Stmt::CXXFunctionalCastExprClass:
341    K = CXCursor_CXXFunctionalCastExpr;
342    break;
343
344  case Stmt::CXXTypeidExprClass:
345    K = CXCursor_CXXTypeidExpr;
346    break;
347
348  case Stmt::CXXBoolLiteralExprClass:
349    K = CXCursor_CXXBoolLiteralExpr;
350    break;
351
352  case Stmt::CXXNullPtrLiteralExprClass:
353    K = CXCursor_CXXNullPtrLiteralExpr;
354    break;
355
356  case Stmt::CXXThisExprClass:
357    K = CXCursor_CXXThisExpr;
358    break;
359
360  case Stmt::CXXThrowExprClass:
361    K = CXCursor_CXXThrowExpr;
362    break;
363
364  case Stmt::CXXNewExprClass:
365    K = CXCursor_CXXNewExpr;
366    break;
367
368  case Stmt::CXXDeleteExprClass:
369    K = CXCursor_CXXDeleteExpr;
370    break;
371
372  case Stmt::ObjCStringLiteralClass:
373    K = CXCursor_ObjCStringLiteral;
374    break;
375
376  case Stmt::ObjCEncodeExprClass:
377    K = CXCursor_ObjCEncodeExpr;
378    break;
379
380  case Stmt::ObjCSelectorExprClass:
381    K = CXCursor_ObjCSelectorExpr;
382    break;
383
384  case Stmt::ObjCProtocolExprClass:
385    K = CXCursor_ObjCProtocolExpr;
386    break;
387
388  case Stmt::ObjCBridgedCastExprClass:
389    K = CXCursor_ObjCBridgedCastExpr;
390    break;
391
392  case Stmt::BlockExprClass:
393    K = CXCursor_BlockExpr;
394    break;
395
396  case Stmt::PackExpansionExprClass:
397    K = CXCursor_PackExpansionExpr;
398    break;
399
400  case Stmt::SizeOfPackExprClass:
401    K = CXCursor_SizeOfPackExpr;
402    break;
403
404  case Stmt::BlockDeclRefExprClass:
405  case Stmt::DeclRefExprClass:
406  case Stmt::DependentScopeDeclRefExprClass:
407  case Stmt::SubstNonTypeTemplateParmExprClass:
408  case Stmt::SubstNonTypeTemplateParmPackExprClass:
409  case Stmt::UnresolvedLookupExprClass:
410    K = CXCursor_DeclRefExpr;
411    break;
412
413  case Stmt::CXXDependentScopeMemberExprClass:
414  case Stmt::CXXPseudoDestructorExprClass:
415  case Stmt::MemberExprClass:
416  case Stmt::ObjCIsaExprClass:
417  case Stmt::ObjCIvarRefExprClass:
418  case Stmt::ObjCPropertyRefExprClass:
419  case Stmt::UnresolvedMemberExprClass:
420    K = CXCursor_MemberRefExpr;
421    break;
422
423  case Stmt::CallExprClass:
424  case Stmt::CXXOperatorCallExprClass:
425  case Stmt::CXXMemberCallExprClass:
426  case Stmt::CUDAKernelCallExprClass:
427  case Stmt::CXXConstructExprClass:
428  case Stmt::CXXTemporaryObjectExprClass:
429  case Stmt::CXXUnresolvedConstructExprClass:
430    K = CXCursor_CallExpr;
431    break;
432
433  case Stmt::ObjCMessageExprClass:
434    K = CXCursor_ObjCMessageExpr;
435    int SelectorIdIndex = -1;
436    // Check if cursor points to a selector id.
437    if (RegionOfInterest.isValid() &&
438        RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
439      SmallVector<SourceLocation, 16> SelLocs;
440      cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
441      SmallVector<SourceLocation, 16>::iterator
442        I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
443      if (I != SelLocs.end())
444        SelectorIdIndex = I - SelLocs.begin();
445    }
446    CXCursor C = { K, 0, { Parent, S, TU } };
447    return getSelectorIdentifierCursor(SelectorIdIndex, C);
448  }
449
450  CXCursor C = { K, 0, { Parent, S, TU } };
451  return C;
452}
453
454CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
455                                               SourceLocation Loc,
456                                               CXTranslationUnit TU) {
457  assert(Super && TU && "Invalid arguments!");
458  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
459  CXCursor C = { CXCursor_ObjCSuperClassRef, 0, { Super, RawLoc, TU } };
460  return C;
461}
462
463std::pair<ObjCInterfaceDecl *, SourceLocation>
464cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
465  assert(C.kind == CXCursor_ObjCSuperClassRef);
466  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
467           SourceLocation::getFromRawEncoding(
468                                      reinterpret_cast<uintptr_t>(C.data[1])));
469}
470
471CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
472                                             SourceLocation Loc,
473                                             CXTranslationUnit TU) {
474  assert(Proto && TU && "Invalid arguments!");
475  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
476  CXCursor C = { CXCursor_ObjCProtocolRef, 0, { (void*)Proto, RawLoc, TU } };
477  return C;
478}
479
480std::pair<ObjCProtocolDecl *, SourceLocation>
481cxcursor::getCursorObjCProtocolRef(CXCursor C) {
482  assert(C.kind == CXCursor_ObjCProtocolRef);
483  return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
484           SourceLocation::getFromRawEncoding(
485                                      reinterpret_cast<uintptr_t>(C.data[1])));
486}
487
488CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
489                                          SourceLocation Loc,
490                                          CXTranslationUnit TU) {
491  // 'Class' can be null for invalid code.
492  if (!Class)
493    return MakeCXCursorInvalid(CXCursor_InvalidCode);
494  assert(TU && "Invalid arguments!");
495  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
496  CXCursor C = { CXCursor_ObjCClassRef, 0, { (void*)Class, RawLoc, TU } };
497  return C;
498}
499
500std::pair<ObjCInterfaceDecl *, SourceLocation>
501cxcursor::getCursorObjCClassRef(CXCursor C) {
502  assert(C.kind == CXCursor_ObjCClassRef);
503  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
504           SourceLocation::getFromRawEncoding(
505                                      reinterpret_cast<uintptr_t>(C.data[1])));
506}
507
508CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
509                                     CXTranslationUnit TU) {
510  assert(Type && TU && "Invalid arguments!");
511  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
512  CXCursor C = { CXCursor_TypeRef, 0, { (void*)Type, RawLoc, TU } };
513  return C;
514}
515
516std::pair<TypeDecl *, SourceLocation>
517cxcursor::getCursorTypeRef(CXCursor C) {
518  assert(C.kind == CXCursor_TypeRef);
519  return std::make_pair(static_cast<TypeDecl *>(C.data[0]),
520           SourceLocation::getFromRawEncoding(
521                                      reinterpret_cast<uintptr_t>(C.data[1])));
522}
523
524CXCursor cxcursor::MakeCursorTemplateRef(TemplateDecl *Template,
525                                         SourceLocation Loc,
526                                         CXTranslationUnit TU) {
527  assert(Template && TU && "Invalid arguments!");
528  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
529  CXCursor C = { CXCursor_TemplateRef, 0, { Template, RawLoc, TU } };
530  return C;
531}
532
533std::pair<TemplateDecl *, SourceLocation>
534cxcursor::getCursorTemplateRef(CXCursor C) {
535  assert(C.kind == CXCursor_TemplateRef);
536  return std::make_pair(static_cast<TemplateDecl *>(C.data[0]),
537                        SourceLocation::getFromRawEncoding(
538                                       reinterpret_cast<uintptr_t>(C.data[1])));
539}
540
541CXCursor cxcursor::MakeCursorNamespaceRef(NamedDecl *NS, SourceLocation Loc,
542                                          CXTranslationUnit TU) {
543
544  assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
545         "Invalid arguments!");
546  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
547  CXCursor C = { CXCursor_NamespaceRef, 0, { NS, RawLoc, TU } };
548  return C;
549}
550
551std::pair<NamedDecl *, SourceLocation>
552cxcursor::getCursorNamespaceRef(CXCursor C) {
553  assert(C.kind == CXCursor_NamespaceRef);
554  return std::make_pair(static_cast<NamedDecl *>(C.data[0]),
555                        SourceLocation::getFromRawEncoding(
556                                       reinterpret_cast<uintptr_t>(C.data[1])));
557}
558
559CXCursor cxcursor::MakeCursorMemberRef(FieldDecl *Field, SourceLocation Loc,
560                                       CXTranslationUnit TU) {
561
562  assert(Field && TU && "Invalid arguments!");
563  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
564  CXCursor C = { CXCursor_MemberRef, 0, { Field, RawLoc, TU } };
565  return C;
566}
567
568std::pair<FieldDecl *, SourceLocation>
569cxcursor::getCursorMemberRef(CXCursor C) {
570  assert(C.kind == CXCursor_MemberRef);
571  return std::make_pair(static_cast<FieldDecl *>(C.data[0]),
572                        SourceLocation::getFromRawEncoding(
573                                       reinterpret_cast<uintptr_t>(C.data[1])));
574}
575
576CXCursor cxcursor::MakeCursorCXXBaseSpecifier(CXXBaseSpecifier *B,
577                                              CXTranslationUnit TU){
578  CXCursor C = { CXCursor_CXXBaseSpecifier, 0, { B, 0, TU } };
579  return C;
580}
581
582CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
583  assert(C.kind == CXCursor_CXXBaseSpecifier);
584  return static_cast<CXXBaseSpecifier*>(C.data[0]);
585}
586
587CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
588                                                    CXTranslationUnit TU) {
589  CXCursor C = { CXCursor_PreprocessingDirective, 0,
590                 { reinterpret_cast<void *>(Range.getBegin().getRawEncoding()),
591                   reinterpret_cast<void *>(Range.getEnd().getRawEncoding()),
592                   TU }
593               };
594  return C;
595}
596
597SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
598  assert(C.kind == CXCursor_PreprocessingDirective);
599  SourceRange Range = SourceRange(SourceLocation::getFromRawEncoding(
600                                      reinterpret_cast<uintptr_t> (C.data[0])),
601                     SourceLocation::getFromRawEncoding(
602                                      reinterpret_cast<uintptr_t> (C.data[1])));
603  ASTUnit *TU = getCursorASTUnit(C);
604  return TU->mapRangeFromPreamble(Range);
605}
606
607CXCursor cxcursor::MakeMacroDefinitionCursor(MacroDefinition *MI,
608                                             CXTranslationUnit TU) {
609  CXCursor C = { CXCursor_MacroDefinition, 0, { MI, 0, TU } };
610  return C;
611}
612
613MacroDefinition *cxcursor::getCursorMacroDefinition(CXCursor C) {
614  assert(C.kind == CXCursor_MacroDefinition);
615  return static_cast<MacroDefinition *>(C.data[0]);
616}
617
618CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
619                                            CXTranslationUnit TU) {
620  CXCursor C = { CXCursor_MacroExpansion, 0, { MI, 0, TU } };
621  return C;
622}
623
624MacroExpansion *cxcursor::getCursorMacroExpansion(CXCursor C) {
625  assert(C.kind == CXCursor_MacroExpansion);
626  return static_cast<MacroExpansion *>(C.data[0]);
627}
628
629CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
630                                                CXTranslationUnit TU) {
631  CXCursor C = { CXCursor_InclusionDirective, 0, { ID, 0, TU } };
632  return C;
633}
634
635InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
636  assert(C.kind == CXCursor_InclusionDirective);
637  return static_cast<InclusionDirective *>(C.data[0]);
638}
639
640CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
641                                      CXTranslationUnit TU) {
642
643  assert(Label && TU && "Invalid arguments!");
644  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
645  CXCursor C = { CXCursor_LabelRef, 0, { Label, RawLoc, TU } };
646  return C;
647}
648
649std::pair<LabelStmt*, SourceLocation>
650cxcursor::getCursorLabelRef(CXCursor C) {
651  assert(C.kind == CXCursor_LabelRef);
652  return std::make_pair(static_cast<LabelStmt *>(C.data[0]),
653                        SourceLocation::getFromRawEncoding(
654                                       reinterpret_cast<uintptr_t>(C.data[1])));
655}
656
657CXCursor cxcursor::MakeCursorOverloadedDeclRef(OverloadExpr *E,
658                                               CXTranslationUnit TU) {
659  assert(E && TU && "Invalid arguments!");
660  OverloadedDeclRefStorage Storage(E);
661  void *RawLoc = reinterpret_cast<void *>(E->getNameLoc().getRawEncoding());
662  CXCursor C = {
663                 CXCursor_OverloadedDeclRef, 0,
664                 { Storage.getOpaqueValue(), RawLoc, TU }
665               };
666  return C;
667}
668
669CXCursor cxcursor::MakeCursorOverloadedDeclRef(Decl *D,
670                                               SourceLocation Loc,
671                                               CXTranslationUnit TU) {
672  assert(D && TU && "Invalid arguments!");
673  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
674  OverloadedDeclRefStorage Storage(D);
675  CXCursor C = {
676    CXCursor_OverloadedDeclRef, 0,
677    { Storage.getOpaqueValue(), RawLoc, TU }
678  };
679  return C;
680}
681
682CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
683                                               SourceLocation Loc,
684                                               CXTranslationUnit TU) {
685  assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
686  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
687  OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
688  CXCursor C = {
689    CXCursor_OverloadedDeclRef, 0,
690    { Storage.getOpaqueValue(), RawLoc, TU }
691  };
692  return C;
693}
694
695std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
696cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
697  assert(C.kind == CXCursor_OverloadedDeclRef);
698  return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(C.data[0]),
699                        SourceLocation::getFromRawEncoding(
700                                       reinterpret_cast<uintptr_t>(C.data[1])));
701}
702
703Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
704  return (Decl *)Cursor.data[0];
705}
706
707Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
708  return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
709}
710
711Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
712  if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
713      Cursor.kind == CXCursor_ObjCProtocolRef ||
714      Cursor.kind == CXCursor_ObjCClassRef)
715    return 0;
716
717  return (Stmt *)Cursor.data[1];
718}
719
720Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
721  return (Attr *)Cursor.data[1];
722}
723
724Decl *cxcursor::getCursorParentDecl(CXCursor Cursor) {
725  return (Decl *)Cursor.data[0];
726}
727
728ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
729  return getCursorASTUnit(Cursor)->getASTContext();
730}
731
732ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
733  return static_cast<ASTUnit *>(static_cast<CXTranslationUnit>(Cursor.data[2])
734                                  ->TUData);
735}
736
737CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
738  return static_cast<CXTranslationUnit>(Cursor.data[2]);
739}
740
741static void CollectOverriddenMethods(CXTranslationUnit TU,
742                                     DeclContext *Ctx,
743                                     ObjCMethodDecl *Method,
744                                     SmallVectorImpl<CXCursor> &Methods) {
745  if (!Ctx)
746    return;
747
748  // If we have a class or category implementation, jump straight to the
749  // interface.
750  if (ObjCImplDecl *Impl = dyn_cast<ObjCImplDecl>(Ctx))
751    return CollectOverriddenMethods(TU, Impl->getClassInterface(),
752                                    Method, Methods);
753
754  ObjCContainerDecl *Container = dyn_cast<ObjCContainerDecl>(Ctx);
755  if (!Container)
756    return;
757
758  // Check whether we have a matching method at this level.
759  if (ObjCMethodDecl *Overridden = Container->getMethod(Method->getSelector(),
760                                                    Method->isInstanceMethod()))
761    if (Method != Overridden) {
762      // We found an override at this level; there is no need to look
763      // into other protocols or categories.
764      Methods.push_back(MakeCXCursor(Overridden, TU));
765      return;
766    }
767
768  if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
769    for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
770                                          PEnd = Protocol->protocol_end();
771         P != PEnd; ++P)
772      CollectOverriddenMethods(TU, *P, Method, Methods);
773  }
774
775  if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
776    for (ObjCCategoryDecl::protocol_iterator P = Category->protocol_begin(),
777                                          PEnd = Category->protocol_end();
778         P != PEnd; ++P)
779      CollectOverriddenMethods(TU, *P, Method, Methods);
780  }
781
782  if (ObjCInterfaceDecl *Interface = dyn_cast<ObjCInterfaceDecl>(Container)) {
783    for (ObjCInterfaceDecl::protocol_iterator P = Interface->protocol_begin(),
784                                           PEnd = Interface->protocol_end();
785         P != PEnd; ++P)
786      CollectOverriddenMethods(TU, *P, Method, Methods);
787
788    for (ObjCCategoryDecl *Category = Interface->getCategoryList();
789         Category; Category = Category->getNextClassCategory())
790      CollectOverriddenMethods(TU, Category, Method, Methods);
791
792    // We only look into the superclass if we haven't found anything yet.
793    if (Methods.empty())
794      if (ObjCInterfaceDecl *Super = Interface->getSuperClass())
795        return CollectOverriddenMethods(TU, Super, Method, Methods);
796  }
797}
798
799void cxcursor::getOverriddenCursors(CXCursor cursor,
800                                    SmallVectorImpl<CXCursor> &overridden) {
801  if (!clang_isDeclaration(cursor.kind))
802    return;
803
804  Decl *D = getCursorDecl(cursor);
805  if (!D)
806    return;
807
808  // Handle C++ member functions.
809  CXTranslationUnit TU = getCursorTU(cursor);
810  if (CXXMethodDecl *CXXMethod = dyn_cast<CXXMethodDecl>(D)) {
811    for (CXXMethodDecl::method_iterator
812              M = CXXMethod->begin_overridden_methods(),
813           MEnd = CXXMethod->end_overridden_methods();
814         M != MEnd; ++M)
815      overridden.push_back(MakeCXCursor(const_cast<CXXMethodDecl*>(*M), TU));
816    return;
817  }
818
819  ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(D);
820  if (!Method)
821    return;
822
823  // Handle Objective-C methods.
824  CollectOverriddenMethods(TU, Method->getDeclContext(), Method, overridden);
825}
826
827std::pair<int, SourceLocation>
828cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
829  if (cursor.kind == CXCursor_ObjCMessageExpr) {
830    if (cursor.xdata != -1)
831      return std::make_pair(cursor.xdata,
832                            cast<ObjCMessageExpr>(getCursorExpr(cursor))
833                                                ->getSelectorLoc(cursor.xdata));
834  } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
835             cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
836    if (cursor.xdata != -1)
837      return std::make_pair(cursor.xdata,
838                            cast<ObjCMethodDecl>(getCursorDecl(cursor))
839                                                ->getSelectorLoc(cursor.xdata));
840  }
841
842  return std::make_pair(-1, SourceLocation());
843}
844
845CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
846  CXCursor newCursor = cursor;
847
848  if (cursor.kind == CXCursor_ObjCMessageExpr) {
849    if (SelIdx == -1 ||
850        unsigned(SelIdx) >= cast<ObjCMessageExpr>(getCursorExpr(cursor))
851                                                         ->getNumSelectorLocs())
852      newCursor.xdata = -1;
853    else
854      newCursor.xdata = SelIdx;
855  } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
856             cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
857    if (SelIdx == -1 ||
858        unsigned(SelIdx) >= cast<ObjCMethodDecl>(getCursorDecl(cursor))
859                                                         ->getNumSelectorLocs())
860      newCursor.xdata = -1;
861    else
862      newCursor.xdata = SelIdx;
863  }
864
865  return newCursor;
866}
867
868CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
869  if (cursor.kind != CXCursor_CallExpr)
870    return cursor;
871
872  if (cursor.xdata == 0)
873    return cursor;
874
875  Expr *E = getCursorExpr(cursor);
876  TypeSourceInfo *Type = 0;
877  if (CXXUnresolvedConstructExpr *
878        UnCtor = dyn_cast<CXXUnresolvedConstructExpr>(E)) {
879    Type = UnCtor->getTypeSourceInfo();
880  } else if (CXXTemporaryObjectExpr *Tmp = dyn_cast<CXXTemporaryObjectExpr>(E)){
881    Type = Tmp->getTypeSourceInfo();
882  }
883
884  if (!Type)
885    return cursor;
886
887  CXTranslationUnit TU = getCursorTU(cursor);
888  QualType Ty = Type->getType();
889  TypeLoc TL = Type->getTypeLoc();
890  SourceLocation Loc = TL.getBeginLoc();
891
892  if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
893    Ty = ElabT->getNamedType();
894    ElaboratedTypeLoc ElabTL = cast<ElaboratedTypeLoc>(TL);
895    Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
896  }
897
898  if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
899    return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
900  if (const TagType *Tag = Ty->getAs<TagType>())
901    return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
902  if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
903    return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
904
905  return cursor;
906}
907
908bool cxcursor::operator==(CXCursor X, CXCursor Y) {
909  return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
910         X.data[2] == Y.data[2];
911}
912
913// FIXME: Remove once we can model DeclGroups and their appropriate ranges
914// properly in the ASTs.
915bool cxcursor::isFirstInDeclGroup(CXCursor C) {
916  assert(clang_isDeclaration(C.kind));
917  return ((uintptr_t) (C.data[1])) != 0;
918}
919
920//===----------------------------------------------------------------------===//
921// libclang CXCursor APIs
922//===----------------------------------------------------------------------===//
923
924extern "C" {
925
926int clang_Cursor_isNull(CXCursor cursor) {
927  return clang_equalCursors(cursor, clang_getNullCursor());
928}
929
930CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
931  return getCursorTU(cursor);
932}
933
934} // end: extern "C"
935
936//===----------------------------------------------------------------------===//
937// CXCursorSet.
938//===----------------------------------------------------------------------===//
939
940typedef llvm::DenseMap<CXCursor, unsigned> CXCursorSet_Impl;
941
942static inline CXCursorSet packCXCursorSet(CXCursorSet_Impl *setImpl) {
943  return (CXCursorSet) setImpl;
944}
945static inline CXCursorSet_Impl *unpackCXCursorSet(CXCursorSet set) {
946  return (CXCursorSet_Impl*) set;
947}
948namespace llvm {
949template<> struct DenseMapInfo<CXCursor> {
950public:
951  static inline CXCursor getEmptyKey() {
952    return MakeCXCursorInvalid(CXCursor_InvalidFile);
953  }
954  static inline CXCursor getTombstoneKey() {
955    return MakeCXCursorInvalid(CXCursor_NoDeclFound);
956  }
957  static inline unsigned getHashValue(const CXCursor &cursor) {
958    return llvm::DenseMapInfo<std::pair<void*,void*> >
959      ::getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
960  }
961  static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
962    return x.kind == y.kind &&
963           x.data[0] == y.data[0] &&
964           x.data[1] == y.data[1];
965  }
966};
967}
968
969extern "C" {
970CXCursorSet clang_createCXCursorSet() {
971  return packCXCursorSet(new CXCursorSet_Impl());
972}
973
974void clang_disposeCXCursorSet(CXCursorSet set) {
975  delete unpackCXCursorSet(set);
976}
977
978unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) {
979  CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
980  if (!setImpl)
981    return 0;
982  return setImpl->find(cursor) == setImpl->end();
983}
984
985unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
986  // Do not insert invalid cursors into the set.
987  if (cursor.kind >= CXCursor_FirstInvalid &&
988      cursor.kind <= CXCursor_LastInvalid)
989    return 1;
990
991  CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
992  if (!setImpl)
993    return 1;
994  unsigned &entry = (*setImpl)[cursor];
995  unsigned flag = entry == 0 ? 1 : 0;
996  entry = 1;
997  return flag;
998}
999
1000CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
1001  enum CXCursorKind kind = clang_getCursorKind(cursor);
1002  if (clang_isDeclaration(kind)) {
1003    Decl *decl = getCursorDecl(cursor);
1004    if (isa<NamedDecl>(decl)) {
1005      NamedDecl *namedDecl = (NamedDecl *)decl;
1006      ASTUnit *unit = getCursorASTUnit(cursor);
1007      if (unit->hasSema()) {
1008        Sema &S = unit->getSema();
1009        CodeCompletionAllocator *Allocator
1010          = unit->getCursorCompletionAllocator().getPtr();
1011        CodeCompletionResult Result(namedDecl);
1012        CodeCompletionString *String
1013          = Result.CreateCodeCompletionString(S, *Allocator);
1014        return String;
1015      }
1016    }
1017  }
1018  else if (kind == CXCursor_MacroDefinition) {
1019    MacroDefinition *definition = getCursorMacroDefinition(cursor);
1020    const IdentifierInfo *MacroInfo = definition->getName();
1021    ASTUnit *unit = getCursorASTUnit(cursor);
1022    if (unit->hasSema()) {
1023      Sema &S = unit->getSema();
1024      CodeCompletionAllocator *Allocator
1025        = unit->getCursorCompletionAllocator().getPtr();
1026      CodeCompletionResult Result(const_cast<IdentifierInfo *>(MacroInfo));
1027      CodeCompletionString *String
1028        = Result.CreateCodeCompletionString(S, *Allocator);
1029      return String;
1030    }
1031  }
1032  return NULL;
1033}
1034
1035} // end: extern "C"
1036