xref: /llvm-project/clang/lib/Serialization/ObjectFilePCHContainerReader.cpp (revision d64eccf4335e99360132b724d060d704892fbb02)
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