25template <
typename T> 
struct Source {
 
   28  operator T() { 
return t; }
 
   29  template <
typename U = T> U &get() { 
return t; }
 
   30  template <
typename U = T> 
const U &get()
 const { 
return t; }
 
   31  template <
typename U> 
operator Source<U>() { 
return Source<U>(t); }
 
   34typedef std::pair<Source<NamedDecl *>, 
ASTImporter *> Candidate;
 
   44Source<const DeclContext *>
 
   45LookupSameContext(Source<TranslationUnitDecl *> SourceTU, 
const DeclContext *DC,
 
   47  DC = CanonicalizeDC(DC);
 
   51  Source<const DeclContext *> SourceParentDC =
 
   52      LookupSameContext(SourceTU, DC->
getParent(), ReverseImporter);
 
   53  if (!SourceParentDC) {
 
   59  auto SourceNameOrErr = ReverseImporter.
Import(Name);
 
   60  if (!SourceNameOrErr) {
 
   61    llvm::consumeError(SourceNameOrErr.takeError());
 
   64  Source<DeclarationName> SourceName = *SourceNameOrErr;
 
   66      SourceParentDC.get()->lookup(SourceName.get());
 
  101  ExternalASTMerger &Parent;
 
  105  bool TemporarySource;
 
  108  llvm::DenseMap<Decl *, Decl *> ToOrigin;
 
  110  ExternalASTMerger *SourceMerger;
 
  111  llvm::raw_ostream &logs() { 
return Parent.logs(); }
 
  113  LazyASTImporter(ExternalASTMerger &_Parent, ASTContext &ToContext,
 
  114                  FileManager &ToFileManager,
 
  115                  const ExternalASTMerger::ImporterSource &S,
 
  116                  std::shared_ptr<ASTImporterSharedState> SharedState)
 
  117      : ASTImporter(ToContext, ToFileManager, S.getASTContext(),
 
  121        Reverse(S.getASTContext(), S.getFileManager(), ToContext, ToFileManager,
 
  123        FromOrigins(S.getOriginMap()), TemporarySource(S.isTemporary()),
 
  124        SourceMerger(S.getMerger()) {}
 
  126  llvm::Expected<Decl *> ImportImpl(Decl *FromD)
 override {
 
  127    if (!TemporarySource || !SourceMerger)
 
  164    Decl *Persistent = SourceMerger->FindOriginalDecl(FromD);
 
  171    ASTImporter &OtherImporter = Parent.ImporterForOrigin(PersistentCtx);
 
  173    assert((&PersistentCtx != &getFromContext()) && (&OtherImporter != 
this) &&
 
  174           "Delegated to same Importer?");
 
  175    auto DeclOrErr = OtherImporter.
Import(Persistent);
 
  179      return DeclOrErr.takeError();
 
  180    Decl *D = *DeclOrErr;
 
  183    MapImported(FromD, D);
 
  189  Decl *GetOriginalDecl(Decl *To)
 override {
 
  190    return ToOrigin.lookup(To);
 
  195  void Imported(Decl *From, Decl *To)
 override {
 
  198    if (
auto *ToDC = dyn_cast<DeclContext>(To)) {
 
  199      const bool LoggingEnabled = Parent.LoggingEnabled();
 
  201        logs() << 
"(ExternalASTMerger*)" << (
void*)&Parent
 
  202               << 
" imported (DeclContext*)" << (
void*)ToDC
 
  203               << 
", (ASTContext*)" << (
void*)&getToContext()
 
  204               << 
" from (DeclContext*)" << (
void*)llvm::cast<DeclContext>(From)
 
  205               << 
", (ASTContext*)" << (
void*)&getFromContext()
 
  207      Source<DeclContext *> FromDC(
 
  209      if (
auto It = FromOrigins.find(FromDC);
 
  210          It != FromOrigins.end() &&
 
  211          Parent.HasImporterForOrigin(*It->second.AST)) {
 
  213          logs() << 
"(ExternalASTMerger*)" << (
void *)&Parent
 
  214                 << 
" forced origin (DeclContext*)" << (
void *)It->second.DC
 
  215                 << 
", (ASTContext*)" << (
void *)It->second.AST << 
"\n";
 
  216        Parent.ForceRecordOrigin(ToDC, It->second);
 
  219          logs() << 
"(ExternalASTMerger*)" << (
void*)&Parent
 
  220                 << 
" maybe recording origin (DeclContext*)" << (
void*)FromDC
 
  221                 << 
", (ASTContext*)" << (
void*)&getFromContext()
 
  223        Parent.MaybeRecordOrigin(ToDC, {FromDC, &getFromContext()});
 
  226    if (
auto *ToTag = dyn_cast<TagDecl>(To)) {
 
  227      ToTag->setHasExternalLexicalStorage();
 
  228      ToTag->getPrimaryContext()->setMustBuildLookupTable();
 
  229      assert(Parent.CanComplete(ToTag));
 
  230    } 
else if (
auto *ToNamespace = dyn_cast<NamespaceDecl>(To)) {
 
  231      ToNamespace->setHasExternalVisibleStorage();
 
  232      assert(Parent.CanComplete(ToNamespace));
 
  233    } 
else if (
auto *ToContainer = dyn_cast<ObjCContainerDecl>(To)) {
 
  234      ToContainer->setHasExternalLexicalStorage();
 
  235      ToContainer->getPrimaryContext()->setMustBuildLookupTable();
 
  236      assert(Parent.CanComplete(ToContainer));
 
  239  ASTImporter &GetReverse() { 
return Reverse; }
 
  245  return llvm::any_of(Decls, [&](
const Candidate &D) {
 
  246    return C.first.get()->getKind() == D.first.get()->getKind();
 
  253  for (
const std::unique_ptr<ASTImporter> &I : Importers)
 
  254    if (&I->getFromContext() == &OriginContext)
 
  256  llvm_unreachable(
"We should have an importer for this origin!");
 
 
  262  return static_cast<LazyASTImporter &
>(
 
  268  for (
const std::unique_ptr<ASTImporter> &I : Importers)
 
  269    if (&I->getFromContext() == &OriginContext)
 
 
  274template <
typename CallbackType>
 
  275void ExternalASTMerger::ForEachMatchingDC(
const DeclContext *DC,
 
  276                                          CallbackType Callback) {
 
  277  if (
auto It = Origins.find(DC); It != Origins.end()) {
 
  279    LazyASTImporter &Importer = LazyImporterForOrigin(*
this, *Origin.
AST);
 
  280    Callback(Importer, Importer.GetReverse(), Origin.
DC);
 
  282    bool DidCallback = 
false;
 
  283    for (
const std::unique_ptr<ASTImporter> &Importer : Importers) {
 
  284      Source<TranslationUnitDecl *> SourceTU =
 
  285          Importer->getFromContext().getTranslationUnitDecl();
 
  287          static_cast<LazyASTImporter *
>(Importer.get())->GetReverse();
 
  288      if (
auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
 
  290        if (Callback(*Importer, Reverse, SourceDC))
 
  295      logs() << 
"(ExternalASTMerger*)" << (
void*)
this 
  296             << 
" asserting for (DeclContext*)" << (
const void*)DC
 
  297             << 
", (ASTContext*)" << (
void*)&Target.AST
 
  299    assert(DidCallback && 
"Couldn't find a source context matching our DC");
 
  304  assert(Tag->hasExternalLexicalStorage());
 
  306                             Source<const DeclContext *> SourceDC) -> 
bool {
 
  308    if (SourceTag->hasExternalLexicalStorage())
 
  310    if (!SourceTag->getDefinition())
 
  312    Forward.MapImported(SourceTag, Tag);
 
  313    if (llvm::Error Err = Forward.ImportDefinition(SourceTag))
 
  314      llvm::consumeError(std::move(Err));
 
  315    Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
 
 
  321  assert(
Interface->hasExternalLexicalStorage());
 
  324                     Source<const DeclContext *> SourceDC) -> 
bool {
 
  327        if (SourceInterface->hasExternalLexicalStorage())
 
  330        if (!SourceInterface->getDefinition())
 
  332        Forward.MapImported(SourceInterface, 
Interface);
 
  333        if (llvm::Error Err = Forward.ImportDefinition(SourceInterface))
 
  334          llvm::consumeError(std::move(Err));
 
 
  340  assert(
Interface->hasExternalLexicalStorage() ||
 
  342  bool FoundMatchingDC = 
false;
 
  345                        Source<const DeclContext *> SourceDC) -> 
bool {
 
  346                      FoundMatchingDC = 
true;
 
  349  return FoundMatchingDC;
 
 
  356  if (
auto *T1 = dyn_cast<TagDecl>(D1))
 
  357    if (
auto *T2 = dyn_cast<TagDecl>(D2))
 
  358      if (T1->getFirstDecl() == T2->getFirstDecl())
 
  360  return D1 == D2 || D1 == CanonicalizeDC(D2);
 
  366  LazyASTImporter &Importer = LazyImporterForOrigin(*
this, *Origin.
AST);
 
  368  Source<const DeclContext *> FoundFromDC =
 
  370  const bool DoRecord = !FoundFromDC || !IsSameDC(FoundFromDC.get(), Origin.
DC);
 
  372    RecordOriginImpl(ToDC, Origin, Importer);
 
  374    logs() << 
"(ExternalASTMerger*)" << (
void*)
this 
  375             << (DoRecord ? 
" decided " : 
" decided NOT")
 
  376             << 
" to record origin (DeclContext*)" << (
void*)Origin.
DC 
  377             << 
", (ASTContext*)" << (
void*)&Origin.
AST 
 
  386void ExternalASTMerger::RecordOriginImpl(
const DeclContext *ToDC, DCOrigin Origin,
 
  388  Origins[ToDC] = Origin;
 
  394    : LogStream(&
llvm::nulls()), Target(Target) {
 
  395  SharedState = std::make_shared<ASTImporterSharedState>(
 
  396      *Target.AST.getTranslationUnitDecl());
 
 
  402  for (
const auto &I : Importers)
 
  403    if (
auto Result = I->GetOriginalDecl(D))
 
 
  410    assert(&S.getASTContext() != &Target.AST);
 
  412    assert(!S.getMerger() || &S.getMerger()->Target.AST == &S.getASTContext());
 
  413    Importers.push_back(std::make_unique<LazyASTImporter>(
 
  414        *
this, Target.AST, Target.FM, S, SharedState));
 
 
  421      logs() << 
"(ExternalASTMerger*)" << (
void *)
this 
  422             << 
" removing source (ASTContext*)" << (
void *)&S.getASTContext()
 
  424  llvm::erase_if(Importers,
 
  425                 [&Sources](std::unique_ptr<ASTImporter> &Importer) -> 
bool {
 
  427                     if (&Importer->getFromContext() == &S.getASTContext())
 
  432  for (OriginMap::iterator OI = Origins.begin(), OE = Origins.end(); OI != OE; ) {
 
  433    std::pair<const DeclContext *, DCOrigin> Origin = *OI;
 
  436      if (&S.getASTContext() == Origin.second.AST) {
 
  442      OI = Origins.erase(OI);
 
 
  448template <
typename DeclTy>
 
  450  for (
auto *Spec : D->specializations()) {
 
  451    auto ImportedSpecOrError = Importer->
Import(Spec);
 
  452    if (!ImportedSpecOrError) {
 
  453      llvm::consumeError(ImportedSpecOrError.takeError());
 
 
  464  if (
auto *FunctionTD = dyn_cast<FunctionTemplateDecl>(D))
 
  466  else if (
auto *ClassTD = dyn_cast<ClassTemplateDecl>(D))
 
  468  else if (
auto *VarTD = dyn_cast<VarTemplateDecl>(D))
 
 
  479  auto FilterFoundDecl = [&Candidates](
const Candidate &
C) {
 
  480   if (!HasDeclOfSameType(Candidates, 
C))
 
  481     Candidates.push_back(
C);
 
  484  ForEachMatchingDC(DC,
 
  486                        Source<const DeclContext *> SourceDC) -> 
bool {
 
  487                      auto FromNameOrErr = Reverse.
Import(Name);
 
  488                      if (!FromNameOrErr) {
 
  489                        llvm::consumeError(FromNameOrErr.takeError());
 
  493                          SourceDC.get()->lookup(*FromNameOrErr);
 
  495                        FilterFoundDecl(std::make_pair(FromD, &Forward));
 
  500  if (Candidates.empty())
 
  503  Decls.reserve(Candidates.size());
 
  504  for (
const Candidate &
C : Candidates) {
 
  505    Decl *LookupRes = 
C.first.get();
 
  507    auto NDOrErr = Importer->
Import(LookupRes);
 
  513    bool IsSpecImportFailed =
 
  515    assert(!IsSpecImportFailed);
 
  516    (void)IsSpecImportFailed;
 
 
  527                            Source<const DeclContext *> SourceDC) -> 
bool {
 
  528    for (
const Decl *SourceDecl : SourceDC.get()->decls()) {
 
  529      if (IsKindWeWant(SourceDecl->getKind())) {
 
  530        auto ImportedDeclOrErr = Forward.Import(SourceDecl);
 
  531        if (ImportedDeclOrErr)
 
  532          assert(!(*ImportedDeclOrErr) ||
 
  533                 IsSameDC((*ImportedDeclOrErr)->getDeclContext(), DC));
 
  535          llvm::consumeError(ImportedDeclOrErr.takeError());
 
 
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Defines the C++ template declaration subclasses.
static bool importSpecializations(DeclTy *D, ASTImporter *Importer)
static bool importSpecializationsIfNeeded(Decl *D, ASTImporter *Importer)
Imports specializations from template declarations that can be specialized.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...
virtual Expected< Decl * > ImportImpl(Decl *From)
Can be overwritten by subclasses to implement their own import logic.
llvm::Expected< ExprWithCleanups::CleanupObject > Import(ExprWithCleanups::CleanupObject From)
Import cleanup objects owned by ExprWithCleanup.
The results of name lookup within a DeclContext.
bool isSingleResult() const
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
DeclContextLookupResult lookup_result
bool isTranslationUnit() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Decl::Kind getDeclKind() const
Decl - This represents one declaration (or definition), e.g.
ASTContext & getASTContext() const LLVM_READONLY
Kind
Lists the kind of concrete classes of Decl.
The name of a declaration.
A source for an ExternalASTMerger.
ExternalASTSource implementation that merges information from several ASTContexts.
llvm::raw_ostream & logs()
Log something if there is a logging callback installed.
ASTImporter & ImporterForOrigin(ASTContext &OriginContext)
Returns a reference to the ASTImporter from Importers whose origin is OriginContext.
Decl * FindOriginalDecl(Decl *D)
Asks all connected ASTImporters if any of them imported the given declaration.
void CompleteType(TagDecl *Tag) override
Implementation of the ExternalASTSource API.
void MaybeRecordOrigin(const DeclContext *ToDC, DCOrigin Origin)
Records an origin in Origins only if name lookup would find something different or nothing at all.
std::map< const DeclContext *, DCOrigin > OriginMap
ExternalASTMerger(const ImporterTarget &Target, ArrayRef< ImporterSource > Sources)
void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin)
Regardless of any checks, override the Origin for a DeclContext.
void RemoveSources(ArrayRef< ImporterSource > Sources)
Remove a set of ASTContexts as possible origins.
bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name, const DeclContext *OriginalDC) override
Implementation of the ExternalASTSource API.
bool CanComplete(DeclContext *DC)
Returns true if DC can be found in any source AST context.
bool LoggingEnabled()
True if the log stream is not llvm::nulls();.
void AddSources(ArrayRef< ImporterSource > Sources)
Add a set of ASTContexts as possible origins.
bool HasImporterForOrigin(ASTContext &OriginContext)
Returns true if Importers contains an ASTImporter whose source is OriginContext.
void FindExternalLexicalDecls(const DeclContext *DC, llvm::function_ref< bool(Decl::Kind)> IsKindWeWant, SmallVectorImpl< Decl * > &Result) override
Implementation of the ExternalASTSource API.
static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef< NamedDecl * > Decls)
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
This represents a decl that may have a name.
Represents an ObjC class declaration.
Represents the declaration of a struct/union/class/enum.
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
@ Result
The result type of a method or function.
const FunctionProtoType * T
U cast(CodeGen::Address addr)
@ Interface
The "__interface" keyword introduces the elaborated-type-specifier.
Diagnostic wrappers for TextAPI types for error reporting.
A single origin for a DeclContext.
The target for an ExternalASTMerger.