我正在使用pyclang解析标头:
import argparse
import clang.cindex
relevant_tokens = [
clang.cindex.CursorKind.FUNCTION_DECL,
clang.cindex.CursorKind.CXX_METHOD,
clang.cindex.CursorKind.CONSTRUCTOR,
clang.cindex.CursorKind.DESTRUCTOR,
clang.cindex.CursorKind.STRUCT_DECL,
clang.cindex.CursorKind.CLASS_DECL,
clang.cindex.CursorKind.FIELD_DECL,
clang.cindex.CursorKind.FUNCTION_TEMPLATE,
clang.cindex.CursorKind.CLASS_TEMPLATE,
]
def ExtractTokensOfInterest(path):
index = clang.cindex.Index.create()
translation_unit = index.parse(path, args=['-std=c++20'])
for token in translation_unit.get_tokens(extent=translation_unit.cursor.extent):
if token.kind == clang.cindex.TokenKind.IDENTIFIER and token.cursor.kind in relevant_tokens:
print(token.cursor.displayname)
print(token.cursor.result_type.spelling)
我在一个相当复杂的头上运行,该头导入vulkan结构,它可以完美地工作,但只要stl向量出现故障,这就是一个示例输出:
SetGlobalPointer(HardwareInterface *)
void
BeginSingleTimeCommands(HardwareInterface &)
vk::CommandBuffer
EndSingleTimeCommands(HardwareInterface &, vk::CommandBuffer &)
void
HardwareInterface()
void
HardwareInterface(GLFWwindow *)
void
Dummy()
int
Dummy()
int
Dummy()
int
Dummy()
int
GetInstance()
vk::Instance &
GetPhysicalDevice()
vk::PhysicalDevice &
GetDevice()
vk::Device &
GetSurface()
vk::SurfaceKHR &
GetCommandPool()
vk::CommandPool &
GetGraphicQueue()
vk::Queue &
GetComputeQueue()
vk::Queue &
GetQueueFamily()
int32_t
GetCmdBuffer()
vk::CommandBuffer &
StartCmdUpdate()
void
EndCmdUpdate()
void
DrawIndexed(const int &, vk::Buffer, vk::Buffer, uint, uint, size_t, size_t, size_t)
void
CreateSemaphores(uint32_t)
int
CreateSemaphores(uint32_t)
int
CreateSemaphores(uint32_t)
int
CreateSemaphores(uint32_t)
int
CreateSemaphores(uint32_t)
int
CreateSemaphores(uint32_t)
int
CreateSemaphores(uint32_t)
int
CreateFences(uint32_t)
int
CreateFences(uint32_t)
int
CreateFences(uint32_t)
int
CreateFences(uint32_t)
int
CreateFences(uint32_t)
int
CreateFences(uint32_t)
int
CreateFences(uint32_t)
int
注意到那个假回归了吗?这就是方法声明的样子:
std::vector<std::string> Dummy();
所以PyClang成功地为vulkan解决了许多超级复杂的基于模板的typdfs,但它不能处理任何类型的stl矢量,甚至不能处理std::string类型的矢量?
示例标题:
#pragma once
#define GLFW_INCLUDE_VULKAN
/** @cond */
#include <GLFW/glfw3.h>
#include "vulkan/vulkan.hpp"
/** @endcond */
#include "VkExtensionsStubs.hpp"
#include "Utils.hpp"
#include "VulkanDebugging.hpp"
using uint = unsigned int;
struct Dummy
{
int field1;
std::string field2;
};
/**
* @brief Wrapper to facilitate communication with the graphics hardware through Vulkan.
*
* The instance, physical device, logical device... Are all encapsulated here, it mostly
* reduces the amoutn of parameters that need to be passed around, but it also provides
* some low level functionality to dispatch GPU work.
*
*/
class HardwareInterface
{
private:
vk::UniqueInstance instance;
vk::PhysicalDevice physical_device;
vk::UniqueDevice device;
vk::UniqueDebugUtilsMessengerEXT debug_messenger;
vk::UniqueSurfaceKHR surface;
vk::UniqueCommandPool cmd_pool;
vk::UniqueCommandBuffer cmd_buffer;
int32_t queue_family = -1;
vk::Queue graphic_queue;
vk::Queue compute_queue;
public:
// TODO (medium): Try to make this into a shared_ptr (currently causes segfault)
static HardwareInterface* h_interface;
static void SetGlobalPointer(HardwareInterface* ptr) { h_interface = ptr; }
/**
* @brief Begin a small command that will be executed once and immediately.
*
* @param h_interface Wrapper around the hardware info (e.g. device, logical device,
* instance...)
* @return vk::CommandBuffer Buffer to record one time commands.
*/
static vk::CommandBuffer BeginSingleTimeCommands(HardwareInterface& h_interface);
/**
* @brief End and call the command. Call after `BeginSingleTimeCommands()`.
*
* @param h_interface Wrapper around the hardware info (e.g. device, logical device,
* instance...)
* @param command_buffer Command created by BeginSingleTimeCommands() where the
* commands were recorded.
*/
static void EndSingleTimeCommands(
HardwareInterface& h_interface, vk::CommandBuffer& command_buffer);
HardwareInterface(){};
/**
* @brief Construct a new Hardware Interface wrapper.
*
* @param window GLFWwindow containing the surface to which we will present.
*
* Example:
* (Create a hardware interface)
* code {.cpp}
* glfwInit();
* glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
* GLFWwindow* window = glfwCreateWindow(1, 1, "dummy window", nullptr, nullptr);
* HardwareInterface hi(window);
* endcode
*/
HardwareInterface(GLFWwindow* window);
/**
* @brief Get the Vulkan Instance.
*
* @return vk::Instance& Vulkan Instance.
*/
vk::Instance& GetInstance() { return *instance; }
/**
* @brief Get the Vulkan PhysicalDevice.
*
* @return vk::PhysicalDevice& Vulkan PhysicalDevice.
*/
vk::PhysicalDevice& GetPhysicalDevice() { return physical_device; }
/**
* @brief Get the Vulkan Device.
*
* @return vk::Device& Vulkan Device.
*/
vk::Device& GetDevice() { return *device; }
/**
* @brief Get the Vulkan Surface.
*
* @return vk::SurfaceKHR& Vulkan Surface.
*/
vk::SurfaceKHR& GetSurface() { return *surface; }
/**
* @brief Get the Vulkan CommandPool.
*
* @return vk::CommandPool& Vulkan CommandPool.
*/
vk::CommandPool& GetCommandPool() { return *cmd_pool; }
/**
* @brief Get the Vulkan Graphic Queue.
*
* @return vk::Queue Graphic Queue.
*/
vk::Queue& GetGraphicQueue() { return graphic_queue; }
/**
* @brief Get the Vulkan Compute Queue.
*
* @return vk::Queue Compute Queue.
*/
vk::Queue& GetComputeQueue() { return compute_queue; }
/**
* @brief Get the Vulkan Queue Family.
*
* @return int32_t Vulkan Queue Family.
*/
int32_t GetQueueFamily() { return queue_family; }
/**
* @brief Get the Vulkan CommandBuffer.
*
* @return vk::CommandBuffer& Vulkan CommandBuffer.
*/
vk::CommandBuffer& GetCmdBuffer() { return *cmd_buffer; }
/**
* @brief Start recording commands for a major compute or render operation.
*
*/
void StartCmdUpdate();
/**
* @brief End recording commands for a major compute or render operation.
*
*/
void EndCmdUpdate();
/**
* @brief Draw using an index buffer expressing vertex connectivity.
*
* @param vertex_buffers Vertex attribute buffers.
* @param index_buffer Index buffer.
* @param instance_buffer Buffer containing the instance data.
* @param index_num Number of indices in the index buffer.
* @param instance_count Total number of instances to render if any. If larger than
* 0 instanced rendering is called insteaf of the regular call.
* @param vertex_offset Offset within the vertex buffer at which indices will start.
* @param index_offset Index used as the base index within the index buffer.
* @param element_count Number of elements to draw.
*/
void DrawIndexed(
const std::vector<vk::Buffer>& vertex_buffers,
vk::Buffer index_buffer,
vk::Buffer instance_buffer,
uint index_num,
uint instance_count,
size_t vertex_offset,
size_t index_offset,
size_t element_count);
/**
* @brief Create a list of Semaphores for GPU to GPU syncing.
*
* @param semaphore_num Number of semaphores to create.
* @return std::vector<vk::UniqueSemaphore> List of semaphores for syncing.
*/
std::vector<vk::UniqueSemaphore> CreateSemaphores(uint32_t semaphore_num);
/**
* @brief Create a list of Fences for CPU to GPU syncing.
*
* @param fence_num Number of fences to create.
* @return std::vector<vk::UniqueFence> List of fences for syncing.
*/
std::vector<vk::UniqueFence> CreateFences(uint32_t fence_num);
};
我也遇到过类似的问题,"int";似乎是出现问题时的回退类型,例如一些未解决的include。这篇文章的答案对我很有用:用libclang解析;无法解析某些令牌(Windows中的Python(
编辑:可以通过检查诊断来指示缺少包含:
for diag in tu.diagnostics:
if diag.severity == diag.Fatal:
print(diag.location)
print(diag.spelling)
print(diag.option)