LLVM Discussion Forums

Libclang returns generic error 1 for Risc-V target; why?

I am trying to use libclang for source code analysis in an IDE for embedded software.

When targeting an ARM processor, I use -target arm-none-eabi to make sure that the appropriate preprocessor macros are defined, and this works well. I am also using -isystem to point libclang to the include files for my arm cross-compiler.

When I try to do the same for a RISC-V target using -target riscv-none-embed, clang_indexSourceFile returns error code 1 (CXError_Failure), which is a “generic error code, no further details are available” according to the comments in clang-c/CxErrorCode.h.

Does this mean that the RISC-V target is not supported yet, or is something else missing? Am I using the wrong target? In general, when clang_indexSourceFile returns an error code, is there a way to figure out the cause?

The C++ program below reproduces the problem. After installing either llvm-9.0.1 or the latest version on the master branch, compile with

g++ -o myclang myclang.cpp

and run with

./myclang -target riscv-none-embed empty.c

where empty.c is an empty file. The output is “Clang error 1: internal error”, and the return code is 1. Adding a source file and/or -isystem options does not change that. With -target arm-none-eabi, it succeeds (no output, return code 0).

Contents of myclang.cpp:

#include <clang-c/Index.h>
#include <iostream>

int main(int argc, char **argv)
{
  CXIndex index = clang_createIndex(1, /*report diagnostics on stderr = */1);
  CXIndexAction index_action = clang_IndexAction_create(index);
  CXTranslationUnit clang_unit = 0;
  unsigned clang_error = clang_indexSourceFile(
    index_action,
    0, // client data
    0, 0, // callbacks
    CXIndexOpt_IndexFunctionLocalSymbols | CXIndexOpt_IndexImplicitTemplateInstantiations,
    0, // source file, or null if included in args
    argv, argc,
    0, 0, // unsaved files
    &clang_unit, //&translation unit pointer or null
    CXTranslationUnit_KeepGoing | CXTranslationUnit_DetailedPreprocessingRecord
  );
  if (clang_error) {
    const char *clang_message[] = {
      "no error",
      "internal error", // Also returned when main source file cannot be opened
      "crashed",
      "invalid arguments",
      "deserialization error"
    };
    const char *message = clang_message[
      clang_error >= sizeof(clang_message)/sizeof(*clang_message)
      ? 1 : clang_error
    ];
    std::cerr << "Clang error " << clang_error << ": " << message << std::endl;
  }
  return clang_error;
}