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