15 #include "llvm/ADT/ScopeExit.h"
16 #include "llvm/Support/VirtualFileSystem.h"
18 #include "gtest/gtest.h"
24 class StoreDiagnostics :
public DiagnosticConsumer {
25 std::vector<StoredDiagnostic> &Out;
30 StoreDiagnostics(std::vector<StoredDiagnostic> &Out,
bool ReportErrors)
31 : Out(Out), ReportErrors(ReportErrors) {}
33 void BeginSourceFile(
const LangOptions &LangOpts,
34 const Preprocessor *)
override {
35 this->LangOpts = LangOpts;
39 const Diagnostic &Info)
override {
40 Out.emplace_back(DiagLevel, Info);
43 llvm::raw_string_ostream
OS(
Text);
44 TextDiagnostic Renderer(OS, LangOpts,
45 &Info.getDiags()->getDiagnosticOptions());
46 Renderer.emitStoredDiagnostic(Out.back());
47 ADD_FAILURE() <<
Text;
54 void createMissingComponents(CompilerInstance &Clang) {
55 if (!Clang.hasDiagnostics())
56 Clang.createDiagnostics();
57 if (!Clang.hasFileManager())
58 Clang.createFileManager();
59 if (!Clang.hasSourceManager())
60 Clang.createSourceManager(Clang.getFileManager());
61 if (!Clang.hasTarget())
63 if (!Clang.hasPreprocessor())
65 if (!Clang.hasASTConsumer())
66 Clang.setASTConsumer(std::make_unique<ASTConsumer>());
67 if (!Clang.hasASTContext())
68 Clang.createASTContext();
76 Clang = std::make_unique<CompilerInstance>(
77 std::make_shared<PCHContainerOperations>());
80 auto RecoverFromEarlyExit =
81 llvm::make_scope_exit([&] { createMissingComponents(*Clang); });
84 bool ErrorOK = In.
ErrorOK || llvm::StringRef(In.
Code).contains(
"error-ok");
85 Clang->createDiagnostics(
new StoreDiagnostics(Diagnostics, !ErrorOK));
88 std::vector<const char *> Argv;
90 for (
const auto &S : LangArgs)
91 Argv.push_back(S.c_str());
93 Argv.push_back(S.c_str());
96 Clang->setInvocation(std::make_unique<CompilerInvocation>());
98 Clang->getDiagnostics(),
"clang")) {
99 ADD_FAILURE() <<
"Failed to create invocation";
102 assert(!Clang->getInvocation().getFrontendOpts().DisableFree);
105 auto VFS = llvm::makeIntrusiveRefCnt<llvm::vfs::InMemoryFileSystem>();
107 llvm::MemoryBuffer::getMemBufferCopy(In.
Code,
Filename));
111 llvm::MemoryBuffer::getMemBufferCopy(Extra.getValue(), Extra.getKey()));
112 Clang->createFileManager(VFS);
116 EXPECT_TRUE(Clang->createTarget());
117 Action = std::make_unique<SyntaxOnlyAction>();
119 if (!Action->BeginSourceFile(*Clang, Main)) {
120 ADD_FAILURE() <<
"Failed to BeginSourceFile()";
124 if (
auto Err = Action->Execute())
125 ADD_FAILURE() <<
"Failed to Execute(): " <<
llvm::toString(std::move(Err));
129 Clang->getPreprocessor().EndSourceFile();
131 Clang->getDiagnosticClient().EndSourceFile();
136 void TestAST::clear() {
140 auto PP = Clang->getPreprocessorPtr();
141 Clang->setPreprocessor(
nullptr);
142 Action->EndSourceFile();
152 Action = std::move(M.Action);
153 Clang = std::move(M.Clang);
154 Diagnostics = std::move(M.Diagnostics);