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

NAKAMURA Takumi via cfe-commits cfe-commits at lists.llvm.org
Sat Feb 13 23:34:47 PST 2016


I guess it would break layering violation.

libclang exports just C API and it involves clangIndex, but coremain
requires clangIndex and other dependent modules.

I think you should do;
  - Export C++ API in libclang. (But I don't expect it would work for win32)
  - Link libclang as static. Then c-index-test became the test that didn't
test "libclang".

On Sun, Feb 14, 2016 at 3:43 PM Argyrios Kyrtzidis via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> 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;
> +}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160214/4d7153fb/attachment-0001.html>


More information about the cfe-commits mailing list