//===- CXCursor.cpp - Routines for manipulating CXCursors -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// 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 "CXTranslationUnit.h"
#include "CXCursor.h"
#include "CXString.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;
  }

  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=std::find(SelLocs.begin(), SelLocs.end(),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::ArrayTypeTraitExprClass:
  case Stmt::AsTypeExprClass:
  case Stmt::AtomicExprClass:
  case Stmt::BinaryConditionalOperatorClass:
  case Stmt::TypeTraitExprClass:
  case Stmt::CoroutineBodyStmtClass:
  case Stmt::CoawaitExprClass:
  case Stmt::DependentCoawaitExprClass:
  case Stmt::CoreturnStmtClass:
  case Stmt::CoyieldExprClass:
  case Stmt::CXXBindTemporaryExprClass:
  case Stmt::CXXDefaultArgExprClass:
  case Stmt::CXXDefaultInitExprClass:
  case Stmt::CXXFoldExprClass:
  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::ConvertVectorExprClass:
  case Stmt::VAArgExprClass:
  case Stmt::ObjCArrayLiteralClass:
  case Stmt::ObjCDictionaryLiteralClass:
  case Stmt::ObjCBoxedExprClass:
  case Stmt::ObjCSubscriptRefExprClass:
    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::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::OMPArraySectionExprClass:
    K = CXCursor_OMPArraySectionExpr;
    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::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=std::find(SelLocs.begin(), SelLocs.end(),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::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::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::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;
  }

  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]);
}

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

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();
    }
  }

  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));
      }
    }
  }

  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];
  }
};
}

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;
      }
    }
  };
}

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);
}
