//===- unittests/Frontend/FrontendActionTest.cpp - FrontendAction tests ---===//
//
// 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
//
//===----------------------------------------------------------------------===//

#include "clang/Frontend/FrontendAction.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DynamicRecursiveASTVisitor.h"
#include "clang/Basic/LangStandard.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "clang/Sema/Sema.h"
#include "clang/Serialization/InMemoryModuleCache.h"
#include "clang/Serialization/ModuleCache.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ToolOutputFile.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/TargetParser/Triple.h"
#include "gtest/gtest.h"

using namespace llvm;
using namespace clang;

namespace {

class TestASTFrontendAction : public ASTFrontendAction {
public:
  TestASTFrontendAction(bool enableIncrementalProcessing = false,
                        bool actOnEndOfTranslationUnit = false)
    : EnableIncrementalProcessing(enableIncrementalProcessing),
      ActOnEndOfTranslationUnit(actOnEndOfTranslationUnit) { }

  bool EnableIncrementalProcessing;
  bool ActOnEndOfTranslationUnit;
  std::vector<std::string> decl_names;

  bool BeginSourceFileAction(CompilerInstance &ci) override {
    if (EnableIncrementalProcessing)
      ci.getPreprocessor().enableIncrementalProcessing();

    return ASTFrontendAction::BeginSourceFileAction(ci);
  }

  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
                                                 StringRef InFile) override {
    return std::make_unique<Visitor>(CI, ActOnEndOfTranslationUnit,
                                      decl_names);
  }

private:
  class Visitor : public ASTConsumer, public DynamicRecursiveASTVisitor {
  public:
    Visitor(CompilerInstance &CI, bool ActOnEndOfTranslationUnit,
            std::vector<std::string> &decl_names) :
      CI(CI), ActOnEndOfTranslationUnit(ActOnEndOfTranslationUnit),
      decl_names_(decl_names) {}

    void HandleTranslationUnit(ASTContext &context) override {
      if (ActOnEndOfTranslationUnit) {
        CI.getSema().ActOnEndOfTranslationUnit();
      }
      TraverseDecl(context.getTranslationUnitDecl());
    }

    bool VisitNamedDecl(NamedDecl *Decl) override {
      decl_names_.push_back(Decl->getQualifiedNameAsString());
      return true;
    }

  private:
    CompilerInstance &CI;
    bool ActOnEndOfTranslationUnit;
    std::vector<std::string> &decl_names_;
  };
};

TEST(ASTFrontendAction, Sanity) {
  auto invocation = std::make_shared<CompilerInvocation>();
  invocation->getPreprocessorOpts().addRemappedFile(
      "test.cc",
      MemoryBuffer::getMemBuffer("int main() { float x; }").release());
  invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile("test.cc", Language::CXX));
  invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
  invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
  CompilerInstance compiler(std::move(invocation));
  compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

  TestASTFrontendAction test_action;
  ASSERT_TRUE(compiler.ExecuteAction(test_action));
  ASSERT_EQ(2U, test_action.decl_names.size());
  EXPECT_EQ("main", test_action.decl_names[0]);
  EXPECT_EQ("x", test_action.decl_names[1]);
}

TEST(ASTFrontendAction, IncrementalParsing) {
  auto invocation = std::make_shared<CompilerInvocation>();
  invocation->getPreprocessorOpts().addRemappedFile(
      "test.cc",
      MemoryBuffer::getMemBuffer("int main() { float x; }").release());
  invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile("test.cc", Language::CXX));
  invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
  invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
  CompilerInstance compiler(std::move(invocation));
  compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

  TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true);
  ASSERT_TRUE(compiler.ExecuteAction(test_action));
  ASSERT_EQ(2U, test_action.decl_names.size());
  EXPECT_EQ("main", test_action.decl_names[0]);
  EXPECT_EQ("x", test_action.decl_names[1]);
}

TEST(ASTFrontendAction, LateTemplateIncrementalParsing) {
  auto invocation = std::make_shared<CompilerInvocation>();
  invocation->getLangOpts().CPlusPlus = true;
  invocation->getLangOpts().DelayedTemplateParsing = true;
  invocation->getPreprocessorOpts().addRemappedFile(
    "test.cc", MemoryBuffer::getMemBuffer(
      "template<typename T> struct A { A(T); T data; };\n"
      "template<typename T> struct B: public A<T> {\n"
      "  B();\n"
      "  B(B const& b): A<T>(b.data) {}\n"
      "};\n"
      "B<char> c() { return B<char>(); }\n").release());
  invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile("test.cc", Language::CXX));
  invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
  invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
  CompilerInstance compiler(std::move(invocation));
  compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

  TestASTFrontendAction test_action(/*enableIncrementalProcessing=*/true,
                                    /*actOnEndOfTranslationUnit=*/true);
  ASSERT_TRUE(compiler.ExecuteAction(test_action));
  ASSERT_EQ(13U, test_action.decl_names.size());
  EXPECT_EQ("A", test_action.decl_names[0]);
  EXPECT_EQ("c", test_action.decl_names[12]);
}

struct TestPPCallbacks : public PPCallbacks {
  TestPPCallbacks() : SeenEnd(false) {}

  void EndOfMainFile() override { SeenEnd = true; }

  bool SeenEnd;
};

class TestPPCallbacksFrontendAction : public PreprocessorFrontendAction {
  TestPPCallbacks *Callbacks;

public:
  TestPPCallbacksFrontendAction(TestPPCallbacks *C)
      : Callbacks(C), SeenEnd(false) {}

  void ExecuteAction() override {
    Preprocessor &PP = getCompilerInstance().getPreprocessor();
    PP.addPPCallbacks(std::unique_ptr<TestPPCallbacks>(Callbacks));
    PP.EnterMainSourceFile();
  }
  void EndSourceFileAction() override { SeenEnd = Callbacks->SeenEnd; }

  bool SeenEnd;
};

TEST(PreprocessorFrontendAction, EndSourceFile) {
  auto Invocation = std::make_shared<CompilerInvocation>();
  Invocation->getPreprocessorOpts().addRemappedFile(
      "test.cc",
      MemoryBuffer::getMemBuffer("int main() { float x; }").release());
  Invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile("test.cc", Language::CXX));
  Invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
  Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
  CompilerInstance Compiler(std::move(Invocation));
  Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

  TestPPCallbacks *Callbacks = new TestPPCallbacks;
  TestPPCallbacksFrontendAction TestAction(Callbacks);
  ASSERT_FALSE(Callbacks->SeenEnd);
  ASSERT_FALSE(TestAction.SeenEnd);
  ASSERT_TRUE(Compiler.ExecuteAction(TestAction));
  // Check that EndOfMainFile was called before EndSourceFileAction.
  ASSERT_TRUE(TestAction.SeenEnd);
}

class TypoExternalSemaSource : public ExternalSemaSource {
  CompilerInstance &CI;

public:
  TypoExternalSemaSource(CompilerInstance &CI) : CI(CI) {}

  TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, int LookupKind,
                             Scope *S, CXXScopeSpec *SS,
                             CorrectionCandidateCallback &CCC,
                             DeclContext *MemberContext, bool EnteringContext,
                             const ObjCObjectPointerType *OPT) override {
    // Generate a fake typo correction with one attached note.
    ASTContext &Ctx = CI.getASTContext();
    TypoCorrection TC(DeclarationName(&Ctx.Idents.get("moo")));
    unsigned DiagID = Ctx.getDiagnostics().getCustomDiagID(
        DiagnosticsEngine::Note, "This is a note");
    TC.addExtraDiagnostic(PartialDiagnostic(DiagID, Ctx.getDiagAllocator()));
    return TC;
  }
};

struct TypoDiagnosticConsumer : public DiagnosticConsumer {
  void HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
                        const Diagnostic &Info) override {
    // Capture errors and notes. There should be one of each.
    if (DiagLevel == DiagnosticsEngine::Error) {
      assert(Error.empty());
      Info.FormatDiagnostic(Error);
    } else {
      assert(Note.empty());
      Info.FormatDiagnostic(Note);
    }
  }
  SmallString<32> Error;
  SmallString<32> Note;
};

TEST(ASTFrontendAction, ExternalSemaSource) {
  auto Invocation = std::make_shared<CompilerInvocation>();
  Invocation->getLangOpts().CPlusPlus = true;
  Invocation->getPreprocessorOpts().addRemappedFile(
      "test.cc", MemoryBuffer::getMemBuffer("void fooo();\n"
                                            "int main() { foo(); }")
                     .release());
  Invocation->getFrontendOpts().Inputs.push_back(
      FrontendInputFile("test.cc", Language::CXX));
  Invocation->getFrontendOpts().ProgramAction = frontend::ParseSyntaxOnly;
  Invocation->getTargetOpts().Triple = "i386-unknown-linux-gnu";
  CompilerInstance Compiler(std::move(Invocation));
  auto *TDC = new TypoDiagnosticConsumer;
  Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem(), TDC,
                             /*ShouldOwnClient=*/true);
  Compiler.setExternalSemaSource(
      llvm::makeIntrusiveRefCnt<TypoExternalSemaSource>(Compiler));

  SyntaxOnlyAction TestAction;
  ASSERT_TRUE(Compiler.ExecuteAction(TestAction));
  // There should be one error correcting to 'moo' and a note attached to it.
  EXPECT_EQ("use of undeclared identifier 'foo'; did you mean 'moo'?",
            std::string(TDC->Error));
  EXPECT_EQ("This is a note", std::string(TDC->Note));
}

TEST(GeneratePCHFrontendAction, CacheGeneratedPCH) {
  // Create a temporary file for writing out the PCH that will be cleaned up.
  int PCHFD;
  llvm::SmallString<128> PCHFilename;
  ASSERT_FALSE(
      llvm::sys::fs::createTemporaryFile("test.h", "pch", PCHFD, PCHFilename));
  llvm::ToolOutputFile PCHFile(PCHFilename, PCHFD);

  for (bool ShouldCache : {false, true}) {
    auto Invocation = std::make_shared<CompilerInvocation>();
    Invocation->getLangOpts().CacheGeneratedPCH = ShouldCache;
    Invocation->getPreprocessorOpts().addRemappedFile(
        "test.h",
        MemoryBuffer::getMemBuffer("int foo(void) { return 1; }\n").release());
    Invocation->getFrontendOpts().Inputs.push_back(
        FrontendInputFile("test.h", Language::C));
    Invocation->getFrontendOpts().OutputFile = PCHFilename.str().str();
    Invocation->getFrontendOpts().ProgramAction = frontend::GeneratePCH;
    Invocation->getTargetOpts().Triple = "x86_64-apple-darwin19.0.0";
    CompilerInstance Compiler(std::move(Invocation));
    Compiler.createDiagnostics(*llvm::vfs::getRealFileSystem());

    GeneratePCHAction TestAction;
    ASSERT_TRUE(Compiler.ExecuteAction(TestAction));

    // Check whether the PCH was cached.
    if (ShouldCache)
      EXPECT_EQ(InMemoryModuleCache::Final,
                Compiler.getModuleCache().getInMemoryModuleCache().getPCMState(
                    PCHFilename));
    else
      EXPECT_EQ(InMemoryModuleCache::Unknown,
                Compiler.getModuleCache().getInMemoryModuleCache().getPCMState(
                    PCHFilename));
  }
}

} // anonymous namespace
