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