brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · aaa8f8e Raw
189 lines · cpp
1//===- CXString.cpp - Routines for manipulating CXStrings -----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file defines routines for manipulating CXStrings. It should be the10// only file that has internal knowledge of the encoding of the data in11// CXStrings.12//13//===----------------------------------------------------------------------===//14 15#include "CXString.h"16#include "CXTranslationUnit.h"17#include "clang-c/Index.h"18#include "clang/Frontend/ASTUnit.h"19#include "llvm/Support/ErrorHandling.h"20 21using namespace clang;22 23/// Describes the kind of underlying data in CXString.24enum CXStringFlag {25  /// CXString contains a 'const char *' that it doesn't own.26  CXS_Unmanaged,27 28  /// CXString contains a 'const char *' that it allocated with malloc().29  CXS_Malloc,30 31  /// CXString contains a CXStringBuf that needs to be returned to the32  /// CXStringPool.33  CXS_StringBuf34};35 36namespace clang {37namespace cxstring {38 39//===----------------------------------------------------------------------===//40// Basic generation of CXStrings.41//===----------------------------------------------------------------------===//42 43CXString createEmpty() {44  CXString Str;45  Str.data = "";46  Str.private_flags = CXS_Unmanaged;47  return Str;48}49 50CXString createNull() {51  CXString Str;52  Str.data = nullptr;53  Str.private_flags = CXS_Unmanaged;54  return Str;55}56 57CXString createRef(const char *String) {58  if (String && String[0] == '\0')59    return createEmpty();60 61  CXString Str;62  Str.data = String;63  Str.private_flags = CXS_Unmanaged;64  return Str;65}66 67CXString createDup(const char *String) {68  if (!String)69    return createNull();70 71  if (String[0] == '\0')72    return createEmpty();73 74  CXString Str;75  Str.data = strdup(String);76  Str.private_flags = CXS_Malloc;77  return Str;78}79 80CXString createRef(StringRef String) {81  if (!String.data())82    return createNull();83 84  // If the string is empty, it might point to a position in another string85  // while having zero length. Make sure we don't create a reference to the86  // larger string.87  if (String.empty())88    return createEmpty();89 90  return createDup(String);91}92 93CXString createDup(StringRef String) {94  CXString Result;95  char *Spelling = static_cast<char *>(llvm::safe_malloc(String.size() + 1));96  memmove(Spelling, String.data(), String.size());97  Spelling[String.size()] = 0;98  Result.data = Spelling;99  Result.private_flags = (unsigned) CXS_Malloc;100  return Result;101}102 103CXString createCXString(CXStringBuf *buf) {104  CXString Str;105  Str.data = buf;106  Str.private_flags = (unsigned) CXS_StringBuf;107  return Str;108}109 110CXStringSet *createSet(const std::vector<std::string> &Strings) {111  CXStringSet *Set = new CXStringSet;112  Set->Count = Strings.size();113  Set->Strings = new CXString[Set->Count];114  for (unsigned SI = 0, SE = Set->Count; SI < SE; ++SI)115    Set->Strings[SI] = createDup(Strings[SI]);116  return Set;117}118 119 120//===----------------------------------------------------------------------===//121// String pools.122//===----------------------------------------------------------------------===//123 124CXStringPool::~CXStringPool() {125  for (std::vector<CXStringBuf *>::iterator I = Pool.begin(), E = Pool.end();126       I != E; ++I) {127    delete *I;128  }129}130 131CXStringBuf *CXStringPool::getCXStringBuf(CXTranslationUnit TU) {132  if (Pool.empty())133    return new CXStringBuf(TU);134 135  CXStringBuf *Buf = Pool.back();136  Buf->Data.clear();137  Pool.pop_back();138  return Buf;139}140 141CXStringBuf *getCXStringBuf(CXTranslationUnit TU) {142  return TU->StringPool->getCXStringBuf(TU);143}144 145void CXStringBuf::dispose() {146  TU->StringPool->Pool.push_back(this);147}148 149bool isManagedByPool(CXString str) {150  return ((CXStringFlag) str.private_flags) == CXS_StringBuf;151}152 153} // end namespace cxstring154} // end namespace clang155 156//===----------------------------------------------------------------------===//157// libClang public APIs.158//===----------------------------------------------------------------------===//159 160const char *clang_getCString(CXString string) {161  if (string.private_flags == (unsigned) CXS_StringBuf) {162    return static_cast<const cxstring::CXStringBuf *>(string.data)->Data.data();163  }164  return static_cast<const char *>(string.data);165}166 167void clang_disposeString(CXString string) {168  switch ((CXStringFlag) string.private_flags) {169    case CXS_Unmanaged:170      break;171    case CXS_Malloc:172      if (string.data)173        free(const_cast<void *>(string.data));174      break;175    case CXS_StringBuf:176      static_cast<cxstring::CXStringBuf *>(177          const_cast<void *>(string.data))->dispose();178      break;179  }180}181 182void clang_disposeStringSet(CXStringSet *set) {183  for (unsigned SI = 0, SE = set->Count; SI < SE; ++SI)184    clang_disposeString(set->Strings[SI]);185  delete[] set->Strings;186  delete set;187}188 189