[clang] [llvm] Enable format info for C function declarations in Clang Index API, so we may have this context (PR #113754)

via cfe-commits cfe-commits at lists.llvm.org
Fri Oct 25 22:15:52 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: AR Visions (ar-visions)

<details>
<summary>Changes</summary>

Enable format info for C function declarations in Clang Index API, so we may have this context

    clang_Cursor_getFormatAttr
	Get FormatAttr at Function Declaration

    clang_FormatAttr_getType
	Get the format-type field for FormatAttr (i.e. printf, scanf)

    clang_FormatAttr_getFormatIdx
	Get the arg index of format template C-string

    clang_FormatAttr_getFirstArg
	Get the arg index of first arg for formatting params


The purpose of this is to enable the silver compiler (LLVM IR C API) to know context information on imported C functions, so it may convert arguments with more context, and no manual tables describing this information.  This leverages LLVM's FormatAttr data that is already present so Clang Index users may parse C more effectively

---
Full diff: https://github.com/llvm/llvm-project/pull/113754.diff


4 Files Affected:

- (modified) .gitignore (+2) 
- (modified) clang/include/clang-c/Index.h (+23) 
- (modified) clang/tools/libclang/CXCursor.cpp (+26) 
- (modified) clang/tools/libclang/libclang.map (+4) 


``````````diff
diff --git a/.gitignore b/.gitignore
index 0e7c6c79001338..61de1404c127d6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -71,3 +71,5 @@ pythonenv*
 /clang/utils/analyzer/projects/*/RefScanBuildResults
 # automodapi puts generated documentation files here.
 /lldb/docs/python_api/
+silver-debug
+silver-build
diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h
index 0c5ac80772e2b9..d27c571b776405 100644
--- a/clang/include/clang-c/Index.h
+++ b/clang/include/clang-c/Index.h
@@ -3109,6 +3109,29 @@ CINDEX_LINKAGE int clang_getFieldDeclBitWidth(CXCursor C);
  */
 CINDEX_LINKAGE int clang_Cursor_getNumArguments(CXCursor C);
 
+/**
+ * Retrieve FormatAttr on function declaration
+ */
+CINDEX_LINKAGE CXCursor clang_Cursor_getFormatAttr   (CXCursor cur);
+
+/**
+ * Retrieve string name of the type of formatting (i.e. scanf or printf)
+ * used with clang_Cursor_getFormatAttr
+ */
+CINDEX_LINKAGE CXString clang_FormatAttr_getType     (CXCursor C);
+
+/**
+ * Retrieve the arg location (0-based) of the template C-string
+ * used with clang_Cursor_getFormatAttr
+ */
+CINDEX_LINKAGE unsigned clang_FormatAttr_getFormatIdx(CXCursor C);
+
+/**
+ * Retrieve the arg location to the first format argument
+ * used with clang_Cursor_getFormatAttr
+ */
+CINDEX_LINKAGE unsigned clang_FormatAttr_getFirstArg (CXCursor C);
+
 /**
  * Retrieve the argument cursor of a function or method.
  *
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index 562228cc334f3a..1ec0dc05123193 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -1330,6 +1330,32 @@ CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
   return getCursorTU(cursor);
 }
 
+CXCursor clang_Cursor_getFormatAttr(CXCursor cur) {
+  const Decl *decl = cxcursor::getCursorDecl(cur);
+  if (const FunctionDecl *fd = dyn_cast_or_null<FunctionDecl>(decl))
+    if (const FormatAttr *fa = fd->getAttr<FormatAttr>())
+      return cxcursor::MakeCXCursor(fa, decl, cxcursor::getCursorTU(cur)); // cursor with FormatAttr
+  return clang_getNullCursor();
+}
+
+CXString clang_FormatAttr_getType(CXCursor cur) {
+  const FormatAttr *fa = dyn_cast_or_null<FormatAttr>(cxcursor::getCursorAttr(cur));
+  if (!fa) return cxstring::createEmpty();
+  return cxstring::createDup(fa->getType()->getName());
+}
+
+unsigned clang_FormatAttr_getFormatIdx(CXCursor cur) {
+  const FormatAttr *fa = dyn_cast_or_null<FormatAttr>(cxcursor::getCursorAttr(cur));
+  if (!fa) return 0;
+  return fa->getFormatIdx();
+}
+
+unsigned clang_FormatAttr_getFirstArg(CXCursor cur) {
+  const FormatAttr *fa = dyn_cast_or_null<FormatAttr>(cxcursor::getCursorAttr(cur));
+  if (!fa) return 0;
+  return fa->getFirstArg();
+}
+
 int clang_Cursor_getNumArguments(CXCursor C) {
   if (clang_isDeclaration(C.kind)) {
     const Decl *D = cxcursor::getCursorDecl(C);
diff --git a/clang/tools/libclang/libclang.map b/clang/tools/libclang/libclang.map
index 25d8ba57d32514..7737abe3288de9 100644
--- a/clang/tools/libclang/libclang.map
+++ b/clang/tools/libclang/libclang.map
@@ -59,6 +59,10 @@ LLVM_13 {
     clang_Cursor_getMangling;
     clang_Cursor_getModule;
     clang_Cursor_getNumArguments;
+    clang_Cursor_getFormatAttr;
+    clang_FormatAttr_getType;
+    clang_FormatAttr_getFormatIdx;
+    clang_FormatAttr_getFirstArg;
     clang_Cursor_getNumTemplateArguments;
     clang_Cursor_getObjCDeclQualifiers;
     clang_Cursor_getObjCManglings;

``````````

</details>


https://github.com/llvm/llvm-project/pull/113754


More information about the cfe-commits mailing list