1 //===--- Compiler.cpp --------------------------------------------*- C++-*-===// 2 // 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 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Compiler.h" 11 #include "Logger.h" 12 #include "clang/Basic/TargetInfo.h" 13 #include "clang/Lex/PreprocessorOptions.h" 14 #include "llvm/Support/Format.h" 15 #include "llvm/Support/FormatVariadic.h" 16 17 using namespace llvm; 18 namespace clang { 19 namespace clangd { 20 21 void IgnoreDiagnostics::log(DiagnosticsEngine::Level DiagLevel, 22 const clang::Diagnostic &Info) { 23 // FIXME: format lazily, in case vlog is off. 24 SmallString<64> Message; 25 Info.FormatDiagnostic(Message); 26 27 SmallString<64> Location; 28 if (Info.hasSourceManager() && Info.getLocation().isValid()) { 29 auto &SourceMgr = Info.getSourceManager(); 30 auto Loc = SourceMgr.getFileLoc(Info.getLocation()); 31 raw_svector_ostream OS(Location); 32 Loc.print(OS, SourceMgr); 33 OS << ":"; 34 } 35 36 clangd::vlog("Ignored diagnostic. {0}{1}", Location, Message); 37 } 38 39 void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 40 const clang::Diagnostic &Info) { 41 IgnoreDiagnostics::log(DiagLevel, Info); 42 } 43 44 std::unique_ptr<CompilerInstance> prepareCompilerInstance( 45 std::unique_ptr<clang::CompilerInvocation> CI, 46 const PrecompiledPreamble *Preamble, std::unique_ptr<MemoryBuffer> Buffer, 47 std::shared_ptr<PCHContainerOperations> PCHs, 48 IntrusiveRefCntPtr<vfs::FileSystem> VFS, DiagnosticConsumer &DiagsClient) { 49 assert(VFS && "VFS is null"); 50 assert(!CI->getPreprocessorOpts().RetainRemappedFileBuffers && 51 "Setting RetainRemappedFileBuffers to true will cause a memory leak " 52 "of ContentsBuffer"); 53 54 // NOTE: we use Buffer.get() when adding remapped files, so we have to make 55 // sure it will be released if no error is emitted. 56 if (Preamble) { 57 Preamble->OverridePreamble(*CI, VFS, Buffer.get()); 58 } else { 59 CI->getPreprocessorOpts().addRemappedFile( 60 CI->getFrontendOpts().Inputs[0].getFile(), Buffer.get()); 61 } 62 63 auto Clang = llvm::make_unique<CompilerInstance>(PCHs); 64 Clang->setInvocation(std::move(CI)); 65 Clang->createDiagnostics(&DiagsClient, false); 66 67 if (auto VFSWithRemapping = createVFSFromCompilerInvocation( 68 Clang->getInvocation(), Clang->getDiagnostics(), VFS)) 69 VFS = VFSWithRemapping; 70 Clang->setVirtualFileSystem(VFS); 71 72 Clang->setTarget(TargetInfo::CreateTargetInfo( 73 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); 74 if (!Clang->hasTarget()) 75 return nullptr; 76 77 // RemappedFileBuffers will handle the lifetime of the Buffer pointer, 78 // release it. 79 Buffer.release(); 80 return Clang; 81 } 82 83 } // namespace clangd 84 } // namespace clang 85