blob: 739646b373042df4420b0287a83bd46c102f4c1a [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-c/Index.h"
Chandler Carruthf59edb92012-12-04 09:25:21 +000019#include "clang/Frontend/ASTUnit.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 {
Dmitri Gribenko689d7472013-01-11 23:08:18 +000038 Str.data = 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)) {
Dmitri Gribenkoe358fd52013-01-11 23:13:36 +000047 char *Spelling = static_cast<char *>(malloc(String.size() + 1));
Ted Kremenekea834df2010-11-16 02:03:55 +000048 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 {
Dmitri Gribenko689d7472013-01-11 23:08:18 +000053 Result.data = 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
Dmitri Gribenko9c48d162013-01-26 22:44:19 +000071cxstring::CXStringPool::~CXStringPool() {
72 for (std::vector<CXStringBuf *>::iterator I = Pool.begin(), E = Pool.end();
73 I != E; ++I) {
74 delete *I;
Ted Kremeneka60ed472010-11-16 08:15:36 +000075 }
76}
77
Dmitri Gribenko9c48d162013-01-26 22:44:19 +000078CXStringBuf *cxstring::CXStringPool::getCXStringBuf(CXTranslationUnit TU) {
79 if (Pool.empty())
Ted Kremeneka60ed472010-11-16 08:15:36 +000080 return new CXStringBuf(TU);
Dmitri Gribenko9c48d162013-01-26 22:44:19 +000081
82 CXStringBuf *Buf = Pool.back();
83 Buf->Data.clear();
84 Pool.pop_back();
85 return Buf;
Ted Kremeneka60ed472010-11-16 08:15:36 +000086}
87
Dmitri Gribenko9c48d162013-01-26 22:44:19 +000088CXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) {
89 return TU->StringPool->getCXStringBuf(TU);
90}
91
92void cxstring::CXStringBuf::dispose() {
93 TU->StringPool->Pool.push_back(this);
Ted Kremeneka60ed472010-11-16 08:15:36 +000094}
95
Ted Kremenekbaf82b02011-08-17 22:19:53 +000096bool cxstring::isManagedByPool(CXString str) {
97 return ((CXStringFlag) str.private_flags) == CXS_StringBuf;
98}
99
Ted Kremenekea834df2010-11-16 02:03:55 +0000100//===----------------------------------------------------------------------===//
101// libClang public APIs.
102//===----------------------------------------------------------------------===//
103
104extern "C" {
105const char *clang_getCString(CXString string) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000106 if (string.private_flags == (unsigned) CXS_StringBuf) {
Dmitri Gribenkoe358fd52013-01-11 23:13:36 +0000107 return static_cast<const CXStringBuf *>(string.data)->Data.data();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000108 }
Dmitri Gribenkoe358fd52013-01-11 23:13:36 +0000109 return static_cast<const char *>(string.data);
Ted Kremenekea834df2010-11-16 02:03:55 +0000110}
111
112void clang_disposeString(CXString string) {
Ted Kremeneka60ed472010-11-16 08:15:36 +0000113 switch ((CXStringFlag) string.private_flags) {
114 case CXS_Unmanaged:
115 break;
116 case CXS_Malloc:
117 if (string.data)
Dmitri Gribenko689d7472013-01-11 23:08:18 +0000118 free(const_cast<void *>(string.data));
Ted Kremeneka60ed472010-11-16 08:15:36 +0000119 break;
120 case CXS_StringBuf:
Dmitri Gribenko9c48d162013-01-26 22:44:19 +0000121 static_cast<CXStringBuf *>(
122 const_cast<void *>(string.data))->dispose();
Ted Kremeneka60ed472010-11-16 08:15:36 +0000123 break;
124 }
Ted Kremenekea834df2010-11-16 02:03:55 +0000125}
126} // end: extern "C"
127