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

42 void getMemoryBufferSizes(MemoryBufferSizes &sizes) const override {

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

44 if (const ExternalASTSource *eSrc =

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 auto Reader = llvm::makeIntrusiveRefCnt(

65 ArrayRef<std::shared_ptr>(),

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;

78

85 break;

86 }

87 return nullptr;

88}

89

93

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

96

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

99

102

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

104 bool firstInclude = (i == 0);

105 std::unique_ptr CInvok;

107

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

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

110 CInvok->getPreprocessorOpts().DisablePCHOrModuleValidation =

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

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

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

115

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

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

119

122 auto Diags = llvm::makeIntrusiveRefCnt(

124

125 auto Clang = std::make_unique(

127 Clang->createVirtualFileSystem();

128 Clang->setDiagnostics(Diags);

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

131 Clang->createFileManager();

132 Clang->createSourceManager();

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, Clang->getCodeGenOpts(), Extensions,

143 true);

144 Clang->getASTContext().setASTMutationListener(

145 consumer->GetASTMutationListener());

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

147 Clang->createSema(TU_Prefix, nullptr);

148

149 if (firstInclude) {

153 } else {

154 assert(!SerialBufs.empty());

156

157

158 for (auto &SB : SerialBufs)

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

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

161 llvm::raw_string_ostream os(pchName);

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

163 serialBufNames.push_back(pchName);

164

167 *Clang, pchName, Bufs, serialBufNames,

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

169 if (!Reader)

170 return nullptr;

171 Clang->setASTReader(Reader);

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

173 }

174

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

176 return nullptr;

177

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

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

181 auto &serialAST = Buffer->Data;

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

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

184 serialAST.clear();

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

186 }

187

188 assert(!SerialBufs.empty());

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

190 serialBufNames.push_back(pchName);

191 OutReader = createASTReader(CI, pchName, SerialBufs, serialBufNames);

192 if (!OutReader)

193 return nullptr;

194

195 auto ChainedSrc =

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

197 return llvm::makeIntrusiveRefCnt(

198 std::move(ChainedSrc), OutReader);

199}

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

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

Definition ChainedIncludesSource.cpp:57

Defines the clang::Preprocessor interface.

@ 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.

ModuleCache & 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()

CodeGenOptions & getCodeGenOpts()

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

static llvm::IntrusiveRefCntPtr< DiagnosticIDs > create()

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, 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< ASTReader > &OutReader)

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

Definition ChainedIncludesSource.cpp:91

@ TU_Prefix

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

@ PCH

Disable validation for a precompiled header and the modules it depends on.