FrontendActions.cpp 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941
  1. //===--- FrontendActions.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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "clang/Frontend/FrontendActions.h"
  9. #include "clang/AST/ASTConsumer.h"
  10. #include "clang/Basic/FileManager.h"
  11. #include "clang/Frontend/ASTConsumers.h"
  12. #include "clang/Frontend/CompilerInstance.h"
  13. #include "clang/Frontend/FrontendDiagnostic.h"
  14. #include "clang/Frontend/MultiplexConsumer.h"
  15. #include "clang/Frontend/Utils.h"
  16. #include "clang/Lex/DependencyDirectivesSourceMinimizer.h"
  17. #include "clang/Lex/HeaderSearch.h"
  18. #include "clang/Lex/Preprocessor.h"
  19. #include "clang/Lex/PreprocessorOptions.h"
  20. #include "clang/Sema/TemplateInstCallback.h"
  21. #include "clang/Serialization/ASTReader.h"
  22. #include "clang/Serialization/ASTWriter.h"
  23. #include "llvm/Support/FileSystem.h"
  24. #include "llvm/Support/MemoryBuffer.h"
  25. #include "llvm/Support/Path.h"
  26. #include "llvm/Support/YAMLTraits.h"
  27. #include "llvm/Support/raw_ostream.h"
  28. #include <memory>
  29. #include <system_error>
  30. using namespace clang;
  31. namespace {
  32. CodeCompleteConsumer *GetCodeCompletionConsumer(CompilerInstance &CI) {
  33. return CI.hasCodeCompletionConsumer() ? &CI.getCodeCompletionConsumer()
  34. : nullptr;
  35. }
  36. void EnsureSemaIsCreated(CompilerInstance &CI, FrontendAction &Action) {
  37. if (Action.hasCodeCompletionSupport() &&
  38. !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
  39. CI.createCodeCompletionConsumer();
  40. if (!CI.hasSema())
  41. CI.createSema(Action.getTranslationUnitKind(),
  42. GetCodeCompletionConsumer(CI));
  43. }
  44. } // namespace
  45. //===----------------------------------------------------------------------===//
  46. // Custom Actions
  47. //===----------------------------------------------------------------------===//
  48. std::unique_ptr<ASTConsumer>
  49. InitOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  50. return llvm::make_unique<ASTConsumer>();
  51. }
  52. void InitOnlyAction::ExecuteAction() {
  53. }
  54. //===----------------------------------------------------------------------===//
  55. // AST Consumer Actions
  56. //===----------------------------------------------------------------------===//
  57. std::unique_ptr<ASTConsumer>
  58. ASTPrintAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  59. if (std::unique_ptr<raw_ostream> OS =
  60. CI.createDefaultOutputFile(false, InFile))
  61. return CreateASTPrinter(std::move(OS), CI.getFrontendOpts().ASTDumpFilter);
  62. return nullptr;
  63. }
  64. std::unique_ptr<ASTConsumer>
  65. ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  66. const FrontendOptions &Opts = CI.getFrontendOpts();
  67. return CreateASTDumper(nullptr /*Dump to stdout.*/, Opts.ASTDumpFilter,
  68. Opts.ASTDumpDecls, Opts.ASTDumpAll,
  69. Opts.ASTDumpLookups, Opts.ASTDumpFormat);
  70. }
  71. std::unique_ptr<ASTConsumer>
  72. ASTDeclListAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  73. return CreateASTDeclNodeLister();
  74. }
  75. std::unique_ptr<ASTConsumer>
  76. ASTViewAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  77. return CreateASTViewer();
  78. }
  79. std::unique_ptr<ASTConsumer>
  80. GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  81. std::string Sysroot;
  82. if (!ComputeASTConsumerArguments(CI, /*ref*/ Sysroot))
  83. return nullptr;
  84. std::string OutputFile;
  85. std::unique_ptr<raw_pwrite_stream> OS =
  86. CreateOutputFile(CI, InFile, /*ref*/ OutputFile);
  87. if (!OS)
  88. return nullptr;
  89. if (!CI.getFrontendOpts().RelocatablePCH)
  90. Sysroot.clear();
  91. const auto &FrontendOpts = CI.getFrontendOpts();
  92. auto Buffer = std::make_shared<PCHBuffer>();
  93. std::vector<std::unique_ptr<ASTConsumer>> Consumers;
  94. Consumers.push_back(llvm::make_unique<PCHGenerator>(
  95. CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
  96. FrontendOpts.ModuleFileExtensions,
  97. CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
  98. FrontendOpts.IncludeTimestamps, +CI.getLangOpts().CacheGeneratedPCH));
  99. Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
  100. CI, InFile, OutputFile, std::move(OS), Buffer));
  101. return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
  102. }
  103. bool GeneratePCHAction::ComputeASTConsumerArguments(CompilerInstance &CI,
  104. std::string &Sysroot) {
  105. Sysroot = CI.getHeaderSearchOpts().Sysroot;
  106. if (CI.getFrontendOpts().RelocatablePCH && Sysroot.empty()) {
  107. CI.getDiagnostics().Report(diag::err_relocatable_without_isysroot);
  108. return false;
  109. }
  110. return true;
  111. }
  112. std::unique_ptr<llvm::raw_pwrite_stream>
  113. GeneratePCHAction::CreateOutputFile(CompilerInstance &CI, StringRef InFile,
  114. std::string &OutputFile) {
  115. // We use createOutputFile here because this is exposed via libclang, and we
  116. // must disable the RemoveFileOnSignal behavior.
  117. // We use a temporary to avoid race conditions.
  118. std::unique_ptr<raw_pwrite_stream> OS =
  119. CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
  120. /*RemoveFileOnSignal=*/false, InFile,
  121. /*Extension=*/"", /*UseTemporary=*/true);
  122. if (!OS)
  123. return nullptr;
  124. OutputFile = CI.getFrontendOpts().OutputFile;
  125. return OS;
  126. }
  127. bool GeneratePCHAction::shouldEraseOutputFiles() {
  128. if (getCompilerInstance().getPreprocessorOpts().AllowPCHWithCompilerErrors)
  129. return false;
  130. return ASTFrontendAction::shouldEraseOutputFiles();
  131. }
  132. bool GeneratePCHAction::BeginSourceFileAction(CompilerInstance &CI) {
  133. CI.getLangOpts().CompilingPCH = true;
  134. return true;
  135. }
  136. std::unique_ptr<ASTConsumer>
  137. GenerateModuleAction::CreateASTConsumer(CompilerInstance &CI,
  138. StringRef InFile) {
  139. std::unique_ptr<raw_pwrite_stream> OS = CreateOutputFile(CI, InFile);
  140. if (!OS)
  141. return nullptr;
  142. std::string OutputFile = CI.getFrontendOpts().OutputFile;
  143. std::string Sysroot;
  144. auto Buffer = std::make_shared<PCHBuffer>();
  145. std::vector<std::unique_ptr<ASTConsumer>> Consumers;
  146. Consumers.push_back(llvm::make_unique<PCHGenerator>(
  147. CI.getPreprocessor(), CI.getModuleCache(), OutputFile, Sysroot, Buffer,
  148. CI.getFrontendOpts().ModuleFileExtensions,
  149. /*AllowASTWithErrors=*/false,
  150. /*IncludeTimestamps=*/
  151. +CI.getFrontendOpts().BuildingImplicitModule,
  152. /*ShouldCacheASTInMemory=*/
  153. +CI.getFrontendOpts().BuildingImplicitModule));
  154. Consumers.push_back(CI.getPCHContainerWriter().CreatePCHContainerGenerator(
  155. CI, InFile, OutputFile, std::move(OS), Buffer));
  156. return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
  157. }
  158. bool GenerateModuleFromModuleMapAction::BeginSourceFileAction(
  159. CompilerInstance &CI) {
  160. if (!CI.getLangOpts().Modules) {
  161. CI.getDiagnostics().Report(diag::err_module_build_requires_fmodules);
  162. return false;
  163. }
  164. return GenerateModuleAction::BeginSourceFileAction(CI);
  165. }
  166. std::unique_ptr<raw_pwrite_stream>
  167. GenerateModuleFromModuleMapAction::CreateOutputFile(CompilerInstance &CI,
  168. StringRef InFile) {
  169. // If no output file was provided, figure out where this module would go
  170. // in the module cache.
  171. if (CI.getFrontendOpts().OutputFile.empty()) {
  172. StringRef ModuleMapFile = CI.getFrontendOpts().OriginalModuleMap;
  173. if (ModuleMapFile.empty())
  174. ModuleMapFile = InFile;
  175. HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
  176. CI.getFrontendOpts().OutputFile =
  177. HS.getCachedModuleFileName(CI.getLangOpts().CurrentModule,
  178. ModuleMapFile);
  179. }
  180. // We use createOutputFile here because this is exposed via libclang, and we
  181. // must disable the RemoveFileOnSignal behavior.
  182. // We use a temporary to avoid race conditions.
  183. return CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
  184. /*RemoveFileOnSignal=*/false, InFile,
  185. /*Extension=*/"", /*UseTemporary=*/true,
  186. /*CreateMissingDirectories=*/true);
  187. }
  188. bool GenerateModuleInterfaceAction::BeginSourceFileAction(
  189. CompilerInstance &CI) {
  190. if (!CI.getLangOpts().ModulesTS && !CI.getLangOpts().CPlusPlusModules) {
  191. CI.getDiagnostics().Report(diag::err_module_interface_requires_cpp_modules);
  192. return false;
  193. }
  194. CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleInterface);
  195. return GenerateModuleAction::BeginSourceFileAction(CI);
  196. }
  197. std::unique_ptr<raw_pwrite_stream>
  198. GenerateModuleInterfaceAction::CreateOutputFile(CompilerInstance &CI,
  199. StringRef InFile) {
  200. return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
  201. }
  202. bool GenerateHeaderModuleAction::PrepareToExecuteAction(
  203. CompilerInstance &CI) {
  204. if (!CI.getLangOpts().Modules) {
  205. CI.getDiagnostics().Report(diag::err_header_module_requires_modules);
  206. return false;
  207. }
  208. auto &Inputs = CI.getFrontendOpts().Inputs;
  209. if (Inputs.empty())
  210. return GenerateModuleAction::BeginInvocation(CI);
  211. auto Kind = Inputs[0].getKind();
  212. // Convert the header file inputs into a single module input buffer.
  213. SmallString<256> HeaderContents;
  214. ModuleHeaders.reserve(Inputs.size());
  215. for (const FrontendInputFile &FIF : Inputs) {
  216. // FIXME: We should support re-compiling from an AST file.
  217. if (FIF.getKind().getFormat() != InputKind::Source || !FIF.isFile()) {
  218. CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
  219. << (FIF.isFile() ? FIF.getFile()
  220. : FIF.getBuffer()->getBufferIdentifier());
  221. return true;
  222. }
  223. HeaderContents += "#include \"";
  224. HeaderContents += FIF.getFile();
  225. HeaderContents += "\"\n";
  226. ModuleHeaders.push_back(FIF.getFile());
  227. }
  228. Buffer = llvm::MemoryBuffer::getMemBufferCopy(
  229. HeaderContents, Module::getModuleInputBufferName());
  230. // Set that buffer up as our "real" input.
  231. Inputs.clear();
  232. Inputs.push_back(FrontendInputFile(Buffer.get(), Kind, /*IsSystem*/false));
  233. return GenerateModuleAction::PrepareToExecuteAction(CI);
  234. }
  235. bool GenerateHeaderModuleAction::BeginSourceFileAction(
  236. CompilerInstance &CI) {
  237. CI.getLangOpts().setCompilingModule(LangOptions::CMK_HeaderModule);
  238. // Synthesize a Module object for the given headers.
  239. auto &HS = CI.getPreprocessor().getHeaderSearchInfo();
  240. SmallVector<Module::Header, 16> Headers;
  241. for (StringRef Name : ModuleHeaders) {
  242. const DirectoryLookup *CurDir = nullptr;
  243. const FileEntry *FE = HS.LookupFile(
  244. Name, SourceLocation(), /*Angled*/ false, nullptr, CurDir,
  245. None, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr);
  246. if (!FE) {
  247. CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
  248. << Name;
  249. continue;
  250. }
  251. Headers.push_back({Name, FE});
  252. }
  253. HS.getModuleMap().createHeaderModule(CI.getLangOpts().CurrentModule, Headers);
  254. return GenerateModuleAction::BeginSourceFileAction(CI);
  255. }
  256. std::unique_ptr<raw_pwrite_stream>
  257. GenerateHeaderModuleAction::CreateOutputFile(CompilerInstance &CI,
  258. StringRef InFile) {
  259. return CI.createDefaultOutputFile(/*Binary=*/true, InFile, "pcm");
  260. }
  261. SyntaxOnlyAction::~SyntaxOnlyAction() {
  262. }
  263. std::unique_ptr<ASTConsumer>
  264. SyntaxOnlyAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  265. return llvm::make_unique<ASTConsumer>();
  266. }
  267. std::unique_ptr<ASTConsumer>
  268. DumpModuleInfoAction::CreateASTConsumer(CompilerInstance &CI,
  269. StringRef InFile) {
  270. return llvm::make_unique<ASTConsumer>();
  271. }
  272. std::unique_ptr<ASTConsumer>
  273. VerifyPCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  274. return llvm::make_unique<ASTConsumer>();
  275. }
  276. void VerifyPCHAction::ExecuteAction() {
  277. CompilerInstance &CI = getCompilerInstance();
  278. bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
  279. const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
  280. std::unique_ptr<ASTReader> Reader(new ASTReader(
  281. CI.getPreprocessor(), CI.getModuleCache(), &CI.getASTContext(),
  282. CI.getPCHContainerReader(), CI.getFrontendOpts().ModuleFileExtensions,
  283. Sysroot.empty() ? "" : Sysroot.c_str(),
  284. /*DisableValidation*/ false,
  285. /*AllowPCHWithCompilerErrors*/ false,
  286. /*AllowConfigurationMismatch*/ true,
  287. /*ValidateSystemInputs*/ true));
  288. Reader->ReadAST(getCurrentFile(),
  289. Preamble ? serialization::MK_Preamble
  290. : serialization::MK_PCH,
  291. SourceLocation(),
  292. ASTReader::ARR_ConfigurationMismatch);
  293. }
  294. namespace {
  295. struct TemplightEntry {
  296. std::string Name;
  297. std::string Kind;
  298. std::string Event;
  299. std::string DefinitionLocation;
  300. std::string PointOfInstantiation;
  301. };
  302. } // namespace
  303. namespace llvm {
  304. namespace yaml {
  305. template <> struct MappingTraits<TemplightEntry> {
  306. static void mapping(IO &io, TemplightEntry &fields) {
  307. io.mapRequired("name", fields.Name);
  308. io.mapRequired("kind", fields.Kind);
  309. io.mapRequired("event", fields.Event);
  310. io.mapRequired("orig", fields.DefinitionLocation);
  311. io.mapRequired("poi", fields.PointOfInstantiation);
  312. }
  313. };
  314. } // namespace yaml
  315. } // namespace llvm
  316. namespace {
  317. class DefaultTemplateInstCallback : public TemplateInstantiationCallback {
  318. using CodeSynthesisContext = Sema::CodeSynthesisContext;
  319. public:
  320. void initialize(const Sema &) override {}
  321. void finalize(const Sema &) override {}
  322. void atTemplateBegin(const Sema &TheSema,
  323. const CodeSynthesisContext &Inst) override {
  324. displayTemplightEntry<true>(llvm::outs(), TheSema, Inst);
  325. }
  326. void atTemplateEnd(const Sema &TheSema,
  327. const CodeSynthesisContext &Inst) override {
  328. displayTemplightEntry<false>(llvm::outs(), TheSema, Inst);
  329. }
  330. private:
  331. static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
  332. switch (Kind) {
  333. case CodeSynthesisContext::TemplateInstantiation:
  334. return "TemplateInstantiation";
  335. case CodeSynthesisContext::DefaultTemplateArgumentInstantiation:
  336. return "DefaultTemplateArgumentInstantiation";
  337. case CodeSynthesisContext::DefaultFunctionArgumentInstantiation:
  338. return "DefaultFunctionArgumentInstantiation";
  339. case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution:
  340. return "ExplicitTemplateArgumentSubstitution";
  341. case CodeSynthesisContext::DeducedTemplateArgumentSubstitution:
  342. return "DeducedTemplateArgumentSubstitution";
  343. case CodeSynthesisContext::PriorTemplateArgumentSubstitution:
  344. return "PriorTemplateArgumentSubstitution";
  345. case CodeSynthesisContext::DefaultTemplateArgumentChecking:
  346. return "DefaultTemplateArgumentChecking";
  347. case CodeSynthesisContext::ExceptionSpecEvaluation:
  348. return "ExceptionSpecEvaluation";
  349. case CodeSynthesisContext::ExceptionSpecInstantiation:
  350. return "ExceptionSpecInstantiation";
  351. case CodeSynthesisContext::DeclaringSpecialMember:
  352. return "DeclaringSpecialMember";
  353. case CodeSynthesisContext::DefiningSynthesizedFunction:
  354. return "DefiningSynthesizedFunction";
  355. case CodeSynthesisContext::Memoization:
  356. return "Memoization";
  357. }
  358. return "";
  359. }
  360. template <bool BeginInstantiation>
  361. static void displayTemplightEntry(llvm::raw_ostream &Out, const Sema &TheSema,
  362. const CodeSynthesisContext &Inst) {
  363. std::string YAML;
  364. {
  365. llvm::raw_string_ostream OS(YAML);
  366. llvm::yaml::Output YO(OS);
  367. TemplightEntry Entry =
  368. getTemplightEntry<BeginInstantiation>(TheSema, Inst);
  369. llvm::yaml::EmptyContext Context;
  370. llvm::yaml::yamlize(YO, Entry, true, Context);
  371. }
  372. Out << "---" << YAML << "\n";
  373. }
  374. template <bool BeginInstantiation>
  375. static TemplightEntry getTemplightEntry(const Sema &TheSema,
  376. const CodeSynthesisContext &Inst) {
  377. TemplightEntry Entry;
  378. Entry.Kind = toString(Inst.Kind);
  379. Entry.Event = BeginInstantiation ? "Begin" : "End";
  380. if (auto *NamedTemplate = dyn_cast_or_null<NamedDecl>(Inst.Entity)) {
  381. llvm::raw_string_ostream OS(Entry.Name);
  382. NamedTemplate->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
  383. const PresumedLoc DefLoc =
  384. TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
  385. if(!DefLoc.isInvalid())
  386. Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
  387. std::to_string(DefLoc.getLine()) + ":" +
  388. std::to_string(DefLoc.getColumn());
  389. }
  390. const PresumedLoc PoiLoc =
  391. TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
  392. if (!PoiLoc.isInvalid()) {
  393. Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
  394. std::to_string(PoiLoc.getLine()) + ":" +
  395. std::to_string(PoiLoc.getColumn());
  396. }
  397. return Entry;
  398. }
  399. };
  400. } // namespace
  401. std::unique_ptr<ASTConsumer>
  402. TemplightDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
  403. return llvm::make_unique<ASTConsumer>();
  404. }
  405. void TemplightDumpAction::ExecuteAction() {
  406. CompilerInstance &CI = getCompilerInstance();
  407. // This part is normally done by ASTFrontEndAction, but needs to happen
  408. // before Templight observers can be created
  409. // FIXME: Move the truncation aspect of this into Sema, we delayed this till
  410. // here so the source manager would be initialized.
  411. EnsureSemaIsCreated(CI, *this);
  412. CI.getSema().TemplateInstCallbacks.push_back(
  413. llvm::make_unique<DefaultTemplateInstCallback>());
  414. ASTFrontendAction::ExecuteAction();
  415. }
  416. namespace {
  417. /// AST reader listener that dumps module information for a module
  418. /// file.
  419. class DumpModuleInfoListener : public ASTReaderListener {
  420. llvm::raw_ostream &Out;
  421. public:
  422. DumpModuleInfoListener(llvm::raw_ostream &Out) : Out(Out) { }
  423. #define DUMP_BOOLEAN(Value, Text) \
  424. Out.indent(4) << Text << ": " << (Value? "Yes" : "No") << "\n"
  425. bool ReadFullVersionInformation(StringRef FullVersion) override {
  426. Out.indent(2)
  427. << "Generated by "
  428. << (FullVersion == getClangFullRepositoryVersion()? "this"
  429. : "a different")
  430. << " Clang: " << FullVersion << "\n";
  431. return ASTReaderListener::ReadFullVersionInformation(FullVersion);
  432. }
  433. void ReadModuleName(StringRef ModuleName) override {
  434. Out.indent(2) << "Module name: " << ModuleName << "\n";
  435. }
  436. void ReadModuleMapFile(StringRef ModuleMapPath) override {
  437. Out.indent(2) << "Module map file: " << ModuleMapPath << "\n";
  438. }
  439. bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
  440. bool AllowCompatibleDifferences) override {
  441. Out.indent(2) << "Language options:\n";
  442. #define LANGOPT(Name, Bits, Default, Description) \
  443. DUMP_BOOLEAN(LangOpts.Name, Description);
  444. #define ENUM_LANGOPT(Name, Type, Bits, Default, Description) \
  445. Out.indent(4) << Description << ": " \
  446. << static_cast<unsigned>(LangOpts.get##Name()) << "\n";
  447. #define VALUE_LANGOPT(Name, Bits, Default, Description) \
  448. Out.indent(4) << Description << ": " << LangOpts.Name << "\n";
  449. #define BENIGN_LANGOPT(Name, Bits, Default, Description)
  450. #define BENIGN_ENUM_LANGOPT(Name, Type, Bits, Default, Description)
  451. #include "clang/Basic/LangOptions.def"
  452. if (!LangOpts.ModuleFeatures.empty()) {
  453. Out.indent(4) << "Module features:\n";
  454. for (StringRef Feature : LangOpts.ModuleFeatures)
  455. Out.indent(6) << Feature << "\n";
  456. }
  457. return false;
  458. }
  459. bool ReadTargetOptions(const TargetOptions &TargetOpts, bool Complain,
  460. bool AllowCompatibleDifferences) override {
  461. Out.indent(2) << "Target options:\n";
  462. Out.indent(4) << " Triple: " << TargetOpts.Triple << "\n";
  463. Out.indent(4) << " CPU: " << TargetOpts.CPU << "\n";
  464. Out.indent(4) << " ABI: " << TargetOpts.ABI << "\n";
  465. if (!TargetOpts.FeaturesAsWritten.empty()) {
  466. Out.indent(4) << "Target features:\n";
  467. for (unsigned I = 0, N = TargetOpts.FeaturesAsWritten.size();
  468. I != N; ++I) {
  469. Out.indent(6) << TargetOpts.FeaturesAsWritten[I] << "\n";
  470. }
  471. }
  472. return false;
  473. }
  474. bool ReadDiagnosticOptions(IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts,
  475. bool Complain) override {
  476. Out.indent(2) << "Diagnostic options:\n";
  477. #define DIAGOPT(Name, Bits, Default) DUMP_BOOLEAN(DiagOpts->Name, #Name);
  478. #define ENUM_DIAGOPT(Name, Type, Bits, Default) \
  479. Out.indent(4) << #Name << ": " << DiagOpts->get##Name() << "\n";
  480. #define VALUE_DIAGOPT(Name, Bits, Default) \
  481. Out.indent(4) << #Name << ": " << DiagOpts->Name << "\n";
  482. #include "clang/Basic/DiagnosticOptions.def"
  483. Out.indent(4) << "Diagnostic flags:\n";
  484. for (const std::string &Warning : DiagOpts->Warnings)
  485. Out.indent(6) << "-W" << Warning << "\n";
  486. for (const std::string &Remark : DiagOpts->Remarks)
  487. Out.indent(6) << "-R" << Remark << "\n";
  488. return false;
  489. }
  490. bool ReadHeaderSearchOptions(const HeaderSearchOptions &HSOpts,
  491. StringRef SpecificModuleCachePath,
  492. bool Complain) override {
  493. Out.indent(2) << "Header search options:\n";
  494. Out.indent(4) << "System root [-isysroot=]: '" << HSOpts.Sysroot << "'\n";
  495. Out.indent(4) << "Resource dir [ -resource-dir=]: '" << HSOpts.ResourceDir << "'\n";
  496. Out.indent(4) << "Module Cache: '" << SpecificModuleCachePath << "'\n";
  497. DUMP_BOOLEAN(HSOpts.UseBuiltinIncludes,
  498. "Use builtin include directories [-nobuiltininc]");
  499. DUMP_BOOLEAN(HSOpts.UseStandardSystemIncludes,
  500. "Use standard system include directories [-nostdinc]");
  501. DUMP_BOOLEAN(HSOpts.UseStandardCXXIncludes,
  502. "Use standard C++ include directories [-nostdinc++]");
  503. DUMP_BOOLEAN(HSOpts.UseLibcxx,
  504. "Use libc++ (rather than libstdc++) [-stdlib=]");
  505. return false;
  506. }
  507. bool ReadPreprocessorOptions(const PreprocessorOptions &PPOpts,
  508. bool Complain,
  509. std::string &SuggestedPredefines) override {
  510. Out.indent(2) << "Preprocessor options:\n";
  511. DUMP_BOOLEAN(PPOpts.UsePredefines,
  512. "Uses compiler/target-specific predefines [-undef]");
  513. DUMP_BOOLEAN(PPOpts.DetailedRecord,
  514. "Uses detailed preprocessing record (for indexing)");
  515. if (!PPOpts.Macros.empty()) {
  516. Out.indent(4) << "Predefined macros:\n";
  517. }
  518. for (std::vector<std::pair<std::string, bool/*isUndef*/> >::const_iterator
  519. I = PPOpts.Macros.begin(), IEnd = PPOpts.Macros.end();
  520. I != IEnd; ++I) {
  521. Out.indent(6);
  522. if (I->second)
  523. Out << "-U";
  524. else
  525. Out << "-D";
  526. Out << I->first << "\n";
  527. }
  528. return false;
  529. }
  530. /// Indicates that a particular module file extension has been read.
  531. void readModuleFileExtension(
  532. const ModuleFileExtensionMetadata &Metadata) override {
  533. Out.indent(2) << "Module file extension '"
  534. << Metadata.BlockName << "' " << Metadata.MajorVersion
  535. << "." << Metadata.MinorVersion;
  536. if (!Metadata.UserInfo.empty()) {
  537. Out << ": ";
  538. Out.write_escaped(Metadata.UserInfo);
  539. }
  540. Out << "\n";
  541. }
  542. /// Tells the \c ASTReaderListener that we want to receive the
  543. /// input files of the AST file via \c visitInputFile.
  544. bool needsInputFileVisitation() override { return true; }
  545. /// Tells the \c ASTReaderListener that we want to receive the
  546. /// input files of the AST file via \c visitInputFile.
  547. bool needsSystemInputFileVisitation() override { return true; }
  548. /// Indicates that the AST file contains particular input file.
  549. ///
  550. /// \returns true to continue receiving the next input file, false to stop.
  551. bool visitInputFile(StringRef Filename, bool isSystem,
  552. bool isOverridden, bool isExplicitModule) override {
  553. Out.indent(2) << "Input file: " << Filename;
  554. if (isSystem || isOverridden || isExplicitModule) {
  555. Out << " [";
  556. if (isSystem) {
  557. Out << "System";
  558. if (isOverridden || isExplicitModule)
  559. Out << ", ";
  560. }
  561. if (isOverridden) {
  562. Out << "Overridden";
  563. if (isExplicitModule)
  564. Out << ", ";
  565. }
  566. if (isExplicitModule)
  567. Out << "ExplicitModule";
  568. Out << "]";
  569. }
  570. Out << "\n";
  571. return true;
  572. }
  573. /// Returns true if this \c ASTReaderListener wants to receive the
  574. /// imports of the AST file via \c visitImport, false otherwise.
  575. bool needsImportVisitation() const override { return true; }
  576. /// If needsImportVisitation returns \c true, this is called for each
  577. /// AST file imported by this AST file.
  578. void visitImport(StringRef ModuleName, StringRef Filename) override {
  579. Out.indent(2) << "Imports module '" << ModuleName
  580. << "': " << Filename.str() << "\n";
  581. }
  582. #undef DUMP_BOOLEAN
  583. };
  584. }
  585. bool DumpModuleInfoAction::BeginInvocation(CompilerInstance &CI) {
  586. // The Object file reader also supports raw ast files and there is no point in
  587. // being strict about the module file format in -module-file-info mode.
  588. CI.getHeaderSearchOpts().ModuleFormat = "obj";
  589. return true;
  590. }
  591. void DumpModuleInfoAction::ExecuteAction() {
  592. // Set up the output file.
  593. std::unique_ptr<llvm::raw_fd_ostream> OutFile;
  594. StringRef OutputFileName = getCompilerInstance().getFrontendOpts().OutputFile;
  595. if (!OutputFileName.empty() && OutputFileName != "-") {
  596. std::error_code EC;
  597. OutFile.reset(new llvm::raw_fd_ostream(OutputFileName.str(), EC,
  598. llvm::sys::fs::OF_Text));
  599. }
  600. llvm::raw_ostream &Out = OutFile.get()? *OutFile.get() : llvm::outs();
  601. Out << "Information for module file '" << getCurrentFile() << "':\n";
  602. auto &FileMgr = getCompilerInstance().getFileManager();
  603. auto Buffer = FileMgr.getBufferForFile(getCurrentFile());
  604. StringRef Magic = (*Buffer)->getMemBufferRef().getBuffer();
  605. bool IsRaw = (Magic.size() >= 4 && Magic[0] == 'C' && Magic[1] == 'P' &&
  606. Magic[2] == 'C' && Magic[3] == 'H');
  607. Out << " Module format: " << (IsRaw ? "raw" : "obj") << "\n";
  608. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  609. DumpModuleInfoListener Listener(Out);
  610. HeaderSearchOptions &HSOpts =
  611. PP.getHeaderSearchInfo().getHeaderSearchOpts();
  612. ASTReader::readASTFileControlBlock(
  613. getCurrentFile(), FileMgr, getCompilerInstance().getPCHContainerReader(),
  614. /*FindModuleFileExtensions=*/true, Listener,
  615. HSOpts.ModulesValidateDiagnosticOptions);
  616. }
  617. //===----------------------------------------------------------------------===//
  618. // Preprocessor Actions
  619. //===----------------------------------------------------------------------===//
  620. void DumpRawTokensAction::ExecuteAction() {
  621. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  622. SourceManager &SM = PP.getSourceManager();
  623. // Start lexing the specified input file.
  624. const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
  625. Lexer RawLex(SM.getMainFileID(), FromFile, SM, PP.getLangOpts());
  626. RawLex.SetKeepWhitespaceMode(true);
  627. Token RawTok;
  628. RawLex.LexFromRawLexer(RawTok);
  629. while (RawTok.isNot(tok::eof)) {
  630. PP.DumpToken(RawTok, true);
  631. llvm::errs() << "\n";
  632. RawLex.LexFromRawLexer(RawTok);
  633. }
  634. }
  635. void DumpTokensAction::ExecuteAction() {
  636. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  637. // Start preprocessing the specified input file.
  638. Token Tok;
  639. PP.EnterMainSourceFile();
  640. do {
  641. PP.Lex(Tok);
  642. PP.DumpToken(Tok, true);
  643. llvm::errs() << "\n";
  644. } while (Tok.isNot(tok::eof));
  645. }
  646. void PreprocessOnlyAction::ExecuteAction() {
  647. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  648. // Ignore unknown pragmas.
  649. PP.IgnorePragmas();
  650. Token Tok;
  651. // Start parsing the specified input file.
  652. PP.EnterMainSourceFile();
  653. do {
  654. PP.Lex(Tok);
  655. } while (Tok.isNot(tok::eof));
  656. }
  657. void PrintPreprocessedAction::ExecuteAction() {
  658. CompilerInstance &CI = getCompilerInstance();
  659. // Output file may need to be set to 'Binary', to avoid converting Unix style
  660. // line feeds (<LF>) to Microsoft style line feeds (<CR><LF>).
  661. //
  662. // Look to see what type of line endings the file uses. If there's a
  663. // CRLF, then we won't open the file up in binary mode. If there is
  664. // just an LF or CR, then we will open the file up in binary mode.
  665. // In this fashion, the output format should match the input format, unless
  666. // the input format has inconsistent line endings.
  667. //
  668. // This should be a relatively fast operation since most files won't have
  669. // all of their source code on a single line. However, that is still a
  670. // concern, so if we scan for too long, we'll just assume the file should
  671. // be opened in binary mode.
  672. bool BinaryMode = true;
  673. bool InvalidFile = false;
  674. const SourceManager& SM = CI.getSourceManager();
  675. const llvm::MemoryBuffer *Buffer = SM.getBuffer(SM.getMainFileID(),
  676. &InvalidFile);
  677. if (!InvalidFile) {
  678. const char *cur = Buffer->getBufferStart();
  679. const char *end = Buffer->getBufferEnd();
  680. const char *next = (cur != end) ? cur + 1 : end;
  681. // Limit ourselves to only scanning 256 characters into the source
  682. // file. This is mostly a sanity check in case the file has no
  683. // newlines whatsoever.
  684. if (end - cur > 256) end = cur + 256;
  685. while (next < end) {
  686. if (*cur == 0x0D) { // CR
  687. if (*next == 0x0A) // CRLF
  688. BinaryMode = false;
  689. break;
  690. } else if (*cur == 0x0A) // LF
  691. break;
  692. ++cur;
  693. ++next;
  694. }
  695. }
  696. std::unique_ptr<raw_ostream> OS =
  697. CI.createDefaultOutputFile(BinaryMode, getCurrentFileOrBufferName());
  698. if (!OS) return;
  699. // If we're preprocessing a module map, start by dumping the contents of the
  700. // module itself before switching to the input buffer.
  701. auto &Input = getCurrentInput();
  702. if (Input.getKind().getFormat() == InputKind::ModuleMap) {
  703. if (Input.isFile()) {
  704. (*OS) << "# 1 \"";
  705. OS->write_escaped(Input.getFile());
  706. (*OS) << "\"\n";
  707. }
  708. getCurrentModule()->print(*OS);
  709. (*OS) << "#pragma clang module contents\n";
  710. }
  711. DoPrintPreprocessedInput(CI.getPreprocessor(), OS.get(),
  712. CI.getPreprocessorOutputOpts());
  713. }
  714. void PrintPreambleAction::ExecuteAction() {
  715. switch (getCurrentFileKind().getLanguage()) {
  716. case InputKind::C:
  717. case InputKind::CXX:
  718. case InputKind::ObjC:
  719. case InputKind::ObjCXX:
  720. case InputKind::OpenCL:
  721. case InputKind::CUDA:
  722. case InputKind::HIP:
  723. break;
  724. case InputKind::Unknown:
  725. case InputKind::Asm:
  726. case InputKind::LLVM_IR:
  727. case InputKind::RenderScript:
  728. // We can't do anything with these.
  729. return;
  730. }
  731. // We don't expect to find any #include directives in a preprocessed input.
  732. if (getCurrentFileKind().isPreprocessed())
  733. return;
  734. CompilerInstance &CI = getCompilerInstance();
  735. auto Buffer = CI.getFileManager().getBufferForFile(getCurrentFile());
  736. if (Buffer) {
  737. unsigned Preamble =
  738. Lexer::ComputePreamble((*Buffer)->getBuffer(), CI.getLangOpts()).Size;
  739. llvm::outs().write((*Buffer)->getBufferStart(), Preamble);
  740. }
  741. }
  742. void DumpCompilerOptionsAction::ExecuteAction() {
  743. CompilerInstance &CI = getCompilerInstance();
  744. std::unique_ptr<raw_ostream> OSP =
  745. CI.createDefaultOutputFile(false, getCurrentFile());
  746. if (!OSP)
  747. return;
  748. raw_ostream &OS = *OSP;
  749. const Preprocessor &PP = CI.getPreprocessor();
  750. const LangOptions &LangOpts = PP.getLangOpts();
  751. // FIXME: Rather than manually format the JSON (which is awkward due to
  752. // needing to remove trailing commas), this should make use of a JSON library.
  753. // FIXME: Instead of printing enums as an integral value and specifying the
  754. // type as a separate field, use introspection to print the enumerator.
  755. OS << "{\n";
  756. OS << "\n\"features\" : [\n";
  757. {
  758. llvm::SmallString<128> Str;
  759. #define FEATURE(Name, Predicate) \
  760. ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
  761. .toVector(Str);
  762. #include "clang/Basic/Features.def"
  763. #undef FEATURE
  764. // Remove the newline and comma from the last entry to ensure this remains
  765. // valid JSON.
  766. OS << Str.substr(0, Str.size() - 2);
  767. }
  768. OS << "\n],\n";
  769. OS << "\n\"extensions\" : [\n";
  770. {
  771. llvm::SmallString<128> Str;
  772. #define EXTENSION(Name, Predicate) \
  773. ("\t{\"" #Name "\" : " + llvm::Twine(Predicate ? "true" : "false") + "},\n") \
  774. .toVector(Str);
  775. #include "clang/Basic/Features.def"
  776. #undef EXTENSION
  777. // Remove the newline and comma from the last entry to ensure this remains
  778. // valid JSON.
  779. OS << Str.substr(0, Str.size() - 2);
  780. }
  781. OS << "\n]\n";
  782. OS << "}";
  783. }
  784. void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() {
  785. CompilerInstance &CI = getCompilerInstance();
  786. SourceManager &SM = CI.getPreprocessor().getSourceManager();
  787. const llvm::MemoryBuffer *FromFile = SM.getBuffer(SM.getMainFileID());
  788. llvm::SmallString<1024> Output;
  789. llvm::SmallVector<minimize_source_to_dependency_directives::Token, 32> Toks;
  790. if (minimizeSourceToDependencyDirectives(
  791. FromFile->getBuffer(), Output, Toks, &CI.getDiagnostics(),
  792. SM.getLocForStartOfFile(SM.getMainFileID()))) {
  793. assert(CI.getDiagnostics().hasErrorOccurred() &&
  794. "no errors reported for failure");
  795. // Preprocess the source when verifying the diagnostics to capture the
  796. // 'expected' comments.
  797. if (CI.getDiagnosticOpts().VerifyDiagnostics) {
  798. // Make sure we don't emit new diagnostics!
  799. CI.getDiagnostics().setSuppressAllDiagnostics();
  800. Preprocessor &PP = getCompilerInstance().getPreprocessor();
  801. PP.EnterMainSourceFile();
  802. Token Tok;
  803. do {
  804. PP.Lex(Tok);
  805. } while (Tok.isNot(tok::eof));
  806. }
  807. return;
  808. }
  809. llvm::outs() << Output;
  810. }