diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/CIndex/CIndex.cpp | 47 | ||||
-rw-r--r-- | tools/CIndex/CXCursor.cpp | 15 | ||||
-rw-r--r-- | tools/CIndex/CXCursor.h | 8 |
3 files changed, 68 insertions, 2 deletions
diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index a1c1230701..907312ab4f 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -17,6 +17,7 @@ #include "clang/AST/DeclVisitor.h" #include "clang/AST/StmtVisitor.h" +#include "clang/AST/TypeLocVisitor.h" #include "clang/Lex/Lexer.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/System/Program.h" @@ -140,7 +141,9 @@ static CXSourceRange translateSourceRange(ASTContext &Context, SourceRange R) { namespace { // Cursor visitor. -class CursorVisitor : public DeclVisitor<CursorVisitor, bool> { +class CursorVisitor : public DeclVisitor<CursorVisitor, bool>, + public TypeLocVisitor<CursorVisitor, bool> +{ ASTUnit *TU; CXCursor Parent; CXCursorVisitor Visitor; @@ -152,6 +155,7 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool> { unsigned MaxPCHLevel; using DeclVisitor<CursorVisitor, bool>::Visit; + using TypeLocVisitor<CursorVisitor, bool>::Visit; public: CursorVisitor(ASTUnit *TU, CXCursorVisitor Visitor, CXClientData ClientData, @@ -167,15 +171,19 @@ public: bool Visit(CXCursor Cursor); bool VisitChildren(CXCursor Parent); + // Declaration visitors bool VisitDeclContext(DeclContext *DC); - bool VisitTranslationUnitDecl(TranslationUnitDecl *D); + bool VisitDeclaratorDecl(DeclaratorDecl *DD); bool VisitFunctionDecl(FunctionDecl *ND); bool VisitObjCCategoryDecl(ObjCCategoryDecl *ND); bool VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); bool VisitObjCMethodDecl(ObjCMethodDecl *ND); bool VisitObjCProtocolDecl(ObjCProtocolDecl *PID); bool VisitTagDecl(TagDecl *D); + + // Type visitors + bool VisitTypedefTypeLoc(TypedefTypeLoc TL); }; } // end anonymous namespace @@ -279,6 +287,14 @@ bool CursorVisitor::VisitDeclContext(DeclContext *DC) { return false; } +bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) { + if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo()) + if (Visit(TSInfo->getTypeLoc())) + return true; + + return false; +} + bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) { // FIXME: This is wrong. We always want to visit the parameters and // the body, if available. @@ -349,6 +365,10 @@ bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); } +bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) { + return Visit(MakeCursorTypeRef(TL.getTypedefDecl(), TL.getNameLoc(), TU)); +} + CXString CIndexer::createCXString(const char *String, bool DupString){ CXString Str; if (DupString) { @@ -705,6 +725,15 @@ CXString clang_getCursorSpelling(CXCursor C) { assert(OID && "getCursorSpelling(): Missing protocol decl"); return CIndexer::createCXString(OID->getIdentifier()->getNameStart()); } + case CXCursor_TypeRef: { + TypeDecl *Type = getCursorTypeRef(C).first; + assert(Type && "Missing type decl"); + + return CIndexer::createCXString( + getCursorContext(C).getTypeDeclType(Type).getAsString().c_str(), + true); + } + default: return CIndexer::createCXString("<not implemented>"); } @@ -745,6 +774,7 @@ const char *clang_getCursorKindSpelling(enum CXCursorKind Kind) { case CXCursor_ObjCSuperClassRef: return "ObjCSuperClassRef"; case CXCursor_ObjCProtocolRef: return "ObjCProtocolRef"; case CXCursor_ObjCClassRef: return "ObjCClassRef"; + case CXCursor_TypeRef: return "TypeRef"; case CXCursor_UnexposedExpr: return "UnexposedExpr"; case CXCursor_DeclRefExpr: return "DeclRefExpr"; case CXCursor_MemberRefExpr: return "MemberRefExpr"; @@ -870,6 +900,11 @@ CXSourceLocation clang_getCursorLocation(CXCursor C) { = getCursorObjCClassRef(C); return translateSourceLocation(P.first->getASTContext(), P.second); } + + case CXCursor_TypeRef: { + std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); + return translateSourceLocation(P.first->getASTContext(), P.second); + } default: // FIXME: Need a way to enumerate all non-reference cases. @@ -914,6 +949,11 @@ CXSourceRange clang_getCursorExtent(CXCursor C) { return translateSourceRange(P.first->getASTContext(), P.second); } + + case CXCursor_TypeRef: { + std::pair<TypeDecl *, SourceLocation> P = getCursorTypeRef(C); + return translateSourceRange(P.first->getASTContext(), P.second); + } default: // FIXME: Need a way to enumerate all non-reference cases. @@ -961,6 +1001,9 @@ CXCursor clang_getCursorReferenced(CXCursor C) { case CXCursor_ObjCClassRef: return MakeCXCursor(getCursorObjCClassRef(C).first, CXXUnit); + + case CXCursor_TypeRef: + return MakeCXCursor(getCursorTypeRef(C).first, CXXUnit); default: // We would prefer to enumerate all non-reference cursor kinds here. diff --git a/tools/CIndex/CXCursor.cpp b/tools/CIndex/CXCursor.cpp index 29bd4e2bbc..63d9bc9f2e 100644 --- a/tools/CIndex/CXCursor.cpp +++ b/tools/CIndex/CXCursor.cpp @@ -259,6 +259,21 @@ cxcursor::getCursorObjCClassRef(CXCursor C) { reinterpret_cast<uintptr_t>(C.data[1]))); } +CXCursor cxcursor::MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, + ASTUnit *TU) { + void *RawLoc = reinterpret_cast<void *>(Loc.getRawEncoding()); + CXCursor C = { CXCursor_TypeRef, { Type, RawLoc, TU } }; + return C; +} + +std::pair<TypeDecl *, SourceLocation> +cxcursor::getCursorTypeRef(CXCursor C) { + assert(C.kind == CXCursor_TypeRef); + return std::make_pair(static_cast<TypeDecl *>(C.data[0]), + SourceLocation::getFromRawEncoding( + reinterpret_cast<uintptr_t>(C.data[1]))); +} + Decl *cxcursor::getCursorDecl(CXCursor Cursor) { return (Decl *)Cursor.data[0]; } diff --git a/tools/CIndex/CXCursor.h b/tools/CIndex/CXCursor.h index 5f81c8a173..546dd7f485 100644 --- a/tools/CIndex/CXCursor.h +++ b/tools/CIndex/CXCursor.h @@ -28,6 +28,7 @@ class NamedDecl; class ObjCInterfaceDecl; class ObjCProtocolDecl; class Stmt; +class TypeDecl; namespace cxcursor { @@ -63,6 +64,13 @@ CXCursor MakeCursorObjCClassRef(ObjCInterfaceDecl *Class, SourceLocation Loc, std::pair<ObjCInterfaceDecl *, SourceLocation> getCursorObjCClassRef(CXCursor C); +/// \brief Create a type reference at the given location. +CXCursor MakeCursorTypeRef(TypeDecl *Type, SourceLocation Loc, ASTUnit *TU); + +/// \brief Unpack a TypeRef cursor into the class it references +/// and optionally the location where the reference occurred. +std::pair<TypeDecl *, SourceLocation> getCursorTypeRef(CXCursor C); + Decl *getCursorDecl(CXCursor Cursor); Expr *getCursorExpr(CXCursor Cursor); Stmt *getCursorStmt(CXCursor Cursor); |