1*d64eccf4SChuanqi Xu //===--- ObjectFilePCHContainerReader.cpp ---------------------------------===// 2*d64eccf4SChuanqi Xu // 3*d64eccf4SChuanqi Xu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*d64eccf4SChuanqi Xu // See https://llvm.org/LICENSE.txt for license information. 5*d64eccf4SChuanqi Xu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*d64eccf4SChuanqi Xu // 7*d64eccf4SChuanqi Xu //===----------------------------------------------------------------------===// 8*d64eccf4SChuanqi Xu 9*d64eccf4SChuanqi Xu #include "clang/Serialization/ObjectFilePCHContainerReader.h" 10*d64eccf4SChuanqi Xu #include "llvm/Object/COFF.h" 11*d64eccf4SChuanqi Xu #include "llvm/Object/ObjectFile.h" 12*d64eccf4SChuanqi Xu 13*d64eccf4SChuanqi Xu using namespace clang; 14*d64eccf4SChuanqi Xu 15*d64eccf4SChuanqi Xu ArrayRef<StringRef> ObjectFilePCHContainerReader::getFormats() const { 16*d64eccf4SChuanqi Xu static StringRef Formats[] = {"obj", "raw"}; 17*d64eccf4SChuanqi Xu return Formats; 18*d64eccf4SChuanqi Xu } 19*d64eccf4SChuanqi Xu 20*d64eccf4SChuanqi Xu StringRef 21*d64eccf4SChuanqi Xu ObjectFilePCHContainerReader::ExtractPCH(llvm::MemoryBufferRef Buffer) const { 22*d64eccf4SChuanqi Xu StringRef PCH; 23*d64eccf4SChuanqi Xu auto OFOrErr = llvm::object::ObjectFile::createObjectFile(Buffer); 24*d64eccf4SChuanqi Xu if (OFOrErr) { 25*d64eccf4SChuanqi Xu auto &OF = OFOrErr.get(); 26*d64eccf4SChuanqi Xu bool IsCOFF = isa<llvm::object::COFFObjectFile>(*OF); 27*d64eccf4SChuanqi Xu // Find the clang AST section in the container. 28*d64eccf4SChuanqi Xu for (auto &Section : OF->sections()) { 29*d64eccf4SChuanqi Xu StringRef Name; 30*d64eccf4SChuanqi Xu if (Expected<StringRef> NameOrErr = Section.getName()) 31*d64eccf4SChuanqi Xu Name = *NameOrErr; 32*d64eccf4SChuanqi Xu else 33*d64eccf4SChuanqi Xu consumeError(NameOrErr.takeError()); 34*d64eccf4SChuanqi Xu 35*d64eccf4SChuanqi Xu if ((!IsCOFF && Name == "__clangast") || (IsCOFF && Name == "clangast")) { 36*d64eccf4SChuanqi Xu if (Expected<StringRef> E = Section.getContents()) 37*d64eccf4SChuanqi Xu return *E; 38*d64eccf4SChuanqi Xu else { 39*d64eccf4SChuanqi Xu handleAllErrors(E.takeError(), [&](const llvm::ErrorInfoBase &EIB) { 40*d64eccf4SChuanqi Xu EIB.log(llvm::errs()); 41*d64eccf4SChuanqi Xu }); 42*d64eccf4SChuanqi Xu return ""; 43*d64eccf4SChuanqi Xu } 44*d64eccf4SChuanqi Xu } 45*d64eccf4SChuanqi Xu } 46*d64eccf4SChuanqi Xu } 47*d64eccf4SChuanqi Xu handleAllErrors(OFOrErr.takeError(), [&](const llvm::ErrorInfoBase &EIB) { 48*d64eccf4SChuanqi Xu if (EIB.convertToErrorCode() == 49*d64eccf4SChuanqi Xu llvm::object::object_error::invalid_file_type) 50*d64eccf4SChuanqi Xu // As a fallback, treat the buffer as a raw AST. 51*d64eccf4SChuanqi Xu PCH = Buffer.getBuffer(); 52*d64eccf4SChuanqi Xu else 53*d64eccf4SChuanqi Xu EIB.log(llvm::errs()); 54*d64eccf4SChuanqi Xu }); 55*d64eccf4SChuanqi Xu return PCH; 56*d64eccf4SChuanqi Xu } 57