From: Steve Naroff Date: Thu, 3 Sep 2009 00:32:06 +0000 (+0000) Subject: Visit function/method bodies and issue callback for parameters and local variables. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=23d8bea7056e7f474ce7f42042021a148feee8f7;p=clang Visit function/method bodies and issue callback for parameters and local variables. Add clang_getTranslationUnitSpelling(). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80859 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index 9efa791e89..f85c9d4160 100644 --- a/include/clang-c/Index.h +++ b/include/clang-c/Index.h @@ -95,6 +95,8 @@ CXTranslationUnit clang_createTranslationUnit( CXIndex, const char *ast_filename ); +const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit); + /* Usage: clang_loadTranslationUnit(). Will load the toplevel declarations within a translation unit, issuing a 'callback' for each one. diff --git a/include/clang/Frontend/ASTUnit.h b/include/clang/Frontend/ASTUnit.h index 5eb7f494d7..deb4436152 100644 --- a/include/clang/Frontend/ASTUnit.h +++ b/include/clang/Frontend/ASTUnit.h @@ -28,6 +28,7 @@ namespace clang { class Preprocessor; class ASTContext; class Decl; + class PCHReader; /// \brief Utility class for loading a ASTContext from a PCH file. /// @@ -39,6 +40,7 @@ class ASTUnit { llvm::OwningPtr Target; llvm::OwningPtr PP; llvm::OwningPtr Ctx; + llvm::OwningPtr Reader; ASTUnit(const ASTUnit&); // do not implement ASTUnit &operator=(const ASTUnit &); // do not implement @@ -59,6 +61,8 @@ public: const Diagnostic &getDiagnostic() const { return *Diags.get(); } Diagnostic &getDiagnostic() { return *Diags.get(); } + const std::string &getOriginalSourceFileName(); + /// \brief Create a ASTUnit from a PCH file. /// /// \param Filename PCH filename diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp index 8143263ca2..38452ed9d4 100644 --- a/lib/Frontend/ASTUnit.cpp +++ b/lib/Frontend/ASTUnit.cpp @@ -77,6 +77,9 @@ public: } // anonymous namespace +const std::string &ASTUnit::getOriginalSourceFileName() { + return Reader->getOriginalSourceFile(); +} ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, FileManager &FileMgr, @@ -101,10 +104,11 @@ ASTUnit *ASTUnit::LoadFromPCHFile(const std::string &Filename, std::string Predefines; unsigned Counter; - llvm::OwningPtr Reader; + llvm::OwningPtr Reader; llvm::OwningPtr Source; Reader.reset(new PCHReader(SourceMgr, FileMgr, Diags)); + AST->Reader.reset(Reader.get()); Reader->setListener(new PCHInfoCollector(LangInfo, HeaderInfo, TargetTriple, Predefines, Counter)); diff --git a/tools/CIndex/CIndex.cpp b/tools/CIndex/CIndex.cpp index 82f7fb8e2b..a0b49c4169 100644 --- a/tools/CIndex/CIndex.cpp +++ b/tools/CIndex/CIndex.cpp @@ -67,6 +67,9 @@ public: break; } } + void VisitVarDecl(VarDecl *ND) { + Call(CXCursor_VarDecl, ND); + } void VisitFunctionDecl(FunctionDecl *ND) { Call(ND->isThisDeclarationADefinition() ? CXCursor_FunctionDefn : CXCursor_FunctionDecl, ND); @@ -95,6 +98,9 @@ class CDeclVisitor : public DeclVisitor { CXClientData CData; void Call(enum CXCursorKind CK, NamedDecl *ND) { + // Disable the callback when the context is equal to the visiting decl. + if (CDecl == ND) + return; CXCursor C = { CK, ND }; Callback(CDecl, C, CData); } @@ -129,17 +135,28 @@ public: void VisitFieldDecl(FieldDecl *ND) { Call(CXCursor_FieldDecl, ND); } + void VisitVarDecl(VarDecl *ND) { + Call(CXCursor_VarDecl, ND); + } + void VisitParmVarDecl(ParmVarDecl *ND) { + Call(CXCursor_ParmDecl, ND); + } void VisitObjCPropertyDecl(ObjCPropertyDecl *ND) { Call(CXCursor_ObjCPropertyDecl, ND); } void VisitObjCIvarDecl(ObjCIvarDecl *ND) { Call(CXCursor_ObjCIvarDecl, ND); } + void VisitFunctionDecl(FunctionDecl *ND) { + if (ND->isThisDeclarationADefinition()) { + VisitDeclContext(dyn_cast(ND)); + } + } void VisitObjCMethodDecl(ObjCMethodDecl *ND) { if (ND->getBody()) { Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDefn : CXCursor_ObjCClassMethodDefn, ND); - // FIXME: load body. + VisitDeclContext(dyn_cast(ND)); } else Call(ND->isInstanceMethod() ? CXCursor_ObjCInstanceMethodDecl : CXCursor_ObjCClassMethodDecl, ND); @@ -167,6 +184,12 @@ CXTranslationUnit clang_createTranslationUnit( return ASTUnit::LoadFromPCHFile(astName, CXXIdx->getFileManager(), &ErrMsg); } +const char *clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) +{ + assert(CTUnit && "Passed null CXTranslationUnit"); + ASTUnit *CXXUnit = static_cast(CTUnit); + return CXXUnit->getOriginalSourceFileName().c_str(); +} void clang_loadTranslationUnit(CXTranslationUnit CTUnit, CXTranslationUnitIterator callback, diff --git a/tools/CIndex/CIndex.exports b/tools/CIndex/CIndex.exports index 3f87a82b3a..7c9660b4d0 100644 --- a/tools/CIndex/CIndex.exports +++ b/tools/CIndex/CIndex.exports @@ -19,3 +19,4 @@ _clang_isReference _clang_isDefinition _clang_getCursorSpelling _clang_getCursorKindSpelling +_clang_getTranslationUnitSpelling diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 2d2be158d0..8df2fc261d 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -3,25 +3,27 @@ #include "clang-c/Index.h" #include +static void PrintCursor(CXCursor Cursor) { + printf("%s => %s", clang_getCursorKindSpelling(Cursor.kind), + clang_getCursorSpelling(Cursor)); + printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor), + clang_getCursorLine(Cursor), + clang_getCursorColumn(Cursor)); +} + static void DeclVisitor(CXDecl Dcl, CXCursor Cursor, CXClientData Filter) { - if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) { - printf("%s => %s", clang_getCursorKindSpelling(Cursor.kind), - clang_getCursorSpelling(Cursor)); - printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor), - clang_getCursorLine(Cursor), - clang_getCursorColumn(Cursor)); - } + printf("%s: ", clang_getDeclSpelling(Dcl)); + if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) + PrintCursor(Cursor); } + static void TranslationUnitVisitor(CXTranslationUnit Unit, CXCursor Cursor, CXClientData Filter) { + printf("%s: ", clang_getTranslationUnitSpelling(Unit)); if (!Filter || (Cursor.kind == *(enum CXCursorKind *)Filter)) { - printf("%s => %s", clang_getCursorKindSpelling(Cursor.kind), - clang_getCursorSpelling(Cursor)); - printf(" (%s,%d:%d)\n", clang_getCursorSource(Cursor), - clang_getCursorLine(Cursor), - clang_getCursorColumn(Cursor)); + PrintCursor(Cursor); clang_loadDeclaration(Cursor.decl, DeclVisitor, 0); }