CXString.cpp revision 9c48d16a11872624410ab3a5944edcba0f32818c
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::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 = 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 = static_cast<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 = 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 71cxstring::CXStringPool::~CXStringPool() { 72 for (std::vector<CXStringBuf *>::iterator I = Pool.begin(), E = Pool.end(); 73 I != E; ++I) { 74 delete *I; 75 } 76} 77 78CXStringBuf *cxstring::CXStringPool::getCXStringBuf(CXTranslationUnit TU) { 79 if (Pool.empty()) 80 return new CXStringBuf(TU); 81 82 CXStringBuf *Buf = Pool.back(); 83 Buf->Data.clear(); 84 Pool.pop_back(); 85 return Buf; 86} 87 88CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) { 89 return TU->StringPool->getCXStringBuf(TU); 90} 91 92void cxstring::CXStringBuf::dispose() { 93 TU->StringPool->Pool.push_back(this); 94} 95 96bool cxstring::isManagedByPool(CXString str) { 97 return ((CXStringFlag) str.private_flags) == CXS_StringBuf; 98} 99 100//===----------------------------------------------------------------------===// 101// libClang public APIs. 102//===----------------------------------------------------------------------===// 103 104extern "C" { 105const char *clang_getCString(CXString string) { 106 if (string.private_flags == (unsigned) CXS_StringBuf) { 107 return static_cast<const CXStringBuf *>(string.data)->Data.data(); 108 } 109 return static_cast<const char *>(string.data); 110} 111 112void clang_disposeString(CXString string) { 113 switch ((CXStringFlag) string.private_flags) { 114 case CXS_Unmanaged: 115 break; 116 case CXS_Malloc: 117 if (string.data) 118 free(const_cast<void *>(string.data)); 119 break; 120 case CXS_StringBuf: 121 static_cast<CXStringBuf *>( 122 const_cast<void *>(string.data))->dispose(); 123 break; 124 } 125} 126} // end: extern "C" 127 128