ClangTool can't treat .h file as c++ header file

Hi, I make standalone program using clang libTooling. But it can’t recognize any C++ related syntax such as “class” in .h file. If I change the file to .hpp, it can process all C++ syntax. How can I make my program to treat .h file as C++ header file?
Thanks.

Regards,

Deddy W.

Do you from compile_ commands.json read compilation options?
And it’s better to post some codes!

No, I don’t read any options for compile_commands.json file. Can you give me an example how to to that?

Below is the code that I try.

#include <sstream>
#include <string>

#include "clang/AST/AST.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Frontend/ASTConsumers.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "clang/Tooling/CommonOptionsParser.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace clang::driver;
using namespace clang::tooling;

static llvm::cl::OptionCategory ToolingSampleCategory("Tooling Sample");

// By implementing RecursiveASTVisitor, we can specify which AST nodes
// we're interested in by overriding relevant methods.
class MyASTVisitor : public RecursiveASTVisitor<MyASTVisitor> {
public:
    MyASTVisitor(Rewriter& R)
        : TheRewriter(R)
    {
    }

	bool VisitFieldDecl(FieldDecl* fieldDecl)
    {
		std::string name = fieldDecl->getNameAsString ();
		QualType QT = fieldDecl->getType();
		std::string type_str = QT.getAsString();
		printf("name: %s\ttype: %s\n", name.c_str(), type_str.c_str());
		
        return true;
    }

private:
    Rewriter& TheRewriter;
};

// Implementation of the ASTConsumer interface for reading an AST produced
// by the Clang parser.
class MyASTConsumer : public ASTConsumer {
public:
    MyASTConsumer(Rewriter& R)
        : Visitor(R)
    {
    }

    // Override the method that gets called for each parsed top-level
    // declaration.
    bool HandleTopLevelDecl(DeclGroupRef DR) override
    {
        for (DeclGroupRef::iterator b = DR.begin(), e = DR.end(); b != e; ++b) {
            // Traverse the declaration using our AST visitor.
            Visitor.TraverseDecl(*b);
        }
        return true;
    }

private:
    MyASTVisitor Visitor;
};

// For each source file provided to the tool, a new FrontendAction is created.
class MyFrontendAction : public ASTFrontendAction {
public:
    MyFrontendAction() { }
    void EndSourceFileAction() override
    {
        SourceManager& SM = TheRewriter.getSourceMgr();
        llvm::errs() << "** EndSourceFileAction for: "
                     << SM.getFileEntryForID(SM.getMainFileID())->getName() << "\n";

        TheRewriter.overwriteChangedFiles(); // overwrite original code
    }

    std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance& CI,
        StringRef file) override
    {
        llvm::errs() << "** Creating AST consumer for: " << file << "\n";
        TheRewriter.setSourceMgr(CI.getSourceManager(), CI.getLangOpts());
        return std::make_unique<MyASTConsumer>(TheRewriter);
    }

private:
    Rewriter TheRewriter;
};

int main(int argc, const char** argv)
{
    CommonOptionsParser op(argc, argv, ToolingSampleCategory);
    ClangTool Tool(op.getCompilations(), op.getSourcePathList());

    return Tool.run(newFrontendActionFactory<MyFrontendAction>().get());
}

And this is my CMakeLists.txt

cmake_minimum_required(VERSION 3.12)

project(test1)

set(CMAKE_BUILD_TYPE RelWithDebInfo)
find_package(Clang REQUIRED)
include_directories(${LLVM_INCLUDE_DIRS} ${CLANG_INCLUDE_DIRS})
add_definitions(${LLVM_DEFINITIONS})

add_executable(${PROJECT_NAME} libtool_example.cpp)

target_link_libraries(${PROJECT_NAME} clangTooling)

After I compile the code, I run following command

test1 trial.h

Below is trial.h code

class DummyClass {
public:
	double getLength();
private:
	double length;
};