mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[sourcekit] Merge SourceKit into the Swift repo.
The code goes into its own sub-tree under 'tools' but tests go under 'test', so that running 'check-swift' will also run all the SourceKit tests. SourceKit is disabled on non-darwin platforms.
This commit is contained in:
106
tools/SourceKit/lib/Support/UIDRegistry.cpp
Normal file
106
tools/SourceKit/lib/Support/UIDRegistry.cpp
Normal file
@@ -0,0 +1,106 @@
|
||||
#include "SourceKit/Support/UIdent.h"
|
||||
#include "SourceKit/Support/Concurrency.h"
|
||||
#include "llvm/ADT/StringMap.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);
|
||||
};
|
||||
}
|
||||
|
||||
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.find(' ') == StringRef::npos);
|
||||
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();
|
||||
}
|
||||
Reference in New Issue
Block a user