//===- IndexTypeSourceInfo.cpp - Indexing types ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "IndexingContext.h"
#include "clang/AST/RecursiveASTVisitor.h"

using namespace clang;
using namespace index;

namespace {

class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
  IndexingContext &IndexCtx;
  const NamedDecl *Parent;
  const DeclContext *ParentDC;
  bool IsBase;
  SmallVector<SymbolRelation, 3> Relations;

  typedef RecursiveASTVisitor<TypeIndexer> base;

public:
  TypeIndexer(IndexingContext &indexCtx, const NamedDecl *parent,
              const DeclContext *DC, bool isBase, bool isIBType)
    : IndexCtx(indexCtx), Parent(parent), ParentDC(DC), IsBase(isBase) {
    if (IsBase) {
      assert(Parent);
      Relations.emplace_back((unsigned)SymbolRole::RelationBaseOf, Parent);
    }
    if (isIBType) {
      assert(Parent);
      Relations.emplace_back((unsigned)SymbolRole::RelationIBTypeOf, Parent);
    }
  }

  bool shouldWalkTypesOfTypeLocs() const { return false; }

#define TRY_TO(CALL_EXPR)                                                      \
  do {                                                                         \
    if (!CALL_EXPR)                                                            \
      return false;                                                            \
  } while (0)

  bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
    SourceLocation Loc = TL.getNameLoc();
    TypedefNameDecl *ND = TL.getTypedefNameDecl();
    if (ND->isTransparentTag()) {
      TagDecl *Underlying = ND->getUnderlyingType()->getAsTagDecl();
      return IndexCtx.handleReference(Underlying, Loc, Parent,
                                      ParentDC, SymbolRoleSet(), Relations);
    }
    if (IsBase) {
      TRY_TO(IndexCtx.handleReference(ND, Loc,
                                      Parent, ParentDC, SymbolRoleSet()));
      if (auto *CD = TL.getType()->getAsCXXRecordDecl()) {
        TRY_TO(IndexCtx.handleReference(CD, Loc, Parent, ParentDC,
                                        (unsigned)SymbolRole::Implicit,
                                        Relations));
      }
    } else {
      TRY_TO(IndexCtx.handleReference(ND, Loc,
                                      Parent, ParentDC, SymbolRoleSet(),
                                      Relations));
    }
    return true;
  }

  bool traverseParamVarHelper(ParmVarDecl *D) {
    TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
    if (D->getTypeSourceInfo())
      TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
    return true;
  }

  bool TraverseParmVarDecl(ParmVarDecl *D) {
    // Avoid visiting default arguments from the definition that were already
    // visited in the declaration.
    // FIXME: A free function definition can have default arguments.
    // Avoiding double visitaiton of default arguments should be handled by the
    // visitor probably with a bit in the AST to indicate if the attached
    // default argument was 'inherited' or written in source.
    if (auto FD = dyn_cast<FunctionDecl>(D->getDeclContext())) {
      if (FD->isThisDeclarationADefinition()) {
        return traverseParamVarHelper(D);
      }
    }

    return base::TraverseParmVarDecl(D);
  }

  bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
    IndexCtx.indexNestedNameSpecifierLoc(NNS, Parent, ParentDC);
    return true;
  }

  bool VisitTagTypeLoc(TagTypeLoc TL) {
    TagDecl *D = TL.getDecl();
    if (D->getParentFunctionOrMethod())
      return true;

    if (TL.isDefinition()) {
      IndexCtx.indexTagDecl(D);
      return true;
    }

    return IndexCtx.handleReference(D, TL.getNameLoc(),
                                    Parent, ParentDC, SymbolRoleSet(),
                                    Relations);
  }

  bool VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
    return IndexCtx.handleReference(TL.getIFaceDecl(), TL.getNameLoc(),
                                    Parent, ParentDC, SymbolRoleSet(), Relations);
  }

  bool VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
    for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i) {
      IndexCtx.handleReference(TL.getProtocol(i), TL.getProtocolLoc(i),
                               Parent, ParentDC, SymbolRoleSet(), Relations);
    }
    return true;
  }

  template<typename TypeLocType>
  bool HandleTemplateSpecializationTypeLoc(TypeLocType TL) {
    if (const auto *T = TL.getTypePtr()) {
      if (IndexCtx.shouldIndexImplicitInstantiation()) {
        if (CXXRecordDecl *RD = T->getAsCXXRecordDecl())
          IndexCtx.handleReference(RD, TL.getTemplateNameLoc(),
                                   Parent, ParentDC, SymbolRoleSet(), Relations);
      } else {
        if (const TemplateDecl *D = T->getTemplateName().getAsTemplateDecl())
          IndexCtx.handleReference(D, TL.getTemplateNameLoc(),
                                   Parent, ParentDC, SymbolRoleSet(), Relations);
      }
    }
    return true;
  }

  bool VisitTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
    return HandleTemplateSpecializationTypeLoc(TL);
  }

  bool VisitDeducedTemplateSpecializationTypeLoc(DeducedTemplateSpecializationTypeLoc TL) {
    return HandleTemplateSpecializationTypeLoc(TL);
  }

  bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
    const DependentNameType *DNT = TL.getTypePtr();
    const NestedNameSpecifier *NNS = DNT->getQualifier();
    const Type *T = NNS->getAsType();
    if (!T)
      return true;
    const TemplateSpecializationType *TST =
        T->getAs<TemplateSpecializationType>();
    if (!TST)
      return true;
    TemplateName TN = TST->getTemplateName();
    const ClassTemplateDecl *TD =
        dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
    if (!TD)
      return true;
    CXXRecordDecl *RD = TD->getTemplatedDecl();
    if (!RD->hasDefinition())
      return true;
    RD = RD->getDefinition();
    DeclarationName Name(DNT->getIdentifier());
    std::vector<const NamedDecl *> Symbols = RD->lookupDependentName(
        Name, [](const NamedDecl *ND) { return isa<TypeDecl>(ND); });
    if (Symbols.size() != 1)
      return true;
    return IndexCtx.handleReference(Symbols[0], TL.getNameLoc(), Parent,
                                    ParentDC, SymbolRoleSet(), Relations);
  }

  bool TraverseStmt(Stmt *S) {
    IndexCtx.indexBody(S, Parent, ParentDC);
    return true;
  }
};

} // anonymous namespace

void IndexingContext::indexTypeSourceInfo(TypeSourceInfo *TInfo,
                                          const NamedDecl *Parent,
                                          const DeclContext *DC,
                                          bool isBase,
                                          bool isIBType) {
  if (!TInfo || TInfo->getTypeLoc().isNull())
    return;

  indexTypeLoc(TInfo->getTypeLoc(), Parent, DC, isBase, isIBType);
}

void IndexingContext::indexTypeLoc(TypeLoc TL,
                                   const NamedDecl *Parent,
                                   const DeclContext *DC,
                                   bool isBase,
                                   bool isIBType) {
  if (TL.isNull())
    return;

  if (!DC)
    DC = Parent->getLexicalDeclContext();
  TypeIndexer(*this, Parent, DC, isBase, isIBType).TraverseTypeLoc(TL);
}

void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
                                                  const NamedDecl *Parent,
                                                  const DeclContext *DC) {
  if (!NNS)
    return;

  if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
    indexNestedNameSpecifierLoc(Prefix, Parent, DC);

  if (!DC)
    DC = Parent->getLexicalDeclContext();
  SourceLocation Loc = NNS.getLocalBeginLoc();

  switch (NNS.getNestedNameSpecifier()->getKind()) {
  case NestedNameSpecifier::Identifier:
  case NestedNameSpecifier::Global:
  case NestedNameSpecifier::Super:
    break;

  case NestedNameSpecifier::Namespace:
    handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
                    Loc, Parent, DC, SymbolRoleSet());
    break;
  case NestedNameSpecifier::NamespaceAlias:
    handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
                    Loc, Parent, DC, SymbolRoleSet());
    break;

  case NestedNameSpecifier::TypeSpec:
  case NestedNameSpecifier::TypeSpecWithTemplate:
    indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
    break;
  }
}

void IndexingContext::indexTagDecl(const TagDecl *D,
                                   ArrayRef<SymbolRelation> Relations) {
  if (!shouldIndex(D))
    return;
  if (!shouldIndexFunctionLocalSymbols() && isFunctionLocalSymbol(D))
    return;

  if (handleDecl(D, /*Roles=*/SymbolRoleSet(), Relations)) {
    if (D->isThisDeclarationADefinition()) {
      indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
      if (auto CXXRD = dyn_cast<CXXRecordDecl>(D)) {
        for (const auto &I : CXXRD->bases()) {
          indexTypeSourceInfo(I.getTypeSourceInfo(), CXXRD, CXXRD, /*isBase=*/true);
        }
      }
      indexDeclContext(D);
    }
  }
}
