blob: a2860a10959807f861344426f40f6d3056a7e5a2 [file] [log] [blame]
Ted Kremenek64dddfb2010-11-16 02:03:55 +00001//===- 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"
Ted Kremenek91554282010-11-16 08:15:36 +000019#include "llvm/ADT/SmallString.h"
Ted Kremenek64dddfb2010-11-16 02:03:55 +000020#include "llvm/Support/ErrorHandling.h"
21
22using namespace clang;
23using namespace clang::cxstring;
24
Ted Kremenek91554282010-11-16 08:15:36 +000025enum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf };
26
27//===----------------------------------------------------------------------===//
28// Basic generation of CXStrings.
29//===----------------------------------------------------------------------===//
Ted Kremenek64dddfb2010-11-16 02:03:55 +000030
31CXString cxstring::createCXString(const char *String, bool DupString){
32 CXString Str;
33 if (DupString) {
Ted Kremenek91554282010-11-16 08:15:36 +000034 Str.data = strdup(String);
Ted Kremenek64dddfb2010-11-16 02:03:55 +000035 Str.private_flags = (unsigned) CXS_Malloc;
36 } else {
Ted Kremenek91554282010-11-16 08:15:36 +000037 Str.data = (void*)String;
Ted Kremenek64dddfb2010-11-16 02:03:55 +000038 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;
Ted Kremenek91554282010-11-16 08:15:36 +000049 Result.data = Spelling;
Ted Kremenek64dddfb2010-11-16 02:03:55 +000050 Result.private_flags = (unsigned) CXS_Malloc;
51 } else {
Ted Kremenek91554282010-11-16 08:15:36 +000052 Result.data = (void*) String.data();
Ted Kremenek64dddfb2010-11-16 02:03:55 +000053 Result.private_flags = (unsigned) CXS_Unmanaged;
54 }
55 return Result;
56}
57
Ted Kremenek91554282010-11-16 08:15:36 +000058CXString 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
Ted Kremenek64dddfb2010-11-16 02:03:55 +0000103//===----------------------------------------------------------------------===//
104// libClang public APIs.
105//===----------------------------------------------------------------------===//
106
107extern "C" {
108const char *clang_getCString(CXString string) {
Ted Kremenek91554282010-11-16 08:15:36 +0000109 if (string.private_flags == (unsigned) CXS_StringBuf) {
110 return ((CXStringBuf*)string.data)->Data.data();
111 }
112 return (const char*) string.data;
Ted Kremenek64dddfb2010-11-16 02:03:55 +0000113}
114
115void clang_disposeString(CXString string) {
Ted Kremenek91554282010-11-16 08:15:36 +0000116 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 }
Ted Kremenek64dddfb2010-11-16 02:03:55 +0000127}
128} // end: extern "C"
129