blob: c94ef75522e0c8d08b300c6fd65206a32f2399c1 [file] [log] [blame]
Kirill Bobyrev8e35f1e2018-08-14 16:03:32 +00001//===--- Compiler.cpp --------------------------------------------*- C++-*-===//
Sam McCall98775c52017-12-04 13:49:59 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
Kirill Bobyrev8e35f1e2018-08-14 16:03:32 +00008//===----------------------------------------------------------------------===//
Eric Liub99d5e82017-12-14 21:22:03 +00009
Sam McCall98775c52017-12-04 13:49:59 +000010#include "Compiler.h"
Ilya Biryukov2d4cdac2018-02-12 12:48:51 +000011#include "Logger.h"
Sam McCall98775c52017-12-04 13:49:59 +000012#include "clang/Basic/TargetInfo.h"
13#include "clang/Lex/PreprocessorOptions.h"
Ilya Biryukov2d4cdac2018-02-12 12:48:51 +000014#include "llvm/Support/Format.h"
15#include "llvm/Support/FormatVariadic.h"
Sam McCall98775c52017-12-04 13:49:59 +000016
17namespace clang {
18namespace clangd {
19
Ilya Biryukov2d4cdac2018-02-12 12:48:51 +000020void IgnoreDiagnostics::log(DiagnosticsEngine::Level DiagLevel,
21 const clang::Diagnostic &Info) {
Sam McCall3fd25fc2018-11-02 12:51:26 +000022 // FIXME: format lazily, in case vlog is off.
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000023 llvm::SmallString<64> Message;
Ilya Biryukov2d4cdac2018-02-12 12:48:51 +000024 Info.FormatDiagnostic(Message);
25
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000026 llvm::SmallString<64> Location;
Ilya Biryukov2d4cdac2018-02-12 12:48:51 +000027 if (Info.hasSourceManager() && Info.getLocation().isValid()) {
28 auto &SourceMgr = Info.getSourceManager();
29 auto Loc = SourceMgr.getFileLoc(Info.getLocation());
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000030 llvm::raw_svector_ostream OS(Location);
Ilya Biryukov2d4cdac2018-02-12 12:48:51 +000031 Loc.print(OS, SourceMgr);
32 OS << ":";
33 }
34
Sam McCall3fd25fc2018-11-02 12:51:26 +000035 clangd::vlog("Ignored diagnostic. {0}{1}", Location, Message);
Ilya Biryukov2d4cdac2018-02-12 12:48:51 +000036}
37
38void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel,
39 const clang::Diagnostic &Info) {
40 IgnoreDiagnostics::log(DiagLevel, Info);
41}
42
Ilya Biryukovf2001aa2019-01-07 15:45:19 +000043std::unique_ptr<CompilerInstance>
44prepareCompilerInstance(std::unique_ptr<clang::CompilerInvocation> CI,
45 const PrecompiledPreamble *Preamble,
46 std::unique_ptr<llvm::MemoryBuffer> Buffer,
47 std::shared_ptr<PCHContainerOperations> PCHs,
48 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
49 DiagnosticConsumer &DiagsClient) {
Sam McCall98775c52017-12-04 13:49:59 +000050 assert(VFS && "VFS is null");
51 assert(!CI->getPreprocessorOpts().RetainRemappedFileBuffers &&
52 "Setting RetainRemappedFileBuffers to true will cause a memory leak "
53 "of ContentsBuffer");
54
55 // NOTE: we use Buffer.get() when adding remapped files, so we have to make
56 // sure it will be released if no error is emitted.
57 if (Preamble) {
Ilya Biryukov295c8e12018-01-18 15:17:00 +000058 Preamble->OverridePreamble(*CI, VFS, Buffer.get());
Sam McCall98775c52017-12-04 13:49:59 +000059 } else {
60 CI->getPreprocessorOpts().addRemappedFile(
61 CI->getFrontendOpts().Inputs[0].getFile(), Buffer.get());
62 }
63
64 auto Clang = llvm::make_unique<CompilerInstance>(PCHs);
65 Clang->setInvocation(std::move(CI));
66 Clang->createDiagnostics(&DiagsClient, false);
67
68 if (auto VFSWithRemapping = createVFSFromCompilerInvocation(
69 Clang->getInvocation(), Clang->getDiagnostics(), VFS))
70 VFS = VFSWithRemapping;
71 Clang->setVirtualFileSystem(VFS);
72
73 Clang->setTarget(TargetInfo::CreateTargetInfo(
74 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));
75 if (!Clang->hasTarget())
76 return nullptr;
77
78 // RemappedFileBuffers will handle the lifetime of the Buffer pointer,
79 // release it.
80 Buffer.release();
81 return Clang;
82}
83
84} // namespace clangd
85} // namespace clang