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 23using namespace clang; 24using namespace clang::cxstring; 25 26enum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf }; 27 28//===----------------------------------------------------------------------===// 29// Basic generation of CXStrings. 30//===----------------------------------------------------------------------===// 31 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 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 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 72typedef std::vector<CXStringBuf *> CXStringPool; 73 74void *cxstring::createCXStringPool() { 75 return new CXStringPool(); 76} 77 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 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 99void cxstring::disposeCXStringBuf(CXStringBuf *buf) { 100 if (buf) 101 static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf); 102} 103 104bool cxstring::isManagedByPool(CXString str) { 105 return ((CXStringFlag) str.private_flags) == CXS_StringBuf; 106} 107 108//===----------------------------------------------------------------------===// 109// libClang public APIs. 110//===----------------------------------------------------------------------===// 111 112extern "C" { 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 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