mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
120 lines
2.9 KiB
C++
120 lines
2.9 KiB
C++
//===--- UIDRegistry.cpp --------------------------------------------------===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "SourceKit/Support/Concurrency.h"
|
|
#include "SourceKit/Support/UIdent.h"
|
|
#include "llvm/ADT/StringMap.h"
|
|
#include "llvm/Support/Allocator.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include <mutex>
|
|
#include <vector>
|
|
|
|
using namespace SourceKit;
|
|
using llvm::StringRef;
|
|
|
|
namespace {
|
|
class UIDRegistryImpl {
|
|
typedef llvm::StringMap<void *, llvm::BumpPtrAllocator> HashTableTy;
|
|
typedef llvm::StringMapEntry<void *> EntryTy;
|
|
HashTableTy HashTable;
|
|
WorkQueue Queue{ WorkQueue::Dequeuing::Concurrent, "UIDRegistryImpl" };
|
|
|
|
public:
|
|
|
|
void *get(StringRef Str);
|
|
static StringRef getName(void *Ptr);
|
|
static void setTag(void *Ptr, void *Tag);
|
|
static void *getTag(void *Ptr);
|
|
};
|
|
} // end anonymous namespace
|
|
|
|
static UIDRegistryImpl *getGlobalRegistry() {
|
|
static UIDRegistryImpl *GlobalRegistry = 0;
|
|
if (!GlobalRegistry) {
|
|
static std::once_flag flag;
|
|
std::call_once(flag, [](){ GlobalRegistry = new UIDRegistryImpl(); });
|
|
}
|
|
return GlobalRegistry;
|
|
}
|
|
|
|
UIdent::UIdent(llvm::StringRef Str) {
|
|
Ptr = getGlobalRegistry()->get(Str);
|
|
}
|
|
|
|
llvm::StringRef UIdent::getName() const {
|
|
if (isInvalid())
|
|
return StringRef();
|
|
return UIDRegistryImpl::getName(Ptr);
|
|
}
|
|
|
|
const char *UIdent::c_str() const {
|
|
if (isInvalid())
|
|
return "";
|
|
return getName().begin();
|
|
}
|
|
|
|
void UIdent::setTag(void *Tag) {
|
|
assert(isValid());
|
|
UIDRegistryImpl::setTag(Ptr, Tag);
|
|
}
|
|
|
|
void *UIdent::getTag() const {
|
|
assert(isValid());
|
|
return UIDRegistryImpl::getTag(Ptr);
|
|
}
|
|
|
|
void UIdent::dump() const {
|
|
print(llvm::errs());
|
|
}
|
|
|
|
void UIdent::print(llvm::raw_ostream &OS) const {
|
|
if (isInvalid())
|
|
OS << "<<INVALID>>";
|
|
else
|
|
OS << getName();
|
|
}
|
|
|
|
void *UIDRegistryImpl::get(StringRef Str) {
|
|
assert(!Str.empty());
|
|
assert(!Str.contains(' '));
|
|
EntryTy *Ptr = 0;
|
|
Queue.dispatchSync([&]{
|
|
HashTableTy::iterator It = HashTable.find(Str);
|
|
if (It != HashTable.end())
|
|
Ptr = &(*It);
|
|
});
|
|
|
|
if (Ptr == 0) {
|
|
Queue.dispatchBarrierSync([&]{
|
|
EntryTy &Entry = *HashTable.insert(std::make_pair(Str, nullptr)).first;
|
|
Ptr = &Entry;
|
|
});
|
|
}
|
|
|
|
return Ptr;
|
|
}
|
|
|
|
StringRef UIDRegistryImpl::getName(void *Ptr) {
|
|
EntryTy *Entry = static_cast<EntryTy*>(Ptr);
|
|
return Entry->getKey();
|
|
}
|
|
|
|
void UIDRegistryImpl::setTag(void *Ptr, void *Tag) {
|
|
EntryTy *Entry = static_cast<EntryTy*>(Ptr);
|
|
Entry->setValue(Tag);
|
|
}
|
|
|
|
void *UIDRegistryImpl::getTag(void *Ptr) {
|
|
EntryTy *Entry = static_cast<EntryTy*>(Ptr);
|
|
return Entry->getValue();
|
|
}
|