• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===- CXString.cpp - Routines for manipulating CXStrings -----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines routines for manipulating CXStrings. It should be the
11 // only file that has internal knowledge of the encoding of the data in
12 // CXStrings.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "CXString.h"
17 #include "CXTranslationUnit.h"
18 #include "clang/Frontend/ASTUnit.h"
19 #include "clang-c/Index.h"
20 #include "llvm/ADT/SmallString.h"
21 #include "llvm/Support/ErrorHandling.h"
22 
23 using namespace clang;
24 using namespace clang::cxstring;
25 
26 enum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf };
27 
28 //===----------------------------------------------------------------------===//
29 // Basic generation of CXStrings.
30 //===----------------------------------------------------------------------===//
31 
createCXString(const char * String,bool DupString)32 CXString cxstring::createCXString(const char *String, bool DupString){
33   CXString Str;
34   if (DupString) {
35     Str.data = strdup(String);
36     Str.private_flags = (unsigned) CXS_Malloc;
37   } else {
38     Str.data = (void*)String;
39     Str.private_flags = (unsigned) CXS_Unmanaged;
40   }
41   return Str;
42 }
43 
createCXString(StringRef String,bool DupString)44 CXString cxstring::createCXString(StringRef String, bool DupString) {
45   CXString Result;
46   if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
47     char *Spelling = (char *)malloc(String.size() + 1);
48     memmove(Spelling, String.data(), String.size());
49     Spelling[String.size()] = 0;
50     Result.data = Spelling;
51     Result.private_flags = (unsigned) CXS_Malloc;
52   } else {
53     Result.data = (void*) String.data();
54     Result.private_flags = (unsigned) CXS_Unmanaged;
55   }
56   return Result;
57 }
58 
createCXString(CXStringBuf * buf)59 CXString cxstring::createCXString(CXStringBuf *buf) {
60   CXString Str;
61   Str.data = buf;
62   Str.private_flags = (unsigned) CXS_StringBuf;
63   return Str;
64 }
65 
66 
67 //===----------------------------------------------------------------------===//
68 // String pools.
69 //===----------------------------------------------------------------------===//
70 
71 
72 typedef std::vector<CXStringBuf *> CXStringPool;
73 
createCXStringPool()74 void *cxstring::createCXStringPool() {
75   return new CXStringPool();
76 }
77 
disposeCXStringPool(void * p)78 void cxstring::disposeCXStringPool(void *p) {
79   CXStringPool *pool = static_cast<CXStringPool*>(p);
80   if (pool) {
81     for (CXStringPool::iterator I = pool->begin(), E = pool->end();
82          I != E; ++I) {
83       delete *I;
84     }
85     delete pool;
86   }
87 }
88 
getCXStringBuf(CXTranslationUnit TU)89 CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) {
90   CXStringPool *pool = static_cast<CXStringPool*>(TU->StringPool);
91   if (pool->empty())
92     return new CXStringBuf(TU);
93   CXStringBuf *buf = pool->back();
94   buf->Data.clear();
95   pool->pop_back();
96   return buf;
97 }
98 
disposeCXStringBuf(CXStringBuf * buf)99 void cxstring::disposeCXStringBuf(CXStringBuf *buf) {
100   if (buf)
101     static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
102 }
103 
isManagedByPool(CXString str)104 bool cxstring::isManagedByPool(CXString str) {
105   return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
106 }
107 
108 //===----------------------------------------------------------------------===//
109 // libClang public APIs.
110 //===----------------------------------------------------------------------===//
111 
112 extern "C" {
clang_getCString(CXString string)113 const char *clang_getCString(CXString string) {
114   if (string.private_flags == (unsigned) CXS_StringBuf) {
115     return ((CXStringBuf*)string.data)->Data.data();
116   }
117   return (const char*) string.data;
118 }
119 
clang_disposeString(CXString string)120 void clang_disposeString(CXString string) {
121   switch ((CXStringFlag) string.private_flags) {
122     case CXS_Unmanaged:
123       break;
124     case CXS_Malloc:
125       if (string.data)
126         free((void*)string.data);
127       break;
128     case CXS_StringBuf:
129       disposeCXStringBuf((CXStringBuf *) string.data);
130       break;
131   }
132 }
133 } // end: extern "C"
134 
135