17#include "llvm/ADT/ScopeExit.h"
18#include "llvm/Support/Error.h"
19#include "llvm/Support/VirtualFileSystem.h"
20#include "gtest/gtest.h"
28 std::vector<StoredDiagnostic> &Out;
33 StoreDiagnostics(std::vector<StoredDiagnostic> &Out,
bool ReportErrors)
34 : Out(Out), ReportErrors(ReportErrors) {}
36 void BeginSourceFile(
const LangOptions &LangOpts,
37 const Preprocessor *)
override {
38 this->LangOpts = LangOpts;
42 const Diagnostic &Info)
override {
43 Out.emplace_back(DiagLevel, Info);
46 llvm::raw_string_ostream
OS(
Text);
47 TextDiagnostic Renderer(OS, LangOpts,
48 Info.getDiags()->getDiagnosticOptions());
49 Renderer.emitStoredDiagnostic(Out.back());
50 ADD_FAILURE() <<
Text;
58 if (!Clang.hasVirtualFileSystem())
59 Clang.createVirtualFileSystem();
60 if (!Clang.hasDiagnostics())
61 Clang.createDiagnostics();
62 if (!Clang.hasFileManager())
63 Clang.createFileManager();
64 if (!Clang.hasSourceManager())
65 Clang.createSourceManager();
66 if (!Clang.hasTarget())
68 if (!Clang.hasPreprocessor())
70 if (!Clang.hasASTConsumer())
71 Clang.setASTConsumer(std::make_unique<ASTConsumer>());
72 if (!Clang.hasASTContext())
73 Clang.createASTContext();
81 Clang = std::make_unique<CompilerInstance>();
84 llvm::scope_exit RecoverFromEarlyExit(
85 [&] { createMissingComponents(*Clang); });
87 std::string Filename = In.FileName;
92 auto VFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
93 if (
auto Err = VFS->setCurrentWorkingDirectory(In.WorkingDir))
94 ADD_FAILURE() <<
"Failed to setWD: " << Err.message();
95 VFS->addFile(Filename, 0,
96 llvm::MemoryBuffer::getMemBufferCopy(In.Code, Filename));
97 for (
const auto &
Extra : In.ExtraFiles)
100 llvm::MemoryBuffer::getMemBufferCopy(
Extra.getValue(),
Extra.getKey()));
103 bool ErrorOK = In.ErrorOK || llvm::StringRef(In.Code).contains(
"error-ok");
104 auto DiagConsumer =
new StoreDiagnostics(Diagnostics, !ErrorOK);
105 Clang->createVirtualFileSystem(std::move(VFS), DiagConsumer);
106 Clang->createDiagnostics(DiagConsumer);
109 std::vector<const char *> Argv;
111 for (
const auto &S : LangArgs)
112 Argv.push_back(S.c_str());
113 for (
const auto &S : In.ExtraArgs)
114 Argv.push_back(S.c_str());
115 Argv.push_back(Filename.c_str());
117 Clang->getDiagnostics(),
"clang")) {
118 ADD_FAILURE() <<
"Failed to create invocation";
121 assert(!Clang->getInvocation().getFrontendOpts().DisableFree);
123 Clang->createFileManager();
127 EXPECT_TRUE(Clang->createTarget());
129 In.MakeAction ? In.MakeAction() : std::make_unique<SyntaxOnlyAction>();
131 if (!Action->BeginSourceFile(*Clang, Main)) {
132 ADD_FAILURE() <<
"Failed to BeginSourceFile()";
136 if (
auto Err = Action->Execute())
137 ADD_FAILURE() <<
"Failed to Execute(): " << llvm::toString(std::move(Err));
141 Clang->getPreprocessor().EndSourceFile();
143 Clang->getDiagnosticClient().EndSourceFile();
148void TestAST::clear() {
152 auto PP = Clang->getPreprocessorPtr();
153 Clang->setPreprocessor(
nullptr);
154 Action->EndSourceFile();
164 Action = std::move(M.Action);
165 Clang = std::move(M.Clang);
166 Diagnostics = std::move(M.Diagnostics);
Defines the Diagnostic-related interfaces.
Defines the clang::LangOptions interface.
Defines the clang::Preprocessor interface.
CompilerInstance - Helper class for managing a single instance of the Clang compiler.
static bool CreateFromArgs(CompilerInvocation &Res, ArrayRef< const char * > CommandLineArgs, DiagnosticsEngine &Diags, const char *Argv0=nullptr)
Create a compiler invocation from a list of input options.
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Level
The level of the diagnostic, after it has been through mapping.
TestAST(const TestInputs &)
Constructing a TestAST parses the virtual file.
TestAST & operator=(TestAST &&)
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
Top level wrappers for InstallAPI frontend operations.
std::vector< std::string > getCC1ArgsForTesting(TestLanguage Lang)
StringRef getFilenameForTesting(TestLanguage Lang)
@ TU_Complete
The translation unit is a complete translation unit.