//===--- TBD.cpp -- generates and validates TBD files ---------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "TBD.h"
#include "swift/AST/ASTContext.h"
#include "swift/AST/Decl.h"
#include "swift/AST/DiagnosticEngine.h"
#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/AST/Module.h"
#include "swift/Basic/LLVM.h"
#include "swift/Demangling/Demangle.h"
#include "swift/Frontend/FrontendOptions.h"
#include "swift/TBDGen/TBDGen.h"

#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/FileSystem.h"
#include <vector>

using namespace swift;

static std::vector<StringRef> sortSymbols(llvm::StringSet<> &symbols) {
  std::vector<StringRef> sorted;
  for (auto &symbol : symbols)
    sorted.push_back(symbol.getKey());
  std::sort(sorted.begin(), sorted.end());
  return sorted;
}

bool swift::writeTBD(ModuleDecl *M, bool hasMultipleIGMs,
                     StringRef OutputFilename, StringRef installName) {
  std::error_code EC;
  llvm::raw_fd_ostream OS(OutputFilename, EC, llvm::sys::fs::F_None);
  if (EC) {
    M->getASTContext().Diags.diagnose(SourceLoc(), diag::error_opening_output,
                                      OutputFilename, EC.message());
    return true;
  }

  writeTBDFile(M, OS, hasMultipleIGMs, installName);

  return false;
}

bool swift::inputFileKindCanHaveTBDValidated(InputFileKind kind) {
  // Only things that involve an AST can have a TBD file computed, at the
  // moment.
  switch (kind) {
  case InputFileKind::IFK_Swift:
  case InputFileKind::IFK_Swift_Library:
    return true;
  case InputFileKind::IFK_None:
  case InputFileKind::IFK_Swift_REPL:
  case InputFileKind::IFK_SIL:
  case InputFileKind::IFK_LLVM_IR:
    return false;
  }
}

static bool validateSymbolSet(DiagnosticEngine &diags,
                              llvm::StringSet<> symbols, llvm::Module &IRModule,
                              bool diagnoseExtraSymbolsInTBD) {
  auto error = false;

  // Diff the two sets of symbols, flagging anything outside their intersection.

  // Delay the emission of errors for things in the IR but not TBD, so we can
  // sort them to get a stable order.
  std::vector<StringRef> irNotTBD;

  for (auto &nameValue : IRModule.getValueSymbolTable()) {
    auto name = nameValue.getKey();
    auto value = nameValue.getValue();
    if (auto GV = dyn_cast<llvm::GlobalValue>(value)) {
      // Is this a symbol that should be listed?
      auto externallyVisible =
          GV->hasExternalLinkage() && !GV->hasHiddenVisibility();
      if (!GV->isDeclaration() && externallyVisible) {
        // Is it listed?
        if (!symbols.erase(name))
          irNotTBD.push_back(name);
      }
    } else {
      assert(symbols.find(name) == symbols.end() &&
             "non-global value in value symbol table");
    }
  }

  std::sort(irNotTBD.begin(), irNotTBD.end());
  for (auto &name : irNotTBD) {
    diags.diagnose(SourceLoc(), diag::symbol_in_ir_not_in_tbd, name,
                   Demangle::demangleSymbolAsString(name));
    error = true;
  }

  if (diagnoseExtraSymbolsInTBD) {
    // Look for any extra symbols.
    for (auto &name : sortSymbols(symbols)) {
      diags.diagnose(SourceLoc(), diag::symbol_in_tbd_not_in_ir, name,
                     Demangle::demangleSymbolAsString(name));
      error = true;
    }
  }

  return error;
}

bool swift::validateTBD(ModuleDecl *M, llvm::Module &IRModule,
                        bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
  llvm::StringSet<> symbols;
  enumeratePublicSymbols(M, symbols, hasMultipleIGMs);

  return validateSymbolSet(M->getASTContext().Diags, symbols, IRModule,
                           diagnoseExtraSymbolsInTBD);
}

bool swift::validateTBD(FileUnit *file, llvm::Module &IRModule,
                        bool hasMultipleIGMs, bool diagnoseExtraSymbolsInTBD) {
  llvm::StringSet<> symbols;
  enumeratePublicSymbols(file, symbols, hasMultipleIGMs);

  return validateSymbolSet(file->getParentModule()->getASTContext().Diags,
                           symbols, IRModule, diagnoseExtraSymbolsInTBD);
}
