CXCursor.cpp revision 97b9872d5775446cb8aca1380e437649fe848d91
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 "CXCursor.h" 17#include "clang/AST/Decl.h" 18#include "clang/AST/DeclObjC.h" 19#include "clang/AST/Expr.h" 20#include "llvm/Support/ErrorHandling.h" 21 22using namespace clang; 23 24CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D) { 25 CXCursor C = { K, { D, 0, 0 } }; 26 return C; 27} 28 29CXCursor cxcursor::MakeCXCursor(CXCursorKind K, Decl *D, Stmt *S, 30 ASTContext &Context) { 31 assert(clang_isReference(K)); 32 CXCursor C = { K, { D, S, &Context } }; 33 return C; 34} 35 36static CXCursorKind GetCursorKind(Decl *D) { 37 switch (D->getKind()) { 38 case Decl::Enum: return CXCursor_EnumDecl; 39 case Decl::EnumConstant: return CXCursor_EnumConstantDecl; 40 case Decl::Field: return CXCursor_FieldDecl; 41 case Decl::Function: 42 return CXCursor_FunctionDecl; 43 case Decl::ObjCCategory: return CXCursor_ObjCCategoryDecl; 44 case Decl::ObjCCategoryImpl: return CXCursor_ObjCCategoryImplDecl; 45 case Decl::ObjCClass: 46 // FIXME 47 return CXCursor_UnexposedDecl; 48 case Decl::ObjCForwardProtocol: 49 // FIXME 50 return CXCursor_UnexposedDecl; 51 case Decl::ObjCImplementation: return CXCursor_ObjCImplementationDecl; 52 case Decl::ObjCInterface: return CXCursor_ObjCInterfaceDecl; 53 case Decl::ObjCIvar: return CXCursor_ObjCIvarDecl; 54 case Decl::ObjCMethod: 55 return cast<ObjCMethodDecl>(D)->isInstanceMethod() 56 ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl; 57 case Decl::ObjCProperty: return CXCursor_ObjCPropertyDecl; 58 case Decl::ObjCProtocol: return CXCursor_ObjCProtocolDecl; 59 case Decl::ParmVar: return CXCursor_ParmDecl; 60 case Decl::Typedef: return CXCursor_TypedefDecl; 61 case Decl::Var: return CXCursor_VarDecl; 62 default: 63 if (TagDecl *TD = dyn_cast<TagDecl>(D)) { 64 switch (TD->getTagKind()) { 65 case TagDecl::TK_struct: return CXCursor_StructDecl; 66 case TagDecl::TK_class: return CXCursor_ClassDecl; 67 case TagDecl::TK_union: return CXCursor_UnionDecl; 68 case TagDecl::TK_enum: return CXCursor_EnumDecl; 69 } 70 } 71 72 return CXCursor_UnexposedDecl; 73 } 74 75 llvm_unreachable("Invalid Decl"); 76 return CXCursor_NotImplemented; 77} 78 79CXCursor cxcursor::MakeCXCursor(Decl *D) { 80 return MakeCXCursor(GetCursorKind(D), D); 81} 82 83CXCursor cxcursor::MakeCXCursor(Stmt *S, Decl *Parent) { 84 CXCursorKind K = CXCursor_NotImplemented; 85 86 switch (S->getStmtClass()) { 87 case Stmt::NoStmtClass: 88 break; 89 90 case Stmt::NullStmtClass: 91 case Stmt::CompoundStmtClass: 92 case Stmt::CaseStmtClass: 93 case Stmt::DefaultStmtClass: 94 case Stmt::LabelStmtClass: 95 case Stmt::IfStmtClass: 96 case Stmt::SwitchStmtClass: 97 case Stmt::WhileStmtClass: 98 case Stmt::DoStmtClass: 99 case Stmt::ForStmtClass: 100 case Stmt::GotoStmtClass: 101 case Stmt::IndirectGotoStmtClass: 102 case Stmt::ContinueStmtClass: 103 case Stmt::BreakStmtClass: 104 case Stmt::ReturnStmtClass: 105 case Stmt::DeclStmtClass: 106 case Stmt::SwitchCaseClass: 107 case Stmt::AsmStmtClass: 108 case Stmt::ObjCAtTryStmtClass: 109 case Stmt::ObjCAtCatchStmtClass: 110 case Stmt::ObjCAtFinallyStmtClass: 111 case Stmt::ObjCAtThrowStmtClass: 112 case Stmt::ObjCAtSynchronizedStmtClass: 113 case Stmt::ObjCForCollectionStmtClass: 114 case Stmt::CXXCatchStmtClass: 115 case Stmt::CXXTryStmtClass: 116 K = CXCursor_UnexposedStmt; 117 break; 118 119 case Stmt::ExprClass: 120 case Stmt::PredefinedExprClass: 121 case Stmt::IntegerLiteralClass: 122 case Stmt::FloatingLiteralClass: 123 case Stmt::ImaginaryLiteralClass: 124 case Stmt::StringLiteralClass: 125 case Stmt::CharacterLiteralClass: 126 case Stmt::ParenExprClass: 127 case Stmt::UnaryOperatorClass: 128 case Stmt::SizeOfAlignOfExprClass: 129 case Stmt::ArraySubscriptExprClass: 130 case Stmt::CastExprClass: 131 case Stmt::BinaryOperatorClass: 132 case Stmt::CompoundAssignOperatorClass: 133 case Stmt::ConditionalOperatorClass: 134 case Stmt::ImplicitCastExprClass: 135 case Stmt::ExplicitCastExprClass: 136 case Stmt::CStyleCastExprClass: 137 case Stmt::CompoundLiteralExprClass: 138 case Stmt::ExtVectorElementExprClass: 139 case Stmt::InitListExprClass: 140 case Stmt::DesignatedInitExprClass: 141 case Stmt::ImplicitValueInitExprClass: 142 case Stmt::ParenListExprClass: 143 case Stmt::VAArgExprClass: 144 case Stmt::AddrLabelExprClass: 145 case Stmt::StmtExprClass: 146 case Stmt::TypesCompatibleExprClass: 147 case Stmt::ChooseExprClass: 148 case Stmt::GNUNullExprClass: 149 case Stmt::CXXNamedCastExprClass: 150 case Stmt::CXXStaticCastExprClass: 151 case Stmt::CXXDynamicCastExprClass: 152 case Stmt::CXXReinterpretCastExprClass: 153 case Stmt::CXXConstCastExprClass: 154 case Stmt::CXXFunctionalCastExprClass: 155 case Stmt::CXXTypeidExprClass: 156 case Stmt::CXXBoolLiteralExprClass: 157 case Stmt::CXXNullPtrLiteralExprClass: 158 case Stmt::CXXThisExprClass: 159 case Stmt::CXXThrowExprClass: 160 case Stmt::CXXDefaultArgExprClass: 161 case Stmt::CXXZeroInitValueExprClass: 162 case Stmt::CXXNewExprClass: 163 case Stmt::CXXDeleteExprClass: 164 case Stmt::CXXPseudoDestructorExprClass: 165 case Stmt::UnresolvedLookupExprClass: 166 case Stmt::UnaryTypeTraitExprClass: 167 case Stmt::DependentScopeDeclRefExprClass: 168 case Stmt::CXXBindTemporaryExprClass: 169 case Stmt::CXXExprWithTemporariesClass: 170 case Stmt::CXXUnresolvedConstructExprClass: 171 case Stmt::CXXDependentScopeMemberExprClass: 172 case Stmt::UnresolvedMemberExprClass: 173 case Stmt::ObjCStringLiteralClass: 174 case Stmt::ObjCEncodeExprClass: 175 case Stmt::ObjCSelectorExprClass: 176 case Stmt::ObjCProtocolExprClass: 177 case Stmt::ObjCImplicitSetterGetterRefExprClass: 178 case Stmt::ObjCSuperExprClass: 179 case Stmt::ObjCIsaExprClass: 180 case Stmt::ShuffleVectorExprClass: 181 case Stmt::BlockExprClass: 182 K = CXCursor_UnexposedExpr; 183 break; 184 case Stmt::DeclRefExprClass: 185 case Stmt::BlockDeclRefExprClass: 186 // FIXME: UnresolvedLookupExpr? 187 // FIXME: DependentScopeDeclRefExpr? 188 K = CXCursor_DeclRefExpr; 189 break; 190 191 case Stmt::MemberExprClass: 192 case Stmt::ObjCIvarRefExprClass: 193 case Stmt::ObjCPropertyRefExprClass: 194 // FIXME: UnresolvedMemberExpr? 195 // FIXME: CXXDependentScopeMemberExpr? 196 K = CXCursor_MemberRefExpr; 197 break; 198 199 case Stmt::CallExprClass: 200 case Stmt::CXXOperatorCallExprClass: 201 case Stmt::CXXMemberCallExprClass: 202 case Stmt::CXXConstructExprClass: 203 case Stmt::CXXTemporaryObjectExprClass: 204 // FIXME: CXXUnresolvedConstructExpr 205 // FIXME: ObjCImplicitSetterGetterRefExpr? 206 K = CXCursor_CallExpr; 207 break; 208 209 case Stmt::ObjCMessageExprClass: 210 K = CXCursor_ObjCMessageExpr; 211 break; 212 } 213 214 CXCursor C = { K, { Parent, S, 0 } }; 215 return C; 216} 217 218CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super, 219 SourceLocation Loc) { 220 void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); 221 CXCursor C = { CXCursor_ObjCSuperClassRef, { Super, RawLoc, 0 } }; 222 return C; 223} 224 225std::pair<ObjCInterfaceDecl *, SourceLocation> 226cxcursor::getCursorObjCSuperClassRef(CXCursor C) { 227 assert(C.kind == CXCursor_ObjCSuperClassRef); 228 return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]), 229 SourceLocation::getFromRawEncoding( 230 reinterpret_cast<uintptr_t>(C.data[1]))); 231} 232 233CXCursor cxcursor::MakeCursorObjCProtocolRef(ObjCProtocolDecl *Super, 234 SourceLocation Loc) { 235 void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); 236 CXCursor C = { CXCursor_ObjCProtocolRef, { Super, RawLoc, 0 } }; 237 return C; 238} 239 240std::pair<ObjCProtocolDecl *, SourceLocation> 241cxcursor::getCursorObjCProtocolRef(CXCursor C) { 242 assert(C.kind == CXCursor_ObjCProtocolRef); 243 return std::make_pair(static_cast<ObjCProtocolDecl *>(C.data[0]), 244 SourceLocation::getFromRawEncoding( 245 reinterpret_cast<uintptr_t>(C.data[1]))); 246} 247 248CXCursor cxcursor::MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, 249 SourceLocation Loc) { 250 void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); 251 CXCursor C = { CXCursor_ObjCClassRef, { Class, RawLoc, 0 } }; 252 return C; 253} 254 255std::pair<ObjCInterfaceDecl *, SourceLocation> 256cxcursor::getCursorObjCClassRef(CXCursor C) { 257 assert(C.kind == CXCursor_ObjCClassRef); 258 return std::make_pair(static_cast<ObjCInterfaceDecl *>(C.data[0]), 259 SourceLocation::getFromRawEncoding( 260 reinterpret_cast<uintptr_t>(C.data[1]))); 261} 262 263Decl *cxcursor::getCursorDecl(CXCursor Cursor) { 264 return (Decl *)Cursor.data[0]; 265} 266 267Expr *cxcursor::getCursorExpr(CXCursor Cursor) { 268 return dyn_cast_or_null<Expr>(getCursorStmt(Cursor)); 269} 270 271Stmt *cxcursor::getCursorStmt(CXCursor Cursor) { 272 if (Cursor.kind == CXCursor_ObjCSuperClassRef || 273 Cursor.kind == CXCursor_ObjCProtocolRef || 274 Cursor.kind == CXCursor_ObjCClassRef) 275 return 0; 276 277 return (Stmt *)Cursor.data[1]; 278} 279 280ASTContext &cxcursor::getCursorContext(CXCursor Cursor) { 281 switch (Cursor.kind) { 282 case CXCursor_TypedefDecl: 283 case CXCursor_StructDecl: 284 case CXCursor_UnionDecl: 285 case CXCursor_ClassDecl: 286 case CXCursor_EnumDecl: 287 case CXCursor_FieldDecl: 288 case CXCursor_EnumConstantDecl: 289 case CXCursor_FunctionDecl: 290 case CXCursor_VarDecl: 291 case CXCursor_ParmDecl: 292 case CXCursor_ObjCInterfaceDecl: 293 case CXCursor_ObjCCategoryDecl: 294 case CXCursor_ObjCProtocolDecl: 295 case CXCursor_ObjCPropertyDecl: 296 case CXCursor_ObjCIvarDecl: 297 case CXCursor_ObjCInstanceMethodDecl: 298 case CXCursor_ObjCClassMethodDecl: 299 case CXCursor_ObjCImplementationDecl: 300 case CXCursor_ObjCCategoryImplDecl: 301 case CXCursor_UnexposedDecl: 302 return static_cast<Decl *>(Cursor.data[0])->getASTContext(); 303 304 case CXCursor_ObjCSuperClassRef: 305 case CXCursor_ObjCProtocolRef: 306 case CXCursor_ObjCClassRef: 307 return static_cast<Decl *>(Cursor.data[0])->getASTContext(); 308 309 case CXCursor_ObjCSelectorRef: 310 case CXCursor_VarRef: 311 case CXCursor_FunctionRef: 312 case CXCursor_EnumConstantRef: 313 return *static_cast<ASTContext *>(Cursor.data[2]); 314 315 case CXCursor_InvalidFile: 316 case CXCursor_NoDeclFound: 317 case CXCursor_NotImplemented: 318 llvm_unreachable("No context in an invalid cursor"); 319 break; 320 321 case CXCursor_UnexposedExpr: 322 case CXCursor_DeclRefExpr: 323 case CXCursor_MemberRefExpr: 324 case CXCursor_CallExpr: 325 case CXCursor_ObjCMessageExpr: 326 case CXCursor_UnexposedStmt: 327 return static_cast<Decl *>(Cursor.data[0])->getASTContext(); 328 329 } 330 331 llvm_unreachable("No context available"); 332} 333 334bool cxcursor::operator==(CXCursor X, CXCursor Y) { 335 return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] && 336 X.data[2] == Y.data[2]; 337} 338