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 "clang/Basic/TargetInfo.h" 12 #include "clang/Lex/PreprocessorOptions.h" 13 14 namespace clang { 15 namespace clangd { 16 17 /// Creates a CompilerInstance from \p CI, with main buffer overriden to \p 18 /// Buffer and arguments to read the PCH from \p Preamble, if \p Preamble is not 19 /// null. Note that vfs::FileSystem inside returned instance may differ from \p 20 /// VFS if additional file remapping were set in command-line arguments. 21 /// On some errors, returns null. When non-null value is returned, it's expected 22 /// to be consumed by the FrontendAction as it will have a pointer to the \p 23 /// Buffer that will only be deleted if BeginSourceFile is called. 24 std::unique_ptr<CompilerInstance> 25 prepareCompilerInstance(std::unique_ptr<clang::CompilerInvocation> CI, 26 const PrecompiledPreamble *Preamble, 27 std::unique_ptr<llvm::MemoryBuffer> Buffer, 28 std::shared_ptr<PCHContainerOperations> PCHs, 29 IntrusiveRefCntPtr<vfs::FileSystem> VFS, 30 DiagnosticConsumer &DiagsClient) { 31 assert(VFS && "VFS is null"); 32 assert(!CI->getPreprocessorOpts().RetainRemappedFileBuffers && 33 "Setting RetainRemappedFileBuffers to true will cause a memory leak " 34 "of ContentsBuffer"); 35 36 // NOTE: we use Buffer.get() when adding remapped files, so we have to make 37 // sure it will be released if no error is emitted. 38 if (Preamble) { 39 Preamble->AddImplicitPreamble(*CI, VFS, Buffer.get()); 40 } else { 41 CI->getPreprocessorOpts().addRemappedFile( 42 CI->getFrontendOpts().Inputs[0].getFile(), Buffer.get()); 43 } 44 45 auto Clang = llvm::make_unique<CompilerInstance>(PCHs); 46 Clang->setInvocation(std::move(CI)); 47 Clang->createDiagnostics(&DiagsClient, false); 48 49 if (auto VFSWithRemapping = createVFSFromCompilerInvocation( 50 Clang->getInvocation(), Clang->getDiagnostics(), VFS)) 51 VFS = VFSWithRemapping; 52 Clang->setVirtualFileSystem(VFS); 53 54 Clang->setTarget(TargetInfo::CreateTargetInfo( 55 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts)); 56 if (!Clang->hasTarget()) 57 return nullptr; 58 59 // RemappedFileBuffers will handle the lifetime of the Buffer pointer, 60 // release it. 61 Buffer.release(); 62 return Clang; 63 } 64 65 } // namespace clangd 66 } // namespace clang 67