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