[clang] Add comments and macros support to Python bindings (PR #81684)

2024-02-13 Thread Dan Miller via cfe-commits

https://github.com/dnmiller created 
https://github.com/llvm/llvm-project/pull/81684

The Python bindings currently do not expose the comment parsing engine and are 
missing a few macro utility functions. This adds bindings for the comments.

>From 497478f08570f1333966c0843d713268bc9ba5c7 Mon Sep 17 00:00:00 2001
From: "Daniel N. Miller (APD)" 
Date: Tue, 13 Feb 2024 15:12:05 -0800
Subject: [PATCH] Add comments and macros support to Python bindings

---
 clang/bindings/python/clang/cindex.py | 284 ++
 1 file changed, 284 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 44a34ca196274c..542bc0172a56fa 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -1907,6 +1907,11 @@ def raw_comment(self):
 """Returns the raw comment text associated with that Cursor"""
 return conf.lib.clang_Cursor_getRawCommentText(self)
 
+@property
+def parsed_comment(self):
+"""Returns the parsed comment text associaetd with that Cursor"""
+return conf.lib.clang_Cursor_getParsedComment(self)
+
 def get_arguments(self):
 """Return an iterator for accessing the arguments of this cursor."""
 num_args = conf.lib.clang_Cursor_getNumArguments(self)
@@ -1994,6 +1999,18 @@ def get_bitfield_width(self):
 """
 return conf.lib.clang_getFieldDeclBitWidth(self)
 
+def is_macro_function(self):
+"""
+Check if the field is a macro function.
+"""
+return conf.lib.clang_Cursor_isMacroFunctionLike(self)
+
+def is_macro_builtin(self):
+"""
+Check if the field is a macro function.
+"""
+return conf.lib.clang_Cursor_isMacroBuiltin(self)
+
 @staticmethod
 def from_result(res, fn, args):
 assert isinstance(res, Cursor)
@@ -2243,6 +2260,72 @@ def __repr__(self):
 TypeKind.EXTVECTOR = TypeKind(176)
 TypeKind.ATOMIC = TypeKind(177)
 
+### Comment Kinds ###
+
+class CommentKind(BaseEnumeration):
+"""
+Describes the kind of comment.
+"""
+
+# The unique kind objects, indexed by id.
+_kinds = []
+_name_map = None
+
+def __repr__(self):
+return 'CommentKind.%s' % (self.name,)
+
+
+CommentKind.NULL = CommentKind(0)
+CommentKind.TEXT = CommentKind(1)
+CommentKind.INLINECOMMAND = CommentKind(2)
+CommentKind.HTMLSTARTTAG = CommentKind(3)
+CommentKind.HTMLENDTAG = CommentKind(4)
+CommentKind.PARAGRAPH = CommentKind(5)
+CommentKind.BLOCKCOMMAND = CommentKind(6)
+CommentKind.PARAMCOMMAND = CommentKind(7)
+CommentKind.TPARAMCOMMAND = CommentKind(8)
+CommentKind.VERBATIMBLOCKCOMMAND = CommentKind(9)
+CommentKind.VERBATIMBLOCKLINE = CommentKind(10)
+CommentKind.VERBATIMLINE = CommentKind(11)
+CommentKind.FULLCOMMENT = CommentKind(12)
+
+
+class CommentInlineCommandRenderKind(BaseEnumeration):
+"""
+Describes the kind of rendering mode of an inline command.
+"""
+# The unique kind objects, indexed by id.
+_kinds = []
+_name_map = None
+
+def __repr__(self):
+return 'CommentInlineCommandRenderKind.%s' % (self.name,)
+
+
+CommentInlineCommandRenderKind.NORMAL = CommentInlineCommandRenderKind(0)
+CommentInlineCommandRenderKind.BOLD = CommentInlineCommandRenderKind(1)
+CommentInlineCommandRenderKind.MONOSPACED = CommentInlineCommandRenderKind(2)
+CommentInlineCommandRenderKind.EMPHASIZE = CommentInlineCommandRenderKind(3)
+
+
+class CommentParamPassDirection(BaseEnumeration):
+"""
+Describes the kind of parameter passing direction for \\param
+or \\arg command
+"""
+# The unique kind objects, indexed by id.
+_kinds = []
+_name_map = None
+
+def __repr__(self):
+return 'CommentParamPassDirection.%s' % (self.name,)
+
+
+CommentParamPassDirection.IN = CommentParamPassDirection(0)
+CommentParamPassDirection.OUT = CommentParamPassDirection(1)
+CommentParamPassDirection.INOU = CommentParamPassDirection(2)
+
+
 
 class RefQualifierKind(BaseEnumeration):
 """Describes a specific ref-qualifier of a type."""
@@ -3574,6 +3657,171 @@ def write_main_file_to_stdout(self):
 callbacks["cursor_visit"] = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
 callbacks["fields_visit"] = CFUNCTYPE(c_int, Cursor, py_object)
 
+class CXTranslationUnitImpl(Structure):
+pass # opaque structure
+
+CXTranslationUnit = POINTER(CXTranslationUnitImpl)
+
+class Comment(Structure):
+_fields_ = [("ASTNode", c_void_p), ("TranslationUnit", CXTranslationUnit)]
+
+def get_text(self):
+return conf.lib.clang_TextComment_getText(self)
+
+@property
+def kind(self):
+"""Return the kind of this comment."""
+kind_id = conf.lib.clang_Comment_getKind(self)
+return CommentKind.from_id(kind_id)
+
+def num_children(self):
+"""Get number of child nodes."""
+return conf.lib.clang_Comment_getNumChildren(self)
+
+def get_children(self):
+"""Return a

[clang] Add comments and macros support to Python bindings (PR #81684)

2024-02-13 Thread Dan Miller via cfe-commits

https://github.com/dnmiller updated 
https://github.com/llvm/llvm-project/pull/81684

>From 0617712f89ef0193f6112680e25bd7b40002d6fd Mon Sep 17 00:00:00 2001
From: "Daniel N. Miller (APD)" 
Date: Tue, 13 Feb 2024 15:12:05 -0800
Subject: [PATCH] Add comments and macros support to Python bindings

---
 clang/bindings/python/clang/cindex.py | 349 ++
 1 file changed, 349 insertions(+)

diff --git a/clang/bindings/python/clang/cindex.py 
b/clang/bindings/python/clang/cindex.py
index 44a34ca196274c..49b4a1f3a765a1 100644
--- a/clang/bindings/python/clang/cindex.py
+++ b/clang/bindings/python/clang/cindex.py
@@ -1378,6 +1378,7 @@ def __repr__(self):
 # A code completion overload candidate.
 CursorKind.OVERLOAD_CANDIDATE = CursorKind(700)
 
+
 ### Template Argument Kinds ###
 class TemplateArgumentKind(BaseEnumeration):
 """
@@ -1396,6 +1397,7 @@ class TemplateArgumentKind(BaseEnumeration):
 TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3)
 TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4)
 
+
 ### Exception Specification Kinds ###
 class ExceptionSpecificationKind(BaseEnumeration):
 """
@@ -1907,6 +1909,11 @@ def raw_comment(self):
 """Returns the raw comment text associated with that Cursor"""
 return conf.lib.clang_Cursor_getRawCommentText(self)
 
+@property
+def parsed_comment(self):
+"""Returns the parsed comment text associaetd with that Cursor"""
+return conf.lib.clang_Cursor_getParsedComment(self)
+
 def get_arguments(self):
 """Return an iterator for accessing the arguments of this cursor."""
 num_args = conf.lib.clang_Cursor_getNumArguments(self)
@@ -1994,6 +2001,18 @@ def get_bitfield_width(self):
 """
 return conf.lib.clang_getFieldDeclBitWidth(self)
 
+def is_macro_function(self):
+"""
+Check if the field is a macro function.
+"""
+return conf.lib.clang_Cursor_isMacroFunctionLike(self)
+
+def is_macro_builtin(self):
+"""
+Check if the field is a macro function.
+"""
+return conf.lib.clang_Cursor_isMacroBuiltin(self)
+
 @staticmethod
 def from_result(res, fn, args):
 assert isinstance(res, Cursor)
@@ -2243,6 +2262,74 @@ def __repr__(self):
 TypeKind.EXTVECTOR = TypeKind(176)
 TypeKind.ATOMIC = TypeKind(177)
 
+### Comment Kinds ###
+
+
+class CommentKind(BaseEnumeration):
+"""
+Describes the kind of comment.
+"""
+
+# The unique kind objects, indexed by id.
+_kinds = []
+_name_map = None
+
+def __repr__(self):
+return "CommentKind.%s" % (self.name,)
+
+
+CommentKind.NULL = CommentKind(0)
+CommentKind.TEXT = CommentKind(1)
+CommentKind.INLINECOMMAND = CommentKind(2)
+CommentKind.HTMLSTARTTAG = CommentKind(3)
+CommentKind.HTMLENDTAG = CommentKind(4)
+CommentKind.PARAGRAPH = CommentKind(5)
+CommentKind.BLOCKCOMMAND = CommentKind(6)
+CommentKind.PARAMCOMMAND = CommentKind(7)
+CommentKind.TPARAMCOMMAND = CommentKind(8)
+CommentKind.VERBATIMBLOCKCOMMAND = CommentKind(9)
+CommentKind.VERBATIMBLOCKLINE = CommentKind(10)
+CommentKind.VERBATIMLINE = CommentKind(11)
+CommentKind.FULLCOMMENT = CommentKind(12)
+
+
+class CommentInlineCommandRenderKind(BaseEnumeration):
+"""
+Describes the kind of rendering mode of an inline command.
+"""
+
+# The unique kind objects, indexed by id.
+_kinds = []
+_name_map = None
+
+def __repr__(self):
+return "CommentInlineCommandRenderKind.%s" % (self.name,)
+
+
+CommentInlineCommandRenderKind.NORMAL = CommentInlineCommandRenderKind(0)
+CommentInlineCommandRenderKind.BOLD = CommentInlineCommandRenderKind(1)
+CommentInlineCommandRenderKind.MONOSPACED = CommentInlineCommandRenderKind(2)
+CommentInlineCommandRenderKind.EMPHASIZE = CommentInlineCommandRenderKind(3)
+
+
+class CommentParamPassDirection(BaseEnumeration):
+"""
+Describes the kind of parameter passing direction for \\param
+or \\arg command
+"""
+
+# The unique kind objects, indexed by id.
+_kinds = []
+_name_map = None
+
+def __repr__(self):
+return "CommentParamPassDirection.%s" % (self.name,)
+
+
+CommentParamPassDirection.IN = CommentParamPassDirection(0)
+CommentParamPassDirection.OUT = CommentParamPassDirection(1)
+CommentParamPassDirection.INOU = CommentParamPassDirection(2)
+
 
 class RefQualifierKind(BaseEnumeration):
 """Describes a specific ref-qualifier of a type."""
@@ -3574,6 +3661,187 @@ def write_main_file_to_stdout(self):
 callbacks["cursor_visit"] = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
 callbacks["fields_visit"] = CFUNCTYPE(c_int, Cursor, py_object)
 
+
+class CXTranslationUnitImpl(Structure):
+pass  # opaque structure
+
+
+CXTranslationUnit = POINTER(CXTranslationUnitImpl)
+
+
+class Comment(Structure):
+_fields_ = [("ASTNode", c_void_p), ("TranslationUnit", CXTranslationUnit)]
+
+def get_text(self):
+return conf.lib.clang_TextComment_getText(self)
+
+@p