blob: 268655ab8a5760e1f2c81b4af50ce38a4c1a2f36 [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 Kremenekea834df2010-11-16 02:03:55 +0000104//===----------------------------------------------------------------------===//
105// libClang public APIs.
106//===----------------------------------------------------------------------===//
107
108extern "C" {
109const char *clang_getCString(CXString string) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000110 if (string.private_flags == (unsigned) CXS_StringBuf) {
111 return ((CXStringBuf*)string.data)->Data.data();
112 }
113 return (const char*) string.data;
Ted Kremenekea834df2010-11-16 02:03:55 +0000114}
115
116void clang_disposeString(CXString string) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000117 switch ((CXStringFlag) string.private_flags) {
118 case CXS_Unmanaged:
119 break;
120 case CXS_Malloc:
121 if (string.data)
122 free((void*)string.data);
123 break;
124 case CXS_StringBuf:
125 disposeCXStringBuf((CXStringBuf *) string.data);
126 break;
127 }
Ted Kremenekea834df2010-11-16 02:03:55 +0000128}
129} // end: extern "C"
130