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