//===- IdentifierTable.cpp - Hash table for identifier lookup -------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the IdentifierInfo, IdentifierVisitor, and
// IdentifierTable interfaces.
//
//===----------------------------------------------------------------------===//

#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/CharInfo.h"
#include "clang/Basic/DiagnosticLex.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Basic/TargetBuiltins.h"
#include "clang/Basic/TokenKinds.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdio>
#include <cstring>
#include <string>

using namespace clang;

// A check to make sure the ObjCOrBuiltinID has sufficient room to store the
// largest possible target/aux-target combination. If we exceed this, we likely
// need to just change the ObjCOrBuiltinIDBits value in IdentifierTable.h.
static_assert(2 * LargestBuiltinID < (2 << (InterestingIdentifierBits - 1)),
              "Insufficient ObjCOrBuiltinID Bits");

//===----------------------------------------------------------------------===//
// IdentifierTable Implementation
//===----------------------------------------------------------------------===//

IdentifierIterator::~IdentifierIterator() = default;

IdentifierInfoLookup::~IdentifierInfoLookup() = default;

namespace {

/// A simple identifier lookup iterator that represents an
/// empty sequence of identifiers.
class EmptyLookupIterator : public IdentifierIterator {
public:
  StringRef Next() override { return StringRef(); }
};

} // namespace

IdentifierIterator *IdentifierInfoLookup::getIdentifiers() {
  return new EmptyLookupIterator();
}

IdentifierTable::IdentifierTable(IdentifierInfoLookup *ExternalLookup)
    : HashTable(8192), // Start with space for 8K identifiers.
      ExternalLookup(ExternalLookup) {}

IdentifierTable::IdentifierTable(const LangOptions &LangOpts,
                                 IdentifierInfoLookup *ExternalLookup)
    : IdentifierTable(ExternalLookup) {
  // Populate the identifier table with info about keywords for the current
  // language.
  AddKeywords(LangOpts);
}

//===----------------------------------------------------------------------===//
// Language Keyword Implementation
//===----------------------------------------------------------------------===//

// This works on a single TokenKey flag and checks the LangOpts to get the
// KeywordStatus based exclusively on this flag, so that it can be merged in
// getKeywordStatus. Most should be enabled/disabled, but some might imply
// 'future' versions, or extensions. Returns 'unknown' unless this is KNOWN to
// be disabled, and the calling function makes it 'disabled' if no other flag
// changes it. This is necessary for the KEYNOCXX and KEYNOOPENCL flags.
static KeywordStatus getKeywordStatusHelper(const LangOptions &LangOpts,
                                            TokenKey Flag) {
  // Flag is a single bit version of TokenKey (that is, not
  // KEYALL/KEYALLCXX/etc), so we can check with == throughout this function.
  assert((Flag & ~(Flag - 1)) == Flag && "Multiple bits set?");

  switch (Flag) {
  case KEYC99:
    if (LangOpts.C99)
      return KS_Enabled;
    return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
  case KEYC23:
    if (LangOpts.C23)
      return KS_Enabled;
    return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
  case KEYCXX:
    return LangOpts.CPlusPlus ? KS_Enabled : KS_Unknown;
  case KEYCXX11:
    if (LangOpts.CPlusPlus11)
      return KS_Enabled;
    return LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
  case KEYCXX20:
    if (LangOpts.CPlusPlus20)
      return KS_Enabled;
    return LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
  case KEYGNU:
    return LangOpts.GNUKeywords ? KS_Extension : KS_Unknown;
  case KEYMS:
    return LangOpts.MicrosoftExt ? KS_Extension : KS_Unknown;
  case BOOLSUPPORT:
    if (LangOpts.Bool)      return KS_Enabled;
    return !LangOpts.CPlusPlus ? KS_Future : KS_Unknown;
  case KEYALTIVEC:
    return LangOpts.AltiVec ? KS_Enabled : KS_Unknown;
  case KEYBORLAND:
    return LangOpts.Borland ? KS_Extension : KS_Unknown;
  case KEYOPENCLC:
    return LangOpts.OpenCL && !LangOpts.OpenCLCPlusPlus ? KS_Enabled
                                                        : KS_Unknown;
  case WCHARSUPPORT:
    return LangOpts.WChar ? KS_Enabled : KS_Unknown;
  case HALFSUPPORT:
    return LangOpts.Half ? KS_Enabled : KS_Unknown;
  case CHAR8SUPPORT:
    if (LangOpts.Char8) return KS_Enabled;
    if (LangOpts.CPlusPlus20) return KS_Unknown;
    if (LangOpts.CPlusPlus) return KS_Future;
    return KS_Unknown;
  case KEYOBJC:
    // We treat bridge casts as objective-C keywords so we can warn on them
    // in non-arc mode.
    return LangOpts.ObjC ? KS_Enabled : KS_Unknown;
  case KEYZVECTOR:
    return LangOpts.ZVector ? KS_Enabled : KS_Unknown;
  case KEYCOROUTINES:
    return LangOpts.Coroutines ? KS_Enabled : KS_Unknown;
  case KEYMODULES:
    return KS_Unknown;
  case KEYOPENCLCXX:
    return LangOpts.OpenCLCPlusPlus ? KS_Enabled : KS_Unknown;
  case KEYMSCOMPAT:
    return LangOpts.MSVCCompat ? KS_Enabled : KS_Unknown;
  case KEYSYCL:
    return LangOpts.isSYCL() ? KS_Enabled : KS_Unknown;
  case KEYCUDA:
    return LangOpts.CUDA ? KS_Enabled : KS_Unknown;
  case KEYZOS:
    return LangOpts.ZOSExt ? KS_Enabled : KS_Unknown;
  case KEYHLSL:
    return LangOpts.HLSL ? KS_Enabled : KS_Unknown;
  case KEYNOCXX:
    // This is enabled in all non-C++ modes, but might be enabled for other
    // reasons as well.
    return LangOpts.CPlusPlus ? KS_Unknown : KS_Enabled;
  case KEYNOOPENCL:
  case KEYNOMS18:
  case KEYNOHLSL:
    // The disable behavior for this is handled in getKeywordStatus.
    return KS_Unknown;
  case KEYFIXEDPOINT:
    return LangOpts.FixedPoint ? KS_Enabled : KS_Disabled;
  case KEYDEFERTS:
    return LangOpts.DeferTS ? KS_Enabled : KS_Disabled;
  default:
    llvm_unreachable("Unknown KeywordStatus flag");
  }
}

KeywordStatus clang::getKeywordStatus(const LangOptions &LangOpts,
                                      unsigned Flags) {
  // KEYALL means always enabled, so special case this one.
  if (Flags == KEYALL) return KS_Enabled;
  // These are tests that need to 'always win', as they are special in that they
  // disable based on certain conditions.
  if (LangOpts.OpenCL && (Flags & KEYNOOPENCL)) return KS_Disabled;
  if (LangOpts.HLSL && (Flags & KEYNOHLSL))
    return KS_Disabled;
  if (LangOpts.MSVCCompat && (Flags & KEYNOMS18) &&
      !LangOpts.isCompatibleWithMSVC(LangOptions::MSVC2015))
    return KS_Disabled;
  KeywordStatus CurStatus = KS_Unknown;

  while (Flags != 0) {
    unsigned CurFlag = Flags & ~(Flags - 1);
    Flags = Flags & ~CurFlag;
    CurStatus = std::max(
        CurStatus,
        getKeywordStatusHelper(LangOpts, static_cast<TokenKey>(CurFlag)));
  }

  if (CurStatus == KS_Unknown)
    return KS_Disabled;
  return CurStatus;
}

static bool IsKeywordInCpp(unsigned Flags) {
  return (Flags & (KEYCXX | KEYCXX11 | KEYCXX20 | BOOLSUPPORT | WCHARSUPPORT |
                   CHAR8SUPPORT)) != 0;
}

static void MarkIdentifierAsKeywordInCpp(IdentifierTable &Table,
                                         StringRef Name) {
  IdentifierInfo &II = Table.get(Name, tok::identifier);
  II.setIsKeywordInCPlusPlus();
  II.setHandleIdentifierCase();
}

/// AddKeyword - This method is used to associate a token ID with specific
/// identifiers because they are language keywords.  This causes the lexer to
/// automatically map matching identifiers to specialized token codes.
static void AddKeyword(StringRef Keyword,
                       tok::TokenKind TokenCode, unsigned Flags,
                       const LangOptions &LangOpts, IdentifierTable &Table) {
  KeywordStatus AddResult = getKeywordStatus(LangOpts, Flags);

  // Don't add this keyword if disabled in this language and isn't otherwise
  // special.
  if (AddResult == KS_Disabled) {
    // We do not consider any identifiers to be C++ keywords when in
    // Objective-C because @ effectively introduces a custom grammar where C++
    // keywords can be used (and similar for selectors). We could enable this
    // for Objective-C, but it would require more logic to ensure we do not
    // issue compatibility diagnostics in these cases.
    if (!LangOpts.ObjC && IsKeywordInCpp(Flags))
      MarkIdentifierAsKeywordInCpp(Table, Keyword);
    return;
  }

  IdentifierInfo &Info =
      Table.get(Keyword, AddResult == KS_Future ? tok::identifier : TokenCode);
  Info.setIsExtensionToken(AddResult == KS_Extension);
  Info.setIsFutureCompatKeyword(AddResult == KS_Future);
}

/// AddCXXOperatorKeyword - Register a C++ operator keyword alternative
/// representations.
static void AddCXXOperatorKeyword(StringRef Keyword,
                                  tok::TokenKind TokenCode,
                                  IdentifierTable &Table) {
  IdentifierInfo &Info = Table.get(Keyword, TokenCode);
  Info.setIsCPlusPlusOperatorKeyword();
}

/// AddObjCKeyword - Register an Objective-C \@keyword like "class" "selector"
/// or "property".
static void AddObjCKeyword(StringRef Name,
                           tok::ObjCKeywordKind ObjCID,
                           IdentifierTable &Table) {
  Table.get(Name).setObjCKeywordID(ObjCID);
}

static void AddNotableIdentifier(StringRef Name,
                                 tok::NotableIdentifierKind BTID,
                                 IdentifierTable &Table) {
  // Don't add 'not_notable' identifier.
  if (BTID != tok::not_notable) {
    IdentifierInfo &Info = Table.get(Name, tok::identifier);
    Info.setNotableIdentifierID(BTID);
  }
}

/// AddKeywords - Add all keywords to the symbol table.
///
void IdentifierTable::AddKeywords(const LangOptions &LangOpts) {
  // Add keywords and tokens for the current language.
#define KEYWORD(NAME, FLAGS) \
  AddKeyword(StringRef(#NAME), tok::kw_ ## NAME,  \
             FLAGS, LangOpts, *this);
#define ALIAS(NAME, TOK, FLAGS) \
  AddKeyword(StringRef(NAME), tok::kw_ ## TOK,  \
             FLAGS, LangOpts, *this);
#define CXX_KEYWORD_OPERATOR(NAME, ALIAS)                                      \
  if (LangOpts.CXXOperatorNames)                                               \
    AddCXXOperatorKeyword(StringRef(#NAME), tok::ALIAS, *this);                \
  else                                                                         \
    MarkIdentifierAsKeywordInCpp(*this, StringRef(#NAME));
#define OBJC_AT_KEYWORD(NAME)  \
  if (LangOpts.ObjC)           \
    AddObjCKeyword(StringRef(#NAME), tok::objc_##NAME, *this);
#define NOTABLE_IDENTIFIER(NAME)                                               \
  AddNotableIdentifier(StringRef(#NAME), tok::NAME, *this);

#define TESTING_KEYWORD(NAME, FLAGS)
#include "clang/Basic/TokenKinds.def"

  if (LangOpts.ParseUnknownAnytype)
    AddKeyword("__unknown_anytype", tok::kw___unknown_anytype, KEYALL,
               LangOpts, *this);

  if (LangOpts.DeclSpecKeyword)
    AddKeyword("__declspec", tok::kw___declspec, KEYALL, LangOpts, *this);

  if (LangOpts.IEEE128)
    AddKeyword("__ieee128", tok::kw___float128, KEYALL, LangOpts, *this);

  // Add the 'import' and 'module' contextual keywords.
  get("import").setKeywordImport(true);
  get("module").setModuleKeyword(true);
  get("__preprocessed_import").setKeywordImport(true);
  get("__preprocessed_module").setModuleKeyword(true);
}

/// Checks if the specified token kind represents a keyword in the
/// specified language.
/// \returns Status of the keyword in the language.
static KeywordStatus getTokenKwStatus(const LangOptions &LangOpts,
                                      tok::TokenKind K) {
  switch (K) {
#define KEYWORD(NAME, FLAGS) \
  case tok::kw_##NAME: return getKeywordStatus(LangOpts, FLAGS);
#include "clang/Basic/TokenKinds.def"
  default: return KS_Disabled;
  }
}

/// Returns true if the identifier represents a keyword in the
/// specified language.
bool IdentifierInfo::isKeyword(const LangOptions &LangOpts) const {
  switch (getTokenKwStatus(LangOpts, getTokenID())) {
  case KS_Enabled:
  case KS_Extension:
    return true;
  default:
    return false;
  }
}

/// Returns true if the identifier represents a C++ keyword in the
/// specified language.
bool IdentifierInfo::isCPlusPlusKeyword(const LangOptions &LangOpts) const {
  if (!LangOpts.CPlusPlus || !isKeyword(LangOpts))
    return false;
  // This is a C++ keyword if this identifier is not a keyword when checked
  // using LangOptions without C++ support.
  LangOptions LangOptsNoCPP = LangOpts;
  LangOptsNoCPP.CPlusPlus = false;
  LangOptsNoCPP.CPlusPlus11 = false;
  LangOptsNoCPP.CPlusPlus20 = false;
  return !isKeyword(LangOptsNoCPP);
}

ReservedIdentifierStatus
IdentifierInfo::isReserved(const LangOptions &LangOpts) const {
  StringRef Name = getName();

  // '_' is a reserved identifier, but its use is so common (e.g. to store
  // ignored values) that we don't warn on it.
  if (Name.size() <= 1)
    return ReservedIdentifierStatus::NotReserved;

  // [lex.name] p3
  if (Name[0] == '_') {

    // Each name that begins with an underscore followed by an uppercase letter
    // or another underscore is reserved.
    if (Name[1] == '_')
      return ReservedIdentifierStatus::StartsWithDoubleUnderscore;

    if ('A' <= Name[1] && Name[1] <= 'Z')
      return ReservedIdentifierStatus::
          StartsWithUnderscoreFollowedByCapitalLetter;

    // This is a bit misleading: it actually means it's only reserved if we're
    // at global scope because it starts with an underscore.
    return ReservedIdentifierStatus::StartsWithUnderscoreAtGlobalScope;
  }

  // Each name that contains a double underscore (__) is reserved.
  if (LangOpts.CPlusPlus && Name.contains("__"))
    return ReservedIdentifierStatus::ContainsDoubleUnderscore;

  return ReservedIdentifierStatus::NotReserved;
}

ReservedLiteralSuffixIdStatus
IdentifierInfo::isReservedLiteralSuffixId() const {
  StringRef Name = getName();

  // Note: the diag::warn_deprecated_literal_operator_id diagnostic depends on
  // this being the first check we do, so if this order changes, we have to fix
  // that as well.
  if (Name[0] != '_')
    return ReservedLiteralSuffixIdStatus::NotStartsWithUnderscore;

  if (Name.contains("__"))
    return ReservedLiteralSuffixIdStatus::ContainsDoubleUnderscore;

  return ReservedLiteralSuffixIdStatus::NotReserved;
}

StringRef IdentifierInfo::deuglifiedName() const {
  StringRef Name = getName();
  if (Name.size() >= 2 && Name.front() == '_' &&
      (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
    return Name.ltrim('_');
  return Name;
}

tok::PPKeywordKind IdentifierInfo::getPPKeywordID() const {
  // We use a perfect hash function here involving the length of the keyword,
  // the first and third character.  For preprocessor ID's there are no
  // collisions (if there were, the switch below would complain about duplicate
  // case values).  Note that this depends on 'if' being null terminated.

#define HASH(LEN, FIRST, THIRD)                                                \
  (LEN << 6) + (((FIRST - 'a') - (THIRD - 'a')) & 63)
#define CASE(LEN, FIRST, THIRD, NAME) \
  case HASH(LEN, FIRST, THIRD): \
    return memcmp(Name, #NAME, LEN) ? tok::pp_not_keyword : tok::pp_ ## NAME

  unsigned Len = getLength();
  if (Len < 2) return tok::pp_not_keyword;
  const char *Name = getNameStart();

  if (Name[0] == '_' && isImportKeyword())
    return tok::pp___preprocessed_import;
  if (Name[0] == '_' && isModuleKeyword())
    return tok::pp___preprocessed_module;

  // clang-format off
  switch (HASH(Len, Name[0], Name[2])) {
  default: return tok::pp_not_keyword;
  CASE( 2, 'i', '\0', if);
  CASE( 4, 'e', 'i', elif);
  CASE( 4, 'e', 's', else);
  CASE( 4, 'l', 'n', line);
  CASE( 4, 's', 'c', sccs);
  CASE( 5, 'e', 'b', embed);
  CASE( 5, 'e', 'd', endif);
  CASE( 5, 'e', 'r', error);
  CASE( 5, 'i', 'e', ident);
  CASE( 5, 'i', 'd', ifdef);
  CASE( 5, 'u', 'd', undef);

  CASE( 6, 'a', 's', assert);
  CASE( 6, 'd', 'f', define);
  CASE( 6, 'i', 'n', ifndef);
  CASE( 6, 'i', 'p', import);
  CASE( 6, 'm', 'd', module);
  CASE( 6, 'p', 'a', pragma);

  CASE( 7, 'd', 'f', defined);
  CASE( 7, 'e', 'i', elifdef);
  CASE( 7, 'i', 'c', include);
  CASE( 7, 'w', 'r', warning);

  CASE( 8, 'e', 'i', elifndef);
  CASE( 8, 'u', 'a', unassert);
  CASE(12, 'i', 'c', include_next);

  CASE(14, '_', 'p', __public_macro);

  CASE(15, '_', 'p', __private_macro);

  CASE(16, '_', 'i', __include_macros);
#undef CASE
#undef HASH
  }
  // clang-format on
}

//===----------------------------------------------------------------------===//
// Stats Implementation
//===----------------------------------------------------------------------===//

/// PrintStats - Print statistics about how well the identifier table is doing
/// at hashing identifiers.
void IdentifierTable::PrintStats() const {
  unsigned NumBuckets = HashTable.getNumBuckets();
  unsigned NumIdentifiers = HashTable.getNumItems();
  unsigned NumEmptyBuckets = NumBuckets-NumIdentifiers;
  unsigned AverageIdentifierSize = 0;
  unsigned MaxIdentifierLength = 0;

  // TODO: Figure out maximum times an identifier had to probe for -stats.
  for (llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator>::const_iterator
       I = HashTable.begin(), E = HashTable.end(); I != E; ++I) {
    unsigned IdLen = I->getKeyLength();
    AverageIdentifierSize += IdLen;
    if (MaxIdentifierLength < IdLen)
      MaxIdentifierLength = IdLen;
  }

  fprintf(stderr, "\n*** Identifier Table Stats:\n");
  fprintf(stderr, "# Identifiers:   %d\n", NumIdentifiers);
  fprintf(stderr, "# Empty Buckets: %d\n", NumEmptyBuckets);
  fprintf(stderr, "Hash density (#identifiers per bucket): %f\n",
          NumIdentifiers/(double)NumBuckets);
  fprintf(stderr, "Ave identifier length: %f\n",
          (AverageIdentifierSize/(double)NumIdentifiers));
  fprintf(stderr, "Max identifier length: %d\n", MaxIdentifierLength);

  // Compute statistics about the memory allocated for identifiers.
  HashTable.getAllocator().PrintStats();
}

//===----------------------------------------------------------------------===//
// SelectorTable Implementation
//===----------------------------------------------------------------------===//

unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) {
  return DenseMapInfo<void*>::getHashValue(S.getAsOpaquePtr());
}

bool Selector::isKeywordSelector(ArrayRef<StringRef> Names) const {
  assert(!Names.empty() && "must have >= 1 selector slots");
  if (getNumArgs() != Names.size())
    return false;
  for (unsigned I = 0, E = Names.size(); I != E; ++I) {
    if (getNameForSlot(I) != Names[I])
      return false;
  }
  return true;
}

bool Selector::isUnarySelector(StringRef Name) const {
  return isUnarySelector() && getNameForSlot(0) == Name;
}

unsigned Selector::getNumArgs() const {
  unsigned IIF = getIdentifierInfoFlag();
  if (IIF <= ZeroArg)
    return 0;
  if (IIF == OneArg)
    return 1;
  // We point to a MultiKeywordSelector.
  MultiKeywordSelector *SI = getMultiKeywordSelector();
  return SI->getNumArgs();
}

const IdentifierInfo *
Selector::getIdentifierInfoForSlot(unsigned argIndex) const {
  if (getIdentifierInfoFlag() < MultiArg) {
    assert(argIndex == 0 && "illegal keyword index");
    return getAsIdentifierInfo();
  }

  // We point to a MultiKeywordSelector.
  MultiKeywordSelector *SI = getMultiKeywordSelector();
  return SI->getIdentifierInfoForSlot(argIndex);
}

StringRef Selector::getNameForSlot(unsigned int argIndex) const {
  const IdentifierInfo *II = getIdentifierInfoForSlot(argIndex);
  return II ? II->getName() : StringRef();
}

std::string MultiKeywordSelector::getName() const {
  SmallString<256> Str;
  llvm::raw_svector_ostream OS(Str);
  for (keyword_iterator I = keyword_begin(), E = keyword_end(); I != E; ++I) {
    if (*I)
      OS << (*I)->getName();
    OS << ':';
  }

  return std::string(OS.str());
}

std::string Selector::getAsString() const {
  if (isNull())
    return "<null selector>";

  if (getIdentifierInfoFlag() < MultiArg) {
    const IdentifierInfo *II = getAsIdentifierInfo();

    if (getNumArgs() == 0) {
      assert(II && "If the number of arguments is 0 then II is guaranteed to "
                   "not be null.");
      return std::string(II->getName());
    }

    if (!II)
      return ":";

    return II->getName().str() + ":";
  }

  // We have a multiple keyword selector.
  return getMultiKeywordSelector()->getName();
}

void Selector::print(llvm::raw_ostream &OS) const {
  OS << getAsString();
}

LLVM_DUMP_METHOD void Selector::dump() const { print(llvm::errs()); }

/// Interpreting the given string using the normal CamelCase
/// conventions, determine whether the given string starts with the
/// given "word", which is assumed to end in a lowercase letter.
static bool startsWithWord(StringRef name, StringRef word) {
  if (name.size() < word.size()) return false;
  return ((name.size() == word.size() || !isLowercase(name[word.size()])) &&
          name.starts_with(word));
}

ObjCMethodFamily Selector::getMethodFamilyImpl(Selector sel) {
  const IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
  if (!first) return OMF_None;

  StringRef name = first->getName();
  if (sel.isUnarySelector()) {
    if (name == "autorelease") return OMF_autorelease;
    if (name == "dealloc") return OMF_dealloc;
    if (name == "finalize") return OMF_finalize;
    if (name == "release") return OMF_release;
    if (name == "retain") return OMF_retain;
    if (name == "retainCount") return OMF_retainCount;
    if (name == "self") return OMF_self;
    if (name == "initialize") return OMF_initialize;
  }

  if (name == "performSelector" || name == "performSelectorInBackground" ||
      name == "performSelectorOnMainThread")
    return OMF_performSelector;

  // The other method families may begin with a prefix of underscores.
  name = name.ltrim('_');

  if (name.empty()) return OMF_None;
  switch (name.front()) {
  case 'a':
    if (startsWithWord(name, "alloc")) return OMF_alloc;
    break;
  case 'c':
    if (startsWithWord(name, "copy")) return OMF_copy;
    break;
  case 'i':
    if (startsWithWord(name, "init")) return OMF_init;
    break;
  case 'm':
    if (startsWithWord(name, "mutableCopy")) return OMF_mutableCopy;
    break;
  case 'n':
    if (startsWithWord(name, "new")) return OMF_new;
    break;
  default:
    break;
  }

  return OMF_None;
}

ObjCInstanceTypeFamily Selector::getInstTypeMethodFamily(Selector sel) {
  const IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
  if (!first) return OIT_None;

  StringRef name = first->getName();

  if (name.empty()) return OIT_None;
  switch (name.front()) {
    case 'a':
      if (startsWithWord(name, "array")) return OIT_Array;
      break;
    case 'd':
      if (startsWithWord(name, "default")) return OIT_ReturnsSelf;
      if (startsWithWord(name, "dictionary")) return OIT_Dictionary;
      break;
    case 's':
      if (startsWithWord(name, "shared")) return OIT_ReturnsSelf;
      if (startsWithWord(name, "standard")) return OIT_Singleton;
      break;
    case 'i':
      if (startsWithWord(name, "init")) return OIT_Init;
      break;
    default:
      break;
  }
  return OIT_None;
}

ObjCStringFormatFamily Selector::getStringFormatFamilyImpl(Selector sel) {
  const IdentifierInfo *first = sel.getIdentifierInfoForSlot(0);
  if (!first) return SFF_None;

  StringRef name = first->getName();

  switch (name.front()) {
    case 'a':
      if (name == "appendFormat") return SFF_NSString;
      break;

    case 'i':
      if (name == "initWithFormat") return SFF_NSString;
      break;

    case 'l':
      if (name == "localizedStringWithFormat") return SFF_NSString;
      break;

    case 's':
      if (name == "stringByAppendingFormat" ||
          name == "stringWithFormat") return SFF_NSString;
      break;
  }
  return SFF_None;
}

namespace {

struct SelectorTableImpl {
  llvm::FoldingSet<MultiKeywordSelector> Table;
  llvm::BumpPtrAllocator Allocator;
};

} // namespace

static SelectorTableImpl &getSelectorTableImpl(void *P) {
  return *static_cast<SelectorTableImpl*>(P);
}

SmallString<64>
SelectorTable::constructSetterName(StringRef Name) {
  SmallString<64> SetterName("set");
  SetterName += Name;
  SetterName[3] = toUppercase(SetterName[3]);
  return SetterName;
}

Selector
SelectorTable::constructSetterSelector(IdentifierTable &Idents,
                                       SelectorTable &SelTable,
                                       const IdentifierInfo *Name) {
  IdentifierInfo *SetterName =
    &Idents.get(constructSetterName(Name->getName()));
  return SelTable.getUnarySelector(SetterName);
}

std::string SelectorTable::getPropertyNameFromSetterSelector(Selector Sel) {
  StringRef Name = Sel.getNameForSlot(0);
  assert(Name.starts_with("set") && "invalid setter name");
  return (Twine(toLowercase(Name[3])) + Name.drop_front(4)).str();
}

size_t SelectorTable::getTotalMemory() const {
  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);
  return SelTabImpl.Allocator.getTotalMemory();
}

Selector SelectorTable::getSelector(unsigned nKeys,
                                    const IdentifierInfo **IIV) {
  if (nKeys < 2)
    return Selector(IIV[0], nKeys);

  SelectorTableImpl &SelTabImpl = getSelectorTableImpl(Impl);

  // Unique selector, to guarantee there is one per name.
  llvm::FoldingSetNodeID ID;
  MultiKeywordSelector::Profile(ID, IIV, nKeys);

  void *InsertPos = nullptr;
  if (MultiKeywordSelector *SI =
        SelTabImpl.Table.FindNodeOrInsertPos(ID, InsertPos))
    return Selector(SI);

  // MultiKeywordSelector objects are not allocated with new because they have a
  // variable size array (for parameter types) at the end of them.
  unsigned Size = sizeof(MultiKeywordSelector) + nKeys*sizeof(IdentifierInfo *);
  MultiKeywordSelector *SI =
      (MultiKeywordSelector *)SelTabImpl.Allocator.Allocate(
          Size, alignof(MultiKeywordSelector));
  new (SI) MultiKeywordSelector(nKeys, IIV);
  SelTabImpl.Table.InsertNode(SI, InsertPos);
  return Selector(SI);
}

SelectorTable::SelectorTable() {
  Impl = new SelectorTableImpl();
}

SelectorTable::~SelectorTable() {
  delete &getSelectorTableImpl(Impl);
}

const char *clang::getOperatorSpelling(OverloadedOperatorKind Operator) {
  switch (Operator) {
  case OO_None:
  case NUM_OVERLOADED_OPERATORS:
    return nullptr;

#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
  case OO_##Name: return Spelling;
#include "clang/Basic/OperatorKinds.def"
  }

  llvm_unreachable("Invalid OverloadedOperatorKind!");
}

StringRef clang::getNullabilitySpelling(NullabilityKind kind,
                                        bool isContextSensitive) {
  switch (kind) {
  case NullabilityKind::NonNull:
    return isContextSensitive ? "nonnull" : "_Nonnull";

  case NullabilityKind::Nullable:
    return isContextSensitive ? "nullable" : "_Nullable";

  case NullabilityKind::NullableResult:
    assert(!isContextSensitive &&
           "_Nullable_result isn't supported as context-sensitive keyword");
    return "_Nullable_result";

  case NullabilityKind::Unspecified:
    return isContextSensitive ? "null_unspecified" : "_Null_unspecified";
  }
  llvm_unreachable("Unknown nullability kind.");
}

llvm::raw_ostream &clang::operator<<(llvm::raw_ostream &OS,
                                     NullabilityKind NK) {
  switch (NK) {
  case NullabilityKind::NonNull:
    return OS << "NonNull";
  case NullabilityKind::Nullable:
    return OS << "Nullable";
  case NullabilityKind::NullableResult:
    return OS << "NullableResult";
  case NullabilityKind::Unspecified:
    return OS << "Unspecified";
  }
  llvm_unreachable("Unknown nullability kind.");
}

diag::kind
IdentifierTable::getFutureCompatDiagKind(const IdentifierInfo &II,
                                         const LangOptions &LangOpts) {
  assert(II.isFutureCompatKeyword() && "diagnostic should not be needed");

  unsigned Flags = llvm::StringSwitch<unsigned>(II.getName())
#define KEYWORD(NAME, FLAGS) .Case(#NAME, FLAGS)
#include "clang/Basic/TokenKinds.def"
#undef KEYWORD
      ;

  if (LangOpts.CPlusPlus) {
    if ((Flags & KEYCXX11) == KEYCXX11)
      return diag::warn_cxx11_keyword;

    // char8_t is not modeled as a CXX20_KEYWORD because it's not
    // unconditionally enabled in C++20 mode. (It can be disabled
    // by -fno-char8_t.)
    if (((Flags & KEYCXX20) == KEYCXX20) ||
        ((Flags & CHAR8SUPPORT) == CHAR8SUPPORT))
      return diag::warn_cxx20_keyword;
  } else {
    if ((Flags & KEYC99) == KEYC99)
      return diag::warn_c99_keyword;
    if ((Flags & KEYC23) == KEYC23)
      return diag::warn_c23_keyword;
  }

  llvm_unreachable(
      "Keyword not known to come from a newer Standard or proposed Standard");
}
