FrontendActions.cpp 33 KB

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