Python get#U包含不';找不到标准库标题

Python get#U包含不';找不到标准库标题,python,c++,libclang,Python,C++,Libclang,我正在玩弄libclang的Python绑定。目前,我正在尝试执行一些非常简单的任务,例如找到C++文件中包含的所有头。我使用的代码如下: from clang.cindex import Index index = Index.create() tu = index.parse("hello.cpp", args=["-std=c++14"]) for it in tu.get_includes(): print(it.include.name

我正在玩弄libclang的Python绑定。目前,我正在尝试执行一些非常简单的任务,例如找到C++文件中包含的所有头。我使用的代码如下:

from clang.cindex import Index

index = Index.create()
tu = index.parse("hello.cpp", args=["-std=c++14"])
for it in tu.get_includes():
    print(it.include.name)
#include <iostream>
#include <stdio.h>
#include "hello.h"

int main()
{
    std::cout << "Hello world\n";
}
#include <list>
文件
hello.cpp
如下所示:

from clang.cindex import Index

index = Index.create()
tu = index.parse("hello.cpp", args=["-std=c++14"])
for it in tu.get_includes():
    print(it.include.name)
#include <iostream>
#include <stdio.h>
#include "hello.h"

int main()
{
    std::cout << "Hello world\n";
}
#include <list>
我认为上面的代码将打印
iostream
stdio.h
hello.h
,如果考虑到可传递的包含,可能会打印
list
,甚至更多。但是,它只打印
/hello.h
,公然忽略标准库标题


我在文档中找不到任何关于它是否是设计的。这是设计的吗?如果是这样,是否有任何方法可以实际获取带有
clang.cindex
的文件包含的所有标题,包括标准库标题?

对于仍在寻找答案的人:

import sys
import os
from enum import Enum
from clang.cindex import Config, Index, CursorKind


Config.set_library_path(os.environ['CLANG_LIBRARY_PATH'])


# clang.cindex.TranslationUnit does not have all latest flags
# see: https://clang.llvm.org/doxygen/group__CINDEX__TRANSLATION__UNIT.html#gab1e4965c1ebe8e41d71e90203a723fe9
CXTranslationUnit_None = 0x0
CXTranslationUnit_DetailedPreprocessingRecord = 0x01
CXTranslationUnit_Incomplete = 0x02
CXTranslationUnit_PrecompiledPreamble = 0x04
CXTranslationUnit_CacheCompletionResults = 0x08
CXTranslationUnit_ForSerialization = 0x10
CXTranslationUnit_CXXChainedPCH = 0x20
CXTranslationUnit_SkipFunctionBodies = 0x40
CXTranslationUnit_IncludeBriefCommentsInCodeCompletion = 0x80
CXTranslationUnit_CreatePreambleOnFirstParse = 0x100
CXTranslationUnit_KeepGoing = 0x200
CXTranslationUnit_SingleFileParse = 0x400
CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800
CXTranslationUnit_IncludeAttributedTypes = 0x1000
CXTranslationUnit_VisitImplicitAttributes = 0x2000
CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles = 0x4000
CXTranslationUnit_RetainExcludedConditionalBlocks = 0x8000


class IncludeForm(Enum):
    Quoted = 0
    AngleBracket = 1


class IncludeInfo:
    def __init__(self, path, form, file=None):
        self.path = path
        self.form = form
        self.file = file

    def __str__(self):
        open_bracket, close_bracket = ('<', '>') if self.form == IncludeForm.AngleBracket else ('"', '"')
        return f'#include {open_bracket}{self.path}{close_bracket} // {self.file}'


default_parser_options = (
    CXTranslationUnit_DetailedPreprocessingRecord |  # needed for preprocessing parsing
    CXTranslationUnit_SkipFunctionBodies |  # for faster parsing
    CXTranslationUnit_SingleFileParse |  # don't parse include files recursively
    CXTranslationUnit_RetainExcludedConditionalBlocks |  # keep includes inside ifdef blocks
    CXTranslationUnit_KeepGoing  # don't stop on errors
)


def create_include_parser(options=default_parser_options):
    def try_get_included_file(node):
        try:
            return node.get_included_file()
        except:
            return None

    def parse_includes(file, args=None):
        tu = index.parse(file, args=args, options=options)

        for node in tu.cursor.get_children():
            if node.kind == CursorKind.INCLUSION_DIRECTIVE:
                yield IncludeInfo(
                    node.displayname,
                    IncludeForm.AngleBracket if list(node.get_tokens())[-1].spelling == '>' else IncludeForm.Quoted,
                    try_get_included_file(node)
                )

    index = Index.create()

    return parse_includes


if __name__ == "__main__":
    parse_includes = create_include_parser()

    for file in sys.argv[1:]:
        for include_info in parse_includes(file):
            print(include_info)

也许这会有所帮助:@SimonKraemer不幸的是,这不是真的。我在提出问题之前就发现了,但这只会增加混乱。另外,它似乎使用了一个旧版本的libclang,并且使用了一个微妙不同的API:/you尝试过将过滤器设置为include目录吗?对不起,我不熟悉这些工具。答案看起来好像OP想要的正是你想要的。@SimonKraemer过滤器是OP添加的。通过阅读libclang的代码和文档,似乎没有内置的过滤机制。