llvm-project

Форк
0
/
FrontendAction.cpp 
1255 строк · 48.1 Кб
1
//===--- FrontendAction.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

9
#include "clang/Frontend/FrontendAction.h"
10
#include "clang/AST/ASTConsumer.h"
11
#include "clang/AST/ASTContext.h"
12
#include "clang/AST/DeclGroup.h"
13
#include "clang/Basic/Builtins.h"
14
#include "clang/Basic/DiagnosticOptions.h"
15
#include "clang/Basic/FileEntry.h"
16
#include "clang/Basic/LangStandard.h"
17
#include "clang/Basic/Sarif.h"
18
#include "clang/Basic/Stack.h"
19
#include "clang/Frontend/ASTUnit.h"
20
#include "clang/Frontend/CompilerInstance.h"
21
#include "clang/Frontend/FrontendDiagnostic.h"
22
#include "clang/Frontend/FrontendPluginRegistry.h"
23
#include "clang/Frontend/LayoutOverrideSource.h"
24
#include "clang/Frontend/MultiplexConsumer.h"
25
#include "clang/Frontend/SARIFDiagnosticPrinter.h"
26
#include "clang/Frontend/Utils.h"
27
#include "clang/Lex/HeaderSearch.h"
28
#include "clang/Lex/LiteralSupport.h"
29
#include "clang/Lex/Preprocessor.h"
30
#include "clang/Lex/PreprocessorOptions.h"
31
#include "clang/Parse/ParseAST.h"
32
#include "clang/Sema/HLSLExternalSemaSource.h"
33
#include "clang/Sema/MultiplexExternalSemaSource.h"
34
#include "clang/Serialization/ASTDeserializationListener.h"
35
#include "clang/Serialization/ASTReader.h"
36
#include "clang/Serialization/GlobalModuleIndex.h"
37
#include "llvm/ADT/ScopeExit.h"
38
#include "llvm/Support/BuryPointer.h"
39
#include "llvm/Support/ErrorHandling.h"
40
#include "llvm/Support/FileSystem.h"
41
#include "llvm/Support/Path.h"
42
#include "llvm/Support/Timer.h"
43
#include "llvm/Support/raw_ostream.h"
44
#include <memory>
45
#include <system_error>
46
using namespace clang;
47

48
LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
49

50
namespace {
51

52
class DelegatingDeserializationListener : public ASTDeserializationListener {
53
  ASTDeserializationListener *Previous;
54
  bool DeletePrevious;
55

56
public:
57
  explicit DelegatingDeserializationListener(
58
      ASTDeserializationListener *Previous, bool DeletePrevious)
59
      : Previous(Previous), DeletePrevious(DeletePrevious) {}
60
  ~DelegatingDeserializationListener() override {
61
    if (DeletePrevious)
62
      delete Previous;
63
  }
64

65
  DelegatingDeserializationListener(const DelegatingDeserializationListener &) =
66
      delete;
67
  DelegatingDeserializationListener &
68
  operator=(const DelegatingDeserializationListener &) = delete;
69

70
  void ReaderInitialized(ASTReader *Reader) override {
71
    if (Previous)
72
      Previous->ReaderInitialized(Reader);
73
  }
74
  void IdentifierRead(serialization::IdentifierID ID,
75
                      IdentifierInfo *II) override {
76
    if (Previous)
77
      Previous->IdentifierRead(ID, II);
78
  }
79
  void TypeRead(serialization::TypeIdx Idx, QualType T) override {
80
    if (Previous)
81
      Previous->TypeRead(Idx, T);
82
  }
83
  void DeclRead(GlobalDeclID ID, const Decl *D) override {
84
    if (Previous)
85
      Previous->DeclRead(ID, D);
86
  }
87
  void SelectorRead(serialization::SelectorID ID, Selector Sel) override {
88
    if (Previous)
89
      Previous->SelectorRead(ID, Sel);
90
  }
91
  void MacroDefinitionRead(serialization::PreprocessedEntityID PPID,
92
                           MacroDefinitionRecord *MD) override {
93
    if (Previous)
94
      Previous->MacroDefinitionRead(PPID, MD);
95
  }
96
};
97

98
/// Dumps deserialized declarations.
99
class DeserializedDeclsDumper : public DelegatingDeserializationListener {
100
public:
101
  explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
102
                                   bool DeletePrevious)
103
      : DelegatingDeserializationListener(Previous, DeletePrevious) {}
104

105
  void DeclRead(GlobalDeclID ID, const Decl *D) override {
106
    llvm::outs() << "PCH DECL: " << D->getDeclKindName();
107
    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
108
      llvm::outs() << " - ";
109
      ND->printQualifiedName(llvm::outs());
110
    }
111
    llvm::outs() << "\n";
112

113
    DelegatingDeserializationListener::DeclRead(ID, D);
114
  }
115
};
116

117
/// Checks deserialized declarations and emits error if a name
118
/// matches one given in command-line using -error-on-deserialized-decl.
119
class DeserializedDeclsChecker : public DelegatingDeserializationListener {
120
  ASTContext &Ctx;
121
  std::set<std::string> NamesToCheck;
122

123
public:
124
  DeserializedDeclsChecker(ASTContext &Ctx,
125
                           const std::set<std::string> &NamesToCheck,
126
                           ASTDeserializationListener *Previous,
127
                           bool DeletePrevious)
128
      : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
129
        NamesToCheck(NamesToCheck) {}
130

131
  void DeclRead(GlobalDeclID ID, const Decl *D) override {
132
    if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
133
      if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
134
        unsigned DiagID
135
          = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
136
                                                 "%0 was deserialized");
137
        Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
138
            << ND;
139
      }
140

141
    DelegatingDeserializationListener::DeclRead(ID, D);
142
  }
143
};
144

145
} // end anonymous namespace
146

147
FrontendAction::FrontendAction() : Instance(nullptr) {}
148

149
FrontendAction::~FrontendAction() {}
150

151
void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
152
                                     std::unique_ptr<ASTUnit> AST) {
153
  this->CurrentInput = CurrentInput;
154
  CurrentASTUnit = std::move(AST);
155
}
156

157
Module *FrontendAction::getCurrentModule() const {
158
  CompilerInstance &CI = getCompilerInstance();
159
  return CI.getPreprocessor().getHeaderSearchInfo().lookupModule(
160
      CI.getLangOpts().CurrentModule, SourceLocation(), /*AllowSearch*/false);
161
}
162

163
std::unique_ptr<ASTConsumer>
164
FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
165
                                         StringRef InFile) {
166
  std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
167
  if (!Consumer)
168
    return nullptr;
169

170
  // Validate -add-plugin args.
171
  bool FoundAllPlugins = true;
172
  for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
173
    bool Found = false;
174
    for (const FrontendPluginRegistry::entry &Plugin :
175
         FrontendPluginRegistry::entries()) {
176
      if (Plugin.getName() == Arg)
177
        Found = true;
178
    }
179
    if (!Found) {
180
      CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
181
      FoundAllPlugins = false;
182
    }
183
  }
184
  if (!FoundAllPlugins)
185
    return nullptr;
186

187
  // If there are no registered plugins we don't need to wrap the consumer
188
  if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
189
    return Consumer;
190

191
  // If this is a code completion run, avoid invoking the plugin consumers
192
  if (CI.hasCodeCompletionConsumer())
193
    return Consumer;
194

195
  // Collect the list of plugins that go before the main action (in Consumers)
196
  // or after it (in AfterConsumers)
197
  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
198
  std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
199
  for (const FrontendPluginRegistry::entry &Plugin :
200
       FrontendPluginRegistry::entries()) {
201
    std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
202
    PluginASTAction::ActionType ActionType = P->getActionType();
203
    if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
204
        ActionType == PluginASTAction::CmdlineBeforeMainAction) {
205
      // This is O(|plugins| * |add_plugins|), but since both numbers are
206
      // way below 50 in practice, that's ok.
207
      if (llvm::is_contained(CI.getFrontendOpts().AddPluginActions,
208
                             Plugin.getName())) {
209
        if (ActionType == PluginASTAction::CmdlineBeforeMainAction)
210
          ActionType = PluginASTAction::AddBeforeMainAction;
211
        else
212
          ActionType = PluginASTAction::AddAfterMainAction;
213
      }
214
    }
215
    if ((ActionType == PluginASTAction::AddBeforeMainAction ||
216
         ActionType == PluginASTAction::AddAfterMainAction) &&
217
        P->ParseArgs(
218
            CI,
219
            CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) {
220
      std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
221
      if (ActionType == PluginASTAction::AddBeforeMainAction) {
222
        Consumers.push_back(std::move(PluginConsumer));
223
      } else {
224
        AfterConsumers.push_back(std::move(PluginConsumer));
225
      }
226
    }
227
  }
228

229
  // Add to Consumers the main consumer, then all the plugins that go after it
230
  Consumers.push_back(std::move(Consumer));
231
  if (!AfterConsumers.empty()) {
232
    // If we have plugins after the main consumer, which may be the codegen
233
    // action, they likely will need the ASTContext, so don't clear it in the
234
    // codegen action.
235
    CI.getCodeGenOpts().ClearASTBeforeBackend = false;
236
    for (auto &C : AfterConsumers)
237
      Consumers.push_back(std::move(C));
238
  }
239

240
  return std::make_unique<MultiplexConsumer>(std::move(Consumers));
241
}
242

243
/// For preprocessed files, if the first line is the linemarker and specifies
244
/// the original source file name, use that name as the input file name.
245
/// Returns the location of the first token after the line marker directive.
246
///
247
/// \param CI The compiler instance.
248
/// \param InputFile Populated with the filename from the line marker.
249
/// \param IsModuleMap If \c true, add a line note corresponding to this line
250
///        directive. (We need to do this because the directive will not be
251
///        visited by the preprocessor.)
252
static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
253
                                           std::string &InputFile,
254
                                           bool IsModuleMap = false) {
255
  auto &SourceMgr = CI.getSourceManager();
256
  auto MainFileID = SourceMgr.getMainFileID();
257

258
  auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
259
  if (!MainFileBuf)
260
    return SourceLocation();
261

262
  std::unique_ptr<Lexer> RawLexer(
263
      new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
264

265
  // If the first line has the syntax of
266
  //
267
  // # NUM "FILENAME"
268
  //
269
  // we use FILENAME as the input file name.
270
  Token T;
271
  if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
272
    return SourceLocation();
273
  if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
274
      T.getKind() != tok::numeric_constant)
275
    return SourceLocation();
276

277
  unsigned LineNo;
278
  SourceLocation LineNoLoc = T.getLocation();
279
  if (IsModuleMap) {
280
    llvm::SmallString<16> Buffer;
281
    if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
282
            .getAsInteger(10, LineNo))
283
      return SourceLocation();
284
  }
285

286
  RawLexer->LexFromRawLexer(T);
287
  if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
288
    return SourceLocation();
289

290
  StringLiteralParser Literal(T, CI.getPreprocessor());
291
  if (Literal.hadError)
292
    return SourceLocation();
293
  RawLexer->LexFromRawLexer(T);
294
  if (T.isNot(tok::eof) && !T.isAtStartOfLine())
295
    return SourceLocation();
296
  InputFile = Literal.GetString().str();
297

298
  if (IsModuleMap)
299
    CI.getSourceManager().AddLineNote(
300
        LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
301
        false, SrcMgr::C_User_ModuleMap);
302

303
  return T.getLocation();
304
}
305

306
static SmallVectorImpl<char> &
307
operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
308
  Includes.append(RHS.begin(), RHS.end());
309
  return Includes;
310
}
311

312
static void addHeaderInclude(StringRef HeaderName,
313
                             SmallVectorImpl<char> &Includes,
314
                             const LangOptions &LangOpts,
315
                             bool IsExternC) {
316
  if (IsExternC && LangOpts.CPlusPlus)
317
    Includes += "extern \"C\" {\n";
318
  if (LangOpts.ObjC)
319
    Includes += "#import \"";
320
  else
321
    Includes += "#include \"";
322

323
  Includes += HeaderName;
324

325
  Includes += "\"\n";
326
  if (IsExternC && LangOpts.CPlusPlus)
327
    Includes += "}\n";
328
}
329

330
/// Collect the set of header includes needed to construct the given
331
/// module and update the TopHeaders file set of the module.
332
///
333
/// \param Module The module we're collecting includes from.
334
///
335
/// \param Includes Will be augmented with the set of \#includes or \#imports
336
/// needed to load all of the named headers.
337
static std::error_code collectModuleHeaderIncludes(
338
    const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
339
    ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl<char> &Includes) {
340
  // Don't collect any headers for unavailable modules.
341
  if (!Module->isAvailable())
342
    return std::error_code();
343

344
  // Resolve all lazy header directives to header files.
345
  ModMap.resolveHeaderDirectives(Module, /*File=*/std::nullopt);
346

347
  // If any headers are missing, we can't build this module. In most cases,
348
  // diagnostics for this should have already been produced; we only get here
349
  // if explicit stat information was provided.
350
  // FIXME: If the name resolves to a file with different stat information,
351
  // produce a better diagnostic.
352
  if (!Module->MissingHeaders.empty()) {
353
    auto &MissingHeader = Module->MissingHeaders.front();
354
    Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
355
      << MissingHeader.IsUmbrella << MissingHeader.FileName;
356
    return std::error_code();
357
  }
358

359
  // Add includes for each of these headers.
360
  for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
361
    for (Module::Header &H : Module->Headers[HK]) {
362
      Module->addTopHeader(H.Entry);
363
      // Use the path as specified in the module map file. We'll look for this
364
      // file relative to the module build directory (the directory containing
365
      // the module map file) so this will find the same file that we found
366
      // while parsing the module map.
367
      addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
368
                       Module->IsExternC);
369
    }
370
  }
371
  // Note that Module->PrivateHeaders will not be a TopHeader.
372

373
  if (std::optional<Module::Header> UmbrellaHeader =
374
          Module->getUmbrellaHeaderAsWritten()) {
375
    Module->addTopHeader(UmbrellaHeader->Entry);
376
    if (Module->Parent)
377
      // Include the umbrella header for submodules.
378
      addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
379
                       Includes, LangOpts, Module->IsExternC);
380
  } else if (std::optional<Module::DirectoryName> UmbrellaDir =
381
                 Module->getUmbrellaDirAsWritten()) {
382
    // Add all of the headers we find in this subdirectory.
383
    std::error_code EC;
384
    SmallString<128> DirNative;
385
    llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
386

387
    llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
388
    SmallVector<std::pair<std::string, FileEntryRef>, 8> Headers;
389
    for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
390
         Dir != End && !EC; Dir.increment(EC)) {
391
      // Check whether this entry has an extension typically associated with
392
      // headers.
393
      if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
394
               .Cases(".h", ".H", ".hh", ".hpp", true)
395
               .Default(false))
396
        continue;
397

398
      auto Header = FileMgr.getOptionalFileRef(Dir->path());
399
      // FIXME: This shouldn't happen unless there is a file system race. Is
400
      // that worth diagnosing?
401
      if (!Header)
402
        continue;
403

404
      // If this header is marked 'unavailable' in this module, don't include
405
      // it.
406
      if (ModMap.isHeaderUnavailableInModule(*Header, Module))
407
        continue;
408

409
      // Compute the relative path from the directory to this file.
410
      SmallVector<StringRef, 16> Components;
411
      auto PathIt = llvm::sys::path::rbegin(Dir->path());
412
      for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
413
        Components.push_back(*PathIt);
414
      SmallString<128> RelativeHeader(
415
          UmbrellaDir->PathRelativeToRootModuleDirectory);
416
      for (auto It = Components.rbegin(), End = Components.rend(); It != End;
417
           ++It)
418
        llvm::sys::path::append(RelativeHeader, *It);
419

420
      std::string RelName = RelativeHeader.c_str();
421
      Headers.push_back(std::make_pair(RelName, *Header));
422
    }
423

424
    if (EC)
425
      return EC;
426

427
    // Sort header paths and make the header inclusion order deterministic
428
    // across different OSs and filesystems.
429
    llvm::sort(Headers, llvm::less_first());
430
    for (auto &H : Headers) {
431
      // Include this header as part of the umbrella directory.
432
      Module->addTopHeader(H.second);
433
      addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC);
434
    }
435
  }
436

437
  // Recurse into submodules.
438
  for (auto *Submodule : Module->submodules())
439
    if (std::error_code Err = collectModuleHeaderIncludes(
440
            LangOpts, FileMgr, Diag, ModMap, Submodule, Includes))
441
      return Err;
442

443
  return std::error_code();
444
}
445

446
static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
447
                                        bool IsPreprocessed,
448
                                        std::string &PresumedModuleMapFile,
449
                                        unsigned &Offset) {
450
  auto &SrcMgr = CI.getSourceManager();
451
  HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
452

453
  // Map the current input to a file.
454
  FileID ModuleMapID = SrcMgr.getMainFileID();
455
  OptionalFileEntryRef ModuleMap = SrcMgr.getFileEntryRefForID(ModuleMapID);
456
  assert(ModuleMap && "MainFileID without FileEntry");
457

458
  // If the module map is preprocessed, handle the initial line marker;
459
  // line directives are not part of the module map syntax in general.
460
  Offset = 0;
461
  if (IsPreprocessed) {
462
    SourceLocation EndOfLineMarker =
463
        ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
464
    if (EndOfLineMarker.isValid())
465
      Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
466
  }
467

468
  // Load the module map file.
469
  if (HS.loadModuleMapFile(*ModuleMap, IsSystem, ModuleMapID, &Offset,
470
                           PresumedModuleMapFile))
471
    return true;
472

473
  if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
474
    Offset = 0;
475

476
  // Infer framework module if possible.
477
  if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) {
478
    SmallString<128> InferredFrameworkPath = ModuleMap->getDir().getName();
479
    llvm::sys::path::append(InferredFrameworkPath,
480
                            CI.getLangOpts().ModuleName + ".framework");
481
    if (auto Dir =
482
            CI.getFileManager().getOptionalDirectoryRef(InferredFrameworkPath))
483
      (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);
484
  }
485

486
  return false;
487
}
488

489
static Module *prepareToBuildModule(CompilerInstance &CI,
490
                                    StringRef ModuleMapFilename) {
491
  if (CI.getLangOpts().CurrentModule.empty()) {
492
    CI.getDiagnostics().Report(diag::err_missing_module_name);
493

494
    // FIXME: Eventually, we could consider asking whether there was just
495
    // a single module described in the module map, and use that as a
496
    // default. Then it would be fairly trivial to just "compile" a module
497
    // map with a single module (the common case).
498
    return nullptr;
499
  }
500

501
  // Dig out the module definition.
502
  HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
503
  Module *M = HS.lookupModule(CI.getLangOpts().CurrentModule, SourceLocation(),
504
                              /*AllowSearch=*/true);
505
  if (!M) {
506
    CI.getDiagnostics().Report(diag::err_missing_module)
507
      << CI.getLangOpts().CurrentModule << ModuleMapFilename;
508

509
    return nullptr;
510
  }
511

512
  // Check whether we can build this module at all.
513
  if (Preprocessor::checkModuleIsAvailable(CI.getLangOpts(), CI.getTarget(), *M,
514
                                           CI.getDiagnostics()))
515
    return nullptr;
516

517
  // Inform the preprocessor that includes from within the input buffer should
518
  // be resolved relative to the build directory of the module map file.
519
  CI.getPreprocessor().setMainFileDir(*M->Directory);
520

521
  // If the module was inferred from a different module map (via an expanded
522
  // umbrella module definition), track that fact.
523
  // FIXME: It would be preferable to fill this in as part of processing
524
  // the module map, rather than adding it after the fact.
525
  StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
526
  if (!OriginalModuleMapName.empty()) {
527
    auto OriginalModuleMap =
528
        CI.getFileManager().getOptionalFileRef(OriginalModuleMapName,
529
                                               /*openFile*/ true);
530
    if (!OriginalModuleMap) {
531
      CI.getDiagnostics().Report(diag::err_module_map_not_found)
532
        << OriginalModuleMapName;
533
      return nullptr;
534
    }
535
    if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
536
                                  CI.getSourceManager().getMainFileID())) {
537
      M->IsInferred = true;
538
      auto FileCharacter =
539
          M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
540
      FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
541
          *OriginalModuleMap, FileCharacter);
542
      CI.getPreprocessor()
543
          .getHeaderSearchInfo()
544
          .getModuleMap()
545
          .setInferredModuleAllowedBy(M, OriginalModuleMapFID);
546
    }
547
  }
548

549
  // If we're being run from the command-line, the module build stack will not
550
  // have been filled in yet, so complete it now in order to allow us to detect
551
  // module cycles.
552
  SourceManager &SourceMgr = CI.getSourceManager();
553
  if (SourceMgr.getModuleBuildStack().empty())
554
    SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
555
                                   FullSourceLoc(SourceLocation(), SourceMgr));
556
  return M;
557
}
558

559
/// Compute the input buffer that should be used to build the specified module.
560
static std::unique_ptr<llvm::MemoryBuffer>
561
getInputBufferForModule(CompilerInstance &CI, Module *M) {
562
  FileManager &FileMgr = CI.getFileManager();
563

564
  // Collect the set of #includes we need to build the module.
565
  SmallString<256> HeaderContents;
566
  std::error_code Err = std::error_code();
567
  if (std::optional<Module::Header> UmbrellaHeader =
568
          M->getUmbrellaHeaderAsWritten())
569
    addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
570
                     HeaderContents, CI.getLangOpts(), M->IsExternC);
571
  Err = collectModuleHeaderIncludes(
572
      CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
573
      CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), M,
574
      HeaderContents);
575

576
  if (Err) {
577
    CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
578
      << M->getFullModuleName() << Err.message();
579
    return nullptr;
580
  }
581

582
  return llvm::MemoryBuffer::getMemBufferCopy(
583
      HeaderContents, Module::getModuleInputBufferName());
584
}
585

586
bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
587
                                     const FrontendInputFile &RealInput) {
588
  FrontendInputFile Input(RealInput);
589
  assert(!Instance && "Already processing a source file!");
590
  assert(!Input.isEmpty() && "Unexpected empty filename!");
591
  setCurrentInput(Input);
592
  setCompilerInstance(&CI);
593

594
  bool HasBegunSourceFile = false;
595
  bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
596
                       usesPreprocessorOnly();
597

598
  // If we fail, reset state since the client will not end up calling the
599
  // matching EndSourceFile(). All paths that return true should release this.
600
  auto FailureCleanup = llvm::make_scope_exit([&]() {
601
    if (HasBegunSourceFile)
602
      CI.getDiagnosticClient().EndSourceFile();
603
    CI.setASTConsumer(nullptr);
604
    CI.clearOutputFiles(/*EraseFiles=*/true);
605
    CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
606
    setCurrentInput(FrontendInputFile());
607
    setCompilerInstance(nullptr);
608
  });
609

610
  if (!BeginInvocation(CI))
611
    return false;
612

613
  // If we're replaying the build of an AST file, import it and set up
614
  // the initial state from its build.
615
  if (ReplayASTFile) {
616
    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
617

618
    // The AST unit populates its own diagnostics engine rather than ours.
619
    IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(
620
        new DiagnosticsEngine(Diags->getDiagnosticIDs(),
621
                              &Diags->getDiagnosticOptions()));
622
    ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
623

624
    // FIXME: What if the input is a memory buffer?
625
    StringRef InputFile = Input.getFile();
626

627
    std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
628
        std::string(InputFile), CI.getPCHContainerReader(),
629
        ASTUnit::LoadPreprocessorOnly, ASTDiags, CI.getFileSystemOpts(),
630
        /*HeaderSearchOptions=*/nullptr);
631
    if (!AST)
632
      return false;
633

634
    // Options relating to how we treat the input (but not what we do with it)
635
    // are inherited from the AST unit.
636
    CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
637
    CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
638
    CI.getLangOpts() = AST->getLangOpts();
639

640
    // Set the shared objects, these are reset when we finish processing the
641
    // file, otherwise the CompilerInstance will happily destroy them.
642
    CI.setFileManager(&AST->getFileManager());
643
    CI.createSourceManager(CI.getFileManager());
644
    CI.getSourceManager().initializeForReplay(AST->getSourceManager());
645

646
    // Preload all the module files loaded transitively by the AST unit. Also
647
    // load all module map files that were parsed as part of building the AST
648
    // unit.
649
    if (auto ASTReader = AST->getASTReader()) {
650
      auto &MM = ASTReader->getModuleManager();
651
      auto &PrimaryModule = MM.getPrimaryModule();
652

653
      for (serialization::ModuleFile &MF : MM)
654
        if (&MF != &PrimaryModule)
655
          CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
656

657
      ASTReader->visitTopLevelModuleMaps(PrimaryModule, [&](FileEntryRef FE) {
658
        CI.getFrontendOpts().ModuleMapFiles.push_back(
659
            std::string(FE.getName()));
660
      });
661
    }
662

663
    // Set up the input file for replay purposes.
664
    auto Kind = AST->getInputKind();
665
    if (Kind.getFormat() == InputKind::ModuleMap) {
666
      Module *ASTModule =
667
          AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
668
              AST->getLangOpts().CurrentModule, SourceLocation(),
669
              /*AllowSearch*/ false);
670
      assert(ASTModule && "module file does not define its own module");
671
      Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
672
    } else {
673
      auto &OldSM = AST->getSourceManager();
674
      FileID ID = OldSM.getMainFileID();
675
      if (auto File = OldSM.getFileEntryRefForID(ID))
676
        Input = FrontendInputFile(File->getName(), Kind);
677
      else
678
        Input = FrontendInputFile(OldSM.getBufferOrFake(ID), Kind);
679
    }
680
    setCurrentInput(Input, std::move(AST));
681
  }
682

683
  // AST files follow a very different path, since they share objects via the
684
  // AST unit.
685
  if (Input.getKind().getFormat() == InputKind::Precompiled) {
686
    assert(!usesPreprocessorOnly() && "this case was handled above");
687
    assert(hasASTFileSupport() &&
688
           "This action does not have AST file support!");
689

690
    IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
691

692
    // FIXME: What if the input is a memory buffer?
693
    StringRef InputFile = Input.getFile();
694

695
    std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
696
        std::string(InputFile), CI.getPCHContainerReader(),
697
        ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(),
698
        CI.getHeaderSearchOptsPtr(), CI.getLangOptsPtr());
699

700
    if (!AST)
701
      return false;
702

703
    // Inform the diagnostic client we are processing a source file.
704
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
705
    HasBegunSourceFile = true;
706

707
    // Set the shared objects, these are reset when we finish processing the
708
    // file, otherwise the CompilerInstance will happily destroy them.
709
    CI.setFileManager(&AST->getFileManager());
710
    CI.setSourceManager(&AST->getSourceManager());
711
    CI.setPreprocessor(AST->getPreprocessorPtr());
712
    Preprocessor &PP = CI.getPreprocessor();
713
    PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
714
                                           PP.getLangOpts());
715
    CI.setASTContext(&AST->getASTContext());
716

717
    setCurrentInput(Input, std::move(AST));
718

719
    // Initialize the action.
720
    if (!BeginSourceFileAction(CI))
721
      return false;
722

723
    // Create the AST consumer.
724
    CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
725
    if (!CI.hasASTConsumer())
726
      return false;
727

728
    FailureCleanup.release();
729
    return true;
730
  }
731

732
  // Set up the file and source managers, if needed.
733
  if (!CI.hasFileManager()) {
734
    if (!CI.createFileManager()) {
735
      return false;
736
    }
737
  }
738
  if (!CI.hasSourceManager()) {
739
    CI.createSourceManager(CI.getFileManager());
740
    if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
741
      static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
742
          ->setSarifWriter(
743
              std::make_unique<SarifDocumentWriter>(CI.getSourceManager()));
744
    }
745
  }
746

747
  // Set up embedding for any specified files. Do this before we load any
748
  // source files, including the primary module map for the compilation.
749
  for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
750
    if (auto FE = CI.getFileManager().getOptionalFileRef(F, /*openFile*/true))
751
      CI.getSourceManager().setFileIsTransient(*FE);
752
    else
753
      CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
754
  }
755
  if (CI.getFrontendOpts().ModulesEmbedAllFiles)
756
    CI.getSourceManager().setAllFilesAreTransient(true);
757

758
  // IR files bypass the rest of initialization.
759
  if (Input.getKind().getLanguage() == Language::LLVM_IR) {
760
    if (!hasIRSupport()) {
761
      CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir)
762
          << Input.getFile();
763
      return false;
764
    }
765

766
    // Inform the diagnostic client we are processing a source file.
767
    CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
768
    HasBegunSourceFile = true;
769

770
    // Initialize the action.
771
    if (!BeginSourceFileAction(CI))
772
      return false;
773

774
    // Initialize the main file entry.
775
    if (!CI.InitializeSourceManager(CurrentInput))
776
      return false;
777

778
    FailureCleanup.release();
779
    return true;
780
  }
781

782
  // If the implicit PCH include is actually a directory, rather than
783
  // a single file, search for a suitable PCH file in that directory.
784
  if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
785
    FileManager &FileMgr = CI.getFileManager();
786
    PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
787
    StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
788
    std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
789
    if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) {
790
      std::error_code EC;
791
      SmallString<128> DirNative;
792
      llvm::sys::path::native(PCHDir->getName(), DirNative);
793
      bool Found = false;
794
      llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
795
      for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
796
                                         DirEnd;
797
           Dir != DirEnd && !EC; Dir.increment(EC)) {
798
        // Check whether this is an acceptable AST file.
799
        if (ASTReader::isAcceptableASTFile(
800
                Dir->path(), FileMgr, CI.getModuleCache(),
801
                CI.getPCHContainerReader(), CI.getLangOpts(),
802
                CI.getTargetOpts(), CI.getPreprocessorOpts(),
803
                SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
804
          PPOpts.ImplicitPCHInclude = std::string(Dir->path());
805
          Found = true;
806
          break;
807
        }
808
      }
809

810
      if (!Found) {
811
        CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
812
        return false;
813
      }
814
    }
815
  }
816

817
  // Set up the preprocessor if needed. When parsing model files the
818
  // preprocessor of the original source is reused.
819
  if (!isModelParsingAction())
820
    CI.createPreprocessor(getTranslationUnitKind());
821

822
  // Inform the diagnostic client we are processing a source file.
823
  CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
824
                                           &CI.getPreprocessor());
825
  HasBegunSourceFile = true;
826

827
  // Handle C++20 header units.
828
  // Here, the user has the option to specify that the header name should be
829
  // looked up in the pre-processor search paths (and the main filename as
830
  // passed by the driver might therefore be incomplete until that look-up).
831
  if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
832
      !Input.getKind().isPreprocessed()) {
833
    StringRef FileName = Input.getFile();
834
    InputKind Kind = Input.getKind();
835
    if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
836
      assert(CI.hasPreprocessor() &&
837
             "trying to build a header unit without a Pre-processor?");
838
      HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
839
      // Relative searches begin from CWD.
840
      auto Dir = CI.getFileManager().getOptionalDirectoryRef(".");
841
      SmallVector<std::pair<OptionalFileEntryRef, DirectoryEntryRef>, 1> CWD;
842
      CWD.push_back({std::nullopt, *Dir});
843
      OptionalFileEntryRef FE =
844
          HS.LookupFile(FileName, SourceLocation(),
845
                        /*Angled*/ Input.getKind().getHeaderUnitKind() ==
846
                            InputKind::HeaderUnit_System,
847
                        nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
848
                        nullptr, nullptr, nullptr);
849
      if (!FE) {
850
        CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
851
            << FileName;
852
        return false;
853
      }
854
      // We now have the filename...
855
      FileName = FE->getName();
856
      // ... still a header unit, but now use the path as written.
857
      Kind = Input.getKind().withHeaderUnit(InputKind::HeaderUnit_Abs);
858
      Input = FrontendInputFile(FileName, Kind, Input.isSystem());
859
    }
860
    // Unless the user has overridden the name, the header unit module name is
861
    // the pathname for the file.
862
    if (CI.getLangOpts().ModuleName.empty())
863
      CI.getLangOpts().ModuleName = std::string(FileName);
864
    CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
865
  }
866

867
  if (!CI.InitializeSourceManager(Input))
868
    return false;
869

870
  if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
871
      Input.getKind().isPreprocessed() && !usesPreprocessorOnly()) {
872
    // We have an input filename like foo.iih, but we want to find the right
873
    // module name (and original file, to build the map entry).
874
    // Check if the first line specifies the original source file name with a
875
    // linemarker.
876
    std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
877
    ReadOriginalFileName(CI, PresumedInputFile);
878
    // Unless the user overrides this, the module name is the name by which the
879
    // original file was known.
880
    if (CI.getLangOpts().ModuleName.empty())
881
      CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
882
    CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
883
  }
884

885
  // For module map files, we first parse the module map and synthesize a
886
  // "<module-includes>" buffer before more conventional processing.
887
  if (Input.getKind().getFormat() == InputKind::ModuleMap) {
888
    CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
889

890
    std::string PresumedModuleMapFile;
891
    unsigned OffsetToContents;
892
    if (loadModuleMapForModuleBuild(CI, Input.isSystem(),
893
                                    Input.isPreprocessed(),
894
                                    PresumedModuleMapFile, OffsetToContents))
895
      return false;
896

897
    auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
898
    if (!CurrentModule)
899
      return false;
900

901
    CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
902

903
    if (OffsetToContents)
904
      // If the module contents are in the same file, skip to them.
905
      CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
906
    else {
907
      // Otherwise, convert the module description to a suitable input buffer.
908
      auto Buffer = getInputBufferForModule(CI, CurrentModule);
909
      if (!Buffer)
910
        return false;
911

912
      // Reinitialize the main file entry to refer to the new input.
913
      auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
914
      auto &SourceMgr = CI.getSourceManager();
915
      auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
916
      assert(BufferID.isValid() && "couldn't create module buffer ID");
917
      SourceMgr.setMainFileID(BufferID);
918
    }
919
  }
920

921
  // Initialize the action.
922
  if (!BeginSourceFileAction(CI))
923
    return false;
924

925
  // If we were asked to load any module map files, do so now.
926
  for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
927
    if (auto File = CI.getFileManager().getOptionalFileRef(Filename))
928
      CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
929
          *File, /*IsSystem*/false);
930
    else
931
      CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
932
  }
933

934
  // If compiling implementation of a module, load its module map file now.
935
  (void)CI.getPreprocessor().getCurrentModuleImplementation();
936

937
  // Add a module declaration scope so that modules from -fmodule-map-file
938
  // arguments may shadow modules found implicitly in search paths.
939
  CI.getPreprocessor()
940
      .getHeaderSearchInfo()
941
      .getModuleMap()
942
      .finishModuleDeclarationScope();
943

944
  // Create the AST context and consumer unless this is a preprocessor only
945
  // action.
946
  if (!usesPreprocessorOnly()) {
947
    // Parsing a model file should reuse the existing ASTContext.
948
    if (!isModelParsingAction())
949
      CI.createASTContext();
950

951
    // For preprocessed files, check if the first line specifies the original
952
    // source file name with a linemarker.
953
    std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
954
    if (Input.isPreprocessed())
955
      ReadOriginalFileName(CI, PresumedInputFile);
956

957
    std::unique_ptr<ASTConsumer> Consumer =
958
        CreateWrappedASTConsumer(CI, PresumedInputFile);
959
    if (!Consumer)
960
      return false;
961

962
    // FIXME: should not overwrite ASTMutationListener when parsing model files?
963
    if (!isModelParsingAction())
964
      CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
965

966
    if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
967
      // Convert headers to PCH and chain them.
968
      IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
969
      source = createChainedIncludesSource(CI, FinalReader);
970
      if (!source)
971
        return false;
972
      CI.setASTReader(static_cast<ASTReader *>(FinalReader.get()));
973
      CI.getASTContext().setExternalSource(source);
974
    } else if (CI.getLangOpts().Modules ||
975
               !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
976
      // Use PCM or PCH.
977
      assert(hasPCHSupport() && "This action does not have PCH support!");
978
      ASTDeserializationListener *DeserialListener =
979
          Consumer->GetASTDeserializationListener();
980
      bool DeleteDeserialListener = false;
981
      if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
982
        DeserialListener = new DeserializedDeclsDumper(DeserialListener,
983
                                                       DeleteDeserialListener);
984
        DeleteDeserialListener = true;
985
      }
986
      if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
987
        DeserialListener = new DeserializedDeclsChecker(
988
            CI.getASTContext(),
989
            CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
990
            DeserialListener, DeleteDeserialListener);
991
        DeleteDeserialListener = true;
992
      }
993
      if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
994
        CI.createPCHExternalASTSource(
995
            CI.getPreprocessorOpts().ImplicitPCHInclude,
996
            CI.getPreprocessorOpts().DisablePCHOrModuleValidation,
997
            CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
998
            DeserialListener, DeleteDeserialListener);
999
        if (!CI.getASTContext().getExternalSource())
1000
          return false;
1001
      }
1002
      // If modules are enabled, create the AST reader before creating
1003
      // any builtins, so that all declarations know that they might be
1004
      // extended by an external source.
1005
      if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1006
          !CI.getASTContext().getExternalSource()) {
1007
        CI.createASTReader();
1008
        CI.getASTReader()->setDeserializationListener(DeserialListener,
1009
                                                      DeleteDeserialListener);
1010
      }
1011
    }
1012

1013
    CI.setASTConsumer(std::move(Consumer));
1014
    if (!CI.hasASTConsumer())
1015
      return false;
1016
  }
1017

1018
  // Initialize built-in info as long as we aren't using an external AST
1019
  // source.
1020
  if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
1021
      !CI.getASTContext().getExternalSource()) {
1022
    Preprocessor &PP = CI.getPreprocessor();
1023
    PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
1024
                                           PP.getLangOpts());
1025
  } else {
1026
    // FIXME: If this is a problem, recover from it by creating a multiplex
1027
    // source.
1028
    assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
1029
           "modules enabled but created an external source that "
1030
           "doesn't support modules");
1031
  }
1032

1033
  // If we were asked to load any module files, do so now.
1034
  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
1035
    serialization::ModuleFile *Loaded = nullptr;
1036
    if (!CI.loadModuleFile(ModuleFile, Loaded))
1037
      return false;
1038

1039
    if (Loaded && Loaded->StandardCXXModule)
1040
      CI.getDiagnostics().Report(
1041
          diag::warn_eagerly_load_for_standard_cplusplus_modules);
1042
  }
1043

1044
  // If there is a layout overrides file, attach an external AST source that
1045
  // provides the layouts from that file.
1046
  if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
1047
      CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
1048
    IntrusiveRefCntPtr<ExternalASTSource>
1049
      Override(new LayoutOverrideSource(
1050
                     CI.getFrontendOpts().OverrideRecordLayoutsFile));
1051
    CI.getASTContext().setExternalSource(Override);
1052
  }
1053

1054
  // Setup HLSL External Sema Source
1055
  if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1056
    IntrusiveRefCntPtr<ExternalSemaSource> HLSLSema(
1057
        new HLSLExternalSemaSource());
1058
    if (auto *SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1059
            CI.getASTContext().getExternalSource())) {
1060
      IntrusiveRefCntPtr<ExternalSemaSource> MultiSema(
1061
          new MultiplexExternalSemaSource(SemaSource, HLSLSema.get()));
1062
      CI.getASTContext().setExternalSource(MultiSema);
1063
    } else
1064
      CI.getASTContext().setExternalSource(HLSLSema);
1065
  }
1066

1067
  FailureCleanup.release();
1068
  return true;
1069
}
1070

1071
llvm::Error FrontendAction::Execute() {
1072
  CompilerInstance &CI = getCompilerInstance();
1073

1074
  if (CI.hasFrontendTimer()) {
1075
    llvm::TimeRegion Timer(CI.getFrontendTimer());
1076
    ExecuteAction();
1077
  }
1078
  else ExecuteAction();
1079

1080
  // If we are supposed to rebuild the global module index, do so now unless
1081
  // there were any module-build failures.
1082
  if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
1083
      CI.hasPreprocessor()) {
1084
    StringRef Cache =
1085
        CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
1086
    if (!Cache.empty()) {
1087
      if (llvm::Error Err = GlobalModuleIndex::writeIndex(
1088
              CI.getFileManager(), CI.getPCHContainerReader(), Cache)) {
1089
        // FIXME this drops the error on the floor, but
1090
        // Index/pch-from-libclang.c seems to rely on dropping at least some of
1091
        // the error conditions!
1092
        consumeError(std::move(Err));
1093
      }
1094
    }
1095
  }
1096

1097
  return llvm::Error::success();
1098
}
1099

1100
void FrontendAction::EndSourceFile() {
1101
  CompilerInstance &CI = getCompilerInstance();
1102

1103
  // Inform the diagnostic client we are done with this source file.
1104
  CI.getDiagnosticClient().EndSourceFile();
1105

1106
  // Inform the preprocessor we are done.
1107
  if (CI.hasPreprocessor())
1108
    CI.getPreprocessor().EndSourceFile();
1109

1110
  // Finalize the action.
1111
  EndSourceFileAction();
1112

1113
  // Sema references the ast consumer, so reset sema first.
1114
  //
1115
  // FIXME: There is more per-file stuff we could just drop here?
1116
  bool DisableFree = CI.getFrontendOpts().DisableFree;
1117
  if (DisableFree) {
1118
    CI.resetAndLeakSema();
1119
    CI.resetAndLeakASTContext();
1120
    llvm::BuryPointer(CI.takeASTConsumer().get());
1121
  } else {
1122
    CI.setSema(nullptr);
1123
    CI.setASTContext(nullptr);
1124
    CI.setASTConsumer(nullptr);
1125
  }
1126

1127
  if (CI.getFrontendOpts().ShowStats) {
1128
    llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
1129
    CI.getPreprocessor().PrintStats();
1130
    CI.getPreprocessor().getIdentifierTable().PrintStats();
1131
    CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
1132
    CI.getSourceManager().PrintStats();
1133
    llvm::errs() << "\n";
1134
  }
1135

1136
  // Cleanup the output streams, and erase the output files if instructed by the
1137
  // FrontendAction.
1138
  CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
1139

1140
  // The resources are owned by AST when the current file is AST.
1141
  // So we reset the resources here to avoid users accessing it
1142
  // accidently.
1143
  if (isCurrentFileAST()) {
1144
    if (DisableFree) {
1145
      CI.resetAndLeakPreprocessor();
1146
      CI.resetAndLeakSourceManager();
1147
      CI.resetAndLeakFileManager();
1148
      llvm::BuryPointer(std::move(CurrentASTUnit));
1149
    } else {
1150
      CI.setPreprocessor(nullptr);
1151
      CI.setSourceManager(nullptr);
1152
      CI.setFileManager(nullptr);
1153
    }
1154
  }
1155

1156
  setCompilerInstance(nullptr);
1157
  setCurrentInput(FrontendInputFile());
1158
  CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
1159
}
1160

1161
bool FrontendAction::shouldEraseOutputFiles() {
1162
  return getCompilerInstance().getDiagnostics().hasErrorOccurred();
1163
}
1164

1165
//===----------------------------------------------------------------------===//
1166
// Utility Actions
1167
//===----------------------------------------------------------------------===//
1168

1169
void ASTFrontendAction::ExecuteAction() {
1170
  CompilerInstance &CI = getCompilerInstance();
1171
  if (!CI.hasPreprocessor())
1172
    return;
1173
  // This is a fallback: If the client forgets to invoke this, we mark the
1174
  // current stack as the bottom. Though not optimal, this could help prevent
1175
  // stack overflow during deep recursion.
1176
  clang::noteBottomOfStack();
1177

1178
  // FIXME: Move the truncation aspect of this into Sema, we delayed this till
1179
  // here so the source manager would be initialized.
1180
  if (hasCodeCompletionSupport() &&
1181
      !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
1182
    CI.createCodeCompletionConsumer();
1183

1184
  // Use a code completion consumer?
1185
  CodeCompleteConsumer *CompletionConsumer = nullptr;
1186
  if (CI.hasCodeCompletionConsumer())
1187
    CompletionConsumer = &CI.getCodeCompletionConsumer();
1188

1189
  if (!CI.hasSema())
1190
    CI.createSema(getTranslationUnitKind(), CompletionConsumer);
1191

1192
  ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats,
1193
           CI.getFrontendOpts().SkipFunctionBodies);
1194
}
1195

1196
void PluginASTAction::anchor() { }
1197

1198
std::unique_ptr<ASTConsumer>
1199
PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
1200
                                              StringRef InFile) {
1201
  llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
1202
}
1203

1204
bool WrapperFrontendAction::PrepareToExecuteAction(CompilerInstance &CI) {
1205
  return WrappedAction->PrepareToExecuteAction(CI);
1206
}
1207
std::unique_ptr<ASTConsumer>
1208
WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
1209
                                         StringRef InFile) {
1210
  return WrappedAction->CreateASTConsumer(CI, InFile);
1211
}
1212
bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
1213
  return WrappedAction->BeginInvocation(CI);
1214
}
1215
bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI) {
1216
  WrappedAction->setCurrentInput(getCurrentInput());
1217
  WrappedAction->setCompilerInstance(&CI);
1218
  auto Ret = WrappedAction->BeginSourceFileAction(CI);
1219
  // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
1220
  setCurrentInput(WrappedAction->getCurrentInput());
1221
  return Ret;
1222
}
1223
void WrapperFrontendAction::ExecuteAction() {
1224
  WrappedAction->ExecuteAction();
1225
}
1226
void WrapperFrontendAction::EndSourceFile() { WrappedAction->EndSourceFile(); }
1227
void WrapperFrontendAction::EndSourceFileAction() {
1228
  WrappedAction->EndSourceFileAction();
1229
}
1230
bool WrapperFrontendAction::shouldEraseOutputFiles() {
1231
  return WrappedAction->shouldEraseOutputFiles();
1232
}
1233

1234
bool WrapperFrontendAction::usesPreprocessorOnly() const {
1235
  return WrappedAction->usesPreprocessorOnly();
1236
}
1237
TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() {
1238
  return WrappedAction->getTranslationUnitKind();
1239
}
1240
bool WrapperFrontendAction::hasPCHSupport() const {
1241
  return WrappedAction->hasPCHSupport();
1242
}
1243
bool WrapperFrontendAction::hasASTFileSupport() const {
1244
  return WrappedAction->hasASTFileSupport();
1245
}
1246
bool WrapperFrontendAction::hasIRSupport() const {
1247
  return WrappedAction->hasIRSupport();
1248
}
1249
bool WrapperFrontendAction::hasCodeCompletionSupport() const {
1250
  return WrappedAction->hasCodeCompletionSupport();
1251
}
1252

1253
WrapperFrontendAction::WrapperFrontendAction(
1254
    std::unique_ptr<FrontendAction> WrappedAction)
1255
  : WrappedAction(std::move(WrappedAction)) {}
1256

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.