--- /dev/null
+//===--- GlobalSelector.h - Cross-translation-unit "token" for selectors --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// GlobalSelector is a ASTContext-independent way to refer to selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_INDEX_GLOBALSELECTOR_H
+#define LLVM_CLANG_INDEX_GLOBALSELECTOR_H
+
+#include "llvm/ADT/DenseMap.h"
+#include <string>
+
+namespace clang {
+ class ASTContext;
+ class Selector;
+
+namespace idx {
+ class Program;
+
+/// \brief A ASTContext-independent way to refer to selectors.
+class GlobalSelector {
+ void *Val;
+
+ explicit GlobalSelector(void *val) : Val(val) { }
+
+public:
+ GlobalSelector() : Val(0) { }
+
+ /// \brief Get the ASTContext-specific selector.
+ Selector getSelector(ASTContext &AST) const;
+
+ bool isValid() const { return Val != 0; }
+ bool isInvalid() const { return !isValid(); }
+
+ /// \brief Get a printable name for debugging purpose.
+ std::string getPrintableName() const;
+
+ /// \brief Get a GlobalSelector for the ASTContext-specific selector.
+ static GlobalSelector get(Selector Sel, Program &Prog);
+
+ void *getAsOpaquePtr() const { return Val; }
+
+ friend bool operator==(const GlobalSelector &LHS, const GlobalSelector &RHS) {
+ return LHS.getAsOpaquePtr() == RHS.getAsOpaquePtr();
+ }
+
+ // For use in a std::map.
+ friend bool operator< (const GlobalSelector &LHS, const GlobalSelector &RHS) {
+ return LHS.getAsOpaquePtr() < RHS.getAsOpaquePtr();
+ }
+
+ // For use in DenseMap/DenseSet.
+ static GlobalSelector getEmptyMarker() { return GlobalSelector((void*)-1); }
+ static GlobalSelector getTombstoneMarker() {
+ return GlobalSelector((void*)-2);
+ }
+};
+
+} // namespace idx
+
+} // namespace clang
+
+namespace llvm {
+/// Define DenseMapInfo so that GlobalSelectors can be used as keys in DenseMap
+/// and DenseSets.
+template<>
+struct DenseMapInfo<clang::idx::GlobalSelector> {
+ static inline clang::idx::GlobalSelector getEmptyKey() {
+ return clang::idx::GlobalSelector::getEmptyMarker();
+ }
+
+ static inline clang::idx::GlobalSelector getTombstoneKey() {
+ return clang::idx::GlobalSelector::getTombstoneMarker();
+ }
+
+ static unsigned getHashValue(clang::idx::GlobalSelector);
+
+ static inline bool
+ isEqual(clang::idx::GlobalSelector LHS, clang::idx::GlobalSelector RHS) {
+ return LHS == RHS;
+ }
+
+ static inline bool isPod() { return true; }
+};
+
+} // end namespace llvm
+
+#endif
Program(const Program&); // do not implement
Program &operator=(const Program &); // do not implement
friend class Entity;
+ friend class GlobalSelector;
public:
Program();
--- /dev/null
+//===-- GlobalSelector.cpp - Cross-translation-unit "token" for selectors -===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// GlobalSelector is a ASTContext-independent way to refer to selectors.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Index/GlobalSelector.h"
+#include "ProgramImpl.h"
+#include "clang/Index/Program.h"
+#include "clang/AST/ASTContext.h"
+using namespace clang;
+using namespace idx;
+
+/// \brief Get the ASTContext-specific selector.
+Selector GlobalSelector::getSelector(ASTContext &AST) const {
+ if (isInvalid())
+ return Selector();
+
+ Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val));
+
+ llvm::SmallVector<IdentifierInfo *, 8> Ids;
+ for (unsigned i = 0, e = GlobSel.isUnarySelector() ? 1 : GlobSel.getNumArgs();
+ i != e; ++i) {
+ IdentifierInfo *GlobII = GlobSel.getIdentifierInfoForSlot(i);
+ IdentifierInfo *II = &AST.Idents.get(GlobII->getName(),
+ GlobII->getName() + GlobII->getLength());
+ Ids.push_back(II);
+ }
+
+ return AST.Selectors.getSelector(Ids.size(), Ids.data());
+}
+
+/// \brief Get a printable name for debugging purpose.
+std::string GlobalSelector::getPrintableName() const {
+ if (isInvalid())
+ return "<< Invalid >>";
+
+ Selector GlobSel = Selector(reinterpret_cast<uintptr_t>(Val));
+ return GlobSel.getAsString();
+}
+
+/// \brief Get a GlobalSelector for the ASTContext-specific selector.
+GlobalSelector GlobalSelector::get(Selector Sel, Program &Prog) {
+ if (Sel.isNull())
+ return GlobalSelector();
+
+ ProgramImpl &ProgImpl = *static_cast<ProgramImpl*>(Prog.Impl);
+
+ llvm::SmallVector<IdentifierInfo *, 8> Ids;
+ for (unsigned i = 0, e = Sel.isUnarySelector() ? 1 : Sel.getNumArgs();
+ i != e; ++i) {
+ IdentifierInfo *II = Sel.getIdentifierInfoForSlot(i);
+ IdentifierInfo *GlobII = &ProgImpl.getIdents().get(II->getName(),
+ II->getName() + II->getLength());
+ Ids.push_back(GlobII);
+ }
+
+ Selector GlobSel = ProgImpl.getSelectors().getSelector(Ids.size(),Ids.data());
+ return GlobalSelector(GlobSel.getAsOpaquePtr());
+}
+
+unsigned
+llvm::DenseMapInfo<GlobalSelector>::getHashValue(GlobalSelector Sel) {
+ return DenseMapInfo<void*>::getHashValue(Sel.getAsOpaquePtr());
+}
llvm::BumpPtrAllocator BumpAlloc;
IdentifierTable Identifiers;
+ SelectorTable Selectors;
ProgramImpl(const ProgramImpl&); // do not implement
ProgramImpl &operator=(const ProgramImpl &); // do not implement
EntitySetTy &getEntities() { return Entities; }
IdentifierTable &getIdents() { return Identifiers; }
+ SelectorTable &getSelectors() { return Selectors; }
void *Allocate(unsigned Size, unsigned Align = 8) {
return BumpAlloc.Allocate(Size, Align);