r260842 - [index] Enhance c-index-test tool and have it link and test the clangIndex library directly.

Argyrios Kyrtzidis via cfe-commits cfe-commits at lists.llvm.org
Sat Feb 13 22:39:12 PST 2016


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
+
+ at 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
+ at 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;
+}




More information about the cfe-commits mailing list