[cfe-dev] Clang indexing doesn't detect C++20 ConceptDecls

E via cfe-dev cfe-dev at lists.llvm.org
Wed Apr 7 12:28:57 PDT 2021


Hello,

I'm having trouble getting Clang's IndexingAction to detect 
clang::ConceptDecls.
I have a minimum working example (reproduced below) that initializes 
an IndexingAction and runs it over some test code that contains two 
ConceptDecls. I've verified that the frontend "sees" these decls by 
dumping the AST.

However, the IndexingAction is set up to print a simple message 
when it encounters any kind of decl, and no such message is 
printed when running over the aforementioned code. Ergo, it 
seems like ConceptDecls are invisible to the IndexingAction, 
whereas other decls are detected properly (clang::CXXRecordDecl, 
clang::FunctionDecl, etc).

I've reproduced this problem in LLVM/Clang 11 and 12.

Any help is appreciated.

Thanks.


CMake build file:

cmake_minimum_required(VERSION 3.8)
project(concepts-test LANGUAGES CXX)

# Sources for the executable are specified at end of CMakeLists.txt
add_executable(concepts-test "")

# Enable C++20
set_property(TARGET concepts-test PROPERTY CXX_STANDARD 20)

# Libraries
find_package(Clang REQUIRED)
target_link_libraries(concepts-test PRIVATE
  clangTooling
  clangToolingInclusions
  clangToolingCore
  clangFrontend
  clangAST
  clangIndex
  clangBasic
)
target_link_libraries(concepts-test PRIVATE LLVM)
target_include_directories(concepts-test SYSTEM PRIVATE ${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS})

target_sources(concepts-test PRIVATE main.cpp)


Source code for main.cpp:

#include "clang/Tooling/Tooling.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/Index/IndexingAction.h"
#include "clang/Index/IndexingOptions.h"
#include <cstdio>

class IndexDataConsumer : public clang::index::IndexDataConsumer {
public:
  // Print a message to stdout if any kind of declaration is found
  bool handleDeclOccurrence(const clang::Decl*,
                            clang::index::SymbolRoleSet,
                            llvm::ArrayRef<clang::index::SymbolRelation>,
                            clang::SourceLocation,
                            clang::index::IndexDataConsumer::ASTNodeInfo) override {
    printf("Found a decl occurrence\n");
    return true;
  }
};

class IndexActionFactory : public clang::tooling::FrontendActionFactory {
public:
  std::unique_ptr<clang::FrontendAction> create() override {
    // The most permissive set of indexing options possible
    clang::index::IndexingOptions opts;
    opts.IndexFunctionLocals           = true;
    opts.IndexImplicitInstantiation    = true;
    opts.IndexMacrosInPreprocessor     = true;
    opts.IndexParametersInDeclarations = true;
    opts.IndexTemplateParameters       = true;
    opts.SystemSymbolFilter            = clang::index::IndexingOptions::SystemSymbolFilterKind::None;
    IndexDataConsumer idx;
    return createIndexingAction(std::make_shared<IndexDataConsumer>(idx), opts);
  }
};

int main() {
  const std::string code = R"(
    // Basic example of a concept
    template <typename T, typename U = T> concept Sumable = requires(T a, U b) {
      {a + b};
      {b + a};
    };

    // Another basic example of a concept
    template<typename T>
    concept has_type_member = requires { typename T::type; };
  )";

  // Run the indexing action over the code above.
  // If any decl is found in the AST, the printf should fire.
  IndexActionFactory IndexFactory;
  clang::tooling::runToolOnCodeWithArgs(IndexFactory.create(), code, {"-std=c++20"});
  return 0;
}



More information about the cfe-dev mailing list