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)32CXString 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)44CXString 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)59CXString 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()74void *cxstring::createCXStringPool() { 75 return new CXStringPool(); 76 } 77 disposeCXStringPool(void * p)78void 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)89CXStringBuf *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)99void cxstring::disposeCXStringBuf(CXStringBuf *buf) { 100 if (buf) 101 static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf); 102 } 103 isManagedByPool(CXString str)104bool 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)113const 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)120void 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