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