Coverage Report

Created: 2020-09-22 08:39

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/AST/ExternalASTMerger.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- ExternalASTMerger.cpp - Merging External AST Interface ---*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
//  This file implements the ExternalASTMerger, which vends a combination of
10
//  ASTs from several different ASTContext/FileManager pairs
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/ASTContext.h"
15
#include "clang/AST/Decl.h"
16
#include "clang/AST/DeclCXX.h"
17
#include "clang/AST/DeclObjC.h"
18
#include "clang/AST/DeclTemplate.h"
19
#include "clang/AST/ExternalASTMerger.h"
20
21
using namespace clang;
22
23
namespace {
24
25
template <typename T> struct Source {
26
  T t;
27
11.3k
  Source(T t) : t(t) {}
ExternalASTMerger.cpp:(anonymous namespace)::Source<clang::DeclContext const*>::Source(clang::DeclContext const*)
Line
Count
Source
27
5.01k
  Source(T t) : t(t) {}
ExternalASTMerger.cpp:(anonymous namespace)::Source<clang::DeclarationName>::Source(clang::DeclarationName)
Line
Count
Source
27
1.67k
  Source(T t) : t(t) {}
ExternalASTMerger.cpp:(anonymous namespace)::Source<clang::TranslationUnitDecl*>::Source(clang::TranslationUnitDecl*)
Line
Count
Source
27
2.95k
  Source(T t) : t(t) {}
ExternalASTMerger.cpp:(anonymous namespace)::Source<clang::DeclContext*>::Source(clang::DeclContext*)
Line
Count
Source
27
739
  Source(T t) : t(t) {}
ExternalASTMerger.cpp:(anonymous namespace)::Source<clang::NamedDecl*>::Source(clang::NamedDecl*)
Line
Count
Source
27
955
  Source(T t) : t(t) {}
28
6.35k
  operator T() { return t; }
ExternalASTMerger.cpp:(anonymous namespace)::Source<clang::DeclContext const*>::operator clang::DeclContext const*()
Line
Count
Source
28
4.68k
  operator T() { return t; }
ExternalASTMerger.cpp:(anonymous namespace)::Source<clang::DeclContext*>::operator clang::DeclContext*()
Line
Count
Source
28
1.66k
  operator T() { return t; }
29
5.79k
  template <typename U = T> U &get() { return t; }
ExternalASTMerger.cpp:clang::DeclarationName& (anonymous namespace)::Source<clang::DeclarationName>::get<clang::DeclarationName>()
Line
Count
Source
29
1.67k
  template <typename U = T> U &get() { return t; }
ExternalASTMerger.cpp:clang::DeclContext const*& (anonymous namespace)::Source<clang::DeclContext const*>::get<clang::DeclContext const*>()
Line
Count
Source
29
4.12k
  template <typename U = T> U &get() { return t; }
30
1.98k
  template <typename U = T> const U &get() const { return t; }
31
2.95k
  template <typename U> operator Source<U>() { return Source<U>(t); }
32
};
33
34
typedef std::pair<Source<NamedDecl *>, ASTImporter *> Candidate;
35
36
/// For the given DC, return the DC that is safe to perform lookups on.  This is
37
/// the DC we actually want to work with most of the time.
38
4.68k
const DeclContext *CanonicalizeDC(const DeclContext *DC) {
39
4.68k
  if (isa<LinkageSpecDecl>(DC))
40
6
    return DC->getRedeclContext();
41
4.68k
  return DC;
42
4.68k
}
43
44
Source<const DeclContext *>
45
LookupSameContext(Source<TranslationUnitDecl *> SourceTU, const DeclContext *DC,
46
4.68k
                  ASTImporter &ReverseImporter) {
47
4.68k
  DC = CanonicalizeDC(DC);
48
4.68k
  if (DC->isTranslationUnit()) {
49
2.95k
    return SourceTU;
50
2.95k
  }
51
1.73k
  Source<const DeclContext *> SourceParentDC =
52
1.73k
      LookupSameContext(SourceTU, DC->getParent(), ReverseImporter);
53
1.73k
  if (!SourceParentDC) {
54
    // If we couldn't find the parent DC in this TranslationUnit, give up.
55
55
    return nullptr;
56
55
  }
57
1.67k
  auto *ND = cast<NamedDecl>(DC);
58
1.67k
  DeclarationName Name = ND->getDeclName();
59
1.67k
  auto SourceNameOrErr = ReverseImporter.Import(Name);
60
1.67k
  if (!SourceNameOrErr) {
61
2
    llvm::consumeError(SourceNameOrErr.takeError());
62
2
    return nullptr;
63
2
  }
64
1.67k
  Source<DeclarationName> SourceName = *SourceNameOrErr;
65
1.67k
  DeclContext::lookup_result SearchResult =
66
1.67k
      SourceParentDC.get()->lookup(SourceName.get());
67
1.67k
  size_t SearchResultSize = SearchResult.size();
68
1.67k
  if (SearchResultSize == 0 || 
SearchResultSize > 11.48k
) {
69
    // There are two cases here.  First, we might not find the name.
70
    // We might also find multiple copies, in which case we have no
71
    // guarantee that the one we wanted is the one we pick.  (E.g.,
72
    // if we have two specializations of the same template it is
73
    // very hard to determine which is the one you want.)
74
    //
75
    // The Origins map fixes this problem by allowing the origin to be
76
    // explicitly recorded, so we trigger that recording by returning
77
    // nothing (rather than a possibly-inaccurate guess) here.
78
253
    return nullptr;
79
1.42k
  } else {
80
1.42k
    NamedDecl *SearchResultDecl = SearchResult[0];
81
1.42k
    if (isa<DeclContext>(SearchResultDecl) &&
82
1.36k
        SearchResultDecl->getKind() == DC->getDeclKind())
83
1.36k
      return cast<DeclContext>(SearchResultDecl)->getPrimaryContext();
84
55
    return nullptr; // This type of lookup is unsupported
85
55
  }
86
1.67k
}
87
88
/// A custom implementation of ASTImporter, for ExternalASTMerger's purposes.
89
///
90
/// There are several modifications:
91
///
92
/// - It enables lazy lookup (via the HasExternalLexicalStorage flag and a few
93
///   others), which instructs Clang to refer to ExternalASTMerger.  Also, it
94
///   forces MinimalImport to true, which is necessary to make this work.
95
/// - It maintains a reverse importer for use with names.  This allows lookup of
96
///   arbitrary names in the source context.
97
/// - It updates the ExternalASTMerger's origin map as needed whenever a
98
///   it sees a DeclContext.
99
class LazyASTImporter : public ASTImporter {
100
private:
101
  ExternalASTMerger &Parent;
102
  ASTImporter Reverse;
103
  const ExternalASTMerger::OriginMap &FromOrigins;
104
  /// @see ExternalASTMerger::ImporterSource::Temporary
105
  bool TemporarySource;
106
  /// Map of imported declarations back to the declarations they originated
107
  /// from.
108
  llvm::DenseMap<Decl *, Decl *> ToOrigin;
109
  /// @see ExternalASTMerger::ImporterSource::Merger
110
  ExternalASTMerger *SourceMerger;
111
0
  llvm::raw_ostream &logs() { return Parent.logs(); }
112
public:
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(),
118
                    S.getFileManager(),
119
                    /*MinimalImport=*/true, SharedState),
120
        Parent(_Parent),
121
        Reverse(S.getASTContext(), S.getFileManager(), ToContext, ToFileManager,
122
                /*MinimalImport=*/true),
123
        FromOrigins(S.getOriginMap()), TemporarySource(S.isTemporary()),
124
132
        SourceMerger(S.getMerger()) {}
125
126
2.37k
  llvm::Expected<Decl *> ImportImpl(Decl *FromD) override {
127
2.37k
    if (!TemporarySource || 
!SourceMerger0
)
128
2.37k
      return ASTImporter::ImportImpl(FromD);
129
130
    // If we get here, then this source is importing from a temporary ASTContext
131
    // that also has another ExternalASTMerger attached. It could be
132
    // possible that the current ExternalASTMerger and the temporary ASTContext
133
    // share a common ImporterSource, which means that the temporary
134
    // AST could contain declarations that were imported from a source
135
    // that this ExternalASTMerger can access directly. Instead of importing
136
    // such declarations from the temporary ASTContext, they should instead
137
    // be directly imported by this ExternalASTMerger from the original
138
    // source. This way the ExternalASTMerger can safely do a minimal import
139
    // without creating incomplete declarations originated from a temporary
140
    // ASTContext. If we would try to complete such declarations later on, we
141
    // would fail to do so as their temporary AST could be deleted (which means
142
    // that the missing parts of the minimally imported declaration in that
143
    // ASTContext were also deleted).
144
    //
145
    // The following code tracks back any declaration that needs to be
146
    // imported from the temporary ASTContext to a persistent ASTContext.
147
    // Then the ExternalASTMerger tries to import from the persistent
148
    // ASTContext directly by using the associated ASTImporter. If that
149
    // succeeds, this ASTImporter just maps the declarations imported by
150
    // the other (persistent) ASTImporter to this (temporary) ASTImporter.
151
    // The steps can be visualized like this:
152
    //
153
    //  Target AST <--- 3. Indirect import --- Persistent AST
154
    //       ^            of persistent decl        ^
155
    //       |                                      |
156
    // 1. Current import           2. Tracking back to persistent decl
157
    // 4. Map persistent decl                       |
158
    //  & pretend we imported.                      |
159
    //       |                                      |
160
    // Temporary AST -------------------------------'
161
162
    // First, ask the ExternalASTMerger of the source where the temporary
163
    // declaration originated from.
164
0
    Decl *Persistent = SourceMerger->FindOriginalDecl(FromD);
165
    // FromD isn't from a persistent AST, so just do a normal import.
166
0
    if (!Persistent)
167
0
      return ASTImporter::ImportImpl(FromD);
168
    // Now ask the current ExternalASTMerger to try import the persistent
169
    // declaration into the target.
170
0
    ASTContext &PersistentCtx = Persistent->getASTContext();
171
0
    ASTImporter &OtherImporter = Parent.ImporterForOrigin(PersistentCtx);
172
    // Check that we never end up in the current Importer again.
173
0
    assert((&PersistentCtx != &getFromContext()) && (&OtherImporter != this) &&
174
0
           "Delegated to same Importer?");
175
0
    auto DeclOrErr = OtherImporter.Import(Persistent);
176
    // Errors when importing the persistent decl are treated as if we
177
    // had errors with importing the temporary decl.
178
0
    if (!DeclOrErr)
179
0
      return DeclOrErr.takeError();
180
0
    Decl *D = *DeclOrErr;
181
    // Tell the current ASTImporter that this has already been imported
182
    // to prevent any further queries for the temporary decl.
183
0
    MapImported(FromD, D);
184
0
    return D;
185
0
  }
186
187
  /// Implements the ASTImporter interface for tracking back a declaration
188
  /// to its original declaration it came from.
189
4
  Decl *GetOriginalDecl(Decl *To) override {
190
4
    auto It = ToOrigin.find(To);
191
4
    if (It != ToOrigin.end())
192
0
      return It->second;
193
4
    return nullptr;
194
4
  }
195
196
  /// Whenever a DeclContext is imported, ensure that ExternalASTSource's origin
197
  /// map is kept up to date.  Also set the appropriate flags.
198
2.37k
  void Imported(Decl *From, Decl *To) override {
199
2.37k
    ToOrigin[To] = From;
200
201
2.37k
    if (auto *ToDC = dyn_cast<DeclContext>(To)) {
202
739
      const bool LoggingEnabled = Parent.LoggingEnabled();
203
739
      if (LoggingEnabled)
204
0
        logs() << "(ExternalASTMerger*)" << (void*)&Parent
205
0
               << " imported (DeclContext*)" << (void*)ToDC
206
0
               << ", (ASTContext*)" << (void*)&getToContext()
207
0
               << " from (DeclContext*)" << (void*)llvm::cast<DeclContext>(From)
208
0
               << ", (ASTContext*)" << (void*)&getFromContext()
209
0
               << "\n";
210
739
      Source<DeclContext *> FromDC(
211
739
          cast<DeclContext>(From)->getPrimaryContext());
212
739
      if (FromOrigins.count(FromDC) &&
213
187
          Parent.HasImporterForOrigin(*FromOrigins.at(FromDC).AST)) {
214
4
        if (LoggingEnabled)
215
0
          logs() << "(ExternalASTMerger*)" << (void*)&Parent
216
0
                 << " forced origin (DeclContext*)"
217
0
                 << (void*)FromOrigins.at(FromDC).DC
218
0
                 << ", (ASTContext*)"
219
0
                 << (void*)FromOrigins.at(FromDC).AST
220
0
                 << "\n";
221
4
        Parent.ForceRecordOrigin(ToDC, FromOrigins.at(FromDC));
222
735
      } else {
223
735
        if (LoggingEnabled)
224
0
          logs() << "(ExternalASTMerger*)" << (void*)&Parent
225
0
                 << " maybe recording origin (DeclContext*)" << (void*)FromDC
226
0
                 << ", (ASTContext*)" << (void*)&getFromContext()
227
0
                 << "\n";
228
735
        Parent.MaybeRecordOrigin(ToDC, {FromDC, &getFromContext()});
229
735
      }
230
739
    }
231
2.37k
    if (auto *ToTag = dyn_cast<TagDecl>(To)) {
232
468
      ToTag->setHasExternalLexicalStorage();
233
468
      ToTag->getPrimaryContext()->setMustBuildLookupTable();
234
468
      assert(Parent.CanComplete(ToTag));
235
1.90k
    } else if (auto *ToNamespace = dyn_cast<NamespaceDecl>(To)) {
236
24
      ToNamespace->setHasExternalVisibleStorage();
237
24
      assert(Parent.CanComplete(ToNamespace));
238
1.88k
    } else if (auto *ToContainer = dyn_cast<ObjCContainerDecl>(To)) {
239
32
      ToContainer->setHasExternalLexicalStorage();
240
32
      ToContainer->getPrimaryContext()->setMustBuildLookupTable();
241
32
      assert(Parent.CanComplete(ToContainer));
242
32
    }
243
2.37k
  }
244
3.28k
  ASTImporter &GetReverse() { return Reverse; }
245
};
246
247
955
bool HasDeclOfSameType(llvm::ArrayRef<Candidate> Decls, const Candidate &C) {
248
955
  if (isa<FunctionDecl>(C.first.get()))
249
75
    return false;
250
880
  return llvm::any_of(Decls, [&](const Candidate &D) {
251
76
    return C.first.get()->getKind() == D.first.get()->getKind();
252
76
  });
253
880
}
254
255
} // end namespace
256
257
1.06k
ASTImporter &ExternalASTMerger::ImporterForOrigin(ASTContext &OriginContext) {
258
1.06k
  for (const std::unique_ptr<ASTImporter> &I : Importers)
259
1.10k
    if (&I->getFromContext() == &OriginContext)
260
1.06k
      return *I;
261
1.06k
  
llvm_unreachable0
("We should have an importer for this origin!");
262
1.06k
}
263
264
namespace {
265
LazyASTImporter &LazyImporterForOrigin(ExternalASTMerger &Merger,
266
1.06k
                                   ASTContext &OriginContext) {
267
1.06k
  return static_cast<LazyASTImporter &>(
268
1.06k
      Merger.ImporterForOrigin(OriginContext));
269
1.06k
}
270
}
271
272
187
bool ExternalASTMerger::HasImporterForOrigin(ASTContext &OriginContext) {
273
187
  for (const std::unique_ptr<ASTImporter> &I : Importers)
274
215
    if (&I->getFromContext() == &OriginContext)
275
4
      return true;
276
183
  return false;
277
187
}
278
279
template <typename CallbackType>
280
void ExternalASTMerger::ForEachMatchingDC(const DeclContext *DC,
281
2.39k
                                          CallbackType Callback) {
282
2.39k
  if (Origins.count(DC)) {
283
329
    ExternalASTMerger::DCOrigin Origin = Origins[DC];
284
329
    LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
285
329
    Callback(Importer, Importer.GetReverse(), Origin.DC);
286
2.06k
  } else {
287
2.06k
    bool DidCallback = false;
288
2.22k
    for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
289
2.22k
      Source<TranslationUnitDecl *> SourceTU =
290
2.22k
          Importer->getFromContext().getTranslationUnitDecl();
291
2.22k
      ASTImporter &Reverse =
292
2.22k
          static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
293
2.22k
      if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
294
2.19k
        DidCallback = true;
295
2.19k
        if (Callback(*Importer, Reverse, SourceDC))
296
331
          break;
297
2.19k
      }
298
2.22k
    }
299
2.06k
    if (!DidCallback && 
LoggingEnabled()0
)
300
0
      logs() << "(ExternalASTMerger*)" << (void*)this
301
0
             << " asserting for (DeclContext*)" << (const void*)DC
302
0
             << ", (ASTContext*)" << (void*)&Target.AST
303
0
             << "\n";
304
2.06k
    assert(DidCallback && "Couldn't find a source context matching our DC");
305
2.06k
  }
306
2.39k
}
ExternalASTMerger.cpp:void clang::ExternalASTMerger::ForEachMatchingDC<clang::ExternalASTMerger::CompleteType(clang::TagDecl*)::$_0>(clang::DeclContext const*, clang::ExternalASTMerger::CompleteType(clang::TagDecl*)::$_0)
Line
Count
Source
281
6
                                          CallbackType Callback) {
282
6
  if (Origins.count(DC)) {
283
0
    ExternalASTMerger::DCOrigin Origin = Origins[DC];
284
0
    LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
285
0
    Callback(Importer, Importer.GetReverse(), Origin.DC);
286
6
  } else {
287
6
    bool DidCallback = false;
288
8
    for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
289
8
      Source<TranslationUnitDecl *> SourceTU =
290
8
          Importer->getFromContext().getTranslationUnitDecl();
291
8
      ASTImporter &Reverse =
292
8
          static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
293
8
      if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
294
8
        DidCallback = true;
295
8
        if (Callback(*Importer, Reverse, SourceDC))
296
4
          break;
297
8
      }
298
8
    }
299
6
    if (!DidCallback && 
LoggingEnabled()0
)
300
0
      logs() << "(ExternalASTMerger*)" << (void*)this
301
0
             << " asserting for (DeclContext*)" << (const void*)DC
302
0
             << ", (ASTContext*)" << (void*)&Target.AST
303
0
             << "\n";
304
6
    assert(DidCallback && "Couldn't find a source context matching our DC");
305
6
  }
306
6
}
ExternalASTMerger.cpp:void clang::ExternalASTMerger::ForEachMatchingDC<clang::ExternalASTMerger::CompleteType(clang::ObjCInterfaceDecl*)::$_1>(clang::DeclContext const*, clang::ExternalASTMerger::CompleteType(clang::ObjCInterfaceDecl*)::$_1)
Line
Count
Source
281
3
                                          CallbackType Callback) {
282
3
  if (Origins.count(DC)) {
283
0
    ExternalASTMerger::DCOrigin Origin = Origins[DC];
284
0
    LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
285
0
    Callback(Importer, Importer.GetReverse(), Origin.DC);
286
3
  } else {
287
3
    bool DidCallback = false;
288
4
    for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
289
4
      Source<TranslationUnitDecl *> SourceTU =
290
4
          Importer->getFromContext().getTranslationUnitDecl();
291
4
      ASTImporter &Reverse =
292
4
          static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
293
4
      if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
294
4
        DidCallback = true;
295
4
        if (Callback(*Importer, Reverse, SourceDC))
296
2
          break;
297
4
      }
298
4
    }
299
3
    if (!DidCallback && 
LoggingEnabled()0
)
300
0
      logs() << "(ExternalASTMerger*)" << (void*)this
301
0
             << " asserting for (DeclContext*)" << (const void*)DC
302
0
             << ", (ASTContext*)" << (void*)&Target.AST
303
0
             << "\n";
304
3
    assert(DidCallback && "Couldn't find a source context matching our DC");
305
3
  }
306
3
}
ExternalASTMerger.cpp:void clang::ExternalASTMerger::ForEachMatchingDC<clang::ExternalASTMerger::CanComplete(clang::DeclContext*)::$_2>(clang::DeclContext const*, clang::ExternalASTMerger::CanComplete(clang::DeclContext*)::$_2)
Line
Count
Source
281
524
                                          CallbackType Callback) {
282
524
  if (Origins.count(DC)) {
283
199
    ExternalASTMerger::DCOrigin Origin = Origins[DC];
284
199
    LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
285
199
    Callback(Importer, Importer.GetReverse(), Origin.DC);
286
325
  } else {
287
325
    bool DidCallback = false;
288
335
    for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
289
335
      Source<TranslationUnitDecl *> SourceTU =
290
335
          Importer->getFromContext().getTranslationUnitDecl();
291
335
      ASTImporter &Reverse =
292
335
          static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
293
335
      if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
294
325
        DidCallback = true;
295
325
        if (Callback(*Importer, Reverse, SourceDC))
296
325
          break;
297
325
      }
298
335
    }
299
325
    if (!DidCallback && 
LoggingEnabled()0
)
300
0
      logs() << "(ExternalASTMerger*)" << (void*)this
301
0
             << " asserting for (DeclContext*)" << (const void*)DC
302
0
             << ", (ASTContext*)" << (void*)&Target.AST
303
0
             << "\n";
304
325
    assert(DidCallback && "Couldn't find a source context matching our DC");
305
325
  }
306
524
}
ExternalASTMerger.cpp:void clang::ExternalASTMerger::ForEachMatchingDC<clang::ExternalASTMerger::FindExternalVisibleDeclsByName(clang::DeclContext const*, clang::DeclarationName)::$_5>(clang::DeclContext const*, clang::ExternalASTMerger::FindExternalVisibleDeclsByName(clang::DeclContext const*, clang::DeclarationName)::$_5)
Line
Count
Source
281
1.58k
                                          CallbackType Callback) {
282
1.58k
  if (Origins.count(DC)) {
283
30
    ExternalASTMerger::DCOrigin Origin = Origins[DC];
284
30
    LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
285
30
    Callback(Importer, Importer.GetReverse(), Origin.DC);
286
1.55k
  } else {
287
1.55k
    bool DidCallback = false;
288
1.68k
    for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
289
1.68k
      Source<TranslationUnitDecl *> SourceTU =
290
1.68k
          Importer->getFromContext().getTranslationUnitDecl();
291
1.68k
      ASTImporter &Reverse =
292
1.68k
          static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
293
1.68k
      if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
294
1.67k
        DidCallback = true;
295
1.67k
        if (Callback(*Importer, Reverse, SourceDC))
296
0
          break;
297
1.67k
      }
298
1.68k
    }
299
1.55k
    if (!DidCallback && 
LoggingEnabled()0
)
300
0
      logs() << "(ExternalASTMerger*)" << (void*)this
301
0
             << " asserting for (DeclContext*)" << (const void*)DC
302
0
             << ", (ASTContext*)" << (void*)&Target.AST
303
0
             << "\n";
304
1.55k
    assert(DidCallback && "Couldn't find a source context matching our DC");
305
1.55k
  }
306
1.58k
}
ExternalASTMerger.cpp:void clang::ExternalASTMerger::ForEachMatchingDC<clang::ExternalASTMerger::FindExternalLexicalDecls(clang::DeclContext const*, llvm::function_ref<bool (clang::Decl::Kind)>, llvm::SmallVectorImpl<clang::Decl*>&)::$_6>(clang::DeclContext const*, clang::ExternalASTMerger::FindExternalLexicalDecls(clang::DeclContext const*, llvm::function_ref<bool (clang::Decl::Kind)>, llvm::SmallVectorImpl<clang::Decl*>&)::$_6)
Line
Count
Source
281
274
                                          CallbackType Callback) {
282
274
  if (Origins.count(DC)) {
283
100
    ExternalASTMerger::DCOrigin Origin = Origins[DC];
284
100
    LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
285
100
    Callback(Importer, Importer.GetReverse(), Origin.DC);
286
174
  } else {
287
174
    bool DidCallback = false;
288
194
    for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
289
194
      Source<TranslationUnitDecl *> SourceTU =
290
194
          Importer->getFromContext().getTranslationUnitDecl();
291
194
      ASTImporter &Reverse =
292
194
          static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
293
194
      if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
294
184
        DidCallback = true;
295
184
        if (Callback(*Importer, Reverse, SourceDC))
296
0
          break;
297
184
      }
298
194
    }
299
174
    if (!DidCallback && 
LoggingEnabled()0
)
300
0
      logs() << "(ExternalASTMerger*)" << (void*)this
301
0
             << " asserting for (DeclContext*)" << (const void*)DC
302
0
             << ", (ASTContext*)" << (void*)&Target.AST
303
0
             << "\n";
304
174
    assert(DidCallback && "Couldn't find a source context matching our DC");
305
174
  }
306
274
}
307
308
6
void ExternalASTMerger::CompleteType(TagDecl *Tag) {
309
6
  assert(Tag->hasExternalLexicalStorage());
310
6
  ForEachMatchingDC(Tag, [&](ASTImporter &Forward, ASTImporter &Reverse,
311
8
                             Source<const DeclContext *> SourceDC) -> bool {
312
8
    auto *SourceTag = const_cast<TagDecl *>(cast<TagDecl>(SourceDC.get()));
313
8
    if (SourceTag->hasExternalLexicalStorage())
314
4
      SourceTag->getASTContext().getExternalSource()->CompleteType(SourceTag);
315
8
    if (!SourceTag->getDefinition())
316
4
      return false;
317
4
    Forward.MapImported(SourceTag, Tag);
318
4
    if (llvm::Error Err = Forward.ImportDefinition(SourceTag))
319
0
      llvm::consumeError(std::move(Err));
320
4
    Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
321
4
    return true;
322
4
  });
323
6
}
324
325
3
void ExternalASTMerger::CompleteType(ObjCInterfaceDecl *Interface) {
326
3
  assert(Interface->hasExternalLexicalStorage());
327
3
  ForEachMatchingDC(
328
3
      Interface, [&](ASTImporter &Forward, ASTImporter &Reverse,
329
4
                     Source<const DeclContext *> SourceDC) -> bool {
330
4
        auto *SourceInterface = const_cast<ObjCInterfaceDecl *>(
331
4
            cast<ObjCInterfaceDecl>(SourceDC.get()));
332
4
        if (SourceInterface->hasExternalLexicalStorage())
333
2
          SourceInterface->getASTContext().getExternalSource()->CompleteType(
334
2
              SourceInterface);
335
4
        if (!SourceInterface->getDefinition())
336
2
          return false;
337
2
        Forward.MapImported(SourceInterface, Interface);
338
2
        if (llvm::Error Err = Forward.ImportDefinition(SourceInterface))
339
0
          llvm::consumeError(std::move(Err));
340
2
        return true;
341
2
      });
342
3
}
343
344
524
bool ExternalASTMerger::CanComplete(DeclContext *Interface) {
345
524
  assert(Interface->hasExternalLexicalStorage() ||
346
524
         Interface->hasExternalVisibleStorage());
347
524
  bool FoundMatchingDC = false;
348
524
  ForEachMatchingDC(Interface,
349
524
                    [&](ASTImporter &Forward, ASTImporter &Reverse,
350
524
                        Source<const DeclContext *> SourceDC) -> bool {
351
524
                      FoundMatchingDC = true;
352
524
                      return true;
353
524
                    });
354
524
  return FoundMatchingDC;
355
524
}
356
357
namespace {
358
1.34k
bool IsSameDC(const DeclContext *D1, const DeclContext *D2) {
359
1.34k
  if (isa<ObjCContainerDecl>(D1) && 
isa<ObjCContainerDecl>(D2)42
)
360
42
    return true; // There are many cases where Objective-C is ambiguous.
361
1.30k
  if (auto *T1 = dyn_cast<TagDecl>(D1))
362
1.16k
    if (auto *T2 = dyn_cast<TagDecl>(D2))
363
1.16k
      if (T1->getFirstDecl() == T2->getFirstDecl())
364
1.16k
        return true;
365
136
  return D1 == D2 || 
D1 == CanonicalizeDC(D2)2
;
366
136
}
367
}
368
369
void ExternalASTMerger::MaybeRecordOrigin(const DeclContext *ToDC,
370
735
                                          DCOrigin Origin) {
371
735
  LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
372
735
  ASTImporter &Reverse = Importer.GetReverse();
373
735
  Source<const DeclContext *> FoundFromDC =
374
735
      LookupSameContext(Origin.AST->getTranslationUnitDecl(), ToDC, Reverse);
375
735
  const bool DoRecord = !FoundFromDC || 
!IsSameDC(FoundFromDC.get(), Origin.DC)448
;
376
735
  if (DoRecord)
377
287
    RecordOriginImpl(ToDC, Origin, Importer);
378
735
  if (LoggingEnabled())
379
0
    logs() << "(ExternalASTMerger*)" << (void*)this
380
0
             << (DoRecord ? " decided " : " decided NOT")
381
0
             << " to record origin (DeclContext*)" << (void*)Origin.DC
382
0
             << ", (ASTContext*)" << (void*)&Origin.AST
383
0
             << "\n";
384
735
}
385
386
void ExternalASTMerger::ForceRecordOrigin(const DeclContext *ToDC,
387
4
                                          DCOrigin Origin) {
388
4
  RecordOriginImpl(ToDC, Origin, ImporterForOrigin(*Origin.AST));
389
4
}
390
391
void ExternalASTMerger::RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
392
291
                                         ASTImporter &Importer) {
393
291
  Origins[ToDC] = Origin;
394
291
  Importer.ASTImporter::MapImported(cast<Decl>(Origin.DC), const_cast<Decl*>(cast<Decl>(ToDC)));
395
291
}
396
397
ExternalASTMerger::ExternalASTMerger(const ImporterTarget &Target,
398
121
                                     llvm::ArrayRef<ImporterSource> Sources) : LogStream(&llvm::nulls()), Target(Target) {
399
121
  SharedState = std::make_shared<ASTImporterSharedState>(
400
121
      *Target.AST.getTranslationUnitDecl());
401
121
  AddSources(Sources);
402
121
}
403
404
0
Decl *ExternalASTMerger::FindOriginalDecl(Decl *D) {
405
0
  assert(&D->getASTContext() == &Target.AST);
406
0
  for (const auto &I : Importers)
407
0
    if (auto Result = I->GetOriginalDecl(D))
408
0
      return Result;
409
0
  return nullptr;
410
0
}
411
412
121
void ExternalASTMerger::AddSources(llvm::ArrayRef<ImporterSource> Sources) {
413
132
  for (const ImporterSource &S : Sources) {
414
132
    assert(&S.getASTContext() != &Target.AST);
415
    // Check that the associated merger actually imports into the source AST.
416
132
    assert(!S.getMerger() || &S.getMerger()->Target.AST == &S.getASTContext());
417
132
    Importers.push_back(std::make_unique<LazyASTImporter>(
418
132
        *this, Target.AST, Target.FM, S, SharedState));
419
132
  }
420
121
}
421
422
55
void ExternalASTMerger::RemoveSources(llvm::ArrayRef<ImporterSource> Sources) {
423
55
  if (LoggingEnabled())
424
0
    for (const ImporterSource &S : Sources)
425
0
      logs() << "(ExternalASTMerger*)" << (void *)this
426
0
             << " removing source (ASTContext*)" << (void *)&S.getASTContext()
427
0
             << "\n";
428
55
  Importers.erase(
429
55
      std::remove_if(Importers.begin(), Importers.end(),
430
66
                     [&Sources](std::unique_ptr<ASTImporter> &Importer) -> bool {
431
80
                       for (const ImporterSource &S : Sources) {
432
80
                         if (&Importer->getFromContext() == &S.getASTContext())
433
66
                           return true;
434
80
                       }
435
0
                       return false;
436
66
                     }),
437
55
      Importers.end());
438
135
  for (OriginMap::iterator OI = Origins.begin(), OE = Origins.end(); OI != OE; ) {
439
80
    std::pair<const DeclContext *, DCOrigin> Origin = *OI;
440
80
    bool Erase = false;
441
88
    for (const ImporterSource &S : Sources) {
442
88
      if (&S.getASTContext() == Origin.second.AST) {
443
80
        Erase = true;
444
80
        break;
445
80
      }
446
88
    }
447
80
    if (Erase)
448
80
      OI = Origins.erase(OI);
449
0
    else
450
0
      ++OI;
451
80
  }
452
55
}
453
454
template <typename DeclTy>
455
14
static bool importSpecializations(DeclTy *D, ASTImporter *Importer) {
456
8
  for (auto *Spec : D->specializations()) {
457
8
    auto ImportedSpecOrError = Importer->Import(Spec);
458
8
    if (!ImportedSpecOrError) {
459
0
      llvm::consumeError(ImportedSpecOrError.takeError());
460
0
      return true;
461
0
    }
462
8
  }
463
14
  return false;
464
14
}
ExternalASTMerger.cpp:bool importSpecializations<clang::FunctionTemplateDecl>(clang::FunctionTemplateDecl*, clang::ASTImporter*)
Line
Count
Source
455
4
static bool importSpecializations(DeclTy *D, ASTImporter *Importer) {
456
4
  for (auto *Spec : D->specializations()) {
457
4
    auto ImportedSpecOrError = Importer->Import(Spec);
458
4
    if (!ImportedSpecOrError) {
459
0
      llvm::consumeError(ImportedSpecOrError.takeError());
460
0
      return true;
461
0
    }
462
4
  }
463
4
  return false;
464
4
}
ExternalASTMerger.cpp:bool importSpecializations<clang::ClassTemplateDecl>(clang::ClassTemplateDecl*, clang::ASTImporter*)
Line
Count
Source
455
10
static bool importSpecializations(DeclTy *D, ASTImporter *Importer) {
456
4
  for (auto *Spec : D->specializations()) {
457
4
    auto ImportedSpecOrError = Importer->Import(Spec);
458
4
    if (!ImportedSpecOrError) {
459
0
      llvm::consumeError(ImportedSpecOrError.takeError());
460
0
      return true;
461
0
    }
462
4
  }
463
10
  return false;
464
10
}
Unexecuted instantiation: ExternalASTMerger.cpp:bool importSpecializations<clang::VarTemplateDecl>(clang::VarTemplateDecl*, clang::ASTImporter*)
465
466
/// Imports specializations from template declarations that can be specialized.
467
880
static bool importSpecializationsIfNeeded(Decl *D, ASTImporter *Importer) {
468
880
  if (!isa<TemplateDecl>(D))
469
858
    return false;
470
22
  if (auto *FunctionTD = dyn_cast<FunctionTemplateDecl>(D))
471
4
    return importSpecializations(FunctionTD, Importer);
472
18
  else if (auto *ClassTD = dyn_cast<ClassTemplateDecl>(D))
473
10
    return importSpecializations(ClassTD, Importer);
474
8
  else if (auto *VarTD = dyn_cast<VarTemplateDecl>(D))
475
0
    return importSpecializations(VarTD, Importer);
476
8
  return false;
477
8
}
478
479
bool ExternalASTMerger::FindExternalVisibleDeclsByName(const DeclContext *DC,
480
1.58k
                                                       DeclarationName Name) {
481
1.58k
  llvm::SmallVector<NamedDecl *, 1> Decls;
482
1.58k
  llvm::SmallVector<Candidate, 4> Candidates;
483
484
955
  auto FilterFoundDecl = [&Candidates](const Candidate &C) {
485
955
   if (!HasDeclOfSameType(Candidates, C))
486
880
     Candidates.push_back(C);
487
955
  };
488
489
1.58k
  ForEachMatchingDC(DC,
490
1.58k
                    [&](ASTImporter &Forward, ASTImporter &Reverse,
491
1.70k
                        Source<const DeclContext *> SourceDC) -> bool {
492
1.70k
                      auto FromNameOrErr = Reverse.Import(Name);
493
1.70k
                      if (!FromNameOrErr) {
494
0
                        llvm::consumeError(FromNameOrErr.takeError());
495
0
                        return false;
496
0
                      }
497
1.70k
                      DeclContextLookupResult Result =
498
1.70k
                          SourceDC.get()->lookup(*FromNameOrErr);
499
955
                      for (NamedDecl *FromD : Result) {
500
955
                        FilterFoundDecl(std::make_pair(FromD, &Forward));
501
955
                      }
502
1.70k
                      return false;
503
1.70k
                    });
504
505
1.58k
  if (Candidates.empty())
506
708
    return false;
507
508
876
  Decls.reserve(Candidates.size());
509
880
  for (const Candidate &C : Candidates) {
510
880
    Decl *LookupRes = C.first.get();
511
880
    ASTImporter *Importer = C.second;
512
880
    auto NDOrErr = Importer->Import(LookupRes);
513
880
    NamedDecl *ND = cast<NamedDecl>(llvm::cantFail(std::move(NDOrErr)));
514
880
    assert(ND);
515
    // If we don't import specialization, they are not available via lookup
516
    // because the lookup result is imported TemplateDecl and it does not
517
    // reference its specializations until they are imported explicitly.
518
880
    bool IsSpecImportFailed =
519
880
        importSpecializationsIfNeeded(LookupRes, Importer);
520
880
    assert(!IsSpecImportFailed);
521
880
    (void)IsSpecImportFailed;
522
880
    Decls.push_back(ND);
523
880
  }
524
876
  SetExternalVisibleDeclsForName(DC, Name, Decls);
525
876
  return true;
526
876
}
527
528
void ExternalASTMerger::FindExternalLexicalDecls(
529
    const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
530
274
    SmallVectorImpl<Decl *> &Result) {
531
274
  ForEachMatchingDC(DC, [&](ASTImporter &Forward, ASTImporter &Reverse,
532
284
                            Source<const DeclContext *> SourceDC) -> bool {
533
940
    for (const Decl *SourceDecl : SourceDC.get()->decls()) {
534
940
      if (IsKindWeWant(SourceDecl->getKind())) {
535
895
        auto ImportedDeclOrErr = Forward.Import(SourceDecl);
536
895
        if (ImportedDeclOrErr)
537
895
          assert(!(*ImportedDeclOrErr) ||
538
895
                 IsSameDC((*ImportedDeclOrErr)->getDeclContext(), DC));
539
895
        else
540
0
          llvm::consumeError(ImportedDeclOrErr.takeError());
541
895
      }
542
940
    }
543
284
    return false;
544
284
  });
545
274
}
546