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 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 44 CXString cxstring::createCXString(llvm::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 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 74 void *cxstring::createCXStringPool() { 75 return new CXStringPool(); 76 } 77 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 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 99 void cxstring::disposeCXStringBuf(CXStringBuf *buf) { 100 if (buf) 101 static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf); 102 } 103 104 //===----------------------------------------------------------------------===// 105 // libClang public APIs. 106 //===----------------------------------------------------------------------===// 107 108 extern "C" { 109 const char *clang_getCString(CXString string) { 110 if (string.private_flags == (unsigned) CXS_StringBuf) { 111 return ((CXStringBuf*)string.data)->Data.data(); 112 } 113 return (const char*) string.data; 114 } 115 116 void clang_disposeString(CXString string) { 117 switch ((CXStringFlag) string.private_flags) { 118 case CXS_Unmanaged: 119 break; 120 case CXS_Malloc: 121 if (string.data) 122 free((void*)string.data); 123 break; 124 case CXS_StringBuf: 125 disposeCXStringBuf((CXStringBuf *) string.data); 126 break; 127 } 128 } 129 } // end: extern "C" 130 131