clang: lib/Frontend/ChainedIncludesSource.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

25#include "llvm/Support/MemoryBuffer.h"

26

27using namespace clang;

28

29namespace {

31public:

32 ChainedIncludesSource(std::vector<std::unique_ptr> CIs)

33 : CIs(std::move(CIs)) {}

34

35protected:

36

37

38

39

40

41

43 for (unsigned i = 0, e = CIs.size(); i != e; ++i) {

45 CIs[i]->getASTContext().getExternalSource()) {

46 eSrc->getMemoryBufferSizes(sizes);

47 }

48 }

49 }

50

51private:

52 std::vector<std::unique_ptr> CIs;

53};

54}

55

58 SmallVectorImpl<std::unique_ptrllvm::MemoryBuffer> &MemBufs,

62 std::unique_ptr Reader;

65 {},

66 "", DisableValidationForModuleKind::PCH));

67 for (unsigned ti = 0; ti < bufNames.size(); ++ti) {

68 StringRef sr(bufNames[ti]);

69 Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));

70 }

71 Reader->setDeserializationListener(deserialListener);

75

76 PP.setPredefines(Reader->getSuggestedPredefines());

77 return Reader.release();

78

85 break;

86 }

87 return nullptr;

88}

89

92

94 assert(!includes.empty() && "No '-chain-include' in options!");

95

96 std::vector<std::unique_ptr> CIs;

98

101

102 for (unsigned i = 0, e = includes.size(); i != e; ++i) {

103 bool firstInclude = (i == 0);

104 std::unique_ptr CInvok;

106

107 CInvok->getPreprocessorOpts().ChainedIncludes.clear();

108 CInvok->getPreprocessorOpts().ImplicitPCHInclude.clear();

109 CInvok->getPreprocessorOpts().DisablePCHOrModuleValidation =

110 DisableValidationForModuleKind::PCH;

111 CInvok->getPreprocessorOpts().Includes.clear();

112 CInvok->getPreprocessorOpts().MacroIncludes.clear();

113 CInvok->getPreprocessorOpts().Macros.clear();

114

115 CInvok->getFrontendOpts().Inputs.clear();

117 CInvok->getFrontendOpts().Inputs.push_back(InputFile);

118

124

125 std::unique_ptr Clang(

127 Clang->setInvocation(std::move(CInvok));

128 Clang->setDiagnostics(Diags.get());

130 Clang->getDiagnostics(), Clang->getInvocation().TargetOpts));

131 Clang->createFileManager();

132 Clang->createSourceManager(Clang->getFileManager());

133 Clang->createPreprocessor(TU_Prefix);

134 Clang->getDiagnosticClient().BeginSourceFile(Clang->getLangOpts(),

135 &Clang->getPreprocessor());

136 Clang->createASTContext();

137

138 auto Buffer = std::make_shared();

140 auto consumer = std::make_unique(

141 Clang->getPreprocessor(), Clang->getModuleCache(), "-", "",

142 Buffer, Extensions, true);

143 Clang->getASTContext().setASTMutationListener(

144 consumer->GetASTMutationListener());

145 Clang->setASTConsumer(std::move(consumer));

146 Clang->createSema(TU_Prefix, nullptr);

147

148 if (firstInclude) {

152 } else {

153 assert(!SerialBufs.empty());

155

156

157 for (auto &SB : SerialBufs)

158 Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(SB->getBuffer()));

159 std::string pchName = includes[i-1];

160 llvm::raw_string_ostream os(pchName);

161 os << ".pch" << i-1;

162 serialBufNames.push_back(pchName);

163

166 *Clang, pchName, Bufs, serialBufNames,

167 Clang->getASTConsumer().GetASTDeserializationListener());

168 if (!Reader)

169 return nullptr;

170 Clang->setASTReader(Reader);

171 Clang->getASTContext().setExternalSource(Reader);

172 }

173

174 if (!Clang->InitializeSourceManager(InputFile))

175 return nullptr;

176

178 Clang->getDiagnosticClient().EndSourceFile();

179 assert(Buffer->IsComplete && "serialization did not complete");

180 auto &serialAST = Buffer->Data;

181 SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(

182 StringRef(serialAST.data(), serialAST.size())));

183 serialAST.clear();

184 CIs.push_back(std::move(Clang));

185 }

186

187 assert(!SerialBufs.empty());

188 std::string pchName = includes.back() + ".pch-final";

189 serialBufNames.push_back(pchName);

190 Reader = createASTReader(CI, pchName, SerialBufs, serialBufNames);

191 if (!Reader)

192 return nullptr;

193

194 auto ChainedSrc =

195 llvm::makeIntrusiveRefCnt(std::move(CIs));

196 return llvm::makeIntrusiveRefCnt(

197 ChainedSrc.get(), Reader.get());

198}

Defines enum values for all the target-independent builtin functions.

static ASTReader * createASTReader(CompilerInstance &CI, StringRef pchFile, SmallVectorImpl< std::unique_ptr< llvm::MemoryBuffer > > &MemBufs, SmallVectorImpl< std::string > &bufNames, ASTDeserializationListener *deserialListener=nullptr)

Defines the clang::Preprocessor interface.

Reads an AST files chain containing the contents of a translation unit.

@ ARR_None

The client can't handle any AST loading failures.

@ Success

The control block was read successfully.

@ ConfigurationMismatch

The AST file was written with a different language/target configuration.

@ OutOfDate

The AST file is out-of-date relative to its input files, and needs to be regenerated.

@ Failure

The AST file itself appears corrupted.

@ VersionMismatch

The AST file was written by a different version of Clang.

@ HadErrors

The AST file has errors.

@ Missing

The AST file was missing.

void initializeBuiltins(IdentifierTable &Table, const LangOptions &LangOpts)

Mark the identifiers for all the builtins with their appropriate builtin ID # and mark any non-portab...

CompilerInstance - Helper class for managing a single instance of the Clang compiler.

const PCHContainerReader & getPCHContainerReader() const

Return the appropriate PCHContainerReader depending on the current CodeGenOptions.

InMemoryModuleCache & getModuleCache() const

Preprocessor & getPreprocessor() const

Return the current preprocessor.

ASTContext & getASTContext() const

FrontendOptions & getFrontendOpts()

CompilerInvocation & getInvocation()

PreprocessorOptions & getPreprocessorOpts()

std::shared_ptr< PCHContainerOperations > getPCHContainerOperations() const

DiagnosticOptions & getDiagnosticOpts()

Helper class for holding the data necessary to invoke the compiler.

Used for handling and querying diagnostic IDs.

Options for controlling the compiler diagnostics engine.

Concrete class used by the front-end to report problems and issues.

Abstract interface for external sources of AST nodes.

MemoryBufferSizes getMemoryBufferSizes() const

Return the amount of memory used by memory buffers, breaking down by heap-backed versus mmap'ed memor...

An abstract interface that should be implemented by external AST sources that also provide informatio...

An input file for the front end.

SmallVector< FrontendInputFile, 0 > Inputs

The input files and their types.

The kind of a file that we've been handed as an input.

std::vector< std::string > ChainedIncludes

Headers that will be converted to chained PCHs in memory.

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

void setPredefines(std::string P)

Set the predefines for this Preprocessor.

IdentifierTable & getIdentifierTable()

Builtin::Context & getBuiltinInfo()

const LangOptions & getLangOpts() const

Encodes a location in the source.

static TargetInfo * CreateTargetInfo(DiagnosticsEngine &Diags, const std::shared_ptr< TargetOptions > &Opts)

Construct a target for the given options.

Defines the clang::TargetInfo interface.

@ MK_PCH

File is a PCH file treated as such.

The JSON file list parser is used to communicate input to InstallAPI.

void ParseAST(Preprocessor &pp, ASTConsumer *C, ASTContext &Ctx, bool PrintStats=false, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr, bool SkipFunctionBodies=false)

Parse the entire file specified, notifying the ASTConsumer as the file is parsed.

IntrusiveRefCntPtr< ExternalSemaSource > createChainedIncludesSource(CompilerInstance &CI, IntrusiveRefCntPtr< ExternalSemaSource > &Reader)

The ChainedIncludesSource class converts headers to chained PCHs in memory, mainly for testing.

@ TU_Prefix

The translation unit is a prefix to a translation unit, and is not complete.