CXCursor.cpp revision f46034af49435a4d1a0085a4738343122aeb6521
116c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
216c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//
316c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//                     The LLVM Compiler Infrastructure
416c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//
516c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek// This file is distributed under the University of Illinois Open Source
616c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek// License. See LICENSE.TXT for details.
716c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//
816c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//===----------------------------------------------------------------------===//
916c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//
102e331b938b38057e333fab0ba841130ea8467794Douglas Gregor// This file defines routines for manipulating CXCursors. It should be the
112e331b938b38057e333fab0ba841130ea8467794Douglas Gregor// only file that has internal knowledge of the encoding of the data in
122e331b938b38057e333fab0ba841130ea8467794Douglas Gregor// CXCursor.
1316c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//
1416c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek//===----------------------------------------------------------------------===//
1516c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek
1616c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "CXCursor.h"
1716c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek#include "clang/AST/Decl.h"
18283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor#include "clang/AST/DeclObjC.h"
19283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor#include "clang/AST/Expr.h"
20edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek#include "llvm/Support/ErrorHandling.h"
2116c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek
2216c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenekusing namespace clang;
2316c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek
2416c440a377b7ec8b722a2e2c7c864f75c95bd305Ted KremenekCXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D) {
25283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  CXCursor C = { K, { D, 0, 0 } };
2616c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek  return C;
2716c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek}
2816c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek
29f46034af49435a4d1a0085a4738343122aeb6521Douglas GregorCXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D, Stmt *S,
30f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor                                ASTContext &Context) {
3116c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek  assert(clang_isReference(K));
32f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  CXCursor C = { K, { D, S, &Context } };
3316c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek  return C;
3416c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek}
3516c440a377b7ec8b722a2e2c7c864f75c95bd305Ted Kremenek
36edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenekstatic CXCursorKind GetCursorKind(Decl *D) {
37edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek  switch (D->getKind()) {
3870ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek    case Decl::Enum:               return CXCursor_EnumDecl;
3970ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek    case Decl::EnumConstant:       return CXCursor_EnumConstantDecl;
4070ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek    case Decl::Field:              return CXCursor_FieldDecl;
41edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::Function:
42edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek      return cast<FunctionDecl>(D)->isThisDeclarationADefinition()
43edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek              ? CXCursor_FunctionDefn : CXCursor_FunctionDecl;
44edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::ObjCCategory:       return CXCursor_ObjCCategoryDecl;
45edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::ObjCCategoryImpl:   return CXCursor_ObjCCategoryDefn;
4670ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek    case Decl::ObjCClass:
4770ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek      // FIXME
4870ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek      return CXCursor_NotImplemented;
496483a773db4d0ea3ab15de5801abe504c1dbc204Ted Kremenek    case Decl::ObjCForwardProtocol:
506483a773db4d0ea3ab15de5801abe504c1dbc204Ted Kremenek      // FIXME
516483a773db4d0ea3ab15de5801abe504c1dbc204Ted Kremenek      return CXCursor_NotImplemented;
52edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::ObjCImplementation: return CXCursor_ObjCClassDefn;
53edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::ObjCInterface:      return CXCursor_ObjCInterfaceDecl;
5470ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek    case Decl::ObjCIvar:           return CXCursor_ObjCIvarDecl;
5570ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek    case Decl::ObjCMethod:
5670ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek      return cast<ObjCMethodDecl>(D)->isInstanceMethod()
5770ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek              ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl;
5810fa3ccf087e167123fdb0a5e1313c7106c3c1fcTed Kremenek    case Decl::ObjCProperty:       return CXCursor_ObjCPropertyDecl;
59edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::ObjCProtocol:       return CXCursor_ObjCProtocolDecl;
6070ee54258035c860ebc71f7e5f803b74f3186889Ted Kremenek    case Decl::ParmVar:            return CXCursor_ParmDecl;
61edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::Typedef:            return CXCursor_TypedefDecl;
62edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    case Decl::Var:                return CXCursor_VarDecl;
63edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek    default:
64edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek      if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
65edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek        switch (TD->getTagKind()) {
66edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek          case TagDecl::TK_struct: return CXCursor_StructDecl;
67edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek          case TagDecl::TK_class:  return CXCursor_ClassDecl;
68edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek          case TagDecl::TK_union:  return CXCursor_UnionDecl;
69edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek          case TagDecl::TK_enum:   return CXCursor_EnumDecl;
70edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek        }
71edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek      }
72edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek  }
73edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek
74edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek  llvm_unreachable("Invalid Decl");
75edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek  return CXCursor_NotImplemented;
76edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek}
77edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek
78edc8aa68ef91aeea686c5aadf64ef902c38318ddTed KremenekCXCursor cxcursor::MakeCXCursor(Decl *D) {
79edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek  return MakeCXCursor(GetCursorKind(D), D);
80edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek}
81edc8aa68ef91aeea686c5aadf64ef902c38318ddTed Kremenek
822e331b938b38057e333fab0ba841130ea8467794Douglas GregorCXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
832e331b938b38057e333fab0ba841130ea8467794Douglas Gregor                                         SourceLocation Loc) {
842e331b938b38057e333fab0ba841130ea8467794Douglas Gregor  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
852e331b938b38057e333fab0ba841130ea8467794Douglas Gregor  CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, 0 } };
862e331b938b38057e333fab0ba841130ea8467794Douglas Gregor  return C;
872e331b938b38057e333fab0ba841130ea8467794Douglas Gregor}
882e331b938b38057e333fab0ba841130ea8467794Douglas Gregor
892e331b938b38057e333fab0ba841130ea8467794Douglas Gregorstd::pair<ObjCInterfaceDecl *, SourceLocation>
902e331b938b38057e333fab0ba841130ea8467794Douglas Gregorcxcursor::getCursorObjCSuperClassRef(CXCursor C) {
912e331b938b38057e333fab0ba841130ea8467794Douglas Gregor  assert(C.kind == CXCursor_ObjCSuperClassRef);
922e331b938b38057e333fab0ba841130ea8467794Douglas Gregor  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
932e331b938b38057e333fab0ba841130ea8467794Douglas Gregor           SourceLocation::getFromRawEncoding(
942e331b938b38057e333fab0ba841130ea8467794Douglas Gregor                                      reinterpret_cast<uintptr_t>(C.data[1])));
952e331b938b38057e333fab0ba841130ea8467794Douglas Gregor}
962e331b938b38057e333fab0ba841130ea8467794Douglas Gregor
9778db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas GregorCXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super,
9878db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor                                             SourceLocation Loc) {
9978db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
10078db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, 0 } };
10178db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  return C;
10278db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor}
10378db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor
10478db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregorstd::pair<ObjCProtocolDecl *, SourceLocation>
10578db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregorcxcursor::getCursorObjCProtocolRef(CXCursor C) {
10678db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  assert(C.kind == CXCursor_ObjCProtocolRef);
10778db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]),
10878db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor           SourceLocation::getFromRawEncoding(
10978db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor                                      reinterpret_cast<uintptr_t>(C.data[1])));
11078db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor}
11178db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor
1121adb082a709f7b588f03672999294e061234b2cfDouglas GregorCXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class,
1131adb082a709f7b588f03672999294e061234b2cfDouglas Gregor                                         SourceLocation Loc) {
1141adb082a709f7b588f03672999294e061234b2cfDouglas Gregor  void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding());
1151adb082a709f7b588f03672999294e061234b2cfDouglas Gregor  CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, 0 } };
1161adb082a709f7b588f03672999294e061234b2cfDouglas Gregor  return C;
1171adb082a709f7b588f03672999294e061234b2cfDouglas Gregor}
1181adb082a709f7b588f03672999294e061234b2cfDouglas Gregor
1191adb082a709f7b588f03672999294e061234b2cfDouglas Gregorstd::pair<ObjCInterfaceDecl *, SourceLocation>
1201adb082a709f7b588f03672999294e061234b2cfDouglas Gregorcxcursor::getCursorObjCClassRef(CXCursor C) {
1211adb082a709f7b588f03672999294e061234b2cfDouglas Gregor  assert(C.kind == CXCursor_ObjCClassRef);
1221adb082a709f7b588f03672999294e061234b2cfDouglas Gregor  return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]),
1231adb082a709f7b588f03672999294e061234b2cfDouglas Gregor           SourceLocation::getFromRawEncoding(
1241adb082a709f7b588f03672999294e061234b2cfDouglas Gregor                                      reinterpret_cast<uintptr_t>(C.data[1])));
1251adb082a709f7b588f03672999294e061234b2cfDouglas Gregor}
1261adb082a709f7b588f03672999294e061234b2cfDouglas Gregor
127283cae37b03047c14ef918503bc46b08405c3b69Douglas GregorDecl *cxcursor::getCursorDecl(CXCursor Cursor) {
128283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  return (Decl *)Cursor.data[0];
129283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor}
130283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor
131283cae37b03047c14ef918503bc46b08405c3b69Douglas GregorExpr *cxcursor::getCursorExpr(CXCursor Cursor) {
132283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
133283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor}
134283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor
135283cae37b03047c14ef918503bc46b08405c3b69Douglas GregorStmt *cxcursor::getCursorStmt(CXCursor Cursor) {
13678db0cdd49ec24034a5b2a4210fcda03a0919a81Douglas Gregor  if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
1371adb082a709f7b588f03672999294e061234b2cfDouglas Gregor      Cursor.kind == CXCursor_ObjCProtocolRef ||
1381adb082a709f7b588f03672999294e061234b2cfDouglas Gregor      Cursor.kind == CXCursor_ObjCClassRef)
1392e331b938b38057e333fab0ba841130ea8467794Douglas Gregor    return 0;
1402e331b938b38057e333fab0ba841130ea8467794Douglas Gregor
141283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  return (Stmt *)Cursor.data[1];
142283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor}
143283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor
144f46034af49435a4d1a0085a4738343122aeb6521Douglas GregorASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
145f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  switch (Cursor.kind) {
146f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_TypedefDecl:
147f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_StructDecl:
148f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_UnionDecl:
149f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ClassDecl:
150f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_EnumDecl:
151f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_FieldDecl:
152f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_EnumConstantDecl:
153f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_FunctionDecl:
154f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_VarDecl:
155f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ParmDecl:
156f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCInterfaceDecl:
157f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCCategoryDecl:
158f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCProtocolDecl:
159f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCPropertyDecl:
160f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCIvarDecl:
161f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCInstanceMethodDecl:
162f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCClassMethodDecl:
163f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_FunctionDefn:
164f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCClassDefn:
165f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCCategoryDefn:
166f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCInstanceMethodDefn:
167f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCClassMethodDefn:
168f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    return static_cast<Decl *>(Cursor.data[0])->getASTContext();
169f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor
170f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCSuperClassRef:
171f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCProtocolRef:
172f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCClassRef:
173f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    return static_cast<Decl *>(Cursor.data[0])->getASTContext();
174f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor
175f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCSelectorRef:
176f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_ObjCIvarRef:
177f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_VarRef:
178f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_FunctionRef:
179f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_EnumConstantRef:
180f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_MemberRef:
181f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    return *static_cast<ASTContext *>(Cursor.data[2]);
182f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor
183f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_InvalidFile:
184f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_NoDeclFound:
185f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  case CXCursor_NotImplemented:
186f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor    llvm_unreachable("No context in an invalid cursor");
187f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  }
188f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor
189f46034af49435a4d1a0085a4738343122aeb6521Douglas Gregor  llvm_unreachable("No context available");
190283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor}
191283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor
192283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregorbool cxcursor::operator==(CXCursor X, CXCursor Y) {
193283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor  return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
194283cae37b03047c14ef918503bc46b08405c3b69Douglas Gregor         X.data[2] == Y.data[2];
1952e331b938b38057e333fab0ba841130ea8467794Douglas Gregor}
196