[clang] refactor(libclang): add CXS_StringRef (PR #139093)

via cfe-commits cfe-commits at lists.llvm.org
Thu May 8 08:30:49 PDT 2025


https://github.com/illusory0x0 created https://github.com/llvm/llvm-project/pull/139093

None

>From f3a692b7b0e4800277bf7df10e800ccacce98b37 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=8C=97=E9=9C=B2?=
 <69190413+illusory0x0 at users.noreply.github.com>
Date: Thu, 8 May 2025 23:00:54 +0800
Subject: [PATCH] refactor(libclang): add CXS_StringRef

---
 clang/tools/libclang/CXString.cpp | 53 ++++++++++++++++++++++++-------
 clang/tools/libclang/CXString.h   | 13 ++++++++
 2 files changed, 54 insertions(+), 12 deletions(-)

diff --git a/clang/tools/libclang/CXString.cpp b/clang/tools/libclang/CXString.cpp
index aaa8f8eeb67a1..4986ddba5ff6e 100644
--- a/clang/tools/libclang/CXString.cpp
+++ b/clang/tools/libclang/CXString.cpp
@@ -30,7 +30,10 @@ enum CXStringFlag {
 
   /// CXString contains a CXStringBuf that needs to be returned to the
   /// CXStringPool.
-  CXS_StringBuf
+  CXS_StringBuf,
+
+  /// CXString contains a 'StringRef' that it doesn't own.
+  CXS_StringRef
 };
 
 namespace clang {
@@ -87,7 +90,10 @@ CXString createRef(StringRef String) {
   if (String.empty())
     return createEmpty();
 
-  return createDup(String);
+  CXString Str;
+  Str.data = new CXStringRef{String};
+  Str.private_flags = CXS_StringRef;
+  return Str;
 }
 
 CXString createDup(StringRef String) {
@@ -161,21 +167,44 @@ const char *clang_getCString(CXString string) {
   if (string.private_flags == (unsigned) CXS_StringBuf) {
     return static_cast<const cxstring::CXStringBuf *>(string.data)->Data.data();
   }
+  if (string.private_flags == (unsigned)CXS_StringRef) {
+    auto *sr =
+        static_cast<cxstring::CXStringRef *>(const_cast<void *>(string.data));
+    auto len = sr->string_ref.size();
+    auto *src = sr->string_ref.data();
+
+    if (sr->null_terminated_string == nullptr) {
+      char *nts = (char *)llvm::safe_malloc(len + 1);
+      memcpy(nts, src, len);
+      nts[len] = '\0';
+      sr->null_terminated_string = nts;
+
+    } else {
+      return sr->null_terminated_string;
+    }
+  }
   return static_cast<const char *>(string.data);
 }
 
 void clang_disposeString(CXString string) {
   switch ((CXStringFlag) string.private_flags) {
-    case CXS_Unmanaged:
-      break;
-    case CXS_Malloc:
-      if (string.data)
-        free(const_cast<void *>(string.data));
-      break;
-    case CXS_StringBuf:
-      static_cast<cxstring::CXStringBuf *>(
-          const_cast<void *>(string.data))->dispose();
-      break;
+  case CXS_Unmanaged:
+    break;
+  case CXS_Malloc:
+    if (string.data)
+      free(const_cast<void *>(string.data));
+    break;
+  case CXS_StringBuf:
+    static_cast<cxstring::CXStringBuf *>(const_cast<void *>(string.data))
+        ->dispose();
+    break;
+  case CXS_StringRef: {
+    auto *sr =
+        static_cast<cxstring::CXStringRef *>(const_cast<void *>(string.data));
+    delete sr;
+  }
+
+  break;
   }
 }
 
diff --git a/clang/tools/libclang/CXString.h b/clang/tools/libclang/CXString.h
index 809bdec3d677f..981ea3c8bf117 100644
--- a/clang/tools/libclang/CXString.h
+++ b/clang/tools/libclang/CXString.h
@@ -82,6 +82,16 @@ class CXStringPool {
   friend struct CXStringBuf;
 };
 
+struct CXStringRef {
+  public:
+  const char* null_terminated_string{nullptr};
+  StringRef string_ref;
+  explicit CXStringRef(StringRef  sr) noexcept : string_ref{sr}  { }
+  ~CXStringRef() noexcept {
+    free(const_cast<char*>(null_terminated_string));
+  }
+};
+
 struct CXStringBuf {
   SmallString<128> Data;
   CXTranslationUnit TU;
@@ -104,5 +114,8 @@ static inline StringRef getContents(const CXUnsavedFile &UF) {
 }
 }
 
+
+
+
 #endif
 



More information about the cfe-commits mailing list