xref: /freebsd/contrib/llvm-project/clang/lib/AST/ExternalASTMerger.cpp (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
10b57cec5SDimitry Andric //===- ExternalASTMerger.cpp - Merging External AST Interface ---*- C++ -*-===//
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 //  This file implements the ExternalASTMerger, which vends a combination of
100b57cec5SDimitry Andric //  ASTs from several different ASTContext/FileManager pairs
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
150b57cec5SDimitry Andric #include "clang/AST/Decl.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
190b57cec5SDimitry Andric #include "clang/AST/ExternalASTMerger.h"
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric using namespace clang;
220b57cec5SDimitry Andric 
230b57cec5SDimitry Andric namespace {
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric template <typename T> struct Source {
260b57cec5SDimitry Andric   T t;
270b57cec5SDimitry Andric   Source(T t) : t(t) {}
280b57cec5SDimitry Andric   operator T() { return t; }
290b57cec5SDimitry Andric   template <typename U = T> U &get() { return t; }
300b57cec5SDimitry Andric   template <typename U = T> const U &get() const { return t; }
310b57cec5SDimitry Andric   template <typename U> operator Source<U>() { return Source<U>(t); }
320b57cec5SDimitry Andric };
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric typedef std::pair<Source<NamedDecl *>, ASTImporter *> Candidate;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric /// For the given DC, return the DC that is safe to perform lookups on.  This is
370b57cec5SDimitry Andric /// the DC we actually want to work with most of the time.
380b57cec5SDimitry Andric const DeclContext *CanonicalizeDC(const DeclContext *DC) {
390b57cec5SDimitry Andric   if (isa<LinkageSpecDecl>(DC))
400b57cec5SDimitry Andric     return DC->getRedeclContext();
410b57cec5SDimitry Andric   return DC;
420b57cec5SDimitry Andric }
430b57cec5SDimitry Andric 
440b57cec5SDimitry Andric Source<const DeclContext *>
450b57cec5SDimitry Andric LookupSameContext(Source<TranslationUnitDecl *> SourceTU, const DeclContext *DC,
460b57cec5SDimitry Andric                   ASTImporter &ReverseImporter) {
470b57cec5SDimitry Andric   DC = CanonicalizeDC(DC);
480b57cec5SDimitry Andric   if (DC->isTranslationUnit()) {
490b57cec5SDimitry Andric     return SourceTU;
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric   Source<const DeclContext *> SourceParentDC =
520b57cec5SDimitry Andric       LookupSameContext(SourceTU, DC->getParent(), ReverseImporter);
530b57cec5SDimitry Andric   if (!SourceParentDC) {
540b57cec5SDimitry Andric     // If we couldn't find the parent DC in this TranslationUnit, give up.
550b57cec5SDimitry Andric     return nullptr;
560b57cec5SDimitry Andric   }
570b57cec5SDimitry Andric   auto *ND = cast<NamedDecl>(DC);
580b57cec5SDimitry Andric   DeclarationName Name = ND->getDeclName();
590b57cec5SDimitry Andric   auto SourceNameOrErr = ReverseImporter.Import(Name);
600b57cec5SDimitry Andric   if (!SourceNameOrErr) {
610b57cec5SDimitry Andric     llvm::consumeError(SourceNameOrErr.takeError());
620b57cec5SDimitry Andric     return nullptr;
630b57cec5SDimitry Andric   }
640b57cec5SDimitry Andric   Source<DeclarationName> SourceName = *SourceNameOrErr;
650b57cec5SDimitry Andric   DeclContext::lookup_result SearchResult =
660b57cec5SDimitry Andric       SourceParentDC.get()->lookup(SourceName.get());
670b57cec5SDimitry Andric   size_t SearchResultSize = SearchResult.size();
680b57cec5SDimitry Andric   if (SearchResultSize == 0 || SearchResultSize > 1) {
690b57cec5SDimitry Andric     // There are two cases here.  First, we might not find the name.
700b57cec5SDimitry Andric     // We might also find multiple copies, in which case we have no
710b57cec5SDimitry Andric     // guarantee that the one we wanted is the one we pick.  (E.g.,
720b57cec5SDimitry Andric     // if we have two specializations of the same template it is
730b57cec5SDimitry Andric     // very hard to determine which is the one you want.)
740b57cec5SDimitry Andric     //
750b57cec5SDimitry Andric     // The Origins map fixes this problem by allowing the origin to be
760b57cec5SDimitry Andric     // explicitly recorded, so we trigger that recording by returning
770b57cec5SDimitry Andric     // nothing (rather than a possibly-inaccurate guess) here.
780b57cec5SDimitry Andric     return nullptr;
790b57cec5SDimitry Andric   } else {
800b57cec5SDimitry Andric     NamedDecl *SearchResultDecl = SearchResult[0];
810b57cec5SDimitry Andric     if (isa<DeclContext>(SearchResultDecl) &&
820b57cec5SDimitry Andric         SearchResultDecl->getKind() == DC->getDeclKind())
830b57cec5SDimitry Andric       return cast<DeclContext>(SearchResultDecl)->getPrimaryContext();
840b57cec5SDimitry Andric     return nullptr; // This type of lookup is unsupported
850b57cec5SDimitry Andric   }
860b57cec5SDimitry Andric }
870b57cec5SDimitry Andric 
880b57cec5SDimitry Andric /// A custom implementation of ASTImporter, for ExternalASTMerger's purposes.
890b57cec5SDimitry Andric ///
900b57cec5SDimitry Andric /// There are several modifications:
910b57cec5SDimitry Andric ///
920b57cec5SDimitry Andric /// - It enables lazy lookup (via the HasExternalLexicalStorage flag and a few
930b57cec5SDimitry Andric ///   others), which instructs Clang to refer to ExternalASTMerger.  Also, it
940b57cec5SDimitry Andric ///   forces MinimalImport to true, which is necessary to make this work.
950b57cec5SDimitry Andric /// - It maintains a reverse importer for use with names.  This allows lookup of
960b57cec5SDimitry Andric ///   arbitrary names in the source context.
970b57cec5SDimitry Andric /// - It updates the ExternalASTMerger's origin map as needed whenever a
980b57cec5SDimitry Andric ///   it sees a DeclContext.
990b57cec5SDimitry Andric class LazyASTImporter : public ASTImporter {
1000b57cec5SDimitry Andric private:
1010b57cec5SDimitry Andric   ExternalASTMerger &Parent;
1020b57cec5SDimitry Andric   ASTImporter Reverse;
1030b57cec5SDimitry Andric   const ExternalASTMerger::OriginMap &FromOrigins;
104*a7dea167SDimitry Andric   /// @see ExternalASTMerger::ImporterSource::Temporary
105*a7dea167SDimitry Andric   bool TemporarySource;
106*a7dea167SDimitry Andric   /// Map of imported declarations back to the declarations they originated
107*a7dea167SDimitry Andric   /// from.
108*a7dea167SDimitry Andric   llvm::DenseMap<Decl *, Decl *> ToOrigin;
109*a7dea167SDimitry Andric   /// @see ExternalASTMerger::ImporterSource::Merger
110*a7dea167SDimitry Andric   ExternalASTMerger *SourceMerger;
1110b57cec5SDimitry Andric   llvm::raw_ostream &logs() { return Parent.logs(); }
1120b57cec5SDimitry Andric public:
1130b57cec5SDimitry Andric   LazyASTImporter(ExternalASTMerger &_Parent, ASTContext &ToContext,
114*a7dea167SDimitry Andric                   FileManager &ToFileManager,
115*a7dea167SDimitry Andric                   const ExternalASTMerger::ImporterSource &S,
116*a7dea167SDimitry Andric                   std::shared_ptr<ASTImporterSharedState> SharedState)
117*a7dea167SDimitry Andric       : ASTImporter(ToContext, ToFileManager, S.getASTContext(),
118*a7dea167SDimitry Andric                     S.getFileManager(),
119*a7dea167SDimitry Andric                     /*MinimalImport=*/true, SharedState),
120*a7dea167SDimitry Andric         Parent(_Parent),
121*a7dea167SDimitry Andric         Reverse(S.getASTContext(), S.getFileManager(), ToContext, ToFileManager,
1220b57cec5SDimitry Andric                 /*MinimalImport=*/true),
123*a7dea167SDimitry Andric         FromOrigins(S.getOriginMap()), TemporarySource(S.isTemporary()),
124*a7dea167SDimitry Andric         SourceMerger(S.getMerger()) {}
125*a7dea167SDimitry Andric 
126*a7dea167SDimitry Andric   llvm::Expected<Decl *> ImportImpl(Decl *FromD) override {
127*a7dea167SDimitry Andric     if (!TemporarySource || !SourceMerger)
128*a7dea167SDimitry Andric       return ASTImporter::ImportImpl(FromD);
129*a7dea167SDimitry Andric 
130*a7dea167SDimitry Andric     // If we get here, then this source is importing from a temporary ASTContext
131*a7dea167SDimitry Andric     // that also has another ExternalASTMerger attached. It could be
132*a7dea167SDimitry Andric     // possible that the current ExternalASTMerger and the temporary ASTContext
133*a7dea167SDimitry Andric     // share a common ImporterSource, which means that the temporary
134*a7dea167SDimitry Andric     // AST could contain declarations that were imported from a source
135*a7dea167SDimitry Andric     // that this ExternalASTMerger can access directly. Instead of importing
136*a7dea167SDimitry Andric     // such declarations from the temporary ASTContext, they should instead
137*a7dea167SDimitry Andric     // be directly imported by this ExternalASTMerger from the original
138*a7dea167SDimitry Andric     // source. This way the ExternalASTMerger can safely do a minimal import
139*a7dea167SDimitry Andric     // without creating incomplete declarations originated from a temporary
140*a7dea167SDimitry Andric     // ASTContext. If we would try to complete such declarations later on, we
141*a7dea167SDimitry Andric     // would fail to do so as their temporary AST could be deleted (which means
142*a7dea167SDimitry Andric     // that the missing parts of the minimally imported declaration in that
143*a7dea167SDimitry Andric     // ASTContext were also deleted).
144*a7dea167SDimitry Andric     //
145*a7dea167SDimitry Andric     // The following code tracks back any declaration that needs to be
146*a7dea167SDimitry Andric     // imported from the temporary ASTContext to a persistent ASTContext.
147*a7dea167SDimitry Andric     // Then the ExternalASTMerger tries to import from the persistent
148*a7dea167SDimitry Andric     // ASTContext directly by using the associated ASTImporter. If that
149*a7dea167SDimitry Andric     // succeeds, this ASTImporter just maps the declarations imported by
150*a7dea167SDimitry Andric     // the other (persistent) ASTImporter to this (temporary) ASTImporter.
151*a7dea167SDimitry Andric     // The steps can be visualized like this:
152*a7dea167SDimitry Andric     //
153*a7dea167SDimitry Andric     //  Target AST <--- 3. Indirect import --- Persistent AST
154*a7dea167SDimitry Andric     //       ^            of persistent decl        ^
155*a7dea167SDimitry Andric     //       |                                      |
156*a7dea167SDimitry Andric     // 1. Current import           2. Tracking back to persistent decl
157*a7dea167SDimitry Andric     // 4. Map persistent decl                       |
158*a7dea167SDimitry Andric     //  & pretend we imported.                      |
159*a7dea167SDimitry Andric     //       |                                      |
160*a7dea167SDimitry Andric     // Temporary AST -------------------------------'
161*a7dea167SDimitry Andric 
162*a7dea167SDimitry Andric     // First, ask the ExternalASTMerger of the source where the temporary
163*a7dea167SDimitry Andric     // declaration originated from.
164*a7dea167SDimitry Andric     Decl *Persistent = SourceMerger->FindOriginalDecl(FromD);
165*a7dea167SDimitry Andric     // FromD isn't from a persistent AST, so just do a normal import.
166*a7dea167SDimitry Andric     if (!Persistent)
167*a7dea167SDimitry Andric       return ASTImporter::ImportImpl(FromD);
168*a7dea167SDimitry Andric     // Now ask the current ExternalASTMerger to try import the persistent
169*a7dea167SDimitry Andric     // declaration into the target.
170*a7dea167SDimitry Andric     ASTContext &PersistentCtx = Persistent->getASTContext();
171*a7dea167SDimitry Andric     ASTImporter &OtherImporter = Parent.ImporterForOrigin(PersistentCtx);
172*a7dea167SDimitry Andric     // Check that we never end up in the current Importer again.
173*a7dea167SDimitry Andric     assert((&PersistentCtx != &getFromContext()) && (&OtherImporter != this) &&
174*a7dea167SDimitry Andric            "Delegated to same Importer?");
175*a7dea167SDimitry Andric     auto DeclOrErr = OtherImporter.Import(Persistent);
176*a7dea167SDimitry Andric     // Errors when importing the persistent decl are treated as if we
177*a7dea167SDimitry Andric     // had errors with importing the temporary decl.
178*a7dea167SDimitry Andric     if (!DeclOrErr)
179*a7dea167SDimitry Andric       return DeclOrErr.takeError();
180*a7dea167SDimitry Andric     Decl *D = *DeclOrErr;
181*a7dea167SDimitry Andric     // Tell the current ASTImporter that this has already been imported
182*a7dea167SDimitry Andric     // to prevent any further queries for the temporary decl.
183*a7dea167SDimitry Andric     MapImported(FromD, D);
184*a7dea167SDimitry Andric     return D;
185*a7dea167SDimitry Andric   }
186*a7dea167SDimitry Andric 
187*a7dea167SDimitry Andric   /// Implements the ASTImporter interface for tracking back a declaration
188*a7dea167SDimitry Andric   /// to its original declaration it came from.
189*a7dea167SDimitry Andric   Decl *GetOriginalDecl(Decl *To) override {
190*a7dea167SDimitry Andric     auto It = ToOrigin.find(To);
191*a7dea167SDimitry Andric     if (It != ToOrigin.end())
192*a7dea167SDimitry Andric       return It->second;
193*a7dea167SDimitry Andric     return nullptr;
194*a7dea167SDimitry Andric   }
1950b57cec5SDimitry Andric 
1960b57cec5SDimitry Andric   /// Whenever a DeclContext is imported, ensure that ExternalASTSource's origin
1970b57cec5SDimitry Andric   /// map is kept up to date.  Also set the appropriate flags.
1980b57cec5SDimitry Andric   void Imported(Decl *From, Decl *To) override {
199*a7dea167SDimitry Andric     ToOrigin[To] = From;
200*a7dea167SDimitry Andric 
2010b57cec5SDimitry Andric     if (auto *ToDC = dyn_cast<DeclContext>(To)) {
2020b57cec5SDimitry Andric       const bool LoggingEnabled = Parent.LoggingEnabled();
2030b57cec5SDimitry Andric       if (LoggingEnabled)
2040b57cec5SDimitry Andric         logs() << "(ExternalASTMerger*)" << (void*)&Parent
2050b57cec5SDimitry Andric                << " imported (DeclContext*)" << (void*)ToDC
2060b57cec5SDimitry Andric                << ", (ASTContext*)" << (void*)&getToContext()
2070b57cec5SDimitry Andric                << " from (DeclContext*)" << (void*)llvm::cast<DeclContext>(From)
2080b57cec5SDimitry Andric                << ", (ASTContext*)" << (void*)&getFromContext()
2090b57cec5SDimitry Andric                << "\n";
2100b57cec5SDimitry Andric       Source<DeclContext *> FromDC(
2110b57cec5SDimitry Andric           cast<DeclContext>(From)->getPrimaryContext());
2120b57cec5SDimitry Andric       if (FromOrigins.count(FromDC) &&
2130b57cec5SDimitry Andric           Parent.HasImporterForOrigin(*FromOrigins.at(FromDC).AST)) {
2140b57cec5SDimitry Andric         if (LoggingEnabled)
2150b57cec5SDimitry Andric           logs() << "(ExternalASTMerger*)" << (void*)&Parent
2160b57cec5SDimitry Andric                  << " forced origin (DeclContext*)"
2170b57cec5SDimitry Andric                  << (void*)FromOrigins.at(FromDC).DC
2180b57cec5SDimitry Andric                  << ", (ASTContext*)"
2190b57cec5SDimitry Andric                  << (void*)FromOrigins.at(FromDC).AST
2200b57cec5SDimitry Andric                  << "\n";
2210b57cec5SDimitry Andric         Parent.ForceRecordOrigin(ToDC, FromOrigins.at(FromDC));
2220b57cec5SDimitry Andric       } else {
2230b57cec5SDimitry Andric         if (LoggingEnabled)
2240b57cec5SDimitry Andric           logs() << "(ExternalASTMerger*)" << (void*)&Parent
2250b57cec5SDimitry Andric                  << " maybe recording origin (DeclContext*)" << (void*)FromDC
2260b57cec5SDimitry Andric                  << ", (ASTContext*)" << (void*)&getFromContext()
2270b57cec5SDimitry Andric                  << "\n";
2280b57cec5SDimitry Andric         Parent.MaybeRecordOrigin(ToDC, {FromDC, &getFromContext()});
2290b57cec5SDimitry Andric       }
2300b57cec5SDimitry Andric     }
2310b57cec5SDimitry Andric     if (auto *ToTag = dyn_cast<TagDecl>(To)) {
2320b57cec5SDimitry Andric       ToTag->setHasExternalLexicalStorage();
2330b57cec5SDimitry Andric       ToTag->getPrimaryContext()->setMustBuildLookupTable();
2340b57cec5SDimitry Andric       assert(Parent.CanComplete(ToTag));
2350b57cec5SDimitry Andric     } else if (auto *ToNamespace = dyn_cast<NamespaceDecl>(To)) {
2360b57cec5SDimitry Andric       ToNamespace->setHasExternalVisibleStorage();
2370b57cec5SDimitry Andric       assert(Parent.CanComplete(ToNamespace));
2380b57cec5SDimitry Andric     } else if (auto *ToContainer = dyn_cast<ObjCContainerDecl>(To)) {
2390b57cec5SDimitry Andric       ToContainer->setHasExternalLexicalStorage();
2400b57cec5SDimitry Andric       ToContainer->getPrimaryContext()->setMustBuildLookupTable();
2410b57cec5SDimitry Andric       assert(Parent.CanComplete(ToContainer));
2420b57cec5SDimitry Andric     }
2430b57cec5SDimitry Andric   }
2440b57cec5SDimitry Andric   ASTImporter &GetReverse() { return Reverse; }
2450b57cec5SDimitry Andric };
2460b57cec5SDimitry Andric 
2470b57cec5SDimitry Andric bool HasDeclOfSameType(llvm::ArrayRef<Candidate> Decls, const Candidate &C) {
2480b57cec5SDimitry Andric   if (isa<FunctionDecl>(C.first.get()))
2490b57cec5SDimitry Andric     return false;
2500b57cec5SDimitry Andric   return llvm::any_of(Decls, [&](const Candidate &D) {
2510b57cec5SDimitry Andric     return C.first.get()->getKind() == D.first.get()->getKind();
2520b57cec5SDimitry Andric   });
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric } // end namespace
2560b57cec5SDimitry Andric 
2570b57cec5SDimitry Andric ASTImporter &ExternalASTMerger::ImporterForOrigin(ASTContext &OriginContext) {
2580b57cec5SDimitry Andric   for (const std::unique_ptr<ASTImporter> &I : Importers)
2590b57cec5SDimitry Andric     if (&I->getFromContext() == &OriginContext)
2600b57cec5SDimitry Andric       return *I;
2610b57cec5SDimitry Andric   llvm_unreachable("We should have an importer for this origin!");
2620b57cec5SDimitry Andric }
2630b57cec5SDimitry Andric 
2640b57cec5SDimitry Andric namespace {
2650b57cec5SDimitry Andric LazyASTImporter &LazyImporterForOrigin(ExternalASTMerger &Merger,
2660b57cec5SDimitry Andric                                    ASTContext &OriginContext) {
2670b57cec5SDimitry Andric   return static_cast<LazyASTImporter &>(
2680b57cec5SDimitry Andric       Merger.ImporterForOrigin(OriginContext));
2690b57cec5SDimitry Andric }
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric bool ExternalASTMerger::HasImporterForOrigin(ASTContext &OriginContext) {
2730b57cec5SDimitry Andric   for (const std::unique_ptr<ASTImporter> &I : Importers)
2740b57cec5SDimitry Andric     if (&I->getFromContext() == &OriginContext)
2750b57cec5SDimitry Andric       return true;
2760b57cec5SDimitry Andric   return false;
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric 
2790b57cec5SDimitry Andric template <typename CallbackType>
2800b57cec5SDimitry Andric void ExternalASTMerger::ForEachMatchingDC(const DeclContext *DC,
2810b57cec5SDimitry Andric                                           CallbackType Callback) {
2820b57cec5SDimitry Andric   if (Origins.count(DC)) {
2830b57cec5SDimitry Andric     ExternalASTMerger::DCOrigin Origin = Origins[DC];
2840b57cec5SDimitry Andric     LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
2850b57cec5SDimitry Andric     Callback(Importer, Importer.GetReverse(), Origin.DC);
2860b57cec5SDimitry Andric   } else {
2870b57cec5SDimitry Andric     bool DidCallback = false;
2880b57cec5SDimitry Andric     for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
2890b57cec5SDimitry Andric       Source<TranslationUnitDecl *> SourceTU =
2900b57cec5SDimitry Andric           Importer->getFromContext().getTranslationUnitDecl();
2910b57cec5SDimitry Andric       ASTImporter &Reverse =
2920b57cec5SDimitry Andric           static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
2930b57cec5SDimitry Andric       if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
2940b57cec5SDimitry Andric         DidCallback = true;
2950b57cec5SDimitry Andric         if (Callback(*Importer, Reverse, SourceDC))
2960b57cec5SDimitry Andric           break;
2970b57cec5SDimitry Andric       }
2980b57cec5SDimitry Andric     }
2990b57cec5SDimitry Andric     if (!DidCallback && LoggingEnabled())
3000b57cec5SDimitry Andric       logs() << "(ExternalASTMerger*)" << (void*)this
3010b57cec5SDimitry Andric              << " asserting for (DeclContext*)" << (const void*)DC
3020b57cec5SDimitry Andric              << ", (ASTContext*)" << (void*)&Target.AST
3030b57cec5SDimitry Andric              << "\n";
3040b57cec5SDimitry Andric     assert(DidCallback && "Couldn't find a source context matching our DC");
3050b57cec5SDimitry Andric   }
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric void ExternalASTMerger::CompleteType(TagDecl *Tag) {
3090b57cec5SDimitry Andric   assert(Tag->hasExternalLexicalStorage());
3100b57cec5SDimitry Andric   ForEachMatchingDC(Tag, [&](ASTImporter &Forward, ASTImporter &Reverse,
3110b57cec5SDimitry Andric                              Source<const DeclContext *> SourceDC) -> bool {
3120b57cec5SDimitry Andric     auto *SourceTag = const_cast<TagDecl *>(cast<TagDecl>(SourceDC.get()));
3130b57cec5SDimitry Andric     if (SourceTag->hasExternalLexicalStorage())
3140b57cec5SDimitry Andric       SourceTag->getASTContext().getExternalSource()->CompleteType(SourceTag);
3150b57cec5SDimitry Andric     if (!SourceTag->getDefinition())
3160b57cec5SDimitry Andric       return false;
3170b57cec5SDimitry Andric     Forward.MapImported(SourceTag, Tag);
3180b57cec5SDimitry Andric     if (llvm::Error Err = Forward.ImportDefinition(SourceTag))
3190b57cec5SDimitry Andric       llvm::consumeError(std::move(Err));
3200b57cec5SDimitry Andric     Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
3210b57cec5SDimitry Andric     return true;
3220b57cec5SDimitry Andric   });
3230b57cec5SDimitry Andric }
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric void ExternalASTMerger::CompleteType(ObjCInterfaceDecl *Interface) {
3260b57cec5SDimitry Andric   assert(Interface->hasExternalLexicalStorage());
3270b57cec5SDimitry Andric   ForEachMatchingDC(
3280b57cec5SDimitry Andric       Interface, [&](ASTImporter &Forward, ASTImporter &Reverse,
3290b57cec5SDimitry Andric                      Source<const DeclContext *> SourceDC) -> bool {
3300b57cec5SDimitry Andric         auto *SourceInterface = const_cast<ObjCInterfaceDecl *>(
3310b57cec5SDimitry Andric             cast<ObjCInterfaceDecl>(SourceDC.get()));
3320b57cec5SDimitry Andric         if (SourceInterface->hasExternalLexicalStorage())
3330b57cec5SDimitry Andric           SourceInterface->getASTContext().getExternalSource()->CompleteType(
3340b57cec5SDimitry Andric               SourceInterface);
3350b57cec5SDimitry Andric         if (!SourceInterface->getDefinition())
3360b57cec5SDimitry Andric           return false;
3370b57cec5SDimitry Andric         Forward.MapImported(SourceInterface, Interface);
3380b57cec5SDimitry Andric         if (llvm::Error Err = Forward.ImportDefinition(SourceInterface))
3390b57cec5SDimitry Andric           llvm::consumeError(std::move(Err));
3400b57cec5SDimitry Andric         return true;
3410b57cec5SDimitry Andric       });
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric 
3440b57cec5SDimitry Andric bool ExternalASTMerger::CanComplete(DeclContext *Interface) {
3450b57cec5SDimitry Andric   assert(Interface->hasExternalLexicalStorage() ||
3460b57cec5SDimitry Andric          Interface->hasExternalVisibleStorage());
3470b57cec5SDimitry Andric   bool FoundMatchingDC = false;
3480b57cec5SDimitry Andric   ForEachMatchingDC(Interface,
3490b57cec5SDimitry Andric                     [&](ASTImporter &Forward, ASTImporter &Reverse,
3500b57cec5SDimitry Andric                         Source<const DeclContext *> SourceDC) -> bool {
3510b57cec5SDimitry Andric                       FoundMatchingDC = true;
3520b57cec5SDimitry Andric                       return true;
3530b57cec5SDimitry Andric                     });
3540b57cec5SDimitry Andric   return FoundMatchingDC;
3550b57cec5SDimitry Andric }
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric namespace {
3580b57cec5SDimitry Andric bool IsSameDC(const DeclContext *D1, const DeclContext *D2) {
3590b57cec5SDimitry Andric   if (isa<ObjCContainerDecl>(D1) && isa<ObjCContainerDecl>(D2))
3600b57cec5SDimitry Andric     return true; // There are many cases where Objective-C is ambiguous.
3610b57cec5SDimitry Andric   if (auto *T1 = dyn_cast<TagDecl>(D1))
3620b57cec5SDimitry Andric     if (auto *T2 = dyn_cast<TagDecl>(D2))
3630b57cec5SDimitry Andric       if (T1->getFirstDecl() == T2->getFirstDecl())
3640b57cec5SDimitry Andric         return true;
3650b57cec5SDimitry Andric   return D1 == D2 || D1 == CanonicalizeDC(D2);
3660b57cec5SDimitry Andric }
3670b57cec5SDimitry Andric }
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric void ExternalASTMerger::MaybeRecordOrigin(const DeclContext *ToDC,
3700b57cec5SDimitry Andric                                           DCOrigin Origin) {
3710b57cec5SDimitry Andric   LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
3720b57cec5SDimitry Andric   ASTImporter &Reverse = Importer.GetReverse();
3730b57cec5SDimitry Andric   Source<const DeclContext *> FoundFromDC =
3740b57cec5SDimitry Andric       LookupSameContext(Origin.AST->getTranslationUnitDecl(), ToDC, Reverse);
3750b57cec5SDimitry Andric   const bool DoRecord = !FoundFromDC || !IsSameDC(FoundFromDC.get(), Origin.DC);
3760b57cec5SDimitry Andric   if (DoRecord)
3770b57cec5SDimitry Andric     RecordOriginImpl(ToDC, Origin, Importer);
3780b57cec5SDimitry Andric   if (LoggingEnabled())
3790b57cec5SDimitry Andric     logs() << "(ExternalASTMerger*)" << (void*)this
3800b57cec5SDimitry Andric              << (DoRecord ? " decided " : " decided NOT")
3810b57cec5SDimitry Andric              << " to record origin (DeclContext*)" << (void*)Origin.DC
3820b57cec5SDimitry Andric              << ", (ASTContext*)" << (void*)&Origin.AST
3830b57cec5SDimitry Andric              << "\n";
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric void ExternalASTMerger::ForceRecordOrigin(const DeclContext *ToDC,
3870b57cec5SDimitry Andric                                           DCOrigin Origin) {
3880b57cec5SDimitry Andric   RecordOriginImpl(ToDC, Origin, ImporterForOrigin(*Origin.AST));
3890b57cec5SDimitry Andric }
3900b57cec5SDimitry Andric 
3910b57cec5SDimitry Andric void ExternalASTMerger::RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
3920b57cec5SDimitry Andric                                          ASTImporter &Importer) {
3930b57cec5SDimitry Andric   Origins[ToDC] = Origin;
3940b57cec5SDimitry Andric   Importer.ASTImporter::MapImported(cast<Decl>(Origin.DC), const_cast<Decl*>(cast<Decl>(ToDC)));
3950b57cec5SDimitry Andric }
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric ExternalASTMerger::ExternalASTMerger(const ImporterTarget &Target,
3980b57cec5SDimitry Andric                                      llvm::ArrayRef<ImporterSource> Sources) : LogStream(&llvm::nulls()), Target(Target) {
399*a7dea167SDimitry Andric   SharedState = std::make_shared<ASTImporterSharedState>(
400*a7dea167SDimitry Andric       *Target.AST.getTranslationUnitDecl());
4010b57cec5SDimitry Andric   AddSources(Sources);
4020b57cec5SDimitry Andric }
4030b57cec5SDimitry Andric 
404*a7dea167SDimitry Andric Decl *ExternalASTMerger::FindOriginalDecl(Decl *D) {
405*a7dea167SDimitry Andric   assert(&D->getASTContext() == &Target.AST);
406*a7dea167SDimitry Andric   for (const auto &I : Importers)
407*a7dea167SDimitry Andric     if (auto Result = I->GetOriginalDecl(D))
408*a7dea167SDimitry Andric       return Result;
409*a7dea167SDimitry Andric   return nullptr;
410*a7dea167SDimitry Andric }
411*a7dea167SDimitry Andric 
4120b57cec5SDimitry Andric void ExternalASTMerger::AddSources(llvm::ArrayRef<ImporterSource> Sources) {
4130b57cec5SDimitry Andric   for (const ImporterSource &S : Sources) {
414*a7dea167SDimitry Andric     assert(&S.getASTContext() != &Target.AST);
415*a7dea167SDimitry Andric     // Check that the associated merger actually imports into the source AST.
416*a7dea167SDimitry Andric     assert(!S.getMerger() || &S.getMerger()->Target.AST == &S.getASTContext());
417*a7dea167SDimitry Andric     Importers.push_back(std::make_unique<LazyASTImporter>(
418*a7dea167SDimitry Andric         *this, Target.AST, Target.FM, S, SharedState));
4190b57cec5SDimitry Andric   }
4200b57cec5SDimitry Andric }
4210b57cec5SDimitry Andric 
4220b57cec5SDimitry Andric void ExternalASTMerger::RemoveSources(llvm::ArrayRef<ImporterSource> Sources) {
4230b57cec5SDimitry Andric   if (LoggingEnabled())
4240b57cec5SDimitry Andric     for (const ImporterSource &S : Sources)
4250b57cec5SDimitry Andric       logs() << "(ExternalASTMerger*)" << (void *)this
426*a7dea167SDimitry Andric              << " removing source (ASTContext*)" << (void *)&S.getASTContext()
4270b57cec5SDimitry Andric              << "\n";
4280b57cec5SDimitry Andric   Importers.erase(
4290b57cec5SDimitry Andric       std::remove_if(Importers.begin(), Importers.end(),
4300b57cec5SDimitry Andric                      [&Sources](std::unique_ptr<ASTImporter> &Importer) -> bool {
4310b57cec5SDimitry Andric                        for (const ImporterSource &S : Sources) {
432*a7dea167SDimitry Andric                          if (&Importer->getFromContext() == &S.getASTContext())
4330b57cec5SDimitry Andric                            return true;
4340b57cec5SDimitry Andric                        }
4350b57cec5SDimitry Andric                        return false;
4360b57cec5SDimitry Andric                      }),
4370b57cec5SDimitry Andric       Importers.end());
4380b57cec5SDimitry Andric   for (OriginMap::iterator OI = Origins.begin(), OE = Origins.end(); OI != OE; ) {
4390b57cec5SDimitry Andric     std::pair<const DeclContext *, DCOrigin> Origin = *OI;
4400b57cec5SDimitry Andric     bool Erase = false;
4410b57cec5SDimitry Andric     for (const ImporterSource &S : Sources) {
442*a7dea167SDimitry Andric       if (&S.getASTContext() == Origin.second.AST) {
4430b57cec5SDimitry Andric         Erase = true;
4440b57cec5SDimitry Andric         break;
4450b57cec5SDimitry Andric       }
4460b57cec5SDimitry Andric     }
4470b57cec5SDimitry Andric     if (Erase)
4480b57cec5SDimitry Andric       OI = Origins.erase(OI);
4490b57cec5SDimitry Andric     else
4500b57cec5SDimitry Andric       ++OI;
4510b57cec5SDimitry Andric   }
4520b57cec5SDimitry Andric }
4530b57cec5SDimitry Andric 
4540b57cec5SDimitry Andric template <typename DeclTy>
4550b57cec5SDimitry Andric static bool importSpecializations(DeclTy *D, ASTImporter *Importer) {
4560b57cec5SDimitry Andric   for (auto *Spec : D->specializations()) {
4570b57cec5SDimitry Andric     auto ImportedSpecOrError = Importer->Import(Spec);
4580b57cec5SDimitry Andric     if (!ImportedSpecOrError) {
4590b57cec5SDimitry Andric       llvm::consumeError(ImportedSpecOrError.takeError());
4600b57cec5SDimitry Andric       return true;
4610b57cec5SDimitry Andric     }
4620b57cec5SDimitry Andric   }
4630b57cec5SDimitry Andric   return false;
4640b57cec5SDimitry Andric }
4650b57cec5SDimitry Andric 
4660b57cec5SDimitry Andric /// Imports specializations from template declarations that can be specialized.
4670b57cec5SDimitry Andric static bool importSpecializationsIfNeeded(Decl *D, ASTImporter *Importer) {
4680b57cec5SDimitry Andric   if (!isa<TemplateDecl>(D))
4690b57cec5SDimitry Andric     return false;
4700b57cec5SDimitry Andric   if (auto *FunctionTD = dyn_cast<FunctionTemplateDecl>(D))
4710b57cec5SDimitry Andric     return importSpecializations(FunctionTD, Importer);
4720b57cec5SDimitry Andric   else if (auto *ClassTD = dyn_cast<ClassTemplateDecl>(D))
4730b57cec5SDimitry Andric     return importSpecializations(ClassTD, Importer);
4740b57cec5SDimitry Andric   else if (auto *VarTD = dyn_cast<VarTemplateDecl>(D))
4750b57cec5SDimitry Andric     return importSpecializations(VarTD, Importer);
4760b57cec5SDimitry Andric   return false;
4770b57cec5SDimitry Andric }
4780b57cec5SDimitry Andric 
4790b57cec5SDimitry Andric bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
4800b57cec5SDimitry Andric                                                        DeclarationName Name) {
4810b57cec5SDimitry Andric   llvm::SmallVector<NamedDecl *, 1> Decls;
4820b57cec5SDimitry Andric   llvm::SmallVector<Candidate, 4> Candidates;
4830b57cec5SDimitry Andric 
4840b57cec5SDimitry Andric   auto FilterFoundDecl = [&Candidates](const Candidate &C) {
4850b57cec5SDimitry Andric    if (!HasDeclOfSameType(Candidates, C))
4860b57cec5SDimitry Andric      Candidates.push_back(C);
4870b57cec5SDimitry Andric   };
4880b57cec5SDimitry Andric 
4890b57cec5SDimitry Andric   ForEachMatchingDC(DC,
4900b57cec5SDimitry Andric                     [&](ASTImporter &Forward, ASTImporter &Reverse,
4910b57cec5SDimitry Andric                         Source<const DeclContext *> SourceDC) -> bool {
4920b57cec5SDimitry Andric                       auto FromNameOrErr = Reverse.Import(Name);
4930b57cec5SDimitry Andric                       if (!FromNameOrErr) {
4940b57cec5SDimitry Andric                         llvm::consumeError(FromNameOrErr.takeError());
4950b57cec5SDimitry Andric                         return false;
4960b57cec5SDimitry Andric                       }
4970b57cec5SDimitry Andric                       DeclContextLookupResult Result =
4980b57cec5SDimitry Andric                           SourceDC.get()->lookup(*FromNameOrErr);
4990b57cec5SDimitry Andric                       for (NamedDecl *FromD : Result) {
5000b57cec5SDimitry Andric                         FilterFoundDecl(std::make_pair(FromD, &Forward));
5010b57cec5SDimitry Andric                       }
5020b57cec5SDimitry Andric                       return false;
5030b57cec5SDimitry Andric                     });
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric   if (Candidates.empty())
5060b57cec5SDimitry Andric     return false;
5070b57cec5SDimitry Andric 
5080b57cec5SDimitry Andric   Decls.reserve(Candidates.size());
5090b57cec5SDimitry Andric   for (const Candidate &C : Candidates) {
5100b57cec5SDimitry Andric     Decl *LookupRes = C.first.get();
5110b57cec5SDimitry Andric     ASTImporter *Importer = C.second;
5120b57cec5SDimitry Andric     auto NDOrErr = Importer->Import(LookupRes);
5130b57cec5SDimitry Andric     assert(NDOrErr);
5140b57cec5SDimitry Andric     (void)static_cast<bool>(NDOrErr);
5150b57cec5SDimitry Andric     NamedDecl *ND = cast_or_null<NamedDecl>(*NDOrErr);
5160b57cec5SDimitry Andric     assert(ND);
5170b57cec5SDimitry Andric     // If we don't import specialization, they are not available via lookup
5180b57cec5SDimitry Andric     // because the lookup result is imported TemplateDecl and it does not
5190b57cec5SDimitry Andric     // reference its specializations until they are imported explicitly.
5200b57cec5SDimitry Andric     bool IsSpecImportFailed =
5210b57cec5SDimitry Andric         importSpecializationsIfNeeded(LookupRes, Importer);
5220b57cec5SDimitry Andric     assert(!IsSpecImportFailed);
5230b57cec5SDimitry Andric     (void)IsSpecImportFailed;
5240b57cec5SDimitry Andric     Decls.push_back(ND);
5250b57cec5SDimitry Andric   }
5260b57cec5SDimitry Andric   SetExternalVisibleDeclsForName(DC, Name, Decls);
5270b57cec5SDimitry Andric   return true;
5280b57cec5SDimitry Andric }
5290b57cec5SDimitry Andric 
5300b57cec5SDimitry Andric void ExternalASTMerger::FindExternalLexicalDecls(
5310b57cec5SDimitry Andric     const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
5320b57cec5SDimitry Andric     SmallVectorImpl<Decl *> &Result) {
5330b57cec5SDimitry Andric   ForEachMatchingDC(DC, [&](ASTImporter &Forward, ASTImporter &Reverse,
5340b57cec5SDimitry Andric                             Source<const DeclContext *> SourceDC) -> bool {
5350b57cec5SDimitry Andric     for (const Decl *SourceDecl : SourceDC.get()->decls()) {
5360b57cec5SDimitry Andric       if (IsKindWeWant(SourceDecl->getKind())) {
5370b57cec5SDimitry Andric         auto ImportedDeclOrErr = Forward.Import(SourceDecl);
5380b57cec5SDimitry Andric         if (ImportedDeclOrErr)
5390b57cec5SDimitry Andric           assert(!(*ImportedDeclOrErr) ||
5400b57cec5SDimitry Andric                  IsSameDC((*ImportedDeclOrErr)->getDeclContext(), DC));
5410b57cec5SDimitry Andric         else
5420b57cec5SDimitry Andric           llvm::consumeError(ImportedDeclOrErr.takeError());
5430b57cec5SDimitry Andric       }
5440b57cec5SDimitry Andric     }
5450b57cec5SDimitry Andric     return false;
5460b57cec5SDimitry Andric   });
5470b57cec5SDimitry Andric }
5480b57cec5SDimitry Andric 
549