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