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 SmallString<64> Message; 23 Info.FormatDiagnostic(Message); 24 25 SmallString<64> Location; 26 if (Info.hasSourceManager() && Info.getLocation().isValid()) { 27 auto &SourceMgr = Info.getSourceManager(); 28 auto Loc = SourceMgr.getFileLoc(Info.getLocation()); 29 llvm::raw_svector_ostream OS(Location); 30 Loc.print(OS, SourceMgr); 31 OS << ":"; 32 } 33 34 clangd::log(llvm::formatv("Ignored diagnostic. {0}{1}", Location, Message)); 35 } 36 37 void IgnoreDiagnostics::HandleDiagnostic(DiagnosticsEngine::Level DiagLevel, 38 const clang::Diagnostic &Info) { 39 IgnoreDiagnostics::log(DiagLevel, Info); 40 } 41 42 std::unique_ptr<CompilerInstance> 43 prepareCompilerInstance(std::unique_ptr<clang::CompilerInvocation> CI, 44 const PrecompiledPreamble *Preamble, 45 std::unique_ptr<llvm::MemoryBuffer> Buffer, 46 std::shared_ptr<PCHContainerOperations> PCHs, 47 IntrusiveRefCntPtr<vfs::FileSystem> VFS, 48 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