CompilerInstanceTest.cpp 3.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. //===- unittests/Frontend/CompilerInstanceTest.cpp - CI tests -------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "clang/Frontend/CompilerInstance.h"
  9. #include "clang/Frontend/CompilerInvocation.h"
  10. #include "clang/Frontend/TextDiagnosticPrinter.h"
  11. #include "llvm/Support/FileSystem.h"
  12. #include "llvm/Support/Format.h"
  13. #include "llvm/Support/ToolOutputFile.h"
  14. #include "gtest/gtest.h"
  15. using namespace llvm;
  16. using namespace clang;
  17. namespace {
  18. TEST(CompilerInstance, DefaultVFSOverlayFromInvocation) {
  19. // Create a temporary VFS overlay yaml file.
  20. int FD;
  21. SmallString<256> FileName;
  22. ASSERT_FALSE(sys::fs::createTemporaryFile("vfs", "yaml", FD, FileName));
  23. ToolOutputFile File(FileName, FD);
  24. SmallString<256> CurrentPath;
  25. sys::fs::current_path(CurrentPath);
  26. sys::fs::make_absolute(CurrentPath, FileName);
  27. // Mount the VFS file itself on the path 'virtual.file'. Makes this test
  28. // a bit shorter than creating a new dummy file just for this purpose.
  29. const std::string CurrentPathStr = CurrentPath.str();
  30. const std::string FileNameStr = FileName.str();
  31. const char *VFSYaml = "{ 'version': 0, 'roots': [\n"
  32. " { 'name': '%s',\n"
  33. " 'type': 'directory',\n"
  34. " 'contents': [\n"
  35. " { 'name': 'vfs-virtual.file', 'type': 'file',\n"
  36. " 'external-contents': '%s'\n"
  37. " }\n"
  38. " ]\n"
  39. " }\n"
  40. "]}\n";
  41. File.os() << format(VFSYaml, CurrentPathStr.c_str(), FileName.c_str());
  42. File.os().flush();
  43. // Create a CompilerInvocation that uses this overlay file.
  44. const std::string VFSArg = "-ivfsoverlay" + FileNameStr;
  45. const char *Args[] = {"clang", VFSArg.c_str(), "-xc++", "-"};
  46. IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
  47. CompilerInstance::createDiagnostics(new DiagnosticOptions());
  48. std::shared_ptr<CompilerInvocation> CInvok =
  49. createInvocationFromCommandLine(Args, Diags);
  50. if (!CInvok)
  51. FAIL() << "could not create compiler invocation";
  52. // Create a minimal CompilerInstance which should use the VFS we specified
  53. // in the CompilerInvocation (as we don't explicitly set our own).
  54. CompilerInstance Instance;
  55. Instance.setDiagnostics(Diags.get());
  56. Instance.setInvocation(CInvok);
  57. Instance.createFileManager();
  58. // Check if the virtual file exists which means that our VFS is used by the
  59. // CompilerInstance.
  60. ASSERT_TRUE(Instance.getFileManager().getFile("vfs-virtual.file"));
  61. }
  62. TEST(CompilerInstance, AllowDiagnosticLogWithUnownedDiagnosticConsumer) {
  63. auto DiagOpts = new DiagnosticOptions();
  64. // Tell the diagnostics engine to emit the diagnostic log to STDERR. This
  65. // ensures that a chained diagnostic consumer is created so that the test can
  66. // exercise the unowned diagnostic consumer in a chained consumer.
  67. DiagOpts->DiagnosticLogFile = "-";
  68. // Create the diagnostic engine with unowned consumer.
  69. std::string DiagnosticOutput;
  70. llvm::raw_string_ostream DiagnosticsOS(DiagnosticOutput);
  71. auto DiagPrinter = std::make_unique<TextDiagnosticPrinter>(
  72. DiagnosticsOS, new DiagnosticOptions());
  73. CompilerInstance Instance;
  74. IntrusiveRefCntPtr<DiagnosticsEngine> Diags = Instance.createDiagnostics(
  75. DiagOpts, DiagPrinter.get(), /*ShouldOwnClient=*/false);
  76. Diags->Report(diag::err_expected) << "no crash";
  77. ASSERT_EQ(DiagnosticsOS.str(), "error: expected no crash\n");
  78. }
  79. } // anonymous namespace