xref: /freebsd-src/contrib/llvm-project/clang/lib/Frontend/FrontendAction.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===--- FrontendAction.cpp -----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric 
90b57cec5SDimitry Andric #include "clang/Frontend/FrontendAction.h"
100b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h"
110b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
120b57cec5SDimitry Andric #include "clang/AST/DeclGroup.h"
13480093f4SDimitry Andric #include "clang/Basic/Builtins.h"
14bdd1243dSDimitry Andric #include "clang/Basic/DiagnosticOptions.h"
15bdd1243dSDimitry Andric #include "clang/Basic/FileEntry.h"
16a7dea167SDimitry Andric #include "clang/Basic/LangStandard.h"
17bdd1243dSDimitry Andric #include "clang/Basic/Sarif.h"
188a4dda33SDimitry Andric #include "clang/Basic/Stack.h"
190b57cec5SDimitry Andric #include "clang/Frontend/ASTUnit.h"
200b57cec5SDimitry Andric #include "clang/Frontend/CompilerInstance.h"
210b57cec5SDimitry Andric #include "clang/Frontend/FrontendDiagnostic.h"
220b57cec5SDimitry Andric #include "clang/Frontend/FrontendPluginRegistry.h"
230b57cec5SDimitry Andric #include "clang/Frontend/LayoutOverrideSource.h"
240b57cec5SDimitry Andric #include "clang/Frontend/MultiplexConsumer.h"
25bdd1243dSDimitry Andric #include "clang/Frontend/SARIFDiagnosticPrinter.h"
260b57cec5SDimitry Andric #include "clang/Frontend/Utils.h"
270b57cec5SDimitry Andric #include "clang/Lex/HeaderSearch.h"
280b57cec5SDimitry Andric #include "clang/Lex/LiteralSupport.h"
290b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
300b57cec5SDimitry Andric #include "clang/Lex/PreprocessorOptions.h"
310b57cec5SDimitry Andric #include "clang/Parse/ParseAST.h"
32753f127fSDimitry Andric #include "clang/Sema/HLSLExternalSemaSource.h"
33bdd1243dSDimitry Andric #include "clang/Sema/MultiplexExternalSemaSource.h"
340b57cec5SDimitry Andric #include "clang/Serialization/ASTDeserializationListener.h"
350b57cec5SDimitry Andric #include "clang/Serialization/ASTReader.h"
360b57cec5SDimitry Andric #include "clang/Serialization/GlobalModuleIndex.h"
37349cc55cSDimitry Andric #include "llvm/ADT/ScopeExit.h"
380b57cec5SDimitry Andric #include "llvm/Support/BuryPointer.h"
390b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
400b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
410b57cec5SDimitry Andric #include "llvm/Support/Path.h"
420b57cec5SDimitry Andric #include "llvm/Support/Timer.h"
430b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
44bdd1243dSDimitry Andric #include <memory>
450b57cec5SDimitry Andric #include <system_error>
460b57cec5SDimitry Andric using namespace clang;
470b57cec5SDimitry Andric 
480b57cec5SDimitry Andric LLVM_INSTANTIATE_REGISTRY(FrontendPluginRegistry)
490b57cec5SDimitry Andric 
500b57cec5SDimitry Andric namespace {
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric class DelegatingDeserializationListener : public ASTDeserializationListener {
530b57cec5SDimitry Andric   ASTDeserializationListener *Previous;
540b57cec5SDimitry Andric   bool DeletePrevious;
550b57cec5SDimitry Andric 
560b57cec5SDimitry Andric public:
570b57cec5SDimitry Andric   explicit DelegatingDeserializationListener(
580b57cec5SDimitry Andric       ASTDeserializationListener *Previous, bool DeletePrevious)
590b57cec5SDimitry Andric       : Previous(Previous), DeletePrevious(DeletePrevious) {}
600b57cec5SDimitry Andric   ~DelegatingDeserializationListener() override {
610b57cec5SDimitry Andric     if (DeletePrevious)
620b57cec5SDimitry Andric       delete Previous;
630b57cec5SDimitry Andric   }
640b57cec5SDimitry Andric 
655f757f3fSDimitry Andric   DelegatingDeserializationListener(const DelegatingDeserializationListener &) =
665f757f3fSDimitry Andric       delete;
675f757f3fSDimitry Andric   DelegatingDeserializationListener &
685f757f3fSDimitry Andric   operator=(const DelegatingDeserializationListener &) = delete;
695f757f3fSDimitry Andric 
700b57cec5SDimitry Andric   void ReaderInitialized(ASTReader *Reader) override {
710b57cec5SDimitry Andric     if (Previous)
720b57cec5SDimitry Andric       Previous->ReaderInitialized(Reader);
730b57cec5SDimitry Andric   }
74*0fca6ea1SDimitry Andric   void IdentifierRead(serialization::IdentifierID ID,
750b57cec5SDimitry Andric                       IdentifierInfo *II) override {
760b57cec5SDimitry Andric     if (Previous)
770b57cec5SDimitry Andric       Previous->IdentifierRead(ID, II);
780b57cec5SDimitry Andric   }
790b57cec5SDimitry Andric   void TypeRead(serialization::TypeIdx Idx, QualType T) override {
800b57cec5SDimitry Andric     if (Previous)
810b57cec5SDimitry Andric       Previous->TypeRead(Idx, T);
820b57cec5SDimitry Andric   }
83*0fca6ea1SDimitry Andric   void DeclRead(GlobalDeclID ID, const Decl *D) override {
840b57cec5SDimitry Andric     if (Previous)
850b57cec5SDimitry Andric       Previous->DeclRead(ID, D);
860b57cec5SDimitry Andric   }
870b57cec5SDimitry Andric   void SelectorRead(serialization::SelectorID ID, Selector Sel) override {
880b57cec5SDimitry Andric     if (Previous)
890b57cec5SDimitry Andric       Previous->SelectorRead(ID, Sel);
900b57cec5SDimitry Andric   }
910b57cec5SDimitry Andric   void MacroDefinitionRead(serialization::PreprocessedEntityID PPID,
920b57cec5SDimitry Andric                            MacroDefinitionRecord *MD) override {
930b57cec5SDimitry Andric     if (Previous)
940b57cec5SDimitry Andric       Previous->MacroDefinitionRead(PPID, MD);
950b57cec5SDimitry Andric   }
960b57cec5SDimitry Andric };
970b57cec5SDimitry Andric 
980b57cec5SDimitry Andric /// Dumps deserialized declarations.
990b57cec5SDimitry Andric class DeserializedDeclsDumper : public DelegatingDeserializationListener {
1000b57cec5SDimitry Andric public:
1010b57cec5SDimitry Andric   explicit DeserializedDeclsDumper(ASTDeserializationListener *Previous,
1020b57cec5SDimitry Andric                                    bool DeletePrevious)
1030b57cec5SDimitry Andric       : DelegatingDeserializationListener(Previous, DeletePrevious) {}
1040b57cec5SDimitry Andric 
105*0fca6ea1SDimitry Andric   void DeclRead(GlobalDeclID ID, const Decl *D) override {
1060b57cec5SDimitry Andric     llvm::outs() << "PCH DECL: " << D->getDeclKindName();
1070b57cec5SDimitry Andric     if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) {
1080b57cec5SDimitry Andric       llvm::outs() << " - ";
1090b57cec5SDimitry Andric       ND->printQualifiedName(llvm::outs());
1100b57cec5SDimitry Andric     }
1110b57cec5SDimitry Andric     llvm::outs() << "\n";
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric     DelegatingDeserializationListener::DeclRead(ID, D);
1140b57cec5SDimitry Andric   }
1150b57cec5SDimitry Andric };
1160b57cec5SDimitry Andric 
1170b57cec5SDimitry Andric /// Checks deserialized declarations and emits error if a name
1180b57cec5SDimitry Andric /// matches one given in command-line using -error-on-deserialized-decl.
1190b57cec5SDimitry Andric class DeserializedDeclsChecker : public DelegatingDeserializationListener {
1200b57cec5SDimitry Andric   ASTContext &Ctx;
1210b57cec5SDimitry Andric   std::set<std::string> NamesToCheck;
1220b57cec5SDimitry Andric 
1230b57cec5SDimitry Andric public:
1240b57cec5SDimitry Andric   DeserializedDeclsChecker(ASTContext &Ctx,
1250b57cec5SDimitry Andric                            const std::set<std::string> &NamesToCheck,
1260b57cec5SDimitry Andric                            ASTDeserializationListener *Previous,
1270b57cec5SDimitry Andric                            bool DeletePrevious)
1280b57cec5SDimitry Andric       : DelegatingDeserializationListener(Previous, DeletePrevious), Ctx(Ctx),
1290b57cec5SDimitry Andric         NamesToCheck(NamesToCheck) {}
1300b57cec5SDimitry Andric 
131*0fca6ea1SDimitry Andric   void DeclRead(GlobalDeclID ID, const Decl *D) override {
1320b57cec5SDimitry Andric     if (const NamedDecl *ND = dyn_cast<NamedDecl>(D))
1330b57cec5SDimitry Andric       if (NamesToCheck.find(ND->getNameAsString()) != NamesToCheck.end()) {
1340b57cec5SDimitry Andric         unsigned DiagID
1350b57cec5SDimitry Andric           = Ctx.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error,
1360b57cec5SDimitry Andric                                                  "%0 was deserialized");
1370b57cec5SDimitry Andric         Ctx.getDiagnostics().Report(Ctx.getFullLoc(D->getLocation()), DiagID)
138e8d8bef9SDimitry Andric             << ND;
1390b57cec5SDimitry Andric       }
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric     DelegatingDeserializationListener::DeclRead(ID, D);
1420b57cec5SDimitry Andric   }
1430b57cec5SDimitry Andric };
1440b57cec5SDimitry Andric 
1450b57cec5SDimitry Andric } // end anonymous namespace
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric FrontendAction::FrontendAction() : Instance(nullptr) {}
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric FrontendAction::~FrontendAction() {}
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric void FrontendAction::setCurrentInput(const FrontendInputFile &CurrentInput,
1520b57cec5SDimitry Andric                                      std::unique_ptr<ASTUnit> AST) {
1530b57cec5SDimitry Andric   this->CurrentInput = CurrentInput;
1540b57cec5SDimitry Andric   CurrentASTUnit = std::move(AST);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
1570b57cec5SDimitry Andric Module *FrontendAction::getCurrentModule() const {
1580b57cec5SDimitry Andric   CompilerInstance &CI = getCompilerInstance();
1590b57cec5SDimitry Andric   return CI.getPreprocessor().getHeaderSearchInfo().lookupModule(
160349cc55cSDimitry Andric       CI.getLangOpts().CurrentModule, SourceLocation(), /*AllowSearch*/false);
1610b57cec5SDimitry Andric }
1620b57cec5SDimitry Andric 
1630b57cec5SDimitry Andric std::unique_ptr<ASTConsumer>
1640b57cec5SDimitry Andric FrontendAction::CreateWrappedASTConsumer(CompilerInstance &CI,
1650b57cec5SDimitry Andric                                          StringRef InFile) {
1660b57cec5SDimitry Andric   std::unique_ptr<ASTConsumer> Consumer = CreateASTConsumer(CI, InFile);
1670b57cec5SDimitry Andric   if (!Consumer)
1680b57cec5SDimitry Andric     return nullptr;
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   // Validate -add-plugin args.
1710b57cec5SDimitry Andric   bool FoundAllPlugins = true;
1720b57cec5SDimitry Andric   for (const std::string &Arg : CI.getFrontendOpts().AddPluginActions) {
1730b57cec5SDimitry Andric     bool Found = false;
1745ffd83dbSDimitry Andric     for (const FrontendPluginRegistry::entry &Plugin :
1755ffd83dbSDimitry Andric          FrontendPluginRegistry::entries()) {
1765ffd83dbSDimitry Andric       if (Plugin.getName() == Arg)
1770b57cec5SDimitry Andric         Found = true;
1780b57cec5SDimitry Andric     }
1790b57cec5SDimitry Andric     if (!Found) {
1800b57cec5SDimitry Andric       CI.getDiagnostics().Report(diag::err_fe_invalid_plugin_name) << Arg;
1810b57cec5SDimitry Andric       FoundAllPlugins = false;
1820b57cec5SDimitry Andric     }
1830b57cec5SDimitry Andric   }
1840b57cec5SDimitry Andric   if (!FoundAllPlugins)
1850b57cec5SDimitry Andric     return nullptr;
1860b57cec5SDimitry Andric 
1870b57cec5SDimitry Andric   // If there are no registered plugins we don't need to wrap the consumer
1880b57cec5SDimitry Andric   if (FrontendPluginRegistry::begin() == FrontendPluginRegistry::end())
1890b57cec5SDimitry Andric     return Consumer;
1900b57cec5SDimitry Andric 
1910b57cec5SDimitry Andric   // If this is a code completion run, avoid invoking the plugin consumers
1920b57cec5SDimitry Andric   if (CI.hasCodeCompletionConsumer())
1930b57cec5SDimitry Andric     return Consumer;
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   // Collect the list of plugins that go before the main action (in Consumers)
1960b57cec5SDimitry Andric   // or after it (in AfterConsumers)
1970b57cec5SDimitry Andric   std::vector<std::unique_ptr<ASTConsumer>> Consumers;
1980b57cec5SDimitry Andric   std::vector<std::unique_ptr<ASTConsumer>> AfterConsumers;
1995ffd83dbSDimitry Andric   for (const FrontendPluginRegistry::entry &Plugin :
2005ffd83dbSDimitry Andric        FrontendPluginRegistry::entries()) {
2015ffd83dbSDimitry Andric     std::unique_ptr<PluginASTAction> P = Plugin.instantiate();
2020b57cec5SDimitry Andric     PluginASTAction::ActionType ActionType = P->getActionType();
203349cc55cSDimitry Andric     if (ActionType == PluginASTAction::CmdlineAfterMainAction ||
204349cc55cSDimitry Andric         ActionType == PluginASTAction::CmdlineBeforeMainAction) {
2050b57cec5SDimitry Andric       // This is O(|plugins| * |add_plugins|), but since both numbers are
2060b57cec5SDimitry Andric       // way below 50 in practice, that's ok.
207bdd1243dSDimitry Andric       if (llvm::is_contained(CI.getFrontendOpts().AddPluginActions,
208bdd1243dSDimitry Andric                              Plugin.getName())) {
209349cc55cSDimitry Andric         if (ActionType == PluginASTAction::CmdlineBeforeMainAction)
210349cc55cSDimitry Andric           ActionType = PluginASTAction::AddBeforeMainAction;
211349cc55cSDimitry Andric         else
2120b57cec5SDimitry Andric           ActionType = PluginASTAction::AddAfterMainAction;
2130b57cec5SDimitry Andric       }
214349cc55cSDimitry Andric     }
2150b57cec5SDimitry Andric     if ((ActionType == PluginASTAction::AddBeforeMainAction ||
2160b57cec5SDimitry Andric          ActionType == PluginASTAction::AddAfterMainAction) &&
2175ffd83dbSDimitry Andric         P->ParseArgs(
2185ffd83dbSDimitry Andric             CI,
2195ffd83dbSDimitry Andric             CI.getFrontendOpts().PluginArgs[std::string(Plugin.getName())])) {
2200b57cec5SDimitry Andric       std::unique_ptr<ASTConsumer> PluginConsumer = P->CreateASTConsumer(CI, InFile);
2210b57cec5SDimitry Andric       if (ActionType == PluginASTAction::AddBeforeMainAction) {
2220b57cec5SDimitry Andric         Consumers.push_back(std::move(PluginConsumer));
2230b57cec5SDimitry Andric       } else {
2240b57cec5SDimitry Andric         AfterConsumers.push_back(std::move(PluginConsumer));
2250b57cec5SDimitry Andric       }
2260b57cec5SDimitry Andric     }
2270b57cec5SDimitry Andric   }
2280b57cec5SDimitry Andric 
2290b57cec5SDimitry Andric   // Add to Consumers the main consumer, then all the plugins that go after it
2300b57cec5SDimitry Andric   Consumers.push_back(std::move(Consumer));
231349cc55cSDimitry Andric   if (!AfterConsumers.empty()) {
232349cc55cSDimitry Andric     // If we have plugins after the main consumer, which may be the codegen
233349cc55cSDimitry Andric     // action, they likely will need the ASTContext, so don't clear it in the
234349cc55cSDimitry Andric     // codegen action.
235349cc55cSDimitry Andric     CI.getCodeGenOpts().ClearASTBeforeBackend = false;
236349cc55cSDimitry Andric     for (auto &C : AfterConsumers)
2370b57cec5SDimitry Andric       Consumers.push_back(std::move(C));
2380b57cec5SDimitry Andric   }
2390b57cec5SDimitry Andric 
240a7dea167SDimitry Andric   return std::make_unique<MultiplexConsumer>(std::move(Consumers));
2410b57cec5SDimitry Andric }
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric /// For preprocessed files, if the first line is the linemarker and specifies
2440b57cec5SDimitry Andric /// the original source file name, use that name as the input file name.
2450b57cec5SDimitry Andric /// Returns the location of the first token after the line marker directive.
2460b57cec5SDimitry Andric ///
2470b57cec5SDimitry Andric /// \param CI The compiler instance.
2480b57cec5SDimitry Andric /// \param InputFile Populated with the filename from the line marker.
2490b57cec5SDimitry Andric /// \param IsModuleMap If \c true, add a line note corresponding to this line
2500b57cec5SDimitry Andric ///        directive. (We need to do this because the directive will not be
2510b57cec5SDimitry Andric ///        visited by the preprocessor.)
2520b57cec5SDimitry Andric static SourceLocation ReadOriginalFileName(CompilerInstance &CI,
2530b57cec5SDimitry Andric                                            std::string &InputFile,
2540b57cec5SDimitry Andric                                            bool IsModuleMap = false) {
2550b57cec5SDimitry Andric   auto &SourceMgr = CI.getSourceManager();
2560b57cec5SDimitry Andric   auto MainFileID = SourceMgr.getMainFileID();
2570b57cec5SDimitry Andric 
258e8d8bef9SDimitry Andric   auto MainFileBuf = SourceMgr.getBufferOrNone(MainFileID);
259e8d8bef9SDimitry Andric   if (!MainFileBuf)
2600b57cec5SDimitry Andric     return SourceLocation();
2610b57cec5SDimitry Andric 
2620b57cec5SDimitry Andric   std::unique_ptr<Lexer> RawLexer(
263e8d8bef9SDimitry Andric       new Lexer(MainFileID, *MainFileBuf, SourceMgr, CI.getLangOpts()));
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   // If the first line has the syntax of
2660b57cec5SDimitry Andric   //
2670b57cec5SDimitry Andric   // # NUM "FILENAME"
2680b57cec5SDimitry Andric   //
2690b57cec5SDimitry Andric   // we use FILENAME as the input file name.
2700b57cec5SDimitry Andric   Token T;
2710b57cec5SDimitry Andric   if (RawLexer->LexFromRawLexer(T) || T.getKind() != tok::hash)
2720b57cec5SDimitry Andric     return SourceLocation();
2730b57cec5SDimitry Andric   if (RawLexer->LexFromRawLexer(T) || T.isAtStartOfLine() ||
2740b57cec5SDimitry Andric       T.getKind() != tok::numeric_constant)
2750b57cec5SDimitry Andric     return SourceLocation();
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   unsigned LineNo;
2780b57cec5SDimitry Andric   SourceLocation LineNoLoc = T.getLocation();
2790b57cec5SDimitry Andric   if (IsModuleMap) {
2800b57cec5SDimitry Andric     llvm::SmallString<16> Buffer;
2810b57cec5SDimitry Andric     if (Lexer::getSpelling(LineNoLoc, Buffer, SourceMgr, CI.getLangOpts())
2820b57cec5SDimitry Andric             .getAsInteger(10, LineNo))
2830b57cec5SDimitry Andric       return SourceLocation();
2840b57cec5SDimitry Andric   }
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   RawLexer->LexFromRawLexer(T);
2870b57cec5SDimitry Andric   if (T.isAtStartOfLine() || T.getKind() != tok::string_literal)
2880b57cec5SDimitry Andric     return SourceLocation();
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   StringLiteralParser Literal(T, CI.getPreprocessor());
2910b57cec5SDimitry Andric   if (Literal.hadError)
2920b57cec5SDimitry Andric     return SourceLocation();
2930b57cec5SDimitry Andric   RawLexer->LexFromRawLexer(T);
2940b57cec5SDimitry Andric   if (T.isNot(tok::eof) && !T.isAtStartOfLine())
2950b57cec5SDimitry Andric     return SourceLocation();
2960b57cec5SDimitry Andric   InputFile = Literal.GetString().str();
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   if (IsModuleMap)
2990b57cec5SDimitry Andric     CI.getSourceManager().AddLineNote(
3000b57cec5SDimitry Andric         LineNoLoc, LineNo, SourceMgr.getLineTableFilenameID(InputFile), false,
3010b57cec5SDimitry Andric         false, SrcMgr::C_User_ModuleMap);
3020b57cec5SDimitry Andric 
3030b57cec5SDimitry Andric   return T.getLocation();
3040b57cec5SDimitry Andric }
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric static SmallVectorImpl<char> &
3070b57cec5SDimitry Andric operator+=(SmallVectorImpl<char> &Includes, StringRef RHS) {
3080b57cec5SDimitry Andric   Includes.append(RHS.begin(), RHS.end());
3090b57cec5SDimitry Andric   return Includes;
3100b57cec5SDimitry Andric }
3110b57cec5SDimitry Andric 
3120b57cec5SDimitry Andric static void addHeaderInclude(StringRef HeaderName,
3130b57cec5SDimitry Andric                              SmallVectorImpl<char> &Includes,
3140b57cec5SDimitry Andric                              const LangOptions &LangOpts,
3150b57cec5SDimitry Andric                              bool IsExternC) {
3160b57cec5SDimitry Andric   if (IsExternC && LangOpts.CPlusPlus)
3170b57cec5SDimitry Andric     Includes += "extern \"C\" {\n";
3180b57cec5SDimitry Andric   if (LangOpts.ObjC)
3190b57cec5SDimitry Andric     Includes += "#import \"";
3200b57cec5SDimitry Andric   else
3210b57cec5SDimitry Andric     Includes += "#include \"";
3220b57cec5SDimitry Andric 
3230b57cec5SDimitry Andric   Includes += HeaderName;
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   Includes += "\"\n";
3260b57cec5SDimitry Andric   if (IsExternC && LangOpts.CPlusPlus)
3270b57cec5SDimitry Andric     Includes += "}\n";
3280b57cec5SDimitry Andric }
3290b57cec5SDimitry Andric 
3300b57cec5SDimitry Andric /// Collect the set of header includes needed to construct the given
3310b57cec5SDimitry Andric /// module and update the TopHeaders file set of the module.
3320b57cec5SDimitry Andric ///
3330b57cec5SDimitry Andric /// \param Module The module we're collecting includes from.
3340b57cec5SDimitry Andric ///
3350b57cec5SDimitry Andric /// \param Includes Will be augmented with the set of \#includes or \#imports
3360b57cec5SDimitry Andric /// needed to load all of the named headers.
3370b57cec5SDimitry Andric static std::error_code collectModuleHeaderIncludes(
3380b57cec5SDimitry Andric     const LangOptions &LangOpts, FileManager &FileMgr, DiagnosticsEngine &Diag,
3390b57cec5SDimitry Andric     ModuleMap &ModMap, clang::Module *Module, SmallVectorImpl<char> &Includes) {
3400b57cec5SDimitry Andric   // Don't collect any headers for unavailable modules.
3410b57cec5SDimitry Andric   if (!Module->isAvailable())
3420b57cec5SDimitry Andric     return std::error_code();
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric   // Resolve all lazy header directives to header files.
345bdd1243dSDimitry Andric   ModMap.resolveHeaderDirectives(Module, /*File=*/std::nullopt);
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   // If any headers are missing, we can't build this module. In most cases,
3480b57cec5SDimitry Andric   // diagnostics for this should have already been produced; we only get here
3490b57cec5SDimitry Andric   // if explicit stat information was provided.
3500b57cec5SDimitry Andric   // FIXME: If the name resolves to a file with different stat information,
3510b57cec5SDimitry Andric   // produce a better diagnostic.
3520b57cec5SDimitry Andric   if (!Module->MissingHeaders.empty()) {
3530b57cec5SDimitry Andric     auto &MissingHeader = Module->MissingHeaders.front();
3540b57cec5SDimitry Andric     Diag.Report(MissingHeader.FileNameLoc, diag::err_module_header_missing)
3550b57cec5SDimitry Andric       << MissingHeader.IsUmbrella << MissingHeader.FileName;
3560b57cec5SDimitry Andric     return std::error_code();
3570b57cec5SDimitry Andric   }
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   // Add includes for each of these headers.
3600b57cec5SDimitry Andric   for (auto HK : {Module::HK_Normal, Module::HK_Private}) {
3610b57cec5SDimitry Andric     for (Module::Header &H : Module->Headers[HK]) {
3620b57cec5SDimitry Andric       Module->addTopHeader(H.Entry);
3630b57cec5SDimitry Andric       // Use the path as specified in the module map file. We'll look for this
3640b57cec5SDimitry Andric       // file relative to the module build directory (the directory containing
3650b57cec5SDimitry Andric       // the module map file) so this will find the same file that we found
3660b57cec5SDimitry Andric       // while parsing the module map.
367fe6060f1SDimitry Andric       addHeaderInclude(H.PathRelativeToRootModuleDirectory, Includes, LangOpts,
368fe6060f1SDimitry Andric                        Module->IsExternC);
3690b57cec5SDimitry Andric     }
3700b57cec5SDimitry Andric   }
3710b57cec5SDimitry Andric   // Note that Module->PrivateHeaders will not be a TopHeader.
3720b57cec5SDimitry Andric 
37306c3fb27SDimitry Andric   if (std::optional<Module::Header> UmbrellaHeader =
37406c3fb27SDimitry Andric           Module->getUmbrellaHeaderAsWritten()) {
37506c3fb27SDimitry Andric     Module->addTopHeader(UmbrellaHeader->Entry);
3760b57cec5SDimitry Andric     if (Module->Parent)
3770b57cec5SDimitry Andric       // Include the umbrella header for submodules.
37806c3fb27SDimitry Andric       addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
379fe6060f1SDimitry Andric                        Includes, LangOpts, Module->IsExternC);
38006c3fb27SDimitry Andric   } else if (std::optional<Module::DirectoryName> UmbrellaDir =
38106c3fb27SDimitry Andric                  Module->getUmbrellaDirAsWritten()) {
3820b57cec5SDimitry Andric     // Add all of the headers we find in this subdirectory.
3830b57cec5SDimitry Andric     std::error_code EC;
3840b57cec5SDimitry Andric     SmallString<128> DirNative;
38506c3fb27SDimitry Andric     llvm::sys::path::native(UmbrellaDir->Entry.getName(), DirNative);
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric     llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
38806c3fb27SDimitry Andric     SmallVector<std::pair<std::string, FileEntryRef>, 8> Headers;
3890b57cec5SDimitry Andric     for (llvm::vfs::recursive_directory_iterator Dir(FS, DirNative, EC), End;
3900b57cec5SDimitry Andric          Dir != End && !EC; Dir.increment(EC)) {
3910b57cec5SDimitry Andric       // Check whether this entry has an extension typically associated with
3920b57cec5SDimitry Andric       // headers.
3930b57cec5SDimitry Andric       if (!llvm::StringSwitch<bool>(llvm::sys::path::extension(Dir->path()))
3940b57cec5SDimitry Andric                .Cases(".h", ".H", ".hh", ".hpp", true)
3950b57cec5SDimitry Andric                .Default(false))
3960b57cec5SDimitry Andric         continue;
3970b57cec5SDimitry Andric 
398bdd1243dSDimitry Andric       auto Header = FileMgr.getOptionalFileRef(Dir->path());
3990b57cec5SDimitry Andric       // FIXME: This shouldn't happen unless there is a file system race. Is
4000b57cec5SDimitry Andric       // that worth diagnosing?
4010b57cec5SDimitry Andric       if (!Header)
4020b57cec5SDimitry Andric         continue;
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric       // If this header is marked 'unavailable' in this module, don't include
4050b57cec5SDimitry Andric       // it.
406a7dea167SDimitry Andric       if (ModMap.isHeaderUnavailableInModule(*Header, Module))
4070b57cec5SDimitry Andric         continue;
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric       // Compute the relative path from the directory to this file.
4100b57cec5SDimitry Andric       SmallVector<StringRef, 16> Components;
4110b57cec5SDimitry Andric       auto PathIt = llvm::sys::path::rbegin(Dir->path());
4120b57cec5SDimitry Andric       for (int I = 0; I != Dir.level() + 1; ++I, ++PathIt)
4130b57cec5SDimitry Andric         Components.push_back(*PathIt);
414fe6060f1SDimitry Andric       SmallString<128> RelativeHeader(
41506c3fb27SDimitry Andric           UmbrellaDir->PathRelativeToRootModuleDirectory);
4160b57cec5SDimitry Andric       for (auto It = Components.rbegin(), End = Components.rend(); It != End;
4170b57cec5SDimitry Andric            ++It)
4180b57cec5SDimitry Andric         llvm::sys::path::append(RelativeHeader, *It);
4190b57cec5SDimitry Andric 
4205ffd83dbSDimitry Andric       std::string RelName = RelativeHeader.c_str();
4215ffd83dbSDimitry Andric       Headers.push_back(std::make_pair(RelName, *Header));
4220b57cec5SDimitry Andric     }
4230b57cec5SDimitry Andric 
4240b57cec5SDimitry Andric     if (EC)
4250b57cec5SDimitry Andric       return EC;
4265ffd83dbSDimitry Andric 
4275ffd83dbSDimitry Andric     // Sort header paths and make the header inclusion order deterministic
4285ffd83dbSDimitry Andric     // across different OSs and filesystems.
429fcaf7f86SDimitry Andric     llvm::sort(Headers, llvm::less_first());
4305ffd83dbSDimitry Andric     for (auto &H : Headers) {
4315ffd83dbSDimitry Andric       // Include this header as part of the umbrella directory.
4325ffd83dbSDimitry Andric       Module->addTopHeader(H.second);
4335ffd83dbSDimitry Andric       addHeaderInclude(H.first, Includes, LangOpts, Module->IsExternC);
4345ffd83dbSDimitry Andric     }
4350b57cec5SDimitry Andric   }
4360b57cec5SDimitry Andric 
4370b57cec5SDimitry Andric   // Recurse into submodules.
43806c3fb27SDimitry Andric   for (auto *Submodule : Module->submodules())
4390b57cec5SDimitry Andric     if (std::error_code Err = collectModuleHeaderIncludes(
44006c3fb27SDimitry Andric             LangOpts, FileMgr, Diag, ModMap, Submodule, Includes))
4410b57cec5SDimitry Andric       return Err;
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric   return std::error_code();
4440b57cec5SDimitry Andric }
4450b57cec5SDimitry Andric 
4460b57cec5SDimitry Andric static bool loadModuleMapForModuleBuild(CompilerInstance &CI, bool IsSystem,
4470b57cec5SDimitry Andric                                         bool IsPreprocessed,
4480b57cec5SDimitry Andric                                         std::string &PresumedModuleMapFile,
4490b57cec5SDimitry Andric                                         unsigned &Offset) {
4500b57cec5SDimitry Andric   auto &SrcMgr = CI.getSourceManager();
4510b57cec5SDimitry Andric   HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
4520b57cec5SDimitry Andric 
4530b57cec5SDimitry Andric   // Map the current input to a file.
4540b57cec5SDimitry Andric   FileID ModuleMapID = SrcMgr.getMainFileID();
45506c3fb27SDimitry Andric   OptionalFileEntryRef ModuleMap = SrcMgr.getFileEntryRefForID(ModuleMapID);
45606c3fb27SDimitry Andric   assert(ModuleMap && "MainFileID without FileEntry");
4570b57cec5SDimitry Andric 
4580b57cec5SDimitry Andric   // If the module map is preprocessed, handle the initial line marker;
4590b57cec5SDimitry Andric   // line directives are not part of the module map syntax in general.
4600b57cec5SDimitry Andric   Offset = 0;
4610b57cec5SDimitry Andric   if (IsPreprocessed) {
4620b57cec5SDimitry Andric     SourceLocation EndOfLineMarker =
4630b57cec5SDimitry Andric         ReadOriginalFileName(CI, PresumedModuleMapFile, /*IsModuleMap*/ true);
4640b57cec5SDimitry Andric     if (EndOfLineMarker.isValid())
4650b57cec5SDimitry Andric       Offset = CI.getSourceManager().getDecomposedLoc(EndOfLineMarker).second;
4660b57cec5SDimitry Andric   }
4670b57cec5SDimitry Andric 
4680b57cec5SDimitry Andric   // Load the module map file.
46906c3fb27SDimitry Andric   if (HS.loadModuleMapFile(*ModuleMap, IsSystem, ModuleMapID, &Offset,
4700b57cec5SDimitry Andric                            PresumedModuleMapFile))
4710b57cec5SDimitry Andric     return true;
4720b57cec5SDimitry Andric 
473e8d8bef9SDimitry Andric   if (SrcMgr.getBufferOrFake(ModuleMapID).getBufferSize() == Offset)
4740b57cec5SDimitry Andric     Offset = 0;
4750b57cec5SDimitry Andric 
47681ad6265SDimitry Andric   // Infer framework module if possible.
47781ad6265SDimitry Andric   if (HS.getModuleMap().canInferFrameworkModule(ModuleMap->getDir())) {
47806c3fb27SDimitry Andric     SmallString<128> InferredFrameworkPath = ModuleMap->getDir().getName();
47981ad6265SDimitry Andric     llvm::sys::path::append(InferredFrameworkPath,
48081ad6265SDimitry Andric                             CI.getLangOpts().ModuleName + ".framework");
48106c3fb27SDimitry Andric     if (auto Dir =
48206c3fb27SDimitry Andric             CI.getFileManager().getOptionalDirectoryRef(InferredFrameworkPath))
48381ad6265SDimitry Andric       (void)HS.getModuleMap().inferFrameworkModule(*Dir, IsSystem, nullptr);
48481ad6265SDimitry Andric   }
48581ad6265SDimitry Andric 
4860b57cec5SDimitry Andric   return false;
4870b57cec5SDimitry Andric }
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric static Module *prepareToBuildModule(CompilerInstance &CI,
4900b57cec5SDimitry Andric                                     StringRef ModuleMapFilename) {
4910b57cec5SDimitry Andric   if (CI.getLangOpts().CurrentModule.empty()) {
4920b57cec5SDimitry Andric     CI.getDiagnostics().Report(diag::err_missing_module_name);
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric     // FIXME: Eventually, we could consider asking whether there was just
4950b57cec5SDimitry Andric     // a single module described in the module map, and use that as a
4960b57cec5SDimitry Andric     // default. Then it would be fairly trivial to just "compile" a module
4970b57cec5SDimitry Andric     // map with a single module (the common case).
4980b57cec5SDimitry Andric     return nullptr;
4990b57cec5SDimitry Andric   }
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric   // Dig out the module definition.
5020b57cec5SDimitry Andric   HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
503349cc55cSDimitry Andric   Module *M = HS.lookupModule(CI.getLangOpts().CurrentModule, SourceLocation(),
504fe6060f1SDimitry Andric                               /*AllowSearch=*/true);
5050b57cec5SDimitry Andric   if (!M) {
5060b57cec5SDimitry Andric     CI.getDiagnostics().Report(diag::err_missing_module)
5070b57cec5SDimitry Andric       << CI.getLangOpts().CurrentModule << ModuleMapFilename;
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric     return nullptr;
5100b57cec5SDimitry Andric   }
5110b57cec5SDimitry Andric 
5120b57cec5SDimitry Andric   // Check whether we can build this module at all.
5135f757f3fSDimitry Andric   if (Preprocessor::checkModuleIsAvailable(CI.getLangOpts(), CI.getTarget(), *M,
5145f757f3fSDimitry Andric                                            CI.getDiagnostics()))
5150b57cec5SDimitry Andric     return nullptr;
5160b57cec5SDimitry Andric 
5170b57cec5SDimitry Andric   // Inform the preprocessor that includes from within the input buffer should
5180b57cec5SDimitry Andric   // be resolved relative to the build directory of the module map file.
51906c3fb27SDimitry Andric   CI.getPreprocessor().setMainFileDir(*M->Directory);
5200b57cec5SDimitry Andric 
5210b57cec5SDimitry Andric   // If the module was inferred from a different module map (via an expanded
5220b57cec5SDimitry Andric   // umbrella module definition), track that fact.
5230b57cec5SDimitry Andric   // FIXME: It would be preferable to fill this in as part of processing
5240b57cec5SDimitry Andric   // the module map, rather than adding it after the fact.
5250b57cec5SDimitry Andric   StringRef OriginalModuleMapName = CI.getFrontendOpts().OriginalModuleMap;
5260b57cec5SDimitry Andric   if (!OriginalModuleMapName.empty()) {
527a7dea167SDimitry Andric     auto OriginalModuleMap =
5285f757f3fSDimitry Andric         CI.getFileManager().getOptionalFileRef(OriginalModuleMapName,
5290b57cec5SDimitry Andric                                                /*openFile*/ true);
5300b57cec5SDimitry Andric     if (!OriginalModuleMap) {
5310b57cec5SDimitry Andric       CI.getDiagnostics().Report(diag::err_module_map_not_found)
5320b57cec5SDimitry Andric         << OriginalModuleMapName;
5330b57cec5SDimitry Andric       return nullptr;
5340b57cec5SDimitry Andric     }
5355f757f3fSDimitry Andric     if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
5360b57cec5SDimitry Andric                                   CI.getSourceManager().getMainFileID())) {
5370b57cec5SDimitry Andric       M->IsInferred = true;
538*0fca6ea1SDimitry Andric       auto FileCharacter =
539*0fca6ea1SDimitry Andric           M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
540*0fca6ea1SDimitry Andric       FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
541*0fca6ea1SDimitry Andric           *OriginalModuleMap, FileCharacter);
542*0fca6ea1SDimitry Andric       CI.getPreprocessor()
543*0fca6ea1SDimitry Andric           .getHeaderSearchInfo()
544*0fca6ea1SDimitry Andric           .getModuleMap()
545*0fca6ea1SDimitry Andric           .setInferredModuleAllowedBy(M, OriginalModuleMapFID);
5460b57cec5SDimitry Andric     }
5470b57cec5SDimitry Andric   }
5480b57cec5SDimitry Andric 
5490b57cec5SDimitry Andric   // If we're being run from the command-line, the module build stack will not
5500b57cec5SDimitry Andric   // have been filled in yet, so complete it now in order to allow us to detect
5510b57cec5SDimitry Andric   // module cycles.
5520b57cec5SDimitry Andric   SourceManager &SourceMgr = CI.getSourceManager();
5530b57cec5SDimitry Andric   if (SourceMgr.getModuleBuildStack().empty())
5540b57cec5SDimitry Andric     SourceMgr.pushModuleBuildStack(CI.getLangOpts().CurrentModule,
5550b57cec5SDimitry Andric                                    FullSourceLoc(SourceLocation(), SourceMgr));
5560b57cec5SDimitry Andric   return M;
5570b57cec5SDimitry Andric }
5580b57cec5SDimitry Andric 
5590b57cec5SDimitry Andric /// Compute the input buffer that should be used to build the specified module.
5600b57cec5SDimitry Andric static std::unique_ptr<llvm::MemoryBuffer>
5610b57cec5SDimitry Andric getInputBufferForModule(CompilerInstance &CI, Module *M) {
5620b57cec5SDimitry Andric   FileManager &FileMgr = CI.getFileManager();
5630b57cec5SDimitry Andric 
5640b57cec5SDimitry Andric   // Collect the set of #includes we need to build the module.
5650b57cec5SDimitry Andric   SmallString<256> HeaderContents;
5660b57cec5SDimitry Andric   std::error_code Err = std::error_code();
56706c3fb27SDimitry Andric   if (std::optional<Module::Header> UmbrellaHeader =
56806c3fb27SDimitry Andric           M->getUmbrellaHeaderAsWritten())
56906c3fb27SDimitry Andric     addHeaderInclude(UmbrellaHeader->PathRelativeToRootModuleDirectory,
570fe6060f1SDimitry Andric                      HeaderContents, CI.getLangOpts(), M->IsExternC);
5710b57cec5SDimitry Andric   Err = collectModuleHeaderIncludes(
5720b57cec5SDimitry Andric       CI.getLangOpts(), FileMgr, CI.getDiagnostics(),
5730b57cec5SDimitry Andric       CI.getPreprocessor().getHeaderSearchInfo().getModuleMap(), M,
5740b57cec5SDimitry Andric       HeaderContents);
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric   if (Err) {
5770b57cec5SDimitry Andric     CI.getDiagnostics().Report(diag::err_module_cannot_create_includes)
5780b57cec5SDimitry Andric       << M->getFullModuleName() << Err.message();
5790b57cec5SDimitry Andric     return nullptr;
5800b57cec5SDimitry Andric   }
5810b57cec5SDimitry Andric 
5820b57cec5SDimitry Andric   return llvm::MemoryBuffer::getMemBufferCopy(
5830b57cec5SDimitry Andric       HeaderContents, Module::getModuleInputBufferName());
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric 
5860b57cec5SDimitry Andric bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
5870b57cec5SDimitry Andric                                      const FrontendInputFile &RealInput) {
5880b57cec5SDimitry Andric   FrontendInputFile Input(RealInput);
5890b57cec5SDimitry Andric   assert(!Instance && "Already processing a source file!");
5900b57cec5SDimitry Andric   assert(!Input.isEmpty() && "Unexpected empty filename!");
5910b57cec5SDimitry Andric   setCurrentInput(Input);
5920b57cec5SDimitry Andric   setCompilerInstance(&CI);
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   bool HasBegunSourceFile = false;
5950b57cec5SDimitry Andric   bool ReplayASTFile = Input.getKind().getFormat() == InputKind::Precompiled &&
5960b57cec5SDimitry Andric                        usesPreprocessorOnly();
597349cc55cSDimitry Andric 
598349cc55cSDimitry Andric   // If we fail, reset state since the client will not end up calling the
599349cc55cSDimitry Andric   // matching EndSourceFile(). All paths that return true should release this.
600349cc55cSDimitry Andric   auto FailureCleanup = llvm::make_scope_exit([&]() {
601349cc55cSDimitry Andric     if (HasBegunSourceFile)
602349cc55cSDimitry Andric       CI.getDiagnosticClient().EndSourceFile();
603753f127fSDimitry Andric     CI.setASTConsumer(nullptr);
604349cc55cSDimitry Andric     CI.clearOutputFiles(/*EraseFiles=*/true);
605349cc55cSDimitry Andric     CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
606349cc55cSDimitry Andric     setCurrentInput(FrontendInputFile());
607349cc55cSDimitry Andric     setCompilerInstance(nullptr);
608349cc55cSDimitry Andric   });
609349cc55cSDimitry Andric 
6100b57cec5SDimitry Andric   if (!BeginInvocation(CI))
611349cc55cSDimitry Andric     return false;
6120b57cec5SDimitry Andric 
6130b57cec5SDimitry Andric   // If we're replaying the build of an AST file, import it and set up
6140b57cec5SDimitry Andric   // the initial state from its build.
6150b57cec5SDimitry Andric   if (ReplayASTFile) {
6160b57cec5SDimitry Andric     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric     // The AST unit populates its own diagnostics engine rather than ours.
6190b57cec5SDimitry Andric     IntrusiveRefCntPtr<DiagnosticsEngine> ASTDiags(
6200b57cec5SDimitry Andric         new DiagnosticsEngine(Diags->getDiagnosticIDs(),
6210b57cec5SDimitry Andric                               &Diags->getDiagnosticOptions()));
6220b57cec5SDimitry Andric     ASTDiags->setClient(Diags->getClient(), /*OwnsClient*/false);
6230b57cec5SDimitry Andric 
6240b57cec5SDimitry Andric     // FIXME: What if the input is a memory buffer?
6250b57cec5SDimitry Andric     StringRef InputFile = Input.getFile();
6260b57cec5SDimitry Andric 
6270b57cec5SDimitry Andric     std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
6285ffd83dbSDimitry Andric         std::string(InputFile), CI.getPCHContainerReader(),
6295ffd83dbSDimitry Andric         ASTUnit::LoadPreprocessorOnly, ASTDiags, CI.getFileSystemOpts(),
6305f757f3fSDimitry Andric         /*HeaderSearchOptions=*/nullptr);
6310b57cec5SDimitry Andric     if (!AST)
632349cc55cSDimitry Andric       return false;
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric     // Options relating to how we treat the input (but not what we do with it)
6350b57cec5SDimitry Andric     // are inherited from the AST unit.
6360b57cec5SDimitry Andric     CI.getHeaderSearchOpts() = AST->getHeaderSearchOpts();
6370b57cec5SDimitry Andric     CI.getPreprocessorOpts() = AST->getPreprocessorOpts();
6380b57cec5SDimitry Andric     CI.getLangOpts() = AST->getLangOpts();
6390b57cec5SDimitry Andric 
6400b57cec5SDimitry Andric     // Set the shared objects, these are reset when we finish processing the
6410b57cec5SDimitry Andric     // file, otherwise the CompilerInstance will happily destroy them.
6420b57cec5SDimitry Andric     CI.setFileManager(&AST->getFileManager());
6430b57cec5SDimitry Andric     CI.createSourceManager(CI.getFileManager());
6440b57cec5SDimitry Andric     CI.getSourceManager().initializeForReplay(AST->getSourceManager());
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric     // Preload all the module files loaded transitively by the AST unit. Also
6470b57cec5SDimitry Andric     // load all module map files that were parsed as part of building the AST
6480b57cec5SDimitry Andric     // unit.
6490b57cec5SDimitry Andric     if (auto ASTReader = AST->getASTReader()) {
6500b57cec5SDimitry Andric       auto &MM = ASTReader->getModuleManager();
6510b57cec5SDimitry Andric       auto &PrimaryModule = MM.getPrimaryModule();
6520b57cec5SDimitry Andric 
6530b57cec5SDimitry Andric       for (serialization::ModuleFile &MF : MM)
6540b57cec5SDimitry Andric         if (&MF != &PrimaryModule)
6550b57cec5SDimitry Andric           CI.getFrontendOpts().ModuleFiles.push_back(MF.FileName);
6560b57cec5SDimitry Andric 
657bdd1243dSDimitry Andric       ASTReader->visitTopLevelModuleMaps(PrimaryModule, [&](FileEntryRef FE) {
6585ffd83dbSDimitry Andric         CI.getFrontendOpts().ModuleMapFiles.push_back(
659bdd1243dSDimitry Andric             std::string(FE.getName()));
6600b57cec5SDimitry Andric       });
6610b57cec5SDimitry Andric     }
6620b57cec5SDimitry Andric 
6630b57cec5SDimitry Andric     // Set up the input file for replay purposes.
6640b57cec5SDimitry Andric     auto Kind = AST->getInputKind();
6650b57cec5SDimitry Andric     if (Kind.getFormat() == InputKind::ModuleMap) {
6660b57cec5SDimitry Andric       Module *ASTModule =
6670b57cec5SDimitry Andric           AST->getPreprocessor().getHeaderSearchInfo().lookupModule(
668349cc55cSDimitry Andric               AST->getLangOpts().CurrentModule, SourceLocation(),
669349cc55cSDimitry Andric               /*AllowSearch*/ false);
6700b57cec5SDimitry Andric       assert(ASTModule && "module file does not define its own module");
6710b57cec5SDimitry Andric       Input = FrontendInputFile(ASTModule->PresumedModuleMapFile, Kind);
6720b57cec5SDimitry Andric     } else {
6730b57cec5SDimitry Andric       auto &OldSM = AST->getSourceManager();
6740b57cec5SDimitry Andric       FileID ID = OldSM.getMainFileID();
6755f757f3fSDimitry Andric       if (auto File = OldSM.getFileEntryRefForID(ID))
6760b57cec5SDimitry Andric         Input = FrontendInputFile(File->getName(), Kind);
6770b57cec5SDimitry Andric       else
678e8d8bef9SDimitry Andric         Input = FrontendInputFile(OldSM.getBufferOrFake(ID), Kind);
6790b57cec5SDimitry Andric     }
6800b57cec5SDimitry Andric     setCurrentInput(Input, std::move(AST));
6810b57cec5SDimitry Andric   }
6820b57cec5SDimitry Andric 
6830b57cec5SDimitry Andric   // AST files follow a very different path, since they share objects via the
6840b57cec5SDimitry Andric   // AST unit.
6850b57cec5SDimitry Andric   if (Input.getKind().getFormat() == InputKind::Precompiled) {
6860b57cec5SDimitry Andric     assert(!usesPreprocessorOnly() && "this case was handled above");
6870b57cec5SDimitry Andric     assert(hasASTFileSupport() &&
6880b57cec5SDimitry Andric            "This action does not have AST file support!");
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric     // FIXME: What if the input is a memory buffer?
6930b57cec5SDimitry Andric     StringRef InputFile = Input.getFile();
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric     std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromASTFile(
6965ffd83dbSDimitry Andric         std::string(InputFile), CI.getPCHContainerReader(),
6975ffd83dbSDimitry Andric         ASTUnit::LoadEverything, Diags, CI.getFileSystemOpts(),
698*0fca6ea1SDimitry Andric         CI.getHeaderSearchOptsPtr(), CI.getLangOptsPtr());
6990b57cec5SDimitry Andric 
7000b57cec5SDimitry Andric     if (!AST)
701349cc55cSDimitry Andric       return false;
7020b57cec5SDimitry Andric 
7030b57cec5SDimitry Andric     // Inform the diagnostic client we are processing a source file.
7040b57cec5SDimitry Andric     CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
7050b57cec5SDimitry Andric     HasBegunSourceFile = true;
7060b57cec5SDimitry Andric 
7070b57cec5SDimitry Andric     // Set the shared objects, these are reset when we finish processing the
7080b57cec5SDimitry Andric     // file, otherwise the CompilerInstance will happily destroy them.
7090b57cec5SDimitry Andric     CI.setFileManager(&AST->getFileManager());
7100b57cec5SDimitry Andric     CI.setSourceManager(&AST->getSourceManager());
7110b57cec5SDimitry Andric     CI.setPreprocessor(AST->getPreprocessorPtr());
7120b57cec5SDimitry Andric     Preprocessor &PP = CI.getPreprocessor();
7130b57cec5SDimitry Andric     PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
7140b57cec5SDimitry Andric                                            PP.getLangOpts());
7150b57cec5SDimitry Andric     CI.setASTContext(&AST->getASTContext());
7160b57cec5SDimitry Andric 
7170b57cec5SDimitry Andric     setCurrentInput(Input, std::move(AST));
7180b57cec5SDimitry Andric 
7190b57cec5SDimitry Andric     // Initialize the action.
7200b57cec5SDimitry Andric     if (!BeginSourceFileAction(CI))
721349cc55cSDimitry Andric       return false;
7220b57cec5SDimitry Andric 
7230b57cec5SDimitry Andric     // Create the AST consumer.
7240b57cec5SDimitry Andric     CI.setASTConsumer(CreateWrappedASTConsumer(CI, InputFile));
7250b57cec5SDimitry Andric     if (!CI.hasASTConsumer())
726349cc55cSDimitry Andric       return false;
7270b57cec5SDimitry Andric 
728349cc55cSDimitry Andric     FailureCleanup.release();
7290b57cec5SDimitry Andric     return true;
7300b57cec5SDimitry Andric   }
7310b57cec5SDimitry Andric 
7320b57cec5SDimitry Andric   // Set up the file and source managers, if needed.
7330b57cec5SDimitry Andric   if (!CI.hasFileManager()) {
7340b57cec5SDimitry Andric     if (!CI.createFileManager()) {
735349cc55cSDimitry Andric       return false;
7360b57cec5SDimitry Andric     }
7370b57cec5SDimitry Andric   }
738bdd1243dSDimitry Andric   if (!CI.hasSourceManager()) {
7390b57cec5SDimitry Andric     CI.createSourceManager(CI.getFileManager());
740bdd1243dSDimitry Andric     if (CI.getDiagnosticOpts().getFormat() == DiagnosticOptions::SARIF) {
741bdd1243dSDimitry Andric       static_cast<SARIFDiagnosticPrinter *>(&CI.getDiagnosticClient())
742bdd1243dSDimitry Andric           ->setSarifWriter(
743bdd1243dSDimitry Andric               std::make_unique<SarifDocumentWriter>(CI.getSourceManager()));
744bdd1243dSDimitry Andric     }
745bdd1243dSDimitry Andric   }
7460b57cec5SDimitry Andric 
7470b57cec5SDimitry Andric   // Set up embedding for any specified files. Do this before we load any
7480b57cec5SDimitry Andric   // source files, including the primary module map for the compilation.
7490b57cec5SDimitry Andric   for (const auto &F : CI.getFrontendOpts().ModulesEmbedFiles) {
7505f757f3fSDimitry Andric     if (auto FE = CI.getFileManager().getOptionalFileRef(F, /*openFile*/true))
751a7dea167SDimitry Andric       CI.getSourceManager().setFileIsTransient(*FE);
7520b57cec5SDimitry Andric     else
7530b57cec5SDimitry Andric       CI.getDiagnostics().Report(diag::err_modules_embed_file_not_found) << F;
7540b57cec5SDimitry Andric   }
7550b57cec5SDimitry Andric   if (CI.getFrontendOpts().ModulesEmbedAllFiles)
7560b57cec5SDimitry Andric     CI.getSourceManager().setAllFilesAreTransient(true);
7570b57cec5SDimitry Andric 
7580b57cec5SDimitry Andric   // IR files bypass the rest of initialization.
759a7dea167SDimitry Andric   if (Input.getKind().getLanguage() == Language::LLVM_IR) {
760*0fca6ea1SDimitry Andric     if (!hasIRSupport()) {
761*0fca6ea1SDimitry Andric       CI.getDiagnostics().Report(diag::err_ast_action_on_llvm_ir)
762*0fca6ea1SDimitry Andric           << Input.getFile();
763*0fca6ea1SDimitry Andric       return false;
764*0fca6ea1SDimitry Andric     }
7650b57cec5SDimitry Andric 
7660b57cec5SDimitry Andric     // Inform the diagnostic client we are processing a source file.
7670b57cec5SDimitry Andric     CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(), nullptr);
7680b57cec5SDimitry Andric     HasBegunSourceFile = true;
7690b57cec5SDimitry Andric 
7700b57cec5SDimitry Andric     // Initialize the action.
7710b57cec5SDimitry Andric     if (!BeginSourceFileAction(CI))
772349cc55cSDimitry Andric       return false;
7730b57cec5SDimitry Andric 
7740b57cec5SDimitry Andric     // Initialize the main file entry.
7750b57cec5SDimitry Andric     if (!CI.InitializeSourceManager(CurrentInput))
776349cc55cSDimitry Andric       return false;
7770b57cec5SDimitry Andric 
778349cc55cSDimitry Andric     FailureCleanup.release();
7790b57cec5SDimitry Andric     return true;
7800b57cec5SDimitry Andric   }
7810b57cec5SDimitry Andric 
7820b57cec5SDimitry Andric   // If the implicit PCH include is actually a directory, rather than
7830b57cec5SDimitry Andric   // a single file, search for a suitable PCH file in that directory.
7840b57cec5SDimitry Andric   if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
7850b57cec5SDimitry Andric     FileManager &FileMgr = CI.getFileManager();
7860b57cec5SDimitry Andric     PreprocessorOptions &PPOpts = CI.getPreprocessorOpts();
7870b57cec5SDimitry Andric     StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
7880b57cec5SDimitry Andric     std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
78981ad6265SDimitry Andric     if (auto PCHDir = FileMgr.getOptionalDirectoryRef(PCHInclude)) {
7900b57cec5SDimitry Andric       std::error_code EC;
7910b57cec5SDimitry Andric       SmallString<128> DirNative;
79281ad6265SDimitry Andric       llvm::sys::path::native(PCHDir->getName(), DirNative);
7930b57cec5SDimitry Andric       bool Found = false;
7940b57cec5SDimitry Andric       llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
7950b57cec5SDimitry Andric       for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
7960b57cec5SDimitry Andric                                          DirEnd;
7970b57cec5SDimitry Andric            Dir != DirEnd && !EC; Dir.increment(EC)) {
7980b57cec5SDimitry Andric         // Check whether this is an acceptable AST file.
7990b57cec5SDimitry Andric         if (ASTReader::isAcceptableASTFile(
800bdd1243dSDimitry Andric                 Dir->path(), FileMgr, CI.getModuleCache(),
801bdd1243dSDimitry Andric                 CI.getPCHContainerReader(), CI.getLangOpts(),
802bdd1243dSDimitry Andric                 CI.getTargetOpts(), CI.getPreprocessorOpts(),
80361cfbce3SDimitry Andric                 SpecificModuleCachePath, /*RequireStrictOptionMatches=*/true)) {
8045ffd83dbSDimitry Andric           PPOpts.ImplicitPCHInclude = std::string(Dir->path());
8050b57cec5SDimitry Andric           Found = true;
8060b57cec5SDimitry Andric           break;
8070b57cec5SDimitry Andric         }
8080b57cec5SDimitry Andric       }
8090b57cec5SDimitry Andric 
8100b57cec5SDimitry Andric       if (!Found) {
8110b57cec5SDimitry Andric         CI.getDiagnostics().Report(diag::err_fe_no_pch_in_dir) << PCHInclude;
812349cc55cSDimitry Andric         return false;
8130b57cec5SDimitry Andric       }
8140b57cec5SDimitry Andric     }
8150b57cec5SDimitry Andric   }
8160b57cec5SDimitry Andric 
8170b57cec5SDimitry Andric   // Set up the preprocessor if needed. When parsing model files the
8180b57cec5SDimitry Andric   // preprocessor of the original source is reused.
8190b57cec5SDimitry Andric   if (!isModelParsingAction())
8200b57cec5SDimitry Andric     CI.createPreprocessor(getTranslationUnitKind());
8210b57cec5SDimitry Andric 
8220b57cec5SDimitry Andric   // Inform the diagnostic client we are processing a source file.
8230b57cec5SDimitry Andric   CI.getDiagnosticClient().BeginSourceFile(CI.getLangOpts(),
8240b57cec5SDimitry Andric                                            &CI.getPreprocessor());
8250b57cec5SDimitry Andric   HasBegunSourceFile = true;
8260b57cec5SDimitry Andric 
82781ad6265SDimitry Andric   // Handle C++20 header units.
82881ad6265SDimitry Andric   // Here, the user has the option to specify that the header name should be
82981ad6265SDimitry Andric   // looked up in the pre-processor search paths (and the main filename as
83081ad6265SDimitry Andric   // passed by the driver might therefore be incomplete until that look-up).
83181ad6265SDimitry Andric   if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
83281ad6265SDimitry Andric       !Input.getKind().isPreprocessed()) {
83381ad6265SDimitry Andric     StringRef FileName = Input.getFile();
83481ad6265SDimitry Andric     InputKind Kind = Input.getKind();
83581ad6265SDimitry Andric     if (Kind.getHeaderUnitKind() != InputKind::HeaderUnit_Abs) {
83681ad6265SDimitry Andric       assert(CI.hasPreprocessor() &&
83781ad6265SDimitry Andric              "trying to build a header unit without a Pre-processor?");
83881ad6265SDimitry Andric       HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
83981ad6265SDimitry Andric       // Relative searches begin from CWD.
84006c3fb27SDimitry Andric       auto Dir = CI.getFileManager().getOptionalDirectoryRef(".");
8415f757f3fSDimitry Andric       SmallVector<std::pair<OptionalFileEntryRef, DirectoryEntryRef>, 1> CWD;
8425f757f3fSDimitry Andric       CWD.push_back({std::nullopt, *Dir});
843bdd1243dSDimitry Andric       OptionalFileEntryRef FE =
84481ad6265SDimitry Andric           HS.LookupFile(FileName, SourceLocation(),
84581ad6265SDimitry Andric                         /*Angled*/ Input.getKind().getHeaderUnitKind() ==
84681ad6265SDimitry Andric                             InputKind::HeaderUnit_System,
84781ad6265SDimitry Andric                         nullptr, nullptr, CWD, nullptr, nullptr, nullptr,
84881ad6265SDimitry Andric                         nullptr, nullptr, nullptr);
84981ad6265SDimitry Andric       if (!FE) {
85081ad6265SDimitry Andric         CI.getDiagnostics().Report(diag::err_module_header_file_not_found)
85181ad6265SDimitry Andric             << FileName;
85281ad6265SDimitry Andric         return false;
85381ad6265SDimitry Andric       }
85481ad6265SDimitry Andric       // We now have the filename...
8555f757f3fSDimitry Andric       FileName = FE->getName();
85681ad6265SDimitry Andric       // ... still a header unit, but now use the path as written.
85781ad6265SDimitry Andric       Kind = Input.getKind().withHeaderUnit(InputKind::HeaderUnit_Abs);
85881ad6265SDimitry Andric       Input = FrontendInputFile(FileName, Kind, Input.isSystem());
85981ad6265SDimitry Andric     }
86081ad6265SDimitry Andric     // Unless the user has overridden the name, the header unit module name is
86181ad6265SDimitry Andric     // the pathname for the file.
86281ad6265SDimitry Andric     if (CI.getLangOpts().ModuleName.empty())
86381ad6265SDimitry Andric       CI.getLangOpts().ModuleName = std::string(FileName);
86481ad6265SDimitry Andric     CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
86581ad6265SDimitry Andric   }
86681ad6265SDimitry Andric 
8670b57cec5SDimitry Andric   if (!CI.InitializeSourceManager(Input))
868349cc55cSDimitry Andric     return false;
8690b57cec5SDimitry Andric 
87081ad6265SDimitry Andric   if (CI.getLangOpts().CPlusPlusModules && Input.getKind().isHeaderUnit() &&
87181ad6265SDimitry Andric       Input.getKind().isPreprocessed() && !usesPreprocessorOnly()) {
87281ad6265SDimitry Andric     // We have an input filename like foo.iih, but we want to find the right
87381ad6265SDimitry Andric     // module name (and original file, to build the map entry).
87481ad6265SDimitry Andric     // Check if the first line specifies the original source file name with a
87581ad6265SDimitry Andric     // linemarker.
87681ad6265SDimitry Andric     std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
87781ad6265SDimitry Andric     ReadOriginalFileName(CI, PresumedInputFile);
87881ad6265SDimitry Andric     // Unless the user overrides this, the module name is the name by which the
87981ad6265SDimitry Andric     // original file was known.
88081ad6265SDimitry Andric     if (CI.getLangOpts().ModuleName.empty())
88181ad6265SDimitry Andric       CI.getLangOpts().ModuleName = std::string(PresumedInputFile);
88281ad6265SDimitry Andric     CI.getLangOpts().CurrentModule = CI.getLangOpts().ModuleName;
88381ad6265SDimitry Andric   }
88481ad6265SDimitry Andric 
8850b57cec5SDimitry Andric   // For module map files, we first parse the module map and synthesize a
8860b57cec5SDimitry Andric   // "<module-includes>" buffer before more conventional processing.
8870b57cec5SDimitry Andric   if (Input.getKind().getFormat() == InputKind::ModuleMap) {
8880b57cec5SDimitry Andric     CI.getLangOpts().setCompilingModule(LangOptions::CMK_ModuleMap);
8890b57cec5SDimitry Andric 
8900b57cec5SDimitry Andric     std::string PresumedModuleMapFile;
8910b57cec5SDimitry Andric     unsigned OffsetToContents;
8920b57cec5SDimitry Andric     if (loadModuleMapForModuleBuild(CI, Input.isSystem(),
8930b57cec5SDimitry Andric                                     Input.isPreprocessed(),
8940b57cec5SDimitry Andric                                     PresumedModuleMapFile, OffsetToContents))
895349cc55cSDimitry Andric       return false;
8960b57cec5SDimitry Andric 
8970b57cec5SDimitry Andric     auto *CurrentModule = prepareToBuildModule(CI, Input.getFile());
8980b57cec5SDimitry Andric     if (!CurrentModule)
899349cc55cSDimitry Andric       return false;
9000b57cec5SDimitry Andric 
9010b57cec5SDimitry Andric     CurrentModule->PresumedModuleMapFile = PresumedModuleMapFile;
9020b57cec5SDimitry Andric 
9030b57cec5SDimitry Andric     if (OffsetToContents)
9040b57cec5SDimitry Andric       // If the module contents are in the same file, skip to them.
9050b57cec5SDimitry Andric       CI.getPreprocessor().setSkipMainFilePreamble(OffsetToContents, true);
9060b57cec5SDimitry Andric     else {
9070b57cec5SDimitry Andric       // Otherwise, convert the module description to a suitable input buffer.
9080b57cec5SDimitry Andric       auto Buffer = getInputBufferForModule(CI, CurrentModule);
9090b57cec5SDimitry Andric       if (!Buffer)
910349cc55cSDimitry Andric         return false;
9110b57cec5SDimitry Andric 
9120b57cec5SDimitry Andric       // Reinitialize the main file entry to refer to the new input.
9130b57cec5SDimitry Andric       auto Kind = CurrentModule->IsSystem ? SrcMgr::C_System : SrcMgr::C_User;
9140b57cec5SDimitry Andric       auto &SourceMgr = CI.getSourceManager();
9150b57cec5SDimitry Andric       auto BufferID = SourceMgr.createFileID(std::move(Buffer), Kind);
9165ffd83dbSDimitry Andric       assert(BufferID.isValid() && "couldn't create module buffer ID");
9170b57cec5SDimitry Andric       SourceMgr.setMainFileID(BufferID);
9180b57cec5SDimitry Andric     }
9190b57cec5SDimitry Andric   }
9200b57cec5SDimitry Andric 
9210b57cec5SDimitry Andric   // Initialize the action.
9220b57cec5SDimitry Andric   if (!BeginSourceFileAction(CI))
923349cc55cSDimitry Andric     return false;
9240b57cec5SDimitry Andric 
9250b57cec5SDimitry Andric   // If we were asked to load any module map files, do so now.
9260b57cec5SDimitry Andric   for (const auto &Filename : CI.getFrontendOpts().ModuleMapFiles) {
92706c3fb27SDimitry Andric     if (auto File = CI.getFileManager().getOptionalFileRef(Filename))
9280b57cec5SDimitry Andric       CI.getPreprocessor().getHeaderSearchInfo().loadModuleMapFile(
929a7dea167SDimitry Andric           *File, /*IsSystem*/false);
9300b57cec5SDimitry Andric     else
9310b57cec5SDimitry Andric       CI.getDiagnostics().Report(diag::err_module_map_not_found) << Filename;
9320b57cec5SDimitry Andric   }
9330b57cec5SDimitry Andric 
934bdd1243dSDimitry Andric   // If compiling implementation of a module, load its module map file now.
935bdd1243dSDimitry Andric   (void)CI.getPreprocessor().getCurrentModuleImplementation();
936bdd1243dSDimitry Andric 
9370b57cec5SDimitry Andric   // Add a module declaration scope so that modules from -fmodule-map-file
9380b57cec5SDimitry Andric   // arguments may shadow modules found implicitly in search paths.
9390b57cec5SDimitry Andric   CI.getPreprocessor()
9400b57cec5SDimitry Andric       .getHeaderSearchInfo()
9410b57cec5SDimitry Andric       .getModuleMap()
9420b57cec5SDimitry Andric       .finishModuleDeclarationScope();
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric   // Create the AST context and consumer unless this is a preprocessor only
9450b57cec5SDimitry Andric   // action.
9460b57cec5SDimitry Andric   if (!usesPreprocessorOnly()) {
9470b57cec5SDimitry Andric     // Parsing a model file should reuse the existing ASTContext.
9480b57cec5SDimitry Andric     if (!isModelParsingAction())
9490b57cec5SDimitry Andric       CI.createASTContext();
9500b57cec5SDimitry Andric 
9510b57cec5SDimitry Andric     // For preprocessed files, check if the first line specifies the original
9520b57cec5SDimitry Andric     // source file name with a linemarker.
9535ffd83dbSDimitry Andric     std::string PresumedInputFile = std::string(getCurrentFileOrBufferName());
9540b57cec5SDimitry Andric     if (Input.isPreprocessed())
9550b57cec5SDimitry Andric       ReadOriginalFileName(CI, PresumedInputFile);
9560b57cec5SDimitry Andric 
9570b57cec5SDimitry Andric     std::unique_ptr<ASTConsumer> Consumer =
9580b57cec5SDimitry Andric         CreateWrappedASTConsumer(CI, PresumedInputFile);
9590b57cec5SDimitry Andric     if (!Consumer)
960349cc55cSDimitry Andric       return false;
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric     // FIXME: should not overwrite ASTMutationListener when parsing model files?
9630b57cec5SDimitry Andric     if (!isModelParsingAction())
9640b57cec5SDimitry Andric       CI.getASTContext().setASTMutationListener(Consumer->GetASTMutationListener());
9650b57cec5SDimitry Andric 
9660b57cec5SDimitry Andric     if (!CI.getPreprocessorOpts().ChainedIncludes.empty()) {
9670b57cec5SDimitry Andric       // Convert headers to PCH and chain them.
9680b57cec5SDimitry Andric       IntrusiveRefCntPtr<ExternalSemaSource> source, FinalReader;
9690b57cec5SDimitry Andric       source = createChainedIncludesSource(CI, FinalReader);
9700b57cec5SDimitry Andric       if (!source)
971349cc55cSDimitry Andric         return false;
9725ffd83dbSDimitry Andric       CI.setASTReader(static_cast<ASTReader *>(FinalReader.get()));
9730b57cec5SDimitry Andric       CI.getASTContext().setExternalSource(source);
9740b57cec5SDimitry Andric     } else if (CI.getLangOpts().Modules ||
9750b57cec5SDimitry Andric                !CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
9760b57cec5SDimitry Andric       // Use PCM or PCH.
9770b57cec5SDimitry Andric       assert(hasPCHSupport() && "This action does not have PCH support!");
9780b57cec5SDimitry Andric       ASTDeserializationListener *DeserialListener =
9790b57cec5SDimitry Andric           Consumer->GetASTDeserializationListener();
9800b57cec5SDimitry Andric       bool DeleteDeserialListener = false;
9810b57cec5SDimitry Andric       if (CI.getPreprocessorOpts().DumpDeserializedPCHDecls) {
9820b57cec5SDimitry Andric         DeserialListener = new DeserializedDeclsDumper(DeserialListener,
9830b57cec5SDimitry Andric                                                        DeleteDeserialListener);
9840b57cec5SDimitry Andric         DeleteDeserialListener = true;
9850b57cec5SDimitry Andric       }
9860b57cec5SDimitry Andric       if (!CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn.empty()) {
9870b57cec5SDimitry Andric         DeserialListener = new DeserializedDeclsChecker(
9880b57cec5SDimitry Andric             CI.getASTContext(),
9890b57cec5SDimitry Andric             CI.getPreprocessorOpts().DeserializedPCHDeclsToErrorOn,
9900b57cec5SDimitry Andric             DeserialListener, DeleteDeserialListener);
9910b57cec5SDimitry Andric         DeleteDeserialListener = true;
9920b57cec5SDimitry Andric       }
9930b57cec5SDimitry Andric       if (!CI.getPreprocessorOpts().ImplicitPCHInclude.empty()) {
9940b57cec5SDimitry Andric         CI.createPCHExternalASTSource(
9950b57cec5SDimitry Andric             CI.getPreprocessorOpts().ImplicitPCHInclude,
996e8d8bef9SDimitry Andric             CI.getPreprocessorOpts().DisablePCHOrModuleValidation,
997e8d8bef9SDimitry Andric             CI.getPreprocessorOpts().AllowPCHWithCompilerErrors,
998e8d8bef9SDimitry Andric             DeserialListener, DeleteDeserialListener);
9990b57cec5SDimitry Andric         if (!CI.getASTContext().getExternalSource())
1000349cc55cSDimitry Andric           return false;
10010b57cec5SDimitry Andric       }
10025ffd83dbSDimitry Andric       // If modules are enabled, create the AST reader before creating
10030b57cec5SDimitry Andric       // any builtins, so that all declarations know that they might be
10040b57cec5SDimitry Andric       // extended by an external source.
10050b57cec5SDimitry Andric       if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
10060b57cec5SDimitry Andric           !CI.getASTContext().getExternalSource()) {
1007480093f4SDimitry Andric         CI.createASTReader();
1008480093f4SDimitry Andric         CI.getASTReader()->setDeserializationListener(DeserialListener,
10090b57cec5SDimitry Andric                                                       DeleteDeserialListener);
10100b57cec5SDimitry Andric       }
10110b57cec5SDimitry Andric     }
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric     CI.setASTConsumer(std::move(Consumer));
10140b57cec5SDimitry Andric     if (!CI.hasASTConsumer())
1015349cc55cSDimitry Andric       return false;
10160b57cec5SDimitry Andric   }
10170b57cec5SDimitry Andric 
10180b57cec5SDimitry Andric   // Initialize built-in info as long as we aren't using an external AST
10190b57cec5SDimitry Andric   // source.
10200b57cec5SDimitry Andric   if (CI.getLangOpts().Modules || !CI.hasASTContext() ||
10210b57cec5SDimitry Andric       !CI.getASTContext().getExternalSource()) {
10220b57cec5SDimitry Andric     Preprocessor &PP = CI.getPreprocessor();
10230b57cec5SDimitry Andric     PP.getBuiltinInfo().initializeBuiltins(PP.getIdentifierTable(),
10240b57cec5SDimitry Andric                                            PP.getLangOpts());
10250b57cec5SDimitry Andric   } else {
10260b57cec5SDimitry Andric     // FIXME: If this is a problem, recover from it by creating a multiplex
10270b57cec5SDimitry Andric     // source.
1028480093f4SDimitry Andric     assert((!CI.getLangOpts().Modules || CI.getASTReader()) &&
10290b57cec5SDimitry Andric            "modules enabled but created an external source that "
10300b57cec5SDimitry Andric            "doesn't support modules");
10310b57cec5SDimitry Andric   }
10320b57cec5SDimitry Andric 
10330b57cec5SDimitry Andric   // If we were asked to load any module files, do so now.
10345f757f3fSDimitry Andric   for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
10355f757f3fSDimitry Andric     serialization::ModuleFile *Loaded = nullptr;
10365f757f3fSDimitry Andric     if (!CI.loadModuleFile(ModuleFile, Loaded))
1037349cc55cSDimitry Andric       return false;
10380b57cec5SDimitry Andric 
10395f757f3fSDimitry Andric     if (Loaded && Loaded->StandardCXXModule)
10405f757f3fSDimitry Andric       CI.getDiagnostics().Report(
10415f757f3fSDimitry Andric           diag::warn_eagerly_load_for_standard_cplusplus_modules);
10425f757f3fSDimitry Andric   }
10435f757f3fSDimitry Andric 
10440b57cec5SDimitry Andric   // If there is a layout overrides file, attach an external AST source that
10450b57cec5SDimitry Andric   // provides the layouts from that file.
10460b57cec5SDimitry Andric   if (!CI.getFrontendOpts().OverrideRecordLayoutsFile.empty() &&
10470b57cec5SDimitry Andric       CI.hasASTContext() && !CI.getASTContext().getExternalSource()) {
10480b57cec5SDimitry Andric     IntrusiveRefCntPtr<ExternalASTSource>
10490b57cec5SDimitry Andric       Override(new LayoutOverrideSource(
10500b57cec5SDimitry Andric                      CI.getFrontendOpts().OverrideRecordLayoutsFile));
10510b57cec5SDimitry Andric     CI.getASTContext().setExternalSource(Override);
10520b57cec5SDimitry Andric   }
10530b57cec5SDimitry Andric 
1054753f127fSDimitry Andric   // Setup HLSL External Sema Source
1055753f127fSDimitry Andric   if (CI.getLangOpts().HLSL && CI.hasASTContext()) {
1056bdd1243dSDimitry Andric     IntrusiveRefCntPtr<ExternalSemaSource> HLSLSema(
1057753f127fSDimitry Andric         new HLSLExternalSemaSource());
1058bdd1243dSDimitry Andric     if (auto *SemaSource = dyn_cast_if_present<ExternalSemaSource>(
1059bdd1243dSDimitry Andric             CI.getASTContext().getExternalSource())) {
1060bdd1243dSDimitry Andric       IntrusiveRefCntPtr<ExternalSemaSource> MultiSema(
1061bdd1243dSDimitry Andric           new MultiplexExternalSemaSource(SemaSource, HLSLSema.get()));
1062bdd1243dSDimitry Andric       CI.getASTContext().setExternalSource(MultiSema);
1063bdd1243dSDimitry Andric     } else
1064753f127fSDimitry Andric       CI.getASTContext().setExternalSource(HLSLSema);
1065753f127fSDimitry Andric   }
1066753f127fSDimitry Andric 
1067349cc55cSDimitry Andric   FailureCleanup.release();
10680b57cec5SDimitry Andric   return true;
10690b57cec5SDimitry Andric }
10700b57cec5SDimitry Andric 
10710b57cec5SDimitry Andric llvm::Error FrontendAction::Execute() {
10720b57cec5SDimitry Andric   CompilerInstance &CI = getCompilerInstance();
10730b57cec5SDimitry Andric 
10740b57cec5SDimitry Andric   if (CI.hasFrontendTimer()) {
10750b57cec5SDimitry Andric     llvm::TimeRegion Timer(CI.getFrontendTimer());
10760b57cec5SDimitry Andric     ExecuteAction();
10770b57cec5SDimitry Andric   }
10780b57cec5SDimitry Andric   else ExecuteAction();
10790b57cec5SDimitry Andric 
10800b57cec5SDimitry Andric   // If we are supposed to rebuild the global module index, do so now unless
10810b57cec5SDimitry Andric   // there were any module-build failures.
10820b57cec5SDimitry Andric   if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
10830b57cec5SDimitry Andric       CI.hasPreprocessor()) {
10840b57cec5SDimitry Andric     StringRef Cache =
10850b57cec5SDimitry Andric         CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath();
10860b57cec5SDimitry Andric     if (!Cache.empty()) {
10870b57cec5SDimitry Andric       if (llvm::Error Err = GlobalModuleIndex::writeIndex(
10880b57cec5SDimitry Andric               CI.getFileManager(), CI.getPCHContainerReader(), Cache)) {
10890b57cec5SDimitry Andric         // FIXME this drops the error on the floor, but
10900b57cec5SDimitry Andric         // Index/pch-from-libclang.c seems to rely on dropping at least some of
10910b57cec5SDimitry Andric         // the error conditions!
10920b57cec5SDimitry Andric         consumeError(std::move(Err));
10930b57cec5SDimitry Andric       }
10940b57cec5SDimitry Andric     }
10950b57cec5SDimitry Andric   }
10960b57cec5SDimitry Andric 
10970b57cec5SDimitry Andric   return llvm::Error::success();
10980b57cec5SDimitry Andric }
10990b57cec5SDimitry Andric 
11000b57cec5SDimitry Andric void FrontendAction::EndSourceFile() {
11010b57cec5SDimitry Andric   CompilerInstance &CI = getCompilerInstance();
11020b57cec5SDimitry Andric 
11030b57cec5SDimitry Andric   // Inform the diagnostic client we are done with this source file.
11040b57cec5SDimitry Andric   CI.getDiagnosticClient().EndSourceFile();
11050b57cec5SDimitry Andric 
11060b57cec5SDimitry Andric   // Inform the preprocessor we are done.
11070b57cec5SDimitry Andric   if (CI.hasPreprocessor())
11080b57cec5SDimitry Andric     CI.getPreprocessor().EndSourceFile();
11090b57cec5SDimitry Andric 
11100b57cec5SDimitry Andric   // Finalize the action.
11110b57cec5SDimitry Andric   EndSourceFileAction();
11120b57cec5SDimitry Andric 
11130b57cec5SDimitry Andric   // Sema references the ast consumer, so reset sema first.
11140b57cec5SDimitry Andric   //
11150b57cec5SDimitry Andric   // FIXME: There is more per-file stuff we could just drop here?
11160b57cec5SDimitry Andric   bool DisableFree = CI.getFrontendOpts().DisableFree;
11170b57cec5SDimitry Andric   if (DisableFree) {
11180b57cec5SDimitry Andric     CI.resetAndLeakSema();
11190b57cec5SDimitry Andric     CI.resetAndLeakASTContext();
11200b57cec5SDimitry Andric     llvm::BuryPointer(CI.takeASTConsumer().get());
11210b57cec5SDimitry Andric   } else {
11220b57cec5SDimitry Andric     CI.setSema(nullptr);
11230b57cec5SDimitry Andric     CI.setASTContext(nullptr);
11240b57cec5SDimitry Andric     CI.setASTConsumer(nullptr);
11250b57cec5SDimitry Andric   }
11260b57cec5SDimitry Andric 
11270b57cec5SDimitry Andric   if (CI.getFrontendOpts().ShowStats) {
112881ad6265SDimitry Andric     llvm::errs() << "\nSTATISTICS FOR '" << getCurrentFileOrBufferName() << "':\n";
11290b57cec5SDimitry Andric     CI.getPreprocessor().PrintStats();
11300b57cec5SDimitry Andric     CI.getPreprocessor().getIdentifierTable().PrintStats();
11310b57cec5SDimitry Andric     CI.getPreprocessor().getHeaderSearchInfo().PrintStats();
11320b57cec5SDimitry Andric     CI.getSourceManager().PrintStats();
11330b57cec5SDimitry Andric     llvm::errs() << "\n";
11340b57cec5SDimitry Andric   }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   // Cleanup the output streams, and erase the output files if instructed by the
11370b57cec5SDimitry Andric   // FrontendAction.
11380b57cec5SDimitry Andric   CI.clearOutputFiles(/*EraseFiles=*/shouldEraseOutputFiles());
11390b57cec5SDimitry Andric 
114006c3fb27SDimitry Andric   // The resources are owned by AST when the current file is AST.
114106c3fb27SDimitry Andric   // So we reset the resources here to avoid users accessing it
114206c3fb27SDimitry Andric   // accidently.
11430b57cec5SDimitry Andric   if (isCurrentFileAST()) {
11440b57cec5SDimitry Andric     if (DisableFree) {
11450b57cec5SDimitry Andric       CI.resetAndLeakPreprocessor();
11460b57cec5SDimitry Andric       CI.resetAndLeakSourceManager();
11470b57cec5SDimitry Andric       CI.resetAndLeakFileManager();
11480b57cec5SDimitry Andric       llvm::BuryPointer(std::move(CurrentASTUnit));
11490b57cec5SDimitry Andric     } else {
11500b57cec5SDimitry Andric       CI.setPreprocessor(nullptr);
11510b57cec5SDimitry Andric       CI.setSourceManager(nullptr);
11520b57cec5SDimitry Andric       CI.setFileManager(nullptr);
11530b57cec5SDimitry Andric     }
11540b57cec5SDimitry Andric   }
11550b57cec5SDimitry Andric 
11560b57cec5SDimitry Andric   setCompilerInstance(nullptr);
11570b57cec5SDimitry Andric   setCurrentInput(FrontendInputFile());
11580b57cec5SDimitry Andric   CI.getLangOpts().setCompilingModule(LangOptions::CMK_None);
11590b57cec5SDimitry Andric }
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric bool FrontendAction::shouldEraseOutputFiles() {
11620b57cec5SDimitry Andric   return getCompilerInstance().getDiagnostics().hasErrorOccurred();
11630b57cec5SDimitry Andric }
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11660b57cec5SDimitry Andric // Utility Actions
11670b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
11680b57cec5SDimitry Andric 
11690b57cec5SDimitry Andric void ASTFrontendAction::ExecuteAction() {
11700b57cec5SDimitry Andric   CompilerInstance &CI = getCompilerInstance();
11710b57cec5SDimitry Andric   if (!CI.hasPreprocessor())
11720b57cec5SDimitry Andric     return;
11738a4dda33SDimitry Andric   // This is a fallback: If the client forgets to invoke this, we mark the
11748a4dda33SDimitry Andric   // current stack as the bottom. Though not optimal, this could help prevent
11758a4dda33SDimitry Andric   // stack overflow during deep recursion.
11768a4dda33SDimitry Andric   clang::noteBottomOfStack();
11770b57cec5SDimitry Andric 
11780b57cec5SDimitry Andric   // FIXME: Move the truncation aspect of this into Sema, we delayed this till
11790b57cec5SDimitry Andric   // here so the source manager would be initialized.
11800b57cec5SDimitry Andric   if (hasCodeCompletionSupport() &&
11810b57cec5SDimitry Andric       !CI.getFrontendOpts().CodeCompletionAt.FileName.empty())
11820b57cec5SDimitry Andric     CI.createCodeCompletionConsumer();
11830b57cec5SDimitry Andric 
11840b57cec5SDimitry Andric   // Use a code completion consumer?
11850b57cec5SDimitry Andric   CodeCompleteConsumer *CompletionConsumer = nullptr;
11860b57cec5SDimitry Andric   if (CI.hasCodeCompletionConsumer())
11870b57cec5SDimitry Andric     CompletionConsumer = &CI.getCodeCompletionConsumer();
11880b57cec5SDimitry Andric 
11890b57cec5SDimitry Andric   if (!CI.hasSema())
11900b57cec5SDimitry Andric     CI.createSema(getTranslationUnitKind(), CompletionConsumer);
11910b57cec5SDimitry Andric 
11920b57cec5SDimitry Andric   ParseAST(CI.getSema(), CI.getFrontendOpts().ShowStats,
11930b57cec5SDimitry Andric            CI.getFrontendOpts().SkipFunctionBodies);
11940b57cec5SDimitry Andric }
11950b57cec5SDimitry Andric 
11960b57cec5SDimitry Andric void PluginASTAction::anchor() { }
11970b57cec5SDimitry Andric 
11980b57cec5SDimitry Andric std::unique_ptr<ASTConsumer>
11990b57cec5SDimitry Andric PreprocessorFrontendAction::CreateASTConsumer(CompilerInstance &CI,
12000b57cec5SDimitry Andric                                               StringRef InFile) {
12010b57cec5SDimitry Andric   llvm_unreachable("Invalid CreateASTConsumer on preprocessor action!");
12020b57cec5SDimitry Andric }
12030b57cec5SDimitry Andric 
12040b57cec5SDimitry Andric bool WrapperFrontendAction::PrepareToExecuteAction(CompilerInstance &CI) {
12050b57cec5SDimitry Andric   return WrappedAction->PrepareToExecuteAction(CI);
12060b57cec5SDimitry Andric }
12070b57cec5SDimitry Andric std::unique_ptr<ASTConsumer>
12080b57cec5SDimitry Andric WrapperFrontendAction::CreateASTConsumer(CompilerInstance &CI,
12090b57cec5SDimitry Andric                                          StringRef InFile) {
12100b57cec5SDimitry Andric   return WrappedAction->CreateASTConsumer(CI, InFile);
12110b57cec5SDimitry Andric }
12120b57cec5SDimitry Andric bool WrapperFrontendAction::BeginInvocation(CompilerInstance &CI) {
12130b57cec5SDimitry Andric   return WrappedAction->BeginInvocation(CI);
12140b57cec5SDimitry Andric }
12150b57cec5SDimitry Andric bool WrapperFrontendAction::BeginSourceFileAction(CompilerInstance &CI) {
12160b57cec5SDimitry Andric   WrappedAction->setCurrentInput(getCurrentInput());
12170b57cec5SDimitry Andric   WrappedAction->setCompilerInstance(&CI);
12180b57cec5SDimitry Andric   auto Ret = WrappedAction->BeginSourceFileAction(CI);
12190b57cec5SDimitry Andric   // BeginSourceFileAction may change CurrentInput, e.g. during module builds.
12200b57cec5SDimitry Andric   setCurrentInput(WrappedAction->getCurrentInput());
12210b57cec5SDimitry Andric   return Ret;
12220b57cec5SDimitry Andric }
12230b57cec5SDimitry Andric void WrapperFrontendAction::ExecuteAction() {
12240b57cec5SDimitry Andric   WrappedAction->ExecuteAction();
12250b57cec5SDimitry Andric }
1226fe6060f1SDimitry Andric void WrapperFrontendAction::EndSourceFile() { WrappedAction->EndSourceFile(); }
12270b57cec5SDimitry Andric void WrapperFrontendAction::EndSourceFileAction() {
12280b57cec5SDimitry Andric   WrappedAction->EndSourceFileAction();
12290b57cec5SDimitry Andric }
12305ffd83dbSDimitry Andric bool WrapperFrontendAction::shouldEraseOutputFiles() {
12315ffd83dbSDimitry Andric   return WrappedAction->shouldEraseOutputFiles();
12325ffd83dbSDimitry Andric }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric bool WrapperFrontendAction::usesPreprocessorOnly() const {
12350b57cec5SDimitry Andric   return WrappedAction->usesPreprocessorOnly();
12360b57cec5SDimitry Andric }
12370b57cec5SDimitry Andric TranslationUnitKind WrapperFrontendAction::getTranslationUnitKind() {
12380b57cec5SDimitry Andric   return WrappedAction->getTranslationUnitKind();
12390b57cec5SDimitry Andric }
12400b57cec5SDimitry Andric bool WrapperFrontendAction::hasPCHSupport() const {
12410b57cec5SDimitry Andric   return WrappedAction->hasPCHSupport();
12420b57cec5SDimitry Andric }
12430b57cec5SDimitry Andric bool WrapperFrontendAction::hasASTFileSupport() const {
12440b57cec5SDimitry Andric   return WrappedAction->hasASTFileSupport();
12450b57cec5SDimitry Andric }
12460b57cec5SDimitry Andric bool WrapperFrontendAction::hasIRSupport() const {
12470b57cec5SDimitry Andric   return WrappedAction->hasIRSupport();
12480b57cec5SDimitry Andric }
12490b57cec5SDimitry Andric bool WrapperFrontendAction::hasCodeCompletionSupport() const {
12500b57cec5SDimitry Andric   return WrappedAction->hasCodeCompletionSupport();
12510b57cec5SDimitry Andric }
12520b57cec5SDimitry Andric 
12530b57cec5SDimitry Andric WrapperFrontendAction::WrapperFrontendAction(
12540b57cec5SDimitry Andric     std::unique_ptr<FrontendAction> WrappedAction)
12550b57cec5SDimitry Andric   : WrappedAction(std::move(WrappedAction)) {}
1256