//===- 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:
  case Stmt::SYCLUniqueStableNameExprClass:
    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::OMPCanonicalLoopClass:
    K = CXCursor_OMPCanonicalLoop;
    break;
  case Stmt::OMPMetaDirectiveClass:
    K = CXCursor_OMPMetaDirective;
    break;
  case Stmt::OMPParallelDirectiveClass:
    K = CXCursor_OMPParallelDirective;
    break;
  case Stmt::OMPSimdDirectiveClass:
    K = CXCursor_OMPSimdDirective;
    break;
  case Stmt::OMPTileDirectiveClass:
    K = CXCursor_OMPTileDirective;
    break;
  case Stmt::OMPUnrollDirectiveClass:
    K = CXCursor_OMPUnrollDirective;
    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::OMPInteropDirectiveClass:
    K = CXCursor_OMPInteropDirective;
    break;
  case Stmt::OMPDispatchDirectiveClass:
    K = CXCursor_OMPDispatchDirective;
    break;
  case Stmt::OMPMaskedDirectiveClass:
    K = CXCursor_OMPMaskedDirective;
    break;
  case Stmt::OMPGenericLoopDirectiveClass:
    K = CXCursor_OMPGenericLoopDirective;
    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 (isa_and_nonnull<CXXMethodDecl>(ME->getMemberDecl())) {
      auto receiverTy = ME->getBase()->IgnoreImpCasts()->getType();
      return cxtype::MakeCXType(receiverTy, TU);
    }
  }

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