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