Skip to content

Commit 11b4c34

Browse files
committed
Revert "[NFC][cling] Add CreateCI to match upstream structure"
This reverts commit 1a2ed14. It introduced a stack-use-after-scope because the Compilation has a reference to the Driver (on the stack). I tried moving back only these two variables and pass CC1Args to CreateCI, but that does not work either because it needs a DiagnosticsEngine. For now I don't see a good way out, so revert this refactoring to solve the concrete issue.
1 parent e928d42 commit 11b4c34

File tree

1 file changed

+45
-67
lines changed

1 file changed

+45
-67
lines changed

interpreter/cling/lib/Interpreter/CIFactory.cpp

Lines changed: 45 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
#include "llvm/Config/llvm-config.h"
4343
#include "llvm/IR/LLVMContext.h"
4444
#include "llvm/Option/ArgList.h"
45-
#include "llvm/Support/Error.h"
4645
#include "llvm/Support/FileSystem.h"
4746
#include "llvm/Support/MemoryBuffer.h"
4847
#include "llvm/Support/Path.h"
@@ -1256,54 +1255,6 @@ namespace {
12561255
}
12571256
}
12581257

1259-
// Goal is to make this as close to the function in
1260-
// clang/lib/Interpreter/Interpreter.cpp taking only clang arguments
1261-
static llvm::Expected<std::unique_ptr<CompilerInstance>>
1262-
CreateCI(const std::vector<const char*>& ClangArgv,
1263-
const std::string& ExeName,
1264-
std::unique_ptr<clang::driver::Compilation>& Compilation) {
1265-
auto InvocationPtr = std::make_shared<clang::CompilerInvocation>();
1266-
1267-
// The compiler invocation is the owner of the diagnostic options.
1268-
// Everything else points to them.
1269-
DiagnosticOptions& DiagOpts = InvocationPtr->getDiagnosticOpts();
1270-
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
1271-
SetupDiagnostics(DiagOpts, ExeName);
1272-
if (!Diags)
1273-
return llvm::createStringError(llvm::errc::not_supported,
1274-
"Could not setup diagnostic engine.");
1275-
1276-
llvm::Triple TheTriple(llvm::sys::getProcessTriple());
1277-
clang::driver::Driver Drvr(ClangArgv[0], TheTriple.getTriple(), *Diags);
1278-
// Drvr.setWarnMissingInput(false);
1279-
Drvr.setCheckInputsExist(false); // think foo.C(12)
1280-
llvm::ArrayRef<const char*> RF(&(ClangArgv[0]), ClangArgv.size());
1281-
Compilation.reset(Drvr.BuildCompilation(RF));
1282-
if (!Compilation)
1283-
return llvm::createStringError(
1284-
llvm::errc::not_supported,
1285-
"Couldn't create clang::driver::Compilation.");
1286-
1287-
const llvm::opt::ArgStringList* CC1Args =
1288-
GetCC1Arguments(Compilation.get());
1289-
if (!CC1Args)
1290-
return llvm::createStringError(llvm::errc::not_supported,
1291-
"Could not get cc1 arguments.");
1292-
1293-
clang::CompilerInvocation::CreateFromArgs(*InvocationPtr, *CC1Args, *Diags);
1294-
// We appreciate the error message about an unknown flag (or do we? if not
1295-
// we should switch to a different DiagEngine for parsing the flags).
1296-
// But in general we'll happily go on.
1297-
Diags->Reset();
1298-
1299-
// Create and setup a compiler instance.
1300-
std::unique_ptr<CompilerInstance> CI(new CompilerInstance());
1301-
CI->setInvocation(InvocationPtr);
1302-
CI->setDiagnostics(Diags.get()); // Diags is ref-counted
1303-
1304-
return CI;
1305-
}
1306-
13071258
static CompilerInstance*
13081259
createCIImpl(std::unique_ptr<llvm::MemoryBuffer> Buffer,
13091260
const CompilerOptions& COpts, const char* LLVMDir,
@@ -1466,27 +1417,53 @@ namespace {
14661417
argvCompile.push_back("<<< cling interactive line includer >>>");
14671418
}
14681419

1420+
auto InvocationPtr = std::make_shared<clang::CompilerInvocation>();
1421+
1422+
// The compiler invocation is the owner of the diagnostic options.
1423+
// Everything else points to them.
1424+
DiagnosticOptions& DiagOpts = InvocationPtr->getDiagnosticOpts();
14691425
// add prefix to diagnostic messages if second compiler instance is existing
14701426
// e.g. in CUDA mode
14711427
std::string ExeName = "";
14721428
if (COpts.CUDAHost)
14731429
ExeName = "cling";
14741430
if (COpts.CUDADevice)
14751431
ExeName = "cling-ptx";
1432+
llvm::IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
1433+
SetupDiagnostics(DiagOpts, ExeName);
1434+
if (!Diags) {
1435+
cling::errs() << "Could not setup diagnostic engine.\n";
1436+
return nullptr;
1437+
}
14761438

1477-
std::unique_ptr<clang::driver::Compilation> Compilation;
1439+
llvm::Triple TheTriple(llvm::sys::getProcessTriple());
1440+
clang::driver::Driver Drvr(argv[0], TheTriple.getTriple(), *Diags);
1441+
//Drvr.setWarnMissingInput(false);
1442+
Drvr.setCheckInputsExist(false); // think foo.C(12)
1443+
llvm::ArrayRef<const char*>RF(&(argvCompile[0]), argvCompile.size());
1444+
std::unique_ptr<clang::driver::Compilation>
1445+
Compilation(Drvr.BuildCompilation(RF));
1446+
if (!Compilation) {
1447+
cling::errs() << "Couldn't create clang::driver::Compilation.\n";
1448+
return nullptr;
1449+
}
14781450

1479-
auto CIOrErr = CreateCI(argvCompile, ExeName, Compilation);
1480-
if (auto Err = CIOrErr.takeError()) {
1481-
llvm::logAllUnhandledErrors(std::move(Err), cling::errs());
1451+
const llvm::opt::ArgStringList* CC1Args = GetCC1Arguments(Compilation.get());
1452+
if (!CC1Args) {
1453+
cling::errs() << "Could not get cc1 arguments.\n";
14821454
return nullptr;
14831455
}
1484-
std::unique_ptr<clang::CompilerInstance> CI = std::move(*CIOrErr);
14851456

1486-
DiagnosticsEngine& Diags = CI->getDiagnostics();
1487-
CompilerInvocation& Invocation = CI->getInvocation();
1488-
DiagnosticOptions& DiagOpts = Invocation.getDiagnosticOpts();
1457+
clang::CompilerInvocation::CreateFromArgs(*InvocationPtr, *CC1Args, *Diags);
1458+
// We appreciate the error message about an unknown flag (or do we? if not
1459+
// we should switch to a different DiagEngine for parsing the flags).
1460+
// But in general we'll happily go on.
1461+
Diags->Reset();
14891462

1463+
// Create and setup a compiler instance.
1464+
std::unique_ptr<CompilerInstance> CI(new CompilerInstance());
1465+
CI->setInvocation(InvocationPtr);
1466+
CI->setDiagnostics(Diags.get()); // Diags is ref-counted
14901467
if (!OnlyLex)
14911468
CI->getDiagnosticOpts().ShowColors =
14921469
llvm::sys::Process::StandardOutIsDisplayed() ||
@@ -1499,9 +1476,9 @@ namespace {
14991476
// Copied from CompilerInstance::createDiagnostics:
15001477
// Chain in -verify checker, if requested.
15011478
if (DiagOpts.VerifyDiagnostics)
1502-
Diags.setClient(new clang::VerifyDiagnosticConsumer(Diags));
1479+
Diags->setClient(new clang::VerifyDiagnosticConsumer(*Diags));
15031480
// Configure our handling of diagnostics.
1504-
ProcessWarningOptions(Diags, DiagOpts);
1481+
ProcessWarningOptions(*Diags, DiagOpts);
15051482

15061483
if (COpts.HasOutput && !OnlyLex) {
15071484
ActionScan scan(clang::driver::Action::PrecompileJobClass,
@@ -1514,13 +1491,14 @@ namespace {
15141491
if (!SetupCompiler(CI.get(), COpts))
15151492
return nullptr;
15161493

1517-
ProcessWarningOptions(Diags, DiagOpts);
1494+
ProcessWarningOptions(*Diags, DiagOpts);
15181495
return CI.release();
15191496
}
15201497

15211498
IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> Overlay =
15221499
new llvm::vfs::OverlayFileSystem(llvm::vfs::getRealFileSystem());
15231500
CI->createFileManager(Overlay);
1501+
clang::CompilerInvocation& Invocation = CI->getInvocation();
15241502
std::string& PCHFile = Invocation.getPreprocessorOpts().ImplicitPCHInclude;
15251503
bool InitLang = true, InitTarget = true;
15261504
if (!PCHFile.empty()) {
@@ -1572,14 +1550,14 @@ namespace {
15721550
// When running interactively pass on the info that the PCH
15731551
// has failed so that IncrmentalParser::Initialize won't try again.
15741552
if (!HasInput && llvm::sys::Process::StandardInIsUserInput()) {
1575-
const unsigned ID =
1576-
Diags.getCustomDiagID(clang::DiagnosticsEngine::Level::Error,
1577-
"Problems loading PCH: '%0'.");
1578-
1579-
Diags.Report(ID) << PCHFile;
1553+
const unsigned ID = Diags->getCustomDiagID(
1554+
clang::DiagnosticsEngine::Level::Error,
1555+
"Problems loading PCH: '%0'.");
1556+
1557+
Diags->Report(ID) << PCHFile;
15801558
// If this was the only error, then don't let it stop anything
1581-
if (Diags.getClient()->getNumErrors() == 1)
1582-
Diags.Reset(true);
1559+
if (Diags->getClient()->getNumErrors() == 1)
1560+
Diags->Reset(true);
15831561
// Clear the include so no one else uses it.
15841562
std::string().swap(PCHFile);
15851563
}

0 commit comments

Comments
 (0)