1*67e74705SXin Li //===--- FrontendActions.cpp ----------------------------------------------===//
2*67e74705SXin Li //
3*67e74705SXin Li // The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li
10*67e74705SXin Li #include "clang/Frontend/FrontendActions.h"
11*67e74705SXin Li #include "clang/AST/ASTConsumer.h"
12*67e74705SXin Li #include "clang/Basic/FileManager.h"
13*67e74705SXin Li #include "clang/Frontend/ASTConsumers.h"
14*67e74705SXin Li #include "clang/Frontend/ASTUnit.h"
15*67e74705SXin Li #include "clang/Frontend/CompilerInstance.h"
16*67e74705SXin Li #include "clang/Frontend/FrontendDiagnostic.h"
17*67e74705SXin Li #include "clang/Frontend/MultiplexConsumer.h"
18*67e74705SXin Li #include "clang/Frontend/Utils.h"
19*67e74705SXin Li #include "clang/Lex/HeaderSearch.h"
20*67e74705SXin Li #include "clang/Lex/Pragma.h"
21*67e74705SXin Li #include "clang/Lex/Preprocessor.h"
22*67e74705SXin Li #include "clang/Parse/Parser.h"
23*67e74705SXin Li #include "clang/Serialization/ASTReader.h"
24*67e74705SXin Li #include "clang/Serialization/ASTWriter.h"
25*67e74705SXin Li #include "llvm/Support/FileSystem.h"
26*67e74705SXin Li #include "llvm/Support/MemoryBuffer.h"
27*67e74705SXin Li #include "llvm/Support/raw_ostream.h"
28*67e74705SXin Li #include <memory>
29*67e74705SXin Li #include <system_error>
30*67e74705SXin Li
31*67e74705SXin Li using namespace clang;
32*67e74705SXin Li
33*67e74705SXin Li //===----------------------------------------------------------------------===//
34*67e74705SXin Li // Custom Actions
35*67e74705SXin Li //===----------------------------------------------------------------------===//
36*67e74705SXin Li
37*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)38*67e74705SXin Li InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
39*67e74705SXin Li return llvm::make_unique<ASTConsumer>();
40*67e74705SXin Li }
41*67e74705SXin Li
ExecuteAction()42*67e74705SXin Li void InitOnlyAction::ExecuteAction() {
43*67e74705SXin Li }
44*67e74705SXin Li
45*67e74705SXin Li //===----------------------------------------------------------------------===//
46*67e74705SXin Li // AST Consumer Actions
47*67e74705SXin Li //===----------------------------------------------------------------------===//
48*67e74705SXin Li
49*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)50*67e74705SXin Li ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
51*67e74705SXin Li if (raw_ostream *OS = CI.createDefaultOutputFile(false, InFile))
52*67e74705SXin Li return CreateASTPrinter(OS, CI.getFrontendOpts().ASTDumpFilter);
53*67e74705SXin Li return nullptr;
54*67e74705SXin Li }
55*67e74705SXin Li
56*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)57*67e74705SXin Li ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
58*67e74705SXin Li return CreateASTDumper(CI.getFrontendOpts().ASTDumpFilter,
59*67e74705SXin Li CI.getFrontendOpts().ASTDumpDecls,
60*67e74705SXin Li CI.getFrontendOpts().ASTDumpLookups);
61*67e74705SXin Li }
62*67e74705SXin Li
63*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)64*67e74705SXin Li ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
65*67e74705SXin Li return CreateASTDeclNodeLister();
66*67e74705SXin Li }
67*67e74705SXin Li
68*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)69*67e74705SXin Li ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
70*67e74705SXin Li return CreateASTViewer();
71*67e74705SXin Li }
72*67e74705SXin Li
73*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)74*67e74705SXin Li DeclContextPrintAction::CreateASTConsumer(CompilerInstance &CI,
75*67e74705SXin Li StringRef InFile) {
76*67e74705SXin Li return CreateDeclContextPrinter();
77*67e74705SXin Li }
78*67e74705SXin Li
79*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)80*67e74705SXin Li GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
81*67e74705SXin Li std::string Sysroot;
82*67e74705SXin Li std::string OutputFile;
83*67e74705SXin Li raw_pwrite_stream *OS =
84*67e74705SXin Li ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
85*67e74705SXin Li if (!OS)
86*67e74705SXin Li return nullptr;
87*67e74705SXin Li
88*67e74705SXin Li if (!CI.getFrontendOpts().RelocatablePCH)
89*67e74705SXin Li Sysroot.clear();
90*67e74705SXin Li
91*67e74705SXin Li auto Buffer = std::make_shared<PCHBuffer>();
92*67e74705SXin Li std::vector<std::unique_ptr<ASTConsumer>> Consumers;
93*67e74705SXin Li Consumers.push_back(llvm::make_unique<PCHGenerator>(
94*67e74705SXin Li CI.getPreprocessor(), OutputFile, nullptr, Sysroot,
95*67e74705SXin Li Buffer, CI.getFrontendOpts().ModuleFileExtensions,
96*67e74705SXin Li /*AllowASTWithErrors*/false,
97*67e74705SXin Li /*IncludeTimestamps*/
98*67e74705SXin Li +CI.getFrontendOpts().IncludeTimestamps));
99*67e74705SXin Li Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
100*67e74705SXin Li CI, InFile, OutputFile, OS, Buffer));
101*67e74705SXin Li
102*67e74705SXin Li return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
103*67e74705SXin Li }
104*67e74705SXin Li
ComputeASTConsumerArguments(CompilerInstance & CI,StringRef InFile,std::string & Sysroot,std::string & OutputFile)105*67e74705SXin Li raw_pwrite_stream *GeneratePCHAction::ComputeASTConsumerArguments(
106*67e74705SXin Li CompilerInstance &CI, StringRef InFile, std::string &Sysroot,
107*67e74705SXin Li std::string &OutputFile) {
108*67e74705SXin Li Sysroot = CI.getHeaderSearchOpts().Sysroot;
109*67e74705SXin Li if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
110*67e74705SXin Li CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
111*67e74705SXin Li return nullptr;
112*67e74705SXin Li }
113*67e74705SXin Li
114*67e74705SXin Li // We use createOutputFile here because this is exposed via libclang, and we
115*67e74705SXin Li // must disable the RemoveFileOnSignal behavior.
116*67e74705SXin Li // We use a temporary to avoid race conditions.
117*67e74705SXin Li raw_pwrite_stream *OS =
118*67e74705SXin Li CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
119*67e74705SXin Li /*RemoveFileOnSignal=*/false, InFile,
120*67e74705SXin Li /*Extension=*/"", /*useTemporary=*/true);
121*67e74705SXin Li if (!OS)
122*67e74705SXin Li return nullptr;
123*67e74705SXin Li
124*67e74705SXin Li OutputFile = CI.getFrontendOpts().OutputFile;
125*67e74705SXin Li return OS;
126*67e74705SXin Li }
127*67e74705SXin Li
128*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)129*67e74705SXin Li GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
130*67e74705SXin Li StringRef InFile) {
131*67e74705SXin Li std::string Sysroot;
132*67e74705SXin Li std::string OutputFile;
133*67e74705SXin Li raw_pwrite_stream *OS =
134*67e74705SXin Li ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
135*67e74705SXin Li if (!OS)
136*67e74705SXin Li return nullptr;
137*67e74705SXin Li
138*67e74705SXin Li auto Buffer = std::make_shared<PCHBuffer>();
139*67e74705SXin Li std::vector<std::unique_ptr<ASTConsumer>> Consumers;
140*67e74705SXin Li
141*67e74705SXin Li Consumers.push_back(llvm::make_unique<PCHGenerator>(
142*67e74705SXin Li CI.getPreprocessor(), OutputFile, Module, Sysroot,
143*67e74705SXin Li Buffer, CI.getFrontendOpts().ModuleFileExtensions,
144*67e74705SXin Li /*AllowASTWithErrors=*/false,
145*67e74705SXin Li /*IncludeTimestamps=*/
146*67e74705SXin Li +CI.getFrontendOpts().BuildingImplicitModule));
147*67e74705SXin Li Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
148*67e74705SXin Li CI, InFile, OutputFile, OS, Buffer));
149*67e74705SXin Li return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
150*67e74705SXin Li }
151*67e74705SXin Li
152*67e74705SXin Li static SmallVectorImpl<char> &
operator +=(SmallVectorImpl<char> & Includes,StringRef RHS)153*67e74705SXin Li operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
154*67e74705SXin Li Includes.append(RHS.begin(), RHS.end());
155*67e74705SXin Li return Includes;
156*67e74705SXin Li }
157*67e74705SXin Li
addHeaderInclude(StringRef HeaderName,SmallVectorImpl<char> & Includes,const LangOptions & LangOpts,bool IsExternC)158*67e74705SXin Li static void addHeaderInclude(StringRef HeaderName,
159*67e74705SXin Li SmallVectorImpl<char> &Includes,
160*67e74705SXin Li const LangOptions &LangOpts,
161*67e74705SXin Li bool IsExternC) {
162*67e74705SXin Li if (IsExternC && LangOpts.CPlusPlus)
163*67e74705SXin Li Includes += "extern \"C\" {\n";
164*67e74705SXin Li if (LangOpts.ObjC1)
165*67e74705SXin Li Includes += "#import \"";
166*67e74705SXin Li else
167*67e74705SXin Li Includes += "#include \"";
168*67e74705SXin Li
169*67e74705SXin Li Includes += HeaderName;
170*67e74705SXin Li
171*67e74705SXin Li Includes += "\"\n";
172*67e74705SXin Li if (IsExternC && LangOpts.CPlusPlus)
173*67e74705SXin Li Includes += "}\n";
174*67e74705SXin Li }
175*67e74705SXin Li
176*67e74705SXin Li /// \brief Collect the set of header includes needed to construct the given
177*67e74705SXin Li /// module and update the TopHeaders file set of the module.
178*67e74705SXin Li ///
179*67e74705SXin Li /// \param Module The module we're collecting includes from.
180*67e74705SXin Li ///
181*67e74705SXin Li /// \param Includes Will be augmented with the set of \#includes or \#imports
182*67e74705SXin Li /// needed to load all of the named headers.
183*67e74705SXin Li static std::error_code
collectModuleHeaderIncludes(const LangOptions & LangOpts,FileManager & FileMgr,ModuleMap & ModMap,clang::Module * Module,SmallVectorImpl<char> & Includes)184*67e74705SXin Li collectModuleHeaderIncludes(const LangOptions &LangOpts, FileManager &FileMgr,
185*67e74705SXin Li ModuleMap &ModMap, clang::Module *Module,
186*67e74705SXin Li SmallVectorImpl<char> &Includes) {
187*67e74705SXin Li // Don't collect any headers for unavailable modules.
188*67e74705SXin Li if (!Module->isAvailable())
189*67e74705SXin Li return std::error_code();
190*67e74705SXin Li
191*67e74705SXin Li // Add includes for each of these headers.
192*67e74705SXin Li for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
193*67e74705SXin Li for (Module::Header &H : Module->Headers[HK]) {
194*67e74705SXin Li Module->addTopHeader(H.Entry);
195*67e74705SXin Li // Use the path as specified in the module map file. We'll look for this
196*67e74705SXin Li // file relative to the module build directory (the directory containing
197*67e74705SXin Li // the module map file) so this will find the same file that we found
198*67e74705SXin Li // while parsing the module map.
199*67e74705SXin Li addHeaderInclude(H.NameAsWritten, Includes, LangOpts, Module->IsExternC);
200*67e74705SXin Li }
201*67e74705SXin Li }
202*67e74705SXin Li // Note that Module->PrivateHeaders will not be a TopHeader.
203*67e74705SXin Li
204*67e74705SXin Li if (Module::Header UmbrellaHeader = Module->getUmbrellaHeader()) {
205*67e74705SXin Li Module->addTopHeader(UmbrellaHeader.Entry);
206*67e74705SXin Li if (Module->Parent)
207*67e74705SXin Li // Include the umbrella header for submodules.
208*67e74705SXin Li addHeaderInclude(UmbrellaHeader.NameAsWritten, Includes, LangOpts,
209*67e74705SXin Li Module->IsExternC);
210*67e74705SXin Li } else if (Module::DirectoryName UmbrellaDir = Module->getUmbrellaDir()) {
211*67e74705SXin Li // Add all of the headers we find in this subdirectory.
212*67e74705SXin Li std::error_code EC;
213*67e74705SXin Li SmallString<128> DirNative;
214*67e74705SXin Li llvm::sys::path::native(UmbrellaDir.Entry->getName(), DirNative);
215*67e74705SXin Li
216*67e74705SXin Li vfs::FileSystem &FS = *FileMgr.getVirtualFileSystem();
217*67e74705SXin Li for (vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
218*67e74705SXin Li Dir != End && !EC; Dir.increment(EC)) {
219*67e74705SXin Li // Check whether this entry has an extension typically associated with
220*67e74705SXin Li // headers.
221*67e74705SXin Li if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->getName()))
222*67e74705SXin Li .Cases(".h", ".H", ".hh", ".hpp", true)
223*67e74705SXin Li .Default(false))
224*67e74705SXin Li continue;
225*67e74705SXin Li
226*67e74705SXin Li const FileEntry *Header = FileMgr.getFile(Dir->getName());
227*67e74705SXin Li // FIXME: This shouldn't happen unless there is a file system race. Is
228*67e74705SXin Li // that worth diagnosing?
229*67e74705SXin Li if (!Header)
230*67e74705SXin Li continue;
231*67e74705SXin Li
232*67e74705SXin Li // If this header is marked 'unavailable' in this module, don't include
233*67e74705SXin Li // it.
234*67e74705SXin Li if (ModMap.isHeaderUnavailableInModule(Header, Module))
235*67e74705SXin Li continue;
236*67e74705SXin Li
237*67e74705SXin Li // Compute the relative path from the directory to this file.
238*67e74705SXin Li SmallVector<StringRef, 16> Components;
239*67e74705SXin Li auto PathIt = llvm::sys::path::rbegin(Dir->getName());
240*67e74705SXin Li for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
241*67e74705SXin Li Components.push_back(*PathIt);
242*67e74705SXin Li SmallString<128> RelativeHeader(UmbrellaDir.NameAsWritten);
243*67e74705SXin Li for (auto It = Components.rbegin(), End = Components.rend(); It != End;
244*67e74705SXin Li ++It)
245*67e74705SXin Li llvm::sys::path::append(RelativeHeader, *It);
246*67e74705SXin Li
247*67e74705SXin Li // Include this header as part of the umbrella directory.
248*67e74705SXin Li Module->addTopHeader(Header);
249*67e74705SXin Li addHeaderInclude(RelativeHeader, Includes, LangOpts, Module->IsExternC);
250*67e74705SXin Li }
251*67e74705SXin Li
252*67e74705SXin Li if (EC)
253*67e74705SXin Li return EC;
254*67e74705SXin Li }
255*67e74705SXin Li
256*67e74705SXin Li // Recurse into submodules.
257*67e74705SXin Li for (clang::Module::submodule_iterator Sub = Module->submodule_begin(),
258*67e74705SXin Li SubEnd = Module->submodule_end();
259*67e74705SXin Li Sub != SubEnd; ++Sub)
260*67e74705SXin Li if (std::error_code Err = collectModuleHeaderIncludes(
261*67e74705SXin Li LangOpts, FileMgr, ModMap, *Sub, Includes))
262*67e74705SXin Li return Err;
263*67e74705SXin Li
264*67e74705SXin Li return std::error_code();
265*67e74705SXin Li }
266*67e74705SXin Li
BeginSourceFileAction(CompilerInstance & CI,StringRef Filename)267*67e74705SXin Li bool GenerateModuleAction::BeginSourceFileAction(CompilerInstance &CI,
268*67e74705SXin Li StringRef Filename) {
269*67e74705SXin Li CI.getLangOpts().CompilingModule = true;
270*67e74705SXin Li
271*67e74705SXin Li // Find the module map file.
272*67e74705SXin Li const FileEntry *ModuleMap =
273*67e74705SXin Li CI.getFileManager().getFile(Filename, /*openFile*/true);
274*67e74705SXin Li if (!ModuleMap) {
275*67e74705SXin Li CI.getDiagnostics().Report(diag::err_module_map_not_found)
276*67e74705SXin Li << Filename;
277*67e74705SXin Li return false;
278*67e74705SXin Li }
279*67e74705SXin Li
280*67e74705SXin Li // Set up embedding for any specified files. Do this before we load any
281*67e74705SXin Li // source files, including the primary module map for the compilation.
282*67e74705SXin Li for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
283*67e74705SXin Li if (const auto *FE = CI.getFileManager().getFile(F, /*openFile*/true))
284*67e74705SXin Li CI.getSourceManager().setFileIsTransient(FE);
285*67e74705SXin Li else
286*67e74705SXin Li CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
287*67e74705SXin Li }
288*67e74705SXin Li if (CI.getFrontendOpts().ModulesEmbedAllFiles)
289*67e74705SXin Li CI.getSourceManager().setAllFilesAreTransient(true);
290*67e74705SXin Li
291*67e74705SXin Li // Parse the module map file.
292*67e74705SXin Li HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
293*67e74705SXin Li if (HS.loadModuleMapFile(ModuleMap, IsSystem))
294*67e74705SXin Li return false;
295*67e74705SXin Li
296*67e74705SXin Li if (CI.getLangOpts().CurrentModule.empty()) {
297*67e74705SXin Li CI.getDiagnostics().Report(diag::err_missing_module_name);
298*67e74705SXin Li
299*67e74705SXin Li // FIXME: Eventually, we could consider asking whether there was just
300*67e74705SXin Li // a single module described in the module map, and use that as a
301*67e74705SXin Li // default. Then it would be fairly trivial to just "compile" a module
302*67e74705SXin Li // map with a single module (the common case).
303*67e74705SXin Li return false;
304*67e74705SXin Li }
305*67e74705SXin Li
306*67e74705SXin Li // If we're being run from the command-line, the module build stack will not
307*67e74705SXin Li // have been filled in yet, so complete it now in order to allow us to detect
308*67e74705SXin Li // module cycles.
309*67e74705SXin Li SourceManager &SourceMgr = CI.getSourceManager();
310*67e74705SXin Li if (SourceMgr.getModuleBuildStack().empty())
311*67e74705SXin Li SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
312*67e74705SXin Li FullSourceLoc(SourceLocation(), SourceMgr));
313*67e74705SXin Li
314*67e74705SXin Li // Dig out the module definition.
315*67e74705SXin Li Module = HS.lookupModule(CI.getLangOpts().CurrentModule,
316*67e74705SXin Li /*AllowSearch=*/false);
317*67e74705SXin Li if (!Module) {
318*67e74705SXin Li CI.getDiagnostics().Report(diag::err_missing_module)
319*67e74705SXin Li << CI.getLangOpts().CurrentModule << Filename;
320*67e74705SXin Li
321*67e74705SXin Li return false;
322*67e74705SXin Li }
323*67e74705SXin Li
324*67e74705SXin Li // Check whether we can build this module at all.
325*67e74705SXin Li clang::Module::Requirement Requirement;
326*67e74705SXin Li clang::Module::UnresolvedHeaderDirective MissingHeader;
327*67e74705SXin Li if (!Module->isAvailable(CI.getLangOpts(), CI.getTarget(), Requirement,
328*67e74705SXin Li MissingHeader)) {
329*67e74705SXin Li if (MissingHeader.FileNameLoc.isValid()) {
330*67e74705SXin Li CI.getDiagnostics().Report(MissingHeader.FileNameLoc,
331*67e74705SXin Li diag::err_module_header_missing)
332*67e74705SXin Li << MissingHeader.IsUmbrella << MissingHeader.FileName;
333*67e74705SXin Li } else {
334*67e74705SXin Li CI.getDiagnostics().Report(diag::err_module_unavailable)
335*67e74705SXin Li << Module->getFullModuleName()
336*67e74705SXin Li << Requirement.second << Requirement.first;
337*67e74705SXin Li }
338*67e74705SXin Li
339*67e74705SXin Li return false;
340*67e74705SXin Li }
341*67e74705SXin Li
342*67e74705SXin Li if (ModuleMapForUniquing && ModuleMapForUniquing != ModuleMap) {
343*67e74705SXin Li Module->IsInferred = true;
344*67e74705SXin Li HS.getModuleMap().setInferredModuleAllowedBy(Module, ModuleMapForUniquing);
345*67e74705SXin Li } else {
346*67e74705SXin Li ModuleMapForUniquing = ModuleMap;
347*67e74705SXin Li }
348*67e74705SXin Li
349*67e74705SXin Li FileManager &FileMgr = CI.getFileManager();
350*67e74705SXin Li
351*67e74705SXin Li // Collect the set of #includes we need to build the module.
352*67e74705SXin Li SmallString<256> HeaderContents;
353*67e74705SXin Li std::error_code Err = std::error_code();
354*67e74705SXin Li if (Module::Header UmbrellaHeader = Module->getUmbrellaHeader())
355*67e74705SXin Li addHeaderInclude(UmbrellaHeader.NameAsWritten, HeaderContents,
356*67e74705SXin Li CI.getLangOpts(), Module->IsExternC);
357*67e74705SXin Li Err = collectModuleHeaderIncludes(
358*67e74705SXin Li CI.getLangOpts(), FileMgr,
359*67e74705SXin Li CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), Module,
360*67e74705SXin Li HeaderContents);
361*67e74705SXin Li
362*67e74705SXin Li if (Err) {
363*67e74705SXin Li CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
364*67e74705SXin Li << Module->getFullModuleName() << Err.message();
365*67e74705SXin Li return false;
366*67e74705SXin Li }
367*67e74705SXin Li
368*67e74705SXin Li // Inform the preprocessor that includes from within the input buffer should
369*67e74705SXin Li // be resolved relative to the build directory of the module map file.
370*67e74705SXin Li CI.getPreprocessor().setMainFileDir(Module->Directory);
371*67e74705SXin Li
372*67e74705SXin Li std::unique_ptr<llvm::MemoryBuffer> InputBuffer =
373*67e74705SXin Li llvm::MemoryBuffer::getMemBufferCopy(HeaderContents,
374*67e74705SXin Li Module::getModuleInputBufferName());
375*67e74705SXin Li // Ownership of InputBuffer will be transferred to the SourceManager.
376*67e74705SXin Li setCurrentInput(FrontendInputFile(InputBuffer.release(), getCurrentFileKind(),
377*67e74705SXin Li Module->IsSystem));
378*67e74705SXin Li return true;
379*67e74705SXin Li }
380*67e74705SXin Li
ComputeASTConsumerArguments(CompilerInstance & CI,StringRef InFile,std::string & Sysroot,std::string & OutputFile)381*67e74705SXin Li raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments(
382*67e74705SXin Li CompilerInstance &CI, StringRef InFile, std::string &Sysroot,
383*67e74705SXin Li std::string &OutputFile) {
384*67e74705SXin Li // If no output file was provided, figure out where this module would go
385*67e74705SXin Li // in the module cache.
386*67e74705SXin Li if (CI.getFrontendOpts().OutputFile.empty()) {
387*67e74705SXin Li HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
388*67e74705SXin Li CI.getFrontendOpts().OutputFile =
389*67e74705SXin Li HS.getModuleFileName(CI.getLangOpts().CurrentModule,
390*67e74705SXin Li ModuleMapForUniquing->getName());
391*67e74705SXin Li }
392*67e74705SXin Li
393*67e74705SXin Li // We use createOutputFile here because this is exposed via libclang, and we
394*67e74705SXin Li // must disable the RemoveFileOnSignal behavior.
395*67e74705SXin Li // We use a temporary to avoid race conditions.
396*67e74705SXin Li raw_pwrite_stream *OS =
397*67e74705SXin Li CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
398*67e74705SXin Li /*RemoveFileOnSignal=*/false, InFile,
399*67e74705SXin Li /*Extension=*/"", /*useTemporary=*/true,
400*67e74705SXin Li /*CreateMissingDirectories=*/true);
401*67e74705SXin Li if (!OS)
402*67e74705SXin Li return nullptr;
403*67e74705SXin Li
404*67e74705SXin Li OutputFile = CI.getFrontendOpts().OutputFile;
405*67e74705SXin Li return OS;
406*67e74705SXin Li }
407*67e74705SXin Li
~SyntaxOnlyAction()408*67e74705SXin Li SyntaxOnlyAction::~SyntaxOnlyAction() {
409*67e74705SXin Li }
410*67e74705SXin Li
411*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)412*67e74705SXin Li SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
413*67e74705SXin Li return llvm::make_unique<ASTConsumer>();
414*67e74705SXin Li }
415*67e74705SXin Li
416*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)417*67e74705SXin Li DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI,
418*67e74705SXin Li StringRef InFile) {
419*67e74705SXin Li return llvm::make_unique<ASTConsumer>();
420*67e74705SXin Li }
421*67e74705SXin Li
422*67e74705SXin Li std::unique_ptr<ASTConsumer>
CreateASTConsumer(CompilerInstance & CI,StringRef InFile)423*67e74705SXin Li VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
424*67e74705SXin Li return llvm::make_unique<ASTConsumer>();
425*67e74705SXin Li }
426*67e74705SXin Li
ExecuteAction()427*67e74705SXin Li void VerifyPCHAction::ExecuteAction() {
428*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
429*67e74705SXin Li bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
430*67e74705SXin Li const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
431*67e74705SXin Li std::unique_ptr<ASTReader> Reader(new ASTReader(
432*67e74705SXin Li CI.getPreprocessor(), CI.getASTContext(), CI.getPCHContainerReader(),
433*67e74705SXin Li CI.getFrontendOpts().ModuleFileExtensions,
434*67e74705SXin Li Sysroot.empty() ? "" : Sysroot.c_str(),
435*67e74705SXin Li /*DisableValidation*/ false,
436*67e74705SXin Li /*AllowPCHWithCompilerErrors*/ false,
437*67e74705SXin Li /*AllowConfigurationMismatch*/ true,
438*67e74705SXin Li /*ValidateSystemInputs*/ true));
439*67e74705SXin Li
440*67e74705SXin Li Reader->ReadAST(getCurrentFile(),
441*67e74705SXin Li Preamble ? serialization::MK_Preamble
442*67e74705SXin Li : serialization::MK_PCH,
443*67e74705SXin Li SourceLocation(),
444*67e74705SXin Li ASTReader::ARR_ConfigurationMismatch);
445*67e74705SXin Li }
446*67e74705SXin Li
447*67e74705SXin Li namespace {
448*67e74705SXin Li /// \brief AST reader listener that dumps module information for a module
449*67e74705SXin Li /// file.
450*67e74705SXin Li class DumpModuleInfoListener : public ASTReaderListener {
451*67e74705SXin Li llvm::raw_ostream &Out;
452*67e74705SXin Li
453*67e74705SXin Li public:
DumpModuleInfoListener(llvm::raw_ostream & Out)454*67e74705SXin Li DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }
455*67e74705SXin Li
456*67e74705SXin Li #define DUMP_BOOLEAN(Value, Text) \
457*67e74705SXin Li Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
458*67e74705SXin Li
ReadFullVersionInformation(StringRef FullVersion)459*67e74705SXin Li bool ReadFullVersionInformation(StringRef FullVersion) override {
460*67e74705SXin Li Out.indent(2)
461*67e74705SXin Li << "Generated by "
462*67e74705SXin Li << (FullVersion == getClangFullRepositoryVersion()? "this"
463*67e74705SXin Li : "a different")
464*67e74705SXin Li << " Clang: " << FullVersion << "\n";
465*67e74705SXin Li return ASTReaderListener::ReadFullVersionInformation(FullVersion);
466*67e74705SXin Li }
467*67e74705SXin Li
ReadModuleName(StringRef ModuleName)468*67e74705SXin Li void ReadModuleName(StringRef ModuleName) override {
469*67e74705SXin Li Out.indent(2) << "Module name: " << ModuleName << "\n";
470*67e74705SXin Li }
ReadModuleMapFile(StringRef ModuleMapPath)471*67e74705SXin Li void ReadModuleMapFile(StringRef ModuleMapPath) override {
472*67e74705SXin Li Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
473*67e74705SXin Li }
474*67e74705SXin Li
ReadLanguageOptions(const LangOptions & LangOpts,bool Complain,bool AllowCompatibleDifferences)475*67e74705SXin Li bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
476*67e74705SXin Li bool AllowCompatibleDifferences) override {
477*67e74705SXin Li Out.indent(2) << "Language options:\n";
478*67e74705SXin Li #define LANGOPT(Name, Bits, Default, Description) \
479*67e74705SXin Li DUMP_BOOLEAN(LangOpts.Name, Description);
480*67e74705SXin Li #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
481*67e74705SXin Li Out.indent(4) << Description << ": " \
482*67e74705SXin Li << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
483*67e74705SXin Li #define VALUE_LANGOPT(Name, Bits, Default, Description) \
484*67e74705SXin Li Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
485*67e74705SXin Li #define BENIGN_LANGOPT(Name, Bits, Default, Description)
486*67e74705SXin Li #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
487*67e74705SXin Li #include "clang/Basic/LangOptions.def"
488*67e74705SXin Li
489*67e74705SXin Li if (!LangOpts.ModuleFeatures.empty()) {
490*67e74705SXin Li Out.indent(4) << "Module features:\n";
491*67e74705SXin Li for (StringRef Feature : LangOpts.ModuleFeatures)
492*67e74705SXin Li Out.indent(6) << Feature << "\n";
493*67e74705SXin Li }
494*67e74705SXin Li
495*67e74705SXin Li return false;
496*67e74705SXin Li }
497*67e74705SXin Li
ReadTargetOptions(const TargetOptions & TargetOpts,bool Complain,bool AllowCompatibleDifferences)498*67e74705SXin Li bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
499*67e74705SXin Li bool AllowCompatibleDifferences) override {
500*67e74705SXin Li Out.indent(2) << "Target options:\n";
501*67e74705SXin Li Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";
502*67e74705SXin Li Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";
503*67e74705SXin Li Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";
504*67e74705SXin Li
505*67e74705SXin Li if (!TargetOpts.FeaturesAsWritten.empty()) {
506*67e74705SXin Li Out.indent(4) << "Target features:\n";
507*67e74705SXin Li for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
508*67e74705SXin Li I != N; ++I) {
509*67e74705SXin Li Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
510*67e74705SXin Li }
511*67e74705SXin Li }
512*67e74705SXin Li
513*67e74705SXin Li return false;
514*67e74705SXin Li }
515*67e74705SXin Li
ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,bool Complain)516*67e74705SXin Li bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
517*67e74705SXin Li bool Complain) override {
518*67e74705SXin Li Out.indent(2) << "Diagnostic options:\n";
519*67e74705SXin Li #define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
520*67e74705SXin Li #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
521*67e74705SXin Li Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
522*67e74705SXin Li #define VALUE_DIAGOPT(Name, Bits, Default) \
523*67e74705SXin Li Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
524*67e74705SXin Li #include "clang/Basic/DiagnosticOptions.def"
525*67e74705SXin Li
526*67e74705SXin Li Out.indent(4) << "Diagnostic flags:\n";
527*67e74705SXin Li for (const std::string &Warning : DiagOpts->Warnings)
528*67e74705SXin Li Out.indent(6) << "-W" << Warning << "\n";
529*67e74705SXin Li for (const std::string &Remark : DiagOpts->Remarks)
530*67e74705SXin Li Out.indent(6) << "-R" << Remark << "\n";
531*67e74705SXin Li
532*67e74705SXin Li return false;
533*67e74705SXin Li }
534*67e74705SXin Li
ReadHeaderSearchOptions(const HeaderSearchOptions & HSOpts,StringRef SpecificModuleCachePath,bool Complain)535*67e74705SXin Li bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
536*67e74705SXin Li StringRef SpecificModuleCachePath,
537*67e74705SXin Li bool Complain) override {
538*67e74705SXin Li Out.indent(2) << "Header search options:\n";
539*67e74705SXin Li Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
540*67e74705SXin Li Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
541*67e74705SXin Li DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
542*67e74705SXin Li "Use builtin include directories [-nobuiltininc]");
543*67e74705SXin Li DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes,
544*67e74705SXin Li "Use standard system include directories [-nostdinc]");
545*67e74705SXin Li DUMP_BOOLEAN(HSOpts.UseStandardCXXIncludes,
546*67e74705SXin Li "Use standard C++ include directories [-nostdinc++]");
547*67e74705SXin Li DUMP_BOOLEAN(HSOpts.UseLibcxx,
548*67e74705SXin Li "Use libc++ (rather than libstdc++) [-stdlib=]");
549*67e74705SXin Li return false;
550*67e74705SXin Li }
551*67e74705SXin Li
ReadPreprocessorOptions(const PreprocessorOptions & PPOpts,bool Complain,std::string & SuggestedPredefines)552*67e74705SXin Li bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
553*67e74705SXin Li bool Complain,
554*67e74705SXin Li std::string &SuggestedPredefines) override {
555*67e74705SXin Li Out.indent(2) << "Preprocessor options:\n";
556*67e74705SXin Li DUMP_BOOLEAN(PPOpts.UsePredefines,
557*67e74705SXin Li "Uses compiler/target-specific predefines [-undef]");
558*67e74705SXin Li DUMP_BOOLEAN(PPOpts.DetailedRecord,
559*67e74705SXin Li "Uses detailed preprocessing record (for indexing)");
560*67e74705SXin Li
561*67e74705SXin Li if (!PPOpts.Macros.empty()) {
562*67e74705SXin Li Out.indent(4) << "Predefined macros:\n";
563*67e74705SXin Li }
564*67e74705SXin Li
565*67e74705SXin Li for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
566*67e74705SXin Li I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
567*67e74705SXin Li I != IEnd; ++I) {
568*67e74705SXin Li Out.indent(6);
569*67e74705SXin Li if (I->second)
570*67e74705SXin Li Out << "-U";
571*67e74705SXin Li else
572*67e74705SXin Li Out << "-D";
573*67e74705SXin Li Out << I->first << "\n";
574*67e74705SXin Li }
575*67e74705SXin Li return false;
576*67e74705SXin Li }
577*67e74705SXin Li
578*67e74705SXin Li /// Indicates that a particular module file extension has been read.
readModuleFileExtension(const ModuleFileExtensionMetadata & Metadata)579*67e74705SXin Li void readModuleFileExtension(
580*67e74705SXin Li const ModuleFileExtensionMetadata &Metadata) override {
581*67e74705SXin Li Out.indent(2) << "Module file extension '"
582*67e74705SXin Li << Metadata.BlockName << "' " << Metadata.MajorVersion
583*67e74705SXin Li << "." << Metadata.MinorVersion;
584*67e74705SXin Li if (!Metadata.UserInfo.empty()) {
585*67e74705SXin Li Out << ": ";
586*67e74705SXin Li Out.write_escaped(Metadata.UserInfo);
587*67e74705SXin Li }
588*67e74705SXin Li
589*67e74705SXin Li Out << "\n";
590*67e74705SXin Li }
591*67e74705SXin Li #undef DUMP_BOOLEAN
592*67e74705SXin Li };
593*67e74705SXin Li }
594*67e74705SXin Li
ExecuteAction()595*67e74705SXin Li void DumpModuleInfoAction::ExecuteAction() {
596*67e74705SXin Li // Set up the output file.
597*67e74705SXin Li std::unique_ptr<llvm::raw_fd_ostream> OutFile;
598*67e74705SXin Li StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile;
599*67e74705SXin Li if (!OutputFileName.empty() && OutputFileName != "-") {
600*67e74705SXin Li std::error_code EC;
601*67e74705SXin Li OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC,
602*67e74705SXin Li llvm::sys::fs::F_Text));
603*67e74705SXin Li }
604*67e74705SXin Li llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
605*67e74705SXin Li
606*67e74705SXin Li Out << "Information for module file '" << getCurrentFile() << "':\n";
607*67e74705SXin Li DumpModuleInfoListener Listener(Out);
608*67e74705SXin Li ASTReader::readASTFileControlBlock(
609*67e74705SXin Li getCurrentFile(), getCompilerInstance().getFileManager(),
610*67e74705SXin Li getCompilerInstance().getPCHContainerReader(),
611*67e74705SXin Li /*FindModuleFileExtensions=*/true, Listener);
612*67e74705SXin Li }
613*67e74705SXin Li
614*67e74705SXin Li //===----------------------------------------------------------------------===//
615*67e74705SXin Li // Preprocessor Actions
616*67e74705SXin Li //===----------------------------------------------------------------------===//
617*67e74705SXin Li
ExecuteAction()618*67e74705SXin Li void DumpRawTokensAction::ExecuteAction() {
619*67e74705SXin Li Preprocessor &PP = getCompilerInstance().getPreprocessor();
620*67e74705SXin Li SourceManager &SM = PP.getSourceManager();
621*67e74705SXin Li
622*67e74705SXin Li // Start lexing the specified input file.
623*67e74705SXin Li const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
624*67e74705SXin Li Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
625*67e74705SXin Li RawLex.SetKeepWhitespaceMode(true);
626*67e74705SXin Li
627*67e74705SXin Li Token RawTok;
628*67e74705SXin Li RawLex.LexFromRawLexer(RawTok);
629*67e74705SXin Li while (RawTok.isNot(tok::eof)) {
630*67e74705SXin Li PP.DumpToken(RawTok, true);
631*67e74705SXin Li llvm::errs() << "\n";
632*67e74705SXin Li RawLex.LexFromRawLexer(RawTok);
633*67e74705SXin Li }
634*67e74705SXin Li }
635*67e74705SXin Li
ExecuteAction()636*67e74705SXin Li void DumpTokensAction::ExecuteAction() {
637*67e74705SXin Li Preprocessor &PP = getCompilerInstance().getPreprocessor();
638*67e74705SXin Li // Start preprocessing the specified input file.
639*67e74705SXin Li Token Tok;
640*67e74705SXin Li PP.EnterMainSourceFile();
641*67e74705SXin Li do {
642*67e74705SXin Li PP.Lex(Tok);
643*67e74705SXin Li PP.DumpToken(Tok, true);
644*67e74705SXin Li llvm::errs() << "\n";
645*67e74705SXin Li } while (Tok.isNot(tok::eof));
646*67e74705SXin Li }
647*67e74705SXin Li
ExecuteAction()648*67e74705SXin Li void GeneratePTHAction::ExecuteAction() {
649*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
650*67e74705SXin Li raw_pwrite_stream *OS = CI.createDefaultOutputFile(true, getCurrentFile());
651*67e74705SXin Li if (!OS)
652*67e74705SXin Li return;
653*67e74705SXin Li
654*67e74705SXin Li CacheTokens(CI.getPreprocessor(), OS);
655*67e74705SXin Li }
656*67e74705SXin Li
ExecuteAction()657*67e74705SXin Li void PreprocessOnlyAction::ExecuteAction() {
658*67e74705SXin Li Preprocessor &PP = getCompilerInstance().getPreprocessor();
659*67e74705SXin Li
660*67e74705SXin Li // Ignore unknown pragmas.
661*67e74705SXin Li PP.IgnorePragmas();
662*67e74705SXin Li
663*67e74705SXin Li Token Tok;
664*67e74705SXin Li // Start parsing the specified input file.
665*67e74705SXin Li PP.EnterMainSourceFile();
666*67e74705SXin Li do {
667*67e74705SXin Li PP.Lex(Tok);
668*67e74705SXin Li } while (Tok.isNot(tok::eof));
669*67e74705SXin Li }
670*67e74705SXin Li
ExecuteAction()671*67e74705SXin Li void PrintPreprocessedAction::ExecuteAction() {
672*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
673*67e74705SXin Li // Output file may need to be set to 'Binary', to avoid converting Unix style
674*67e74705SXin Li // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
675*67e74705SXin Li //
676*67e74705SXin Li // Look to see what type of line endings the file uses. If there's a
677*67e74705SXin Li // CRLF, then we won't open the file up in binary mode. If there is
678*67e74705SXin Li // just an LF or CR, then we will open the file up in binary mode.
679*67e74705SXin Li // In this fashion, the output format should match the input format, unless
680*67e74705SXin Li // the input format has inconsistent line endings.
681*67e74705SXin Li //
682*67e74705SXin Li // This should be a relatively fast operation since most files won't have
683*67e74705SXin Li // all of their source code on a single line. However, that is still a
684*67e74705SXin Li // concern, so if we scan for too long, we'll just assume the file should
685*67e74705SXin Li // be opened in binary mode.
686*67e74705SXin Li bool BinaryMode = true;
687*67e74705SXin Li bool InvalidFile = false;
688*67e74705SXin Li const SourceManager& SM = CI.getSourceManager();
689*67e74705SXin Li const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(),
690*67e74705SXin Li &InvalidFile);
691*67e74705SXin Li if (!InvalidFile) {
692*67e74705SXin Li const char *cur = Buffer->getBufferStart();
693*67e74705SXin Li const char *end = Buffer->getBufferEnd();
694*67e74705SXin Li const char *next = (cur != end) ? cur + 1 : end;
695*67e74705SXin Li
696*67e74705SXin Li // Limit ourselves to only scanning 256 characters into the source
697*67e74705SXin Li // file. This is mostly a sanity check in case the file has no
698*67e74705SXin Li // newlines whatsoever.
699*67e74705SXin Li if (end - cur > 256) end = cur + 256;
700*67e74705SXin Li
701*67e74705SXin Li while (next < end) {
702*67e74705SXin Li if (*cur == 0x0D) { // CR
703*67e74705SXin Li if (*next == 0x0A) // CRLF
704*67e74705SXin Li BinaryMode = false;
705*67e74705SXin Li
706*67e74705SXin Li break;
707*67e74705SXin Li } else if (*cur == 0x0A) // LF
708*67e74705SXin Li break;
709*67e74705SXin Li
710*67e74705SXin Li ++cur;
711*67e74705SXin Li ++next;
712*67e74705SXin Li }
713*67e74705SXin Li }
714*67e74705SXin Li
715*67e74705SXin Li raw_ostream *OS = CI.createDefaultOutputFile(BinaryMode, getCurrentFile());
716*67e74705SXin Li if (!OS) return;
717*67e74705SXin Li
718*67e74705SXin Li DoPrintPreprocessedInput(CI.getPreprocessor(), OS,
719*67e74705SXin Li CI.getPreprocessorOutputOpts());
720*67e74705SXin Li }
721*67e74705SXin Li
ExecuteAction()722*67e74705SXin Li void PrintPreambleAction::ExecuteAction() {
723*67e74705SXin Li switch (getCurrentFileKind()) {
724*67e74705SXin Li case IK_C:
725*67e74705SXin Li case IK_CXX:
726*67e74705SXin Li case IK_ObjC:
727*67e74705SXin Li case IK_ObjCXX:
728*67e74705SXin Li case IK_OpenCL:
729*67e74705SXin Li case IK_CUDA:
730*67e74705SXin Li break;
731*67e74705SXin Li
732*67e74705SXin Li case IK_None:
733*67e74705SXin Li case IK_Asm:
734*67e74705SXin Li case IK_PreprocessedC:
735*67e74705SXin Li case IK_PreprocessedCuda:
736*67e74705SXin Li case IK_PreprocessedCXX:
737*67e74705SXin Li case IK_PreprocessedObjC:
738*67e74705SXin Li case IK_PreprocessedObjCXX:
739*67e74705SXin Li case IK_AST:
740*67e74705SXin Li case IK_LLVM_IR:
741*67e74705SXin Li case IK_RenderScript:
742*67e74705SXin Li // We can't do anything with these.
743*67e74705SXin Li return;
744*67e74705SXin Li }
745*67e74705SXin Li
746*67e74705SXin Li CompilerInstance &CI = getCompilerInstance();
747*67e74705SXin Li auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
748*67e74705SXin Li if (Buffer) {
749*67e74705SXin Li unsigned Preamble =
750*67e74705SXin Li Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).first;
751*67e74705SXin Li llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
752*67e74705SXin Li }
753*67e74705SXin Li }
754