From a1c728438c44ae9727d6bbedc4d1dcfdacb95122 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Fri, 28 Aug 2009 15:28:48 +0000 Subject: [PATCH] Lot's of little changes to get the C-based indexing API going... Work in progress. llvm-svn: 80367 --- clang/clang.xcodeproj/project.pbxproj | 18 +++++++++ clang/include/clang-c/Index.h | 42 +++++++++++---------- clang/include/clang/Index/Indexer.h | 8 +++- clang/tools/CIndex/CIndex.cpp | 49 +++++++++++++++++++++---- clang/tools/CIndex/CIndex.exports | 2 +- clang/tools/Makefile | 2 +- clang/tools/c-index-test/CMakeLists.txt | 20 ++++++++++ clang/tools/c-index-test/Makefile | 24 ++++++++++++ clang/tools/c-index-test/c-index-test.c | 12 ++++++ clang/tools/index-test/index-test.cpp | 2 +- 10 files changed, 148 insertions(+), 31 deletions(-) create mode 100644 clang/tools/c-index-test/CMakeLists.txt create mode 100644 clang/tools/c-index-test/Makefile create mode 100644 clang/tools/c-index-test/c-index-test.c diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index 89fb901d3869..705ff04a32db 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -108,6 +108,8 @@ 84AF36A10CB17A3B00C820A5 /* DeclObjC.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84AF36A00CB17A3B00C820A5 /* DeclObjC.h */; }; 84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; }; 84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; }; + 9012911D1048068D0083456D /* ASTUnit.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9012911C1048068D0083456D /* ASTUnit.cpp */; }; + 90129121104812F90083456D /* CIndex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9012911F104812F90083456D /* CIndex.cpp */; }; 906BF4B00F83BA2E001071FA /* ConvertUTF.c in Sources */ = {isa = PBXBuildFile; fileRef = 906BF4AF0F83BA2E001071FA /* ConvertUTF.c */; }; 90FD6D7B103C3D49005F5B73 /* Analyzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D6D103C3D49005F5B73 /* Analyzer.cpp */; }; 90FD6D7C103C3D49005F5B73 /* ASTLocation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 90FD6D6E103C3D49005F5B73 /* ASTLocation.cpp */; }; @@ -497,6 +499,9 @@ 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = ""; tabWidth = 2; }; 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; 9012911510470FCE0083456D /* Index.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Index.h; path = "clang-c/Index.h"; sourceTree = ""; }; + 9012911C1048068D0083456D /* ASTUnit.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTUnit.cpp; path = lib/Frontend/ASTUnit.cpp; sourceTree = ""; }; + 9012911F104812F90083456D /* CIndex.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CIndex.cpp; path = tools/CIndex/CIndex.cpp; sourceTree = ""; }; + 90129120104812F90083456D /* CIndex.exports */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = CIndex.exports; path = tools/CIndex/CIndex.exports; sourceTree = ""; }; 9063F2210F9E8BDF002F7251 /* ExternalSemaSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ExternalSemaSource.h; path = clang/Sema/ExternalSemaSource.h; sourceTree = ""; }; 9063F2220F9E8BDF002F7251 /* SemaConsumer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaConsumer.h; path = clang/Sema/SemaConsumer.h; sourceTree = ""; }; 9063F2280F9E911F002F7251 /* OnDiskHashTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OnDiskHashTable.h; sourceTree = ""; }; @@ -879,6 +884,7 @@ 352246E00F5C6BC000D0D279 /* Frontend */ = { isa = PBXGroup; children = ( + 9012911C1048068D0083456D /* ASTUnit.cpp */, 1A2A54A40FD1DD1C00F4CE45 /* AnalysisConsumer.cpp */, 1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */, 1A2A54A60FD1DD1C00F4CE45 /* Backend.cpp */, @@ -1027,6 +1033,15 @@ name = "clang-c"; sourceTree = ""; }; + 9012911E104812DA0083456D /* CIndex */ = { + isa = PBXGroup; + children = ( + 9012911F104812F90083456D /* CIndex.cpp */, + 90129120104812F90083456D /* CIndex.exports */, + ); + name = CIndex; + sourceTree = ""; + }; 90FD6D5E103C3D03005F5B73 /* Index */ = { isa = PBXGroup; children = ( @@ -1466,6 +1481,7 @@ DEDFE61F0F7B3AE10035BD10 /* Tools */ = { isa = PBXGroup; children = ( + 9012911E104812DA0083456D /* CIndex */, 90FD6DB4103D9763005F5B73 /* index-test */, DEDFE6200F7B3AE90035BD10 /* clang-cc */, DEDFE6210F7B3AF10035BD10 /* clang */, @@ -1849,6 +1865,8 @@ 90FD6D84103C3D49005F5B73 /* ResolveLocation.cpp in Sources */, 90FD6D85103C3D49005F5B73 /* SelectorMap.cpp in Sources */, 90FD6DB6103D977E005F5B73 /* index-test.cpp in Sources */, + 9012911D1048068D0083456D /* ASTUnit.cpp in Sources */, + 90129121104812F90083456D /* CIndex.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index 52ffb931ee1f..b96cb6cb1431 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -33,13 +33,13 @@ extern "C" { Naming Conventions: To avoid namespace pollution, data types are prefixed with "CX" and functions are prefixed with "clang_". */ -typedef void *CXIndex; // An indexing instance. +typedef void *CXIndex; /* An indexing instance. */ -typedef void *CXTranslationUnit; // A translation unit instance. +typedef void *CXTranslationUnit; /* A translation unit instance. */ -typedef void *CXCursor; // An opaque cursor into the CXTranslationUnit. +typedef void *CXCursor; /* An opaque cursor into the CXTranslationUnit. */ -// Cursors represent declarations and references (provides line/column info). +/* Cursors represent declarations and references (provides line/column info). */ enum CXCursorKind { CXCursor_Declaration, CXCursor_Reference, @@ -49,9 +49,9 @@ enum CXCursorKind { CXCursor_ObjC_SelectorRef }; -typedef void *CXDecl; // A specific declaration within a translation unit. +typedef void *CXDecl; /* A specific declaration within a translation unit. */ -enum CXDeclKind { // The various kinds of declarations. +enum CXDeclKind { /* The various kinds of declarations. */ CXDecl_any, CXDecl_typedef, CXDecl_enum, @@ -73,12 +73,12 @@ enum CXDeclKind { // The various kinds of declarations. CXDecl_ObjC_property_implementation }; -// A unique token for looking up "visible" CXDecls from a CXTranslationUnit. +/* A unique token for looking up "visible" CXDecls from a CXTranslationUnit. */ typedef void *CXEntity; CXIndex clang_createIndex(); -CXTranslationUnit clang_loadTranslationUnitFromASTFile( +CXTranslationUnit clang_createTranslationUnit( CXIndex, const char *ast_filename ); @@ -130,33 +130,35 @@ void clang_loadTranslationUnit( */ void clang_loadDeclaration(CXDecl, void (*callback)(CXDecl, CXCursor)); -// -// CXEntity Operations. -// +/* + * CXEntity Operations. + */ const char *clang_getDeclarationName(CXEntity); const char *clang_getURI(CXEntity); CXEntity clang_getEntity(const char *URI); -// -// CXDecl Operations. -// +/* + * CXDecl Operations. + */ CXCursor clang_getCursorFromDecl(CXDecl); CXEntity clang_getEntityFromDecl(CXDecl); enum CXDeclKind clang_getDeclKind(CXDecl); const char *clang_getDeclSpelling(CXDecl); -// -// CXCursor Operations. -// +/* + * CXCursor Operations. + */ CXCursor clang_getCursor(CXTranslationUnit, const char *source_name, unsigned line, unsigned column); -CXCursorKind clang_getCursorKind(CXCursor); +enum CXCursorKind clang_getCursorKind(CXCursor); unsigned clang_getCursorLine(CXCursor); unsigned clang_getCursorColumn(CXCursor); const char *clang_getCursorSource(CXCursor); -// If CXCursorKind == Cursor_Reference, then this will return the referenced declaration. -// If CXCursorKind == Cursor_Declaration, then this will return the declaration. +/* + * If CXCursorKind == Cursor_Reference, then this will return the referenced declaration. + * If CXCursorKind == Cursor_Declaration, then this will return the declaration. + */ CXDecl clang_getCursorDecl(CXCursor); #ifdef __cplusplus diff --git a/clang/include/clang/Index/Indexer.h b/clang/include/clang/Index/Indexer.h index 98cce9e44ba4..0fcf31c64437 100644 --- a/clang/include/clang/Index/Indexer.h +++ b/clang/include/clang/Index/Indexer.h @@ -19,6 +19,7 @@ #include "clang/Index/GlobalSelector.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/DenseMap.h" +#include "clang/Basic/FileManager.h" #include namespace clang { @@ -36,10 +37,13 @@ public: typedef std::map MapTy; typedef std::map SelMapTy; - explicit Indexer(Program &prog) : Prog(prog) { } + explicit Indexer(Program &prog, FileManager &FM) : + Prog(prog), FileMgr(FM) { } Program &getProgram() const { return Prog; } + FileManager &getFileManager() const { return FileMgr; } + /// \brief Find all Entities and map them to the given translation unit. void IndexAST(TranslationUnit *TU); @@ -50,6 +54,8 @@ public: private: Program &Prog; + FileManager &FileMgr; + MapTy Map; CtxTUMapTy CtxTUMap; SelMapTy SelMap; diff --git a/clang/tools/CIndex/CIndex.cpp b/clang/tools/CIndex/CIndex.cpp index ec575475ecd5..dc44fd2b1cc5 100644 --- a/clang/tools/CIndex/CIndex.cpp +++ b/clang/tools/CIndex/CIndex.cpp @@ -13,23 +13,58 @@ #include "clang-c/Index.h" +#include "clang/Index/Program.h" +#include "clang/Index/Indexer.h" + +#include "clang/Frontend/ASTUnit.h" +#include "clang/Basic/FileManager.h" + +#include "clang/AST/DeclVisitor.h" + +using namespace clang; +using namespace idx; + extern "C" { CXIndex clang_createIndex() -{ - return 0; +{ + return new Indexer(*new Program(), *new FileManager()); } -CXTranslationUnit clang_loadTranslationUnitFromASTFile( - CXIndex, const char *ast_filename) +// FIXME: need to pass back error info. +CXTranslationUnit clang_createTranslationUnit( + CXIndex CIdx, const char *ast_filename) { - return 0; + assert(CIdx && "Passed null CXIndex"); + Indexer *CXXIdx = static_cast(CIdx); + std::string astName(ast_filename); + std::string ErrMsg; + + return ASTUnit::LoadFromPCHFile(astName, CXXIdx->getFileManager(), &ErrMsg); } +class IdxVisitor : public DeclVisitor { +public: + IdxVisitor(); + + void VisitNamedDecl(NamedDecl *ND) { + printf("NamedDecl (%s:", ND->getDeclKindName()); + if (ND->getIdentifier()) + printf("%s)\n", ND->getIdentifier()->getName()); + else + printf(")\n"); + } +}; + void clang_loadTranslationUnit( - CXTranslationUnit, void (*callback)(CXTranslationUnit, CXCursor) -) + CXTranslationUnit CTUnit, void (*callback)(CXTranslationUnit, CXCursor)) { + assert(CTUnit && "Passed null CXTranslationUnit"); + ASTUnit *CXXUnit = static_cast(CTUnit); + ASTContext &Ctx = CXXUnit->getASTContext(); + + IdxVisitor DVisit; + DVisit.Visit(Ctx.getTranslationUnitDecl()); } void clang_loadDeclaration(CXDecl, void (*callback)(CXDecl, CXCursor)) diff --git a/clang/tools/CIndex/CIndex.exports b/clang/tools/CIndex/CIndex.exports index 0e6cfa549a59..41b67a246750 100644 --- a/clang/tools/CIndex/CIndex.exports +++ b/clang/tools/CIndex/CIndex.exports @@ -14,4 +14,4 @@ _clang_getEntityFromDecl _clang_getURI _clang_loadDeclaration _clang_loadTranslationUnit -_clang_loadTranslationUnitFromASTFile +_clang_createTranslationUnit diff --git a/clang/tools/Makefile b/clang/tools/Makefile index 3ee73ca28275..d76e95606d47 100644 --- a/clang/tools/Makefile +++ b/clang/tools/Makefile @@ -8,6 +8,6 @@ ##===----------------------------------------------------------------------===## LEVEL := ../../.. -DIRS := clang-cc driver index-test wpa CIndex +DIRS := clang-cc driver index-test wpa CIndex c-index-test include $(LEVEL)/Makefile.common diff --git a/clang/tools/c-index-test/CMakeLists.txt b/clang/tools/c-index-test/CMakeLists.txt new file mode 100644 index 000000000000..abf3cc4400c3 --- /dev/null +++ b/clang/tools/c-index-test/CMakeLists.txt @@ -0,0 +1,20 @@ +set(LLVM_NO_RTTI 1) + +set( LLVM_USED_LIBS + CIndex + clangIndex + clangFrontend + clangSema + clangAST + clangLex + clangBasic + ) + +set( LLVM_LINK_COMPONENTS + bitreader + mc + ) + +add_clang_executable(c-index-test + c-index-test.c + ) diff --git a/clang/tools/c-index-test/Makefile b/clang/tools/c-index-test/Makefile new file mode 100644 index 000000000000..81fee40b66e2 --- /dev/null +++ b/clang/tools/c-index-test/Makefile @@ -0,0 +1,24 @@ +##===- tools/index-test/Makefile ---------------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## +LEVEL = ../../../.. + +TOOLNAME = c-index-test +CPPFLAGS += -I$(PROJ_SRC_DIR)/../../include -I$(PROJ_OBJ_DIR)/../../include +CXXFLAGS = -fno-rtti +NO_INSTALL = 1 + +# No plugins, optimize startup time. +TOOL_NO_EXPORTS = 1 + +include $(LEVEL)/Makefile.config + +LINK_COMPONENTS := bitreader mc +USEDLIBS = CIndex.a clangIndex.a clangFrontend.a clangSema.a clangAST.a clangLex.a clangBasic.a + +include $(LLVM_SRC_ROOT)/Makefile.rules diff --git a/clang/tools/c-index-test/c-index-test.c b/clang/tools/c-index-test/c-index-test.c new file mode 100644 index 000000000000..71bdcc5c64d0 --- /dev/null +++ b/clang/tools/c-index-test/c-index-test.c @@ -0,0 +1,12 @@ + +#include "clang-c/Index.h" + +/* + * First sign of life:-) + */ +int main(int argc, char **argv) { + CXIndex Idx = clang_createIndex(); + CXTranslationUnit TU = clang_createTranslationUnit(Idx, argv[1]); + clang_loadTranslationUnit(TU, 0); + return 1; +} diff --git a/clang/tools/index-test/index-test.cpp b/clang/tools/index-test/index-test.cpp index 02971ed782a6..88fd2417ac0d 100644 --- a/clang/tools/index-test/index-test.cpp +++ b/clang/tools/index-test/index-test.cpp @@ -214,7 +214,7 @@ int main(int argc, char **argv) { FileManager FileMgr; Program Prog; - Indexer Idxer(Prog); + Indexer Idxer(Prog, FileMgr); llvm::SmallVector TUnits; // If no input was specified, read from stdin.