Author: akirtzidis Date: Sun Feb 14 00:39:11 2016 New Revision: 260842 URL: http://llvm.org/viewvc/llvm-project?rev=260842&view=rev Log: [index] Enhance c-index-test tool and have it link and test the clangIndex library directly.
Added: cfe/trunk/test/Index/Core/ cfe/trunk/test/Index/Core/index-source.m cfe/trunk/tools/c-index-test/core_main.cpp Modified: cfe/trunk/include/clang/Index/IndexSymbol.h cfe/trunk/lib/Index/IndexSymbol.cpp cfe/trunk/tools/c-index-test/CMakeLists.txt cfe/trunk/tools/c-index-test/c-index-test.c Modified: cfe/trunk/include/clang/Index/IndexSymbol.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Index/IndexSymbol.h?rev=260842&r1=260841&r2=260842&view=diff ============================================================================== --- cfe/trunk/include/clang/Index/IndexSymbol.h (original) +++ cfe/trunk/include/clang/Index/IndexSymbol.h Sun Feb 14 00:39:11 2016 @@ -11,6 +11,7 @@ #define LLVM_CLANG_INDEX_INDEXSYMBOL_H #include "clang/Basic/LLVM.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/DataTypes.h" namespace clang { @@ -107,6 +108,13 @@ struct SymbolInfo { SymbolInfo getSymbolInfo(const Decl *D); +void applyForEachSymbolRole(SymbolRoleSet Roles, + llvm::function_ref<void(SymbolRole)> Fn); +void printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS); +StringRef getSymbolKindString(SymbolKind K); +StringRef getTemplateKindStr(SymbolCXXTemplateKind TK); +StringRef getSymbolLanguageString(SymbolLanguage K); + } // namespace index } // namespace clang Modified: cfe/trunk/lib/Index/IndexSymbol.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/IndexSymbol.cpp?rev=260842&r1=260841&r2=260842&view=diff ============================================================================== --- cfe/trunk/lib/Index/IndexSymbol.cpp (original) +++ cfe/trunk/lib/Index/IndexSymbol.cpp Sun Feb 14 00:39:11 2016 @@ -185,3 +185,102 @@ SymbolInfo index::getSymbolInfo(const De return Info; } + +void index::applyForEachSymbolRole(SymbolRoleSet Roles, + llvm::function_ref<void(SymbolRole)> Fn) { +#define APPLY_FOR_ROLE(Role) \ + if (Roles & (unsigned)SymbolRole::Role) \ + Fn(SymbolRole::Role) + + APPLY_FOR_ROLE(Declaration); + APPLY_FOR_ROLE(Definition); + APPLY_FOR_ROLE(Reference); + APPLY_FOR_ROLE(Read); + APPLY_FOR_ROLE(Write); + APPLY_FOR_ROLE(Call); + APPLY_FOR_ROLE(Dynamic); + APPLY_FOR_ROLE(AddressOf); + APPLY_FOR_ROLE(Implicit); + APPLY_FOR_ROLE(RelationChildOf); + APPLY_FOR_ROLE(RelationBaseOf); + APPLY_FOR_ROLE(RelationOverrideOf); + APPLY_FOR_ROLE(RelationReceivedBy); + +#undef APPLY_FOR_ROLE +} + +void index::printSymbolRoles(SymbolRoleSet Roles, raw_ostream &OS) { + bool VisitedOnce = false; + applyForEachSymbolRole(Roles, [&](SymbolRole Role) { + if (VisitedOnce) + OS << '/'; + else + VisitedOnce = true; + switch (Role) { + case SymbolRole::Declaration: OS << "Decl"; break; + case SymbolRole::Definition: OS << "Def"; break; + case SymbolRole::Reference: OS << "Ref"; break; + case SymbolRole::Read: OS << "Read"; break; + case SymbolRole::Write: OS << "Writ"; break; + case SymbolRole::Call: OS << "Call"; break; + case SymbolRole::Dynamic: OS << "Dyn"; break; + case SymbolRole::AddressOf: OS << "Addr"; break; + case SymbolRole::Implicit: OS << "Impl"; break; + case SymbolRole::RelationChildOf: OS << "RelChild"; break; + case SymbolRole::RelationBaseOf: OS << "RelBase"; break; + case SymbolRole::RelationOverrideOf: OS << "RelOver"; break; + case SymbolRole::RelationReceivedBy: OS << "RelRec"; break; + } + }); +} + +StringRef index::getSymbolKindString(SymbolKind K) { + switch (K) { + case SymbolKind::Unknown: return "<unknown>"; + case SymbolKind::Module: return "module"; + case SymbolKind::Macro: return "macro"; + case SymbolKind::Enum: return "enum"; + case SymbolKind::Struct: return "struct"; + case SymbolKind::Union: return "union"; + case SymbolKind::Typedef: return "typedef"; + case SymbolKind::Function: return "function"; + case SymbolKind::Variable: return "variable"; + case SymbolKind::Field: return "field"; + case SymbolKind::EnumConstant: return "enumerator"; + case SymbolKind::ObjCClass: return "objc-class"; + case SymbolKind::ObjCProtocol: return "objc-protocol"; + case SymbolKind::ObjCCategory: return "objc-category"; + case SymbolKind::ObjCInstanceMethod: return "objc-instance-method"; + case SymbolKind::ObjCClassMethod: return "objc-class-method"; + case SymbolKind::ObjCProperty: return "objc-property"; + case SymbolKind::ObjCIvar: return "objc-ivar"; + case SymbolKind::CXXClass: return "c++-class"; + case SymbolKind::CXXNamespace: return "namespace"; + case SymbolKind::CXXNamespaceAlias: return "namespace-alias"; + case SymbolKind::CXXStaticVariable: return "c++-static-var"; + case SymbolKind::CXXStaticMethod: return "c++-static-method"; + case SymbolKind::CXXInstanceMethod: return "c++-instance-method"; + case SymbolKind::CXXConstructor: return "constructor"; + case SymbolKind::CXXDestructor: return "destructor"; + case SymbolKind::CXXConversionFunction: return "coversion-func"; + case SymbolKind::CXXTypeAlias: return "type-alias"; + case SymbolKind::CXXInterface: return "c++-__interface"; + } +} + +StringRef index::getTemplateKindStr(SymbolCXXTemplateKind TK) { + switch (TK) { + case SymbolCXXTemplateKind::NonTemplate: return "NT"; + case SymbolCXXTemplateKind::Template : return "T"; + case SymbolCXXTemplateKind::TemplatePartialSpecialization : return "TPS"; + case SymbolCXXTemplateKind::TemplateSpecialization: return "TS"; + } +} + +StringRef index::getSymbolLanguageString(SymbolLanguage K) { + switch (K) { + case SymbolLanguage::C: return "C"; + case SymbolLanguage::ObjC: return "ObjC"; + case SymbolLanguage::CXX: return "C++"; + } +} Added: cfe/trunk/test/Index/Core/index-source.m URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Core/index-source.m?rev=260842&view=auto ============================================================================== --- cfe/trunk/test/Index/Core/index-source.m (added) +++ cfe/trunk/test/Index/Core/index-source.m Sun Feb 14 00:39:11 2016 @@ -0,0 +1,8 @@ +// RUN: c-index-test core -print-source-symbols -- %s | FileCheck %s + +@interface Base +// CHECK: [[@LINE-1]]:12 | objc-class/ObjC | Base | c:objc(cs)Base | Decl | rel: 0 +-(void)meth; +// CHECK: [[@LINE-1]]:1 | objc-instance-method/ObjC | meth | c:objc(cs)Base(im)meth | Decl/Dyn/RelChild | rel: 1 +// CHECK-NEXT: RelChild | Base | c:objc(cs)Base +@end Modified: cfe/trunk/tools/c-index-test/CMakeLists.txt URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/CMakeLists.txt?rev=260842&r1=260841&r2=260842&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/CMakeLists.txt (original) +++ cfe/trunk/tools/c-index-test/CMakeLists.txt Sun Feb 14 00:39:11 2016 @@ -1,5 +1,10 @@ +set(LLVM_LINK_COMPONENTS + support +) + add_clang_executable(c-index-test c-index-test.c + core_main.cpp ) if(NOT MSVC) @@ -12,10 +17,12 @@ endif() if (LLVM_BUILD_STATIC) target_link_libraries(c-index-test libclang_static + clangIndex ) else() target_link_libraries(c-index-test libclang + clangIndex ) endif() Modified: cfe/trunk/tools/c-index-test/c-index-test.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/c-index-test.c?rev=260842&r1=260841&r2=260842&view=diff ============================================================================== --- cfe/trunk/tools/c-index-test/c-index-test.c (original) +++ cfe/trunk/tools/c-index-test/c-index-test.c Sun Feb 14 00:39:11 2016 @@ -23,6 +23,8 @@ # include <unistd.h> #endif +extern int indextest_core_main(int argc, const char **argv); + /******************************************************************************/ /* Utility functions. */ /******************************************************************************/ @@ -4410,13 +4412,15 @@ int cindextest_main(int argc, const char * size). */ typedef struct thread_info { + int (*main_func)(int argc, const char **argv); int argc; const char **argv; int result; } thread_info; void thread_runner(void *client_data_v) { thread_info *client_data = client_data_v; - client_data->result = cindextest_main(client_data->argc, client_data->argv); + client_data->result = client_data->main_func(client_data->argc, + client_data->argv); } static void flush_atexit(void) { @@ -4435,11 +4439,19 @@ int main(int argc, const char **argv) { LIBXML_TEST_VERSION #endif - if (getenv("CINDEXTEST_NOTHREADS")) - return cindextest_main(argc, argv); - + client_data.main_func = cindextest_main; client_data.argc = argc; client_data.argv = argv; + + if (argc > 1 && strcmp(argv[1], "core") == 0) { + client_data.main_func = indextest_core_main; + --client_data.argc; + ++client_data.argv; + } + + if (getenv("CINDEXTEST_NOTHREADS")) + return client_data.main_func(client_data.argc, client_data.argv); + clang_executeOnThread(thread_runner, &client_data, 0); return client_data.result; } Added: cfe/trunk/tools/c-index-test/core_main.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/c-index-test/core_main.cpp?rev=260842&view=auto ============================================================================== --- cfe/trunk/tools/c-index-test/core_main.cpp (added) +++ cfe/trunk/tools/c-index-test/core_main.cpp Sun Feb 14 00:39:11 2016 @@ -0,0 +1,197 @@ +//===-- core_main.cpp - Core Index Tool testbed ---------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "clang/Frontend/ASTUnit.h" +#include "clang/Frontend/CompilerInstance.h" +#include "clang/Frontend/CompilerInvocation.h" +#include "clang/Frontend/FrontendAction.h" +#include "clang/Index/IndexingAction.h" +#include "clang/Index/IndexDataConsumer.h" +#include "clang/Index/USRGeneration.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/Support/PrettyStackTrace.h" + +using namespace clang; +using namespace clang::index; +using namespace llvm; + +extern "C" int indextest_core_main(int argc, const char **argv); + +namespace { + +enum class ActionType { + None, + PrintSourceSymbols, +}; + +namespace options { + +static cl::OptionCategory IndexTestCoreCategory("index-test-core options"); + +static cl::opt<ActionType> +Action(cl::desc("Action:"), cl::init(ActionType::None), + cl::values( + clEnumValN(ActionType::PrintSourceSymbols, + "print-source-symbols", "Print symbols from source"), + clEnumValEnd), + cl::cat(IndexTestCoreCategory)); + +static cl::extrahelp MoreHelp( + "\nAdd \"-- <compiler arguments>\" at the end to setup the compiler " + "invocation\n" +); + +} +} // anonymous namespace + +static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS); +static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx, + raw_ostream &OS); + +namespace { + +class PrintIndexDataConsumer : public IndexDataConsumer { + raw_ostream &OS; + +public: + PrintIndexDataConsumer(raw_ostream &OS) : OS(OS) { + } + + bool handleDeclOccurence(const Decl *D, SymbolRoleSet Roles, + ArrayRef<SymbolRelation> Relations, + FileID FID, unsigned Offset, + ASTNodeInfo ASTNode) override { + ASTContext &Ctx = D->getASTContext(); + SourceManager &SM = Ctx.getSourceManager(); + + unsigned Line = SM.getLineNumber(FID, Offset); + unsigned Col = SM.getColumnNumber(FID, Offset); + OS << Line << ':' << Col << " | "; + + printSymbolInfo(getSymbolInfo(D), OS); + OS << " | "; + + printSymbolNameAndUSR(D, Ctx, OS); + OS << " | "; + + printSymbolRoles(Roles, OS); + OS << " | "; + + OS << "rel: " << Relations.size() << '\n'; + + for (auto &SymRel : Relations) { + OS << '\t'; + printSymbolRoles(SymRel.Roles, OS); + OS << " | "; + printSymbolNameAndUSR(SymRel.RelatedSymbol, Ctx, OS); + OS << '\n'; + } + + return true; + } +}; + +} // anonymous namespace + +//===----------------------------------------------------------------------===// +// Print Source Symbols +//===----------------------------------------------------------------------===// + +static bool printSourceSymbols(ArrayRef<const char *> Args) { + SmallVector<const char *, 4> ArgsWithProgName; + ArgsWithProgName.push_back("clang"); + ArgsWithProgName.append(Args.begin(), Args.end()); + IntrusiveRefCntPtr<DiagnosticsEngine> + Diags(CompilerInstance::createDiagnostics(new DiagnosticOptions)); + IntrusiveRefCntPtr<CompilerInvocation> + CInvok(createInvocationFromCommandLine(ArgsWithProgName, Diags)); + if (!CInvok) + return true; + + auto DataConsumer = std::make_shared<PrintIndexDataConsumer>(outs()); + IndexingOptions IndexOpts; + std::unique_ptr<FrontendAction> IndexAction; + IndexAction = createIndexingAction(DataConsumer, IndexOpts); + + auto PCHContainerOps = std::make_shared<PCHContainerOperations>(); + ASTUnit *Unit = + ASTUnit::LoadFromCompilerInvocationAction(CInvok.get(), PCHContainerOps, + Diags, IndexAction.get()); + + if (!Unit) + return true; + + return false; +} + +//===----------------------------------------------------------------------===// +// Helper Utils +//===----------------------------------------------------------------------===// + +static void printSymbolInfo(SymbolInfo SymInfo, raw_ostream &OS) { + OS << getSymbolKindString(SymInfo.Kind); + if (SymInfo.TemplateKind != SymbolCXXTemplateKind::NonTemplate) { + OS << '-' << getTemplateKindStr(SymInfo.TemplateKind); + } + OS << '/' << getSymbolLanguageString(SymInfo.Lang); +} + +static void printSymbolNameAndUSR(const Decl *D, ASTContext &Ctx, + raw_ostream &OS) { + if (auto *ND = dyn_cast<NamedDecl>(D)) { + PrintingPolicy PrintPolicy(Ctx.getLangOpts()); + ND->getDeclName().print(OS, PrintPolicy); + } else { + OS << "<no-name>"; + } + OS << " | "; + + SmallString<256> USRBuf; + if (generateUSRForDecl(D, USRBuf)) { + OS << "<no-usr>"; + } else { + OS << USRBuf; + } +} + +//===----------------------------------------------------------------------===// +// Command line processing. +//===----------------------------------------------------------------------===// + +int indextest_core_main(int argc, const char **argv) { + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + + std::vector<const char *> CompArgs; + const char *const *DoubleDash = std::find(argv, argv + argc, StringRef("--")); + if (DoubleDash != argv + argc) { + CompArgs = std::vector<const char *>(DoubleDash + 1, argv + argc); + argc = DoubleDash - argv; + } + + cl::HideUnrelatedOptions(options::IndexTestCoreCategory); + cl::ParseCommandLineOptions(argc, argv, "index-test-core"); + + if (options::Action == ActionType::None) { + errs() << "error: action required; pass '-help' for options\n"; + return 1; + } + + if (options::Action == ActionType::PrintSourceSymbols) { + if (CompArgs.empty()) { + errs() << "error: missing compiler args; pass '-- <compiler arguments>'\n"; + return 1; + } + return printSourceSymbols(CompArgs); + } + + return 0; +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits