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 namespace clang { 18 namespace clangd { 19 20 void IgnoreDiagnostics::log(DiagnosticsEngine::Level DiagLevel, 21 const clang::Diagnostic &Info) { 22 // FIXME: format lazily, in case vlog is off. 23 llvm::SmallString<64> Message; 24 Info.FormatDiagnostic(Message); 25 26 llvm::SmallString<64> Location; 27 if (Info.hasSourceManager() && Info.getLocation().isValid()) { 28 auto &SourceMgr = Info.getSourceManager(); 29 auto Loc = SourceMgr.getFileLoc(Info.getLocation()); 30 llvm::raw_svector_ostream OS(Location); 31 Loc.print(OS, SourceMgr); 32 OS << ":"; 33 } 34 35 clangd::vlog("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> 44 prepareCompilerInstance(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) { 50 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) { 58 Preamble->OverridePreamble(*CI, VFS, Buffer.get()); 59 } 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 86