//===- CIndex.cpp - Clang-C Source Indexing Library -----------------------===//
//
// 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 main API hooks in the Clang-C Source Indexing
// library.
//
//===----------------------------------------------------------------------===//

#include "CIndexDiagnostic.h"
#include "CIndexer.h"
#include "CLog.h"
#include "CXCursor.h"
#include "CXSourceLocation.h"
#include "CXString.h"
#include "CXTranslationUnit.h"
#include "CXType.h"
#include "CursorVisitor.h"
#include "clang-c/FatalErrorHandler.h"
#include "clang/AST/Attr.h"
#include "clang/AST/DeclObjCCommon.h"
#include "clang/AST/Mangle.h"
#include "clang/AST/OpenMPClause.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/DiagnosticCategories.h"
#include "clang/Basic/DiagnosticIDs.h"
#include "clang/Basic/Stack.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Index/CommentToXML.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/PreprocessingRecord.h"
#include "clang/Lex/Preprocessor.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/Config/llvm-config.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/CrashRecoveryContext.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include <mutex>

#if LLVM_ENABLE_THREADS != 0 && defined(__APPLE__)
#define USE_DARWIN_THREADS
#endif

#ifdef USE_DARWIN_THREADS
#include <pthread.h>
#endif

using namespace clang;
using namespace clang::cxcursor;
using namespace clang::cxtu;
using namespace clang::cxindex;

CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx,
                                              std::unique_ptr<ASTUnit> AU) {
  if (!AU)
    return nullptr;
  assert(CIdx);
  CXTranslationUnit D = new CXTranslationUnitImpl();
  D->CIdx = CIdx;
  D->TheASTUnit = AU.release();
  D->StringPool = new cxstring::CXStringPool();
  D->Diagnostics = nullptr;
  D->OverridenCursorsPool = createOverridenCXCursorsPool();
  D->CommentToXML = nullptr;
  D->ParsingOptions = 0;
  D->Arguments = {};
  return D;
}

bool cxtu::isASTReadError(ASTUnit *AU) {
  for (ASTUnit::stored_diag_iterator D = AU->stored_diag_begin(),
                                     DEnd = AU->stored_diag_end();
       D != DEnd; ++D) {
    if (D->getLevel() >= DiagnosticsEngine::Error &&
        DiagnosticIDs::getCategoryNumberForDiag(D->getID()) ==
            diag::DiagCat_AST_Deserialization_Issue)
      return true;
  }
  return false;
}

cxtu::CXTUOwner::~CXTUOwner() {
  if (TU)
    clang_disposeTranslationUnit(TU);
}

/// Compare two source ranges to determine their relative position in
/// the translation unit.
static RangeComparisonResult RangeCompare(SourceManager &SM, SourceRange R1,
                                          SourceRange R2) {
  assert(R1.isValid() && "First range is invalid?");
  assert(R2.isValid() && "Second range is invalid?");
  if (R1.getEnd() != R2.getBegin() &&
      SM.isBeforeInTranslationUnit(R1.getEnd(), R2.getBegin()))
    return RangeBefore;
  if (R2.getEnd() != R1.getBegin() &&
      SM.isBeforeInTranslationUnit(R2.getEnd(), R1.getBegin()))
    return RangeAfter;
  return RangeOverlap;
}

/// Determine if a source location falls within, before, or after a
///   a given source range.
static RangeComparisonResult LocationCompare(SourceManager &SM,
                                             SourceLocation L, SourceRange R) {
  assert(R.isValid() && "First range is invalid?");
  assert(L.isValid() && "Second range is invalid?");
  if (L == R.getBegin() || L == R.getEnd())
    return RangeOverlap;
  if (SM.isBeforeInTranslationUnit(L, R.getBegin()))
    return RangeBefore;
  if (SM.isBeforeInTranslationUnit(R.getEnd(), L))
    return RangeAfter;
  return RangeOverlap;
}

/// Translate a Clang source range into a CIndex source range.
///
/// Clang internally represents ranges where the end location points to the
/// start of the token at the end. However, for external clients it is more
/// useful to have a CXSourceRange be a proper half-open interval. This routine
/// does the appropriate translation.
CXSourceRange cxloc::translateSourceRange(const SourceManager &SM,
                                          const LangOptions &LangOpts,
                                          const CharSourceRange &R) {
  // We want the last character in this location, so we will adjust the
  // location accordingly.
  SourceLocation EndLoc = R.getEnd();
  bool IsTokenRange = R.isTokenRange();
  if (EndLoc.isValid() && EndLoc.isMacroID() &&
      !SM.isMacroArgExpansion(EndLoc)) {
    CharSourceRange Expansion = SM.getExpansionRange(EndLoc);
    EndLoc = Expansion.getEnd();
    IsTokenRange = Expansion.isTokenRange();
  }
  if (IsTokenRange && EndLoc.isValid()) {
    unsigned Length =
        Lexer::MeasureTokenLength(SM.getSpellingLoc(EndLoc), SM, LangOpts);
    EndLoc = EndLoc.getLocWithOffset(Length);
  }

  CXSourceRange Result = {
      {&SM, &LangOpts}, R.getBegin().getRawEncoding(), EndLoc.getRawEncoding()};
  return Result;
}

//===----------------------------------------------------------------------===//
// Cursor visitor.
//===----------------------------------------------------------------------===//

static SourceRange getRawCursorExtent(CXCursor C);
static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr);

RangeComparisonResult CursorVisitor::CompareRegionOfInterest(SourceRange R) {
  return RangeCompare(AU->getSourceManager(), R, RegionOfInterest);
}

/// Visit the given cursor and, if requested by the visitor,
/// its children.
///
/// \param Cursor the cursor to visit.
///
/// \param CheckedRegionOfInterest if true, then the caller already checked
/// that this cursor is within the region of interest.
///
/// \returns true if the visitation should be aborted, false if it
/// should continue.
bool CursorVisitor::Visit(CXCursor Cursor, bool CheckedRegionOfInterest) {
  if (clang_isInvalid(Cursor.kind))
    return false;

  if (clang_isDeclaration(Cursor.kind)) {
    const Decl *D = getCursorDecl(Cursor);
    if (!D) {
      assert(0 && "Invalid declaration cursor");
      return true; // abort.
    }

    // Ignore implicit declarations, unless it's an objc method because
    // currently we should report implicit methods for properties when indexing.
    if (D->isImplicit() && !isa<ObjCMethodDecl>(D))
      return false;
  }

  // If we have a range of interest, and this cursor doesn't intersect with it,
  // we're done.
  if (RegionOfInterest.isValid() && !CheckedRegionOfInterest) {
    SourceRange Range = getRawCursorExtent(Cursor);
    if (Range.isInvalid() || CompareRegionOfInterest(Range))
      return false;
  }

  switch (Visitor(Cursor, Parent, ClientData)) {
  case CXChildVisit_Break:
    return true;

  case CXChildVisit_Continue:
    return false;

  case CXChildVisit_Recurse: {
    bool ret = VisitChildren(Cursor);
    if (PostChildrenVisitor)
      if (PostChildrenVisitor(Cursor, ClientData))
        return true;
    return ret;
  }
  }

  llvm_unreachable("Invalid CXChildVisitResult!");
}

static bool visitPreprocessedEntitiesInRange(SourceRange R,
                                             PreprocessingRecord &PPRec,
                                             CursorVisitor &Visitor) {
  SourceManager &SM = Visitor.getASTUnit()->getSourceManager();
  FileID FID;

  if (!Visitor.shouldVisitIncludedEntities()) {
    // If the begin/end of the range lie in the same FileID, do the optimization
    // where we skip preprocessed entities that do not come from the same
    // FileID.
    FID = SM.getFileID(SM.getFileLoc(R.getBegin()));
    if (FID != SM.getFileID(SM.getFileLoc(R.getEnd())))
      FID = FileID();
  }

  const auto &Entities = PPRec.getPreprocessedEntitiesInRange(R);
  return Visitor.visitPreprocessedEntities(Entities.begin(), Entities.end(),
                                           PPRec, FID);
}

bool CursorVisitor::visitFileRegion() {
  if (RegionOfInterest.isInvalid())
    return false;

  ASTUnit *Unit = cxtu::getASTUnit(TU);
  SourceManager &SM = Unit->getSourceManager();

  std::pair<FileID, unsigned> Begin = SM.getDecomposedLoc(
                                  SM.getFileLoc(RegionOfInterest.getBegin())),
                              End = SM.getDecomposedLoc(
                                  SM.getFileLoc(RegionOfInterest.getEnd()));

  if (End.first != Begin.first) {
    // If the end does not reside in the same file, try to recover by
    // picking the end of the file of begin location.
    End.first = Begin.first;
    End.second = SM.getFileIDSize(Begin.first);
  }

  assert(Begin.first == End.first);
  if (Begin.second > End.second)
    return false;

  FileID File = Begin.first;
  unsigned Offset = Begin.second;
  unsigned Length = End.second - Begin.second;

  if (!VisitDeclsOnly && !VisitPreprocessorLast)
    if (visitPreprocessedEntitiesInRegion())
      return true; // visitation break.

  if (visitDeclsFromFileRegion(File, Offset, Length))
    return true; // visitation break.

  if (!VisitDeclsOnly && VisitPreprocessorLast)
    return visitPreprocessedEntitiesInRegion();

  return false;
}

static bool isInLexicalContext(Decl *D, DeclContext *DC) {
  if (!DC)
    return false;

  for (DeclContext *DeclDC = D->getLexicalDeclContext(); DeclDC;
       DeclDC = DeclDC->getLexicalParent()) {
    if (DeclDC == DC)
      return true;
  }
  return false;
}

bool CursorVisitor::visitDeclsFromFileRegion(FileID File, unsigned Offset,
                                             unsigned Length) {
  ASTUnit *Unit = cxtu::getASTUnit(TU);
  SourceManager &SM = Unit->getSourceManager();
  SourceRange Range = RegionOfInterest;

  SmallVector<Decl *, 16> Decls;
  Unit->findFileRegionDecls(File, Offset, Length, Decls);

  // If we didn't find any file level decls for the file, try looking at the
  // file that it was included from.
  while (Decls.empty() || Decls.front()->isTopLevelDeclInObjCContainer()) {
    bool Invalid = false;
    const SrcMgr::SLocEntry &SLEntry = SM.getSLocEntry(File, &Invalid);
    if (Invalid)
      return false;

    SourceLocation Outer;
    if (SLEntry.isFile())
      Outer = SLEntry.getFile().getIncludeLoc();
    else
      Outer = SLEntry.getExpansion().getExpansionLocStart();
    if (Outer.isInvalid())
      return false;

    std::tie(File, Offset) = SM.getDecomposedExpansionLoc(Outer);
    Length = 0;
    Unit->findFileRegionDecls(File, Offset, Length, Decls);
  }

  assert(!Decls.empty());

  bool VisitedAtLeastOnce = false;
  DeclContext *CurDC = nullptr;
  SmallVectorImpl<Decl *>::iterator DIt = Decls.begin();
  for (SmallVectorImpl<Decl *>::iterator DE = Decls.end(); DIt != DE; ++DIt) {
    Decl *D = *DIt;
    if (D->getSourceRange().isInvalid())
      continue;

    if (isInLexicalContext(D, CurDC))
      continue;

    CurDC = dyn_cast<DeclContext>(D);

    if (TagDecl *TD = dyn_cast<TagDecl>(D))
      if (!TD->isFreeStanding())
        continue;

    RangeComparisonResult CompRes =
        RangeCompare(SM, D->getSourceRange(), Range);
    if (CompRes == RangeBefore)
      continue;
    if (CompRes == RangeAfter)
      break;

    assert(CompRes == RangeOverlap);
    VisitedAtLeastOnce = true;

    if (isa<ObjCContainerDecl>(D)) {
      FileDI_current = &DIt;
      FileDE_current = DE;
    } else {
      FileDI_current = nullptr;
    }

    if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
      return true; // visitation break.
  }

  if (VisitedAtLeastOnce)
    return false;

  // No Decls overlapped with the range. Move up the lexical context until there
  // is a context that contains the range or we reach the translation unit
  // level.
  DeclContext *DC = DIt == Decls.begin()
                        ? (*DIt)->getLexicalDeclContext()
                        : (*(DIt - 1))->getLexicalDeclContext();

  while (DC && !DC->isTranslationUnit()) {
    Decl *D = cast<Decl>(DC);
    SourceRange CurDeclRange = D->getSourceRange();
    if (CurDeclRange.isInvalid())
      break;

    if (RangeCompare(SM, CurDeclRange, Range) == RangeOverlap) {
      if (Visit(MakeCXCursor(D, TU, Range), /*CheckedRegionOfInterest=*/true))
        return true; // visitation break.
    }

    DC = D->getLexicalDeclContext();
  }

  return false;
}

bool CursorVisitor::visitPreprocessedEntitiesInRegion() {
  if (!AU->getPreprocessor().getPreprocessingRecord())
    return false;

  PreprocessingRecord &PPRec = *AU->getPreprocessor().getPreprocessingRecord();
  SourceManager &SM = AU->getSourceManager();

  if (RegionOfInterest.isValid()) {
    SourceRange MappedRange = AU->mapRangeToPreamble(RegionOfInterest);
    SourceLocation B = MappedRange.getBegin();
    SourceLocation E = MappedRange.getEnd();

    if (AU->isInPreambleFileID(B)) {
      if (SM.isLoadedSourceLocation(E))
        return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec,
                                                *this);

      // Beginning of range lies in the preamble but it also extends beyond
      // it into the main file. Split the range into 2 parts, one covering
      // the preamble and another covering the main file. This allows subsequent
      // calls to visitPreprocessedEntitiesInRange to accept a source range that
      // lies in the same FileID, allowing it to skip preprocessed entities that
      // do not come from the same FileID.
      bool breaked = visitPreprocessedEntitiesInRange(
          SourceRange(B, AU->getEndOfPreambleFileID()), PPRec, *this);
      if (breaked)
        return true;
      return visitPreprocessedEntitiesInRange(
          SourceRange(AU->getStartOfMainFileID(), E), PPRec, *this);
    }

    return visitPreprocessedEntitiesInRange(SourceRange(B, E), PPRec, *this);
  }

  bool OnlyLocalDecls = !AU->isMainFileAST() && AU->getOnlyLocalDecls();

  if (OnlyLocalDecls)
    return visitPreprocessedEntities(PPRec.local_begin(), PPRec.local_end(),
                                     PPRec);

  return visitPreprocessedEntities(PPRec.begin(), PPRec.end(), PPRec);
}

template <typename InputIterator>
bool CursorVisitor::visitPreprocessedEntities(InputIterator First,
                                              InputIterator Last,
                                              PreprocessingRecord &PPRec,
                                              FileID FID) {
  for (; First != Last; ++First) {
    if (!FID.isInvalid() && !PPRec.isEntityInFileID(First, FID))
      continue;

    PreprocessedEntity *PPE = *First;
    if (!PPE)
      continue;

    if (MacroExpansion *ME = dyn_cast<MacroExpansion>(PPE)) {
      if (Visit(MakeMacroExpansionCursor(ME, TU)))
        return true;

      continue;
    }

    if (MacroDefinitionRecord *MD = dyn_cast<MacroDefinitionRecord>(PPE)) {
      if (Visit(MakeMacroDefinitionCursor(MD, TU)))
        return true;

      continue;
    }

    if (InclusionDirective *ID = dyn_cast<InclusionDirective>(PPE)) {
      if (Visit(MakeInclusionDirectiveCursor(ID, TU)))
        return true;

      continue;
    }
  }

  return false;
}

/// Visit the children of the given cursor.
///
/// \returns true if the visitation should be aborted, false if it
/// should continue.
bool CursorVisitor::VisitChildren(CXCursor Cursor) {
  if (clang_isReference(Cursor.kind) &&
      Cursor.kind != CXCursor_CXXBaseSpecifier) {
    // By definition, references have no children.
    return false;
  }

  // Set the Parent field to Cursor, then back to its old value once we're
  // done.
  SetParentRAII SetParent(Parent, StmtParent, Cursor);

  if (clang_isDeclaration(Cursor.kind)) {
    Decl *D = const_cast<Decl *>(getCursorDecl(Cursor));
    if (!D)
      return false;

    return VisitAttributes(D) || Visit(D);
  }

  if (clang_isStatement(Cursor.kind)) {
    if (const Stmt *S = getCursorStmt(Cursor))
      return Visit(S);

    return false;
  }

  if (clang_isExpression(Cursor.kind)) {
    if (const Expr *E = getCursorExpr(Cursor))
      return Visit(E);

    return false;
  }

  if (clang_isTranslationUnit(Cursor.kind)) {
    CXTranslationUnit TU = getCursorTU(Cursor);
    ASTUnit *CXXUnit = cxtu::getASTUnit(TU);

    int VisitOrder[2] = {VisitPreprocessorLast, !VisitPreprocessorLast};
    for (unsigned I = 0; I != 2; ++I) {
      if (VisitOrder[I]) {
        if (!CXXUnit->isMainFileAST() && CXXUnit->getOnlyLocalDecls() &&
            RegionOfInterest.isInvalid()) {
          for (ASTUnit::top_level_iterator TL = CXXUnit->top_level_begin(),
                                           TLEnd = CXXUnit->top_level_end();
               TL != TLEnd; ++TL) {
            const Optional<bool> V = handleDeclForVisitation(*TL);
            if (!V.hasValue())
              continue;
            return V.getValue();
          }
        } else if (VisitDeclContext(
                       CXXUnit->getASTContext().getTranslationUnitDecl()))
          return true;
        continue;
      }

      // Walk the preprocessing record.
      if (CXXUnit->getPreprocessor().getPreprocessingRecord())
        visitPreprocessedEntitiesInRegion();
    }

    return false;
  }

  if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
    if (const CXXBaseSpecifier *Base = getCursorCXXBaseSpecifier(Cursor)) {
      if (TypeSourceInfo *BaseTSInfo = Base->getTypeSourceInfo()) {
        return Visit(BaseTSInfo->getTypeLoc());
      }
    }
  }

  if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
    const IBOutletCollectionAttr *A =
        cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(Cursor));
    if (const ObjCObjectType *ObjT = A->getInterface()->getAs<ObjCObjectType>())
      return Visit(cxcursor::MakeCursorObjCClassRef(
          ObjT->getInterface(),
          A->getInterfaceLoc()->getTypeLoc().getBeginLoc(), TU));
  }

  // If pointing inside a macro definition, check if the token is an identifier
  // that was ever defined as a macro. In such a case, create a "pseudo" macro
  // expansion cursor for that token.
  SourceLocation BeginLoc = RegionOfInterest.getBegin();
  if (Cursor.kind == CXCursor_MacroDefinition &&
      BeginLoc == RegionOfInterest.getEnd()) {
    SourceLocation Loc = AU->mapLocationToPreamble(BeginLoc);
    const MacroInfo *MI =
        getMacroInfo(cxcursor::getCursorMacroDefinition(Cursor), TU);
    if (MacroDefinitionRecord *MacroDef =
            checkForMacroInMacroDefinition(MI, Loc, TU))
      return Visit(cxcursor::MakeMacroExpansionCursor(MacroDef, BeginLoc, TU));
  }

  // Nothing to visit at the moment.
  return false;
}

bool CursorVisitor::VisitBlockDecl(BlockDecl *B) {
  if (TypeSourceInfo *TSInfo = B->getSignatureAsWritten())
    if (Visit(TSInfo->getTypeLoc()))
      return true;

  if (Stmt *Body = B->getBody())
    return Visit(MakeCXCursor(Body, StmtParent, TU, RegionOfInterest));

  return false;
}

Optional<bool> CursorVisitor::shouldVisitCursor(CXCursor Cursor) {
  if (RegionOfInterest.isValid()) {
    SourceRange Range = getFullCursorExtent(Cursor, AU->getSourceManager());
    if (Range.isInvalid())
      return None;

    switch (CompareRegionOfInterest(Range)) {
    case RangeBefore:
      // This declaration comes before the region of interest; skip it.
      return None;

    case RangeAfter:
      // This declaration comes after the region of interest; we're done.
      return false;

    case RangeOverlap:
      // This declaration overlaps the region of interest; visit it.
      break;
    }
  }
  return true;
}

bool CursorVisitor::VisitDeclContext(DeclContext *DC) {
  DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();

  // FIXME: Eventually remove.  This part of a hack to support proper
  // iteration over all Decls contained lexically within an ObjC container.
  SaveAndRestore<DeclContext::decl_iterator *> DI_saved(DI_current, &I);
  SaveAndRestore<DeclContext::decl_iterator> DE_saved(DE_current, E);

  for (; I != E; ++I) {
    Decl *D = *I;
    if (D->getLexicalDeclContext() != DC)
      continue;
    // Filter out synthesized property accessor redeclarations.
    if (isa<ObjCImplDecl>(DC))
      if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
        if (OMD->isSynthesizedAccessorStub())
          continue;
    const Optional<bool> V = handleDeclForVisitation(D);
    if (!V.hasValue())
      continue;
    return V.getValue();
  }
  return false;
}

Optional<bool> CursorVisitor::handleDeclForVisitation(const Decl *D) {
  CXCursor Cursor = MakeCXCursor(D, TU, RegionOfInterest);

  // Ignore synthesized ivars here, otherwise if we have something like:
  //   @synthesize prop = _prop;
  // and '_prop' is not declared, we will encounter a '_prop' ivar before
  // encountering the 'prop' synthesize declaration and we will think that
  // we passed the region-of-interest.
  if (auto *ivarD = dyn_cast<ObjCIvarDecl>(D)) {
    if (ivarD->getSynthesize())
      return None;
  }

  // FIXME: ObjCClassRef/ObjCProtocolRef for forward class/protocol
  // declarations is a mismatch with the compiler semantics.
  if (Cursor.kind == CXCursor_ObjCInterfaceDecl) {
    auto *ID = cast<ObjCInterfaceDecl>(D);
    if (!ID->isThisDeclarationADefinition())
      Cursor = MakeCursorObjCClassRef(ID, ID->getLocation(), TU);

  } else if (Cursor.kind == CXCursor_ObjCProtocolDecl) {
    auto *PD = cast<ObjCProtocolDecl>(D);
    if (!PD->isThisDeclarationADefinition())
      Cursor = MakeCursorObjCProtocolRef(PD, PD->getLocation(), TU);
  }

  const Optional<bool> V = shouldVisitCursor(Cursor);
  if (!V.hasValue())
    return None;
  if (!V.getValue())
    return false;
  if (Visit(Cursor, true))
    return true;
  return None;
}

bool CursorVisitor::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
  llvm_unreachable("Translation units are visited directly by Visit()");
}

bool CursorVisitor::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
  if (VisitTemplateParameters(D->getTemplateParameters()))
    return true;

  return Visit(MakeCXCursor(D->getTemplatedDecl(), TU, RegionOfInterest));
}

bool CursorVisitor::VisitTypeAliasDecl(TypeAliasDecl *D) {
  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
    return Visit(TSInfo->getTypeLoc());

  return false;
}

bool CursorVisitor::VisitTypedefDecl(TypedefDecl *D) {
  if (TypeSourceInfo *TSInfo = D->getTypeSourceInfo())
    return Visit(TSInfo->getTypeLoc());

  return false;
}

bool CursorVisitor::VisitTagDecl(TagDecl *D) { return VisitDeclContext(D); }

bool CursorVisitor::VisitClassTemplateSpecializationDecl(
    ClassTemplateSpecializationDecl *D) {
  bool ShouldVisitBody = false;
  switch (D->getSpecializationKind()) {
  case TSK_Undeclared:
  case TSK_ImplicitInstantiation:
    // Nothing to visit
    return false;

  case TSK_ExplicitInstantiationDeclaration:
  case TSK_ExplicitInstantiationDefinition:
    break;

  case TSK_ExplicitSpecialization:
    ShouldVisitBody = true;
    break;
  }

  // Visit the template arguments used in the specialization.
  if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
    TypeLoc TL = SpecType->getTypeLoc();
    if (TemplateSpecializationTypeLoc TSTLoc =
            TL.getAs<TemplateSpecializationTypeLoc>()) {
      for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
        if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
          return true;
    }
  }

  return ShouldVisitBody && VisitCXXRecordDecl(D);
}

bool CursorVisitor::VisitClassTemplatePartialSpecializationDecl(
    ClassTemplatePartialSpecializationDecl *D) {
  // FIXME: Visit the "outer" template parameter lists on the TagDecl
  // before visiting these template parameters.
  if (VisitTemplateParameters(D->getTemplateParameters()))
    return true;

  // Visit the partial specialization arguments.
  const ASTTemplateArgumentListInfo *Info = D->getTemplateArgsAsWritten();
  const TemplateArgumentLoc *TemplateArgs = Info->getTemplateArgs();
  for (unsigned I = 0, N = Info->NumTemplateArgs; I != N; ++I)
    if (VisitTemplateArgumentLoc(TemplateArgs[I]))
      return true;

  return VisitCXXRecordDecl(D);
}

bool CursorVisitor::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
  if (const auto *TC = D->getTypeConstraint())
    if (Visit(MakeCXCursor(TC->getImmediatelyDeclaredConstraint(), StmtParent,
                           TU, RegionOfInterest)))
      return true;

  // Visit the default argument.
  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
    if (TypeSourceInfo *DefArg = D->getDefaultArgumentInfo())
      if (Visit(DefArg->getTypeLoc()))
        return true;

  return false;
}

bool CursorVisitor::VisitEnumConstantDecl(EnumConstantDecl *D) {
  if (Expr *Init = D->getInitExpr())
    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));
  return false;
}

bool CursorVisitor::VisitDeclaratorDecl(DeclaratorDecl *DD) {
  unsigned NumParamList = DD->getNumTemplateParameterLists();
  for (unsigned i = 0; i < NumParamList; i++) {
    TemplateParameterList *Params = DD->getTemplateParameterList(i);
    if (VisitTemplateParameters(Params))
      return true;
  }

  if (TypeSourceInfo *TSInfo = DD->getTypeSourceInfo())
    if (Visit(TSInfo->getTypeLoc()))
      return true;

  // Visit the nested-name-specifier, if present.
  if (NestedNameSpecifierLoc QualifierLoc = DD->getQualifierLoc())
    if (VisitNestedNameSpecifierLoc(QualifierLoc))
      return true;

  return false;
}

static bool HasTrailingReturnType(FunctionDecl *ND) {
  const QualType Ty = ND->getType();
  if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
    if (const FunctionProtoType *FT = dyn_cast<FunctionProtoType>(AFT))
      return FT->hasTrailingReturn();
  }

  return false;
}

/// Compare two base or member initializers based on their source order.
static int CompareCXXCtorInitializers(CXXCtorInitializer *const *X,
                                      CXXCtorInitializer *const *Y) {
  return (*X)->getSourceOrder() - (*Y)->getSourceOrder();
}

bool CursorVisitor::VisitFunctionDecl(FunctionDecl *ND) {
  unsigned NumParamList = ND->getNumTemplateParameterLists();
  for (unsigned i = 0; i < NumParamList; i++) {
    TemplateParameterList *Params = ND->getTemplateParameterList(i);
    if (VisitTemplateParameters(Params))
      return true;
  }

  if (TypeSourceInfo *TSInfo = ND->getTypeSourceInfo()) {
    // Visit the function declaration's syntactic components in the order
    // written. This requires a bit of work.
    TypeLoc TL = TSInfo->getTypeLoc().IgnoreParens();
    FunctionTypeLoc FTL = TL.getAs<FunctionTypeLoc>();
    const bool HasTrailingRT = HasTrailingReturnType(ND);

    // If we have a function declared directly (without the use of a typedef),
    // visit just the return type. Otherwise, just visit the function's type
    // now.
    if ((FTL && !isa<CXXConversionDecl>(ND) && !HasTrailingRT &&
         Visit(FTL.getReturnLoc())) ||
        (!FTL && Visit(TL)))
      return true;

    // Visit the nested-name-specifier, if present.
    if (NestedNameSpecifierLoc QualifierLoc = ND->getQualifierLoc())
      if (VisitNestedNameSpecifierLoc(QualifierLoc))
        return true;

    // Visit the declaration name.
    if (!isa<CXXDestructorDecl>(ND))
      if (VisitDeclarationNameInfo(ND->getNameInfo()))
        return true;

    // FIXME: Visit explicitly-specified template arguments!

    // Visit the function parameters, if we have a function type.
    if (FTL && VisitFunctionTypeLoc(FTL, true))
      return true;

    // Visit the function's trailing return type.
    if (FTL && HasTrailingRT && Visit(FTL.getReturnLoc()))
      return true;

    // FIXME: Attributes?
  }

  if (ND->doesThisDeclarationHaveABody() && !ND->isLateTemplateParsed()) {
    if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(ND)) {
      // Find the initializers that were written in the source.
      SmallVector<CXXCtorInitializer *, 4> WrittenInits;
      for (auto *I : Constructor->inits()) {
        if (!I->isWritten())
          continue;

        WrittenInits.push_back(I);
      }

      // Sort the initializers in source order
      llvm::array_pod_sort(WrittenInits.begin(), WrittenInits.end(),
                           &CompareCXXCtorInitializers);

      // Visit the initializers in source order
      for (unsigned I = 0, N = WrittenInits.size(); I != N; ++I) {
        CXXCtorInitializer *Init = WrittenInits[I];
        if (Init->isAnyMemberInitializer()) {
          if (Visit(MakeCursorMemberRef(Init->getAnyMember(),
                                        Init->getMemberLocation(), TU)))
            return true;
        } else if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo()) {
          if (Visit(TInfo->getTypeLoc()))
            return true;
        }

        // Visit the initializer value.
        if (Expr *Initializer = Init->getInit())
          if (Visit(MakeCXCursor(Initializer, ND, TU, RegionOfInterest)))
            return true;
      }
    }

    if (Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest)))
      return true;
  }

  return false;
}

bool CursorVisitor::VisitFieldDecl(FieldDecl *D) {
  if (VisitDeclaratorDecl(D))
    return true;

  if (Expr *BitWidth = D->getBitWidth())
    return Visit(MakeCXCursor(BitWidth, StmtParent, TU, RegionOfInterest));

  if (Expr *Init = D->getInClassInitializer())
    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));

  return false;
}

bool CursorVisitor::VisitVarDecl(VarDecl *D) {
  if (VisitDeclaratorDecl(D))
    return true;

  if (Expr *Init = D->getInit())
    return Visit(MakeCXCursor(Init, StmtParent, TU, RegionOfInterest));

  return false;
}

bool CursorVisitor::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
  if (VisitDeclaratorDecl(D))
    return true;

  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
    if (Expr *DefArg = D->getDefaultArgument())
      return Visit(MakeCXCursor(DefArg, StmtParent, TU, RegionOfInterest));

  return false;
}

bool CursorVisitor::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
  // FIXME: Visit the "outer" template parameter lists on the FunctionDecl
  // before visiting these template parameters.
  if (VisitTemplateParameters(D->getTemplateParameters()))
    return true;

  auto *FD = D->getTemplatedDecl();
  return VisitAttributes(FD) || VisitFunctionDecl(FD);
}

bool CursorVisitor::VisitClassTemplateDecl(ClassTemplateDecl *D) {
  // FIXME: Visit the "outer" template parameter lists on the TagDecl
  // before visiting these template parameters.
  if (VisitTemplateParameters(D->getTemplateParameters()))
    return true;

  auto *CD = D->getTemplatedDecl();
  return VisitAttributes(CD) || VisitCXXRecordDecl(CD);
}

bool CursorVisitor::VisitTemplateTemplateParmDecl(TemplateTemplateParmDecl *D) {
  if (VisitTemplateParameters(D->getTemplateParameters()))
    return true;

  if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited() &&
      VisitTemplateArgumentLoc(D->getDefaultArgument()))
    return true;

  return false;
}

bool CursorVisitor::VisitObjCTypeParamDecl(ObjCTypeParamDecl *D) {
  // Visit the bound, if it's explicit.
  if (D->hasExplicitBound()) {
    if (auto TInfo = D->getTypeSourceInfo()) {
      if (Visit(TInfo->getTypeLoc()))
        return true;
    }
  }

  return false;
}

bool CursorVisitor::VisitObjCMethodDecl(ObjCMethodDecl *ND) {
  if (TypeSourceInfo *TSInfo = ND->getReturnTypeSourceInfo())
    if (Visit(TSInfo->getTypeLoc()))
      return true;

  for (const auto *P : ND->parameters()) {
    if (Visit(MakeCXCursor(P, TU, RegionOfInterest)))
      return true;
  }

  return ND->isThisDeclarationADefinition() &&
         Visit(MakeCXCursor(ND->getBody(), StmtParent, TU, RegionOfInterest));
}

template <typename DeclIt>
static void addRangedDeclsInContainer(DeclIt *DI_current, DeclIt DE_current,
                                      SourceManager &SM, SourceLocation EndLoc,
                                      SmallVectorImpl<Decl *> &Decls) {
  DeclIt next = *DI_current;
  while (++next != DE_current) {
    Decl *D_next = *next;
    if (!D_next)
      break;
    SourceLocation L = D_next->getBeginLoc();
    if (!L.isValid())
      break;
    if (SM.isBeforeInTranslationUnit(L, EndLoc)) {
      *DI_current = next;
      Decls.push_back(D_next);
      continue;
    }
    break;
  }
}

bool CursorVisitor::VisitObjCContainerDecl(ObjCContainerDecl *D) {
  // FIXME: Eventually convert back to just 'VisitDeclContext()'.  Essentially
  // an @implementation can lexically contain Decls that are not properly
  // nested in the AST.  When we identify such cases, we need to retrofit
  // this nesting here.
  if (!DI_current && !FileDI_current)
    return VisitDeclContext(D);

  // Scan the Decls that immediately come after the container
  // in the current DeclContext.  If any fall within the
  // container's lexical region, stash them into a vector
  // for later processing.
  SmallVector<Decl *, 24> DeclsInContainer;
  SourceLocation EndLoc = D->getSourceRange().getEnd();
  SourceManager &SM = AU->getSourceManager();
  if (EndLoc.isValid()) {
    if (DI_current) {
      addRangedDeclsInContainer(DI_current, DE_current, SM, EndLoc,
                                DeclsInContainer);
    } else {
      addRangedDeclsInContainer(FileDI_current, FileDE_current, SM, EndLoc,
                                DeclsInContainer);
    }
  }

  // The common case.
  if (DeclsInContainer.empty())
    return VisitDeclContext(D);

  // Get all the Decls in the DeclContext, and sort them with the
  // additional ones we've collected.  Then visit them.
  for (auto *SubDecl : D->decls()) {
    if (!SubDecl || SubDecl->getLexicalDeclContext() != D ||
        SubDecl->getBeginLoc().isInvalid())
      continue;
    DeclsInContainer.push_back(SubDecl);
  }

  // Now sort the Decls so that they appear in lexical order.
  llvm::sort(DeclsInContainer, [&SM](Decl *A, Decl *B) {
    SourceLocation L_A = A->getBeginLoc();
    SourceLocation L_B = B->getBeginLoc();
    return L_A != L_B
               ? SM.isBeforeInTranslationUnit(L_A, L_B)
               : SM.isBeforeInTranslationUnit(A->getEndLoc(), B->getEndLoc());
  });

  // Now visit the decls.
  for (SmallVectorImpl<Decl *>::iterator I = DeclsInContainer.begin(),
                                         E = DeclsInContainer.end();
       I != E; ++I) {
    CXCursor Cursor = MakeCXCursor(*I, TU, RegionOfInterest);
    const Optional<bool> &V = shouldVisitCursor(Cursor);
    if (!V.hasValue())
      continue;
    if (!V.getValue())
      return false;
    if (Visit(Cursor, true))
      return true;
  }
  return false;
}

bool CursorVisitor::VisitObjCCategoryDecl(ObjCCategoryDecl *ND) {
  if (Visit(MakeCursorObjCClassRef(ND->getClassInterface(), ND->getLocation(),
                                   TU)))
    return true;

  if (VisitObjCTypeParamList(ND->getTypeParamList()))
    return true;

  ObjCCategoryDecl::protocol_loc_iterator PL = ND->protocol_loc_begin();
  for (ObjCCategoryDecl::protocol_iterator I = ND->protocol_begin(),
                                           E = ND->protocol_end();
       I != E; ++I, ++PL)
    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
      return true;

  return VisitObjCContainerDecl(ND);
}

bool CursorVisitor::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
  if (!PID->isThisDeclarationADefinition())
    return Visit(MakeCursorObjCProtocolRef(PID, PID->getLocation(), TU));

  ObjCProtocolDecl::protocol_loc_iterator PL = PID->protocol_loc_begin();
  for (ObjCProtocolDecl::protocol_iterator I = PID->protocol_begin(),
                                           E = PID->protocol_end();
       I != E; ++I, ++PL)
    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
      return true;

  return VisitObjCContainerDecl(PID);
}

bool CursorVisitor::VisitObjCPropertyDecl(ObjCPropertyDecl *PD) {
  if (PD->getTypeSourceInfo() && Visit(PD->getTypeSourceInfo()->getTypeLoc()))
    return true;

  // FIXME: This implements a workaround with @property declarations also being
  // installed in the DeclContext for the @interface.  Eventually this code
  // should be removed.
  ObjCCategoryDecl *CDecl = dyn_cast<ObjCCategoryDecl>(PD->getDeclContext());
  if (!CDecl || !CDecl->IsClassExtension())
    return false;

  ObjCInterfaceDecl *ID = CDecl->getClassInterface();
  if (!ID)
    return false;

  IdentifierInfo *PropertyId = PD->getIdentifier();
  ObjCPropertyDecl *prevDecl = ObjCPropertyDecl::findPropertyDecl(
      cast<DeclContext>(ID), PropertyId, PD->getQueryKind());

  if (!prevDecl)
    return false;

  // Visit synthesized methods since they will be skipped when visiting
  // the @interface.
  if (ObjCMethodDecl *MD = prevDecl->getGetterMethodDecl())
    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
        return true;

  if (ObjCMethodDecl *MD = prevDecl->getSetterMethodDecl())
    if (MD->isPropertyAccessor() && MD->getLexicalDeclContext() == CDecl)
      if (Visit(MakeCXCursor(MD, TU, RegionOfInterest)))
        return true;

  return false;
}

bool CursorVisitor::VisitObjCTypeParamList(ObjCTypeParamList *typeParamList) {
  if (!typeParamList)
    return false;

  for (auto *typeParam : *typeParamList) {
    // Visit the type parameter.
    if (Visit(MakeCXCursor(typeParam, TU, RegionOfInterest)))
      return true;
  }

  return false;
}

bool CursorVisitor::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) {
  if (!D->isThisDeclarationADefinition()) {
    // Forward declaration is treated like a reference.
    return Visit(MakeCursorObjCClassRef(D, D->getLocation(), TU));
  }

  // Objective-C type parameters.
  if (VisitObjCTypeParamList(D->getTypeParamListAsWritten()))
    return true;

  // Issue callbacks for super class.
  if (D->getSuperClass() && Visit(MakeCursorObjCSuperClassRef(
                                D->getSuperClass(), D->getSuperClassLoc(), TU)))
    return true;

  if (TypeSourceInfo *SuperClassTInfo = D->getSuperClassTInfo())
    if (Visit(SuperClassTInfo->getTypeLoc()))
      return true;

  ObjCInterfaceDecl::protocol_loc_iterator PL = D->protocol_loc_begin();
  for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(),
                                            E = D->protocol_end();
       I != E; ++I, ++PL)
    if (Visit(MakeCursorObjCProtocolRef(*I, *PL, TU)))
      return true;

  return VisitObjCContainerDecl(D);
}

bool CursorVisitor::VisitObjCImplDecl(ObjCImplDecl *D) {
  return VisitObjCContainerDecl(D);
}

bool CursorVisitor::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) {
  // 'ID' could be null when dealing with invalid code.
  if (ObjCInterfaceDecl *ID = D->getClassInterface())
    if (Visit(MakeCursorObjCClassRef(ID, D->getLocation(), TU)))
      return true;

  return VisitObjCImplDecl(D);
}

bool CursorVisitor::VisitObjCImplementationDecl(ObjCImplementationDecl *D) {
#if 0
  // Issue callbacks for super class.
  // FIXME: No source location information!
  if (D->getSuperClass() &&
      Visit(MakeCursorObjCSuperClassRef(D->getSuperClass(),
                                        D->getSuperClassLoc(),
                                        TU)))
    return true;
#endif

  return VisitObjCImplDecl(D);
}

bool CursorVisitor::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PD) {
  if (ObjCIvarDecl *Ivar = PD->getPropertyIvarDecl())
    if (PD->isIvarNameSpecified())
      return Visit(MakeCursorMemberRef(Ivar, PD->getPropertyIvarDeclLoc(), TU));

  return false;
}

bool CursorVisitor::VisitNamespaceDecl(NamespaceDecl *D) {
  return VisitDeclContext(D);
}

bool CursorVisitor::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
  // Visit nested-name-specifier.
  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
    if (VisitNestedNameSpecifierLoc(QualifierLoc))
      return true;

  return Visit(MakeCursorNamespaceRef(D->getAliasedNamespace(),
                                      D->getTargetNameLoc(), TU));
}

bool CursorVisitor::VisitUsingDecl(UsingDecl *D) {
  // Visit nested-name-specifier.
  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
    if (VisitNestedNameSpecifierLoc(QualifierLoc))
      return true;
  }

  if (Visit(MakeCursorOverloadedDeclRef(D, D->getLocation(), TU)))
    return true;

  return VisitDeclarationNameInfo(D->getNameInfo());
}

bool CursorVisitor::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
  // Visit nested-name-specifier.
  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
    if (VisitNestedNameSpecifierLoc(QualifierLoc))
      return true;

  return Visit(MakeCursorNamespaceRef(D->getNominatedNamespaceAsWritten(),
                                      D->getIdentLocation(), TU));
}

bool CursorVisitor::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
  // Visit nested-name-specifier.
  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc()) {
    if (VisitNestedNameSpecifierLoc(QualifierLoc))
      return true;
  }

  return VisitDeclarationNameInfo(D->getNameInfo());
}

bool CursorVisitor::VisitUnresolvedUsingTypenameDecl(
    UnresolvedUsingTypenameDecl *D) {
  // Visit nested-name-specifier.
  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
    if (VisitNestedNameSpecifierLoc(QualifierLoc))
      return true;

  return false;
}

bool CursorVisitor::VisitStaticAssertDecl(StaticAssertDecl *D) {
  if (Visit(MakeCXCursor(D->getAssertExpr(), StmtParent, TU, RegionOfInterest)))
    return true;
  if (StringLiteral *Message = D->getMessage())
    if (Visit(MakeCXCursor(Message, StmtParent, TU, RegionOfInterest)))
      return true;
  return false;
}

bool CursorVisitor::VisitFriendDecl(FriendDecl *D) {
  if (NamedDecl *FriendD = D->getFriendDecl()) {
    if (Visit(MakeCXCursor(FriendD, TU, RegionOfInterest)))
      return true;
  } else if (TypeSourceInfo *TI = D->getFriendType()) {
    if (Visit(TI->getTypeLoc()))
      return true;
  }
  return false;
}

bool CursorVisitor::VisitDecompositionDecl(DecompositionDecl *D) {
  for (auto *B : D->bindings()) {
    if (Visit(MakeCXCursor(B, TU, RegionOfInterest)))
      return true;
  }
  return VisitVarDecl(D);
}

bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
  switch (Name.getName().getNameKind()) {
  case clang::DeclarationName::Identifier:
  case clang::DeclarationName::CXXLiteralOperatorName:
  case clang::DeclarationName::CXXDeductionGuideName:
  case clang::DeclarationName::CXXOperatorName:
  case clang::DeclarationName::CXXUsingDirective:
    return false;

  case clang::DeclarationName::CXXConstructorName:
  case clang::DeclarationName::CXXDestructorName:
  case clang::DeclarationName::CXXConversionFunctionName:
    if (TypeSourceInfo *TSInfo = Name.getNamedTypeInfo())
      return Visit(TSInfo->getTypeLoc());
    return false;

  case clang::DeclarationName::ObjCZeroArgSelector:
  case clang::DeclarationName::ObjCOneArgSelector:
  case clang::DeclarationName::ObjCMultiArgSelector:
    // FIXME: Per-identifier location info?
    return false;
  }

  llvm_unreachable("Invalid DeclarationName::Kind!");
}

bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
                                             SourceRange Range) {
  // FIXME: This whole routine is a hack to work around the lack of proper
  // source information in nested-name-specifiers (PR5791). Since we do have
  // a beginning source location, we can visit the first component of the
  // nested-name-specifier, if it's a single-token component.
  if (!NNS)
    return false;

  // Get the first component in the nested-name-specifier.
  while (NestedNameSpecifier *Prefix = NNS->getPrefix())
    NNS = Prefix;

  switch (NNS->getKind()) {
  case NestedNameSpecifier::Namespace:
    return Visit(
        MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));

  case NestedNameSpecifier::NamespaceAlias:
    return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
                                        Range.getBegin(), TU));

  case NestedNameSpecifier::TypeSpec: {
    // If the type has a form where we know that the beginning of the source
    // range matches up with a reference cursor. Visit the appropriate reference
    // cursor.
    const Type *T = NNS->getAsType();
    if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
      return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
    if (const TagType *Tag = dyn_cast<TagType>(T))
      return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
    if (const TemplateSpecializationType *TST =
            dyn_cast<TemplateSpecializationType>(T))
      return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
    break;
  }

  case NestedNameSpecifier::TypeSpecWithTemplate:
  case NestedNameSpecifier::Global:
  case NestedNameSpecifier::Identifier:
  case NestedNameSpecifier::Super:
    break;
  }

  return false;
}

bool CursorVisitor::VisitNestedNameSpecifierLoc(
    NestedNameSpecifierLoc Qualifier) {
  SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
  for (; Qualifier; Qualifier = Qualifier.getPrefix())
    Qualifiers.push_back(Qualifier);

  while (!Qualifiers.empty()) {
    NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
    NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
    switch (NNS->getKind()) {
    case NestedNameSpecifier::Namespace:
      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
                                       Q.getLocalBeginLoc(), TU)))
        return true;

      break;

    case NestedNameSpecifier::NamespaceAlias:
      if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
                                       Q.getLocalBeginLoc(), TU)))
        return true;

      break;

    case NestedNameSpecifier::TypeSpec:
    case NestedNameSpecifier::TypeSpecWithTemplate:
      if (Visit(Q.getTypeLoc()))
        return true;

      break;

    case NestedNameSpecifier::Global:
    case NestedNameSpecifier::Identifier:
    case NestedNameSpecifier::Super:
      break;
    }
  }

  return false;
}

bool CursorVisitor::VisitTemplateParameters(
    const TemplateParameterList *Params) {
  if (!Params)
    return false;

  for (TemplateParameterList::const_iterator P = Params->begin(),
                                             PEnd = Params->end();
       P != PEnd; ++P) {
    if (Visit(MakeCXCursor(*P, TU, RegionOfInterest)))
      return true;
  }

  return false;
}

bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
  switch (Name.getKind()) {
  case TemplateName::Template:
    return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));

  case TemplateName::OverloadedTemplate:
    // Visit the overloaded template set.
    if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
      return true;

    return false;

  case TemplateName::AssumedTemplate:
    // FIXME: Visit DeclarationName?
    return false;

  case TemplateName::DependentTemplate:
    // FIXME: Visit nested-name-specifier.
    return false;

  case TemplateName::QualifiedTemplate:
    // FIXME: Visit nested-name-specifier.
    return Visit(MakeCursorTemplateRef(
        Name.getAsQualifiedTemplateName()->getDecl(), Loc, TU));

  case TemplateName::SubstTemplateTemplateParm:
    return Visit(MakeCursorTemplateRef(
        Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));

  case TemplateName::SubstTemplateTemplateParmPack:
    return Visit(MakeCursorTemplateRef(
        Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
        TU));
  }

  llvm_unreachable("Invalid TemplateName::Kind!");
}

bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
  switch (TAL.getArgument().getKind()) {
  case TemplateArgument::Null:
  case TemplateArgument::Integral:
  case TemplateArgument::Pack:
    return false;

  case TemplateArgument::Type:
    if (TypeSourceInfo *TSInfo = TAL.getTypeSourceInfo())
      return Visit(TSInfo->getTypeLoc());
    return false;

  case TemplateArgument::Declaration:
    if (Expr *E = TAL.getSourceDeclExpression())
      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
    return false;

  case TemplateArgument::NullPtr:
    if (Expr *E = TAL.getSourceNullPtrExpression())
      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
    return false;

  case TemplateArgument::Expression:
    if (Expr *E = TAL.getSourceExpression())
      return Visit(MakeCXCursor(E, StmtParent, TU, RegionOfInterest));
    return false;

  case TemplateArgument::Template:
  case TemplateArgument::TemplateExpansion:
    if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
      return true;

    return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
                             TAL.getTemplateNameLoc());
  }

  llvm_unreachable("Invalid TemplateArgument::Kind!");
}

bool CursorVisitor::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
  return VisitDeclContext(D);
}

bool CursorVisitor::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) {
  return Visit(TL.getUnqualifiedLoc());
}

bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
  ASTContext &Context = AU->getASTContext();

  // Some builtin types (such as Objective-C's "id", "sel", and
  // "Class") have associated declarations. Create cursors for those.
  QualType VisitType;
  switch (TL.getTypePtr()->getKind()) {

  case BuiltinType::Void:
  case BuiltinType::NullPtr:
  case BuiltinType::Dependent:
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix)                   \
  case BuiltinType::Id:
#include "clang/Basic/OpenCLImageTypes.def"
#define EXT_OPAQUE_TYPE(ExtTYpe, Id, Ext) case BuiltinType::Id:
#include "clang/Basic/OpenCLExtensionTypes.def"
  case BuiltinType::OCLSampler:
  case BuiltinType::OCLEvent:
  case BuiltinType::OCLClkEvent:
  case BuiltinType::OCLQueue:
  case BuiltinType::OCLReserveID:
#define SVE_TYPE(Name, Id, SingletonId) case BuiltinType::Id:
#include "clang/Basic/AArch64SVEACLETypes.def"
#define BUILTIN_TYPE(Id, SingletonId)
#define SIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
#define UNSIGNED_TYPE(Id, SingletonId) case BuiltinType::Id:
#define FLOATING_TYPE(Id, SingletonId) case BuiltinType::Id:
#define PLACEHOLDER_TYPE(Id, SingletonId) case BuiltinType::Id:
#include "clang/AST/BuiltinTypes.def"
    break;

  case BuiltinType::ObjCId:
    VisitType = Context.getObjCIdType();
    break;

  case BuiltinType::ObjCClass:
    VisitType = Context.getObjCClassType();
    break;

  case BuiltinType::ObjCSel:
    VisitType = Context.getObjCSelType();
    break;
  }

  if (!VisitType.isNull()) {
    if (const TypedefType *Typedef = VisitType->getAs<TypedefType>())
      return Visit(
          MakeCursorTypeRef(Typedef->getDecl(), TL.getBuiltinLoc(), TU));
  }

  return false;
}

bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
  return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
}

bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}

bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
  if (TL.isDefinition())
    return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));

  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}

bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}

bool CursorVisitor::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
  return Visit(MakeCursorObjCClassRef(TL.getIFaceDecl(), TL.getNameLoc(), TU));
}

bool CursorVisitor::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
  if (Visit(MakeCursorTypeRef(TL.getDecl(), TL.getBeginLoc(), TU)))
    return true;
  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
                                        TU)))
      return true;
  }

  return false;
}

bool CursorVisitor::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
  if (TL.hasBaseTypeAsWritten() && Visit(TL.getBaseLoc()))
    return true;

  for (unsigned I = 0, N = TL.getNumTypeArgs(); I != N; ++I) {
    if (Visit(TL.getTypeArgTInfo(I)->getTypeLoc()))
      return true;
  }

  for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
    if (Visit(MakeCursorObjCProtocolRef(TL.getProtocol(I), TL.getProtocolLoc(I),
                                        TU)))
      return true;
  }

  return false;
}

bool CursorVisitor::VisitObjCObjectPointerTypeLoc(ObjCObjectPointerTypeLoc TL) {
  return Visit(TL.getPointeeLoc());
}

bool CursorVisitor::VisitParenTypeLoc(ParenTypeLoc TL) {
  return Visit(TL.getInnerLoc());
}

bool CursorVisitor::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
  return Visit(TL.getInnerLoc());
}

bool CursorVisitor::VisitPointerTypeLoc(PointerTypeLoc TL) {
  return Visit(TL.getPointeeLoc());
}

bool CursorVisitor::VisitBlockPointerTypeLoc(BlockPointerTypeLoc TL) {
  return Visit(TL.getPointeeLoc());
}

bool CursorVisitor::VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
  return Visit(TL.getPointeeLoc());
}

bool CursorVisitor::VisitLValueReferenceTypeLoc(LValueReferenceTypeLoc TL) {
  return Visit(TL.getPointeeLoc());
}

bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
  return Visit(TL.getPointeeLoc());
}

bool CursorVisitor::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
  return Visit(TL.getModifiedLoc());
}

bool CursorVisitor::VisitFunctionTypeLoc(FunctionTypeLoc TL,
                                         bool SkipResultType) {
  if (!SkipResultType && Visit(TL.getReturnLoc()))
    return true;

  for (unsigned I = 0, N = TL.getNumParams(); I != N; ++I)
    if (Decl *D = TL.getParam(I))
      if (Visit(MakeCXCursor(D, TU, RegionOfInterest)))
        return true;

  return false;
}

bool CursorVisitor::VisitArrayTypeLoc(ArrayTypeLoc TL) {
  if (Visit(TL.getElementLoc()))
    return true;

  if (Expr *Size = TL.getSizeExpr())
    return Visit(MakeCXCursor(Size, StmtParent, TU, RegionOfInterest));

  return false;
}

bool CursorVisitor::VisitDecayedTypeLoc(DecayedTypeLoc TL) {
  return Visit(TL.getOriginalLoc());
}

bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
  return Visit(TL.getOriginalLoc());
}

bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
    DeducedTemplateSpecializationTypeLoc TL) {
  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
                        TL.getTemplateNameLoc()))
    return true;

  return false;
}

bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
    TemplateSpecializationTypeLoc TL) {
  // Visit the template name.
  if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
                        TL.getTemplateNameLoc()))
    return true;

  // Visit the template arguments.
  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
      return true;

  return false;
}

bool CursorVisitor::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
  return Visit(MakeCXCursor(TL.getUnderlyingExpr(), StmtParent, TU));
}

bool CursorVisitor::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) {
  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
    return Visit(TSInfo->getTypeLoc());

  return false;
}

bool CursorVisitor::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) {
  if (TypeSourceInfo *TSInfo = TL.getUnderlyingTInfo())
    return Visit(TSInfo->getTypeLoc());

  return false;
}

bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
  return VisitNestedNameSpecifierLoc(TL.getQualifierLoc());
}

bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
    DependentTemplateSpecializationTypeLoc TL) {
  // Visit the nested-name-specifier, if there is one.
  if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
    return true;

  // Visit the template arguments.
  for (unsigned I = 0, N = TL.getNumArgs(); I != N; ++I)
    if (VisitTemplateArgumentLoc(TL.getArgLoc(I)))
      return true;

  return false;
}

bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
  if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
    return true;

  return Visit(TL.getNamedTypeLoc());
}

bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
  return Visit(TL.getPatternLoc());
}

bool CursorVisitor::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) {
  if (Expr *E = TL.getUnderlyingExpr())
    return Visit(MakeCXCursor(E, StmtParent, TU));

  return false;
}

bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
  return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}

bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
  return Visit(TL.getValueLoc());
}

bool CursorVisitor::VisitPipeTypeLoc(PipeTypeLoc TL) {
  return Visit(TL.getValueLoc());
}

#define DEFAULT_TYPELOC_IMPL(CLASS, PARENT)                                    \
  bool CursorVisitor::Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) {               \
    return Visit##PARENT##Loc(TL);                                             \
  }

DEFAULT_TYPELOC_IMPL(Complex, Type)
DEFAULT_TYPELOC_IMPL(ConstantArray, ArrayType)
DEFAULT_TYPELOC_IMPL(IncompleteArray, ArrayType)
DEFAULT_TYPELOC_IMPL(VariableArray, ArrayType)
DEFAULT_TYPELOC_IMPL(DependentSizedArray, ArrayType)
DEFAULT_TYPELOC_IMPL(DependentAddressSpace, Type)
DEFAULT_TYPELOC_IMPL(DependentVector, Type)
DEFAULT_TYPELOC_IMPL(DependentSizedExtVector, Type)
DEFAULT_TYPELOC_IMPL(Vector, Type)
DEFAULT_TYPELOC_IMPL(ExtVector, VectorType)
DEFAULT_TYPELOC_IMPL(ConstantMatrix, MatrixType)
DEFAULT_TYPELOC_IMPL(DependentSizedMatrix, MatrixType)
DEFAULT_TYPELOC_IMPL(FunctionProto, FunctionType)
DEFAULT_TYPELOC_IMPL(FunctionNoProto, FunctionType)
DEFAULT_TYPELOC_IMPL(Record, TagType)
DEFAULT_TYPELOC_IMPL(Enum, TagType)
DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParm, Type)
DEFAULT_TYPELOC_IMPL(SubstTemplateTypeParmPack, Type)
DEFAULT_TYPELOC_IMPL(Auto, Type)
DEFAULT_TYPELOC_IMPL(ExtInt, Type)
DEFAULT_TYPELOC_IMPL(DependentExtInt, Type)

bool CursorVisitor::VisitCXXRecordDecl(CXXRecordDecl *D) {
  // Visit the nested-name-specifier, if present.
  if (NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc())
    if (VisitNestedNameSpecifierLoc(QualifierLoc))
      return true;

  if (D->isCompleteDefinition()) {
    for (const auto &I : D->bases()) {
      if (Visit(cxcursor::MakeCursorCXXBaseSpecifier(&I, TU)))
        return true;
    }
  }

  return VisitTagDecl(D);
}

bool CursorVisitor::VisitAttributes(Decl *D) {
  for (const auto *I : D->attrs())
    if ((TU->ParsingOptions & CXTranslationUnit_VisitImplicitAttributes ||
         !I->isImplicit()) &&
        Visit(MakeCXCursor(I, D, TU)))
      return true;

  return false;
}

//===----------------------------------------------------------------------===//
// Data-recursive visitor methods.
//===----------------------------------------------------------------------===//

namespace {
#define DEF_JOB(NAME, DATA, KIND)                                              \
  class NAME : public VisitorJob {                                             \
  public:                                                                      \
    NAME(const DATA *d, CXCursor parent)                                       \
        : VisitorJob(parent, VisitorJob::KIND, d) {}                           \
    static bool classof(const VisitorJob *VJ) {                                \
      return VJ->getKind() == KIND;                                            \
    }                                                                          \
    const DATA *get() const { return static_cast<const DATA *>(data[0]); }     \
  };

DEF_JOB(StmtVisit, Stmt, StmtVisitKind)
DEF_JOB(MemberExprParts, MemberExpr, MemberExprPartsKind)
DEF_JOB(DeclRefExprParts, DeclRefExpr, DeclRefExprPartsKind)
DEF_JOB(OverloadExprParts, OverloadExpr, OverloadExprPartsKind)
DEF_JOB(SizeOfPackExprParts, SizeOfPackExpr, SizeOfPackExprPartsKind)
DEF_JOB(LambdaExprParts, LambdaExpr, LambdaExprPartsKind)
DEF_JOB(PostChildrenVisit, void, PostChildrenVisitKind)
#undef DEF_JOB

class ExplicitTemplateArgsVisit : public VisitorJob {
public:
  ExplicitTemplateArgsVisit(const TemplateArgumentLoc *Begin,
                            const TemplateArgumentLoc *End, CXCursor parent)
      : VisitorJob(parent, VisitorJob::ExplicitTemplateArgsVisitKind, Begin,
                   End) {}
  static bool classof(const VisitorJob *VJ) {
    return VJ->getKind() == ExplicitTemplateArgsVisitKind;
  }
  const TemplateArgumentLoc *begin() const {
    return static_cast<const TemplateArgumentLoc *>(data[0]);
  }
  const TemplateArgumentLoc *end() {
    return static_cast<const TemplateArgumentLoc *>(data[1]);
  }
};
class DeclVisit : public VisitorJob {
public:
  DeclVisit(const Decl *D, CXCursor parent, bool isFirst)
      : VisitorJob(parent, VisitorJob::DeclVisitKind, D,
                   isFirst ? (void *)1 : (void *)nullptr) {}
  static bool classof(const VisitorJob *VJ) {
    return VJ->getKind() == DeclVisitKind;
  }
  const Decl *get() const { return static_cast<const Decl *>(data[0]); }
  bool isFirst() const { return data[1] != nullptr; }
};
class TypeLocVisit : public VisitorJob {
public:
  TypeLocVisit(TypeLoc tl, CXCursor parent)
      : VisitorJob(parent, VisitorJob::TypeLocVisitKind,
                   tl.getType().getAsOpaquePtr(), tl.getOpaqueData()) {}

  static bool classof(const VisitorJob *VJ) {
    return VJ->getKind() == TypeLocVisitKind;
  }

  TypeLoc get() const {
    QualType T = QualType::getFromOpaquePtr(data[0]);
    return TypeLoc(T, const_cast<void *>(data[1]));
  }
};

class LabelRefVisit : public VisitorJob {
public:
  LabelRefVisit(LabelDecl *LD, SourceLocation labelLoc, CXCursor parent)
      : VisitorJob(parent, VisitorJob::LabelRefVisitKind, LD,
                   labelLoc.getPtrEncoding()) {}

  static bool classof(const VisitorJob *VJ) {
    return VJ->getKind() == VisitorJob::LabelRefVisitKind;
  }
  const LabelDecl *get() const {
    return static_cast<const LabelDecl *>(data[0]);
  }
  SourceLocation getLoc() const {
    return SourceLocation::getFromPtrEncoding(data[1]);
  }
};

class NestedNameSpecifierLocVisit : public VisitorJob {
public:
  NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
      : VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
                   Qualifier.getNestedNameSpecifier(),
                   Qualifier.getOpaqueData()) {}

  static bool classof(const VisitorJob *VJ) {
    return VJ->getKind() == VisitorJob::NestedNameSpecifierLocVisitKind;
  }

  NestedNameSpecifierLoc get() const {
    return NestedNameSpecifierLoc(
        const_cast<NestedNameSpecifier *>(
            static_cast<const NestedNameSpecifier *>(data[0])),
        const_cast<void *>(data[1]));
  }
};

class DeclarationNameInfoVisit : public VisitorJob {
public:
  DeclarationNameInfoVisit(const Stmt *S, CXCursor parent)
      : VisitorJob(parent, VisitorJob::DeclarationNameInfoVisitKind, S) {}
  static bool classof(const VisitorJob *VJ) {
    return VJ->getKind() == VisitorJob::DeclarationNameInfoVisitKind;
  }
  DeclarationNameInfo get() const {
    const Stmt *S = static_cast<const Stmt *>(data[0]);
    switch (S->getStmtClass()) {
    default:
      llvm_unreachable("Unhandled Stmt");
    case clang::Stmt::MSDependentExistsStmtClass:
      return cast<MSDependentExistsStmt>(S)->getNameInfo();
    case Stmt::CXXDependentScopeMemberExprClass:
      return cast<CXXDependentScopeMemberExpr>(S)->getMemberNameInfo();
    case Stmt::DependentScopeDeclRefExprClass:
      return cast<DependentScopeDeclRefExpr>(S)->getNameInfo();
    case Stmt::OMPCriticalDirectiveClass:
      return cast<OMPCriticalDirective>(S)->getDirectiveName();
    }
  }
};
class MemberRefVisit : public VisitorJob {
public:
  MemberRefVisit(const FieldDecl *D, SourceLocation L, CXCursor parent)
      : VisitorJob(parent, VisitorJob::MemberRefVisitKind, D,
                   L.getPtrEncoding()) {}
  static bool classof(const VisitorJob *VJ) {
    return VJ->getKind() == VisitorJob::MemberRefVisitKind;
  }
  const FieldDecl *get() const {
    return static_cast<const FieldDecl *>(data[0]);
  }
  SourceLocation getLoc() const {
    return SourceLocation::getFromRawEncoding((unsigned)(uintptr_t)data[1]);
  }
};
class EnqueueVisitor : public ConstStmtVisitor<EnqueueVisitor, void> {
  friend class OMPClauseEnqueue;
  VisitorWorkList &WL;
  CXCursor Parent;

public:
  EnqueueVisitor(VisitorWorkList &wl, CXCursor parent)
      : WL(wl), Parent(parent) {}

  void VisitAddrLabelExpr(const AddrLabelExpr *E);
  void VisitBlockExpr(const BlockExpr *B);
  void VisitCompoundLiteralExpr(const CompoundLiteralExpr *E);
  void VisitCompoundStmt(const CompoundStmt *S);
  void VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *E) { /* Do nothing. */
  }
  void VisitMSDependentExistsStmt(const MSDependentExistsStmt *S);
  void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *E);
  void VisitCXXNewExpr(const CXXNewExpr *E);
  void VisitCXXScalarValueInitExpr(const CXXScalarValueInitExpr *E);
  void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *E);
  void VisitCXXPseudoDestructorExpr(const CXXPseudoDestructorExpr *E);
  void VisitCXXTemporaryObjectExpr(const CXXTemporaryObjectExpr *E);
  void VisitCXXTypeidExpr(const CXXTypeidExpr *E);
  void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *E);
  void VisitCXXUuidofExpr(const CXXUuidofExpr *E);
  void VisitCXXCatchStmt(const CXXCatchStmt *S);
  void VisitCXXForRangeStmt(const CXXForRangeStmt *S);
  void VisitDeclRefExpr(const DeclRefExpr *D);
  void VisitDeclStmt(const DeclStmt *S);
  void VisitDependentScopeDeclRefExpr(const DependentScopeDeclRefExpr *E);
  void VisitDesignatedInitExpr(const DesignatedInitExpr *E);
  void VisitExplicitCastExpr(const ExplicitCastExpr *E);
  void VisitForStmt(const ForStmt *FS);
  void VisitGotoStmt(const GotoStmt *GS);
  void VisitIfStmt(const IfStmt *If);
  void VisitInitListExpr(const InitListExpr *IE);
  void VisitMemberExpr(const MemberExpr *M);
  void VisitOffsetOfExpr(const OffsetOfExpr *E);
  void VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
  void VisitObjCMessageExpr(const ObjCMessageExpr *M);
  void VisitOverloadExpr(const OverloadExpr *E);
  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *E);
  void VisitStmt(const Stmt *S);
  void VisitSwitchStmt(const SwitchStmt *S);
  void VisitWhileStmt(const WhileStmt *W);
  void VisitTypeTraitExpr(const TypeTraitExpr *E);
  void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E);
  void VisitExpressionTraitExpr(const ExpressionTraitExpr *E);
  void VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U);
  void VisitVAArgExpr(const VAArgExpr *E);
  void VisitSizeOfPackExpr(const SizeOfPackExpr *E);
  void VisitPseudoObjectExpr(const PseudoObjectExpr *E);
  void VisitOpaqueValueExpr(const OpaqueValueExpr *E);
  void VisitLambdaExpr(const LambdaExpr *E);
  void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
  void VisitOMPLoopDirective(const OMPLoopDirective *D);
  void VisitOMPParallelDirective(const OMPParallelDirective *D);
  void VisitOMPSimdDirective(const OMPSimdDirective *D);
  void VisitOMPForDirective(const OMPForDirective *D);
  void VisitOMPForSimdDirective(const OMPForSimdDirective *D);
  void VisitOMPSectionsDirective(const OMPSectionsDirective *D);
  void VisitOMPSectionDirective(const OMPSectionDirective *D);
  void VisitOMPSingleDirective(const OMPSingleDirective *D);
  void VisitOMPMasterDirective(const OMPMasterDirective *D);
  void VisitOMPCriticalDirective(const OMPCriticalDirective *D);
  void VisitOMPParallelForDirective(const OMPParallelForDirective *D);
  void VisitOMPParallelForSimdDirective(const OMPParallelForSimdDirective *D);
  void VisitOMPParallelMasterDirective(const OMPParallelMasterDirective *D);
  void VisitOMPParallelSectionsDirective(const OMPParallelSectionsDirective *D);
  void VisitOMPTaskDirective(const OMPTaskDirective *D);
  void VisitOMPTaskyieldDirective(const OMPTaskyieldDirective *D);
  void VisitOMPBarrierDirective(const OMPBarrierDirective *D);
  void VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D);
  void VisitOMPTaskgroupDirective(const OMPTaskgroupDirective *D);
  void
  VisitOMPCancellationPointDirective(const OMPCancellationPointDirective *D);
  void VisitOMPCancelDirective(const OMPCancelDirective *D);
  void VisitOMPFlushDirective(const OMPFlushDirective *D);
  void VisitOMPDepobjDirective(const OMPDepobjDirective *D);
  void VisitOMPScanDirective(const OMPScanDirective *D);
  void VisitOMPOrderedDirective(const OMPOrderedDirective *D);
  void VisitOMPAtomicDirective(const OMPAtomicDirective *D);
  void VisitOMPTargetDirective(const OMPTargetDirective *D);
  void VisitOMPTargetDataDirective(const OMPTargetDataDirective *D);
  void VisitOMPTargetEnterDataDirective(const OMPTargetEnterDataDirective *D);
  void VisitOMPTargetExitDataDirective(const OMPTargetExitDataDirective *D);
  void VisitOMPTargetParallelDirective(const OMPTargetParallelDirective *D);
  void
  VisitOMPTargetParallelForDirective(const OMPTargetParallelForDirective *D);
  void VisitOMPTeamsDirective(const OMPTeamsDirective *D);
  void VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D);
  void VisitOMPTaskLoopSimdDirective(const OMPTaskLoopSimdDirective *D);
  void VisitOMPMasterTaskLoopDirective(const OMPMasterTaskLoopDirective *D);
  void
  VisitOMPMasterTaskLoopSimdDirective(const OMPMasterTaskLoopSimdDirective *D);
  void VisitOMPParallelMasterTaskLoopDirective(
      const OMPParallelMasterTaskLoopDirective *D);
  void VisitOMPParallelMasterTaskLoopSimdDirective(
      const OMPParallelMasterTaskLoopSimdDirective *D);
  void VisitOMPDistributeDirective(const OMPDistributeDirective *D);
  void VisitOMPDistributeParallelForDirective(
      const OMPDistributeParallelForDirective *D);
  void VisitOMPDistributeParallelForSimdDirective(
      const OMPDistributeParallelForSimdDirective *D);
  void VisitOMPDistributeSimdDirective(const OMPDistributeSimdDirective *D);
  void VisitOMPTargetParallelForSimdDirective(
      const OMPTargetParallelForSimdDirective *D);
  void VisitOMPTargetSimdDirective(const OMPTargetSimdDirective *D);
  void VisitOMPTeamsDistributeDirective(const OMPTeamsDistributeDirective *D);
  void VisitOMPTeamsDistributeSimdDirective(
      const OMPTeamsDistributeSimdDirective *D);
  void VisitOMPTeamsDistributeParallelForSimdDirective(
      const OMPTeamsDistributeParallelForSimdDirective *D);
  void VisitOMPTeamsDistributeParallelForDirective(
      const OMPTeamsDistributeParallelForDirective *D);
  void VisitOMPTargetTeamsDirective(const OMPTargetTeamsDirective *D);
  void VisitOMPTargetTeamsDistributeDirective(
      const OMPTargetTeamsDistributeDirective *D);
  void VisitOMPTargetTeamsDistributeParallelForDirective(
      const OMPTargetTeamsDistributeParallelForDirective *D);
  void VisitOMPTargetTeamsDistributeParallelForSimdDirective(
      const OMPTargetTeamsDistributeParallelForSimdDirective *D);
  void VisitOMPTargetTeamsDistributeSimdDirective(
      const OMPTargetTeamsDistributeSimdDirective *D);

private:
  void AddDeclarationNameInfo(const Stmt *S);
  void AddNestedNameSpecifierLoc(NestedNameSpecifierLoc Qualifier);
  void AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
                               unsigned NumTemplateArgs);
  void AddMemberRef(const FieldDecl *D, SourceLocation L);
  void AddStmt(const Stmt *S);
  void AddDecl(const Decl *D, bool isFirst = true);
  void AddTypeLoc(TypeSourceInfo *TI);
  void EnqueueChildren(const Stmt *S);
  void EnqueueChildren(const OMPClause *S);
};
} // namespace

void EnqueueVisitor::AddDeclarationNameInfo(const Stmt *S) {
  // 'S' should always be non-null, since it comes from the
  // statement we are visiting.
  WL.push_back(DeclarationNameInfoVisit(S, Parent));
}

void EnqueueVisitor::AddNestedNameSpecifierLoc(
    NestedNameSpecifierLoc Qualifier) {
  if (Qualifier)
    WL.push_back(NestedNameSpecifierLocVisit(Qualifier, Parent));
}

void EnqueueVisitor::AddStmt(const Stmt *S) {
  if (S)
    WL.push_back(StmtVisit(S, Parent));
}
void EnqueueVisitor::AddDecl(const Decl *D, bool isFirst) {
  if (D)
    WL.push_back(DeclVisit(D, Parent, isFirst));
}
void EnqueueVisitor::AddExplicitTemplateArgs(const TemplateArgumentLoc *A,
                                             unsigned NumTemplateArgs) {
  WL.push_back(ExplicitTemplateArgsVisit(A, A + NumTemplateArgs, Parent));
}
void EnqueueVisitor::AddMemberRef(const FieldDecl *D, SourceLocation L) {
  if (D)
    WL.push_back(MemberRefVisit(D, L, Parent));
}
void EnqueueVisitor::AddTypeLoc(TypeSourceInfo *TI) {
  if (TI)
    WL.push_back(TypeLocVisit(TI->getTypeLoc(), Parent));
}
void EnqueueVisitor::EnqueueChildren(const Stmt *S) {
  unsigned size = WL.size();
  for (const Stmt *SubStmt : S->children()) {
    AddStmt(SubStmt);
  }
  if (size == WL.size())
    return;
  // Now reverse the entries we just added.  This will match the DFS
  // ordering performed by the worklist.
  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
  std::reverse(I, E);
}
namespace {
class OMPClauseEnqueue : public ConstOMPClauseVisitor<OMPClauseEnqueue> {
  EnqueueVisitor *Visitor;
  /// Process clauses with list of variables.
  template <typename T> void VisitOMPClauseList(T *Node);

public:
  OMPClauseEnqueue(EnqueueVisitor *Visitor) : Visitor(Visitor) {}
#define OMP_CLAUSE_CLASS(Enum, Str, Class) void Visit##Class(const Class *C);
#include "llvm/Frontend/OpenMP/OMPKinds.def"
  void VisitOMPClauseWithPreInit(const OMPClauseWithPreInit *C);
  void VisitOMPClauseWithPostUpdate(const OMPClauseWithPostUpdate *C);
};

void OMPClauseEnqueue::VisitOMPClauseWithPreInit(
    const OMPClauseWithPreInit *C) {
  Visitor->AddStmt(C->getPreInitStmt());
}

void OMPClauseEnqueue::VisitOMPClauseWithPostUpdate(
    const OMPClauseWithPostUpdate *C) {
  VisitOMPClauseWithPreInit(C);
  Visitor->AddStmt(C->getPostUpdateExpr());
}

void OMPClauseEnqueue::VisitOMPIfClause(const OMPIfClause *C) {
  VisitOMPClauseWithPreInit(C);
  Visitor->AddStmt(C->getCondition());
}

void OMPClauseEnqueue::VisitOMPFinalClause(const OMPFinalClause *C) {
  Visitor->AddStmt(C->getCondition());
}

void OMPClauseEnqueue::VisitOMPNumThreadsClause(const OMPNumThreadsClause *C) {
  VisitOMPClauseWithPreInit(C);
  Visitor->AddStmt(C->getNumThreads());
}

void OMPClauseEnqueue::VisitOMPSafelenClause(const OMPSafelenClause *C) {
  Visitor->AddStmt(C->getSafelen());
}

void OMPClauseEnqueue::VisitOMPSimdlenClause(const OMPSimdlenClause *C) {
  Visitor->AddStmt(C->getSimdlen());
}

void OMPClauseEnqueue::VisitOMPAllocatorClause(const OMPAllocatorClause *C) {
  Visitor->AddStmt(C->getAllocator());
}

void OMPClauseEnqueue::VisitOMPCollapseClause(const OMPCollapseClause *C) {
  Visitor->AddStmt(C->getNumForLoops());
}

void OMPClauseEnqueue::VisitOMPDefaultClause(const OMPDefaultClause *C) {}

void OMPClauseEnqueue::VisitOMPProcBindClause(const OMPProcBindClause *C) {}

void OMPClauseEnqueue::VisitOMPScheduleClause(const OMPScheduleClause *C) {
  VisitOMPClauseWithPreInit(C);
  Visitor->AddStmt(C->getChunkSize());
}

void OMPClauseEnqueue::VisitOMPOrderedClause(const OMPOrderedClause *C) {
  Visitor->AddStmt(C->getNumForLoops());
}

void OMPClauseEnqueue::VisitOMPDetachClause(const OMPDetachClause *C) {
  Visitor->AddStmt(C->getEventHandler());
}

void OMPClauseEnqueue::VisitOMPNowaitClause(const OMPNowaitClause *) {}

void OMPClauseEnqueue::VisitOMPUntiedClause(const OMPUntiedClause *) {}

void OMPClauseEnqueue::VisitOMPMergeableClause(const OMPMergeableClause *) {}

void OMPClauseEnqueue::VisitOMPReadClause(const OMPReadClause *) {}

void OMPClauseEnqueue::VisitOMPWriteClause(const OMPWriteClause *) {}

void OMPClauseEnqueue::VisitOMPUpdateClause(const OMPUpdateClause *) {}

void OMPClauseEnqueue::VisitOMPCaptureClause(const OMPCaptureClause *) {}

void OMPClauseEnqueue::VisitOMPSeqCstClause(const OMPSeqCstClause *) {}

void OMPClauseEnqueue::VisitOMPAcqRelClause(const OMPAcqRelClause *) {}

void OMPClauseEnqueue::VisitOMPAcquireClause(const OMPAcquireClause *) {}

void OMPClauseEnqueue::VisitOMPReleaseClause(const OMPReleaseClause *) {}

void OMPClauseEnqueue::VisitOMPRelaxedClause(const OMPRelaxedClause *) {}

void OMPClauseEnqueue::VisitOMPThreadsClause(const OMPThreadsClause *) {}

void OMPClauseEnqueue::VisitOMPSIMDClause(const OMPSIMDClause *) {}

void OMPClauseEnqueue::VisitOMPNogroupClause(const OMPNogroupClause *) {}

void OMPClauseEnqueue::VisitOMPDestroyClause(const OMPDestroyClause *) {}

void OMPClauseEnqueue::VisitOMPUnifiedAddressClause(
    const OMPUnifiedAddressClause *) {}

void OMPClauseEnqueue::VisitOMPUnifiedSharedMemoryClause(
    const OMPUnifiedSharedMemoryClause *) {}

void OMPClauseEnqueue::VisitOMPReverseOffloadClause(
    const OMPReverseOffloadClause *) {}

void OMPClauseEnqueue::VisitOMPDynamicAllocatorsClause(
    const OMPDynamicAllocatorsClause *) {}

void OMPClauseEnqueue::VisitOMPAtomicDefaultMemOrderClause(
    const OMPAtomicDefaultMemOrderClause *) {}

void OMPClauseEnqueue::VisitOMPDeviceClause(const OMPDeviceClause *C) {
  Visitor->AddStmt(C->getDevice());
}

void OMPClauseEnqueue::VisitOMPNumTeamsClause(const OMPNumTeamsClause *C) {
  VisitOMPClauseWithPreInit(C);
  Visitor->AddStmt(C->getNumTeams());
}

void OMPClauseEnqueue::VisitOMPThreadLimitClause(
    const OMPThreadLimitClause *C) {
  VisitOMPClauseWithPreInit(C);
  Visitor->AddStmt(C->getThreadLimit());
}

void OMPClauseEnqueue::VisitOMPPriorityClause(const OMPPriorityClause *C) {
  Visitor->AddStmt(C->getPriority());
}

void OMPClauseEnqueue::VisitOMPGrainsizeClause(const OMPGrainsizeClause *C) {
  Visitor->AddStmt(C->getGrainsize());
}

void OMPClauseEnqueue::VisitOMPNumTasksClause(const OMPNumTasksClause *C) {
  Visitor->AddStmt(C->getNumTasks());
}

void OMPClauseEnqueue::VisitOMPHintClause(const OMPHintClause *C) {
  Visitor->AddStmt(C->getHint());
}

template <typename T> void OMPClauseEnqueue::VisitOMPClauseList(T *Node) {
  for (const auto *I : Node->varlists()) {
    Visitor->AddStmt(I);
  }
}

void OMPClauseEnqueue::VisitOMPInclusiveClause(const OMPInclusiveClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPExclusiveClause(const OMPExclusiveClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPAllocateClause(const OMPAllocateClause *C) {
  VisitOMPClauseList(C);
  Visitor->AddStmt(C->getAllocator());
}
void OMPClauseEnqueue::VisitOMPPrivateClause(const OMPPrivateClause *C) {
  VisitOMPClauseList(C);
  for (const auto *E : C->private_copies()) {
    Visitor->AddStmt(E);
  }
}
void OMPClauseEnqueue::VisitOMPFirstprivateClause(
    const OMPFirstprivateClause *C) {
  VisitOMPClauseList(C);
  VisitOMPClauseWithPreInit(C);
  for (const auto *E : C->private_copies()) {
    Visitor->AddStmt(E);
  }
  for (const auto *E : C->inits()) {
    Visitor->AddStmt(E);
  }
}
void OMPClauseEnqueue::VisitOMPLastprivateClause(
    const OMPLastprivateClause *C) {
  VisitOMPClauseList(C);
  VisitOMPClauseWithPostUpdate(C);
  for (auto *E : C->private_copies()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->source_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->destination_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->assignment_ops()) {
    Visitor->AddStmt(E);
  }
}
void OMPClauseEnqueue::VisitOMPSharedClause(const OMPSharedClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
  VisitOMPClauseList(C);
  VisitOMPClauseWithPostUpdate(C);
  for (auto *E : C->privates()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->lhs_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->rhs_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->reduction_ops()) {
    Visitor->AddStmt(E);
  }
  if (C->getModifier() == clang::OMPC_REDUCTION_inscan) {
    for (auto *E : C->copy_ops()) {
      Visitor->AddStmt(E);
    }
    for (auto *E : C->copy_array_temps()) {
      Visitor->AddStmt(E);
    }
    for (auto *E : C->copy_array_elems()) {
      Visitor->AddStmt(E);
    }
  }
}
void OMPClauseEnqueue::VisitOMPTaskReductionClause(
    const OMPTaskReductionClause *C) {
  VisitOMPClauseList(C);
  VisitOMPClauseWithPostUpdate(C);
  for (auto *E : C->privates()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->lhs_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->rhs_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->reduction_ops()) {
    Visitor->AddStmt(E);
  }
}
void OMPClauseEnqueue::VisitOMPInReductionClause(
    const OMPInReductionClause *C) {
  VisitOMPClauseList(C);
  VisitOMPClauseWithPostUpdate(C);
  for (auto *E : C->privates()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->lhs_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->rhs_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->reduction_ops()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->taskgroup_descriptors())
    Visitor->AddStmt(E);
}
void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
  VisitOMPClauseList(C);
  VisitOMPClauseWithPostUpdate(C);
  for (const auto *E : C->privates()) {
    Visitor->AddStmt(E);
  }
  for (const auto *E : C->inits()) {
    Visitor->AddStmt(E);
  }
  for (const auto *E : C->updates()) {
    Visitor->AddStmt(E);
  }
  for (const auto *E : C->finals()) {
    Visitor->AddStmt(E);
  }
  Visitor->AddStmt(C->getStep());
  Visitor->AddStmt(C->getCalcStep());
}
void OMPClauseEnqueue::VisitOMPAlignedClause(const OMPAlignedClause *C) {
  VisitOMPClauseList(C);
  Visitor->AddStmt(C->getAlignment());
}
void OMPClauseEnqueue::VisitOMPCopyinClause(const OMPCopyinClause *C) {
  VisitOMPClauseList(C);
  for (auto *E : C->source_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->destination_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->assignment_ops()) {
    Visitor->AddStmt(E);
  }
}
void OMPClauseEnqueue::VisitOMPCopyprivateClause(
    const OMPCopyprivateClause *C) {
  VisitOMPClauseList(C);
  for (auto *E : C->source_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->destination_exprs()) {
    Visitor->AddStmt(E);
  }
  for (auto *E : C->assignment_ops()) {
    Visitor->AddStmt(E);
  }
}
void OMPClauseEnqueue::VisitOMPFlushClause(const OMPFlushClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPDepobjClause(const OMPDepobjClause *C) {
  Visitor->AddStmt(C->getDepobj());
}
void OMPClauseEnqueue::VisitOMPDependClause(const OMPDependClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPMapClause(const OMPMapClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPDistScheduleClause(
    const OMPDistScheduleClause *C) {
  VisitOMPClauseWithPreInit(C);
  Visitor->AddStmt(C->getChunkSize());
}
void OMPClauseEnqueue::VisitOMPDefaultmapClause(
    const OMPDefaultmapClause * /*C*/) {}
void OMPClauseEnqueue::VisitOMPToClause(const OMPToClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPFromClause(const OMPFromClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPUseDevicePtrClause(
    const OMPUseDevicePtrClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPUseDeviceAddrClause(
    const OMPUseDeviceAddrClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPIsDevicePtrClause(
    const OMPIsDevicePtrClause *C) {
  VisitOMPClauseList(C);
}
void OMPClauseEnqueue::VisitOMPNontemporalClause(
    const OMPNontemporalClause *C) {
  VisitOMPClauseList(C);
  for (const auto *E : C->private_refs())
    Visitor->AddStmt(E);
}
void OMPClauseEnqueue::VisitOMPOrderClause(const OMPOrderClause *C) {}
void OMPClauseEnqueue::VisitOMPUsesAllocatorsClause(
    const OMPUsesAllocatorsClause *C) {
  for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
    const OMPUsesAllocatorsClause::Data &D = C->getAllocatorData(I);
    Visitor->AddStmt(D.Allocator);
    Visitor->AddStmt(D.AllocatorTraits);
  }
}
void OMPClauseEnqueue::VisitOMPAffinityClause(const OMPAffinityClause *C) {
  Visitor->AddStmt(C->getModifier());
  for (const Expr *E : C->varlists())
    Visitor->AddStmt(E);
}
} // namespace

void EnqueueVisitor::EnqueueChildren(const OMPClause *S) {
  unsigned size = WL.size();
  OMPClauseEnqueue Visitor(this);
  Visitor.Visit(S);
  if (size == WL.size())
    return;
  // Now reverse the entries we just added.  This will match the DFS
  // ordering performed by the worklist.
  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
  std::reverse(I, E);
}
void EnqueueVisitor::VisitAddrLabelExpr(const AddrLabelExpr *E) {
  WL.push_back(LabelRefVisit(E->getLabel(), E->getLabelLoc(), Parent));
}
void EnqueueVisitor::VisitBlockExpr(const BlockExpr *B) {
  AddDecl(B->getBlockDecl());
}
void EnqueueVisitor::VisitCompoundLiteralExpr(const CompoundLiteralExpr *E) {
  EnqueueChildren(E);
  AddTypeLoc(E->getTypeSourceInfo());
}
void EnqueueVisitor::VisitCompoundStmt(const CompoundStmt *S) {
  for (auto &I : llvm::reverse(S->body()))
    AddStmt(I);
}
void EnqueueVisitor::VisitMSDependentExistsStmt(
    const MSDependentExistsStmt *S) {
  AddStmt(S->getSubStmt());
  AddDeclarationNameInfo(S);
  if (NestedNameSpecifierLoc QualifierLoc = S->getQualifierLoc())
    AddNestedNameSpecifierLoc(QualifierLoc);
}

void EnqueueVisitor::VisitCXXDependentScopeMemberExpr(
    const CXXDependentScopeMemberExpr *E) {
  if (E->hasExplicitTemplateArgs())
    AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
  AddDeclarationNameInfo(E);
  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
    AddNestedNameSpecifierLoc(QualifierLoc);
  if (!E->isImplicitAccess())
    AddStmt(E->getBase());
}
void EnqueueVisitor::VisitCXXNewExpr(const CXXNewExpr *E) {
  // Enqueue the initializer , if any.
  AddStmt(E->getInitializer());
  // Enqueue the array size, if any.
  AddStmt(E->getArraySize().getValueOr(nullptr));
  // Enqueue the allocated type.
  AddTypeLoc(E->getAllocatedTypeSourceInfo());
  // Enqueue the placement arguments.
  for (unsigned I = E->getNumPlacementArgs(); I > 0; --I)
    AddStmt(E->getPlacementArg(I - 1));
}
void EnqueueVisitor::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *CE) {
  for (unsigned I = CE->getNumArgs(); I > 1 /* Yes, this is 1 */; --I)
    AddStmt(CE->getArg(I - 1));
  AddStmt(CE->getCallee());
  AddStmt(CE->getArg(0));
}
void EnqueueVisitor::VisitCXXPseudoDestructorExpr(
    const CXXPseudoDestructorExpr *E) {
  // Visit the name of the type being destroyed.
  AddTypeLoc(E->getDestroyedTypeInfo());
  // Visit the scope type that looks disturbingly like the nested-name-specifier
  // but isn't.
  AddTypeLoc(E->getScopeTypeInfo());
  // Visit the nested-name-specifier.
  if (NestedNameSpecifierLoc QualifierLoc = E->getQualifierLoc())
    AddNestedNameSpecifierLoc(QualifierLoc);
  // Visit base expression.
  AddStmt(E->getBase());
}
void EnqueueVisitor::VisitCXXScalarValueInitExpr(
    const CXXScalarValueInitExpr *E) {
  AddTypeLoc(E->getTypeSourceInfo());
}
void EnqueueVisitor::VisitCXXTemporaryObjectExpr(
    const CXXTemporaryObjectExpr *E) {
  EnqueueChildren(E);
  AddTypeLoc(E->getTypeSourceInfo());
}
void EnqueueVisitor::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
  EnqueueChildren(E);
  if (E->isTypeOperand())
    AddTypeLoc(E->getTypeOperandSourceInfo());
}

void EnqueueVisitor::VisitCXXUnresolvedConstructExpr(
    const CXXUnresolvedConstructExpr *E) {
  EnqueueChildren(E);
  AddTypeLoc(E->getTypeSourceInfo());
}
void EnqueueVisitor::VisitCXXUuidofExpr(const CXXUuidofExpr *E) {
  EnqueueChildren(E);
  if (E->isTypeOperand())
    AddTypeLoc(E->getTypeOperandSourceInfo());
}

void EnqueueVisitor::VisitCXXCatchStmt(const CXXCatchStmt *S) {
  EnqueueChildren(S);
  AddDecl(S->getExceptionDecl());
}

void EnqueueVisitor::VisitCXXForRangeStmt(const CXXForRangeStmt *S) {
  AddStmt(S->getBody());
  AddStmt(S->getRangeInit());
  AddDecl(S->getLoopVariable());
}

void EnqueueVisitor::VisitDeclRefExpr(const DeclRefExpr *DR) {
  if (DR->hasExplicitTemplateArgs())
    AddExplicitTemplateArgs(DR->getTemplateArgs(), DR->getNumTemplateArgs());
  WL.push_back(DeclRefExprParts(DR, Parent));
}
void EnqueueVisitor::VisitDependentScopeDeclRefExpr(
    const DependentScopeDeclRefExpr *E) {
  if (E->hasExplicitTemplateArgs())
    AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
  AddDeclarationNameInfo(E);
  AddNestedNameSpecifierLoc(E->getQualifierLoc());
}
void EnqueueVisitor::VisitDeclStmt(const DeclStmt *S) {
  unsigned size = WL.size();
  bool isFirst = true;
  for (const auto *D : S->decls()) {
    AddDecl(D, isFirst);
    isFirst = false;
  }
  if (size == WL.size())
    return;
  // Now reverse the entries we just added.  This will match the DFS
  // ordering performed by the worklist.
  VisitorWorkList::iterator I = WL.begin() + size, E = WL.end();
  std::reverse(I, E);
}
void EnqueueVisitor::VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
  AddStmt(E->getInit());
  for (const DesignatedInitExpr::Designator &D :
       llvm::reverse(E->designators())) {
    if (D.isFieldDesignator()) {
      if (FieldDecl *Field = D.getField())
        AddMemberRef(Field, D.getFieldLoc());
      continue;
    }
    if (D.isArrayDesignator()) {
      AddStmt(E->getArrayIndex(D));
      continue;
    }
    assert(D.isArrayRangeDesignator() && "Unknown designator kind");
    AddStmt(E->getArrayRangeEnd(D));
    AddStmt(E->getArrayRangeStart(D));
  }
}
void EnqueueVisitor::VisitExplicitCastExpr(const ExplicitCastExpr *E) {
  EnqueueChildren(E);
  AddTypeLoc(E->getTypeInfoAsWritten());
}
void EnqueueVisitor::VisitForStmt(const ForStmt *FS) {
  AddStmt(FS->getBody());
  AddStmt(FS->getInc());
  AddStmt(FS->getCond());
  AddDecl(FS->getConditionVariable());
  AddStmt(FS->getInit());
}
void EnqueueVisitor::VisitGotoStmt(const GotoStmt *GS) {
  WL.push_back(LabelRefVisit(GS->getLabel(), GS->getLabelLoc(), Parent));
}
void EnqueueVisitor::VisitIfStmt(const IfStmt *If) {
  AddStmt(If->getElse());
  AddStmt(If->getThen());
  AddStmt(If->getCond());
  AddStmt(If->getInit());
  AddDecl(If->getConditionVariable());
}
void EnqueueVisitor::VisitInitListExpr(const InitListExpr *IE) {
  // We care about the syntactic form of the initializer list, only.
  if (InitListExpr *Syntactic = IE->getSyntacticForm())
    IE = Syntactic;
  EnqueueChildren(IE);
}
void EnqueueVisitor::VisitMemberExpr(const MemberExpr *M) {
  WL.push_back(MemberExprParts(M, Parent));

  // If the base of the member access expression is an implicit 'this', don't
  // visit it.
  // FIXME: If we ever want to show these implicit accesses, this will be
  // unfortunate. However, clang_getCursor() relies on this behavior.
  if (M->isImplicitAccess())
    return;

  // Ignore base anonymous struct/union fields, otherwise they will shadow the
  // real field that we are interested in.
  if (auto *SubME = dyn_cast<MemberExpr>(M->getBase())) {
    if (auto *FD = dyn_cast_or_null<FieldDecl>(SubME->getMemberDecl())) {
      if (FD->isAnonymousStructOrUnion()) {
        AddStmt(SubME->getBase());
        return;
      }
    }
  }

  AddStmt(M->getBase());
}
void EnqueueVisitor::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
  AddTypeLoc(E->getEncodedTypeSourceInfo());
}
void EnqueueVisitor::VisitObjCMessageExpr(const ObjCMessageExpr *M) {
  EnqueueChildren(M);
  AddTypeLoc(M->getClassReceiverTypeInfo());
}
void EnqueueVisitor::VisitOffsetOfExpr(const OffsetOfExpr *E) {
  // Visit the components of the offsetof expression.
  for (unsigned N = E->getNumComponents(), I = N; I > 0; --I) {
    const OffsetOfNode &Node = E->getComponent(I - 1);
    switch (Node.getKind()) {
    case OffsetOfNode::Array:
      AddStmt(E->getIndexExpr(Node.getArrayExprIndex()));
      break;
    case OffsetOfNode::Field:
      AddMemberRef(Node.getField(), Node.getSourceRange().getEnd());
      break;
    case OffsetOfNode::Identifier:
    case OffsetOfNode::Base:
      continue;
    }
  }
  // Visit the type into which we're computing the offset.
  AddTypeLoc(E->getTypeSourceInfo());
}
void EnqueueVisitor::VisitOverloadExpr(const OverloadExpr *E) {
  if (E->hasExplicitTemplateArgs())
    AddExplicitTemplateArgs(E->getTemplateArgs(), E->getNumTemplateArgs());
  WL.push_back(OverloadExprParts(E, Parent));
}
void EnqueueVisitor::VisitUnaryExprOrTypeTraitExpr(
    const UnaryExprOrTypeTraitExpr *E) {
  EnqueueChildren(E);
  if (E->isArgumentType())
    AddTypeLoc(E->getArgumentTypeInfo());
}
void EnqueueVisitor::VisitStmt(const Stmt *S) { EnqueueChildren(S); }
void EnqueueVisitor::VisitSwitchStmt(const SwitchStmt *S) {
  AddStmt(S->getBody());
  AddStmt(S->getCond());
  AddDecl(S->getConditionVariable());
}

void EnqueueVisitor::VisitWhileStmt(const WhileStmt *W) {
  AddStmt(W->getBody());
  AddStmt(W->getCond());
  AddDecl(W->getConditionVariable());
}

void EnqueueVisitor::VisitTypeTraitExpr(const TypeTraitExpr *E) {
  for (unsigned I = E->getNumArgs(); I > 0; --I)
    AddTypeLoc(E->getArg(I - 1));
}

void EnqueueVisitor::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *E) {
  AddTypeLoc(E->getQueriedTypeSourceInfo());
}

void EnqueueVisitor::VisitExpressionTraitExpr(const ExpressionTraitExpr *E) {
  EnqueueChildren(E);
}

void EnqueueVisitor::VisitUnresolvedMemberExpr(const UnresolvedMemberExpr *U) {
  VisitOverloadExpr(U);
  if (!U->isImplicitAccess())
    AddStmt(U->getBase());
}
void EnqueueVisitor::VisitVAArgExpr(const VAArgExpr *E) {
  AddStmt(E->getSubExpr());
  AddTypeLoc(E->getWrittenTypeInfo());
}
void EnqueueVisitor::VisitSizeOfPackExpr(const SizeOfPackExpr *E) {
  WL.push_back(SizeOfPackExprParts(E, Parent));
}
void EnqueueVisitor::VisitOpaqueValueExpr(const OpaqueValueExpr *E) {
  // If the opaque value has a source expression, just transparently
  // visit that.  This is useful for (e.g.) pseudo-object expressions.
  if (Expr *SourceExpr = E->getSourceExpr())
    return Visit(SourceExpr);
}
void EnqueueVisitor::VisitLambdaExpr(const LambdaExpr *E) {
  AddStmt(E->getBody());
  WL.push_back(LambdaExprParts(E, Parent));
}
void EnqueueVisitor::VisitPseudoObjectExpr(const PseudoObjectExpr *E) {
  // Treat the expression like its syntactic form.
  Visit(E->getSyntacticForm());
}

void EnqueueVisitor::VisitOMPExecutableDirective(
    const OMPExecutableDirective *D) {
  EnqueueChildren(D);
  for (ArrayRef<OMPClause *>::iterator I = D->clauses().begin(),
                                       E = D->clauses().end();
       I != E; ++I)
    EnqueueChildren(*I);
}

void EnqueueVisitor::VisitOMPLoopDirective(const OMPLoopDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPParallelDirective(const OMPParallelDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPSimdDirective(const OMPSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPForDirective(const OMPForDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPForSimdDirective(const OMPForSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPSectionsDirective(const OMPSectionsDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPSectionDirective(const OMPSectionDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPSingleDirective(const OMPSingleDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPMasterDirective(const OMPMasterDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPCriticalDirective(const OMPCriticalDirective *D) {
  VisitOMPExecutableDirective(D);
  AddDeclarationNameInfo(D);
}

void EnqueueVisitor::VisitOMPParallelForDirective(
    const OMPParallelForDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPParallelForSimdDirective(
    const OMPParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPParallelMasterDirective(
    const OMPParallelMasterDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPParallelSectionsDirective(
    const OMPParallelSectionsDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTaskDirective(const OMPTaskDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTaskyieldDirective(
    const OMPTaskyieldDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPBarrierDirective(const OMPBarrierDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTaskwaitDirective(const OMPTaskwaitDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTaskgroupDirective(
    const OMPTaskgroupDirective *D) {
  VisitOMPExecutableDirective(D);
  if (const Expr *E = D->getReductionRef())
    VisitStmt(E);
}

void EnqueueVisitor::VisitOMPFlushDirective(const OMPFlushDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPDepobjDirective(const OMPDepobjDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPScanDirective(const OMPScanDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPOrderedDirective(const OMPOrderedDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPAtomicDirective(const OMPAtomicDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTargetDirective(const OMPTargetDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTargetDataDirective(
    const OMPTargetDataDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTargetEnterDataDirective(
    const OMPTargetEnterDataDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTargetExitDataDirective(
    const OMPTargetExitDataDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTargetParallelDirective(
    const OMPTargetParallelDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTargetParallelForDirective(
    const OMPTargetParallelForDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTeamsDirective(const OMPTeamsDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPCancellationPointDirective(
    const OMPCancellationPointDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPCancelDirective(const OMPCancelDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTaskLoopDirective(const OMPTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTaskLoopSimdDirective(
    const OMPTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPMasterTaskLoopDirective(
    const OMPMasterTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPMasterTaskLoopSimdDirective(
    const OMPMasterTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPParallelMasterTaskLoopDirective(
    const OMPParallelMasterTaskLoopDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPParallelMasterTaskLoopSimdDirective(
    const OMPParallelMasterTaskLoopSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPDistributeDirective(
    const OMPDistributeDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPDistributeParallelForDirective(
    const OMPDistributeParallelForDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPDistributeParallelForSimdDirective(
    const OMPDistributeParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPDistributeSimdDirective(
    const OMPDistributeSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTargetParallelForSimdDirective(
    const OMPTargetParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTargetSimdDirective(
    const OMPTargetSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTeamsDistributeDirective(
    const OMPTeamsDistributeDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTeamsDistributeSimdDirective(
    const OMPTeamsDistributeSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTeamsDistributeParallelForSimdDirective(
    const OMPTeamsDistributeParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTeamsDistributeParallelForDirective(
    const OMPTeamsDistributeParallelForDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTargetTeamsDirective(
    const OMPTargetTeamsDirective *D) {
  VisitOMPExecutableDirective(D);
}

void EnqueueVisitor::VisitOMPTargetTeamsDistributeDirective(
    const OMPTargetTeamsDistributeDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForDirective(
    const OMPTargetTeamsDistributeParallelForDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTargetTeamsDistributeParallelForSimdDirective(
    const OMPTargetTeamsDistributeParallelForSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void EnqueueVisitor::VisitOMPTargetTeamsDistributeSimdDirective(
    const OMPTargetTeamsDistributeSimdDirective *D) {
  VisitOMPLoopDirective(D);
}

void CursorVisitor::EnqueueWorkList(VisitorWorkList &WL, const Stmt *S) {
  EnqueueVisitor(WL, MakeCXCursor(S, StmtParent, TU, RegionOfInterest))
      .Visit(S);
}

bool CursorVisitor::IsInRegionOfInterest(CXCursor C) {
  if (RegionOfInterest.isValid()) {
    SourceRange Range = getRawCursorExtent(C);
    if (Range.isInvalid() || CompareRegionOfInterest(Range))
      return false;
  }
  return true;
}

bool CursorVisitor::RunVisitorWorkList(VisitorWorkList &WL) {
  while (!WL.empty()) {
    // Dequeue the worklist item.
    VisitorJob LI = WL.pop_back_val();

    // Set the Parent field, then back to its old value once we're done.
    SetParentRAII SetParent(Parent, StmtParent, LI.getParent());

    switch (LI.getKind()) {
    case VisitorJob::DeclVisitKind: {
      const Decl *D = cast<DeclVisit>(&LI)->get();
      if (!D)
        continue;

      // For now, perform default visitation for Decls.
      if (Visit(MakeCXCursor(D, TU, RegionOfInterest,
                             cast<DeclVisit>(&LI)->isFirst())))
        return true;

      continue;
    }
    case VisitorJob::ExplicitTemplateArgsVisitKind: {
      for (const TemplateArgumentLoc &Arg :
           *cast<ExplicitTemplateArgsVisit>(&LI)) {
        if (VisitTemplateArgumentLoc(Arg))
          return true;
      }
      continue;
    }
    case VisitorJob::TypeLocVisitKind: {
      // Perform default visitation for TypeLocs.
      if (Visit(cast<TypeLocVisit>(&LI)->get()))
        return true;
      continue;
    }
    case VisitorJob::LabelRefVisitKind: {
      const LabelDecl *LS = cast<LabelRefVisit>(&LI)->get();
      if (LabelStmt *stmt = LS->getStmt()) {
        if (Visit(MakeCursorLabelRef(stmt, cast<LabelRefVisit>(&LI)->getLoc(),
                                     TU))) {
          return true;
        }
      }
      continue;
    }

    case VisitorJob::NestedNameSpecifierLocVisitKind: {
      NestedNameSpecifierLocVisit *V = cast<NestedNameSpecifierLocVisit>(&LI);
      if (VisitNestedNameSpecifierLoc(V->get()))
        return true;
      continue;
    }

    case VisitorJob::DeclarationNameInfoVisitKind: {
      if (VisitDeclarationNameInfo(cast<DeclarationNameInfoVisit>(&LI)->get()))
        return true;
      continue;
    }
    case VisitorJob::MemberRefVisitKind: {
      MemberRefVisit *V = cast<MemberRefVisit>(&LI);
      if (Visit(MakeCursorMemberRef(V->get(), V->getLoc(), TU)))
        return true;
      continue;
    }
    case VisitorJob::StmtVisitKind: {
      const Stmt *S = cast<StmtVisit>(&LI)->get();
      if (!S)
        continue;

      // Update the current cursor.
      CXCursor Cursor = MakeCXCursor(S, StmtParent, TU, RegionOfInterest);
      if (!IsInRegionOfInterest(Cursor))
        continue;
      switch (Visitor(Cursor, Parent, ClientData)) {
      case CXChildVisit_Break:
        return true;
      case CXChildVisit_Continue:
        break;
      case CXChildVisit_Recurse:
        if (PostChildrenVisitor)
          WL.push_back(PostChildrenVisit(nullptr, Cursor));
        EnqueueWorkList(WL, S);
        break;
      }
      continue;
    }
    case VisitorJob::MemberExprPartsKind: {
      // Handle the other pieces in the MemberExpr besides the base.
      const MemberExpr *M = cast<MemberExprParts>(&LI)->get();

      // Visit the nested-name-specifier
      if (NestedNameSpecifierLoc QualifierLoc = M->getQualifierLoc())
        if (VisitNestedNameSpecifierLoc(QualifierLoc))
          return true;

      // Visit the declaration name.
      if (VisitDeclarationNameInfo(M->getMemberNameInfo()))
        return true;

      // Visit the explicitly-specified template arguments, if any.
      if (M->hasExplicitTemplateArgs()) {
        for (const TemplateArgumentLoc *Arg = M->getTemplateArgs(),
                                       *ArgEnd = Arg + M->getNumTemplateArgs();
             Arg != ArgEnd; ++Arg) {
          if (VisitTemplateArgumentLoc(*Arg))
            return true;
        }
      }
      continue;
    }
    case VisitorJob::DeclRefExprPartsKind: {
      const DeclRefExpr *DR = cast<DeclRefExprParts>(&LI)->get();
      // Visit nested-name-specifier, if present.
      if (NestedNameSpecifierLoc QualifierLoc = DR->getQualifierLoc())
        if (VisitNestedNameSpecifierLoc(QualifierLoc))
          return true;
      // Visit declaration name.
      if (VisitDeclarationNameInfo(DR->getNameInfo()))
        return true;
      continue;
    }
    case VisitorJob::OverloadExprPartsKind: {
      const OverloadExpr *O = cast<OverloadExprParts>(&LI)->get();
      // Visit the nested-name-specifier.
      if (NestedNameSpecifierLoc QualifierLoc = O->getQualifierLoc())
        if (VisitNestedNameSpecifierLoc(QualifierLoc))
          return true;
      // Visit the declaration name.
      if (VisitDeclarationNameInfo(O->getNameInfo()))
        return true;
      // Visit the overloaded declaration reference.
      if (Visit(MakeCursorOverloadedDeclRef(O, TU)))
        return true;
      continue;
    }
    case VisitorJob::SizeOfPackExprPartsKind: {
      const SizeOfPackExpr *E = cast<SizeOfPackExprParts>(&LI)->get();
      NamedDecl *Pack = E->getPack();
      if (isa<TemplateTypeParmDecl>(Pack)) {
        if (Visit(MakeCursorTypeRef(cast<TemplateTypeParmDecl>(Pack),
                                    E->getPackLoc(), TU)))
          return true;

        continue;
      }

      if (isa<TemplateTemplateParmDecl>(Pack)) {
        if (Visit(MakeCursorTemplateRef(cast<TemplateTemplateParmDecl>(Pack),
                                        E->getPackLoc(), TU)))
          return true;

        continue;
      }

      // Non-type template parameter packs and function parameter packs are
      // treated like DeclRefExpr cursors.
      continue;
    }

    case VisitorJob::LambdaExprPartsKind: {
      // Visit non-init captures.
      const LambdaExpr *E = cast<LambdaExprParts>(&LI)->get();
      for (LambdaExpr::capture_iterator C = E->explicit_capture_begin(),
                                        CEnd = E->explicit_capture_end();
           C != CEnd; ++C) {
        if (!C->capturesVariable())
          continue;

        if (Visit(MakeCursorVariableRef(C->getCapturedVar(), C->getLocation(),
                                        TU)))
          return true;
      }
      // Visit init captures
      for (auto InitExpr : E->capture_inits()) {
        if (InitExpr && Visit(InitExpr))
          return true;
      }

      TypeLoc TL = E->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
      // Visit parameters and return type, if present.
      if (FunctionTypeLoc Proto = TL.getAs<FunctionProtoTypeLoc>()) {
        if (E->hasExplicitParameters()) {
          // Visit parameters.
          for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
            if (Visit(MakeCXCursor(Proto.getParam(I), TU)))
              return true;
        }
        if (E->hasExplicitResultType()) {
          // Visit result type.
          if (Visit(Proto.getReturnLoc()))
            return true;
        }
      }
      break;
    }

    case VisitorJob::PostChildrenVisitKind:
      if (PostChildrenVisitor(Parent, ClientData))
        return true;
      break;
    }
  }
  return false;
}

bool CursorVisitor::Visit(const Stmt *S) {
  VisitorWorkList *WL = nullptr;
  if (!WorkListFreeList.empty()) {
    WL = WorkListFreeList.back();
    WL->clear();
    WorkListFreeList.pop_back();
  } else {
    WL = new VisitorWorkList();
    WorkListCache.push_back(WL);
  }
  EnqueueWorkList(*WL, S);
  bool result = RunVisitorWorkList(*WL);
  WorkListFreeList.push_back(WL);
  return result;
}

namespace {
typedef SmallVector<SourceRange, 4> RefNamePieces;
RefNamePieces buildPieces(unsigned NameFlags, bool IsMemberRefExpr,
                          const DeclarationNameInfo &NI, SourceRange QLoc,
                          const SourceRange *TemplateArgsLoc = nullptr) {
  const bool WantQualifier = NameFlags & CXNameRange_WantQualifier;
  const bool WantTemplateArgs = NameFlags & CXNameRange_WantTemplateArgs;
  const bool WantSinglePiece = NameFlags & CXNameRange_WantSinglePiece;

  const DeclarationName::NameKind Kind = NI.getName().getNameKind();

  RefNamePieces Pieces;

  if (WantQualifier && QLoc.isValid())
    Pieces.push_back(QLoc);

  if (Kind != DeclarationName::CXXOperatorName || IsMemberRefExpr)
    Pieces.push_back(NI.getLoc());

  if (WantTemplateArgs && TemplateArgsLoc && TemplateArgsLoc->isValid())
    Pieces.push_back(*TemplateArgsLoc);

  if (Kind == DeclarationName::CXXOperatorName) {
    Pieces.push_back(SourceLocation::getFromRawEncoding(
        NI.getInfo().CXXOperatorName.BeginOpNameLoc));
    Pieces.push_back(SourceLocation::getFromRawEncoding(
        NI.getInfo().CXXOperatorName.EndOpNameLoc));
  }

  if (WantSinglePiece) {
    SourceRange R(Pieces.front().getBegin(), Pieces.back().getEnd());
    Pieces.clear();
    Pieces.push_back(R);
  }

  return Pieces;
}
} // namespace

//===----------------------------------------------------------------------===//
// Misc. API hooks.
//===----------------------------------------------------------------------===//

namespace {
struct RegisterFatalErrorHandler {
  RegisterFatalErrorHandler() {
    clang_install_aborting_llvm_fatal_error_handler();
  }
};
} // namespace

static llvm::ManagedStatic<RegisterFatalErrorHandler>
    RegisterFatalErrorHandlerOnce;

CXIndex clang_createIndex(int excludeDeclarationsFromPCH,
                          int displayDiagnostics) {
  // We use crash recovery to make some of our APIs more reliable, implicitly
  // enable it.
  if (!getenv("LIBCLANG_DISABLE_CRASH_RECOVERY"))
    llvm::CrashRecoveryContext::Enable();

  // Look through the managed static to trigger construction of the managed
  // static which registers our fatal error handler. This ensures it is only
  // registered once.
  (void)*RegisterFatalErrorHandlerOnce;

  // Initialize targets for clang module support.
  llvm::InitializeAllTargets();
  llvm::InitializeAllTargetMCs();
  llvm::InitializeAllAsmPrinters();
  llvm::InitializeAllAsmParsers();

  CIndexer *CIdxr = new CIndexer();

  if (excludeDeclarationsFromPCH)
    CIdxr->setOnlyLocalDecls();
  if (displayDiagnostics)
    CIdxr->setDisplayDiagnostics();

  if (getenv("LIBCLANG_BGPRIO_INDEX"))
    CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
                               CXGlobalOpt_ThreadBackgroundPriorityForIndexing);
  if (getenv("LIBCLANG_BGPRIO_EDIT"))
    CIdxr->setCXGlobalOptFlags(CIdxr->getCXGlobalOptFlags() |
                               CXGlobalOpt_ThreadBackgroundPriorityForEditing);

  return CIdxr;
}

void clang_disposeIndex(CXIndex CIdx) {
  if (CIdx)
    delete static_cast<CIndexer *>(CIdx);
}

void clang_CXIndex_setGlobalOptions(CXIndex CIdx, unsigned options) {
  if (CIdx)
    static_cast<CIndexer *>(CIdx)->setCXGlobalOptFlags(options);
}

unsigned clang_CXIndex_getGlobalOptions(CXIndex CIdx) {
  if (CIdx)
    return static_cast<CIndexer *>(CIdx)->getCXGlobalOptFlags();
  return 0;
}

void clang_CXIndex_setInvocationEmissionPathOption(CXIndex CIdx,
                                                   const char *Path) {
  if (CIdx)
    static_cast<CIndexer *>(CIdx)->setInvocationEmissionPath(Path ? Path : "");
}

void clang_toggleCrashRecovery(unsigned isEnabled) {
  if (isEnabled)
    llvm::CrashRecoveryContext::Enable();
  else
    llvm::CrashRecoveryContext::Disable();
}

CXTranslationUnit clang_createTranslationUnit(CXIndex CIdx,
                                              const char *ast_filename) {
  CXTranslationUnit TU;
  enum CXErrorCode Result =
      clang_createTranslationUnit2(CIdx, ast_filename, &TU);
  (void)Result;
  assert((TU && Result == CXError_Success) ||
         (!TU && Result != CXError_Success));
  return TU;
}

enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
                                              const char *ast_filename,
                                              CXTranslationUnit *out_TU) {
  if (out_TU)
    *out_TU = nullptr;

  if (!CIdx || !ast_filename || !out_TU)
    return CXError_InvalidArguments;

  LOG_FUNC_SECTION { *Log << ast_filename; }

  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);
  FileSystemOptions FileSystemOpts;

  IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
      CompilerInstance::createDiagnostics(new DiagnosticOptions());
  std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
      ast_filename, CXXIdx->getPCHContainerOperations()->getRawReader(),
      ASTUnit::LoadEverything, Diags, FileSystemOpts, /*UseDebugInfo=*/false,
      CXXIdx->getOnlyLocalDecls(), None, CaptureDiagsKind::All,
      /*AllowPCHWithCompilerErrors=*/true,
      /*UserFilesAreVolatile=*/true);
  *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(AU));
  return *out_TU ? CXError_Success : CXError_Failure;
}

unsigned clang_defaultEditingTranslationUnitOptions() {
  return CXTranslationUnit_PrecompiledPreamble |
         CXTranslationUnit_CacheCompletionResults;
}

CXTranslationUnit clang_createTranslationUnitFromSourceFile(
    CXIndex CIdx, const char *source_filename, int num_command_line_args,
    const char *const *command_line_args, unsigned num_unsaved_files,
    struct CXUnsavedFile *unsaved_files) {
  unsigned Options = CXTranslationUnit_DetailedPreprocessingRecord;
  return clang_parseTranslationUnit(CIdx, source_filename, command_line_args,
                                    num_command_line_args, unsaved_files,
                                    num_unsaved_files, Options);
}

static CXErrorCode
clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename,
                                const char *const *command_line_args,
                                int num_command_line_args,
                                ArrayRef<CXUnsavedFile> unsaved_files,
                                unsigned options, CXTranslationUnit *out_TU) {
  // Set up the initial return values.
  if (out_TU)
    *out_TU = nullptr;

  // Check arguments.
  if (!CIdx || !out_TU)
    return CXError_InvalidArguments;

  CIndexer *CXXIdx = static_cast<CIndexer *>(CIdx);

  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
    setThreadBackgroundPriority();

  bool PrecompilePreamble = options & CXTranslationUnit_PrecompiledPreamble;
  bool CreatePreambleOnFirstParse =
      options & CXTranslationUnit_CreatePreambleOnFirstParse;
  // FIXME: Add a flag for modules.
  TranslationUnitKind TUKind = (options & (CXTranslationUnit_Incomplete |
                                           CXTranslationUnit_SingleFileParse))
                                   ? TU_Prefix
                                   : TU_Complete;
  bool CacheCodeCompletionResults =
      options & CXTranslationUnit_CacheCompletionResults;
  bool IncludeBriefCommentsInCodeCompletion =
      options & CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
  bool SingleFileParse = options & CXTranslationUnit_SingleFileParse;
  bool ForSerialization = options & CXTranslationUnit_ForSerialization;
  bool RetainExcludedCB =
      options & CXTranslationUnit_RetainExcludedConditionalBlocks;
  SkipFunctionBodiesScope SkipFunctionBodies = SkipFunctionBodiesScope::None;
  if (options & CXTranslationUnit_SkipFunctionBodies) {
    SkipFunctionBodies =
        (options & CXTranslationUnit_LimitSkipFunctionBodiesToPreamble)
            ? SkipFunctionBodiesScope::Preamble
            : SkipFunctionBodiesScope::PreambleAndMainFile;
  }

  // Configure the diagnostics.
  IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
      CompilerInstance::createDiagnostics(new DiagnosticOptions));

  if (options & CXTranslationUnit_KeepGoing)
    Diags->setFatalsAsError(true);

  CaptureDiagsKind CaptureDiagnostics = CaptureDiagsKind::All;
  if (options & CXTranslationUnit_IgnoreNonErrorsFromIncludedFiles)
    CaptureDiagnostics = CaptureDiagsKind::AllWithoutNonErrorsFromIncludes;

  // Recover resources if we crash before exiting this function.
  llvm::CrashRecoveryContextCleanupRegistrar<
      DiagnosticsEngine,
      llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine>>
      DiagCleanup(Diags.get());

  std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
      new std::vector<ASTUnit::RemappedFile>());

  // Recover resources if we crash before exiting this function.
  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
      RemappedCleanup(RemappedFiles.get());

  for (auto &UF : unsaved_files) {
    std::unique_ptr<llvm::MemoryBuffer> MB =
        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
    RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
  }

  std::unique_ptr<std::vector<const char *>> Args(
      new std::vector<const char *>());

  // Recover resources if we crash before exiting this method.
  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<const char *>>
      ArgsCleanup(Args.get());

  // Since the Clang C library is primarily used by batch tools dealing with
  // (often very broken) source code, where spell-checking can have a
  // significant negative impact on performance (particularly when
  // precompiled headers are involved), we disable it by default.
  // Only do this if we haven't found a spell-checking-related argument.
  bool FoundSpellCheckingArgument = false;
  for (int I = 0; I != num_command_line_args; ++I) {
    if (strcmp(command_line_args[I], "-fno-spell-checking") == 0 ||
        strcmp(command_line_args[I], "-fspell-checking") == 0) {
      FoundSpellCheckingArgument = true;
      break;
    }
  }
  Args->insert(Args->end(), command_line_args,
               command_line_args + num_command_line_args);

  if (!FoundSpellCheckingArgument)
    Args->insert(Args->begin() + 1, "-fno-spell-checking");

  // The 'source_filename' argument is optional.  If the caller does not
  // specify it then it is assumed that the source file is specified
  // in the actual argument list.
  // Put the source file after command_line_args otherwise if '-x' flag is
  // present it will be unused.
  if (source_filename)
    Args->push_back(source_filename);

  // Do we need the detailed preprocessing record?
  if (options & CXTranslationUnit_DetailedPreprocessingRecord) {
    Args->push_back("-Xclang");
    Args->push_back("-detailed-preprocessing-record");
  }

  // Suppress any editor placeholder diagnostics.
  Args->push_back("-fallow-editor-placeholders");

  unsigned NumErrors = Diags->getClient()->getNumErrors();
  std::unique_ptr<ASTUnit> ErrUnit;
  // Unless the user specified that they want the preamble on the first parse
  // set it up to be created on the first reparse. This makes the first parse
  // faster, trading for a slower (first) reparse.
  unsigned PrecompilePreambleAfterNParses =
      !PrecompilePreamble ? 0 : 2 - CreatePreambleOnFirstParse;

  LibclangInvocationReporter InvocationReporter(
      *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation,
      options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None,
      unsaved_files);
  std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
      Args->data(), Args->data() + Args->size(),
      CXXIdx->getPCHContainerOperations(), Diags,
      CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
      CaptureDiagnostics, *RemappedFiles.get(),
      /*RemappedFilesKeepOriginalName=*/true, PrecompilePreambleAfterNParses,
      TUKind, CacheCodeCompletionResults, IncludeBriefCommentsInCodeCompletion,
      /*AllowPCHWithCompilerErrors=*/true, SkipFunctionBodies, SingleFileParse,
      /*UserFilesAreVolatile=*/true, ForSerialization, RetainExcludedCB,
      CXXIdx->getPCHContainerOperations()->getRawReader().getFormat(),
      &ErrUnit));

  // Early failures in LoadFromCommandLine may return with ErrUnit unset.
  if (!Unit && !ErrUnit)
    return CXError_ASTReadError;

  if (NumErrors != Diags->getClient()->getNumErrors()) {
    // Make sure to check that 'Unit' is non-NULL.
    if (CXXIdx->getDisplayDiagnostics())
      printDiagsToStderr(Unit ? Unit.get() : ErrUnit.get());
  }

  if (isASTReadError(Unit ? Unit.get() : ErrUnit.get()))
    return CXError_ASTReadError;

  *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit));
  if (CXTranslationUnitImpl *TU = *out_TU) {
    TU->ParsingOptions = options;
    TU->Arguments.reserve(Args->size());
    for (const char *Arg : *Args)
      TU->Arguments.push_back(Arg);
    return CXError_Success;
  }
  return CXError_Failure;
}

CXTranslationUnit
clang_parseTranslationUnit(CXIndex CIdx, const char *source_filename,
                           const char *const *command_line_args,
                           int num_command_line_args,
                           struct CXUnsavedFile *unsaved_files,
                           unsigned num_unsaved_files, unsigned options) {
  CXTranslationUnit TU;
  enum CXErrorCode Result = clang_parseTranslationUnit2(
      CIdx, source_filename, command_line_args, num_command_line_args,
      unsaved_files, num_unsaved_files, options, &TU);
  (void)Result;
  assert((TU && Result == CXError_Success) ||
         (!TU && Result != CXError_Success));
  return TU;
}

enum CXErrorCode clang_parseTranslationUnit2(
    CXIndex CIdx, const char *source_filename,
    const char *const *command_line_args, int num_command_line_args,
    struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
    unsigned options, CXTranslationUnit *out_TU) {
  noteBottomOfStack();
  SmallVector<const char *, 4> Args;
  Args.push_back("clang");
  Args.append(command_line_args, command_line_args + num_command_line_args);
  return clang_parseTranslationUnit2FullArgv(
      CIdx, source_filename, Args.data(), Args.size(), unsaved_files,
      num_unsaved_files, options, out_TU);
}

enum CXErrorCode clang_parseTranslationUnit2FullArgv(
    CXIndex CIdx, const char *source_filename,
    const char *const *command_line_args, int num_command_line_args,
    struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files,
    unsigned options, CXTranslationUnit *out_TU) {
  LOG_FUNC_SECTION {
    *Log << source_filename << ": ";
    for (int i = 0; i != num_command_line_args; ++i)
      *Log << command_line_args[i] << " ";
  }

  if (num_unsaved_files && !unsaved_files)
    return CXError_InvalidArguments;

  CXErrorCode result = CXError_Failure;
  auto ParseTranslationUnitImpl = [=, &result] {
    noteBottomOfStack();
    result = clang_parseTranslationUnit_Impl(
        CIdx, source_filename, command_line_args, num_command_line_args,
        llvm::makeArrayRef(unsaved_files, num_unsaved_files), options, out_TU);
  };

  llvm::CrashRecoveryContext CRC;

  if (!RunSafely(CRC, ParseTranslationUnitImpl)) {
    fprintf(stderr, "libclang: crash detected during parsing: {\n");
    fprintf(stderr, "  'source_filename' : '%s'\n", source_filename);
    fprintf(stderr, "  'command_line_args' : [");
    for (int i = 0; i != num_command_line_args; ++i) {
      if (i)
        fprintf(stderr, ", ");
      fprintf(stderr, "'%s'", command_line_args[i]);
    }
    fprintf(stderr, "],\n");
    fprintf(stderr, "  'unsaved_files' : [");
    for (unsigned i = 0; i != num_unsaved_files; ++i) {
      if (i)
        fprintf(stderr, ", ");
      fprintf(stderr, "('%s', '...', %ld)", unsaved_files[i].Filename,
              unsaved_files[i].Length);
    }
    fprintf(stderr, "],\n");
    fprintf(stderr, "  'options' : %d,\n", options);
    fprintf(stderr, "}\n");

    return CXError_Crashed;
  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
    if (CXTranslationUnit *TU = out_TU)
      PrintLibclangResourceUsage(*TU);
  }

  return result;
}

CXString clang_Type_getObjCEncoding(CXType CT) {
  CXTranslationUnit tu = static_cast<CXTranslationUnit>(CT.data[1]);
  ASTContext &Ctx = getASTUnit(tu)->getASTContext();
  std::string encoding;
  Ctx.getObjCEncodingForType(QualType::getFromOpaquePtr(CT.data[0]), encoding);

  return cxstring::createDup(encoding);
}

static const IdentifierInfo *getMacroIdentifier(CXCursor C) {
  if (C.kind == CXCursor_MacroDefinition) {
    if (const MacroDefinitionRecord *MDR = getCursorMacroDefinition(C))
      return MDR->getName();
  } else if (C.kind == CXCursor_MacroExpansion) {
    MacroExpansionCursor ME = getCursorMacroExpansion(C);
    return ME.getName();
  }
  return nullptr;
}

unsigned clang_Cursor_isMacroFunctionLike(CXCursor C) {
  const IdentifierInfo *II = getMacroIdentifier(C);
  if (!II) {
    return false;
  }
  ASTUnit *ASTU = getCursorASTUnit(C);
  Preprocessor &PP = ASTU->getPreprocessor();
  if (const MacroInfo *MI = PP.getMacroInfo(II))
    return MI->isFunctionLike();
  return false;
}

unsigned clang_Cursor_isMacroBuiltin(CXCursor C) {
  const IdentifierInfo *II = getMacroIdentifier(C);
  if (!II) {
    return false;
  }
  ASTUnit *ASTU = getCursorASTUnit(C);
  Preprocessor &PP = ASTU->getPreprocessor();
  if (const MacroInfo *MI = PP.getMacroInfo(II))
    return MI->isBuiltinMacro();
  return false;
}

unsigned clang_Cursor_isFunctionInlined(CXCursor C) {
  const Decl *D = getCursorDecl(C);
  const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
  if (!FD) {
    return false;
  }
  return FD->isInlined();
}

static StringLiteral *getCFSTR_value(CallExpr *callExpr) {
  if (callExpr->getNumArgs() != 1) {
    return nullptr;
  }

  StringLiteral *S = nullptr;
  auto *arg = callExpr->getArg(0);
  if (arg->getStmtClass() == Stmt::ImplicitCastExprClass) {
    ImplicitCastExpr *I = static_cast<ImplicitCastExpr *>(arg);
    auto *subExpr = I->getSubExprAsWritten();

    if (subExpr->getStmtClass() != Stmt::StringLiteralClass) {
      return nullptr;
    }

    S = static_cast<StringLiteral *>(I->getSubExprAsWritten());
  } else if (arg->getStmtClass() == Stmt::StringLiteralClass) {
    S = static_cast<StringLiteral *>(callExpr->getArg(0));
  } else {
    return nullptr;
  }
  return S;
}

struct ExprEvalResult {
  CXEvalResultKind EvalType;
  union {
    unsigned long long unsignedVal;
    long long intVal;
    double floatVal;
    char *stringVal;
  } EvalData;
  bool IsUnsignedInt;
  ~ExprEvalResult() {
    if (EvalType != CXEval_UnExposed && EvalType != CXEval_Float &&
        EvalType != CXEval_Int) {
      delete[] EvalData.stringVal;
    }
  }
};

void clang_EvalResult_dispose(CXEvalResult E) {
  delete static_cast<ExprEvalResult *>(E);
}

CXEvalResultKind clang_EvalResult_getKind(CXEvalResult E) {
  if (!E) {
    return CXEval_UnExposed;
  }
  return ((ExprEvalResult *)E)->EvalType;
}

int clang_EvalResult_getAsInt(CXEvalResult E) {
  return clang_EvalResult_getAsLongLong(E);
}

long long clang_EvalResult_getAsLongLong(CXEvalResult E) {
  if (!E) {
    return 0;
  }
  ExprEvalResult *Result = (ExprEvalResult *)E;
  if (Result->IsUnsignedInt)
    return Result->EvalData.unsignedVal;
  return Result->EvalData.intVal;
}

unsigned clang_EvalResult_isUnsignedInt(CXEvalResult E) {
  return ((ExprEvalResult *)E)->IsUnsignedInt;
}

unsigned long long clang_EvalResult_getAsUnsigned(CXEvalResult E) {
  if (!E) {
    return 0;
  }

  ExprEvalResult *Result = (ExprEvalResult *)E;
  if (Result->IsUnsignedInt)
    return Result->EvalData.unsignedVal;
  return Result->EvalData.intVal;
}

double clang_EvalResult_getAsDouble(CXEvalResult E) {
  if (!E) {
    return 0;
  }
  return ((ExprEvalResult *)E)->EvalData.floatVal;
}

const char *clang_EvalResult_getAsStr(CXEvalResult E) {
  if (!E) {
    return nullptr;
  }
  return ((ExprEvalResult *)E)->EvalData.stringVal;
}

static const ExprEvalResult *evaluateExpr(Expr *expr, CXCursor C) {
  Expr::EvalResult ER;
  ASTContext &ctx = getCursorContext(C);
  if (!expr)
    return nullptr;

  expr = expr->IgnoreParens();
  if (expr->isValueDependent())
    return nullptr;
  if (!expr->EvaluateAsRValue(ER, ctx))
    return nullptr;

  QualType rettype;
  CallExpr *callExpr;
  auto result = std::make_unique<ExprEvalResult>();
  result->EvalType = CXEval_UnExposed;
  result->IsUnsignedInt = false;

  if (ER.Val.isInt()) {
    result->EvalType = CXEval_Int;

    auto &val = ER.Val.getInt();
    if (val.isUnsigned()) {
      result->IsUnsignedInt = true;
      result->EvalData.unsignedVal = val.getZExtValue();
    } else {
      result->EvalData.intVal = val.getExtValue();
    }

    return result.release();
  }

  if (ER.Val.isFloat()) {
    llvm::SmallVector<char, 100> Buffer;
    ER.Val.getFloat().toString(Buffer);
    std::string floatStr(Buffer.data(), Buffer.size());
    result->EvalType = CXEval_Float;
    bool ignored;
    llvm::APFloat apFloat = ER.Val.getFloat();
    apFloat.convert(llvm::APFloat::IEEEdouble(),
                    llvm::APFloat::rmNearestTiesToEven, &ignored);
    result->EvalData.floatVal = apFloat.convertToDouble();
    return result.release();
  }

  if (expr->getStmtClass() == Stmt::ImplicitCastExprClass) {
    const ImplicitCastExpr *I = dyn_cast<ImplicitCastExpr>(expr);
    auto *subExpr = I->getSubExprAsWritten();
    if (subExpr->getStmtClass() == Stmt::StringLiteralClass ||
        subExpr->getStmtClass() == Stmt::ObjCStringLiteralClass) {
      const StringLiteral *StrE = nullptr;
      const ObjCStringLiteral *ObjCExpr;
      ObjCExpr = dyn_cast<ObjCStringLiteral>(subExpr);

      if (ObjCExpr) {
        StrE = ObjCExpr->getString();
        result->EvalType = CXEval_ObjCStrLiteral;
      } else {
        StrE = cast<StringLiteral>(I->getSubExprAsWritten());
        result->EvalType = CXEval_StrLiteral;
      }

      std::string strRef(StrE->getString().str());
      result->EvalData.stringVal = new char[strRef.size() + 1];
      strncpy((char *)result->EvalData.stringVal, strRef.c_str(),
              strRef.size());
      result->EvalData.stringVal[strRef.size()] = '\0';
      return result.release();
    }
  } else if (expr->getStmtClass() == Stmt::ObjCStringLiteralClass ||
             expr->getStmtClass() == Stmt::StringLiteralClass) {
    const StringLiteral *StrE = nullptr;
    const ObjCStringLiteral *ObjCExpr;
    ObjCExpr = dyn_cast<ObjCStringLiteral>(expr);

    if (ObjCExpr) {
      StrE = ObjCExpr->getString();
      result->EvalType = CXEval_ObjCStrLiteral;
    } else {
      StrE = cast<StringLiteral>(expr);
      result->EvalType = CXEval_StrLiteral;
    }

    std::string strRef(StrE->getString().str());
    result->EvalData.stringVal = new char[strRef.size() + 1];
    strncpy((char *)result->EvalData.stringVal, strRef.c_str(), strRef.size());
    result->EvalData.stringVal[strRef.size()] = '\0';
    return result.release();
  }

  if (expr->getStmtClass() == Stmt::CStyleCastExprClass) {
    CStyleCastExpr *CC = static_cast<CStyleCastExpr *>(expr);

    rettype = CC->getType();
    if (rettype.getAsString() == "CFStringRef" &&
        CC->getSubExpr()->getStmtClass() == Stmt::CallExprClass) {

      callExpr = static_cast<CallExpr *>(CC->getSubExpr());
      StringLiteral *S = getCFSTR_value(callExpr);
      if (S) {
        std::string strLiteral(S->getString().str());
        result->EvalType = CXEval_CFStr;

        result->EvalData.stringVal = new char[strLiteral.size() + 1];
        strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
                strLiteral.size());
        result->EvalData.stringVal[strLiteral.size()] = '\0';
        return result.release();
      }
    }

  } else if (expr->getStmtClass() == Stmt::CallExprClass) {
    callExpr = static_cast<CallExpr *>(expr);
    rettype = callExpr->getCallReturnType(ctx);

    if (rettype->isVectorType() || callExpr->getNumArgs() > 1)
      return nullptr;

    if (rettype->isIntegralType(ctx) || rettype->isRealFloatingType()) {
      if (callExpr->getNumArgs() == 1 &&
          !callExpr->getArg(0)->getType()->isIntegralType(ctx))
        return nullptr;
    } else if (rettype.getAsString() == "CFStringRef") {

      StringLiteral *S = getCFSTR_value(callExpr);
      if (S) {
        std::string strLiteral(S->getString().str());
        result->EvalType = CXEval_CFStr;
        result->EvalData.stringVal = new char[strLiteral.size() + 1];
        strncpy((char *)result->EvalData.stringVal, strLiteral.c_str(),
                strLiteral.size());
        result->EvalData.stringVal[strLiteral.size()] = '\0';
        return result.release();
      }
    }
  } else if (expr->getStmtClass() == Stmt::DeclRefExprClass) {
    DeclRefExpr *D = static_cast<DeclRefExpr *>(expr);
    ValueDecl *V = D->getDecl();
    if (V->getKind() == Decl::Function) {
      std::string strName = V->getNameAsString();
      result->EvalType = CXEval_Other;
      result->EvalData.stringVal = new char[strName.size() + 1];
      strncpy(result->EvalData.stringVal, strName.c_str(), strName.size());
      result->EvalData.stringVal[strName.size()] = '\0';
      return result.release();
    }
  }

  return nullptr;
}

static const Expr *evaluateDeclExpr(const Decl *D) {
  if (!D)
    return nullptr;
  if (auto *Var = dyn_cast<VarDecl>(D))
    return Var->getInit();
  else if (auto *Field = dyn_cast<FieldDecl>(D))
    return Field->getInClassInitializer();
  return nullptr;
}

static const Expr *evaluateCompoundStmtExpr(const CompoundStmt *CS) {
  assert(CS && "invalid compound statement");
  for (auto *bodyIterator : CS->body()) {
    if (const auto *E = dyn_cast<Expr>(bodyIterator))
      return E;
  }
  return nullptr;
}

CXEvalResult clang_Cursor_Evaluate(CXCursor C) {
  const Expr *E = nullptr;
  if (clang_getCursorKind(C) == CXCursor_CompoundStmt)
    E = evaluateCompoundStmtExpr(cast<CompoundStmt>(getCursorStmt(C)));
  else if (clang_isDeclaration(C.kind))
    E = evaluateDeclExpr(getCursorDecl(C));
  else if (clang_isExpression(C.kind))
    E = getCursorExpr(C);
  if (E)
    return const_cast<CXEvalResult>(
        reinterpret_cast<const void *>(evaluateExpr(const_cast<Expr *>(E), C)));
  return nullptr;
}

unsigned clang_Cursor_hasAttrs(CXCursor C) {
  const Decl *D = getCursorDecl(C);
  if (!D) {
    return 0;
  }

  if (D->hasAttrs()) {
    return 1;
  }

  return 0;
}
unsigned clang_defaultSaveOptions(CXTranslationUnit TU) {
  return CXSaveTranslationUnit_None;
}

static CXSaveError clang_saveTranslationUnit_Impl(CXTranslationUnit TU,
                                                  const char *FileName,
                                                  unsigned options) {
  CIndexer *CXXIdx = TU->CIdx;
  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForIndexing))
    setThreadBackgroundPriority();

  bool hadError = cxtu::getASTUnit(TU)->Save(FileName);
  return hadError ? CXSaveError_Unknown : CXSaveError_None;
}

int clang_saveTranslationUnit(CXTranslationUnit TU, const char *FileName,
                              unsigned options) {
  LOG_FUNC_SECTION { *Log << TU << ' ' << FileName; }

  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return CXSaveError_InvalidTU;
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  ASTUnit::ConcurrencyCheck Check(*CXXUnit);
  if (!CXXUnit->hasSema())
    return CXSaveError_InvalidTU;

  CXSaveError result;
  auto SaveTranslationUnitImpl = [=, &result]() {
    result = clang_saveTranslationUnit_Impl(TU, FileName, options);
  };

  if (!CXXUnit->getDiagnostics().hasUnrecoverableErrorOccurred()) {
    SaveTranslationUnitImpl();

    if (getenv("LIBCLANG_RESOURCE_USAGE"))
      PrintLibclangResourceUsage(TU);

    return result;
  }

  // We have an AST that has invalid nodes due to compiler errors.
  // Use a crash recovery thread for protection.

  llvm::CrashRecoveryContext CRC;

  if (!RunSafely(CRC, SaveTranslationUnitImpl)) {
    fprintf(stderr, "libclang: crash detected during AST saving: {\n");
    fprintf(stderr, "  'filename' : '%s'\n", FileName);
    fprintf(stderr, "  'options' : %d,\n", options);
    fprintf(stderr, "}\n");

    return CXSaveError_Unknown;

  } else if (getenv("LIBCLANG_RESOURCE_USAGE")) {
    PrintLibclangResourceUsage(TU);
  }

  return result;
}

void clang_disposeTranslationUnit(CXTranslationUnit CTUnit) {
  if (CTUnit) {
    // If the translation unit has been marked as unsafe to free, just discard
    // it.
    ASTUnit *Unit = cxtu::getASTUnit(CTUnit);
    if (Unit && Unit->isUnsafeToFree())
      return;

    delete cxtu::getASTUnit(CTUnit);
    delete CTUnit->StringPool;
    delete static_cast<CXDiagnosticSetImpl *>(CTUnit->Diagnostics);
    disposeOverridenCXCursorsPool(CTUnit->OverridenCursorsPool);
    delete CTUnit->CommentToXML;
    delete CTUnit;
  }
}

unsigned clang_suspendTranslationUnit(CXTranslationUnit CTUnit) {
  if (CTUnit) {
    ASTUnit *Unit = cxtu::getASTUnit(CTUnit);

    if (Unit && Unit->isUnsafeToFree())
      return false;

    Unit->ResetForParse();
    return true;
  }

  return false;
}

unsigned clang_defaultReparseOptions(CXTranslationUnit TU) {
  return CXReparse_None;
}

static CXErrorCode
clang_reparseTranslationUnit_Impl(CXTranslationUnit TU,
                                  ArrayRef<CXUnsavedFile> unsaved_files,
                                  unsigned options) {
  // Check arguments.
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return CXError_InvalidArguments;
  }

  // Reset the associated diagnostics.
  delete static_cast<CXDiagnosticSetImpl *>(TU->Diagnostics);
  TU->Diagnostics = nullptr;

  CIndexer *CXXIdx = TU->CIdx;
  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
    setThreadBackgroundPriority();

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  ASTUnit::ConcurrencyCheck Check(*CXXUnit);

  std::unique_ptr<std::vector<ASTUnit::RemappedFile>> RemappedFiles(
      new std::vector<ASTUnit::RemappedFile>());

  // Recover resources if we crash before exiting this function.
  llvm::CrashRecoveryContextCleanupRegistrar<std::vector<ASTUnit::RemappedFile>>
      RemappedCleanup(RemappedFiles.get());

  for (auto &UF : unsaved_files) {
    std::unique_ptr<llvm::MemoryBuffer> MB =
        llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
    RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
  }

  if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
                        *RemappedFiles.get()))
    return CXError_Success;
  if (isASTReadError(CXXUnit))
    return CXError_ASTReadError;
  return CXError_Failure;
}

int clang_reparseTranslationUnit(CXTranslationUnit TU,
                                 unsigned num_unsaved_files,
                                 struct CXUnsavedFile *unsaved_files,
                                 unsigned options) {
  LOG_FUNC_SECTION { *Log << TU; }

  if (num_unsaved_files && !unsaved_files)
    return CXError_InvalidArguments;

  CXErrorCode result;
  auto ReparseTranslationUnitImpl = [=, &result]() {
    result = clang_reparseTranslationUnit_Impl(
        TU, llvm::makeArrayRef(unsaved_files, num_unsaved_files), options);
  };

  llvm::CrashRecoveryContext CRC;

  if (!RunSafely(CRC, ReparseTranslationUnitImpl)) {
    fprintf(stderr, "libclang: crash detected during reparsing\n");
    cxtu::getASTUnit(TU)->setUnsafeToFree(true);
    return CXError_Crashed;
  } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
    PrintLibclangResourceUsage(TU);

  return result;
}

CXString clang_getTranslationUnitSpelling(CXTranslationUnit CTUnit) {
  if (isNotUsableTU(CTUnit)) {
    LOG_BAD_TU(CTUnit);
    return cxstring::createEmpty();
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
  return cxstring::createDup(CXXUnit->getOriginalSourceFileName());
}

CXCursor clang_getTranslationUnitCursor(CXTranslationUnit TU) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return clang_getNullCursor();
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  return MakeCXCursor(CXXUnit->getASTContext().getTranslationUnitDecl(), TU);
}

CXTargetInfo clang_getTranslationUnitTargetInfo(CXTranslationUnit CTUnit) {
  if (isNotUsableTU(CTUnit)) {
    LOG_BAD_TU(CTUnit);
    return nullptr;
  }

  CXTargetInfoImpl *impl = new CXTargetInfoImpl();
  impl->TranslationUnit = CTUnit;
  return impl;
}

CXString clang_TargetInfo_getTriple(CXTargetInfo TargetInfo) {
  if (!TargetInfo)
    return cxstring::createEmpty();

  CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
  assert(!isNotUsableTU(CTUnit) &&
         "Unexpected unusable translation unit in TargetInfo");

  ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
  std::string Triple =
      CXXUnit->getASTContext().getTargetInfo().getTriple().normalize();
  return cxstring::createDup(Triple);
}

int clang_TargetInfo_getPointerWidth(CXTargetInfo TargetInfo) {
  if (!TargetInfo)
    return -1;

  CXTranslationUnit CTUnit = TargetInfo->TranslationUnit;
  assert(!isNotUsableTU(CTUnit) &&
         "Unexpected unusable translation unit in TargetInfo");

  ASTUnit *CXXUnit = cxtu::getASTUnit(CTUnit);
  return CXXUnit->getASTContext().getTargetInfo().getMaxPointerWidth();
}

void clang_TargetInfo_dispose(CXTargetInfo TargetInfo) {
  if (!TargetInfo)
    return;

  delete TargetInfo;
}

//===----------------------------------------------------------------------===//
// CXFile Operations.
//===----------------------------------------------------------------------===//

CXString clang_getFileName(CXFile SFile) {
  if (!SFile)
    return cxstring::createNull();

  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
  return cxstring::createRef(FEnt->getName());
}

time_t clang_getFileTime(CXFile SFile) {
  if (!SFile)
    return 0;

  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
  return FEnt->getModificationTime();
}

CXFile clang_getFile(CXTranslationUnit TU, const char *file_name) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return nullptr;
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);

  FileManager &FMgr = CXXUnit->getFileManager();
  auto File = FMgr.getFile(file_name);
  if (!File)
    return nullptr;
  return const_cast<FileEntry *>(*File);
}

const char *clang_getFileContents(CXTranslationUnit TU, CXFile file,
                                  size_t *size) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return nullptr;
  }

  const SourceManager &SM = cxtu::getASTUnit(TU)->getSourceManager();
  FileID fid = SM.translateFile(static_cast<FileEntry *>(file));
  bool Invalid = true;
  const llvm::MemoryBuffer *buf = SM.getBuffer(fid, &Invalid);
  if (Invalid) {
    if (size)
      *size = 0;
    return nullptr;
  }
  if (size)
    *size = buf->getBufferSize();
  return buf->getBufferStart();
}

unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit TU, CXFile file) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return 0;
  }

  if (!file)
    return 0;

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  FileEntry *FEnt = static_cast<FileEntry *>(file);
  return CXXUnit->getPreprocessor()
      .getHeaderSearchInfo()
      .isFileMultipleIncludeGuarded(FEnt);
}

int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID) {
  if (!file || !outID)
    return 1;

  FileEntry *FEnt = static_cast<FileEntry *>(file);
  const llvm::sys::fs::UniqueID &ID = FEnt->getUniqueID();
  outID->data[0] = ID.getDevice();
  outID->data[1] = ID.getFile();
  outID->data[2] = FEnt->getModificationTime();
  return 0;
}

int clang_File_isEqual(CXFile file1, CXFile file2) {
  if (file1 == file2)
    return true;

  if (!file1 || !file2)
    return false;

  FileEntry *FEnt1 = static_cast<FileEntry *>(file1);
  FileEntry *FEnt2 = static_cast<FileEntry *>(file2);
  return FEnt1->getUniqueID() == FEnt2->getUniqueID();
}

CXString clang_File_tryGetRealPathName(CXFile SFile) {
  if (!SFile)
    return cxstring::createNull();

  FileEntry *FEnt = static_cast<FileEntry *>(SFile);
  return cxstring::createRef(FEnt->tryGetRealPathName());
}

//===----------------------------------------------------------------------===//
// CXCursor Operations.
//===----------------------------------------------------------------------===//

static const Decl *getDeclFromExpr(const Stmt *E) {
  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
    return getDeclFromExpr(CE->getSubExpr());

  if (const DeclRefExpr *RefExpr = dyn_cast<DeclRefExpr>(E))
    return RefExpr->getDecl();
  if (const MemberExpr *ME = dyn_cast<MemberExpr>(E))
    return ME->getMemberDecl();
  if (const ObjCIvarRefExpr *RE = dyn_cast<ObjCIvarRefExpr>(E))
    return RE->getDecl();
  if (const ObjCPropertyRefExpr *PRE = dyn_cast<ObjCPropertyRefExpr>(E)) {
    if (PRE->isExplicitProperty())
      return PRE->getExplicitProperty();
    // It could be messaging both getter and setter as in:
    // ++myobj.myprop;
    // in which case prefer to associate the setter since it is less obvious
    // from inspecting the source that the setter is going to get called.
    if (PRE->isMessagingSetter())
      return PRE->getImplicitPropertySetter();
    return PRE->getImplicitPropertyGetter();
  }
  if (const PseudoObjectExpr *POE = dyn_cast<PseudoObjectExpr>(E))
    return getDeclFromExpr(POE->getSyntacticForm());
  if (const OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E))
    if (Expr *Src = OVE->getSourceExpr())
      return getDeclFromExpr(Src);

  if (const CallExpr *CE = dyn_cast<CallExpr>(E))
    return getDeclFromExpr(CE->getCallee());
  if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E))
    if (!CE->isElidable())
      return CE->getConstructor();
  if (const CXXInheritedCtorInitExpr *CE =
          dyn_cast<CXXInheritedCtorInitExpr>(E))
    return CE->getConstructor();
  if (const ObjCMessageExpr *OME = dyn_cast<ObjCMessageExpr>(E))
    return OME->getMethodDecl();

  if (const ObjCProtocolExpr *PE = dyn_cast<ObjCProtocolExpr>(E))
    return PE->getProtocol();
  if (const SubstNonTypeTemplateParmPackExpr *NTTP =
          dyn_cast<SubstNonTypeTemplateParmPackExpr>(E))
    return NTTP->getParameterPack();
  if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
    if (isa<NonTypeTemplateParmDecl>(SizeOfPack->getPack()) ||
        isa<ParmVarDecl>(SizeOfPack->getPack()))
      return SizeOfPack->getPack();

  return nullptr;
}

static SourceLocation getLocationFromExpr(const Expr *E) {
  if (const ImplicitCastExpr *CE = dyn_cast<ImplicitCastExpr>(E))
    return getLocationFromExpr(CE->getSubExpr());

  if (const ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E))
    return /*FIXME:*/ Msg->getLeftLoc();
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
    return DRE->getLocation();
  if (const MemberExpr *Member = dyn_cast<MemberExpr>(E))
    return Member->getMemberLoc();
  if (const ObjCIvarRefExpr *Ivar = dyn_cast<ObjCIvarRefExpr>(E))
    return Ivar->getLocation();
  if (const SizeOfPackExpr *SizeOfPack = dyn_cast<SizeOfPackExpr>(E))
    return SizeOfPack->getPackLoc();
  if (const ObjCPropertyRefExpr *PropRef = dyn_cast<ObjCPropertyRefExpr>(E))
    return PropRef->getLocation();

  return E->getBeginLoc();
}

extern "C" {

unsigned clang_visitChildren(CXCursor parent, CXCursorVisitor visitor,
                             CXClientData client_data) {
  CursorVisitor CursorVis(getCursorTU(parent), visitor, client_data,
                          /*VisitPreprocessorLast=*/false);
  return CursorVis.VisitChildren(parent);
}

#ifndef __has_feature
#define __has_feature(x) 0
#endif
#if __has_feature(blocks)
typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor,
                                                        CXCursor parent);

static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
                                              CXClientData client_data) {
  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
  return block(cursor, parent);
}
#else
// If we are compiled with a compiler that doesn't have native blocks support,
// define and call the block manually, so the
typedef struct _CXChildVisitResult {
  void *isa;
  int flags;
  int reserved;
  enum CXChildVisitResult (*invoke)(struct _CXChildVisitResult *, CXCursor,
                                    CXCursor);
} * CXCursorVisitorBlock;

static enum CXChildVisitResult visitWithBlock(CXCursor cursor, CXCursor parent,
                                              CXClientData client_data) {
  CXCursorVisitorBlock block = (CXCursorVisitorBlock)client_data;
  return block->invoke(block, cursor, parent);
}
#endif

unsigned clang_visitChildrenWithBlock(CXCursor parent,
                                      CXCursorVisitorBlock block) {
  return clang_visitChildren(parent, visitWithBlock, block);
}

static CXString getDeclSpelling(const Decl *D) {
  if (!D)
    return cxstring::createEmpty();

  const NamedDecl *ND = dyn_cast<NamedDecl>(D);
  if (!ND) {
    if (const ObjCPropertyImplDecl *PropImpl =
            dyn_cast<ObjCPropertyImplDecl>(D))
      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
        return cxstring::createDup(Property->getIdentifier()->getName());

    if (const ImportDecl *ImportD = dyn_cast<ImportDecl>(D))
      if (Module *Mod = ImportD->getImportedModule())
        return cxstring::createDup(Mod->getFullModuleName());

    return cxstring::createEmpty();
  }

  if (const ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(ND))
    return cxstring::createDup(OMD->getSelector().getAsString());

  if (const ObjCCategoryImplDecl *CIMP = dyn_cast<ObjCCategoryImplDecl>(ND))
    // No, this isn't the same as the code below. getIdentifier() is non-virtual
    // and returns different names. NamedDecl returns the class name and
    // ObjCCategoryImplDecl returns the category name.
    return cxstring::createRef(CIMP->getIdentifier()->getNameStart());

  if (isa<UsingDirectiveDecl>(D))
    return cxstring::createEmpty();

  SmallString<1024> S;
  llvm::raw_svector_ostream os(S);
  ND->printName(os);

  return cxstring::createDup(os.str());
}

CXString clang_getCursorSpelling(CXCursor C) {
  if (clang_isTranslationUnit(C.kind))
    return clang_getTranslationUnitSpelling(getCursorTU(C));

  if (clang_isReference(C.kind)) {
    switch (C.kind) {
    case CXCursor_ObjCSuperClassRef: {
      const ObjCInterfaceDecl *Super = getCursorObjCSuperClassRef(C).first;
      return cxstring::createRef(Super->getIdentifier()->getNameStart());
    }
    case CXCursor_ObjCClassRef: {
      const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
      return cxstring::createRef(Class->getIdentifier()->getNameStart());
    }
    case CXCursor_ObjCProtocolRef: {
      const ObjCProtocolDecl *OID = getCursorObjCProtocolRef(C).first;
      assert(OID && "getCursorSpelling(): Missing protocol decl");
      return cxstring::createRef(OID->getIdentifier()->getNameStart());
    }
    case CXCursor_CXXBaseSpecifier: {
      const CXXBaseSpecifier *B = getCursorCXXBaseSpecifier(C);
      return cxstring::createDup(B->getType().getAsString());
    }
    case CXCursor_TypeRef: {
      const TypeDecl *Type = getCursorTypeRef(C).first;
      assert(Type && "Missing type decl");

      return cxstring::createDup(
          getCursorContext(C).getTypeDeclType(Type).getAsString());
    }
    case CXCursor_TemplateRef: {
      const TemplateDecl *Template = getCursorTemplateRef(C).first;
      assert(Template && "Missing template decl");

      return cxstring::createDup(Template->getNameAsString());
    }

    case CXCursor_NamespaceRef: {
      const NamedDecl *NS = getCursorNamespaceRef(C).first;
      assert(NS && "Missing namespace decl");

      return cxstring::createDup(NS->getNameAsString());
    }

    case CXCursor_MemberRef: {
      const FieldDecl *Field = getCursorMemberRef(C).first;
      assert(Field && "Missing member decl");

      return cxstring::createDup(Field->getNameAsString());
    }

    case CXCursor_LabelRef: {
      const LabelStmt *Label = getCursorLabelRef(C).first;
      assert(Label && "Missing label");

      return cxstring::createRef(Label->getName());
    }

    case CXCursor_OverloadedDeclRef: {
      OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
      if (const Decl *D = Storage.dyn_cast<const Decl *>()) {
        if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
          return cxstring::createDup(ND->getNameAsString());
        return cxstring::createEmpty();
      }
      if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
        return cxstring::createDup(E->getName().getAsString());
      OverloadedTemplateStorage *Ovl =
          Storage.get<OverloadedTemplateStorage *>();
      if (Ovl->size() == 0)
        return cxstring::createEmpty();
      return cxstring::createDup((*Ovl->begin())->getNameAsString());
    }

    case CXCursor_VariableRef: {
      const VarDecl *Var = getCursorVariableRef(C).first;
      assert(Var && "Missing variable decl");

      return cxstring::createDup(Var->getNameAsString());
    }

    default:
      return cxstring::createRef("<not implemented>");
    }
  }

  if (clang_isExpression(C.kind)) {
    const Expr *E = getCursorExpr(C);

    if (C.kind == CXCursor_ObjCStringLiteral ||
        C.kind == CXCursor_StringLiteral) {
      const StringLiteral *SLit;
      if (const ObjCStringLiteral *OSL = dyn_cast<ObjCStringLiteral>(E)) {
        SLit = OSL->getString();
      } else {
        SLit = cast<StringLiteral>(E);
      }
      SmallString<256> Buf;
      llvm::raw_svector_ostream OS(Buf);
      SLit->outputString(OS);
      return cxstring::createDup(OS.str());
    }

    const Decl *D = getDeclFromExpr(getCursorExpr(C));
    if (D)
      return getDeclSpelling(D);
    return cxstring::createEmpty();
  }

  if (clang_isStatement(C.kind)) {
    const Stmt *S = getCursorStmt(C);
    if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S))
      return cxstring::createRef(Label->getName());

    return cxstring::createEmpty();
  }

  if (C.kind == CXCursor_MacroExpansion)
    return cxstring::createRef(
        getCursorMacroExpansion(C).getName()->getNameStart());

  if (C.kind == CXCursor_MacroDefinition)
    return cxstring::createRef(
        getCursorMacroDefinition(C)->getName()->getNameStart());

  if (C.kind == CXCursor_InclusionDirective)
    return cxstring::createDup(getCursorInclusionDirective(C)->getFileName());

  if (clang_isDeclaration(C.kind))
    return getDeclSpelling(getCursorDecl(C));

  if (C.kind == CXCursor_AnnotateAttr) {
    const AnnotateAttr *AA = cast<AnnotateAttr>(cxcursor::getCursorAttr(C));
    return cxstring::createDup(AA->getAnnotation());
  }

  if (C.kind == CXCursor_AsmLabelAttr) {
    const AsmLabelAttr *AA = cast<AsmLabelAttr>(cxcursor::getCursorAttr(C));
    return cxstring::createDup(AA->getLabel());
  }

  if (C.kind == CXCursor_PackedAttr) {
    return cxstring::createRef("packed");
  }

  if (C.kind == CXCursor_VisibilityAttr) {
    const VisibilityAttr *AA = cast<VisibilityAttr>(cxcursor::getCursorAttr(C));
    switch (AA->getVisibility()) {
    case VisibilityAttr::VisibilityType::Default:
      return cxstring::createRef("default");
    case VisibilityAttr::VisibilityType::Hidden:
      return cxstring::createRef("hidden");
    case VisibilityAttr::VisibilityType::Protected:
      return cxstring::createRef("protected");
    }
    llvm_unreachable("unknown visibility type");
  }

  return cxstring::createEmpty();
}

CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor C, unsigned pieceIndex,
                                                unsigned options) {
  if (clang_Cursor_isNull(C))
    return clang_getNullRange();

  ASTContext &Ctx = getCursorContext(C);

  if (clang_isStatement(C.kind)) {
    const Stmt *S = getCursorStmt(C);
    if (const LabelStmt *Label = dyn_cast_or_null<LabelStmt>(S)) {
      if (pieceIndex > 0)
        return clang_getNullRange();
      return cxloc::translateSourceRange(Ctx, Label->getIdentLoc());
    }

    return clang_getNullRange();
  }

  if (C.kind == CXCursor_ObjCMessageExpr) {
    if (const ObjCMessageExpr *ME =
            dyn_cast_or_null<ObjCMessageExpr>(getCursorExpr(C))) {
      if (pieceIndex >= ME->getNumSelectorLocs())
        return clang_getNullRange();
      return cxloc::translateSourceRange(Ctx, ME->getSelectorLoc(pieceIndex));
    }
  }

  if (C.kind == CXCursor_ObjCInstanceMethodDecl ||
      C.kind == CXCursor_ObjCClassMethodDecl) {
    if (const ObjCMethodDecl *MD =
            dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(C))) {
      if (pieceIndex >= MD->getNumSelectorLocs())
        return clang_getNullRange();
      return cxloc::translateSourceRange(Ctx, MD->getSelectorLoc(pieceIndex));
    }
  }

  if (C.kind == CXCursor_ObjCCategoryDecl ||
      C.kind == CXCursor_ObjCCategoryImplDecl) {
    if (pieceIndex > 0)
      return clang_getNullRange();
    if (const ObjCCategoryDecl *CD =
            dyn_cast_or_null<ObjCCategoryDecl>(getCursorDecl(C)))
      return cxloc::translateSourceRange(Ctx, CD->getCategoryNameLoc());
    if (const ObjCCategoryImplDecl *CID =
            dyn_cast_or_null<ObjCCategoryImplDecl>(getCursorDecl(C)))
      return cxloc::translateSourceRange(Ctx, CID->getCategoryNameLoc());
  }

  if (C.kind == CXCursor_ModuleImportDecl) {
    if (pieceIndex > 0)
      return clang_getNullRange();
    if (const ImportDecl *ImportD =
            dyn_cast_or_null<ImportDecl>(getCursorDecl(C))) {
      ArrayRef<SourceLocation> Locs = ImportD->getIdentifierLocs();
      if (!Locs.empty())
        return cxloc::translateSourceRange(
            Ctx, SourceRange(Locs.front(), Locs.back()));
    }
    return clang_getNullRange();
  }

  if (C.kind == CXCursor_CXXMethod || C.kind == CXCursor_Destructor ||
      C.kind == CXCursor_ConversionFunction ||
      C.kind == CXCursor_FunctionDecl) {
    if (pieceIndex > 0)
      return clang_getNullRange();
    if (const FunctionDecl *FD =
            dyn_cast_or_null<FunctionDecl>(getCursorDecl(C))) {
      DeclarationNameInfo FunctionName = FD->getNameInfo();
      return cxloc::translateSourceRange(Ctx, FunctionName.getSourceRange());
    }
    return clang_getNullRange();
  }

  // FIXME: A CXCursor_InclusionDirective should give the location of the
  // filename, but we don't keep track of this.

  // FIXME: A CXCursor_AnnotateAttr should give the location of the annotation
  // but we don't keep track of this.

  // FIXME: A CXCursor_AsmLabelAttr should give the location of the label
  // but we don't keep track of this.

  // Default handling, give the location of the cursor.

  if (pieceIndex > 0)
    return clang_getNullRange();

  CXSourceLocation CXLoc = clang_getCursorLocation(C);
  SourceLocation Loc = cxloc::translateSourceLocation(CXLoc);
  return cxloc::translateSourceRange(Ctx, Loc);
}

CXString clang_Cursor_getMangling(CXCursor C) {
  if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
    return cxstring::createEmpty();

  // Mangling only works for functions and variables.
  const Decl *D = getCursorDecl(C);
  if (!D || !(isa<FunctionDecl>(D) || isa<VarDecl>(D)))
    return cxstring::createEmpty();

  ASTContext &Ctx = D->getASTContext();
  ASTNameGenerator ASTNameGen(Ctx);
  return cxstring::createDup(ASTNameGen.getName(D));
}

CXStringSet *clang_Cursor_getCXXManglings(CXCursor C) {
  if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
    return nullptr;

  const Decl *D = getCursorDecl(C);
  if (!(isa<CXXRecordDecl>(D) || isa<CXXMethodDecl>(D)))
    return nullptr;

  ASTContext &Ctx = D->getASTContext();
  ASTNameGenerator ASTNameGen(Ctx);
  std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
  return cxstring::createSet(Manglings);
}

CXStringSet *clang_Cursor_getObjCManglings(CXCursor C) {
  if (clang_isInvalid(C.kind) || !clang_isDeclaration(C.kind))
    return nullptr;

  const Decl *D = getCursorDecl(C);
  if (!(isa<ObjCInterfaceDecl>(D) || isa<ObjCImplementationDecl>(D)))
    return nullptr;

  ASTContext &Ctx = D->getASTContext();
  ASTNameGenerator ASTNameGen(Ctx);
  std::vector<std::string> Manglings = ASTNameGen.getAllManglings(D);
  return cxstring::createSet(Manglings);
}

CXPrintingPolicy clang_getCursorPrintingPolicy(CXCursor C) {
  if (clang_Cursor_isNull(C))
    return 0;
  return new PrintingPolicy(getCursorContext(C).getPrintingPolicy());
}

void clang_PrintingPolicy_dispose(CXPrintingPolicy Policy) {
  if (Policy)
    delete static_cast<PrintingPolicy *>(Policy);
}

unsigned
clang_PrintingPolicy_getProperty(CXPrintingPolicy Policy,
                                 enum CXPrintingPolicyProperty Property) {
  if (!Policy)
    return 0;

  PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
  switch (Property) {
  case CXPrintingPolicy_Indentation:
    return P->Indentation;
  case CXPrintingPolicy_SuppressSpecifiers:
    return P->SuppressSpecifiers;
  case CXPrintingPolicy_SuppressTagKeyword:
    return P->SuppressTagKeyword;
  case CXPrintingPolicy_IncludeTagDefinition:
    return P->IncludeTagDefinition;
  case CXPrintingPolicy_SuppressScope:
    return P->SuppressScope;
  case CXPrintingPolicy_SuppressUnwrittenScope:
    return P->SuppressUnwrittenScope;
  case CXPrintingPolicy_SuppressInitializers:
    return P->SuppressInitializers;
  case CXPrintingPolicy_ConstantArraySizeAsWritten:
    return P->ConstantArraySizeAsWritten;
  case CXPrintingPolicy_AnonymousTagLocations:
    return P->AnonymousTagLocations;
  case CXPrintingPolicy_SuppressStrongLifetime:
    return P->SuppressStrongLifetime;
  case CXPrintingPolicy_SuppressLifetimeQualifiers:
    return P->SuppressLifetimeQualifiers;
  case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
    return P->SuppressTemplateArgsInCXXConstructors;
  case CXPrintingPolicy_Bool:
    return P->Bool;
  case CXPrintingPolicy_Restrict:
    return P->Restrict;
  case CXPrintingPolicy_Alignof:
    return P->Alignof;
  case CXPrintingPolicy_UnderscoreAlignof:
    return P->UnderscoreAlignof;
  case CXPrintingPolicy_UseVoidForZeroParams:
    return P->UseVoidForZeroParams;
  case CXPrintingPolicy_TerseOutput:
    return P->TerseOutput;
  case CXPrintingPolicy_PolishForDeclaration:
    return P->PolishForDeclaration;
  case CXPrintingPolicy_Half:
    return P->Half;
  case CXPrintingPolicy_MSWChar:
    return P->MSWChar;
  case CXPrintingPolicy_IncludeNewlines:
    return P->IncludeNewlines;
  case CXPrintingPolicy_MSVCFormatting:
    return P->MSVCFormatting;
  case CXPrintingPolicy_ConstantsAsWritten:
    return P->ConstantsAsWritten;
  case CXPrintingPolicy_SuppressImplicitBase:
    return P->SuppressImplicitBase;
  case CXPrintingPolicy_FullyQualifiedName:
    return P->FullyQualifiedName;
  }

  assert(false && "Invalid CXPrintingPolicyProperty");
  return 0;
}

void clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy,
                                      enum CXPrintingPolicyProperty Property,
                                      unsigned Value) {
  if (!Policy)
    return;

  PrintingPolicy *P = static_cast<PrintingPolicy *>(Policy);
  switch (Property) {
  case CXPrintingPolicy_Indentation:
    P->Indentation = Value;
    return;
  case CXPrintingPolicy_SuppressSpecifiers:
    P->SuppressSpecifiers = Value;
    return;
  case CXPrintingPolicy_SuppressTagKeyword:
    P->SuppressTagKeyword = Value;
    return;
  case CXPrintingPolicy_IncludeTagDefinition:
    P->IncludeTagDefinition = Value;
    return;
  case CXPrintingPolicy_SuppressScope:
    P->SuppressScope = Value;
    return;
  case CXPrintingPolicy_SuppressUnwrittenScope:
    P->SuppressUnwrittenScope = Value;
    return;
  case CXPrintingPolicy_SuppressInitializers:
    P->SuppressInitializers = Value;
    return;
  case CXPrintingPolicy_ConstantArraySizeAsWritten:
    P->ConstantArraySizeAsWritten = Value;
    return;
  case CXPrintingPolicy_AnonymousTagLocations:
    P->AnonymousTagLocations = Value;
    return;
  case CXPrintingPolicy_SuppressStrongLifetime:
    P->SuppressStrongLifetime = Value;
    return;
  case CXPrintingPolicy_SuppressLifetimeQualifiers:
    P->SuppressLifetimeQualifiers = Value;
    return;
  case CXPrintingPolicy_SuppressTemplateArgsInCXXConstructors:
    P->SuppressTemplateArgsInCXXConstructors = Value;
    return;
  case CXPrintingPolicy_Bool:
    P->Bool = Value;
    return;
  case CXPrintingPolicy_Restrict:
    P->Restrict = Value;
    return;
  case CXPrintingPolicy_Alignof:
    P->Alignof = Value;
    return;
  case CXPrintingPolicy_UnderscoreAlignof:
    P->UnderscoreAlignof = Value;
    return;
  case CXPrintingPolicy_UseVoidForZeroParams:
    P->UseVoidForZeroParams = Value;
    return;
  case CXPrintingPolicy_TerseOutput:
    P->TerseOutput = Value;
    return;
  case CXPrintingPolicy_PolishForDeclaration:
    P->PolishForDeclaration = Value;
    return;
  case CXPrintingPolicy_Half:
    P->Half = Value;
    return;
  case CXPrintingPolicy_MSWChar:
    P->MSWChar = Value;
    return;
  case CXPrintingPolicy_IncludeNewlines:
    P->IncludeNewlines = Value;
    return;
  case CXPrintingPolicy_MSVCFormatting:
    P->MSVCFormatting = Value;
    return;
  case CXPrintingPolicy_ConstantsAsWritten:
    P->ConstantsAsWritten = Value;
    return;
  case CXPrintingPolicy_SuppressImplicitBase:
    P->SuppressImplicitBase = Value;
    return;
  case CXPrintingPolicy_FullyQualifiedName:
    P->FullyQualifiedName = Value;
    return;
  }

  assert(false && "Invalid CXPrintingPolicyProperty");
}

CXString clang_getCursorPrettyPrinted(CXCursor C, CXPrintingPolicy cxPolicy) {
  if (clang_Cursor_isNull(C))
    return cxstring::createEmpty();

  if (clang_isDeclaration(C.kind)) {
    const Decl *D = getCursorDecl(C);
    if (!D)
      return cxstring::createEmpty();

    SmallString<128> Str;
    llvm::raw_svector_ostream OS(Str);
    PrintingPolicy *UserPolicy = static_cast<PrintingPolicy *>(cxPolicy);
    D->print(OS, UserPolicy ? *UserPolicy
                            : getCursorContext(C).getPrintingPolicy());

    return cxstring::createDup(OS.str());
  }

  return cxstring::createEmpty();
}

CXString clang_getCursorDisplayName(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return clang_getCursorSpelling(C);

  const Decl *D = getCursorDecl(C);
  if (!D)
    return cxstring::createEmpty();

  PrintingPolicy Policy = getCursorContext(C).getPrintingPolicy();
  if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D))
    D = FunTmpl->getTemplatedDecl();

  if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) {
    SmallString<64> Str;
    llvm::raw_svector_ostream OS(Str);
    OS << *Function;
    if (Function->getPrimaryTemplate())
      OS << "<>";
    OS << "(";
    for (unsigned I = 0, N = Function->getNumParams(); I != N; ++I) {
      if (I)
        OS << ", ";
      OS << Function->getParamDecl(I)->getType().getAsString(Policy);
    }

    if (Function->isVariadic()) {
      if (Function->getNumParams())
        OS << ", ";
      OS << "...";
    }
    OS << ")";
    return cxstring::createDup(OS.str());
  }

  if (const ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(D)) {
    SmallString<64> Str;
    llvm::raw_svector_ostream OS(Str);
    OS << *ClassTemplate;
    OS << "<";
    TemplateParameterList *Params = ClassTemplate->getTemplateParameters();
    for (unsigned I = 0, N = Params->size(); I != N; ++I) {
      if (I)
        OS << ", ";

      NamedDecl *Param = Params->getParam(I);
      if (Param->getIdentifier()) {
        OS << Param->getIdentifier()->getName();
        continue;
      }

      // There is no parameter name, which makes this tricky. Try to come up
      // with something useful that isn't too long.
      if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
        if (const auto *TC = TTP->getTypeConstraint()) {
          TC->getConceptNameInfo().printName(OS, Policy);
          if (TC->hasExplicitTemplateArgs())
            OS << "<...>";
        } else
          OS << (TTP->wasDeclaredWithTypename() ? "typename" : "class");
      else if (NonTypeTemplateParmDecl *NTTP =
                   dyn_cast<NonTypeTemplateParmDecl>(Param))
        OS << NTTP->getType().getAsString(Policy);
      else
        OS << "template<...> class";
    }

    OS << ">";
    return cxstring::createDup(OS.str());
  }

  if (const ClassTemplateSpecializationDecl *ClassSpec =
          dyn_cast<ClassTemplateSpecializationDecl>(D)) {
    // If the type was explicitly written, use that.
    if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
      return cxstring::createDup(TSInfo->getType().getAsString(Policy));

    SmallString<128> Str;
    llvm::raw_svector_ostream OS(Str);
    OS << *ClassSpec;
    printTemplateArgumentList(OS, ClassSpec->getTemplateArgs().asArray(),
                              Policy);
    return cxstring::createDup(OS.str());
  }

  return clang_getCursorSpelling(C);
}

CXString clang_getCursorKindSpelling(enum CXCursorKind Kind) {
  switch (Kind) {
  case CXCursor_FunctionDecl:
    return cxstring::createRef("FunctionDecl");
  case CXCursor_TypedefDecl:
    return cxstring::createRef("TypedefDecl");
  case CXCursor_EnumDecl:
    return cxstring::createRef("EnumDecl");
  case CXCursor_EnumConstantDecl:
    return cxstring::createRef("EnumConstantDecl");
  case CXCursor_StructDecl:
    return cxstring::createRef("StructDecl");
  case CXCursor_UnionDecl:
    return cxstring::createRef("UnionDecl");
  case CXCursor_ClassDecl:
    return cxstring::createRef("ClassDecl");
  case CXCursor_FieldDecl:
    return cxstring::createRef("FieldDecl");
  case CXCursor_VarDecl:
    return cxstring::createRef("VarDecl");
  case CXCursor_ParmDecl:
    return cxstring::createRef("ParmDecl");
  case CXCursor_ObjCInterfaceDecl:
    return cxstring::createRef("ObjCInterfaceDecl");
  case CXCursor_ObjCCategoryDecl:
    return cxstring::createRef("ObjCCategoryDecl");
  case CXCursor_ObjCProtocolDecl:
    return cxstring::createRef("ObjCProtocolDecl");
  case CXCursor_ObjCPropertyDecl:
    return cxstring::createRef("ObjCPropertyDecl");
  case CXCursor_ObjCIvarDecl:
    return cxstring::createRef("ObjCIvarDecl");
  case CXCursor_ObjCInstanceMethodDecl:
    return cxstring::createRef("ObjCInstanceMethodDecl");
  case CXCursor_ObjCClassMethodDecl:
    return cxstring::createRef("ObjCClassMethodDecl");
  case CXCursor_ObjCImplementationDecl:
    return cxstring::createRef("ObjCImplementationDecl");
  case CXCursor_ObjCCategoryImplDecl:
    return cxstring::createRef("ObjCCategoryImplDecl");
  case CXCursor_CXXMethod:
    return cxstring::createRef("CXXMethod");
  case CXCursor_UnexposedDecl:
    return cxstring::createRef("UnexposedDecl");
  case CXCursor_ObjCSuperClassRef:
    return cxstring::createRef("ObjCSuperClassRef");
  case CXCursor_ObjCProtocolRef:
    return cxstring::createRef("ObjCProtocolRef");
  case CXCursor_ObjCClassRef:
    return cxstring::createRef("ObjCClassRef");
  case CXCursor_TypeRef:
    return cxstring::createRef("TypeRef");
  case CXCursor_TemplateRef:
    return cxstring::createRef("TemplateRef");
  case CXCursor_NamespaceRef:
    return cxstring::createRef("NamespaceRef");
  case CXCursor_MemberRef:
    return cxstring::createRef("MemberRef");
  case CXCursor_LabelRef:
    return cxstring::createRef("LabelRef");
  case CXCursor_OverloadedDeclRef:
    return cxstring::createRef("OverloadedDeclRef");
  case CXCursor_VariableRef:
    return cxstring::createRef("VariableRef");
  case CXCursor_IntegerLiteral:
    return cxstring::createRef("IntegerLiteral");
  case CXCursor_FixedPointLiteral:
    return cxstring::createRef("FixedPointLiteral");
  case CXCursor_FloatingLiteral:
    return cxstring::createRef("FloatingLiteral");
  case CXCursor_ImaginaryLiteral:
    return cxstring::createRef("ImaginaryLiteral");
  case CXCursor_StringLiteral:
    return cxstring::createRef("StringLiteral");
  case CXCursor_CharacterLiteral:
    return cxstring::createRef("CharacterLiteral");
  case CXCursor_ParenExpr:
    return cxstring::createRef("ParenExpr");
  case CXCursor_UnaryOperator:
    return cxstring::createRef("UnaryOperator");
  case CXCursor_ArraySubscriptExpr:
    return cxstring::createRef("ArraySubscriptExpr");
  case CXCursor_OMPArraySectionExpr:
    return cxstring::createRef("OMPArraySectionExpr");
  case CXCursor_OMPArrayShapingExpr:
    return cxstring::createRef("OMPArrayShapingExpr");
  case CXCursor_OMPIteratorExpr:
    return cxstring::createRef("OMPIteratorExpr");
  case CXCursor_BinaryOperator:
    return cxstring::createRef("BinaryOperator");
  case CXCursor_CompoundAssignOperator:
    return cxstring::createRef("CompoundAssignOperator");
  case CXCursor_ConditionalOperator:
    return cxstring::createRef("ConditionalOperator");
  case CXCursor_CStyleCastExpr:
    return cxstring::createRef("CStyleCastExpr");
  case CXCursor_CompoundLiteralExpr:
    return cxstring::createRef("CompoundLiteralExpr");
  case CXCursor_InitListExpr:
    return cxstring::createRef("InitListExpr");
  case CXCursor_AddrLabelExpr:
    return cxstring::createRef("AddrLabelExpr");
  case CXCursor_StmtExpr:
    return cxstring::createRef("StmtExpr");
  case CXCursor_GenericSelectionExpr:
    return cxstring::createRef("GenericSelectionExpr");
  case CXCursor_GNUNullExpr:
    return cxstring::createRef("GNUNullExpr");
  case CXCursor_CXXStaticCastExpr:
    return cxstring::createRef("CXXStaticCastExpr");
  case CXCursor_CXXDynamicCastExpr:
    return cxstring::createRef("CXXDynamicCastExpr");
  case CXCursor_CXXReinterpretCastExpr:
    return cxstring::createRef("CXXReinterpretCastExpr");
  case CXCursor_CXXConstCastExpr:
    return cxstring::createRef("CXXConstCastExpr");
  case CXCursor_CXXFunctionalCastExpr:
    return cxstring::createRef("CXXFunctionalCastExpr");
  case CXCursor_CXXAddrspaceCastExpr:
    return cxstring::createRef("CXXAddrspaceCastExpr");
  case CXCursor_CXXTypeidExpr:
    return cxstring::createRef("CXXTypeidExpr");
  case CXCursor_CXXBoolLiteralExpr:
    return cxstring::createRef("CXXBoolLiteralExpr");
  case CXCursor_CXXNullPtrLiteralExpr:
    return cxstring::createRef("CXXNullPtrLiteralExpr");
  case CXCursor_CXXThisExpr:
    return cxstring::createRef("CXXThisExpr");
  case CXCursor_CXXThrowExpr:
    return cxstring::createRef("CXXThrowExpr");
  case CXCursor_CXXNewExpr:
    return cxstring::createRef("CXXNewExpr");
  case CXCursor_CXXDeleteExpr:
    return cxstring::createRef("CXXDeleteExpr");
  case CXCursor_UnaryExpr:
    return cxstring::createRef("UnaryExpr");
  case CXCursor_ObjCStringLiteral:
    return cxstring::createRef("ObjCStringLiteral");
  case CXCursor_ObjCBoolLiteralExpr:
    return cxstring::createRef("ObjCBoolLiteralExpr");
  case CXCursor_ObjCAvailabilityCheckExpr:
    return cxstring::createRef("ObjCAvailabilityCheckExpr");
  case CXCursor_ObjCSelfExpr:
    return cxstring::createRef("ObjCSelfExpr");
  case CXCursor_ObjCEncodeExpr:
    return cxstring::createRef("ObjCEncodeExpr");
  case CXCursor_ObjCSelectorExpr:
    return cxstring::createRef("ObjCSelectorExpr");
  case CXCursor_ObjCProtocolExpr:
    return cxstring::createRef("ObjCProtocolExpr");
  case CXCursor_ObjCBridgedCastExpr:
    return cxstring::createRef("ObjCBridgedCastExpr");
  case CXCursor_BlockExpr:
    return cxstring::createRef("BlockExpr");
  case CXCursor_PackExpansionExpr:
    return cxstring::createRef("PackExpansionExpr");
  case CXCursor_SizeOfPackExpr:
    return cxstring::createRef("SizeOfPackExpr");
  case CXCursor_LambdaExpr:
    return cxstring::createRef("LambdaExpr");
  case CXCursor_UnexposedExpr:
    return cxstring::createRef("UnexposedExpr");
  case CXCursor_DeclRefExpr:
    return cxstring::createRef("DeclRefExpr");
  case CXCursor_MemberRefExpr:
    return cxstring::createRef("MemberRefExpr");
  case CXCursor_CallExpr:
    return cxstring::createRef("CallExpr");
  case CXCursor_ObjCMessageExpr:
    return cxstring::createRef("ObjCMessageExpr");
  case CXCursor_BuiltinBitCastExpr:
    return cxstring::createRef("BuiltinBitCastExpr");
  case CXCursor_UnexposedStmt:
    return cxstring::createRef("UnexposedStmt");
  case CXCursor_DeclStmt:
    return cxstring::createRef("DeclStmt");
  case CXCursor_LabelStmt:
    return cxstring::createRef("LabelStmt");
  case CXCursor_CompoundStmt:
    return cxstring::createRef("CompoundStmt");
  case CXCursor_CaseStmt:
    return cxstring::createRef("CaseStmt");
  case CXCursor_DefaultStmt:
    return cxstring::createRef("DefaultStmt");
  case CXCursor_IfStmt:
    return cxstring::createRef("IfStmt");
  case CXCursor_SwitchStmt:
    return cxstring::createRef("SwitchStmt");
  case CXCursor_WhileStmt:
    return cxstring::createRef("WhileStmt");
  case CXCursor_DoStmt:
    return cxstring::createRef("DoStmt");
  case CXCursor_ForStmt:
    return cxstring::createRef("ForStmt");
  case CXCursor_GotoStmt:
    return cxstring::createRef("GotoStmt");
  case CXCursor_IndirectGotoStmt:
    return cxstring::createRef("IndirectGotoStmt");
  case CXCursor_ContinueStmt:
    return cxstring::createRef("ContinueStmt");
  case CXCursor_BreakStmt:
    return cxstring::createRef("BreakStmt");
  case CXCursor_ReturnStmt:
    return cxstring::createRef("ReturnStmt");
  case CXCursor_GCCAsmStmt:
    return cxstring::createRef("GCCAsmStmt");
  case CXCursor_MSAsmStmt:
    return cxstring::createRef("MSAsmStmt");
  case CXCursor_ObjCAtTryStmt:
    return cxstring::createRef("ObjCAtTryStmt");
  case CXCursor_ObjCAtCatchStmt:
    return cxstring::createRef("ObjCAtCatchStmt");
  case CXCursor_ObjCAtFinallyStmt:
    return cxstring::createRef("ObjCAtFinallyStmt");
  case CXCursor_ObjCAtThrowStmt:
    return cxstring::createRef("ObjCAtThrowStmt");
  case CXCursor_ObjCAtSynchronizedStmt:
    return cxstring::createRef("ObjCAtSynchronizedStmt");
  case CXCursor_ObjCAutoreleasePoolStmt:
    return cxstring::createRef("ObjCAutoreleasePoolStmt");
  case CXCursor_ObjCForCollectionStmt:
    return cxstring::createRef("ObjCForCollectionStmt");
  case CXCursor_CXXCatchStmt:
    return cxstring::createRef("CXXCatchStmt");
  case CXCursor_CXXTryStmt:
    return cxstring::createRef("CXXTryStmt");
  case CXCursor_CXXForRangeStmt:
    return cxstring::createRef("CXXForRangeStmt");
  case CXCursor_SEHTryStmt:
    return cxstring::createRef("SEHTryStmt");
  case CXCursor_SEHExceptStmt:
    return cxstring::createRef("SEHExceptStmt");
  case CXCursor_SEHFinallyStmt:
    return cxstring::createRef("SEHFinallyStmt");
  case CXCursor_SEHLeaveStmt:
    return cxstring::createRef("SEHLeaveStmt");
  case CXCursor_NullStmt:
    return cxstring::createRef("NullStmt");
  case CXCursor_InvalidFile:
    return cxstring::createRef("InvalidFile");
  case CXCursor_InvalidCode:
    return cxstring::createRef("InvalidCode");
  case CXCursor_NoDeclFound:
    return cxstring::createRef("NoDeclFound");
  case CXCursor_NotImplemented:
    return cxstring::createRef("NotImplemented");
  case CXCursor_TranslationUnit:
    return cxstring::createRef("TranslationUnit");
  case CXCursor_UnexposedAttr:
    return cxstring::createRef("UnexposedAttr");
  case CXCursor_IBActionAttr:
    return cxstring::createRef("attribute(ibaction)");
  case CXCursor_IBOutletAttr:
    return cxstring::createRef("attribute(iboutlet)");
  case CXCursor_IBOutletCollectionAttr:
    return cxstring::createRef("attribute(iboutletcollection)");
  case CXCursor_CXXFinalAttr:
    return cxstring::createRef("attribute(final)");
  case CXCursor_CXXOverrideAttr:
    return cxstring::createRef("attribute(override)");
  case CXCursor_AnnotateAttr:
    return cxstring::createRef("attribute(annotate)");
  case CXCursor_AsmLabelAttr:
    return cxstring::createRef("asm label");
  case CXCursor_PackedAttr:
    return cxstring::createRef("attribute(packed)");
  case CXCursor_PureAttr:
    return cxstring::createRef("attribute(pure)");
  case CXCursor_ConstAttr:
    return cxstring::createRef("attribute(const)");
  case CXCursor_NoDuplicateAttr:
    return cxstring::createRef("attribute(noduplicate)");
  case CXCursor_CUDAConstantAttr:
    return cxstring::createRef("attribute(constant)");
  case CXCursor_CUDADeviceAttr:
    return cxstring::createRef("attribute(device)");
  case CXCursor_CUDAGlobalAttr:
    return cxstring::createRef("attribute(global)");
  case CXCursor_CUDAHostAttr:
    return cxstring::createRef("attribute(host)");
  case CXCursor_CUDASharedAttr:
    return cxstring::createRef("attribute(shared)");
  case CXCursor_VisibilityAttr:
    return cxstring::createRef("attribute(visibility)");
  case CXCursor_DLLExport:
    return cxstring::createRef("attribute(dllexport)");
  case CXCursor_DLLImport:
    return cxstring::createRef("attribute(dllimport)");
  case CXCursor_NSReturnsRetained:
    return cxstring::createRef("attribute(ns_returns_retained)");
  case CXCursor_NSReturnsNotRetained:
    return cxstring::createRef("attribute(ns_returns_not_retained)");
  case CXCursor_NSReturnsAutoreleased:
    return cxstring::createRef("attribute(ns_returns_autoreleased)");
  case CXCursor_NSConsumesSelf:
    return cxstring::createRef("attribute(ns_consumes_self)");
  case CXCursor_NSConsumed:
    return cxstring::createRef("attribute(ns_consumed)");
  case CXCursor_ObjCException:
    return cxstring::createRef("attribute(objc_exception)");
  case CXCursor_ObjCNSObject:
    return cxstring::createRef("attribute(NSObject)");
  case CXCursor_ObjCIndependentClass:
    return cxstring::createRef("attribute(objc_independent_class)");
  case CXCursor_ObjCPreciseLifetime:
    return cxstring::createRef("attribute(objc_precise_lifetime)");
  case CXCursor_ObjCReturnsInnerPointer:
    return cxstring::createRef("attribute(objc_returns_inner_pointer)");
  case CXCursor_ObjCRequiresSuper:
    return cxstring::createRef("attribute(objc_requires_super)");
  case CXCursor_ObjCRootClass:
    return cxstring::createRef("attribute(objc_root_class)");
  case CXCursor_ObjCSubclassingRestricted:
    return cxstring::createRef("attribute(objc_subclassing_restricted)");
  case CXCursor_ObjCExplicitProtocolImpl:
    return cxstring::createRef(
        "attribute(objc_protocol_requires_explicit_implementation)");
  case CXCursor_ObjCDesignatedInitializer:
    return cxstring::createRef("attribute(objc_designated_initializer)");
  case CXCursor_ObjCRuntimeVisible:
    return cxstring::createRef("attribute(objc_runtime_visible)");
  case CXCursor_ObjCBoxable:
    return cxstring::createRef("attribute(objc_boxable)");
  case CXCursor_FlagEnum:
    return cxstring::createRef("attribute(flag_enum)");
  case CXCursor_PreprocessingDirective:
    return cxstring::createRef("preprocessing directive");
  case CXCursor_MacroDefinition:
    return cxstring::createRef("macro definition");
  case CXCursor_MacroExpansion:
    return cxstring::createRef("macro expansion");
  case CXCursor_InclusionDirective:
    return cxstring::createRef("inclusion directive");
  case CXCursor_Namespace:
    return cxstring::createRef("Namespace");
  case CXCursor_LinkageSpec:
    return cxstring::createRef("LinkageSpec");
  case CXCursor_CXXBaseSpecifier:
    return cxstring::createRef("C++ base class specifier");
  case CXCursor_Constructor:
    return cxstring::createRef("CXXConstructor");
  case CXCursor_Destructor:
    return cxstring::createRef("CXXDestructor");
  case CXCursor_ConversionFunction:
    return cxstring::createRef("CXXConversion");
  case CXCursor_TemplateTypeParameter:
    return cxstring::createRef("TemplateTypeParameter");
  case CXCursor_NonTypeTemplateParameter:
    return cxstring::createRef("NonTypeTemplateParameter");
  case CXCursor_TemplateTemplateParameter:
    return cxstring::createRef("TemplateTemplateParameter");
  case CXCursor_FunctionTemplate:
    return cxstring::createRef("FunctionTemplate");
  case CXCursor_ClassTemplate:
    return cxstring::createRef("ClassTemplate");
  case CXCursor_ClassTemplatePartialSpecialization:
    return cxstring::createRef("ClassTemplatePartialSpecialization");
  case CXCursor_NamespaceAlias:
    return cxstring::createRef("NamespaceAlias");
  case CXCursor_UsingDirective:
    return cxstring::createRef("UsingDirective");
  case CXCursor_UsingDeclaration:
    return cxstring::createRef("UsingDeclaration");
  case CXCursor_TypeAliasDecl:
    return cxstring::createRef("TypeAliasDecl");
  case CXCursor_ObjCSynthesizeDecl:
    return cxstring::createRef("ObjCSynthesizeDecl");
  case CXCursor_ObjCDynamicDecl:
    return cxstring::createRef("ObjCDynamicDecl");
  case CXCursor_CXXAccessSpecifier:
    return cxstring::createRef("CXXAccessSpecifier");
  case CXCursor_ModuleImportDecl:
    return cxstring::createRef("ModuleImport");
  case CXCursor_OMPParallelDirective:
    return cxstring::createRef("OMPParallelDirective");
  case CXCursor_OMPSimdDirective:
    return cxstring::createRef("OMPSimdDirective");
  case CXCursor_OMPForDirective:
    return cxstring::createRef("OMPForDirective");
  case CXCursor_OMPForSimdDirective:
    return cxstring::createRef("OMPForSimdDirective");
  case CXCursor_OMPSectionsDirective:
    return cxstring::createRef("OMPSectionsDirective");
  case CXCursor_OMPSectionDirective:
    return cxstring::createRef("OMPSectionDirective");
  case CXCursor_OMPSingleDirective:
    return cxstring::createRef("OMPSingleDirective");
  case CXCursor_OMPMasterDirective:
    return cxstring::createRef("OMPMasterDirective");
  case CXCursor_OMPCriticalDirective:
    return cxstring::createRef("OMPCriticalDirective");
  case CXCursor_OMPParallelForDirective:
    return cxstring::createRef("OMPParallelForDirective");
  case CXCursor_OMPParallelForSimdDirective:
    return cxstring::createRef("OMPParallelForSimdDirective");
  case CXCursor_OMPParallelMasterDirective:
    return cxstring::createRef("OMPParallelMasterDirective");
  case CXCursor_OMPParallelSectionsDirective:
    return cxstring::createRef("OMPParallelSectionsDirective");
  case CXCursor_OMPTaskDirective:
    return cxstring::createRef("OMPTaskDirective");
  case CXCursor_OMPTaskyieldDirective:
    return cxstring::createRef("OMPTaskyieldDirective");
  case CXCursor_OMPBarrierDirective:
    return cxstring::createRef("OMPBarrierDirective");
  case CXCursor_OMPTaskwaitDirective:
    return cxstring::createRef("OMPTaskwaitDirective");
  case CXCursor_OMPTaskgroupDirective:
    return cxstring::createRef("OMPTaskgroupDirective");
  case CXCursor_OMPFlushDirective:
    return cxstring::createRef("OMPFlushDirective");
  case CXCursor_OMPDepobjDirective:
    return cxstring::createRef("OMPDepobjDirective");
  case CXCursor_OMPScanDirective:
    return cxstring::createRef("OMPScanDirective");
  case CXCursor_OMPOrderedDirective:
    return cxstring::createRef("OMPOrderedDirective");
  case CXCursor_OMPAtomicDirective:
    return cxstring::createRef("OMPAtomicDirective");
  case CXCursor_OMPTargetDirective:
    return cxstring::createRef("OMPTargetDirective");
  case CXCursor_OMPTargetDataDirective:
    return cxstring::createRef("OMPTargetDataDirective");
  case CXCursor_OMPTargetEnterDataDirective:
    return cxstring::createRef("OMPTargetEnterDataDirective");
  case CXCursor_OMPTargetExitDataDirective:
    return cxstring::createRef("OMPTargetExitDataDirective");
  case CXCursor_OMPTargetParallelDirective:
    return cxstring::createRef("OMPTargetParallelDirective");
  case CXCursor_OMPTargetParallelForDirective:
    return cxstring::createRef("OMPTargetParallelForDirective");
  case CXCursor_OMPTargetUpdateDirective:
    return cxstring::createRef("OMPTargetUpdateDirective");
  case CXCursor_OMPTeamsDirective:
    return cxstring::createRef("OMPTeamsDirective");
  case CXCursor_OMPCancellationPointDirective:
    return cxstring::createRef("OMPCancellationPointDirective");
  case CXCursor_OMPCancelDirective:
    return cxstring::createRef("OMPCancelDirective");
  case CXCursor_OMPTaskLoopDirective:
    return cxstring::createRef("OMPTaskLoopDirective");
  case CXCursor_OMPTaskLoopSimdDirective:
    return cxstring::createRef("OMPTaskLoopSimdDirective");
  case CXCursor_OMPMasterTaskLoopDirective:
    return cxstring::createRef("OMPMasterTaskLoopDirective");
  case CXCursor_OMPMasterTaskLoopSimdDirective:
    return cxstring::createRef("OMPMasterTaskLoopSimdDirective");
  case CXCursor_OMPParallelMasterTaskLoopDirective:
    return cxstring::createRef("OMPParallelMasterTaskLoopDirective");
  case CXCursor_OMPParallelMasterTaskLoopSimdDirective:
    return cxstring::createRef("OMPParallelMasterTaskLoopSimdDirective");
  case CXCursor_OMPDistributeDirective:
    return cxstring::createRef("OMPDistributeDirective");
  case CXCursor_OMPDistributeParallelForDirective:
    return cxstring::createRef("OMPDistributeParallelForDirective");
  case CXCursor_OMPDistributeParallelForSimdDirective:
    return cxstring::createRef("OMPDistributeParallelForSimdDirective");
  case CXCursor_OMPDistributeSimdDirective:
    return cxstring::createRef("OMPDistributeSimdDirective");
  case CXCursor_OMPTargetParallelForSimdDirective:
    return cxstring::createRef("OMPTargetParallelForSimdDirective");
  case CXCursor_OMPTargetSimdDirective:
    return cxstring::createRef("OMPTargetSimdDirective");
  case CXCursor_OMPTeamsDistributeDirective:
    return cxstring::createRef("OMPTeamsDistributeDirective");
  case CXCursor_OMPTeamsDistributeSimdDirective:
    return cxstring::createRef("OMPTeamsDistributeSimdDirective");
  case CXCursor_OMPTeamsDistributeParallelForSimdDirective:
    return cxstring::createRef("OMPTeamsDistributeParallelForSimdDirective");
  case CXCursor_OMPTeamsDistributeParallelForDirective:
    return cxstring::createRef("OMPTeamsDistributeParallelForDirective");
  case CXCursor_OMPTargetTeamsDirective:
    return cxstring::createRef("OMPTargetTeamsDirective");
  case CXCursor_OMPTargetTeamsDistributeDirective:
    return cxstring::createRef("OMPTargetTeamsDistributeDirective");
  case CXCursor_OMPTargetTeamsDistributeParallelForDirective:
    return cxstring::createRef("OMPTargetTeamsDistributeParallelForDirective");
  case CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective:
    return cxstring::createRef(
        "OMPTargetTeamsDistributeParallelForSimdDirective");
  case CXCursor_OMPTargetTeamsDistributeSimdDirective:
    return cxstring::createRef("OMPTargetTeamsDistributeSimdDirective");
  case CXCursor_OverloadCandidate:
    return cxstring::createRef("OverloadCandidate");
  case CXCursor_TypeAliasTemplateDecl:
    return cxstring::createRef("TypeAliasTemplateDecl");
  case CXCursor_StaticAssert:
    return cxstring::createRef("StaticAssert");
  case CXCursor_FriendDecl:
    return cxstring::createRef("FriendDecl");
  case CXCursor_ConvergentAttr:
    return cxstring::createRef("attribute(convergent)");
  case CXCursor_WarnUnusedAttr:
    return cxstring::createRef("attribute(warn_unused)");
  case CXCursor_WarnUnusedResultAttr:
    return cxstring::createRef("attribute(warn_unused_result)");
  case CXCursor_AlignedAttr:
    return cxstring::createRef("attribute(aligned)");
  }

  llvm_unreachable("Unhandled CXCursorKind");
}

struct GetCursorData {
  SourceLocation TokenBeginLoc;
  bool PointsAtMacroArgExpansion;
  bool VisitedObjCPropertyImplDecl;
  SourceLocation VisitedDeclaratorDeclStartLoc;
  CXCursor &BestCursor;

  GetCursorData(SourceManager &SM, SourceLocation tokenBegin,
                CXCursor &outputCursor)
      : TokenBeginLoc(tokenBegin), BestCursor(outputCursor) {
    PointsAtMacroArgExpansion = SM.isMacroArgExpansion(tokenBegin);
    VisitedObjCPropertyImplDecl = false;
  }
};

static enum CXChildVisitResult
GetCursorVisitor(CXCursor cursor, CXCursor parent, CXClientData client_data) {
  GetCursorData *Data = static_cast<GetCursorData *>(client_data);
  CXCursor *BestCursor = &Data->BestCursor;

  // If we point inside a macro argument we should provide info of what the
  // token is so use the actual cursor, don't replace it with a macro expansion
  // cursor.
  if (cursor.kind == CXCursor_MacroExpansion && Data->PointsAtMacroArgExpansion)
    return CXChildVisit_Recurse;

  if (clang_isDeclaration(cursor.kind)) {
    // Avoid having the implicit methods override the property decls.
    if (const ObjCMethodDecl *MD =
            dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
      if (MD->isImplicit())
        return CXChildVisit_Break;

    } else if (const ObjCInterfaceDecl *ID =
                   dyn_cast_or_null<ObjCInterfaceDecl>(getCursorDecl(cursor))) {
      // Check that when we have multiple @class references in the same line,
      // that later ones do not override the previous ones.
      // If we have:
      // @class Foo, Bar;
      // source ranges for both start at '@', so 'Bar' will end up overriding
      // 'Foo' even though the cursor location was at 'Foo'.
      if (BestCursor->kind == CXCursor_ObjCInterfaceDecl ||
          BestCursor->kind == CXCursor_ObjCClassRef)
        if (const ObjCInterfaceDecl *PrevID =
                dyn_cast_or_null<ObjCInterfaceDecl>(
                    getCursorDecl(*BestCursor))) {
          if (PrevID != ID && !PrevID->isThisDeclarationADefinition() &&
              !ID->isThisDeclarationADefinition())
            return CXChildVisit_Break;
        }

    } else if (const DeclaratorDecl *DD =
                   dyn_cast_or_null<DeclaratorDecl>(getCursorDecl(cursor))) {
      SourceLocation StartLoc = DD->getSourceRange().getBegin();
      // Check that when we have multiple declarators in the same line,
      // that later ones do not override the previous ones.
      // If we have:
      // int Foo, Bar;
      // source ranges for both start at 'int', so 'Bar' will end up overriding
      // 'Foo' even though the cursor location was at 'Foo'.
      if (Data->VisitedDeclaratorDeclStartLoc == StartLoc)
        return CXChildVisit_Break;
      Data->VisitedDeclaratorDeclStartLoc = StartLoc;

    } else if (const ObjCPropertyImplDecl *PropImp =
                   dyn_cast_or_null<ObjCPropertyImplDecl>(
                       getCursorDecl(cursor))) {
      (void)PropImp;
      // Check that when we have multiple @synthesize in the same line,
      // that later ones do not override the previous ones.
      // If we have:
      // @synthesize Foo, Bar;
      // source ranges for both start at '@', so 'Bar' will end up overriding
      // 'Foo' even though the cursor location was at 'Foo'.
      if (Data->VisitedObjCPropertyImplDecl)
        return CXChildVisit_Break;
      Data->VisitedObjCPropertyImplDecl = true;
    }
  }

  if (clang_isExpression(cursor.kind) &&
      clang_isDeclaration(BestCursor->kind)) {
    if (const Decl *D = getCursorDecl(*BestCursor)) {
      // Avoid having the cursor of an expression replace the declaration cursor
      // when the expression source range overlaps the declaration range.
      // This can happen for C++ constructor expressions whose range generally
      // include the variable declaration, e.g.:
      //  MyCXXClass foo; // Make sure pointing at 'foo' returns a VarDecl
      //  cursor.
      if (D->getLocation().isValid() && Data->TokenBeginLoc.isValid() &&
          D->getLocation() == Data->TokenBeginLoc)
        return CXChildVisit_Break;
    }
  }

  // If our current best cursor is the construction of a temporary object,
  // don't replace that cursor with a type reference, because we want
  // clang_getCursor() to point at the constructor.
  if (clang_isExpression(BestCursor->kind) &&
      isa<CXXTemporaryObjectExpr>(getCursorExpr(*BestCursor)) &&
      cursor.kind == CXCursor_TypeRef) {
    // Keep the cursor pointing at CXXTemporaryObjectExpr but also mark it
    // as having the actual point on the type reference.
    *BestCursor = getTypeRefedCallExprCursor(*BestCursor);
    return CXChildVisit_Recurse;
  }

  // If we already have an Objective-C superclass reference, don't
  // update it further.
  if (BestCursor->kind == CXCursor_ObjCSuperClassRef)
    return CXChildVisit_Break;

  *BestCursor = cursor;
  return CXChildVisit_Recurse;
}

CXCursor clang_getCursor(CXTranslationUnit TU, CXSourceLocation Loc) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return clang_getNullCursor();
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  ASTUnit::ConcurrencyCheck Check(*CXXUnit);

  SourceLocation SLoc = cxloc::translateSourceLocation(Loc);
  CXCursor Result = cxcursor::getCursor(TU, SLoc);

  LOG_FUNC_SECTION {
    CXFile SearchFile;
    unsigned SearchLine, SearchColumn;
    CXFile ResultFile;
    unsigned ResultLine, ResultColumn;
    CXString SearchFileName, ResultFileName, KindSpelling, USR;
    const char *IsDef = clang_isCursorDefinition(Result) ? " (Definition)" : "";
    CXSourceLocation ResultLoc = clang_getCursorLocation(Result);

    clang_getFileLocation(Loc, &SearchFile, &SearchLine, &SearchColumn,
                          nullptr);
    clang_getFileLocation(ResultLoc, &ResultFile, &ResultLine, &ResultColumn,
                          nullptr);
    SearchFileName = clang_getFileName(SearchFile);
    ResultFileName = clang_getFileName(ResultFile);
    KindSpelling = clang_getCursorKindSpelling(Result.kind);
    USR = clang_getCursorUSR(Result);
    *Log << llvm::format("(%s:%d:%d) = %s", clang_getCString(SearchFileName),
                         SearchLine, SearchColumn,
                         clang_getCString(KindSpelling))
         << llvm::format("(%s:%d:%d):%s%s", clang_getCString(ResultFileName),
                         ResultLine, ResultColumn, clang_getCString(USR),
                         IsDef);
    clang_disposeString(SearchFileName);
    clang_disposeString(ResultFileName);
    clang_disposeString(KindSpelling);
    clang_disposeString(USR);

    CXCursor Definition = clang_getCursorDefinition(Result);
    if (!clang_equalCursors(Definition, clang_getNullCursor())) {
      CXSourceLocation DefinitionLoc = clang_getCursorLocation(Definition);
      CXString DefinitionKindSpelling =
          clang_getCursorKindSpelling(Definition.kind);
      CXFile DefinitionFile;
      unsigned DefinitionLine, DefinitionColumn;
      clang_getFileLocation(DefinitionLoc, &DefinitionFile, &DefinitionLine,
                            &DefinitionColumn, nullptr);
      CXString DefinitionFileName = clang_getFileName(DefinitionFile);
      *Log << llvm::format("  -> %s(%s:%d:%d)",
                           clang_getCString(DefinitionKindSpelling),
                           clang_getCString(DefinitionFileName), DefinitionLine,
                           DefinitionColumn);
      clang_disposeString(DefinitionFileName);
      clang_disposeString(DefinitionKindSpelling);
    }
  }

  return Result;
}

CXCursor clang_getNullCursor(void) {
  return MakeCXCursorInvalid(CXCursor_InvalidFile);
}

unsigned clang_equalCursors(CXCursor X, CXCursor Y) {
  // Clear out the "FirstInDeclGroup" part in a declaration cursor, since we
  // can't set consistently. For example, when visiting a DeclStmt we will set
  // it but we don't set it on the result of clang_getCursorDefinition for
  // a reference of the same declaration.
  // FIXME: Setting "FirstInDeclGroup" in CXCursors is a hack that only works
  // when visiting a DeclStmt currently, the AST should be enhanced to be able
  // to provide that kind of info.
  if (clang_isDeclaration(X.kind))
    X.data[1] = nullptr;
  if (clang_isDeclaration(Y.kind))
    Y.data[1] = nullptr;

  return X == Y;
}

unsigned clang_hashCursor(CXCursor C) {
  unsigned Index = 0;
  if (clang_isExpression(C.kind) || clang_isStatement(C.kind))
    Index = 1;

  return llvm::DenseMapInfo<std::pair<unsigned, const void *>>::getHashValue(
      std::make_pair(C.kind, C.data[Index]));
}

unsigned clang_isInvalid(enum CXCursorKind K) {
  return K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid;
}

unsigned clang_isDeclaration(enum CXCursorKind K) {
  return (K >= CXCursor_FirstDecl && K <= CXCursor_LastDecl) ||
         (K >= CXCursor_FirstExtraDecl && K <= CXCursor_LastExtraDecl);
}

unsigned clang_isInvalidDeclaration(CXCursor C) {
  if (clang_isDeclaration(C.kind)) {
    if (const Decl *D = getCursorDecl(C))
      return D->isInvalidDecl();
  }

  return 0;
}

unsigned clang_isReference(enum CXCursorKind K) {
  return K >= CXCursor_FirstRef && K <= CXCursor_LastRef;
}

unsigned clang_isExpression(enum CXCursorKind K) {
  return K >= CXCursor_FirstExpr && K <= CXCursor_LastExpr;
}

unsigned clang_isStatement(enum CXCursorKind K) {
  return K >= CXCursor_FirstStmt && K <= CXCursor_LastStmt;
}

unsigned clang_isAttribute(enum CXCursorKind K) {
  return K >= CXCursor_FirstAttr && K <= CXCursor_LastAttr;
}

unsigned clang_isTranslationUnit(enum CXCursorKind K) {
  return K == CXCursor_TranslationUnit;
}

unsigned clang_isPreprocessing(enum CXCursorKind K) {
  return K >= CXCursor_FirstPreprocessing && K <= CXCursor_LastPreprocessing;
}

unsigned clang_isUnexposed(enum CXCursorKind K) {
  switch (K) {
  case CXCursor_UnexposedDecl:
  case CXCursor_UnexposedExpr:
  case CXCursor_UnexposedStmt:
  case CXCursor_UnexposedAttr:
    return true;
  default:
    return false;
  }
}

CXCursorKind clang_getCursorKind(CXCursor C) { return C.kind; }

CXSourceLocation clang_getCursorLocation(CXCursor C) {
  if (clang_isReference(C.kind)) {
    switch (C.kind) {
    case CXCursor_ObjCSuperClassRef: {
      std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
          getCursorObjCSuperClassRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_ObjCProtocolRef: {
      std::pair<const ObjCProtocolDecl *, SourceLocation> P =
          getCursorObjCProtocolRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_ObjCClassRef: {
      std::pair<const ObjCInterfaceDecl *, SourceLocation> P =
          getCursorObjCClassRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_TypeRef: {
      std::pair<const TypeDecl *, SourceLocation> P = getCursorTypeRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_TemplateRef: {
      std::pair<const TemplateDecl *, SourceLocation> P =
          getCursorTemplateRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_NamespaceRef: {
      std::pair<const NamedDecl *, SourceLocation> P = getCursorNamespaceRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_MemberRef: {
      std::pair<const FieldDecl *, SourceLocation> P = getCursorMemberRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_VariableRef: {
      std::pair<const VarDecl *, SourceLocation> P = getCursorVariableRef(C);
      return cxloc::translateSourceLocation(P.first->getASTContext(), P.second);
    }

    case CXCursor_CXXBaseSpecifier: {
      const CXXBaseSpecifier *BaseSpec = getCursorCXXBaseSpecifier(C);
      if (!BaseSpec)
        return clang_getNullLocation();

      if (TypeSourceInfo *TSInfo = BaseSpec->getTypeSourceInfo())
        return cxloc::translateSourceLocation(
            getCursorContext(C), TSInfo->getTypeLoc().getBeginLoc());

      return cxloc::translateSourceLocation(getCursorContext(C),
                                            BaseSpec->getBeginLoc());
    }

    case CXCursor_LabelRef: {
      std::pair<const LabelStmt *, SourceLocation> P = getCursorLabelRef(C);
      return cxloc::translateSourceLocation(getCursorContext(C), P.second);
    }

    case CXCursor_OverloadedDeclRef:
      return cxloc::translateSourceLocation(
          getCursorContext(C), getCursorOverloadedDeclRef(C).second);

    default:
      // FIXME: Need a way to enumerate all non-reference cases.
      llvm_unreachable("Missed a reference kind");
    }
  }

  if (clang_isExpression(C.kind))
    return cxloc::translateSourceLocation(
        getCursorContext(C), getLocationFromExpr(getCursorExpr(C)));

  if (clang_isStatement(C.kind))
    return cxloc::translateSourceLocation(getCursorContext(C),
                                          getCursorStmt(C)->getBeginLoc());

  if (C.kind == CXCursor_PreprocessingDirective) {
    SourceLocation L = cxcursor::getCursorPreprocessingDirective(C).getBegin();
    return cxloc::translateSourceLocation(getCursorContext(C), L);
  }

  if (C.kind == CXCursor_MacroExpansion) {
    SourceLocation L =
        cxcursor::getCursorMacroExpansion(C).getSourceRange().getBegin();
    return cxloc::translateSourceLocation(getCursorContext(C), L);
  }

  if (C.kind == CXCursor_MacroDefinition) {
    SourceLocation L = cxcursor::getCursorMacroDefinition(C)->getLocation();
    return cxloc::translateSourceLocation(getCursorContext(C), L);
  }

  if (C.kind == CXCursor_InclusionDirective) {
    SourceLocation L =
        cxcursor::getCursorInclusionDirective(C)->getSourceRange().getBegin();
    return cxloc::translateSourceLocation(getCursorContext(C), L);
  }

  if (clang_isAttribute(C.kind)) {
    SourceLocation L = cxcursor::getCursorAttr(C)->getLocation();
    return cxloc::translateSourceLocation(getCursorContext(C), L);
  }

  if (!clang_isDeclaration(C.kind))
    return clang_getNullLocation();

  const Decl *D = getCursorDecl(C);
  if (!D)
    return clang_getNullLocation();

  SourceLocation Loc = D->getLocation();
  // FIXME: Multiple variables declared in a single declaration
  // currently lack the information needed to correctly determine their
  // ranges when accounting for the type-specifier.  We use context
  // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
  // and if so, whether it is the first decl.
  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
    if (!cxcursor::isFirstInDeclGroup(C))
      Loc = VD->getLocation();
  }

  // For ObjC methods, give the start location of the method name.
  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
    Loc = MD->getSelectorStartLoc();

  return cxloc::translateSourceLocation(getCursorContext(C), Loc);
}

} // end extern "C"

CXCursor cxcursor::getCursor(CXTranslationUnit TU, SourceLocation SLoc) {
  assert(TU);

  // Guard against an invalid SourceLocation, or we may assert in one
  // of the following calls.
  if (SLoc.isInvalid())
    return clang_getNullCursor();

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);

  // Translate the given source location to make it point at the beginning of
  // the token under the cursor.
  SLoc = Lexer::GetBeginningOfToken(SLoc, CXXUnit->getSourceManager(),
                                    CXXUnit->getASTContext().getLangOpts());

  CXCursor Result = MakeCXCursorInvalid(CXCursor_NoDeclFound);
  if (SLoc.isValid()) {
    GetCursorData ResultData(CXXUnit->getSourceManager(), SLoc, Result);
    CursorVisitor CursorVis(TU, GetCursorVisitor, &ResultData,
                            /*VisitPreprocessorLast=*/true,
                            /*VisitIncludedEntities=*/false,
                            SourceLocation(SLoc));
    CursorVis.visitFileRegion();
  }

  return Result;
}

static SourceRange getRawCursorExtent(CXCursor C) {
  if (clang_isReference(C.kind)) {
    switch (C.kind) {
    case CXCursor_ObjCSuperClassRef:
      return getCursorObjCSuperClassRef(C).second;

    case CXCursor_ObjCProtocolRef:
      return getCursorObjCProtocolRef(C).second;

    case CXCursor_ObjCClassRef:
      return getCursorObjCClassRef(C).second;

    case CXCursor_TypeRef:
      return getCursorTypeRef(C).second;

    case CXCursor_TemplateRef:
      return getCursorTemplateRef(C).second;

    case CXCursor_NamespaceRef:
      return getCursorNamespaceRef(C).second;

    case CXCursor_MemberRef:
      return getCursorMemberRef(C).second;

    case CXCursor_CXXBaseSpecifier:
      return getCursorCXXBaseSpecifier(C)->getSourceRange();

    case CXCursor_LabelRef:
      return getCursorLabelRef(C).second;

    case CXCursor_OverloadedDeclRef:
      return getCursorOverloadedDeclRef(C).second;

    case CXCursor_VariableRef:
      return getCursorVariableRef(C).second;

    default:
      // FIXME: Need a way to enumerate all non-reference cases.
      llvm_unreachable("Missed a reference kind");
    }
  }

  if (clang_isExpression(C.kind))
    return getCursorExpr(C)->getSourceRange();

  if (clang_isStatement(C.kind))
    return getCursorStmt(C)->getSourceRange();

  if (clang_isAttribute(C.kind))
    return getCursorAttr(C)->getRange();

  if (C.kind == CXCursor_PreprocessingDirective)
    return cxcursor::getCursorPreprocessingDirective(C);

  if (C.kind == CXCursor_MacroExpansion) {
    ASTUnit *TU = getCursorASTUnit(C);
    SourceRange Range = cxcursor::getCursorMacroExpansion(C).getSourceRange();
    return TU->mapRangeFromPreamble(Range);
  }

  if (C.kind == CXCursor_MacroDefinition) {
    ASTUnit *TU = getCursorASTUnit(C);
    SourceRange Range = cxcursor::getCursorMacroDefinition(C)->getSourceRange();
    return TU->mapRangeFromPreamble(Range);
  }

  if (C.kind == CXCursor_InclusionDirective) {
    ASTUnit *TU = getCursorASTUnit(C);
    SourceRange Range =
        cxcursor::getCursorInclusionDirective(C)->getSourceRange();
    return TU->mapRangeFromPreamble(Range);
  }

  if (C.kind == CXCursor_TranslationUnit) {
    ASTUnit *TU = getCursorASTUnit(C);
    FileID MainID = TU->getSourceManager().getMainFileID();
    SourceLocation Start = TU->getSourceManager().getLocForStartOfFile(MainID);
    SourceLocation End = TU->getSourceManager().getLocForEndOfFile(MainID);
    return SourceRange(Start, End);
  }

  if (clang_isDeclaration(C.kind)) {
    const Decl *D = cxcursor::getCursorDecl(C);
    if (!D)
      return SourceRange();

    SourceRange R = D->getSourceRange();
    // FIXME: Multiple variables declared in a single declaration
    // currently lack the information needed to correctly determine their
    // ranges when accounting for the type-specifier.  We use context
    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
    // and if so, whether it is the first decl.
    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
      if (!cxcursor::isFirstInDeclGroup(C))
        R.setBegin(VD->getLocation());
    }
    return R;
  }
  return SourceRange();
}

/// Retrieves the "raw" cursor extent, which is then extended to include
/// the decl-specifier-seq for declarations.
static SourceRange getFullCursorExtent(CXCursor C, SourceManager &SrcMgr) {
  if (clang_isDeclaration(C.kind)) {
    const Decl *D = cxcursor::getCursorDecl(C);
    if (!D)
      return SourceRange();

    SourceRange R = D->getSourceRange();

    // Adjust the start of the location for declarations preceded by
    // declaration specifiers.
    SourceLocation StartLoc;
    if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D)) {
      if (TypeSourceInfo *TI = DD->getTypeSourceInfo())
        StartLoc = TI->getTypeLoc().getBeginLoc();
    } else if (const TypedefDecl *Typedef = dyn_cast<TypedefDecl>(D)) {
      if (TypeSourceInfo *TI = Typedef->getTypeSourceInfo())
        StartLoc = TI->getTypeLoc().getBeginLoc();
    }

    if (StartLoc.isValid() && R.getBegin().isValid() &&
        SrcMgr.isBeforeInTranslationUnit(StartLoc, R.getBegin()))
      R.setBegin(StartLoc);

    // FIXME: Multiple variables declared in a single declaration
    // currently lack the information needed to correctly determine their
    // ranges when accounting for the type-specifier.  We use context
    // stored in the CXCursor to determine if the VarDecl is in a DeclGroup,
    // and if so, whether it is the first decl.
    if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
      if (!cxcursor::isFirstInDeclGroup(C))
        R.setBegin(VD->getLocation());
    }

    return R;
  }

  return getRawCursorExtent(C);
}

CXSourceRange clang_getCursorExtent(CXCursor C) {
  SourceRange R = getRawCursorExtent(C);
  if (R.isInvalid())
    return clang_getNullRange();

  return cxloc::translateSourceRange(getCursorContext(C), R);
}

CXCursor clang_getCursorReferenced(CXCursor C) {
  if (clang_isInvalid(C.kind))
    return clang_getNullCursor();

  CXTranslationUnit tu = getCursorTU(C);
  if (clang_isDeclaration(C.kind)) {
    const Decl *D = getCursorDecl(C);
    if (!D)
      return clang_getNullCursor();
    if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
      return MakeCursorOverloadedDeclRef(Using, D->getLocation(), tu);
    if (const ObjCPropertyImplDecl *PropImpl =
            dyn_cast<ObjCPropertyImplDecl>(D))
      if (ObjCPropertyDecl *Property = PropImpl->getPropertyDecl())
        return MakeCXCursor(Property, tu);

    return C;
  }

  if (clang_isExpression(C.kind)) {
    const Expr *E = getCursorExpr(C);
    const Decl *D = getDeclFromExpr(E);
    if (D) {
      CXCursor declCursor = MakeCXCursor(D, tu);
      declCursor = getSelectorIdentifierCursor(getSelectorIdentifierIndex(C),
                                               declCursor);
      return declCursor;
    }

    if (const OverloadExpr *Ovl = dyn_cast_or_null<OverloadExpr>(E))
      return MakeCursorOverloadedDeclRef(Ovl, tu);

    return clang_getNullCursor();
  }

  if (clang_isStatement(C.kind)) {
    const Stmt *S = getCursorStmt(C);
    if (const GotoStmt *Goto = dyn_cast_or_null<GotoStmt>(S))
      if (LabelDecl *label = Goto->getLabel())
        if (LabelStmt *labelS = label->getStmt())
          return MakeCXCursor(labelS, getCursorDecl(C), tu);

    return clang_getNullCursor();
  }

  if (C.kind == CXCursor_MacroExpansion) {
    if (const MacroDefinitionRecord *Def =
            getCursorMacroExpansion(C).getDefinition())
      return MakeMacroDefinitionCursor(Def, tu);
  }

  if (!clang_isReference(C.kind))
    return clang_getNullCursor();

  switch (C.kind) {
  case CXCursor_ObjCSuperClassRef:
    return MakeCXCursor(getCursorObjCSuperClassRef(C).first, tu);

  case CXCursor_ObjCProtocolRef: {
    const ObjCProtocolDecl *Prot = getCursorObjCProtocolRef(C).first;
    if (const ObjCProtocolDecl *Def = Prot->getDefinition())
      return MakeCXCursor(Def, tu);

    return MakeCXCursor(Prot, tu);
  }

  case CXCursor_ObjCClassRef: {
    const ObjCInterfaceDecl *Class = getCursorObjCClassRef(C).first;
    if (const ObjCInterfaceDecl *Def = Class->getDefinition())
      return MakeCXCursor(Def, tu);

    return MakeCXCursor(Class, tu);
  }

  case CXCursor_TypeRef:
    return MakeCXCursor(getCursorTypeRef(C).first, tu);

  case CXCursor_TemplateRef:
    return MakeCXCursor(getCursorTemplateRef(C).first, tu);

  case CXCursor_NamespaceRef:
    return MakeCXCursor(getCursorNamespaceRef(C).first, tu);

  case CXCursor_MemberRef:
    return MakeCXCursor(getCursorMemberRef(C).first, tu);

  case CXCursor_CXXBaseSpecifier: {
    const CXXBaseSpecifier *B = cxcursor::getCursorCXXBaseSpecifier(C);
    return clang_getTypeDeclaration(cxtype::MakeCXType(B->getType(), tu));
  }

  case CXCursor_LabelRef:
    // FIXME: We end up faking the "parent" declaration here because we
    // don't want to make CXCursor larger.
    return MakeCXCursor(
        getCursorLabelRef(C).first,
        cxtu::getASTUnit(tu)->getASTContext().getTranslationUnitDecl(), tu);

  case CXCursor_OverloadedDeclRef:
    return C;

  case CXCursor_VariableRef:
    return MakeCXCursor(getCursorVariableRef(C).first, tu);

  default:
    // We would prefer to enumerate all non-reference cursor kinds here.
    llvm_unreachable("Unhandled reference cursor kind");
  }
}

CXCursor clang_getCursorDefinition(CXCursor C) {
  if (clang_isInvalid(C.kind))
    return clang_getNullCursor();

  CXTranslationUnit TU = getCursorTU(C);

  bool WasReference = false;
  if (clang_isReference(C.kind) || clang_isExpression(C.kind)) {
    C = clang_getCursorReferenced(C);
    WasReference = true;
  }

  if (C.kind == CXCursor_MacroExpansion)
    return clang_getCursorReferenced(C);

  if (!clang_isDeclaration(C.kind))
    return clang_getNullCursor();

  const Decl *D = getCursorDecl(C);
  if (!D)
    return clang_getNullCursor();

  switch (D->getKind()) {
  // Declaration kinds that don't really separate the notions of
  // declaration and definition.
  case Decl::Namespace:
  case Decl::Typedef:
  case Decl::TypeAlias:
  case Decl::TypeAliasTemplate:
  case Decl::TemplateTypeParm:
  case Decl::EnumConstant:
  case Decl::Field:
  case Decl::Binding:
  case Decl::MSProperty:
  case Decl::MSGuid:
  case Decl::IndirectField:
  case Decl::ObjCIvar:
  case Decl::ObjCAtDefsField:
  case Decl::ImplicitParam:
  case Decl::ParmVar:
  case Decl::NonTypeTemplateParm:
  case Decl::TemplateTemplateParm:
  case Decl::ObjCCategoryImpl:
  case Decl::ObjCImplementation:
  case Decl::AccessSpec:
  case Decl::LinkageSpec:
  case Decl::Export:
  case Decl::ObjCPropertyImpl:
  case Decl::FileScopeAsm:
  case Decl::StaticAssert:
  case Decl::Block:
  case Decl::Captured:
  case Decl::OMPCapturedExpr:
  case Decl::Label: // FIXME: Is this right??
  case Decl::ClassScopeFunctionSpecialization:
  case Decl::CXXDeductionGuide:
  case Decl::Import:
  case Decl::OMPThreadPrivate:
  case Decl::OMPAllocate:
  case Decl::OMPDeclareReduction:
  case Decl::OMPDeclareMapper:
  case Decl::OMPRequires:
  case Decl::ObjCTypeParam:
  case Decl::BuiltinTemplate:
  case Decl::PragmaComment:
  case Decl::PragmaDetectMismatch:
  case Decl::UsingPack:
  case Decl::Concept:
  case Decl::LifetimeExtendedTemporary:
  case Decl::RequiresExprBody:
    return C;

  // Declaration kinds that don't make any sense here, but are
  // nonetheless harmless.
  case Decl::Empty:
  case Decl::TranslationUnit:
  case Decl::ExternCContext:
    break;

  // Declaration kinds for which the definition is not resolvable.
  case Decl::UnresolvedUsingTypename:
  case Decl::UnresolvedUsingValue:
    break;

  case Decl::UsingDirective:
    return MakeCXCursor(cast<UsingDirectiveDecl>(D)->getNominatedNamespace(),
                        TU);

  case Decl::NamespaceAlias:
    return MakeCXCursor(cast<NamespaceAliasDecl>(D)->getNamespace(), TU);

  case Decl::Enum:
  case Decl::Record:
  case Decl::CXXRecord:
  case Decl::ClassTemplateSpecialization:
  case Decl::ClassTemplatePartialSpecialization:
    if (TagDecl *Def = cast<TagDecl>(D)->getDefinition())
      return MakeCXCursor(Def, TU);
    return clang_getNullCursor();

  case Decl::Function:
  case Decl::CXXMethod:
  case Decl::CXXConstructor:
  case Decl::CXXDestructor:
  case Decl::CXXConversion: {
    const FunctionDecl *Def = nullptr;
    if (cast<FunctionDecl>(D)->getBody(Def))
      return MakeCXCursor(Def, TU);
    return clang_getNullCursor();
  }

  case Decl::Var:
  case Decl::VarTemplateSpecialization:
  case Decl::VarTemplatePartialSpecialization:
  case Decl::Decomposition: {
    // Ask the variable if it has a definition.
    if (const VarDecl *Def = cast<VarDecl>(D)->getDefinition())
      return MakeCXCursor(Def, TU);
    return clang_getNullCursor();
  }

  case Decl::FunctionTemplate: {
    const FunctionDecl *Def = nullptr;
    if (cast<FunctionTemplateDecl>(D)->getTemplatedDecl()->getBody(Def))
      return MakeCXCursor(Def->getDescribedFunctionTemplate(), TU);
    return clang_getNullCursor();
  }

  case Decl::ClassTemplate: {
    if (RecordDecl *Def =
            cast<ClassTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
      return MakeCXCursor(cast<CXXRecordDecl>(Def)->getDescribedClassTemplate(),
                          TU);
    return clang_getNullCursor();
  }

  case Decl::VarTemplate: {
    if (VarDecl *Def =
            cast<VarTemplateDecl>(D)->getTemplatedDecl()->getDefinition())
      return MakeCXCursor(cast<VarDecl>(Def)->getDescribedVarTemplate(), TU);
    return clang_getNullCursor();
  }

  case Decl::Using:
    return MakeCursorOverloadedDeclRef(cast<UsingDecl>(D), D->getLocation(),
                                       TU);

  case Decl::UsingShadow:
  case Decl::ConstructorUsingShadow:
    return clang_getCursorDefinition(
        MakeCXCursor(cast<UsingShadowDecl>(D)->getTargetDecl(), TU));

  case Decl::ObjCMethod: {
    const ObjCMethodDecl *Method = cast<ObjCMethodDecl>(D);
    if (Method->isThisDeclarationADefinition())
      return C;

    // Dig out the method definition in the associated
    // @implementation, if we have it.
    // FIXME: The ASTs should make finding the definition easier.
    if (const ObjCInterfaceDecl *Class =
            dyn_cast<ObjCInterfaceDecl>(Method->getDeclContext()))
      if (ObjCImplementationDecl *ClassImpl = Class->getImplementation())
        if (ObjCMethodDecl *Def = ClassImpl->getMethod(
                Method->getSelector(), Method->isInstanceMethod()))
          if (Def->isThisDeclarationADefinition())
            return MakeCXCursor(Def, TU);

    return clang_getNullCursor();
  }

  case Decl::ObjCCategory:
    if (ObjCCategoryImplDecl *Impl =
            cast<ObjCCategoryDecl>(D)->getImplementation())
      return MakeCXCursor(Impl, TU);
    return clang_getNullCursor();

  case Decl::ObjCProtocol:
    if (const ObjCProtocolDecl *Def =
            cast<ObjCProtocolDecl>(D)->getDefinition())
      return MakeCXCursor(Def, TU);
    return clang_getNullCursor();

  case Decl::ObjCInterface: {
    // There are two notions of a "definition" for an Objective-C
    // class: the interface and its implementation. When we resolved a
    // reference to an Objective-C class, produce the @interface as
    // the definition; when we were provided with the interface,
    // produce the @implementation as the definition.
    const ObjCInterfaceDecl *IFace = cast<ObjCInterfaceDecl>(D);
    if (WasReference) {
      if (const ObjCInterfaceDecl *Def = IFace->getDefinition())
        return MakeCXCursor(Def, TU);
    } else if (ObjCImplementationDecl *Impl = IFace->getImplementation())
      return MakeCXCursor(Impl, TU);
    return clang_getNullCursor();
  }

  case Decl::ObjCProperty:
    // FIXME: We don't really know where to find the
    // ObjCPropertyImplDecls that implement this property.
    return clang_getNullCursor();

  case Decl::ObjCCompatibleAlias:
    if (const ObjCInterfaceDecl *Class =
            cast<ObjCCompatibleAliasDecl>(D)->getClassInterface())
      if (const ObjCInterfaceDecl *Def = Class->getDefinition())
        return MakeCXCursor(Def, TU);

    return clang_getNullCursor();

  case Decl::Friend:
    if (NamedDecl *Friend = cast<FriendDecl>(D)->getFriendDecl())
      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
    return clang_getNullCursor();

  case Decl::FriendTemplate:
    if (NamedDecl *Friend = cast<FriendTemplateDecl>(D)->getFriendDecl())
      return clang_getCursorDefinition(MakeCXCursor(Friend, TU));
    return clang_getNullCursor();
  }

  return clang_getNullCursor();
}

unsigned clang_isCursorDefinition(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  return clang_getCursorDefinition(C) == C;
}

CXCursor clang_getCanonicalCursor(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return C;

  if (const Decl *D = getCursorDecl(C)) {
    if (const ObjCCategoryImplDecl *CatImplD =
            dyn_cast<ObjCCategoryImplDecl>(D))
      if (ObjCCategoryDecl *CatD = CatImplD->getCategoryDecl())
        return MakeCXCursor(CatD, getCursorTU(C));

    if (const ObjCImplDecl *ImplD = dyn_cast<ObjCImplDecl>(D))
      if (const ObjCInterfaceDecl *IFD = ImplD->getClassInterface())
        return MakeCXCursor(IFD, getCursorTU(C));

    return MakeCXCursor(D->getCanonicalDecl(), getCursorTU(C));
  }

  return C;
}

int clang_Cursor_getObjCSelectorIndex(CXCursor cursor) {
  return cxcursor::getSelectorIdentifierIndexAndLoc(cursor).first;
}

unsigned clang_getNumOverloadedDecls(CXCursor C) {
  if (C.kind != CXCursor_OverloadedDeclRef)
    return 0;

  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(C).first;
  if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
    return E->getNumDecls();

  if (OverloadedTemplateStorage *S =
          Storage.dyn_cast<OverloadedTemplateStorage *>())
    return S->size();

  const Decl *D = Storage.get<const Decl *>();
  if (const UsingDecl *Using = dyn_cast<UsingDecl>(D))
    return Using->shadow_size();

  return 0;
}

CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index) {
  if (cursor.kind != CXCursor_OverloadedDeclRef)
    return clang_getNullCursor();

  if (index >= clang_getNumOverloadedDecls(cursor))
    return clang_getNullCursor();

  CXTranslationUnit TU = getCursorTU(cursor);
  OverloadedDeclRefStorage Storage = getCursorOverloadedDeclRef(cursor).first;
  if (const OverloadExpr *E = Storage.dyn_cast<const OverloadExpr *>())
    return MakeCXCursor(E->decls_begin()[index], TU);

  if (OverloadedTemplateStorage *S =
          Storage.dyn_cast<OverloadedTemplateStorage *>())
    return MakeCXCursor(S->begin()[index], TU);

  const Decl *D = Storage.get<const Decl *>();
  if (const UsingDecl *Using = dyn_cast<UsingDecl>(D)) {
    // FIXME: This is, unfortunately, linear time.
    UsingDecl::shadow_iterator Pos = Using->shadow_begin();
    std::advance(Pos, index);
    return MakeCXCursor(cast<UsingShadowDecl>(*Pos)->getTargetDecl(), TU);
  }

  return clang_getNullCursor();
}

void clang_getDefinitionSpellingAndExtent(
    CXCursor C, const char **startBuf, const char **endBuf, unsigned *startLine,
    unsigned *startColumn, unsigned *endLine, unsigned *endColumn) {
  assert(getCursorDecl(C) && "CXCursor has null decl");
  const FunctionDecl *FD = dyn_cast<FunctionDecl>(getCursorDecl(C));
  CompoundStmt *Body = dyn_cast<CompoundStmt>(FD->getBody());

  SourceManager &SM = FD->getASTContext().getSourceManager();
  *startBuf = SM.getCharacterData(Body->getLBracLoc());
  *endBuf = SM.getCharacterData(Body->getRBracLoc());
  *startLine = SM.getSpellingLineNumber(Body->getLBracLoc());
  *startColumn = SM.getSpellingColumnNumber(Body->getLBracLoc());
  *endLine = SM.getSpellingLineNumber(Body->getRBracLoc());
  *endColumn = SM.getSpellingColumnNumber(Body->getRBracLoc());
}

CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, unsigned NameFlags,
                                                unsigned PieceIndex) {
  RefNamePieces Pieces;

  switch (C.kind) {
  case CXCursor_MemberRefExpr:
    if (const MemberExpr *E = dyn_cast<MemberExpr>(getCursorExpr(C)))
      Pieces = buildPieces(NameFlags, true, E->getMemberNameInfo(),
                           E->getQualifierLoc().getSourceRange());
    break;

  case CXCursor_DeclRefExpr:
    if (const DeclRefExpr *E = dyn_cast<DeclRefExpr>(getCursorExpr(C))) {
      SourceRange TemplateArgLoc(E->getLAngleLoc(), E->getRAngleLoc());
      Pieces =
          buildPieces(NameFlags, false, E->getNameInfo(),
                      E->getQualifierLoc().getSourceRange(), &TemplateArgLoc);
    }
    break;

  case CXCursor_CallExpr:
    if (const CXXOperatorCallExpr *OCE =
            dyn_cast<CXXOperatorCallExpr>(getCursorExpr(C))) {
      const Expr *Callee = OCE->getCallee();
      if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee))
        Callee = ICE->getSubExpr();

      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Callee))
        Pieces = buildPieces(NameFlags, false, DRE->getNameInfo(),
                             DRE->getQualifierLoc().getSourceRange());
    }
    break;

  default:
    break;
  }

  if (Pieces.empty()) {
    if (PieceIndex == 0)
      return clang_getCursorExtent(C);
  } else if (PieceIndex < Pieces.size()) {
    SourceRange R = Pieces[PieceIndex];
    if (R.isValid())
      return cxloc::translateSourceRange(getCursorContext(C), R);
  }

  return clang_getNullRange();
}

void clang_enableStackTraces(void) {
  // FIXME: Provide an argv0 here so we can find llvm-symbolizer.
  llvm::sys::PrintStackTraceOnErrorSignal(StringRef());
}

void clang_executeOnThread(void (*fn)(void *), void *user_data,
                           unsigned stack_size) {
  llvm::llvm_execute_on_thread(fn, user_data,
                               stack_size == 0
                                   ? clang::DesiredStackSize
                                   : llvm::Optional<unsigned>(stack_size));
}

//===----------------------------------------------------------------------===//
// Token-based Operations.
//===----------------------------------------------------------------------===//

/* CXToken layout:
 *   int_data[0]: a CXTokenKind
 *   int_data[1]: starting token location
 *   int_data[2]: token length
 *   int_data[3]: reserved
 *   ptr_data: for identifiers and keywords, an IdentifierInfo*.
 *   otherwise unused.
 */
CXTokenKind clang_getTokenKind(CXToken CXTok) {
  return static_cast<CXTokenKind>(CXTok.int_data[0]);
}

CXString clang_getTokenSpelling(CXTranslationUnit TU, CXToken CXTok) {
  switch (clang_getTokenKind(CXTok)) {
  case CXToken_Identifier:
  case CXToken_Keyword:
    // We know we have an IdentifierInfo*, so use that.
    return cxstring::createRef(
        static_cast<IdentifierInfo *>(CXTok.ptr_data)->getNameStart());

  case CXToken_Literal: {
    // We have stashed the starting pointer in the ptr_data field. Use it.
    const char *Text = static_cast<const char *>(CXTok.ptr_data);
    return cxstring::createDup(StringRef(Text, CXTok.int_data[2]));
  }

  case CXToken_Punctuation:
  case CXToken_Comment:
    break;
  }

  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return cxstring::createEmpty();
  }

  // We have to find the starting buffer pointer the hard way, by
  // deconstructing the source location.
  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  if (!CXXUnit)
    return cxstring::createEmpty();

  SourceLocation Loc = SourceLocation::getFromRawEncoding(CXTok.int_data[1]);
  std::pair<FileID, unsigned> LocInfo =
      CXXUnit->getSourceManager().getDecomposedSpellingLoc(Loc);
  bool Invalid = false;
  StringRef Buffer =
      CXXUnit->getSourceManager().getBufferData(LocInfo.first, &Invalid);
  if (Invalid)
    return cxstring::createEmpty();

  return cxstring::createDup(Buffer.substr(LocInfo.second, CXTok.int_data[2]));
}

CXSourceLocation clang_getTokenLocation(CXTranslationUnit TU, CXToken CXTok) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return clang_getNullLocation();
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  if (!CXXUnit)
    return clang_getNullLocation();

  return cxloc::translateSourceLocation(
      CXXUnit->getASTContext(),
      SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
}

CXSourceRange clang_getTokenExtent(CXTranslationUnit TU, CXToken CXTok) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return clang_getNullRange();
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  if (!CXXUnit)
    return clang_getNullRange();

  return cxloc::translateSourceRange(
      CXXUnit->getASTContext(),
      SourceLocation::getFromRawEncoding(CXTok.int_data[1]));
}

static void getTokens(ASTUnit *CXXUnit, SourceRange Range,
                      SmallVectorImpl<CXToken> &CXTokens) {
  SourceManager &SourceMgr = CXXUnit->getSourceManager();
  std::pair<FileID, unsigned> BeginLocInfo =
      SourceMgr.getDecomposedSpellingLoc(Range.getBegin());
  std::pair<FileID, unsigned> EndLocInfo =
      SourceMgr.getDecomposedSpellingLoc(Range.getEnd());

  // Cannot tokenize across files.
  if (BeginLocInfo.first != EndLocInfo.first)
    return;

  // Create a lexer
  bool Invalid = false;
  StringRef Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
  if (Invalid)
    return;

  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
            CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
            Buffer.data() + BeginLocInfo.second, Buffer.end());
  Lex.SetCommentRetentionState(true);

  // Lex tokens until we hit the end of the range.
  const char *EffectiveBufferEnd = Buffer.data() + EndLocInfo.second;
  Token Tok;
  bool previousWasAt = false;
  do {
    // Lex the next token
    Lex.LexFromRawLexer(Tok);
    if (Tok.is(tok::eof))
      break;

    // Initialize the CXToken.
    CXToken CXTok;

    //   - Common fields
    CXTok.int_data[1] = Tok.getLocation().getRawEncoding();
    CXTok.int_data[2] = Tok.getLength();
    CXTok.int_data[3] = 0;

    //   - Kind-specific fields
    if (Tok.isLiteral()) {
      CXTok.int_data[0] = CXToken_Literal;
      CXTok.ptr_data = const_cast<char *>(Tok.getLiteralData());
    } else if (Tok.is(tok::raw_identifier)) {
      // Lookup the identifier to determine whether we have a keyword.
      IdentifierInfo *II = CXXUnit->getPreprocessor().LookUpIdentifierInfo(Tok);

      if ((II->getObjCKeywordID() != tok::objc_not_keyword) && previousWasAt) {
        CXTok.int_data[0] = CXToken_Keyword;
      } else {
        CXTok.int_data[0] =
            Tok.is(tok::identifier) ? CXToken_Identifier : CXToken_Keyword;
      }
      CXTok.ptr_data = II;
    } else if (Tok.is(tok::comment)) {
      CXTok.int_data[0] = CXToken_Comment;
      CXTok.ptr_data = nullptr;
    } else {
      CXTok.int_data[0] = CXToken_Punctuation;
      CXTok.ptr_data = nullptr;
    }
    CXTokens.push_back(CXTok);
    previousWasAt = Tok.is(tok::at);
  } while (Lex.getBufferLocation() < EffectiveBufferEnd);
}

CXToken *clang_getToken(CXTranslationUnit TU, CXSourceLocation Location) {
  LOG_FUNC_SECTION { *Log << TU << ' ' << Location; }

  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return NULL;
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  if (!CXXUnit)
    return NULL;

  SourceLocation Begin = cxloc::translateSourceLocation(Location);
  if (Begin.isInvalid())
    return NULL;
  SourceManager &SM = CXXUnit->getSourceManager();
  std::pair<FileID, unsigned> DecomposedEnd = SM.getDecomposedLoc(Begin);
  DecomposedEnd.second +=
      Lexer::MeasureTokenLength(Begin, SM, CXXUnit->getLangOpts());

  SourceLocation End =
      SM.getComposedLoc(DecomposedEnd.first, DecomposedEnd.second);

  SmallVector<CXToken, 32> CXTokens;
  getTokens(CXXUnit, SourceRange(Begin, End), CXTokens);

  if (CXTokens.empty())
    return NULL;

  CXTokens.resize(1);
  CXToken *Token = static_cast<CXToken *>(llvm::safe_malloc(sizeof(CXToken)));

  memmove(Token, CXTokens.data(), sizeof(CXToken));
  return Token;
}

void clang_tokenize(CXTranslationUnit TU, CXSourceRange Range, CXToken **Tokens,
                    unsigned *NumTokens) {
  LOG_FUNC_SECTION { *Log << TU << ' ' << Range; }

  if (Tokens)
    *Tokens = nullptr;
  if (NumTokens)
    *NumTokens = 0;

  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return;
  }

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  if (!CXXUnit || !Tokens || !NumTokens)
    return;

  ASTUnit::ConcurrencyCheck Check(*CXXUnit);

  SourceRange R = cxloc::translateCXSourceRange(Range);
  if (R.isInvalid())
    return;

  SmallVector<CXToken, 32> CXTokens;
  getTokens(CXXUnit, R, CXTokens);

  if (CXTokens.empty())
    return;

  *Tokens = static_cast<CXToken *>(
      llvm::safe_malloc(sizeof(CXToken) * CXTokens.size()));
  memmove(*Tokens, CXTokens.data(), sizeof(CXToken) * CXTokens.size());
  *NumTokens = CXTokens.size();
}

void clang_disposeTokens(CXTranslationUnit TU, CXToken *Tokens,
                         unsigned NumTokens) {
  free(Tokens);
}

//===----------------------------------------------------------------------===//
// Token annotation APIs.
//===----------------------------------------------------------------------===//

static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
                                                     CXCursor parent,
                                                     CXClientData client_data);
static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
                                              CXClientData client_data);

namespace {
class AnnotateTokensWorker {
  CXToken *Tokens;
  CXCursor *Cursors;
  unsigned NumTokens;
  unsigned TokIdx;
  unsigned PreprocessingTokIdx;
  CursorVisitor AnnotateVis;
  SourceManager &SrcMgr;
  bool HasContextSensitiveKeywords;

  struct PostChildrenAction {
    CXCursor cursor;
    enum Action { Invalid, Ignore, Postpone } action;
  };
  using PostChildrenActions = SmallVector<PostChildrenAction, 0>;

  struct PostChildrenInfo {
    CXCursor Cursor;
    SourceRange CursorRange;
    unsigned BeforeReachingCursorIdx;
    unsigned BeforeChildrenTokenIdx;
    PostChildrenActions ChildActions;
  };
  SmallVector<PostChildrenInfo, 8> PostChildrenInfos;

  CXToken &getTok(unsigned Idx) {
    assert(Idx < NumTokens);
    return Tokens[Idx];
  }
  const CXToken &getTok(unsigned Idx) const {
    assert(Idx < NumTokens);
    return Tokens[Idx];
  }
  bool MoreTokens() const { return TokIdx < NumTokens; }
  unsigned NextToken() const { return TokIdx; }
  void AdvanceToken() { ++TokIdx; }
  SourceLocation GetTokenLoc(unsigned tokI) {
    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
  }
  bool isFunctionMacroToken(unsigned tokI) const {
    return getTok(tokI).int_data[3] != 0;
  }
  SourceLocation getFunctionMacroTokenLoc(unsigned tokI) const {
    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[3]);
  }

  void annotateAndAdvanceTokens(CXCursor, RangeComparisonResult, SourceRange);
  bool annotateAndAdvanceFunctionMacroTokens(CXCursor, RangeComparisonResult,
                                             SourceRange);

public:
  AnnotateTokensWorker(CXToken *tokens, CXCursor *cursors, unsigned numTokens,
                       CXTranslationUnit TU, SourceRange RegionOfInterest)
      : Tokens(tokens), Cursors(cursors), NumTokens(numTokens), TokIdx(0),
        PreprocessingTokIdx(0),
        AnnotateVis(TU, AnnotateTokensVisitor, this,
                    /*VisitPreprocessorLast=*/true,
                    /*VisitIncludedEntities=*/false, RegionOfInterest,
                    /*VisitDeclsOnly=*/false,
                    AnnotateTokensPostChildrenVisitor),
        SrcMgr(cxtu::getASTUnit(TU)->getSourceManager()),
        HasContextSensitiveKeywords(false) {}

  void VisitChildren(CXCursor C) { AnnotateVis.VisitChildren(C); }
  enum CXChildVisitResult Visit(CXCursor cursor, CXCursor parent);
  bool IsIgnoredChildCursor(CXCursor cursor) const;
  PostChildrenActions DetermineChildActions(CXCursor Cursor) const;

  bool postVisitChildren(CXCursor cursor);
  void HandlePostPonedChildCursors(const PostChildrenInfo &Info);
  void HandlePostPonedChildCursor(CXCursor Cursor, unsigned StartTokenIndex);

  void AnnotateTokens();

  /// Determine whether the annotator saw any cursors that have
  /// context-sensitive keywords.
  bool hasContextSensitiveKeywords() const {
    return HasContextSensitiveKeywords;
  }

  ~AnnotateTokensWorker() { assert(PostChildrenInfos.empty()); }
};
} // namespace

void AnnotateTokensWorker::AnnotateTokens() {
  // Walk the AST within the region of interest, annotating tokens
  // along the way.
  AnnotateVis.visitFileRegion();
}

bool AnnotateTokensWorker::IsIgnoredChildCursor(CXCursor cursor) const {
  if (PostChildrenInfos.empty())
    return false;

  for (const auto &ChildAction : PostChildrenInfos.back().ChildActions) {
    if (ChildAction.cursor == cursor &&
        ChildAction.action == PostChildrenAction::Ignore) {
      return true;
    }
  }

  return false;
}

const CXXOperatorCallExpr *GetSubscriptOrCallOperator(CXCursor Cursor) {
  if (!clang_isExpression(Cursor.kind))
    return nullptr;

  const Expr *E = getCursorExpr(Cursor);
  if (const auto *OCE = dyn_cast<CXXOperatorCallExpr>(E)) {
    const OverloadedOperatorKind Kind = OCE->getOperator();
    if (Kind == OO_Call || Kind == OO_Subscript)
      return OCE;
  }

  return nullptr;
}

AnnotateTokensWorker::PostChildrenActions
AnnotateTokensWorker::DetermineChildActions(CXCursor Cursor) const {
  PostChildrenActions actions;

  // The DeclRefExpr of CXXOperatorCallExpr refering to the custom operator is
  // visited before the arguments to the operator call. For the Call and
  // Subscript operator the range of this DeclRefExpr includes the whole call
  // expression, so that all tokens in that range would be mapped to the
  // operator function, including the tokens of the arguments. To avoid that,
  // ensure to visit this DeclRefExpr as last node.
  if (const auto *OCE = GetSubscriptOrCallOperator(Cursor)) {
    const Expr *Callee = OCE->getCallee();
    if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Callee)) {
      const Expr *SubExpr = ICE->getSubExpr();
      if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(SubExpr)) {
        const Decl *parentDecl = getCursorDecl(Cursor);
        CXTranslationUnit TU = clang_Cursor_getTranslationUnit(Cursor);

        // Visit the DeclRefExpr as last.
        CXCursor cxChild = MakeCXCursor(DRE, parentDecl, TU);
        actions.push_back({cxChild, PostChildrenAction::Postpone});

        // The parent of the DeclRefExpr, an ImplicitCastExpr, has an equally
        // wide range as the DeclRefExpr. We can skip visiting this entirely.
        cxChild = MakeCXCursor(ICE, parentDecl, TU);
        actions.push_back({cxChild, PostChildrenAction::Ignore});
      }
    }
  }

  return actions;
}

static inline void updateCursorAnnotation(CXCursor &Cursor,
                                          const CXCursor &updateC) {
  if (clang_isInvalid(updateC.kind) || !clang_isInvalid(Cursor.kind))
    return;
  Cursor = updateC;
}

/// It annotates and advances tokens with a cursor until the comparison
//// between the cursor location and the source range is the same as
/// \arg compResult.
///
/// Pass RangeBefore to annotate tokens with a cursor until a range is reached.
/// Pass RangeOverlap to annotate tokens inside a range.
void AnnotateTokensWorker::annotateAndAdvanceTokens(
    CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
  while (MoreTokens()) {
    const unsigned I = NextToken();
    if (isFunctionMacroToken(I))
      if (!annotateAndAdvanceFunctionMacroTokens(updateC, compResult, range))
        return;

    SourceLocation TokLoc = GetTokenLoc(I);
    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
      updateCursorAnnotation(Cursors[I], updateC);
      AdvanceToken();
      continue;
    }
    break;
  }
}

/// Special annotation handling for macro argument tokens.
/// \returns true if it advanced beyond all macro tokens, false otherwise.
bool AnnotateTokensWorker::annotateAndAdvanceFunctionMacroTokens(
    CXCursor updateC, RangeComparisonResult compResult, SourceRange range) {
  assert(MoreTokens());
  assert(isFunctionMacroToken(NextToken()) &&
         "Should be called only for macro arg tokens");

  // This works differently than annotateAndAdvanceTokens; because expanded
  // macro arguments can have arbitrary translation-unit source order, we do not
  // advance the token index one by one until a token fails the range test.
  // We only advance once past all of the macro arg tokens if all of them
  // pass the range test. If one of them fails we keep the token index pointing
  // at the start of the macro arg tokens so that the failing token will be
  // annotated by a subsequent annotation try.

  bool atLeastOneCompFail = false;

  unsigned I = NextToken();
  for (; I < NumTokens && isFunctionMacroToken(I); ++I) {
    SourceLocation TokLoc = getFunctionMacroTokenLoc(I);
    if (TokLoc.isFileID())
      continue; // not macro arg token, it's parens or comma.
    if (LocationCompare(SrcMgr, TokLoc, range) == compResult) {
      if (clang_isInvalid(clang_getCursorKind(Cursors[I])))
        Cursors[I] = updateC;
    } else
      atLeastOneCompFail = true;
  }

  if (atLeastOneCompFail)
    return false;

  TokIdx = I; // All of the tokens were handled, advance beyond all of them.
  return true;
}

enum CXChildVisitResult AnnotateTokensWorker::Visit(CXCursor cursor,
                                                    CXCursor parent) {
  SourceRange cursorRange = getRawCursorExtent(cursor);
  if (cursorRange.isInvalid())
    return CXChildVisit_Recurse;

  if (IsIgnoredChildCursor(cursor))
    return CXChildVisit_Continue;

  if (!HasContextSensitiveKeywords) {
    // Objective-C properties can have context-sensitive keywords.
    if (cursor.kind == CXCursor_ObjCPropertyDecl) {
      if (const ObjCPropertyDecl *Property =
              dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(cursor)))
        HasContextSensitiveKeywords =
            Property->getPropertyAttributesAsWritten() != 0;
    }
    // Objective-C methods can have context-sensitive keywords.
    else if (cursor.kind == CXCursor_ObjCInstanceMethodDecl ||
             cursor.kind == CXCursor_ObjCClassMethodDecl) {
      if (const ObjCMethodDecl *Method =
              dyn_cast_or_null<ObjCMethodDecl>(getCursorDecl(cursor))) {
        if (Method->getObjCDeclQualifier())
          HasContextSensitiveKeywords = true;
        else {
          for (const auto *P : Method->parameters()) {
            if (P->getObjCDeclQualifier()) {
              HasContextSensitiveKeywords = true;
              break;
            }
          }
        }
      }
    }
    // C++ methods can have context-sensitive keywords.
    else if (cursor.kind == CXCursor_CXXMethod) {
      if (const CXXMethodDecl *Method =
              dyn_cast_or_null<CXXMethodDecl>(getCursorDecl(cursor))) {
        if (Method->hasAttr<FinalAttr>() || Method->hasAttr<OverrideAttr>())
          HasContextSensitiveKeywords = true;
      }
    }
    // C++ classes can have context-sensitive keywords.
    else if (cursor.kind == CXCursor_StructDecl ||
             cursor.kind == CXCursor_ClassDecl ||
             cursor.kind == CXCursor_ClassTemplate ||
             cursor.kind == CXCursor_ClassTemplatePartialSpecialization) {
      if (const Decl *D = getCursorDecl(cursor))
        if (D->hasAttr<FinalAttr>())
          HasContextSensitiveKeywords = true;
    }
  }

  // Don't override a property annotation with its getter/setter method.
  if (cursor.kind == CXCursor_ObjCInstanceMethodDecl &&
      parent.kind == CXCursor_ObjCPropertyDecl)
    return CXChildVisit_Continue;

  if (clang_isPreprocessing(cursor.kind)) {
    // Items in the preprocessing record are kept separate from items in
    // declarations, so we keep a separate token index.
    unsigned SavedTokIdx = TokIdx;
    TokIdx = PreprocessingTokIdx;

    // Skip tokens up until we catch up to the beginning of the preprocessing
    // entry.
    while (MoreTokens()) {
      const unsigned I = NextToken();
      SourceLocation TokLoc = GetTokenLoc(I);
      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
      case RangeBefore:
        AdvanceToken();
        continue;
      case RangeAfter:
      case RangeOverlap:
        break;
      }
      break;
    }

    // Look at all of the tokens within this range.
    while (MoreTokens()) {
      const unsigned I = NextToken();
      SourceLocation TokLoc = GetTokenLoc(I);
      switch (LocationCompare(SrcMgr, TokLoc, cursorRange)) {
      case RangeBefore:
        llvm_unreachable("Infeasible");
      case RangeAfter:
        break;
      case RangeOverlap:
        // For macro expansions, just note where the beginning of the macro
        // expansion occurs.
        if (cursor.kind == CXCursor_MacroExpansion) {
          if (TokLoc == cursorRange.getBegin())
            Cursors[I] = cursor;
          AdvanceToken();
          break;
        }
        // We may have already annotated macro names inside macro definitions.
        if (Cursors[I].kind != CXCursor_MacroExpansion)
          Cursors[I] = cursor;
        AdvanceToken();
        continue;
      }
      break;
    }

    // Save the preprocessing token index; restore the non-preprocessing
    // token index.
    PreprocessingTokIdx = TokIdx;
    TokIdx = SavedTokIdx;
    return CXChildVisit_Recurse;
  }

  if (cursorRange.isInvalid())
    return CXChildVisit_Continue;

  unsigned BeforeReachingCursorIdx = NextToken();
  const enum CXCursorKind cursorK = clang_getCursorKind(cursor);
  const enum CXCursorKind K = clang_getCursorKind(parent);
  const CXCursor updateC =
      (clang_isInvalid(K) || K == CXCursor_TranslationUnit ||
       // Attributes are annotated out-of-order, skip tokens until we reach it.
       clang_isAttribute(cursor.kind))
          ? clang_getNullCursor()
          : parent;

  annotateAndAdvanceTokens(updateC, RangeBefore, cursorRange);

  // Avoid having the cursor of an expression "overwrite" the annotation of the
  // variable declaration that it belongs to.
  // This can happen for C++ constructor expressions whose range generally
  // include the variable declaration, e.g.:
  //  MyCXXClass foo; // Make sure we don't annotate 'foo' as a CallExpr cursor.
  if (clang_isExpression(cursorK) && MoreTokens()) {
    const Expr *E = getCursorExpr(cursor);
    if (const Decl *D = getCursorDecl(cursor)) {
      const unsigned I = NextToken();
      if (E->getBeginLoc().isValid() && D->getLocation().isValid() &&
          E->getBeginLoc() == D->getLocation() &&
          E->getBeginLoc() == GetTokenLoc(I)) {
        updateCursorAnnotation(Cursors[I], updateC);
        AdvanceToken();
      }
    }
  }

  // Before recursing into the children keep some state that we are going
  // to use in the AnnotateTokensWorker::postVisitChildren callback to do some
  // extra work after the child nodes are visited.
  // Note that we don't call VisitChildren here to avoid traversing statements
  // code-recursively which can blow the stack.

  PostChildrenInfo Info;
  Info.Cursor = cursor;
  Info.CursorRange = cursorRange;
  Info.BeforeReachingCursorIdx = BeforeReachingCursorIdx;
  Info.BeforeChildrenTokenIdx = NextToken();
  Info.ChildActions = DetermineChildActions(cursor);
  PostChildrenInfos.push_back(Info);

  return CXChildVisit_Recurse;
}

bool AnnotateTokensWorker::postVisitChildren(CXCursor cursor) {
  if (PostChildrenInfos.empty())
    return false;
  const PostChildrenInfo &Info = PostChildrenInfos.back();
  if (!clang_equalCursors(Info.Cursor, cursor))
    return false;

  HandlePostPonedChildCursors(Info);

  const unsigned BeforeChildren = Info.BeforeChildrenTokenIdx;
  const unsigned AfterChildren = NextToken();
  SourceRange cursorRange = Info.CursorRange;

  // Scan the tokens that are at the end of the cursor, but are not captured
  // but the child cursors.
  annotateAndAdvanceTokens(cursor, RangeOverlap, cursorRange);

  // Scan the tokens that are at the beginning of the cursor, but are not
  // capture by the child cursors.
  for (unsigned I = BeforeChildren; I != AfterChildren; ++I) {
    if (!clang_isInvalid(clang_getCursorKind(Cursors[I])))
      break;

    Cursors[I] = cursor;
  }

  // Attributes are annotated out-of-order, rewind TokIdx to when we first
  // encountered the attribute cursor.
  if (clang_isAttribute(cursor.kind))
    TokIdx = Info.BeforeReachingCursorIdx;

  PostChildrenInfos.pop_back();
  return false;
}

void AnnotateTokensWorker::HandlePostPonedChildCursors(
    const PostChildrenInfo &Info) {
  for (const auto &ChildAction : Info.ChildActions) {
    if (ChildAction.action == PostChildrenAction::Postpone) {
      HandlePostPonedChildCursor(ChildAction.cursor,
                                 Info.BeforeChildrenTokenIdx);
    }
  }
}

void AnnotateTokensWorker::HandlePostPonedChildCursor(
    CXCursor Cursor, unsigned StartTokenIndex) {
  unsigned I = StartTokenIndex;

  // The bracket tokens of a Call or Subscript operator are mapped to
  // CallExpr/CXXOperatorCallExpr because we skipped visiting the corresponding
  // DeclRefExpr. Remap these tokens to the DeclRefExpr cursors.
  for (unsigned RefNameRangeNr = 0; I < NumTokens; RefNameRangeNr++) {
    const CXSourceRange CXRefNameRange = clang_getCursorReferenceNameRange(
        Cursor, CXNameRange_WantQualifier, RefNameRangeNr);
    if (clang_Range_isNull(CXRefNameRange))
      break; // All ranges handled.

    SourceRange RefNameRange = cxloc::translateCXSourceRange(CXRefNameRange);
    while (I < NumTokens) {
      const SourceLocation TokenLocation = GetTokenLoc(I);
      if (!TokenLocation.isValid())
        break;

      // Adapt the end range, because LocationCompare() reports
      // RangeOverlap even for the not-inclusive end location.
      const SourceLocation fixedEnd =
          RefNameRange.getEnd().getLocWithOffset(-1);
      RefNameRange = SourceRange(RefNameRange.getBegin(), fixedEnd);

      const RangeComparisonResult ComparisonResult =
          LocationCompare(SrcMgr, TokenLocation, RefNameRange);

      if (ComparisonResult == RangeOverlap) {
        Cursors[I++] = Cursor;
      } else if (ComparisonResult == RangeBefore) {
        ++I; // Not relevant token, check next one.
      } else if (ComparisonResult == RangeAfter) {
        break; // All tokens updated for current range, check next.
      }
    }
  }
}

static enum CXChildVisitResult AnnotateTokensVisitor(CXCursor cursor,
                                                     CXCursor parent,
                                                     CXClientData client_data) {
  return static_cast<AnnotateTokensWorker *>(client_data)
      ->Visit(cursor, parent);
}

static bool AnnotateTokensPostChildrenVisitor(CXCursor cursor,
                                              CXClientData client_data) {
  return static_cast<AnnotateTokensWorker *>(client_data)
      ->postVisitChildren(cursor);
}

namespace {

/// Uses the macro expansions in the preprocessing record to find
/// and mark tokens that are macro arguments. This info is used by the
/// AnnotateTokensWorker.
class MarkMacroArgTokensVisitor {
  SourceManager &SM;
  CXToken *Tokens;
  unsigned NumTokens;
  unsigned CurIdx;

public:
  MarkMacroArgTokensVisitor(SourceManager &SM, CXToken *tokens,
                            unsigned numTokens)
      : SM(SM), Tokens(tokens), NumTokens(numTokens), CurIdx(0) {}

  CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
    if (cursor.kind != CXCursor_MacroExpansion)
      return CXChildVisit_Continue;

    SourceRange macroRange = getCursorMacroExpansion(cursor).getSourceRange();
    if (macroRange.getBegin() == macroRange.getEnd())
      return CXChildVisit_Continue; // it's not a function macro.

    for (; CurIdx < NumTokens; ++CurIdx) {
      if (!SM.isBeforeInTranslationUnit(getTokenLoc(CurIdx),
                                        macroRange.getBegin()))
        break;
    }

    if (CurIdx == NumTokens)
      return CXChildVisit_Break;

    for (; CurIdx < NumTokens; ++CurIdx) {
      SourceLocation tokLoc = getTokenLoc(CurIdx);
      if (!SM.isBeforeInTranslationUnit(tokLoc, macroRange.getEnd()))
        break;

      setFunctionMacroTokenLoc(CurIdx, SM.getMacroArgExpandedLocation(tokLoc));
    }

    if (CurIdx == NumTokens)
      return CXChildVisit_Break;

    return CXChildVisit_Continue;
  }

private:
  CXToken &getTok(unsigned Idx) {
    assert(Idx < NumTokens);
    return Tokens[Idx];
  }
  const CXToken &getTok(unsigned Idx) const {
    assert(Idx < NumTokens);
    return Tokens[Idx];
  }

  SourceLocation getTokenLoc(unsigned tokI) {
    return SourceLocation::getFromRawEncoding(getTok(tokI).int_data[1]);
  }

  void setFunctionMacroTokenLoc(unsigned tokI, SourceLocation loc) {
    // The third field is reserved and currently not used. Use it here
    // to mark macro arg expanded tokens with their expanded locations.
    getTok(tokI).int_data[3] = loc.getRawEncoding();
  }
};

} // end anonymous namespace

static CXChildVisitResult
MarkMacroArgTokensVisitorDelegate(CXCursor cursor, CXCursor parent,
                                  CXClientData client_data) {
  return static_cast<MarkMacroArgTokensVisitor *>(client_data)
      ->visit(cursor, parent);
}

/// Used by \c annotatePreprocessorTokens.
/// \returns true if lexing was finished, false otherwise.
static bool lexNext(Lexer &Lex, Token &Tok, unsigned &NextIdx,
                    unsigned NumTokens) {
  if (NextIdx >= NumTokens)
    return true;

  ++NextIdx;
  Lex.LexFromRawLexer(Tok);
  return Tok.is(tok::eof);
}

static void annotatePreprocessorTokens(CXTranslationUnit TU,
                                       SourceRange RegionOfInterest,
                                       CXCursor *Cursors, CXToken *Tokens,
                                       unsigned NumTokens) {
  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);

  Preprocessor &PP = CXXUnit->getPreprocessor();
  SourceManager &SourceMgr = CXXUnit->getSourceManager();
  std::pair<FileID, unsigned> BeginLocInfo =
      SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getBegin());
  std::pair<FileID, unsigned> EndLocInfo =
      SourceMgr.getDecomposedSpellingLoc(RegionOfInterest.getEnd());

  if (BeginLocInfo.first != EndLocInfo.first)
    return;

  StringRef Buffer;
  bool Invalid = false;
  Buffer = SourceMgr.getBufferData(BeginLocInfo.first, &Invalid);
  if (Buffer.empty() || Invalid)
    return;

  Lexer Lex(SourceMgr.getLocForStartOfFile(BeginLocInfo.first),
            CXXUnit->getASTContext().getLangOpts(), Buffer.begin(),
            Buffer.data() + BeginLocInfo.second, Buffer.end());
  Lex.SetCommentRetentionState(true);

  unsigned NextIdx = 0;
  // Lex tokens in raw mode until we hit the end of the range, to avoid
  // entering #includes or expanding macros.
  while (true) {
    Token Tok;
    if (lexNext(Lex, Tok, NextIdx, NumTokens))
      break;
    unsigned TokIdx = NextIdx - 1;
    assert(Tok.getLocation() ==
           SourceLocation::getFromRawEncoding(Tokens[TokIdx].int_data[1]));

  reprocess:
    if (Tok.is(tok::hash) && Tok.isAtStartOfLine()) {
      // We have found a preprocessing directive. Annotate the tokens
      // appropriately.
      //
      // FIXME: Some simple tests here could identify macro definitions and
      // #undefs, to provide specific cursor kinds for those.

      SourceLocation BeginLoc = Tok.getLocation();
      if (lexNext(Lex, Tok, NextIdx, NumTokens))
        break;

      MacroInfo *MI = nullptr;
      if (Tok.is(tok::raw_identifier) && Tok.getRawIdentifier() == "define") {
        if (lexNext(Lex, Tok, NextIdx, NumTokens))
          break;

        if (Tok.is(tok::raw_identifier)) {
          IdentifierInfo &II =
              PP.getIdentifierTable().get(Tok.getRawIdentifier());
          SourceLocation MappedTokLoc =
              CXXUnit->mapLocationToPreamble(Tok.getLocation());
          MI = getMacroInfo(II, MappedTokLoc, TU);
        }
      }

      bool finished = false;
      do {
        if (lexNext(Lex, Tok, NextIdx, NumTokens)) {
          finished = true;
          break;
        }
        // If we are in a macro definition, check if the token was ever a
        // macro name and annotate it if that's the case.
        if (MI) {
          SourceLocation SaveLoc = Tok.getLocation();
          Tok.setLocation(CXXUnit->mapLocationToPreamble(SaveLoc));
          MacroDefinitionRecord *MacroDef =
              checkForMacroInMacroDefinition(MI, Tok, TU);
          Tok.setLocation(SaveLoc);
          if (MacroDef)
            Cursors[NextIdx - 1] =
                MakeMacroExpansionCursor(MacroDef, Tok.getLocation(), TU);
        }
      } while (!Tok.isAtStartOfLine());

      unsigned LastIdx = finished ? NextIdx - 1 : NextIdx - 2;
      assert(TokIdx <= LastIdx);
      SourceLocation EndLoc =
          SourceLocation::getFromRawEncoding(Tokens[LastIdx].int_data[1]);
      CXCursor Cursor =
          MakePreprocessingDirectiveCursor(SourceRange(BeginLoc, EndLoc), TU);

      for (; TokIdx <= LastIdx; ++TokIdx)
        updateCursorAnnotation(Cursors[TokIdx], Cursor);

      if (finished)
        break;
      goto reprocess;
    }
  }
}

// This gets run a separate thread to avoid stack blowout.
static void clang_annotateTokensImpl(CXTranslationUnit TU, ASTUnit *CXXUnit,
                                     CXToken *Tokens, unsigned NumTokens,
                                     CXCursor *Cursors) {
  CIndexer *CXXIdx = TU->CIdx;
  if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
    setThreadBackgroundPriority();

  // Determine the region of interest, which contains all of the tokens.
  SourceRange RegionOfInterest;
  RegionOfInterest.setBegin(
      cxloc::translateSourceLocation(clang_getTokenLocation(TU, Tokens[0])));
  RegionOfInterest.setEnd(cxloc::translateSourceLocation(
      clang_getTokenLocation(TU, Tokens[NumTokens - 1])));

  // Relex the tokens within the source range to look for preprocessing
  // directives.
  annotatePreprocessorTokens(TU, RegionOfInterest, Cursors, Tokens, NumTokens);

  // If begin location points inside a macro argument, set it to the expansion
  // location so we can have the full context when annotating semantically.
  {
    SourceManager &SM = CXXUnit->getSourceManager();
    SourceLocation Loc =
        SM.getMacroArgExpandedLocation(RegionOfInterest.getBegin());
    if (Loc.isMacroID())
      RegionOfInterest.setBegin(SM.getExpansionLoc(Loc));
  }

  if (CXXUnit->getPreprocessor().getPreprocessingRecord()) {
    // Search and mark tokens that are macro argument expansions.
    MarkMacroArgTokensVisitor Visitor(CXXUnit->getSourceManager(), Tokens,
                                      NumTokens);
    CursorVisitor MacroArgMarker(
        TU, MarkMacroArgTokensVisitorDelegate, &Visitor,
        /*VisitPreprocessorLast=*/true,
        /*VisitIncludedEntities=*/false, RegionOfInterest);
    MacroArgMarker.visitPreprocessedEntitiesInRegion();
  }

  // Annotate all of the source locations in the region of interest that map to
  // a specific cursor.
  AnnotateTokensWorker W(Tokens, Cursors, NumTokens, TU, RegionOfInterest);

  // FIXME: We use a ridiculous stack size here because the data-recursion
  // algorithm uses a large stack frame than the non-data recursive version,
  // and AnnotationTokensWorker currently transforms the data-recursion
  // algorithm back into a traditional recursion by explicitly calling
  // VisitChildren().  We will need to remove this explicit recursive call.
  W.AnnotateTokens();

  // If we ran into any entities that involve context-sensitive keywords,
  // take another pass through the tokens to mark them as such.
  if (W.hasContextSensitiveKeywords()) {
    for (unsigned I = 0; I != NumTokens; ++I) {
      if (clang_getTokenKind(Tokens[I]) != CXToken_Identifier)
        continue;

      if (Cursors[I].kind == CXCursor_ObjCPropertyDecl) {
        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
        if (const ObjCPropertyDecl *Property =
                dyn_cast_or_null<ObjCPropertyDecl>(getCursorDecl(Cursors[I]))) {
          if (Property->getPropertyAttributesAsWritten() != 0 &&
              llvm::StringSwitch<bool>(II->getName())
                  .Case("readonly", true)
                  .Case("assign", true)
                  .Case("unsafe_unretained", true)
                  .Case("readwrite", true)
                  .Case("retain", true)
                  .Case("copy", true)
                  .Case("nonatomic", true)
                  .Case("atomic", true)
                  .Case("getter", true)
                  .Case("setter", true)
                  .Case("strong", true)
                  .Case("weak", true)
                  .Case("class", true)
                  .Default(false))
            Tokens[I].int_data[0] = CXToken_Keyword;
        }
        continue;
      }

      if (Cursors[I].kind == CXCursor_ObjCInstanceMethodDecl ||
          Cursors[I].kind == CXCursor_ObjCClassMethodDecl) {
        IdentifierInfo *II = static_cast<IdentifierInfo *>(Tokens[I].ptr_data);
        if (llvm::StringSwitch<bool>(II->getName())
                .Case("in", true)
                .Case("out", true)
                .Case("inout", true)
                .Case("oneway", true)
                .Case("bycopy", true)
                .Case("byref", true)
                .Default(false))
          Tokens[I].int_data[0] = CXToken_Keyword;
        continue;
      }

      if (Cursors[I].kind == CXCursor_CXXFinalAttr ||
          Cursors[I].kind == CXCursor_CXXOverrideAttr) {
        Tokens[I].int_data[0] = CXToken_Keyword;
        continue;
      }
    }
  }
}

void clang_annotateTokens(CXTranslationUnit TU, CXToken *Tokens,
                          unsigned NumTokens, CXCursor *Cursors) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return;
  }
  if (NumTokens == 0 || !Tokens || !Cursors) {
    LOG_FUNC_SECTION { *Log << "<null input>"; }
    return;
  }

  LOG_FUNC_SECTION {
    *Log << TU << ' ';
    CXSourceLocation bloc = clang_getTokenLocation(TU, Tokens[0]);
    CXSourceLocation eloc = clang_getTokenLocation(TU, Tokens[NumTokens - 1]);
    *Log << clang_getRange(bloc, eloc);
  }

  // Any token we don't specifically annotate will have a NULL cursor.
  CXCursor C = clang_getNullCursor();
  for (unsigned I = 0; I != NumTokens; ++I)
    Cursors[I] = C;

  ASTUnit *CXXUnit = cxtu::getASTUnit(TU);
  if (!CXXUnit)
    return;

  ASTUnit::ConcurrencyCheck Check(*CXXUnit);

  auto AnnotateTokensImpl = [=]() {
    clang_annotateTokensImpl(TU, CXXUnit, Tokens, NumTokens, Cursors);
  };
  llvm::CrashRecoveryContext CRC;
  if (!RunSafely(CRC, AnnotateTokensImpl, GetSafetyThreadStackSize() * 2)) {
    fprintf(stderr, "libclang: crash detected while annotating tokens\n");
  }
}

//===----------------------------------------------------------------------===//
// Operations for querying linkage of a cursor.
//===----------------------------------------------------------------------===//

CXLinkageKind clang_getCursorLinkage(CXCursor cursor) {
  if (!clang_isDeclaration(cursor.kind))
    return CXLinkage_Invalid;

  const Decl *D = cxcursor::getCursorDecl(cursor);
  if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
    switch (ND->getLinkageInternal()) {
    case NoLinkage:
    case VisibleNoLinkage:
      return CXLinkage_NoLinkage;
    case ModuleInternalLinkage:
    case InternalLinkage:
      return CXLinkage_Internal;
    case UniqueExternalLinkage:
      return CXLinkage_UniqueExternal;
    case ModuleLinkage:
    case ExternalLinkage:
      return CXLinkage_External;
    };

  return CXLinkage_Invalid;
}

//===----------------------------------------------------------------------===//
// Operations for querying visibility of a cursor.
//===----------------------------------------------------------------------===//

CXVisibilityKind clang_getCursorVisibility(CXCursor cursor) {
  if (!clang_isDeclaration(cursor.kind))
    return CXVisibility_Invalid;

  const Decl *D = cxcursor::getCursorDecl(cursor);
  if (const NamedDecl *ND = dyn_cast_or_null<NamedDecl>(D))
    switch (ND->getVisibility()) {
    case HiddenVisibility:
      return CXVisibility_Hidden;
    case ProtectedVisibility:
      return CXVisibility_Protected;
    case DefaultVisibility:
      return CXVisibility_Default;
    };

  return CXVisibility_Invalid;
}

//===----------------------------------------------------------------------===//
// Operations for querying language of a cursor.
//===----------------------------------------------------------------------===//

static CXLanguageKind getDeclLanguage(const Decl *D) {
  if (!D)
    return CXLanguage_C;

  switch (D->getKind()) {
  default:
    break;
  case Decl::ImplicitParam:
  case Decl::ObjCAtDefsField:
  case Decl::ObjCCategory:
  case Decl::ObjCCategoryImpl:
  case Decl::ObjCCompatibleAlias:
  case Decl::ObjCImplementation:
  case Decl::ObjCInterface:
  case Decl::ObjCIvar:
  case Decl::ObjCMethod:
  case Decl::ObjCProperty:
  case Decl::ObjCPropertyImpl:
  case Decl::ObjCProtocol:
  case Decl::ObjCTypeParam:
    return CXLanguage_ObjC;
  case Decl::CXXConstructor:
  case Decl::CXXConversion:
  case Decl::CXXDestructor:
  case Decl::CXXMethod:
  case Decl::CXXRecord:
  case Decl::ClassTemplate:
  case Decl::ClassTemplatePartialSpecialization:
  case Decl::ClassTemplateSpecialization:
  case Decl::Friend:
  case Decl::FriendTemplate:
  case Decl::FunctionTemplate:
  case Decl::LinkageSpec:
  case Decl::Namespace:
  case Decl::NamespaceAlias:
  case Decl::NonTypeTemplateParm:
  case Decl::StaticAssert:
  case Decl::TemplateTemplateParm:
  case Decl::TemplateTypeParm:
  case Decl::UnresolvedUsingTypename:
  case Decl::UnresolvedUsingValue:
  case Decl::Using:
  case Decl::UsingDirective:
  case Decl::UsingShadow:
    return CXLanguage_CPlusPlus;
  }

  return CXLanguage_C;
}

static CXAvailabilityKind getCursorAvailabilityForDecl(const Decl *D) {
  if (isa<FunctionDecl>(D) && cast<FunctionDecl>(D)->isDeleted())
    return CXAvailability_NotAvailable;

  switch (D->getAvailability()) {
  case AR_Available:
  case AR_NotYetIntroduced:
    if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
      return getCursorAvailabilityForDecl(
          cast<Decl>(EnumConst->getDeclContext()));
    return CXAvailability_Available;

  case AR_Deprecated:
    return CXAvailability_Deprecated;

  case AR_Unavailable:
    return CXAvailability_NotAvailable;
  }

  llvm_unreachable("Unknown availability kind!");
}

enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor) {
  if (clang_isDeclaration(cursor.kind))
    if (const Decl *D = cxcursor::getCursorDecl(cursor))
      return getCursorAvailabilityForDecl(D);

  return CXAvailability_Available;
}

static CXVersion convertVersion(VersionTuple In) {
  CXVersion Out = {-1, -1, -1};
  if (In.empty())
    return Out;

  Out.Major = In.getMajor();

  Optional<unsigned> Minor = In.getMinor();
  if (Minor.hasValue())
    Out.Minor = *Minor;
  else
    return Out;

  Optional<unsigned> Subminor = In.getSubminor();
  if (Subminor.hasValue())
    Out.Subminor = *Subminor;

  return Out;
}

static void getCursorPlatformAvailabilityForDecl(
    const Decl *D, int *always_deprecated, CXString *deprecated_message,
    int *always_unavailable, CXString *unavailable_message,
    SmallVectorImpl<AvailabilityAttr *> &AvailabilityAttrs) {
  bool HadAvailAttr = false;
  for (auto A : D->attrs()) {
    if (DeprecatedAttr *Deprecated = dyn_cast<DeprecatedAttr>(A)) {
      HadAvailAttr = true;
      if (always_deprecated)
        *always_deprecated = 1;
      if (deprecated_message) {
        clang_disposeString(*deprecated_message);
        *deprecated_message = cxstring::createDup(Deprecated->getMessage());
      }
      continue;
    }

    if (UnavailableAttr *Unavailable = dyn_cast<UnavailableAttr>(A)) {
      HadAvailAttr = true;
      if (always_unavailable)
        *always_unavailable = 1;
      if (unavailable_message) {
        clang_disposeString(*unavailable_message);
        *unavailable_message = cxstring::createDup(Unavailable->getMessage());
      }
      continue;
    }

    if (AvailabilityAttr *Avail = dyn_cast<AvailabilityAttr>(A)) {
      AvailabilityAttrs.push_back(Avail);
      HadAvailAttr = true;
    }
  }

  if (!HadAvailAttr)
    if (const EnumConstantDecl *EnumConst = dyn_cast<EnumConstantDecl>(D))
      return getCursorPlatformAvailabilityForDecl(
          cast<Decl>(EnumConst->getDeclContext()), always_deprecated,
          deprecated_message, always_unavailable, unavailable_message,
          AvailabilityAttrs);

  if (AvailabilityAttrs.empty())
    return;

  llvm::sort(
      AvailabilityAttrs, [](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
        return LHS->getPlatform()->getName() < RHS->getPlatform()->getName();
      });
  ASTContext &Ctx = D->getASTContext();
  auto It = std::unique(
      AvailabilityAttrs.begin(), AvailabilityAttrs.end(),
      [&Ctx](AvailabilityAttr *LHS, AvailabilityAttr *RHS) {
        if (LHS->getPlatform() != RHS->getPlatform())
          return false;

        if (LHS->getIntroduced() == RHS->getIntroduced() &&
            LHS->getDeprecated() == RHS->getDeprecated() &&
            LHS->getObsoleted() == RHS->getObsoleted() &&
            LHS->getMessage() == RHS->getMessage() &&
            LHS->getReplacement() == RHS->getReplacement())
          return true;

        if ((!LHS->getIntroduced().empty() && !RHS->getIntroduced().empty()) ||
            (!LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) ||
            (!LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()))
          return false;

        if (LHS->getIntroduced().empty() && !RHS->getIntroduced().empty())
          LHS->setIntroduced(Ctx, RHS->getIntroduced());

        if (LHS->getDeprecated().empty() && !RHS->getDeprecated().empty()) {
          LHS->setDeprecated(Ctx, RHS->getDeprecated());
          if (LHS->getMessage().empty())
            LHS->setMessage(Ctx, RHS->getMessage());
          if (LHS->getReplacement().empty())
            LHS->setReplacement(Ctx, RHS->getReplacement());
        }

        if (LHS->getObsoleted().empty() && !RHS->getObsoleted().empty()) {
          LHS->setObsoleted(Ctx, RHS->getObsoleted());
          if (LHS->getMessage().empty())
            LHS->setMessage(Ctx, RHS->getMessage());
          if (LHS->getReplacement().empty())
            LHS->setReplacement(Ctx, RHS->getReplacement());
        }

        return true;
      });
  AvailabilityAttrs.erase(It, AvailabilityAttrs.end());
}

int clang_getCursorPlatformAvailability(CXCursor cursor, int *always_deprecated,
                                        CXString *deprecated_message,
                                        int *always_unavailable,
                                        CXString *unavailable_message,
                                        CXPlatformAvailability *availability,
                                        int availability_size) {
  if (always_deprecated)
    *always_deprecated = 0;
  if (deprecated_message)
    *deprecated_message = cxstring::createEmpty();
  if (always_unavailable)
    *always_unavailable = 0;
  if (unavailable_message)
    *unavailable_message = cxstring::createEmpty();

  if (!clang_isDeclaration(cursor.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(cursor);
  if (!D)
    return 0;

  SmallVector<AvailabilityAttr *, 8> AvailabilityAttrs;
  getCursorPlatformAvailabilityForDecl(D, always_deprecated, deprecated_message,
                                       always_unavailable, unavailable_message,
                                       AvailabilityAttrs);
  for (const auto &Avail :
       llvm::enumerate(llvm::makeArrayRef(AvailabilityAttrs)
                           .take_front(availability_size))) {
    availability[Avail.index()].Platform =
        cxstring::createDup(Avail.value()->getPlatform()->getName());
    availability[Avail.index()].Introduced =
        convertVersion(Avail.value()->getIntroduced());
    availability[Avail.index()].Deprecated =
        convertVersion(Avail.value()->getDeprecated());
    availability[Avail.index()].Obsoleted =
        convertVersion(Avail.value()->getObsoleted());
    availability[Avail.index()].Unavailable = Avail.value()->getUnavailable();
    availability[Avail.index()].Message =
        cxstring::createDup(Avail.value()->getMessage());
  }

  return AvailabilityAttrs.size();
}

void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability) {
  clang_disposeString(availability->Platform);
  clang_disposeString(availability->Message);
}

CXLanguageKind clang_getCursorLanguage(CXCursor cursor) {
  if (clang_isDeclaration(cursor.kind))
    return getDeclLanguage(cxcursor::getCursorDecl(cursor));

  return CXLanguage_Invalid;
}

CXTLSKind clang_getCursorTLSKind(CXCursor cursor) {
  const Decl *D = cxcursor::getCursorDecl(cursor);
  if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
    switch (VD->getTLSKind()) {
    case VarDecl::TLS_None:
      return CXTLS_None;
    case VarDecl::TLS_Dynamic:
      return CXTLS_Dynamic;
    case VarDecl::TLS_Static:
      return CXTLS_Static;
    }
  }

  return CXTLS_None;
}

/// If the given cursor is the "templated" declaration
/// describing a class or function template, return the class or
/// function template.
static const Decl *maybeGetTemplateCursor(const Decl *D) {
  if (!D)
    return nullptr;

  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
    if (FunctionTemplateDecl *FunTmpl = FD->getDescribedFunctionTemplate())
      return FunTmpl;

  if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D))
    if (ClassTemplateDecl *ClassTmpl = RD->getDescribedClassTemplate())
      return ClassTmpl;

  return D;
}

enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor C) {
  StorageClass sc = SC_None;
  const Decl *D = getCursorDecl(C);
  if (D) {
    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
      sc = FD->getStorageClass();
    } else if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
      sc = VD->getStorageClass();
    } else {
      return CX_SC_Invalid;
    }
  } else {
    return CX_SC_Invalid;
  }
  switch (sc) {
  case SC_None:
    return CX_SC_None;
  case SC_Extern:
    return CX_SC_Extern;
  case SC_Static:
    return CX_SC_Static;
  case SC_PrivateExtern:
    return CX_SC_PrivateExtern;
  case SC_Auto:
    return CX_SC_Auto;
  case SC_Register:
    return CX_SC_Register;
  }
  llvm_unreachable("Unhandled storage class!");
}

CXCursor clang_getCursorSemanticParent(CXCursor cursor) {
  if (clang_isDeclaration(cursor.kind)) {
    if (const Decl *D = getCursorDecl(cursor)) {
      const DeclContext *DC = D->getDeclContext();
      if (!DC)
        return clang_getNullCursor();

      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
                          getCursorTU(cursor));
    }
  }

  if (clang_isStatement(cursor.kind) || clang_isExpression(cursor.kind)) {
    if (const Decl *D = getCursorDecl(cursor))
      return MakeCXCursor(D, getCursorTU(cursor));
  }

  return clang_getNullCursor();
}

CXCursor clang_getCursorLexicalParent(CXCursor cursor) {
  if (clang_isDeclaration(cursor.kind)) {
    if (const Decl *D = getCursorDecl(cursor)) {
      const DeclContext *DC = D->getLexicalDeclContext();
      if (!DC)
        return clang_getNullCursor();

      return MakeCXCursor(maybeGetTemplateCursor(cast<Decl>(DC)),
                          getCursorTU(cursor));
    }
  }

  // FIXME: Note that we can't easily compute the lexical context of a
  // statement or expression, so we return nothing.
  return clang_getNullCursor();
}

CXFile clang_getIncludedFile(CXCursor cursor) {
  if (cursor.kind != CXCursor_InclusionDirective)
    return nullptr;

  const InclusionDirective *ID = getCursorInclusionDirective(cursor);
  return const_cast<FileEntry *>(ID->getFile());
}

unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved) {
  if (C.kind != CXCursor_ObjCPropertyDecl)
    return CXObjCPropertyAttr_noattr;

  unsigned Result = CXObjCPropertyAttr_noattr;
  const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
  ObjCPropertyAttribute::Kind Attr = PD->getPropertyAttributesAsWritten();

#define SET_CXOBJCPROP_ATTR(A)                                                 \
  if (Attr & ObjCPropertyAttribute::kind_##A)                                  \
  Result |= CXObjCPropertyAttr_##A
  SET_CXOBJCPROP_ATTR(readonly);
  SET_CXOBJCPROP_ATTR(getter);
  SET_CXOBJCPROP_ATTR(assign);
  SET_CXOBJCPROP_ATTR(readwrite);
  SET_CXOBJCPROP_ATTR(retain);
  SET_CXOBJCPROP_ATTR(copy);
  SET_CXOBJCPROP_ATTR(nonatomic);
  SET_CXOBJCPROP_ATTR(setter);
  SET_CXOBJCPROP_ATTR(atomic);
  SET_CXOBJCPROP_ATTR(weak);
  SET_CXOBJCPROP_ATTR(strong);
  SET_CXOBJCPROP_ATTR(unsafe_unretained);
  SET_CXOBJCPROP_ATTR(class);
#undef SET_CXOBJCPROP_ATTR

  return Result;
}

CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C) {
  if (C.kind != CXCursor_ObjCPropertyDecl)
    return cxstring::createNull();

  const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
  Selector sel = PD->getGetterName();
  if (sel.isNull())
    return cxstring::createNull();

  return cxstring::createDup(sel.getAsString());
}

CXString clang_Cursor_getObjCPropertySetterName(CXCursor C) {
  if (C.kind != CXCursor_ObjCPropertyDecl)
    return cxstring::createNull();

  const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(getCursorDecl(C));
  Selector sel = PD->getSetterName();
  if (sel.isNull())
    return cxstring::createNull();

  return cxstring::createDup(sel.getAsString());
}

unsigned clang_Cursor_getObjCDeclQualifiers(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return CXObjCDeclQualifier_None;

  Decl::ObjCDeclQualifier QT = Decl::OBJC_TQ_None;
  const Decl *D = getCursorDecl(C);
  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
    QT = MD->getObjCDeclQualifier();
  else if (const ParmVarDecl *PD = dyn_cast<ParmVarDecl>(D))
    QT = PD->getObjCDeclQualifier();
  if (QT == Decl::OBJC_TQ_None)
    return CXObjCDeclQualifier_None;

  unsigned Result = CXObjCDeclQualifier_None;
  if (QT & Decl::OBJC_TQ_In)
    Result |= CXObjCDeclQualifier_In;
  if (QT & Decl::OBJC_TQ_Inout)
    Result |= CXObjCDeclQualifier_Inout;
  if (QT & Decl::OBJC_TQ_Out)
    Result |= CXObjCDeclQualifier_Out;
  if (QT & Decl::OBJC_TQ_Bycopy)
    Result |= CXObjCDeclQualifier_Bycopy;
  if (QT & Decl::OBJC_TQ_Byref)
    Result |= CXObjCDeclQualifier_Byref;
  if (QT & Decl::OBJC_TQ_Oneway)
    Result |= CXObjCDeclQualifier_Oneway;

  return Result;
}

unsigned clang_Cursor_isObjCOptional(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = getCursorDecl(C);
  if (const ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(D))
    return PD->getPropertyImplementation() == ObjCPropertyDecl::Optional;
  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
    return MD->getImplementationControl() == ObjCMethodDecl::Optional;

  return 0;
}

unsigned clang_Cursor_isVariadic(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = getCursorDecl(C);
  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
    return FD->isVariadic();
  if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
    return MD->isVariadic();

  return 0;
}

unsigned clang_Cursor_isExternalSymbol(CXCursor C, CXString *language,
                                       CXString *definedIn,
                                       unsigned *isGenerated) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = getCursorDecl(C);

  if (auto *attr = D->getExternalSourceSymbolAttr()) {
    if (language)
      *language = cxstring::createDup(attr->getLanguage());
    if (definedIn)
      *definedIn = cxstring::createDup(attr->getDefinedIn());
    if (isGenerated)
      *isGenerated = attr->getGeneratedDeclaration();
    return 1;
  }
  return 0;
}

CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return clang_getNullRange();

  const Decl *D = getCursorDecl(C);
  ASTContext &Context = getCursorContext(C);
  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
  if (!RC)
    return clang_getNullRange();

  return cxloc::translateSourceRange(Context, RC->getSourceRange());
}

CXString clang_Cursor_getRawCommentText(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return cxstring::createNull();

  const Decl *D = getCursorDecl(C);
  ASTContext &Context = getCursorContext(C);
  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);
  StringRef RawText =
      RC ? RC->getRawText(Context.getSourceManager()) : StringRef();

  // Don't duplicate the string because RawText points directly into source
  // code.
  return cxstring::createRef(RawText);
}

CXString clang_Cursor_getBriefCommentText(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return cxstring::createNull();

  const Decl *D = getCursorDecl(C);
  const ASTContext &Context = getCursorContext(C);
  const RawComment *RC = Context.getRawCommentForAnyRedecl(D);

  if (RC) {
    StringRef BriefText = RC->getBriefText(Context);

    // Don't duplicate the string because RawComment ensures that this memory
    // will not go away.
    return cxstring::createRef(BriefText);
  }

  return cxstring::createNull();
}

CXModule clang_Cursor_getModule(CXCursor C) {
  if (C.kind == CXCursor_ModuleImportDecl) {
    if (const ImportDecl *ImportD =
            dyn_cast_or_null<ImportDecl>(getCursorDecl(C)))
      return ImportD->getImportedModule();
  }

  return nullptr;
}

CXModule clang_getModuleForFile(CXTranslationUnit TU, CXFile File) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return nullptr;
  }
  if (!File)
    return nullptr;
  FileEntry *FE = static_cast<FileEntry *>(File);

  ASTUnit &Unit = *cxtu::getASTUnit(TU);
  HeaderSearch &HS = Unit.getPreprocessor().getHeaderSearchInfo();
  ModuleMap::KnownHeader Header = HS.findModuleForHeader(FE);

  return Header.getModule();
}

CXFile clang_Module_getASTFile(CXModule CXMod) {
  if (!CXMod)
    return nullptr;
  Module *Mod = static_cast<Module *>(CXMod);
  return const_cast<FileEntry *>(Mod->getASTFile());
}

CXModule clang_Module_getParent(CXModule CXMod) {
  if (!CXMod)
    return nullptr;
  Module *Mod = static_cast<Module *>(CXMod);
  return Mod->Parent;
}

CXString clang_Module_getName(CXModule CXMod) {
  if (!CXMod)
    return cxstring::createEmpty();
  Module *Mod = static_cast<Module *>(CXMod);
  return cxstring::createDup(Mod->Name);
}

CXString clang_Module_getFullName(CXModule CXMod) {
  if (!CXMod)
    return cxstring::createEmpty();
  Module *Mod = static_cast<Module *>(CXMod);
  return cxstring::createDup(Mod->getFullModuleName());
}

int clang_Module_isSystem(CXModule CXMod) {
  if (!CXMod)
    return 0;
  Module *Mod = static_cast<Module *>(CXMod);
  return Mod->IsSystem;
}

unsigned clang_Module_getNumTopLevelHeaders(CXTranslationUnit TU,
                                            CXModule CXMod) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return 0;
  }
  if (!CXMod)
    return 0;
  Module *Mod = static_cast<Module *>(CXMod);
  FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();
  ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
  return TopHeaders.size();
}

CXFile clang_Module_getTopLevelHeader(CXTranslationUnit TU, CXModule CXMod,
                                      unsigned Index) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return nullptr;
  }
  if (!CXMod)
    return nullptr;
  Module *Mod = static_cast<Module *>(CXMod);
  FileManager &FileMgr = cxtu::getASTUnit(TU)->getFileManager();

  ArrayRef<const FileEntry *> TopHeaders = Mod->getTopHeaders(FileMgr);
  if (Index < TopHeaders.size())
    return const_cast<FileEntry *>(TopHeaders[Index]);

  return nullptr;
}

//===----------------------------------------------------------------------===//
// C++ AST instrospection.
//===----------------------------------------------------------------------===//

unsigned clang_CXXConstructor_isDefaultConstructor(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXConstructorDecl *Constructor =
      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
  return (Constructor && Constructor->isDefaultConstructor()) ? 1 : 0;
}

unsigned clang_CXXConstructor_isCopyConstructor(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXConstructorDecl *Constructor =
      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
  return (Constructor && Constructor->isCopyConstructor()) ? 1 : 0;
}

unsigned clang_CXXConstructor_isMoveConstructor(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXConstructorDecl *Constructor =
      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
  return (Constructor && Constructor->isMoveConstructor()) ? 1 : 0;
}

unsigned clang_CXXConstructor_isConvertingConstructor(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXConstructorDecl *Constructor =
      D ? dyn_cast_or_null<CXXConstructorDecl>(D->getAsFunction()) : nullptr;
  // Passing 'false' excludes constructors marked 'explicit'.
  return (Constructor && Constructor->isConvertingConstructor(false)) ? 1 : 0;
}

unsigned clang_CXXField_isMutable(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  if (const auto D = cxcursor::getCursorDecl(C))
    if (const auto FD = dyn_cast_or_null<FieldDecl>(D))
      return FD->isMutable() ? 1 : 0;
  return 0;
}

unsigned clang_CXXMethod_isPureVirtual(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXMethodDecl *Method =
      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
  return (Method && Method->isVirtual() && Method->isPure()) ? 1 : 0;
}

unsigned clang_CXXMethod_isConst(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXMethodDecl *Method =
      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
  return (Method && Method->getMethodQualifiers().hasConst()) ? 1 : 0;
}

unsigned clang_CXXMethod_isDefaulted(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXMethodDecl *Method =
      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
  return (Method && Method->isDefaulted()) ? 1 : 0;
}

unsigned clang_CXXMethod_isStatic(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXMethodDecl *Method =
      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
  return (Method && Method->isStatic()) ? 1 : 0;
}

unsigned clang_CXXMethod_isVirtual(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  const CXXMethodDecl *Method =
      D ? dyn_cast_or_null<CXXMethodDecl>(D->getAsFunction()) : nullptr;
  return (Method && Method->isVirtual()) ? 1 : 0;
}

unsigned clang_CXXRecord_isAbstract(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const auto *D = cxcursor::getCursorDecl(C);
  const auto *RD = dyn_cast_or_null<CXXRecordDecl>(D);
  if (RD)
    RD = RD->getDefinition();
  return (RD && RD->isAbstract()) ? 1 : 0;
}

unsigned clang_EnumDecl_isScoped(CXCursor C) {
  if (!clang_isDeclaration(C.kind))
    return 0;

  const Decl *D = cxcursor::getCursorDecl(C);
  auto *Enum = dyn_cast_or_null<EnumDecl>(D);
  return (Enum && Enum->isScoped()) ? 1 : 0;
}

//===----------------------------------------------------------------------===//
// Attribute introspection.
//===----------------------------------------------------------------------===//

CXType clang_getIBOutletCollectionType(CXCursor C) {
  if (C.kind != CXCursor_IBOutletCollectionAttr)
    return cxtype::MakeCXType(QualType(), cxcursor::getCursorTU(C));

  const IBOutletCollectionAttr *A =
      cast<IBOutletCollectionAttr>(cxcursor::getCursorAttr(C));

  return cxtype::MakeCXType(A->getInterface(), cxcursor::getCursorTU(C));
}

//===----------------------------------------------------------------------===//
// Inspecting memory usage.
//===----------------------------------------------------------------------===//

typedef std::vector<CXTUResourceUsageEntry> MemUsageEntries;

static inline void createCXTUResourceUsageEntry(MemUsageEntries &entries,
                                                enum CXTUResourceUsageKind k,
                                                unsigned long amount) {
  CXTUResourceUsageEntry entry = {k, amount};
  entries.push_back(entry);
}

const char *clang_getTUResourceUsageName(CXTUResourceUsageKind kind) {
  const char *str = "";
  switch (kind) {
  case CXTUResourceUsage_AST:
    str = "ASTContext: expressions, declarations, and types";
    break;
  case CXTUResourceUsage_Identifiers:
    str = "ASTContext: identifiers";
    break;
  case CXTUResourceUsage_Selectors:
    str = "ASTContext: selectors";
    break;
  case CXTUResourceUsage_GlobalCompletionResults:
    str = "Code completion: cached global results";
    break;
  case CXTUResourceUsage_SourceManagerContentCache:
    str = "SourceManager: content cache allocator";
    break;
  case CXTUResourceUsage_AST_SideTables:
    str = "ASTContext: side tables";
    break;
  case CXTUResourceUsage_SourceManager_Membuffer_Malloc:
    str = "SourceManager: malloc'ed memory buffers";
    break;
  case CXTUResourceUsage_SourceManager_Membuffer_MMap:
    str = "SourceManager: mmap'ed memory buffers";
    break;
  case CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc:
    str = "ExternalASTSource: malloc'ed memory buffers";
    break;
  case CXTUResourceUsage_ExternalASTSource_Membuffer_MMap:
    str = "ExternalASTSource: mmap'ed memory buffers";
    break;
  case CXTUResourceUsage_Preprocessor:
    str = "Preprocessor: malloc'ed memory";
    break;
  case CXTUResourceUsage_PreprocessingRecord:
    str = "Preprocessor: PreprocessingRecord";
    break;
  case CXTUResourceUsage_SourceManager_DataStructures:
    str = "SourceManager: data structures and tables";
    break;
  case CXTUResourceUsage_Preprocessor_HeaderSearch:
    str = "Preprocessor: header search tables";
    break;
  }
  return str;
}

CXTUResourceUsage clang_getCXTUResourceUsage(CXTranslationUnit TU) {
  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    CXTUResourceUsage usage = {(void *)nullptr, 0, nullptr};
    return usage;
  }

  ASTUnit *astUnit = cxtu::getASTUnit(TU);
  std::unique_ptr<MemUsageEntries> entries(new MemUsageEntries());
  ASTContext &astContext = astUnit->getASTContext();

  // How much memory is used by AST nodes and types?
  createCXTUResourceUsageEntry(
      *entries, CXTUResourceUsage_AST,
      (unsigned long)astContext.getASTAllocatedMemory());

  // How much memory is used by identifiers?
  createCXTUResourceUsageEntry(
      *entries, CXTUResourceUsage_Identifiers,
      (unsigned long)astContext.Idents.getAllocator().getTotalMemory());

  // How much memory is used for selectors?
  createCXTUResourceUsageEntry(
      *entries, CXTUResourceUsage_Selectors,
      (unsigned long)astContext.Selectors.getTotalMemory());

  // How much memory is used by ASTContext's side tables?
  createCXTUResourceUsageEntry(
      *entries, CXTUResourceUsage_AST_SideTables,
      (unsigned long)astContext.getSideTableAllocatedMemory());

  // How much memory is used for caching global code completion results?
  unsigned long completionBytes = 0;
  if (GlobalCodeCompletionAllocator *completionAllocator =
          astUnit->getCachedCompletionAllocator().get()) {
    completionBytes = completionAllocator->getTotalMemory();
  }
  createCXTUResourceUsageEntry(
      *entries, CXTUResourceUsage_GlobalCompletionResults, completionBytes);

  // How much memory is being used by SourceManager's content cache?
  createCXTUResourceUsageEntry(
      *entries, CXTUResourceUsage_SourceManagerContentCache,
      (unsigned long)astContext.getSourceManager().getContentCacheSize());

  // How much memory is being used by the MemoryBuffer's in SourceManager?
  const SourceManager::MemoryBufferSizes &srcBufs =
      astUnit->getSourceManager().getMemoryBufferSizes();

  createCXTUResourceUsageEntry(*entries,
                               CXTUResourceUsage_SourceManager_Membuffer_Malloc,
                               (unsigned long)srcBufs.malloc_bytes);
  createCXTUResourceUsageEntry(*entries,
                               CXTUResourceUsage_SourceManager_Membuffer_MMap,
                               (unsigned long)srcBufs.mmap_bytes);
  createCXTUResourceUsageEntry(
      *entries, CXTUResourceUsage_SourceManager_DataStructures,
      (unsigned long)astContext.getSourceManager().getDataStructureSizes());

  // How much memory is being used by the ExternalASTSource?
  if (ExternalASTSource *esrc = astContext.getExternalSource()) {
    const ExternalASTSource::MemoryBufferSizes &sizes =
        esrc->getMemoryBufferSizes();

    createCXTUResourceUsageEntry(
        *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc,
        (unsigned long)sizes.malloc_bytes);
    createCXTUResourceUsageEntry(
        *entries, CXTUResourceUsage_ExternalASTSource_Membuffer_MMap,
        (unsigned long)sizes.mmap_bytes);
  }

  // How much memory is being used by the Preprocessor?
  Preprocessor &pp = astUnit->getPreprocessor();
  createCXTUResourceUsageEntry(*entries, CXTUResourceUsage_Preprocessor,
                               pp.getTotalMemory());

  if (PreprocessingRecord *pRec = pp.getPreprocessingRecord()) {
    createCXTUResourceUsageEntry(*entries,
                                 CXTUResourceUsage_PreprocessingRecord,
                                 pRec->getTotalMemory());
  }

  createCXTUResourceUsageEntry(*entries,
                               CXTUResourceUsage_Preprocessor_HeaderSearch,
                               pp.getHeaderSearchInfo().getTotalMemory());

  CXTUResourceUsage usage = {(void *)entries.get(), (unsigned)entries->size(),
                             !entries->empty() ? &(*entries)[0] : nullptr};
  (void)entries.release();
  return usage;
}

void clang_disposeCXTUResourceUsage(CXTUResourceUsage usage) {
  if (usage.data)
    delete (MemUsageEntries *)usage.data;
}

CXSourceRangeList *clang_getSkippedRanges(CXTranslationUnit TU, CXFile file) {
  CXSourceRangeList *skipped = new CXSourceRangeList;
  skipped->count = 0;
  skipped->ranges = nullptr;

  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return skipped;
  }

  if (!file)
    return skipped;

  ASTUnit *astUnit = cxtu::getASTUnit(TU);
  PreprocessingRecord *ppRec =
      astUnit->getPreprocessor().getPreprocessingRecord();
  if (!ppRec)
    return skipped;

  ASTContext &Ctx = astUnit->getASTContext();
  SourceManager &sm = Ctx.getSourceManager();
  FileEntry *fileEntry = static_cast<FileEntry *>(file);
  FileID wantedFileID = sm.translateFile(fileEntry);
  bool isMainFile = wantedFileID == sm.getMainFileID();

  const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();
  std::vector<SourceRange> wantedRanges;
  for (std::vector<SourceRange>::const_iterator i = SkippedRanges.begin(),
                                                ei = SkippedRanges.end();
       i != ei; ++i) {
    if (sm.getFileID(i->getBegin()) == wantedFileID ||
        sm.getFileID(i->getEnd()) == wantedFileID)
      wantedRanges.push_back(*i);
    else if (isMainFile && (astUnit->isInPreambleFileID(i->getBegin()) ||
                            astUnit->isInPreambleFileID(i->getEnd())))
      wantedRanges.push_back(*i);
  }

  skipped->count = wantedRanges.size();
  skipped->ranges = new CXSourceRange[skipped->count];
  for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
    skipped->ranges[i] = cxloc::translateSourceRange(Ctx, wantedRanges[i]);

  return skipped;
}

CXSourceRangeList *clang_getAllSkippedRanges(CXTranslationUnit TU) {
  CXSourceRangeList *skipped = new CXSourceRangeList;
  skipped->count = 0;
  skipped->ranges = nullptr;

  if (isNotUsableTU(TU)) {
    LOG_BAD_TU(TU);
    return skipped;
  }

  ASTUnit *astUnit = cxtu::getASTUnit(TU);
  PreprocessingRecord *ppRec =
      astUnit->getPreprocessor().getPreprocessingRecord();
  if (!ppRec)
    return skipped;

  ASTContext &Ctx = astUnit->getASTContext();

  const std::vector<SourceRange> &SkippedRanges = ppRec->getSkippedRanges();

  skipped->count = SkippedRanges.size();
  skipped->ranges = new CXSourceRange[skipped->count];
  for (unsigned i = 0, ei = skipped->count; i != ei; ++i)
    skipped->ranges[i] = cxloc::translateSourceRange(Ctx, SkippedRanges[i]);

  return skipped;
}

void clang_disposeSourceRangeList(CXSourceRangeList *ranges) {
  if (ranges) {
    delete[] ranges->ranges;
    delete ranges;
  }
}

void clang::PrintLibclangResourceUsage(CXTranslationUnit TU) {
  CXTUResourceUsage Usage = clang_getCXTUResourceUsage(TU);
  for (unsigned I = 0; I != Usage.numEntries; ++I)
    fprintf(stderr, "  %s: %lu\n",
            clang_getTUResourceUsageName(Usage.entries[I].kind),
            Usage.entries[I].amount);

  clang_disposeCXTUResourceUsage(Usage);
}

//===----------------------------------------------------------------------===//
// Misc. utility functions.
//===----------------------------------------------------------------------===//

/// Default to using our desired 8 MB stack size on "safety" threads.
static unsigned SafetyStackThreadSize = DesiredStackSize;

namespace clang {

bool RunSafely(llvm::CrashRecoveryContext &CRC, llvm::function_ref<void()> Fn,
               unsigned Size) {
  if (!Size)
    Size = GetSafetyThreadStackSize();
  if (Size && !getenv("LIBCLANG_NOTHREADS"))
    return CRC.RunSafelyOnThread(Fn, Size);
  return CRC.RunSafely(Fn);
}

unsigned GetSafetyThreadStackSize() { return SafetyStackThreadSize; }

void SetSafetyThreadStackSize(unsigned Value) { SafetyStackThreadSize = Value; }

} // namespace clang

void clang::setThreadBackgroundPriority() {
  if (getenv("LIBCLANG_BGPRIO_DISABLE"))
    return;

#if LLVM_ENABLE_THREADS
  llvm::set_thread_priority(llvm::ThreadPriority::Background);
#endif
}

void cxindex::printDiagsToStderr(ASTUnit *Unit) {
  if (!Unit)
    return;

  for (ASTUnit::stored_diag_iterator D = Unit->stored_diag_begin(),
                                     DEnd = Unit->stored_diag_end();
       D != DEnd; ++D) {
    CXStoredDiagnostic Diag(*D, Unit->getLangOpts());
    CXString Msg =
        clang_formatDiagnostic(&Diag, clang_defaultDiagnosticDisplayOptions());
    fprintf(stderr, "%s\n", clang_getCString(Msg));
    clang_disposeString(Msg);
  }
#ifdef _WIN32
  // On Windows, force a flush, since there may be multiple copies of
  // stderr and stdout in the file system, all with different buffers
  // but writing to the same device.
  fflush(stderr);
#endif
}

MacroInfo *cxindex::getMacroInfo(const IdentifierInfo &II,
                                 SourceLocation MacroDefLoc,
                                 CXTranslationUnit TU) {
  if (MacroDefLoc.isInvalid() || !TU)
    return nullptr;
  if (!II.hadMacroDefinition())
    return nullptr;

  ASTUnit *Unit = cxtu::getASTUnit(TU);
  Preprocessor &PP = Unit->getPreprocessor();
  MacroDirective *MD = PP.getLocalMacroDirectiveHistory(&II);
  if (MD) {
    for (MacroDirective::DefInfo Def = MD->getDefinition(); Def;
         Def = Def.getPreviousDefinition()) {
      if (MacroDefLoc == Def.getMacroInfo()->getDefinitionLoc())
        return Def.getMacroInfo();
    }
  }

  return nullptr;
}

const MacroInfo *cxindex::getMacroInfo(const MacroDefinitionRecord *MacroDef,
                                       CXTranslationUnit TU) {
  if (!MacroDef || !TU)
    return nullptr;
  const IdentifierInfo *II = MacroDef->getName();
  if (!II)
    return nullptr;

  return getMacroInfo(*II, MacroDef->getLocation(), TU);
}

MacroDefinitionRecord *
cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
                                        CXTranslationUnit TU) {
  if (!MI || !TU)
    return nullptr;
  if (Tok.isNot(tok::raw_identifier))
    return nullptr;

  if (MI->getNumTokens() == 0)
    return nullptr;
  SourceRange DefRange(MI->getReplacementToken(0).getLocation(),
                       MI->getDefinitionEndLoc());
  ASTUnit *Unit = cxtu::getASTUnit(TU);

  // Check that the token is inside the definition and not its argument list.
  SourceManager &SM = Unit->getSourceManager();
  if (SM.isBeforeInTranslationUnit(Tok.getLocation(), DefRange.getBegin()))
    return nullptr;
  if (SM.isBeforeInTranslationUnit(DefRange.getEnd(), Tok.getLocation()))
    return nullptr;

  Preprocessor &PP = Unit->getPreprocessor();
  PreprocessingRecord *PPRec = PP.getPreprocessingRecord();
  if (!PPRec)
    return nullptr;

  IdentifierInfo &II = PP.getIdentifierTable().get(Tok.getRawIdentifier());
  if (!II.hadMacroDefinition())
    return nullptr;

  // Check that the identifier is not one of the macro arguments.
  if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
    return nullptr;

  MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
  if (!InnerMD)
    return nullptr;

  return PPRec->findMacroDefinition(InnerMD->getMacroInfo());
}

MacroDefinitionRecord *
cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, SourceLocation Loc,
                                        CXTranslationUnit TU) {
  if (Loc.isInvalid() || !MI || !TU)
    return nullptr;

  if (MI->getNumTokens() == 0)
    return nullptr;
  ASTUnit *Unit = cxtu::getASTUnit(TU);
  Preprocessor &PP = Unit->getPreprocessor();
  if (!PP.getPreprocessingRecord())
    return nullptr;
  Loc = Unit->getSourceManager().getSpellingLoc(Loc);
  Token Tok;
  if (PP.getRawToken(Loc, Tok))
    return nullptr;

  return checkForMacroInMacroDefinition(MI, Tok, TU);
}

CXString clang_getClangVersion() {
  return cxstring::createDup(getClangFullVersion());
}

Logger &cxindex::Logger::operator<<(CXTranslationUnit TU) {
  if (TU) {
    if (ASTUnit *Unit = cxtu::getASTUnit(TU)) {
      LogOS << '<' << Unit->getMainFileName() << '>';
      if (Unit->isMainFileAST())
        LogOS << " (" << Unit->getASTFileName() << ')';
      return *this;
    }
  } else {
    LogOS << "<NULL TU>";
  }
  return *this;
}

Logger &cxindex::Logger::operator<<(const FileEntry *FE) {
  *this << FE->getName();
  return *this;
}

Logger &cxindex::Logger::operator<<(CXCursor cursor) {
  CXString cursorName = clang_getCursorDisplayName(cursor);
  *this << cursorName << "@" << clang_getCursorLocation(cursor);
  clang_disposeString(cursorName);
  return *this;
}

Logger &cxindex::Logger::operator<<(CXSourceLocation Loc) {
  CXFile File;
  unsigned Line, Column;
  clang_getFileLocation(Loc, &File, &Line, &Column, nullptr);
  CXString FileName = clang_getFileName(File);
  *this << llvm::format("(%s:%d:%d)", clang_getCString(FileName), Line, Column);
  clang_disposeString(FileName);
  return *this;
}

Logger &cxindex::Logger::operator<<(CXSourceRange range) {
  CXSourceLocation BLoc = clang_getRangeStart(range);
  CXSourceLocation ELoc = clang_getRangeEnd(range);

  CXFile BFile;
  unsigned BLine, BColumn;
  clang_getFileLocation(BLoc, &BFile, &BLine, &BColumn, nullptr);

  CXFile EFile;
  unsigned ELine, EColumn;
  clang_getFileLocation(ELoc, &EFile, &ELine, &EColumn, nullptr);

  CXString BFileName = clang_getFileName(BFile);
  if (BFile == EFile) {
    *this << llvm::format("[%s %d:%d-%d:%d]", clang_getCString(BFileName),
                          BLine, BColumn, ELine, EColumn);
  } else {
    CXString EFileName = clang_getFileName(EFile);
    *this << llvm::format("[%s:%d:%d - ", clang_getCString(BFileName), BLine,
                          BColumn)
          << llvm::format("%s:%d:%d]", clang_getCString(EFileName), ELine,
                          EColumn);
    clang_disposeString(EFileName);
  }
  clang_disposeString(BFileName);
  return *this;
}

Logger &cxindex::Logger::operator<<(CXString Str) {
  *this << clang_getCString(Str);
  return *this;
}

Logger &cxindex::Logger::operator<<(const llvm::format_object_base &Fmt) {
  LogOS << Fmt;
  return *this;
}

static llvm::ManagedStatic<std::mutex> LoggingMutex;

cxindex::Logger::~Logger() {
  std::lock_guard<std::mutex> L(*LoggingMutex);

  static llvm::TimeRecord sBeginTR = llvm::TimeRecord::getCurrentTime();

  raw_ostream &OS = llvm::errs();
  OS << "[libclang:" << Name << ':';

#ifdef USE_DARWIN_THREADS
  // TODO: Portability.
  mach_port_t tid = pthread_mach_thread_np(pthread_self());
  OS << tid << ':';
#endif

  llvm::TimeRecord TR = llvm::TimeRecord::getCurrentTime();
  OS << llvm::format("%7.4f] ", TR.getWallTime() - sBeginTR.getWallTime());
  OS << Msg << '\n';

  if (Trace) {
    llvm::sys::PrintStackTrace(OS);
    OS << "--------------------------------------------------\n";
  }
}

#ifdef CLANG_TOOL_EXTRA_BUILD
// This anchor is used to force the linker to link the clang-tidy plugin.
extern volatile int ClangTidyPluginAnchorSource;
static int LLVM_ATTRIBUTE_UNUSED ClangTidyPluginAnchorDestination =
    ClangTidyPluginAnchorSource;

// This anchor is used to force the linker to link the clang-include-fixer
// plugin.
extern volatile int ClangIncludeFixerPluginAnchorSource;
static int LLVM_ATTRIBUTE_UNUSED ClangIncludeFixerPluginAnchorDestination =
    ClangIncludeFixerPluginAnchorSource;
#endif
