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