1ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===- CXString.cpp - Routines for manipulating CXStrings -----------------===// 2ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// 3ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// The LLVM Compiler Infrastructure 4ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// 5ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// This file is distributed under the University of Illinois Open Source 6ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// License. See LICENSE.TXT for details. 7ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// 8ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===----------------------------------------------------------------------===// 9ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// 10ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// This file defines routines for manipulating CXStrings. It should be the 11ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// only file that has internal knowledge of the encoding of the data in 12ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// CXStrings. 13ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// 14ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===----------------------------------------------------------------------===// 15ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 16ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "CXString.h" 170a90d32523bfe5fa63e11b648686c9699f786d15Ted Kremenek#include "CXTranslationUnit.h" 18ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "clang/Frontend/ASTUnit.h" 19ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "clang-c/Index.h" 20a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek#include "llvm/ADT/SmallString.h" 21ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek#include "llvm/Support/ErrorHandling.h" 22ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 23ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenekusing namespace clang; 24ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenekusing namespace clang::cxstring; 25ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 26a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekenum CXStringFlag { CXS_Unmanaged, CXS_Malloc, CXS_StringBuf }; 27a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 28a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek//===----------------------------------------------------------------------===// 29a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek// Basic generation of CXStrings. 30a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek//===----------------------------------------------------------------------===// 31ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 32ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed KremenekCXString cxstring::createCXString(const char *String, bool DupString){ 33ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek CXString Str; 34ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek if (DupString) { 35a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Str.data = strdup(String); 36ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek Str.private_flags = (unsigned) CXS_Malloc; 37ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek } else { 38a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Str.data = (void*)String; 39ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek Str.private_flags = (unsigned) CXS_Unmanaged; 40ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek } 41ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek return Str; 42ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek} 43ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 445f9e272e632e951b1efe824cd16acb4d96077930Chris LattnerCXString cxstring::createCXString(StringRef String, bool DupString) { 45ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek CXString Result; 46ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek if (DupString || (!String.empty() && String.data()[String.size()] != 0)) { 47ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek char *Spelling = (char *)malloc(String.size() + 1); 48ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek memmove(Spelling, String.data(), String.size()); 49ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek Spelling[String.size()] = 0; 50a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Result.data = Spelling; 51ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek Result.private_flags = (unsigned) CXS_Malloc; 52ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek } else { 53a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Result.data = (void*) String.data(); 54ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek Result.private_flags = (unsigned) CXS_Unmanaged; 55ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek } 56ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek return Result; 57ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek} 58ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 59a60ed47da13393796d8552b9fdca12abbb3eea42Ted KremenekCXString cxstring::createCXString(CXStringBuf *buf) { 60a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXString Str; 61a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Str.data = buf; 62a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek Str.private_flags = (unsigned) CXS_StringBuf; 63a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return Str; 64a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 65a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 66a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 67a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek//===----------------------------------------------------------------------===// 68a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek// String pools. 69a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek//===----------------------------------------------------------------------===// 70a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 71a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 72a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenektypedef std::vector<CXStringBuf *> CXStringPool; 73a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 74a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekvoid *cxstring::createCXStringPool() { 75a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return new CXStringPool(); 76a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 77a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 78a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekvoid cxstring::disposeCXStringPool(void *p) { 79a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXStringPool *pool = static_cast<CXStringPool*>(p); 80a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (pool) { 81a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek for (CXStringPool::iterator I = pool->begin(), E = pool->end(); 82a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek I != E; ++I) { 83a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek delete *I; 84a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek } 85a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek delete pool; 86a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek } 87a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 88a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 89a60ed47da13393796d8552b9fdca12abbb3eea42Ted KremenekCXStringBuf *cxstring::getCXStringBuf(CXTranslationUnit TU) { 90a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXStringPool *pool = static_cast<CXStringPool*>(TU->StringPool); 91a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (pool->empty()) 92a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return new CXStringBuf(TU); 93a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek CXStringBuf *buf = pool->back(); 94a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek buf->Data.clear(); 95a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek pool->pop_back(); 96a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return buf; 97a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 98a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 99a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenekvoid cxstring::disposeCXStringBuf(CXStringBuf *buf) { 100a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (buf) 101a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek static_cast<CXStringPool*>(buf->TU->StringPool)->push_back(buf); 102a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek} 103a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek 104baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenekbool cxstring::isManagedByPool(CXString str) { 105baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek return ((CXStringFlag) str.private_flags) == CXS_StringBuf; 106baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek} 107baf82b0fdf5c23dff80660add40bb92bd850bba0Ted Kremenek 108ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===----------------------------------------------------------------------===// 109ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek// libClang public APIs. 110ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek//===----------------------------------------------------------------------===// 111ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 112ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenekextern "C" { 113ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenekconst char *clang_getCString(CXString string) { 114a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (string.private_flags == (unsigned) CXS_StringBuf) { 115a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return ((CXStringBuf*)string.data)->Data.data(); 116a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek } 117a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek return (const char*) string.data; 118ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek} 119ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 120ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenekvoid clang_disposeString(CXString string) { 121a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek switch ((CXStringFlag) string.private_flags) { 122a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek case CXS_Unmanaged: 123a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek break; 124a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek case CXS_Malloc: 125a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek if (string.data) 126a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek free((void*)string.data); 127a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek break; 128a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek case CXS_StringBuf: 129a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek disposeCXStringBuf((CXStringBuf *) string.data); 130a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek break; 131a60ed47da13393796d8552b9fdca12abbb3eea42Ted Kremenek } 132ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek} 133ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek} // end: extern "C" 134ea834df7cd07d67a77e7dd6e48e8db27464be2fdTed Kremenek 135