//===-- FindAllSymbols.cpp - find all symbols--------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "FindAllSymbols.h"
#include "HeaderMapCollector.h"
#include "PathConfig.h"
#include "SymbolInfo.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/Type.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/ADT/Optional.h"
#include "llvm/Support/FileSystem.h"

using namespace clang::ast_matchers;

namespace clang {
namespace find_all_symbols {
namespace {

AST_MATCHER(EnumConstantDecl, isInScopedEnum) {
  if (const auto *ED = dyn_cast<EnumDecl>(Node.getDeclContext()))
    return ED->isScoped();
  return false;
}

AST_POLYMORPHIC_MATCHER(isFullySpecialized,
                        AST_POLYMORPHIC_SUPPORTED_TYPES(FunctionDecl, VarDecl,
                                                        CXXRecordDecl)) {
  if (Node.getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
    bool IsPartialSpecialization =
        llvm::isa<VarTemplatePartialSpecializationDecl>(Node) ||
        llvm::isa<ClassTemplatePartialSpecializationDecl>(Node);
    return !IsPartialSpecialization;
  }
  return false;
}

std::vector<SymbolInfo::Context> GetContexts(const NamedDecl *ND) {
  std::vector<SymbolInfo::Context> Contexts;
  for (const auto *Context = ND->getDeclContext(); Context;
       Context = Context->getParent()) {
    if (llvm::isa<TranslationUnitDecl>(Context) ||
        llvm::isa<LinkageSpecDecl>(Context))
      break;

    assert(llvm::isa<NamedDecl>(Context) &&
           "Expect Context to be a NamedDecl");
    if (const auto *NSD = dyn_cast<NamespaceDecl>(Context)) {
      if (!NSD->isInlineNamespace())
        Contexts.emplace_back(SymbolInfo::ContextType::Namespace,
                              NSD->getName().str());
    } else if (const auto *ED = dyn_cast<EnumDecl>(Context)) {
      Contexts.emplace_back(SymbolInfo::ContextType::EnumDecl,
                            ED->getName().str());
    } else {
      const auto *RD = cast<RecordDecl>(Context);
      Contexts.emplace_back(SymbolInfo::ContextType::Record,
                            RD->getName().str());
    }
  }
  return Contexts;
}

llvm::Optional<SymbolInfo>
CreateSymbolInfo(const NamedDecl *ND, const SourceManager &SM,
                 const HeaderMapCollector *Collector) {
  SymbolInfo::SymbolKind Type;
  if (llvm::isa<VarDecl>(ND)) {
    Type = SymbolInfo::SymbolKind::Variable;
  } else if (llvm::isa<FunctionDecl>(ND)) {
    Type = SymbolInfo::SymbolKind::Function;
  } else if (llvm::isa<TypedefNameDecl>(ND)) {
    Type = SymbolInfo::SymbolKind::TypedefName;
  } else if (llvm::isa<EnumConstantDecl>(ND)) {
    Type = SymbolInfo::SymbolKind::EnumConstantDecl;
  } else if (llvm::isa<EnumDecl>(ND)) {
    Type = SymbolInfo::SymbolKind::EnumDecl;
    // Ignore anonymous enum declarations.
    if (ND->getName().empty())
      return llvm::None;
  } else {
    assert(llvm::isa<RecordDecl>(ND) &&
           "Matched decl must be one of VarDecl, "
           "FunctionDecl, TypedefNameDecl, EnumConstantDecl, "
           "EnumDecl and RecordDecl!");
    // C-style record decl can have empty name, e.g "struct { ... } var;".
    if (ND->getName().empty())
      return llvm::None;
    Type = SymbolInfo::SymbolKind::Class;
  }

  SourceLocation Loc = SM.getExpansionLoc(ND->getLocation());
  if (!Loc.isValid()) {
    llvm::errs() << "Declaration " << ND->getNameAsString() << "("
                 << ND->getDeclKindName()
                 << ") has invalid declaration location.";
    return llvm::None;
  }

  std::string FilePath = getIncludePath(SM, Loc, Collector);
  if (FilePath.empty()) return llvm::None;

  return SymbolInfo(ND->getNameAsString(), Type, FilePath, GetContexts(ND));
}

} // namespace

void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {
  // FIXME: Handle specialization.
  auto IsInSpecialization = hasAncestor(
      decl(anyOf(cxxRecordDecl(isExplicitTemplateSpecialization()),
                 functionDecl(isExplicitTemplateSpecialization()))));

  // Matchers for both C and C++.
  // We only match symbols from header files, i.e. not from main files (see
  // function's comment for detailed explanation).
  auto CommonFilter =
      allOf(unless(isImplicit()), unless(isExpansionInMainFile()));

  auto HasNSOrTUCtxMatcher =
      hasDeclContext(anyOf(namespaceDecl(), translationUnitDecl()));

  // We need seperate rules for C record types and C++ record types since some
  // template related matchers are inapplicable on C record declarations.
  //
  // Matchers specific to C++ code.
  // All declarations should be in namespace or translation unit.
  auto CCMatcher =
      allOf(HasNSOrTUCtxMatcher, unless(IsInSpecialization),
            unless(ast_matchers::isTemplateInstantiation()),
            unless(isInstantiated()), unless(isFullySpecialized()));

  // Matchers specific to code in extern "C" {...}.
  auto ExternCMatcher = hasDeclContext(linkageSpecDecl());

  // Matchers for variable declarations.
  //
  // In most cases, `ParmVarDecl` is filtered out by hasDeclContext(...)
  // matcher since the declaration context is usually `MethodDecl`. However,
  // this assumption does not hold for parameters of a function pointer
  // parameter.
  // For example, consider a function declaration:
  //        void Func(void (*)(float), int);
  // The float parameter of the function pointer has an empty name, and its
  // declaration context is an anonymous namespace; therefore, it won't be
  // filtered out by our matchers above.
  auto Vars = varDecl(CommonFilter, anyOf(ExternCMatcher, CCMatcher),
                      unless(parmVarDecl()));

  // Matchers for C-style record declarations in extern "C" {...}.
  auto CRecords = recordDecl(CommonFilter, ExternCMatcher, isDefinition());
  // Matchers for C++ record declarations.
  auto CXXRecords = cxxRecordDecl(CommonFilter, CCMatcher, isDefinition());

  // Matchers for function declarations.
  // We want to exclude friend declaration, but the `DeclContext` of a friend
  // function declaration is not the class in which it is declared, so we need
  // to explicitly check if the parent is a `friendDecl`.
  auto Functions = functionDecl(CommonFilter, unless(hasParent(friendDecl())),
                                anyOf(ExternCMatcher, CCMatcher));

  // Matcher for typedef and type alias declarations.
  //
  // typedef and type alias can come from C-style headers and C++ headers.
  // For C-style headers, `DeclContxet` can be either `TranslationUnitDecl`
  // or `LinkageSpecDecl`.
  // For C++ headers, `DeclContext ` can be either `TranslationUnitDecl`
  // or `NamespaceDecl`.
  // With the following context matcher, we can match `typedefNameDecl` from
  // both C-style headers and C++ headers (except for those in classes).
  // "cc_matchers" are not included since template-related matchers are not
  // applicable on `TypedefNameDecl`.
  auto Typedefs =
      typedefNameDecl(CommonFilter, anyOf(HasNSOrTUCtxMatcher,
                                          hasDeclContext(linkageSpecDecl())));

  // Matchers for enum declarations.
  auto Enums = enumDecl(CommonFilter, isDefinition(),
                        anyOf(HasNSOrTUCtxMatcher, ExternCMatcher));

  // Matchers for enum constant declarations.
  // We only match the enum constants in non-scoped enum declarations which are
  // inside toplevel translation unit or a namespace.
  auto EnumConstants = enumConstantDecl(
      CommonFilter, unless(isInScopedEnum()),
      anyOf(hasDeclContext(enumDecl(HasNSOrTUCtxMatcher)), ExternCMatcher));

  // Most of the time we care about all matchable decls, or all types.
  auto Types = namedDecl(anyOf(CRecords, CXXRecords, Enums));
  auto Decls = namedDecl(anyOf(CRecords, CXXRecords, Enums, Typedefs, Vars,
                               EnumConstants, Functions));

  // We want eligible decls bound to "decl"...
  MatchFinder->addMatcher(Decls.bind("decl"), this);

  // ... and all uses of them bound to "use". These have many cases:
  // Uses of values/functions: these generate a declRefExpr.
  MatchFinder->addMatcher(
      declRefExpr(isExpansionInMainFile(), to(Decls.bind("use"))), this);
  // Uses of function templates:
  MatchFinder->addMatcher(
      declRefExpr(isExpansionInMainFile(),
                  to(functionDecl(hasParent(
                      functionTemplateDecl(has(Functions.bind("use"))))))),
      this);

  // Uses of most types: just look at what the typeLoc refers to.
  MatchFinder->addMatcher(
      typeLoc(isExpansionInMainFile(),
              loc(qualType(hasDeclaration(Types.bind("use"))))),
      this);
  // Uses of typedefs: these are often transparent to hasDeclaration, so we need
  // to handle them explicitly.
  MatchFinder->addMatcher(
      typeLoc(isExpansionInMainFile(),
              loc(typedefType(hasDeclaration(Typedefs.bind("use"))))),
      this);
  // Uses of class templates:
  // The typeLoc names the templateSpecializationType. Its declaration is the
  // ClassTemplateDecl, which contains the CXXRecordDecl we want.
  MatchFinder->addMatcher(
      typeLoc(isExpansionInMainFile(),
              loc(templateSpecializationType(hasDeclaration(
                  classTemplateSpecializationDecl(hasSpecializedTemplate(
                      classTemplateDecl(has(CXXRecords.bind("use"))))))))),
      this);
}

void FindAllSymbols::run(const MatchFinder::MatchResult &Result) {
  // Ignore Results in failing TUs.
  if (Result.Context->getDiagnostics().hasErrorOccurred()) {
    return;
  }

  SymbolInfo::Signals Signals;
  const NamedDecl *ND;
  if ((ND = Result.Nodes.getNodeAs<NamedDecl>("use")))
    Signals.Used = 1;
  else if ((ND = Result.Nodes.getNodeAs<NamedDecl>("decl")))
    Signals.Seen = 1;
  else
    assert(false && "Must match a NamedDecl!");

  const SourceManager *SM = Result.SourceManager;
  if (auto Symbol = CreateSymbolInfo(ND, *SM, Collector)) {
    Filename = SM->getFileEntryForID(SM->getMainFileID())->getName();
    FileSymbols[*Symbol] += Signals;
  }
}

void FindAllSymbols::onEndOfTranslationUnit() {
  if (Filename != "") {
    Reporter->reportSymbols(Filename, FileSymbols);
    FileSymbols.clear();
    Filename = "";
  }
}

} // namespace find_all_symbols
} // namespace clang
