blob: bb09cd5cdc226b804df37f561a964c67a3e56a2f [file] [log] [blame]
Ted Kremenekea834df2010-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"
Ted Kremenek0a90d322010-11-17 23:24:11 +000017#include "CXTranslationUnit.h"
Ted Kremenekea834df2010-11-16 02:03:55 +000018#include "clang/Frontend/ASTUnit.h"
19#include "clang-c/Index.h"
Ted Kremeneka60ed472010-11-16 08:15:36 +000020#include "llvm/ADT/SmallString.h"
Ted Kremenekea834df2010-11-16 02:03:55 +000021#include "llvm/Support/ErrorHandling.h"
22
23using namespace clang;
24using namespace clang::cxstring;
25
Ted Kremeneka60ed472010-11-16 08:15:36 +000026enum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf };
27
28//===----------------------------------------------------------------------===//
29// Basic generation of CXStrings.
30//===----------------------------------------------------------------------===//
Ted Kremenekea834df2010-11-16 02:03:55 +000031
32CXString cxstring::createCXString(const char *String, bool DupString){
33 CXString Str;
34 if (DupString) {
Ted Kremeneka60ed472010-11-16 08:15:36 +000035 Str.data = strdup(String);
Ted Kremenekea834df2010-11-16 02:03:55 +000036 Str.private_flags = (unsigned) CXS_Malloc;
37 } else {
Ted Kremeneka60ed472010-11-16 08:15:36 +000038 Str.data = (void*)String;
Ted Kremenekea834df2010-11-16 02:03:55 +000039 Str.private_flags = (unsigned) CXS_Unmanaged;
40 }
41 return Str;
42}
43
Chris Lattner5f9e2722011-07-23 10:55:15 +000044CXString cxstring::createCXString(StringRef String, bool DupString) {
Ted Kremenekea834df2010-11-16 02:03:55 +000045 CXString Result;
46 if (DupString || (!String.empty() && String.data()[String.size()] != 0)) {
47 char *Spelling = (char *)malloc(String.size() + 1);
48 memmove(Spelling, String.data(), String.size());
49 Spelling[String.size()] = 0;
Ted Kremeneka60ed472010-11-16 08:15:36 +000050 Result.data = Spelling;
Ted Kremenekea834df2010-11-16 02:03:55 +000051 Result.private_flags = (unsigned) CXS_Malloc;
52 } else {
Ted Kremeneka60ed472010-11-16 08:15:36 +000053 Result.data = (void*) String.data();
Ted Kremenekea834df2010-11-16 02:03:55 +000054 Result.private_flags = (unsigned) CXS_Unmanaged;
55 }
56 return Result;
57}
58
Ted Kremeneka60ed472010-11-16 08:15:36 +000059CXString 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
71
72typedef std::vector<CXStringBuf *> CXStringPool;
73
74void *cxstring::createCXStringPool() {
75 return new CXStringPool();
76}
77
78void cxstring::disposeCXStringPool(void *p) {
79 CXStringPool *pool = static_cast<CXStringPool*>(p);
80 if (pool) {
81 for (CXStringPool::iterator I = pool->begin(), E = pool->end();
82 I != E; ++I) {
83 delete *I;
84 }
85 delete pool;
86 }
87}
88
89CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) {
90 CXStringPool *pool = static_cast<CXStringPool*>(TU->StringPool);
91 if (pool->empty())
92 return new CXStringBuf(TU);
93 CXStringBuf *buf = pool->back();
94 buf->Data.clear();
95 pool->pop_back();
96 return buf;
97}
98
99void cxstring::disposeCXStringBuf(CXStringBuf *buf) {
100 if (buf)
101 static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf);
102}
103
Ted Kremenekbaf82b02011-08-17 22:19:53 +0000104bool cxstring::isManagedByPool(CXString str) {
105 return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
106}
107
Ted Kremenekea834df2010-11-16 02:03:55 +0000108//===----------------------------------------------------------------------===//
109// libClang public APIs.
110//===----------------------------------------------------------------------===//
111
112extern "C" {
113const char *clang_getCString(CXString string) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000114 if (string.private_flags == (unsigned) CXS_StringBuf) {
115 return ((CXStringBuf*)string.data)->Data.data();
116 }
117 return (const char*) string.data;
Ted Kremenekea834df2010-11-16 02:03:55 +0000118}
119
120void clang_disposeString(CXString string) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000121 switch ((CXStringFlag) string.private_flags) {
122 case CXS_Unmanaged:
123 break;
124 case CXS_Malloc:
125 if (string.data)
126 free((void*)string.data);
127 break;
128 case CXS_StringBuf:
129 disposeCXStringBuf((CXStringBuf *) string.data);
130 break;
131 }
Ted Kremenekea834df2010-11-16 02:03:55 +0000132}
133} // end: extern "C"
134