CXString.cpp revision dad4c1a9ac4ef1aa591ac2ef20dc4c30d96f9f2a
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-c/Index.h" 19#include "clang/Frontend/ASTUnit.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::createNull() { 33 CXString Str; 34 Str.data = 0; 35 Str.private_flags = CXS_Unmanaged; 36 return Str; 37} 38 39CXString cxstring::createCXString(const char *String, bool DupString){ 40 CXString Str; 41 if (DupString) { 42 Str.data = strdup(String); 43 Str.private_flags = (unsigned) CXS_Malloc; 44 } else { 45 Str.data = String; 46 Str.private_flags = (unsigned) CXS_Unmanaged; 47 } 48 return Str; 49} 50 51CXString cxstring::createCXString(StringRef String, bool DupString) { 52 CXString Result; 53 if (DupString || (!String.empty() && String.data()[String.size()] != 0)) { 54 char *Spelling = static_cast<char *>(malloc(String.size() + 1)); 55 memmove(Spelling, String.data(), String.size()); 56 Spelling[String.size()] = 0; 57 Result.data = Spelling; 58 Result.private_flags = (unsigned) CXS_Malloc; 59 } else { 60 Result.data = String.data(); 61 Result.private_flags = (unsigned) CXS_Unmanaged; 62 } 63 return Result; 64} 65 66CXString cxstring::createCXString(CXStringBuf *buf) { 67 CXString Str; 68 Str.data = buf; 69 Str.private_flags = (unsigned) CXS_StringBuf; 70 return Str; 71} 72 73 74//===----------------------------------------------------------------------===// 75// String pools. 76//===----------------------------------------------------------------------===// 77 78cxstring::CXStringPool::~CXStringPool() { 79 for (std::vector<CXStringBuf *>::iterator I = Pool.begin(), E = Pool.end(); 80 I != E; ++I) { 81 delete *I; 82 } 83} 84 85CXStringBuf *cxstring::CXStringPool::getCXStringBuf(CXTranslationUnit TU) { 86 if (Pool.empty()) 87 return new CXStringBuf(TU); 88 89 CXStringBuf *Buf = Pool.back(); 90 Buf->Data.clear(); 91 Pool.pop_back(); 92 return Buf; 93} 94 95CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) { 96 return TU->StringPool->getCXStringBuf(TU); 97} 98 99void cxstring::CXStringBuf::dispose() { 100 TU->StringPool->Pool.push_back(this); 101} 102 103bool cxstring::isManagedByPool(CXString str) { 104 return ((CXStringFlag) str.private_flags) == CXS_StringBuf; 105} 106 107//===----------------------------------------------------------------------===// 108// libClang public APIs. 109//===----------------------------------------------------------------------===// 110 111extern "C" { 112const char *clang_getCString(CXString string) { 113 if (string.private_flags == (unsigned) CXS_StringBuf) { 114 return static_cast<const CXStringBuf *>(string.data)->Data.data(); 115 } 116 return static_cast<const char *>(string.data); 117} 118 119void clang_disposeString(CXString string) { 120 switch ((CXStringFlag) string.private_flags) { 121 case CXS_Unmanaged: 122 break; 123 case CXS_Malloc: 124 if (string.data) 125 free(const_cast<void *>(string.data)); 126 break; 127 case CXS_StringBuf: 128 static_cast<CXStringBuf *>( 129 const_cast<void *>(string.data))->dispose(); 130 break; 131 } 132} 133} // end: extern "C" 134 135