//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
//
// 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 defines routines for manipulating CXCursors. It should be the
// only file that has internal knowledge of the encoding of the data in
// CXCursor.
//
//===----------------------------------------------------------------------===//

#include "CXCursor.h"
#include "CXString.h"
#include "CXTranslationUnit.h"
#include "CXType.h"
#include "clang-c/Index.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/ExprObjC.h"
#include "clang/Frontend/ASTUnit.h"
#include "llvm/Support/ErrorHandling.h"

using namespace clang;
using namespace cxcursor;

CXCursor cxcursor::MakeCXCursorInvalid(CXCursorKind K, CXTranslationUnit TU) {
  assert(K >= CXCursor_FirstInvalid && K <= CXCursor_LastInvalid);
  CXCursor C = {K, 0, {nullptr, nullptr, TU}};
  return C;
}

static CXCursorKind GetCursorKind(const Attr *A) {
  assert(A && "Invalid arguments!");
  switch (A->getKind()) {
  default:
    break;
  case attr::IBAction:
    return CXCursor_IBActionAttr;
  case attr::IBOutlet:
    return CXCursor_IBOutletAttr;
  case attr::IBOutletCollection:
    return CXCursor_IBOutletCollectionAttr;
  case attr::Final:
    return CXCursor_CXXFinalAttr;
  case attr::Override:
    return CXCursor_CXXOverrideAttr;
  case attr::Annotate:
    return CXCursor_AnnotateAttr;
  case attr::AsmLabel:
    return CXCursor_AsmLabelAttr;
  case attr::Packed:
    return CXCursor_PackedAttr;
  case attr::Pure:
    return CXCursor_PureAttr;
  case attr::Const:
    return CXCursor_ConstAttr;
  case attr::NoDuplicate:
    return CXCursor_NoDuplicateAttr;
  case attr::CUDAConstant:
    return CXCursor_CUDAConstantAttr;
  case attr::CUDADevice:
    return CXCursor_CUDADeviceAttr;
  case attr::CUDAGlobal:
    return CXCursor_CUDAGlobalAttr;
  case attr::CUDAHost:
    return CXCursor_CUDAHostAttr;
  case attr::CUDAShared:
    return CXCursor_CUDASharedAttr;
  case attr::Visibility:
    return CXCursor_VisibilityAttr;
  case attr::DLLExport:
    return CXCursor_DLLExport;
  case attr::DLLImport:
    return CXCursor_DLLImport;
  case attr::NSReturnsRetained:
    return CXCursor_NSReturnsRetained;
  case attr::NSReturnsNotRetained:
    return CXCursor_NSReturnsNotRetained;
  case attr::NSReturnsAutoreleased:
    return CXCursor_NSReturnsAutoreleased;
  case attr::NSConsumesSelf:
    return CXCursor_NSConsumesSelf;
  case attr::NSConsumed:
    return CXCursor_NSConsumed;
  case attr::ObjCException:
    return CXCursor_ObjCException;
  case attr::ObjCNSObject:
    return CXCursor_ObjCNSObject;
  case attr::ObjCIndependentClass:
    return CXCursor_ObjCIndependentClass;
  case attr::ObjCPreciseLifetime:
    return CXCursor_ObjCPreciseLifetime;
  case attr::ObjCReturnsInnerPointer:
    return CXCursor_ObjCReturnsInnerPointer;
  case attr::ObjCRequiresSuper:
    return CXCursor_ObjCRequiresSuper;
  case attr::ObjCRootClass:
    return CXCursor_ObjCRootClass;
  case attr::ObjCSubclassingRestricted:
    return CXCursor_ObjCSubclassingRestricted;
  case attr::ObjCExplicitProtocolImpl:
    return CXCursor_ObjCExplicitProtocolImpl;
  case attr::ObjCDesignatedInitializer:
    return CXCursor_ObjCDesignatedInitializer;
  case attr::ObjCRuntimeVisible:
    return CXCursor_ObjCRuntimeVisible;
  case attr::ObjCBoxable:
    return CXCursor_ObjCBoxable;
  case attr::FlagEnum:
    return CXCursor_FlagEnum;
  case attr::Convergent:
    return CXCursor_ConvergentAttr;
  case attr::WarnUnused:
    return CXCursor_WarnUnusedAttr;
  case attr::WarnUnusedResult:
    return CXCursor_WarnUnusedResultAttr;
  case attr::Aligned:
    return CXCursor_AlignedAttr;
  }

  return CXCursor_UnexposedAttr;
}

CXCursor cxcursor::MakeCXCursor(const Attr *A, const Decl *Parent,
                                CXTranslationUnit TU) {
  assert(A && Parent && TU && "Invalid arguments!");
  CXCursor C = {GetCursorKind(A), 0, {Parent, A, TU}};
  return C;
}

CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
                                SourceRange RegionOfInterest,
                                bool FirstInDeclGroup) {
  assert(D && TU && "Invalid arguments!");

  CXCursorKind K = getCursorKindForDecl(D);

  if (K == CXCursor_ObjCClassMethodDecl ||
      K == CXCursor_ObjCInstanceMethodDecl) {
    int SelectorIdIndex = -1;
    // Check if cursor points to a selector id.
    if (RegionOfInterest.isValid() &&
        RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
      SmallVector<SourceLocation, 16> SelLocs;
      cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
      SmallVectorImpl<SourceLocation>::iterator I =
          llvm::find(SelLocs, RegionOfInterest.getBegin());
      if (I != SelLocs.end())
        SelectorIdIndex = I - SelLocs.begin();
    }
    CXCursor C = {K,
                  SelectorIdIndex,
                  {D, (void *)(intptr_t)(FirstInDeclGroup ? 1 : 0), TU}};
    return C;
  }

  CXCursor C = {K, 0, {D, (void *)(intptr_t)(FirstInDeclGroup ? 1 : 0), TU}};
  return C;
}

CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
                                CXTranslationUnit TU,
                                SourceRange RegionOfInterest) {
  assert(S && TU && "Invalid arguments!");
  CXCursorKind K = CXCursor_NotImplemented;

  switch (S->getStmtClass()) {
  case Stmt::NoStmtClass:
    break;

  case Stmt::CaseStmtClass:
    K = CXCursor_CaseStmt;
    break;

  case Stmt::DefaultStmtClass:
    K = CXCursor_DefaultStmt;
    break;

  case Stmt::IfStmtClass:
    K = CXCursor_IfStmt;
    break;

  case Stmt::SwitchStmtClass:
    K = CXCursor_SwitchStmt;
    break;

  case Stmt::WhileStmtClass:
    K = CXCursor_WhileStmt;
    break;

  case Stmt::DoStmtClass:
    K = CXCursor_DoStmt;
    break;

  case Stmt::ForStmtClass:
    K = CXCursor_ForStmt;
    break;

  case Stmt::GotoStmtClass:
    K = CXCursor_GotoStmt;
    break;

  case Stmt::IndirectGotoStmtClass:
    K = CXCursor_IndirectGotoStmt;
    break;

  case Stmt::ContinueStmtClass:
    K = CXCursor_ContinueStmt;
    break;

  case Stmt::BreakStmtClass:
    K = CXCursor_BreakStmt;
    break;

  case Stmt::ReturnStmtClass:
    K = CXCursor_ReturnStmt;
    break;

  case Stmt::GCCAsmStmtClass:
    K = CXCursor_GCCAsmStmt;
    break;

  case Stmt::MSAsmStmtClass:
    K = CXCursor_MSAsmStmt;
    break;

  case Stmt::ObjCAtTryStmtClass:
    K = CXCursor_ObjCAtTryStmt;
    break;

  case Stmt::ObjCAtCatchStmtClass:
    K = CXCursor_ObjCAtCatchStmt;
    break;

  case Stmt::ObjCAtFinallyStmtClass:
    K = CXCursor_ObjCAtFinallyStmt;
    break;

  case Stmt::ObjCAtThrowStmtClass:
    K = CXCursor_ObjCAtThrowStmt;
    break;

  case Stmt::ObjCAtSynchronizedStmtClass:
    K = CXCursor_ObjCAtSynchronizedStmt;
    break;

  case Stmt::ObjCAutoreleasePoolStmtClass:
    K = CXCursor_ObjCAutoreleasePoolStmt;
    break;

  case Stmt::ObjCForCollectionStmtClass:
    K = CXCursor_ObjCForCollectionStmt;
    break;

  case Stmt::CXXCatchStmtClass:
    K = CXCursor_CXXCatchStmt;
    break;

  case Stmt::CXXTryStmtClass:
    K = CXCursor_CXXTryStmt;
    break;

  case Stmt::CXXForRangeStmtClass:
    K = CXCursor_CXXForRangeStmt;
    break;

  case Stmt::SEHTryStmtClass:
    K = CXCursor_SEHTryStmt;
    break;

  case Stmt::SEHExceptStmtClass:
    K = CXCursor_SEHExceptStmt;
    break;

  case Stmt::SEHFinallyStmtClass:
    K = CXCursor_SEHFinallyStmt;
    break;

  case Stmt::SEHLeaveStmtClass:
    K = CXCursor_SEHLeaveStmt;
    break;

  case Stmt::CoroutineBodyStmtClass:
  case Stmt::CoreturnStmtClass:
    K = CXCursor_UnexposedStmt;
    break;

  case Stmt::ArrayTypeTraitExprClass:
  case Stmt::AsTypeExprClass:
  case Stmt::AtomicExprClass:
  case Stmt::BinaryConditionalOperatorClass:
  case Stmt::TypeTraitExprClass:
  case Stmt::CoawaitExprClass:
  case Stmt::ConceptSpecializationExprClass:
  case Stmt::RequiresExprClass:
  case Stmt::DependentCoawaitExprClass:
  case Stmt::CoyieldExprClass:
  case Stmt::CXXBindTemporaryExprClass:
  case Stmt::CXXDefaultArgExprClass:
  case Stmt::CXXDefaultInitExprClass:
  case Stmt::CXXFoldExprClass:
  case Stmt::CXXRewrittenBinaryOperatorClass:
  case Stmt::CXXStdInitializerListExprClass:
  case Stmt::CXXScalarValueInitExprClass:
  case Stmt::CXXUuidofExprClass:
  case Stmt::ChooseExprClass:
  case Stmt::DesignatedInitExprClass:
  case Stmt::DesignatedInitUpdateExprClass:
  case Stmt::ArrayInitLoopExprClass:
  case Stmt::ArrayInitIndexExprClass:
  case Stmt::ExprWithCleanupsClass:
  case Stmt::ExpressionTraitExprClass:
  case Stmt::ExtVectorElementExprClass:
  case Stmt::ImplicitCastExprClass:
  case Stmt::ImplicitValueInitExprClass:
  case Stmt::NoInitExprClass:
  case Stmt::MaterializeTemporaryExprClass:
  case Stmt::ObjCIndirectCopyRestoreExprClass:
  case Stmt::OffsetOfExprClass:
  case Stmt::ParenListExprClass:
  case Stmt::PredefinedExprClass:
  case Stmt::ShuffleVectorExprClass:
  case Stmt::SourceLocExprClass:
  case Stmt::ConvertVectorExprClass:
  case Stmt::VAArgExprClass:
  case Stmt::ObjCArrayLiteralClass:
  case Stmt::ObjCDictionaryLiteralClass:
  case Stmt::ObjCBoxedExprClass:
  case Stmt::ObjCSubscriptRefExprClass:
  case Stmt::RecoveryExprClass:
    K = CXCursor_UnexposedExpr;
    break;

  case Stmt::OpaqueValueExprClass:
    if (Expr *Src = cast<OpaqueValueExpr>(S)->getSourceExpr())
      return MakeCXCursor(Src, Parent, TU, RegionOfInterest);
    K = CXCursor_UnexposedExpr;
    break;

  case Stmt::PseudoObjectExprClass:
    return MakeCXCursor(cast<PseudoObjectExpr>(S)->getSyntacticForm(), Parent,
                        TU, RegionOfInterest);

  case Stmt::CompoundStmtClass:
    K = CXCursor_CompoundStmt;
    break;

  case Stmt::NullStmtClass:
    K = CXCursor_NullStmt;
    break;

  case Stmt::LabelStmtClass:
    K = CXCursor_LabelStmt;
    break;

  case Stmt::AttributedStmtClass:
    K = CXCursor_UnexposedStmt;
    break;

  case Stmt::DeclStmtClass:
    K = CXCursor_DeclStmt;
    break;

  case Stmt::CapturedStmtClass:
    K = CXCursor_UnexposedStmt;
    break;

  case Stmt::IntegerLiteralClass:
    K = CXCursor_IntegerLiteral;
    break;

  case Stmt::FixedPointLiteralClass:
    K = CXCursor_FixedPointLiteral;
    break;

  case Stmt::FloatingLiteralClass:
    K = CXCursor_FloatingLiteral;
    break;

  case Stmt::ImaginaryLiteralClass:
    K = CXCursor_ImaginaryLiteral;
    break;

  case Stmt::StringLiteralClass:
    K = CXCursor_StringLiteral;
    break;

  case Stmt::CharacterLiteralClass:
    K = CXCursor_CharacterLiteral;
    break;

  case Stmt::ConstantExprClass:
    return MakeCXCursor(cast<ConstantExpr>(S)->getSubExpr(), Parent, TU,
                        RegionOfInterest);

  case Stmt::ParenExprClass:
    K = CXCursor_ParenExpr;
    break;

  case Stmt::UnaryOperatorClass:
    K = CXCursor_UnaryOperator;
    break;

  case Stmt::UnaryExprOrTypeTraitExprClass:
  case Stmt::CXXNoexceptExprClass:
    K = CXCursor_UnaryExpr;
    break;

  case Stmt::MSPropertySubscriptExprClass:
  case Stmt::ArraySubscriptExprClass:
    K = CXCursor_ArraySubscriptExpr;
    break;

  case Stmt::MatrixSubscriptExprClass:
    // TODO: add support for MatrixSubscriptExpr.
    K = CXCursor_UnexposedExpr;
    break;

  case Stmt::OMPArraySectionExprClass:
    K = CXCursor_OMPArraySectionExpr;
    break;

  case Stmt::OMPArrayShapingExprClass:
    K = CXCursor_OMPArrayShapingExpr;
    break;

  case Stmt::OMPIteratorExprClass:
    K = CXCursor_OMPIteratorExpr;
    break;

  case Stmt::BinaryOperatorClass:
    K = CXCursor_BinaryOperator;
    break;

  case Stmt::CompoundAssignOperatorClass:
    K = CXCursor_CompoundAssignOperator;
    break;

  case Stmt::ConditionalOperatorClass:
    K = CXCursor_ConditionalOperator;
    break;

  case Stmt::CStyleCastExprClass:
    K = CXCursor_CStyleCastExpr;
    break;

  case Stmt::CompoundLiteralExprClass:
    K = CXCursor_CompoundLiteralExpr;
    break;

  case Stmt::InitListExprClass:
    K = CXCursor_InitListExpr;
    break;

  case Stmt::AddrLabelExprClass:
    K = CXCursor_AddrLabelExpr;
    break;

  case Stmt::StmtExprClass:
    K = CXCursor_StmtExpr;
    break;

  case Stmt::GenericSelectionExprClass:
    K = CXCursor_GenericSelectionExpr;
    break;

  case Stmt::GNUNullExprClass:
    K = CXCursor_GNUNullExpr;
    break;

  case Stmt::CXXStaticCastExprClass:
    K = CXCursor_CXXStaticCastExpr;
    break;

  case Stmt::CXXDynamicCastExprClass:
    K = CXCursor_CXXDynamicCastExpr;
    break;

  case Stmt::CXXReinterpretCastExprClass:
    K = CXCursor_CXXReinterpretCastExpr;
    break;

  case Stmt::CXXConstCastExprClass:
    K = CXCursor_CXXConstCastExpr;
    break;

  case Stmt::CXXFunctionalCastExprClass:
    K = CXCursor_CXXFunctionalCastExpr;
    break;

  case Stmt::CXXAddrspaceCastExprClass:
    K = CXCursor_CXXAddrspaceCastExpr;
    break;

  case Stmt::CXXTypeidExprClass:
    K = CXCursor_CXXTypeidExpr;
    break;

  case Stmt::CXXBoolLiteralExprClass:
    K = CXCursor_CXXBoolLiteralExpr;
    break;

  case Stmt::CXXNullPtrLiteralExprClass:
    K = CXCursor_CXXNullPtrLiteralExpr;
    break;

  case Stmt::CXXThisExprClass:
    K = CXCursor_CXXThisExpr;
    break;

  case Stmt::CXXThrowExprClass:
    K = CXCursor_CXXThrowExpr;
    break;

  case Stmt::CXXNewExprClass:
    K = CXCursor_CXXNewExpr;
    break;

  case Stmt::CXXDeleteExprClass:
    K = CXCursor_CXXDeleteExpr;
    break;

  case Stmt::ObjCStringLiteralClass:
    K = CXCursor_ObjCStringLiteral;
    break;

  case Stmt::ObjCEncodeExprClass:
    K = CXCursor_ObjCEncodeExpr;
    break;

  case Stmt::ObjCSelectorExprClass:
    K = CXCursor_ObjCSelectorExpr;
    break;

  case Stmt::ObjCProtocolExprClass:
    K = CXCursor_ObjCProtocolExpr;
    break;

  case Stmt::ObjCBoolLiteralExprClass:
    K = CXCursor_ObjCBoolLiteralExpr;
    break;

  case Stmt::ObjCAvailabilityCheckExprClass:
    K = CXCursor_ObjCAvailabilityCheckExpr;
    break;

  case Stmt::ObjCBridgedCastExprClass:
    K = CXCursor_ObjCBridgedCastExpr;
    break;

  case Stmt::BlockExprClass:
    K = CXCursor_BlockExpr;
    break;

  case Stmt::PackExpansionExprClass:
    K = CXCursor_PackExpansionExpr;
    break;

  case Stmt::SizeOfPackExprClass:
    K = CXCursor_SizeOfPackExpr;
    break;

  case Stmt::DeclRefExprClass:
    if (const ImplicitParamDecl *IPD = dyn_cast_or_null<ImplicitParamDecl>(
            cast<DeclRefExpr>(S)->getDecl())) {
      if (const ObjCMethodDecl *MD =
              dyn_cast<ObjCMethodDecl>(IPD->getDeclContext())) {
        if (MD->getSelfDecl() == IPD) {
          K = CXCursor_ObjCSelfExpr;
          break;
        }
      }
    }

    K = CXCursor_DeclRefExpr;
    break;

  case Stmt::DependentScopeDeclRefExprClass:
  case Stmt::SubstNonTypeTemplateParmExprClass:
  case Stmt::SubstNonTypeTemplateParmPackExprClass:
  case Stmt::FunctionParmPackExprClass:
  case Stmt::UnresolvedLookupExprClass:
  case Stmt::TypoExprClass: // A typo could actually be a DeclRef or a MemberRef
    K = CXCursor_DeclRefExpr;
    break;

  case Stmt::CXXDependentScopeMemberExprClass:
  case Stmt::CXXPseudoDestructorExprClass:
  case Stmt::MemberExprClass:
  case Stmt::MSPropertyRefExprClass:
  case Stmt::ObjCIsaExprClass:
  case Stmt::ObjCIvarRefExprClass:
  case Stmt::ObjCPropertyRefExprClass:
  case Stmt::UnresolvedMemberExprClass:
    K = CXCursor_MemberRefExpr;
    break;

  case Stmt::CallExprClass:
  case Stmt::CXXOperatorCallExprClass:
  case Stmt::CXXMemberCallExprClass:
  case Stmt::CUDAKernelCallExprClass:
  case Stmt::CXXConstructExprClass:
  case Stmt::CXXInheritedCtorInitExprClass:
  case Stmt::CXXTemporaryObjectExprClass:
  case Stmt::CXXUnresolvedConstructExprClass:
  case Stmt::UserDefinedLiteralClass:
    K = CXCursor_CallExpr;
    break;

  case Stmt::LambdaExprClass:
    K = CXCursor_LambdaExpr;
    break;

  case Stmt::ObjCMessageExprClass: {
    K = CXCursor_ObjCMessageExpr;
    int SelectorIdIndex = -1;
    // Check if cursor points to a selector id.
    if (RegionOfInterest.isValid() &&
        RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
      SmallVector<SourceLocation, 16> SelLocs;
      cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
      SmallVectorImpl<SourceLocation>::iterator I =
          llvm::find(SelLocs, RegionOfInterest.getBegin());
      if (I != SelLocs.end())
        SelectorIdIndex = I - SelLocs.begin();
    }
    CXCursor C = {K, 0, {Parent, S, TU}};
    return getSelectorIdentifierCursor(SelectorIdIndex, C);
  }

  case Stmt::MSDependentExistsStmtClass:
    K = CXCursor_UnexposedStmt;
    break;
  case Stmt::OMPParallelDirectiveClass:
    K = CXCursor_OMPParallelDirective;
    break;
  case Stmt::OMPSimdDirectiveClass:
    K = CXCursor_OMPSimdDirective;
    break;
  case Stmt::OMPForDirectiveClass:
    K = CXCursor_OMPForDirective;
    break;
  case Stmt::OMPForSimdDirectiveClass:
    K = CXCursor_OMPForSimdDirective;
    break;
  case Stmt::OMPSectionsDirectiveClass:
    K = CXCursor_OMPSectionsDirective;
    break;
  case Stmt::OMPSectionDirectiveClass:
    K = CXCursor_OMPSectionDirective;
    break;
  case Stmt::OMPSingleDirectiveClass:
    K = CXCursor_OMPSingleDirective;
    break;
  case Stmt::OMPMasterDirectiveClass:
    K = CXCursor_OMPMasterDirective;
    break;
  case Stmt::OMPCriticalDirectiveClass:
    K = CXCursor_OMPCriticalDirective;
    break;
  case Stmt::OMPParallelForDirectiveClass:
    K = CXCursor_OMPParallelForDirective;
    break;
  case Stmt::OMPParallelForSimdDirectiveClass:
    K = CXCursor_OMPParallelForSimdDirective;
    break;
  case Stmt::OMPParallelMasterDirectiveClass:
    K = CXCursor_OMPParallelMasterDirective;
    break;
  case Stmt::OMPParallelSectionsDirectiveClass:
    K = CXCursor_OMPParallelSectionsDirective;
    break;
  case Stmt::OMPTaskDirectiveClass:
    K = CXCursor_OMPTaskDirective;
    break;
  case Stmt::OMPTaskyieldDirectiveClass:
    K = CXCursor_OMPTaskyieldDirective;
    break;
  case Stmt::OMPBarrierDirectiveClass:
    K = CXCursor_OMPBarrierDirective;
    break;
  case Stmt::OMPTaskwaitDirectiveClass:
    K = CXCursor_OMPTaskwaitDirective;
    break;
  case Stmt::OMPTaskgroupDirectiveClass:
    K = CXCursor_OMPTaskgroupDirective;
    break;
  case Stmt::OMPFlushDirectiveClass:
    K = CXCursor_OMPFlushDirective;
    break;
  case Stmt::OMPDepobjDirectiveClass:
    K = CXCursor_OMPDepobjDirective;
    break;
  case Stmt::OMPScanDirectiveClass:
    K = CXCursor_OMPScanDirective;
    break;
  case Stmt::OMPOrderedDirectiveClass:
    K = CXCursor_OMPOrderedDirective;
    break;
  case Stmt::OMPAtomicDirectiveClass:
    K = CXCursor_OMPAtomicDirective;
    break;
  case Stmt::OMPTargetDirectiveClass:
    K = CXCursor_OMPTargetDirective;
    break;
  case Stmt::OMPTargetDataDirectiveClass:
    K = CXCursor_OMPTargetDataDirective;
    break;
  case Stmt::OMPTargetEnterDataDirectiveClass:
    K = CXCursor_OMPTargetEnterDataDirective;
    break;
  case Stmt::OMPTargetExitDataDirectiveClass:
    K = CXCursor_OMPTargetExitDataDirective;
    break;
  case Stmt::OMPTargetParallelDirectiveClass:
    K = CXCursor_OMPTargetParallelDirective;
    break;
  case Stmt::OMPTargetParallelForDirectiveClass:
    K = CXCursor_OMPTargetParallelForDirective;
    break;
  case Stmt::OMPTargetUpdateDirectiveClass:
    K = CXCursor_OMPTargetUpdateDirective;
    break;
  case Stmt::OMPTeamsDirectiveClass:
    K = CXCursor_OMPTeamsDirective;
    break;
  case Stmt::OMPCancellationPointDirectiveClass:
    K = CXCursor_OMPCancellationPointDirective;
    break;
  case Stmt::OMPCancelDirectiveClass:
    K = CXCursor_OMPCancelDirective;
    break;
  case Stmt::OMPTaskLoopDirectiveClass:
    K = CXCursor_OMPTaskLoopDirective;
    break;
  case Stmt::OMPTaskLoopSimdDirectiveClass:
    K = CXCursor_OMPTaskLoopSimdDirective;
    break;
  case Stmt::OMPMasterTaskLoopDirectiveClass:
    K = CXCursor_OMPMasterTaskLoopDirective;
    break;
  case Stmt::OMPMasterTaskLoopSimdDirectiveClass:
    K = CXCursor_OMPMasterTaskLoopSimdDirective;
    break;
  case Stmt::OMPParallelMasterTaskLoopDirectiveClass:
    K = CXCursor_OMPParallelMasterTaskLoopDirective;
    break;
  case Stmt::OMPParallelMasterTaskLoopSimdDirectiveClass:
    K = CXCursor_OMPParallelMasterTaskLoopSimdDirective;
    break;
  case Stmt::OMPDistributeDirectiveClass:
    K = CXCursor_OMPDistributeDirective;
    break;
  case Stmt::OMPDistributeParallelForDirectiveClass:
    K = CXCursor_OMPDistributeParallelForDirective;
    break;
  case Stmt::OMPDistributeParallelForSimdDirectiveClass:
    K = CXCursor_OMPDistributeParallelForSimdDirective;
    break;
  case Stmt::OMPDistributeSimdDirectiveClass:
    K = CXCursor_OMPDistributeSimdDirective;
    break;
  case Stmt::OMPTargetParallelForSimdDirectiveClass:
    K = CXCursor_OMPTargetParallelForSimdDirective;
    break;
  case Stmt::OMPTargetSimdDirectiveClass:
    K = CXCursor_OMPTargetSimdDirective;
    break;
  case Stmt::OMPTeamsDistributeDirectiveClass:
    K = CXCursor_OMPTeamsDistributeDirective;
    break;
  case Stmt::OMPTeamsDistributeSimdDirectiveClass:
    K = CXCursor_OMPTeamsDistributeSimdDirective;
    break;
  case Stmt::OMPTeamsDistributeParallelForSimdDirectiveClass:
    K = CXCursor_OMPTeamsDistributeParallelForSimdDirective;
    break;
  case Stmt::OMPTeamsDistributeParallelForDirectiveClass:
    K = CXCursor_OMPTeamsDistributeParallelForDirective;
    break;
  case Stmt::OMPTargetTeamsDirectiveClass:
    K = CXCursor_OMPTargetTeamsDirective;
    break;
  case Stmt::OMPTargetTeamsDistributeDirectiveClass:
    K = CXCursor_OMPTargetTeamsDistributeDirective;
    break;
  case Stmt::OMPTargetTeamsDistributeParallelForDirectiveClass:
    K = CXCursor_OMPTargetTeamsDistributeParallelForDirective;
    break;
  case Stmt::OMPTargetTeamsDistributeParallelForSimdDirectiveClass:
    K = CXCursor_OMPTargetTeamsDistributeParallelForSimdDirective;
    break;
  case Stmt::OMPTargetTeamsDistributeSimdDirectiveClass:
    K = CXCursor_OMPTargetTeamsDistributeSimdDirective;
    break;
  case Stmt::BuiltinBitCastExprClass:
    K = CXCursor_BuiltinBitCastExpr;
  }

  CXCursor C = {K, 0, {Parent, S, TU}};
  return C;
}

CXCursor cxcursor::MakeCursorObjCSuperClassRef(ObjCInterfaceDecl *Super,
                                               SourceLocation Loc,
                                               CXTranslationUnit TU) {
  assert(Super && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_ObjCSuperClassRef, 0, {Super, RawLoc, TU}};
  return C;
}

std::pair<const ObjCInterfaceDecl *, SourceLocation>
cxcursor::getCursorObjCSuperClassRef(CXCursor C) {
  assert(C.kind == CXCursor_ObjCSuperClassRef);
  return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorObjCProtocolRef(const ObjCProtocolDecl *Proto,
                                             SourceLocation Loc,
                                             CXTranslationUnit TU) {
  assert(Proto && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_ObjCProtocolRef, 0, {Proto, RawLoc, TU}};
  return C;
}

std::pair<const ObjCProtocolDecl *, SourceLocation>
cxcursor::getCursorObjCProtocolRef(CXCursor C) {
  assert(C.kind == CXCursor_ObjCProtocolRef);
  return std::make_pair(static_cast<const ObjCProtocolDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorObjCClassRef(const ObjCInterfaceDecl *Class,
                                          SourceLocation Loc,
                                          CXTranslationUnit TU) {
  // 'Class' can be null for invalid code.
  if (!Class)
    return MakeCXCursorInvalid(CXCursor_InvalidCode);
  assert(TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_ObjCClassRef, 0, {Class, RawLoc, TU}};
  return C;
}

std::pair<const ObjCInterfaceDecl *, SourceLocation>
cxcursor::getCursorObjCClassRef(CXCursor C) {
  assert(C.kind == CXCursor_ObjCClassRef);
  return std::make_pair(static_cast<const ObjCInterfaceDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorTypeRef(const TypeDecl *Type, SourceLocation Loc,
                                     CXTranslationUnit TU) {
  assert(Type && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_TypeRef, 0, {Type, RawLoc, TU}};
  return C;
}

std::pair<const TypeDecl *, SourceLocation>
cxcursor::getCursorTypeRef(CXCursor C) {
  assert(C.kind == CXCursor_TypeRef);
  return std::make_pair(static_cast<const TypeDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorTemplateRef(const TemplateDecl *Template,
                                         SourceLocation Loc,
                                         CXTranslationUnit TU) {
  assert(Template && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_TemplateRef, 0, {Template, RawLoc, TU}};
  return C;
}

std::pair<const TemplateDecl *, SourceLocation>
cxcursor::getCursorTemplateRef(CXCursor C) {
  assert(C.kind == CXCursor_TemplateRef);
  return std::make_pair(static_cast<const TemplateDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorNamespaceRef(const NamedDecl *NS,
                                          SourceLocation Loc,
                                          CXTranslationUnit TU) {

  assert(NS && (isa<NamespaceDecl>(NS) || isa<NamespaceAliasDecl>(NS)) && TU &&
         "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_NamespaceRef, 0, {NS, RawLoc, TU}};
  return C;
}

std::pair<const NamedDecl *, SourceLocation>
cxcursor::getCursorNamespaceRef(CXCursor C) {
  assert(C.kind == CXCursor_NamespaceRef);
  return std::make_pair(static_cast<const NamedDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorVariableRef(const VarDecl *Var, SourceLocation Loc,
                                         CXTranslationUnit TU) {

  assert(Var && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_VariableRef, 0, {Var, RawLoc, TU}};
  return C;
}

std::pair<const VarDecl *, SourceLocation>
cxcursor::getCursorVariableRef(CXCursor C) {
  assert(C.kind == CXCursor_VariableRef);
  return std::make_pair(static_cast<const VarDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorMemberRef(const FieldDecl *Field,
                                       SourceLocation Loc,
                                       CXTranslationUnit TU) {

  assert(Field && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_MemberRef, 0, {Field, RawLoc, TU}};
  return C;
}

std::pair<const FieldDecl *, SourceLocation>
cxcursor::getCursorMemberRef(CXCursor C) {
  assert(C.kind == CXCursor_MemberRef);
  return std::make_pair(static_cast<const FieldDecl *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorCXXBaseSpecifier(const CXXBaseSpecifier *B,
                                              CXTranslationUnit TU) {
  CXCursor C = {CXCursor_CXXBaseSpecifier, 0, {B, nullptr, TU}};
  return C;
}

const CXXBaseSpecifier *cxcursor::getCursorCXXBaseSpecifier(CXCursor C) {
  assert(C.kind == CXCursor_CXXBaseSpecifier);
  return static_cast<const CXXBaseSpecifier *>(C.data[0]);
}

CXCursor cxcursor::MakePreprocessingDirectiveCursor(SourceRange Range,
                                                    CXTranslationUnit TU) {
  CXCursor C = {
      CXCursor_PreprocessingDirective,
      0,
      {Range.getBegin().getPtrEncoding(), Range.getEnd().getPtrEncoding(), TU}};
  return C;
}

SourceRange cxcursor::getCursorPreprocessingDirective(CXCursor C) {
  assert(C.kind == CXCursor_PreprocessingDirective);
  SourceRange Range(SourceLocation::getFromPtrEncoding(C.data[0]),
                    SourceLocation::getFromPtrEncoding(C.data[1]));
  ASTUnit *TU = getCursorASTUnit(C);
  return TU->mapRangeFromPreamble(Range);
}

CXCursor cxcursor::MakeMacroDefinitionCursor(const MacroDefinitionRecord *MI,
                                             CXTranslationUnit TU) {
  CXCursor C = {CXCursor_MacroDefinition, 0, {MI, nullptr, TU}};
  return C;
}

const MacroDefinitionRecord *cxcursor::getCursorMacroDefinition(CXCursor C) {
  assert(C.kind == CXCursor_MacroDefinition);
  return static_cast<const MacroDefinitionRecord *>(C.data[0]);
}

CXCursor cxcursor::MakeMacroExpansionCursor(MacroExpansion *MI,
                                            CXTranslationUnit TU) {
  CXCursor C = {CXCursor_MacroExpansion, 0, {MI, nullptr, TU}};
  return C;
}

CXCursor cxcursor::MakeMacroExpansionCursor(MacroDefinitionRecord *MI,
                                            SourceLocation Loc,
                                            CXTranslationUnit TU) {
  assert(Loc.isValid());
  CXCursor C = {CXCursor_MacroExpansion, 0, {MI, Loc.getPtrEncoding(), TU}};
  return C;
}

const IdentifierInfo *cxcursor::MacroExpansionCursor::getName() const {
  if (isPseudo())
    return getAsMacroDefinition()->getName();
  return getAsMacroExpansion()->getName();
}
const MacroDefinitionRecord *
cxcursor::MacroExpansionCursor::getDefinition() const {
  if (isPseudo())
    return getAsMacroDefinition();
  return getAsMacroExpansion()->getDefinition();
}
SourceRange cxcursor::MacroExpansionCursor::getSourceRange() const {
  if (isPseudo())
    return getPseudoLoc();
  return getAsMacroExpansion()->getSourceRange();
}

CXCursor cxcursor::MakeInclusionDirectiveCursor(InclusionDirective *ID,
                                                CXTranslationUnit TU) {
  CXCursor C = {CXCursor_InclusionDirective, 0, {ID, nullptr, TU}};
  return C;
}

const InclusionDirective *cxcursor::getCursorInclusionDirective(CXCursor C) {
  assert(C.kind == CXCursor_InclusionDirective);
  return static_cast<const InclusionDirective *>(C.data[0]);
}

CXCursor cxcursor::MakeCursorLabelRef(LabelStmt *Label, SourceLocation Loc,
                                      CXTranslationUnit TU) {

  assert(Label && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  CXCursor C = {CXCursor_LabelRef, 0, {Label, RawLoc, TU}};
  return C;
}

std::pair<const LabelStmt *, SourceLocation>
cxcursor::getCursorLabelRef(CXCursor C) {
  assert(C.kind == CXCursor_LabelRef);
  return std::make_pair(static_cast<const LabelStmt *>(C.data[0]),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

CXCursor cxcursor::MakeCursorOverloadedDeclRef(const OverloadExpr *E,
                                               CXTranslationUnit TU) {
  assert(E && TU && "Invalid arguments!");
  OverloadedDeclRefStorage Storage(E);
  void *RawLoc = E->getNameLoc().getPtrEncoding();
  CXCursor C = {
      CXCursor_OverloadedDeclRef, 0, {Storage.getOpaqueValue(), RawLoc, TU}};
  return C;
}

CXCursor cxcursor::MakeCursorOverloadedDeclRef(const Decl *D,
                                               SourceLocation Loc,
                                               CXTranslationUnit TU) {
  assert(D && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  OverloadedDeclRefStorage Storage(D);
  CXCursor C = {
      CXCursor_OverloadedDeclRef, 0, {Storage.getOpaqueValue(), RawLoc, TU}};
  return C;
}

CXCursor cxcursor::MakeCursorOverloadedDeclRef(TemplateName Name,
                                               SourceLocation Loc,
                                               CXTranslationUnit TU) {
  assert(Name.getAsOverloadedTemplate() && TU && "Invalid arguments!");
  void *RawLoc = Loc.getPtrEncoding();
  OverloadedDeclRefStorage Storage(Name.getAsOverloadedTemplate());
  CXCursor C = {
      CXCursor_OverloadedDeclRef, 0, {Storage.getOpaqueValue(), RawLoc, TU}};
  return C;
}

std::pair<cxcursor::OverloadedDeclRefStorage, SourceLocation>
cxcursor::getCursorOverloadedDeclRef(CXCursor C) {
  assert(C.kind == CXCursor_OverloadedDeclRef);
  return std::make_pair(OverloadedDeclRefStorage::getFromOpaqueValue(
                            const_cast<void *>(C.data[0])),
                        SourceLocation::getFromPtrEncoding(C.data[1]));
}

const Decl *cxcursor::getCursorDecl(CXCursor Cursor) {
  return static_cast<const Decl *>(Cursor.data[0]);
}

const Expr *cxcursor::getCursorExpr(CXCursor Cursor) {
  return dyn_cast_or_null<Expr>(getCursorStmt(Cursor));
}

const Stmt *cxcursor::getCursorStmt(CXCursor Cursor) {
  if (Cursor.kind == CXCursor_ObjCSuperClassRef ||
      Cursor.kind == CXCursor_ObjCProtocolRef ||
      Cursor.kind == CXCursor_ObjCClassRef)
    return nullptr;

  return static_cast<const Stmt *>(Cursor.data[1]);
}

const Attr *cxcursor::getCursorAttr(CXCursor Cursor) {
  return static_cast<const Attr *>(Cursor.data[1]);
}

ASTContext &cxcursor::getCursorContext(CXCursor Cursor) {
  return getCursorASTUnit(Cursor)->getASTContext();
}

ASTUnit *cxcursor::getCursorASTUnit(CXCursor Cursor) {
  CXTranslationUnit TU = getCursorTU(Cursor);
  if (!TU)
    return nullptr;
  return cxtu::getASTUnit(TU);
}

CXTranslationUnit cxcursor::getCursorTU(CXCursor Cursor) {
  return static_cast<CXTranslationUnit>(const_cast<void *>(Cursor.data[2]));
}

void cxcursor::getOverriddenCursors(CXCursor cursor,
                                    SmallVectorImpl<CXCursor> &overridden) {
  assert(clang_isDeclaration(cursor.kind));
  const NamedDecl *D = dyn_cast_or_null<NamedDecl>(getCursorDecl(cursor));
  if (!D)
    return;

  CXTranslationUnit TU = getCursorTU(cursor);
  SmallVector<const NamedDecl *, 8> OverDecls;
  D->getASTContext().getOverriddenMethods(D, OverDecls);

  for (SmallVectorImpl<const NamedDecl *>::iterator I = OverDecls.begin(),
                                                    E = OverDecls.end();
       I != E; ++I) {
    overridden.push_back(MakeCXCursor(*I, TU));
  }
}

std::pair<int, SourceLocation>
cxcursor::getSelectorIdentifierIndexAndLoc(CXCursor cursor) {
  if (cursor.kind == CXCursor_ObjCMessageExpr) {
    if (cursor.xdata != -1)
      return std::make_pair(cursor.xdata,
                            cast<ObjCMessageExpr>(getCursorExpr(cursor))
                                ->getSelectorLoc(cursor.xdata));
  } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
             cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
    if (cursor.xdata != -1)
      return std::make_pair(cursor.xdata,
                            cast<ObjCMethodDecl>(getCursorDecl(cursor))
                                ->getSelectorLoc(cursor.xdata));
  }

  return std::make_pair(-1, SourceLocation());
}

CXCursor cxcursor::getSelectorIdentifierCursor(int SelIdx, CXCursor cursor) {
  CXCursor newCursor = cursor;

  if (cursor.kind == CXCursor_ObjCMessageExpr) {
    if (SelIdx == -1 ||
        unsigned(SelIdx) >=
            cast<ObjCMessageExpr>(getCursorExpr(cursor))->getNumSelectorLocs())
      newCursor.xdata = -1;
    else
      newCursor.xdata = SelIdx;
  } else if (cursor.kind == CXCursor_ObjCClassMethodDecl ||
             cursor.kind == CXCursor_ObjCInstanceMethodDecl) {
    if (SelIdx == -1 ||
        unsigned(SelIdx) >=
            cast<ObjCMethodDecl>(getCursorDecl(cursor))->getNumSelectorLocs())
      newCursor.xdata = -1;
    else
      newCursor.xdata = SelIdx;
  }

  return newCursor;
}

CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
  if (cursor.kind != CXCursor_CallExpr)
    return cursor;

  if (cursor.xdata == 0)
    return cursor;

  const Expr *E = getCursorExpr(cursor);
  TypeSourceInfo *Type = nullptr;
  if (const CXXUnresolvedConstructExpr *UnCtor =
          dyn_cast<CXXUnresolvedConstructExpr>(E)) {
    Type = UnCtor->getTypeSourceInfo();
  } else if (const CXXTemporaryObjectExpr *Tmp =
                 dyn_cast<CXXTemporaryObjectExpr>(E)) {
    Type = Tmp->getTypeSourceInfo();
  }

  if (!Type)
    return cursor;

  CXTranslationUnit TU = getCursorTU(cursor);
  QualType Ty = Type->getType();
  TypeLoc TL = Type->getTypeLoc();
  SourceLocation Loc = TL.getBeginLoc();

  if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
    Ty = ElabT->getNamedType();
    ElaboratedTypeLoc ElabTL = TL.castAs<ElaboratedTypeLoc>();
    Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
  }

  if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
    return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
  if (const TagType *Tag = Ty->getAs<TagType>())
    return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
  if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
    return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);

  return cursor;
}

bool cxcursor::operator==(CXCursor X, CXCursor Y) {
  return X.kind == Y.kind && X.data[0] == Y.data[0] && X.data[1] == Y.data[1] &&
         X.data[2] == Y.data[2];
}

// FIXME: Remove once we can model DeclGroups and their appropriate ranges
// properly in the ASTs.
bool cxcursor::isFirstInDeclGroup(CXCursor C) {
  assert(clang_isDeclaration(C.kind));
  return ((uintptr_t)(C.data[1])) != 0;
}

//===----------------------------------------------------------------------===//
// libclang CXCursor APIs
//===----------------------------------------------------------------------===//

int clang_Cursor_isNull(CXCursor cursor) {
  return clang_equalCursors(cursor, clang_getNullCursor());
}

CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor cursor) {
  return getCursorTU(cursor);
}

int clang_Cursor_getNumArguments(CXCursor C) {
  if (clang_isDeclaration(C.kind)) {
    const Decl *D = cxcursor::getCursorDecl(C);
    if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D))
      return MD->param_size();
    if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
      return FD->param_size();
  }

  if (clang_isExpression(C.kind)) {
    const Expr *E = cxcursor::getCursorExpr(C);
    if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
      return CE->getNumArgs();
    }
    if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E)) {
      return CE->getNumArgs();
    }
  }

  return -1;
}

CXCursor clang_Cursor_getArgument(CXCursor C, unsigned i) {
  if (clang_isDeclaration(C.kind)) {
    const Decl *D = cxcursor::getCursorDecl(C);
    if (const ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
      if (i < MD->param_size())
        return cxcursor::MakeCXCursor(MD->parameters()[i],
                                      cxcursor::getCursorTU(C));
    } else if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D)) {
      if (i < FD->param_size())
        return cxcursor::MakeCXCursor(FD->parameters()[i],
                                      cxcursor::getCursorTU(C));
    }
  }

  if (clang_isExpression(C.kind)) {
    const Expr *E = cxcursor::getCursorExpr(C);
    if (const CallExpr *CE = dyn_cast<CallExpr>(E)) {
      if (i < CE->getNumArgs()) {
        return cxcursor::MakeCXCursor(CE->getArg(i), getCursorDecl(C),
                                      cxcursor::getCursorTU(C));
      }
    }
    if (const CXXConstructExpr *CE = dyn_cast<CXXConstructExpr>(E)) {
      if (i < CE->getNumArgs()) {
        return cxcursor::MakeCXCursor(CE->getArg(i), getCursorDecl(C),
                                      cxcursor::getCursorTU(C));
      }
    }
  }

  return clang_getNullCursor();
}

int clang_Cursor_getNumTemplateArguments(CXCursor C) {
  if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
    return -1;
  }

  const FunctionDecl *FD =
      llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C));
  if (!FD) {
    return -1;
  }

  const FunctionTemplateSpecializationInfo *SpecInfo =
      FD->getTemplateSpecializationInfo();
  if (!SpecInfo) {
    return -1;
  }

  return SpecInfo->TemplateArguments->size();
}

enum CXGetTemplateArgumentStatus {
  /** The operation completed successfully */
  CXGetTemplateArgumentStatus_Success = 0,

  /** The specified cursor did not represent a FunctionDecl. */
  CXGetTemplateArgumentStatus_CursorNotFunctionDecl = -1,

  /** The specified cursor was not castable to a FunctionDecl. */
  CXGetTemplateArgumentStatus_BadFunctionDeclCast = -2,

  /** A NULL FunctionTemplateSpecializationInfo was retrieved. */
  CXGetTemplateArgumentStatus_NullTemplSpecInfo = -3,

  /** An invalid (OOB) argument index was specified */
  CXGetTemplateArgumentStatus_InvalidIndex = -4
};

static int clang_Cursor_getTemplateArgument(CXCursor C, unsigned I,
                                            TemplateArgument *TA) {
  if (clang_getCursorKind(C) != CXCursor_FunctionDecl) {
    return CXGetTemplateArgumentStatus_CursorNotFunctionDecl;
  }

  const FunctionDecl *FD =
      llvm::dyn_cast_or_null<clang::FunctionDecl>(getCursorDecl(C));
  if (!FD) {
    return CXGetTemplateArgumentStatus_BadFunctionDeclCast;
  }

  const FunctionTemplateSpecializationInfo *SpecInfo =
      FD->getTemplateSpecializationInfo();
  if (!SpecInfo) {
    return CXGetTemplateArgumentStatus_NullTemplSpecInfo;
  }

  if (I >= SpecInfo->TemplateArguments->size()) {
    return CXGetTemplateArgumentStatus_InvalidIndex;
  }

  *TA = SpecInfo->TemplateArguments->get(I);
  return 0;
}

enum CXTemplateArgumentKind clang_Cursor_getTemplateArgumentKind(CXCursor C,
                                                                 unsigned I) {
  TemplateArgument TA;
  if (clang_Cursor_getTemplateArgument(C, I, &TA)) {
    return CXTemplateArgumentKind_Invalid;
  }

  switch (TA.getKind()) {
  case TemplateArgument::Null:
    return CXTemplateArgumentKind_Null;
  case TemplateArgument::Type:
    return CXTemplateArgumentKind_Type;
  case TemplateArgument::Declaration:
    return CXTemplateArgumentKind_Declaration;
  case TemplateArgument::NullPtr:
    return CXTemplateArgumentKind_NullPtr;
  case TemplateArgument::Integral:
    return CXTemplateArgumentKind_Integral;
  case TemplateArgument::Template:
    return CXTemplateArgumentKind_Template;
  case TemplateArgument::TemplateExpansion:
    return CXTemplateArgumentKind_TemplateExpansion;
  case TemplateArgument::Expression:
    return CXTemplateArgumentKind_Expression;
  case TemplateArgument::Pack:
    return CXTemplateArgumentKind_Pack;
  }

  return CXTemplateArgumentKind_Invalid;
}

CXType clang_Cursor_getTemplateArgumentType(CXCursor C, unsigned I) {
  TemplateArgument TA;
  if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
      CXGetTemplateArgumentStatus_Success) {
    return cxtype::MakeCXType(QualType(), getCursorTU(C));
  }

  if (TA.getKind() != TemplateArgument::Type) {
    return cxtype::MakeCXType(QualType(), getCursorTU(C));
  }

  return cxtype::MakeCXType(TA.getAsType(), getCursorTU(C));
}

long long clang_Cursor_getTemplateArgumentValue(CXCursor C, unsigned I) {
  TemplateArgument TA;
  if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
      CXGetTemplateArgumentStatus_Success) {
    assert(0 && "Unable to retrieve TemplateArgument");
    return 0;
  }

  if (TA.getKind() != TemplateArgument::Integral) {
    assert(0 && "Passed template argument is not Integral");
    return 0;
  }

  return TA.getAsIntegral().getSExtValue();
}

unsigned long long clang_Cursor_getTemplateArgumentUnsignedValue(CXCursor C,
                                                                 unsigned I) {
  TemplateArgument TA;
  if (clang_Cursor_getTemplateArgument(C, I, &TA) !=
      CXGetTemplateArgumentStatus_Success) {
    assert(0 && "Unable to retrieve TemplateArgument");
    return 0;
  }

  if (TA.getKind() != TemplateArgument::Integral) {
    assert(0 && "Passed template argument is not Integral");
    return 0;
  }

  return TA.getAsIntegral().getZExtValue();
}

//===----------------------------------------------------------------------===//
// CXCursorSet.
//===----------------------------------------------------------------------===//

typedef llvm::DenseMap<CXCursor, unsigned> CXCursorSet_Impl;

static inline CXCursorSet packCXCursorSet(CXCursorSet_Impl *setImpl) {
  return (CXCursorSet)setImpl;
}
static inline CXCursorSet_Impl *unpackCXCursorSet(CXCursorSet set) {
  return (CXCursorSet_Impl *)set;
}
namespace llvm {
template <> struct DenseMapInfo<CXCursor> {
public:
  static inline CXCursor getEmptyKey() {
    return MakeCXCursorInvalid(CXCursor_InvalidFile);
  }
  static inline CXCursor getTombstoneKey() {
    return MakeCXCursorInvalid(CXCursor_NoDeclFound);
  }
  static inline unsigned getHashValue(const CXCursor &cursor) {
    return llvm::DenseMapInfo<std::pair<const void *, const void *>>::
        getHashValue(std::make_pair(cursor.data[0], cursor.data[1]));
  }
  static inline bool isEqual(const CXCursor &x, const CXCursor &y) {
    return x.kind == y.kind && x.data[0] == y.data[0] && x.data[1] == y.data[1];
  }
};
} // namespace llvm

CXCursorSet clang_createCXCursorSet() {
  return packCXCursorSet(new CXCursorSet_Impl());
}

void clang_disposeCXCursorSet(CXCursorSet set) {
  delete unpackCXCursorSet(set);
}

unsigned clang_CXCursorSet_contains(CXCursorSet set, CXCursor cursor) {
  CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
  if (!setImpl)
    return 0;
  return setImpl->find(cursor) != setImpl->end();
}

unsigned clang_CXCursorSet_insert(CXCursorSet set, CXCursor cursor) {
  // Do not insert invalid cursors into the set.
  if (cursor.kind >= CXCursor_FirstInvalid &&
      cursor.kind <= CXCursor_LastInvalid)
    return 1;

  CXCursorSet_Impl *setImpl = unpackCXCursorSet(set);
  if (!setImpl)
    return 1;
  unsigned &entry = (*setImpl)[cursor];
  unsigned flag = entry == 0 ? 1 : 0;
  entry = 1;
  return flag;
}

CXCompletionString clang_getCursorCompletionString(CXCursor cursor) {
  enum CXCursorKind kind = clang_getCursorKind(cursor);
  if (clang_isDeclaration(kind)) {
    const Decl *decl = getCursorDecl(cursor);
    if (const NamedDecl *namedDecl = dyn_cast_or_null<NamedDecl>(decl)) {
      ASTUnit *unit = getCursorASTUnit(cursor);
      CodeCompletionResult Result(namedDecl, CCP_Declaration);
      CodeCompletionString *String = Result.CreateCodeCompletionString(
          unit->getASTContext(), unit->getPreprocessor(),
          CodeCompletionContext::CCC_Other,
          unit->getCodeCompletionTUInfo().getAllocator(),
          unit->getCodeCompletionTUInfo(), true);
      return String;
    }
  } else if (kind == CXCursor_MacroDefinition) {
    const MacroDefinitionRecord *definition = getCursorMacroDefinition(cursor);
    const IdentifierInfo *Macro = definition->getName();
    ASTUnit *unit = getCursorASTUnit(cursor);
    CodeCompletionResult Result(
        Macro,
        unit->getPreprocessor().getMacroDefinition(Macro).getMacroInfo());
    CodeCompletionString *String = Result.CreateCodeCompletionString(
        unit->getASTContext(), unit->getPreprocessor(),
        CodeCompletionContext::CCC_Other,
        unit->getCodeCompletionTUInfo().getAllocator(),
        unit->getCodeCompletionTUInfo(), false);
    return String;
  }
  return nullptr;
}

namespace {
struct OverridenCursorsPool {
  typedef SmallVector<CXCursor, 2> CursorVec;
  std::vector<CursorVec *> AllCursors;
  std::vector<CursorVec *> AvailableCursors;

  ~OverridenCursorsPool() {
    for (std::vector<CursorVec *>::iterator I = AllCursors.begin(),
                                            E = AllCursors.end();
         I != E; ++I) {
      delete *I;
    }
  }
};
} // namespace

void *cxcursor::createOverridenCXCursorsPool() {
  return new OverridenCursorsPool();
}

void cxcursor::disposeOverridenCXCursorsPool(void *pool) {
  delete static_cast<OverridenCursorsPool *>(pool);
}

void clang_getOverriddenCursors(CXCursor cursor, CXCursor **overridden,
                                unsigned *num_overridden) {
  if (overridden)
    *overridden = nullptr;
  if (num_overridden)
    *num_overridden = 0;

  CXTranslationUnit TU = cxcursor::getCursorTU(cursor);

  if (!overridden || !num_overridden || !TU)
    return;

  if (!clang_isDeclaration(cursor.kind))
    return;

  OverridenCursorsPool &pool =
      *static_cast<OverridenCursorsPool *>(TU->OverridenCursorsPool);

  OverridenCursorsPool::CursorVec *Vec = nullptr;

  if (!pool.AvailableCursors.empty()) {
    Vec = pool.AvailableCursors.back();
    pool.AvailableCursors.pop_back();
  } else {
    Vec = new OverridenCursorsPool::CursorVec();
    pool.AllCursors.push_back(Vec);
  }

  // Clear out the vector, but don't free the memory contents.  This
  // reduces malloc() traffic.
  Vec->clear();

  // Use the first entry to contain a back reference to the vector.
  // This is a complete hack.
  CXCursor backRefCursor = MakeCXCursorInvalid(CXCursor_InvalidFile, TU);
  backRefCursor.data[0] = Vec;
  assert(cxcursor::getCursorTU(backRefCursor) == TU);
  Vec->push_back(backRefCursor);

  // Get the overridden cursors.
  cxcursor::getOverriddenCursors(cursor, *Vec);

  // Did we get any overridden cursors?  If not, return Vec to the pool
  // of available cursor vectors.
  if (Vec->size() == 1) {
    pool.AvailableCursors.push_back(Vec);
    return;
  }

  // Now tell the caller about the overridden cursors.
  assert(Vec->size() > 1);
  *overridden = &((*Vec)[1]);
  *num_overridden = Vec->size() - 1;
}

void clang_disposeOverriddenCursors(CXCursor *overridden) {
  if (!overridden)
    return;

  // Use pointer arithmetic to get back the first faux entry
  // which has a back-reference to the TU and the vector.
  --overridden;
  OverridenCursorsPool::CursorVec *Vec =
      static_cast<OverridenCursorsPool::CursorVec *>(
          const_cast<void *>(overridden->data[0]));
  CXTranslationUnit TU = getCursorTU(*overridden);

  assert(Vec && TU);

  OverridenCursorsPool &pool =
      *static_cast<OverridenCursorsPool *>(TU->OverridenCursorsPool);

  pool.AvailableCursors.push_back(Vec);
}

int clang_Cursor_isDynamicCall(CXCursor C) {
  const Expr *E = nullptr;
  if (clang_isExpression(C.kind))
    E = getCursorExpr(C);
  if (!E)
    return 0;

  if (const ObjCMessageExpr *MsgE = dyn_cast<ObjCMessageExpr>(E)) {
    if (MsgE->getReceiverKind() != ObjCMessageExpr::Instance)
      return false;
    if (auto *RecE = dyn_cast<ObjCMessageExpr>(
            MsgE->getInstanceReceiver()->IgnoreParenCasts())) {
      if (RecE->getMethodFamily() == OMF_alloc)
        return false;
    }
    return true;
  }

  if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(E)) {
    return !PropRefE->isSuperReceiver();
  }

  const MemberExpr *ME = nullptr;
  if (isa<MemberExpr>(E))
    ME = cast<MemberExpr>(E);
  else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
    ME = dyn_cast_or_null<MemberExpr>(CE->getCallee());

  if (ME) {
    if (const CXXMethodDecl *MD =
            dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl()))
      return MD->isVirtual() &&
             ME->performsVirtualDispatch(
                 cxcursor::getCursorContext(C).getLangOpts());
  }

  return 0;
}

CXType clang_Cursor_getReceiverType(CXCursor C) {
  CXTranslationUnit TU = cxcursor::getCursorTU(C);
  const Expr *E = nullptr;
  if (clang_isExpression(C.kind))
    E = getCursorExpr(C);

  if (const ObjCMessageExpr *MsgE = dyn_cast_or_null<ObjCMessageExpr>(E))
    return cxtype::MakeCXType(MsgE->getReceiverType(), TU);

  if (auto *PropRefE = dyn_cast<ObjCPropertyRefExpr>(E)) {
    return cxtype::MakeCXType(
        PropRefE->getReceiverType(cxcursor::getCursorContext(C)), TU);
  }

  const MemberExpr *ME = nullptr;
  if (isa<MemberExpr>(E))
    ME = cast<MemberExpr>(E);
  else if (const CallExpr *CE = dyn_cast<CallExpr>(E))
    ME = dyn_cast_or_null<MemberExpr>(CE->getCallee());

  if (ME) {
    if (dyn_cast_or_null<CXXMethodDecl>(ME->getMemberDecl())) {
      auto receiverTy = ME->getBase()->IgnoreImpCasts()->getType();
      return cxtype::MakeCXType(receiverTy, TU);
    }
  }

  return cxtype::MakeCXType(QualType(), TU);
}
