diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-01-21 16:28:34 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-01-21 16:28:34 +0000 |
commit | 7d0d40e58807f73e06ff5eb637a48e9f978b0e2a (patch) | |
tree | 915bf1da7b2af745ef8180943559dcdd184759dc | |
parent | c0265406a82d391a5fc60d16dd1c6cd61a92cfce (diff) |
Introduce type references into the C API, capturing references to
typedefs only (for now).
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94078 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang-c/Index.h | 18 | ||||
-rw-r--r-- | test/Index/c-index-api-loadTU-test.m | 1 | ||||
-rw-r--r-- | test/Index/cindex-from-source.m | 2 | ||||
-rw-r--r-- | tools/CIndex/CIndex.cpp | 47 | ||||
-rw-r--r-- | tools/CIndex/CXCursor.cpp | 15 | ||||
-rw-r--r-- | tools/CIndex/CXCursor.h | 8 |
6 files changed, 87 insertions, 4 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 110e49904b..b1b763cab5 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -128,7 +128,23 @@ enum CXCursorKind { CXCursor_ObjCSuperClassRef = 40, CXCursor_ObjCProtocolRef = 41, CXCursor_ObjCClassRef = 42, - CXCursor_LastRef = 42, + /** + * \brief A reference to a type declaration. + * + * A type reference occurs anywhere where a type is named but not + * declared. For example, given: + * + * \code + * typedef unsigned size_type; + * size_type size; + * \endcode + * + * The typedef is a declaration of size_type (CXCursor_TypedefDecl), + * while the type of the variable "size" is referenced. The cursor + * referenced by the type of size is the typedef for size_type. + */ + CXCursor_TypeRef = 43, + CXCursor_LastRef = 43, /* Error conditions */ CXCursor_FirstInvalid = 70, diff --git a/test/Index/c-index-api-loadTU-test.m b/test/Index/c-index-api-loadTU-test.m index 349f52139c..10805eb81f 100644 --- a/test/Index/c-index-api-loadTU-test.m +++ b/test/Index/c-index-api-loadTU-test.m @@ -79,6 +79,7 @@ int main (int argc, const char * argv[]) { // CHECK: c-index-api-loadTU-test.m:45:34: ParmDecl=argv:45:34 (Definition) [Extent=45:34:45:37] // CHECK: c-index-api-loadTU-test.m:46:8: VarDecl=bee:46:8 (Definition) [Extent=46:8:46:10] // CHECK: c-index-api-loadTU-test.m:47:5: VarDecl=a:47:5 (Definition) [Extent=47:5:47:17] +// CHECK: c-index-api-loadTU-test.m:47:2: TypeRef=id:0:0 [Extent=47:2:47:3] // CHECK: c-index-api-loadTU-test.m:48:12: VarDecl=c:48:12 (Definition) [Extent=48:12:48:25] // CHECK: c-index-api-loadTU-test.m:49:13: VarDecl=d:49:13 (Definition) [Extent=49:13:49:13] diff --git a/test/Index/cindex-from-source.m b/test/Index/cindex-from-source.m index 9f9dd21902..8f79304cb6 100644 --- a/test/Index/cindex-from-source.m +++ b/test/Index/cindex-from-source.m @@ -4,6 +4,6 @@ // RUN: FileCheck %s < %t // CHECK: cindex-from-source.m:{{.*}}:{{.*}}: StructDecl=s0:{{.*}}:{{.*}} // CHECK: cindex-from-source.m:{{.*}}:{{.*}}: VarDecl=g0:{{.*}}:{{.*}} - +// CHECK: cindex-from-source.m:9:1: TypeRef=t0:1:13 [Extent=9:1:9:2] struct s0 {}; t0 g0; 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); |