FrontendActions.cpp 33 KB

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