clang  10.0.0svn
ExternalASTMerger.cpp
Go to the documentation of this file.
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"
20 
21 using namespace clang;
22 
23 namespace {
24 
25 template <typename T> struct Source {
26  T t;
27  Source(T t) : t(t) {}
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); }
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 const DeclContext *CanonicalizeDC(const DeclContext *DC) {
39  if (isa<LinkageSpecDecl>(DC))
40  return DC->getRedeclContext();
41  return DC;
42 }
43 
44 Source<const DeclContext *>
45 LookupSameContext(Source<TranslationUnitDecl *> SourceTU, const DeclContext *DC,
46  ASTImporter &ReverseImporter) {
47  DC = CanonicalizeDC(DC);
48  if (DC->isTranslationUnit()) {
49  return SourceTU;
50  }
51  Source<const DeclContext *> SourceParentDC =
52  LookupSameContext(SourceTU, DC->getParent(), ReverseImporter);
53  if (!SourceParentDC) {
54  // If we couldn't find the parent DC in this TranslationUnit, give up.
55  return nullptr;
56  }
57  auto *ND = cast<NamedDecl>(DC);
58  DeclarationName Name = ND->getDeclName();
59  auto SourceNameOrErr = ReverseImporter.Import(Name);
60  if (!SourceNameOrErr) {
61  llvm::consumeError(SourceNameOrErr.takeError());
62  return nullptr;
63  }
64  Source<DeclarationName> SourceName = *SourceNameOrErr;
65  DeclContext::lookup_result SearchResult =
66  SourceParentDC.get()->lookup(SourceName.get());
67  size_t SearchResultSize = SearchResult.size();
68  if (SearchResultSize == 0 || SearchResultSize > 1) {
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  return nullptr;
79  } else {
80  NamedDecl *SearchResultDecl = SearchResult[0];
81  if (isa<DeclContext>(SearchResultDecl) &&
82  SearchResultDecl->getKind() == DC->getDeclKind())
83  return cast<DeclContext>(SearchResultDecl)->getPrimaryContext();
84  return nullptr; // This type of lookup is unsupported
85  }
86 }
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:
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  llvm::raw_ostream &logs() { return Parent.logs(); }
112 public:
113  LazyASTImporter(ExternalASTMerger &_Parent, ASTContext &ToContext,
114  FileManager &ToFileManager,
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  SourceMerger(S.getMerger()) {}
125 
126  llvm::Expected<Decl *> ImportImpl(Decl *FromD) override {
127  if (!TemporarySource || !SourceMerger)
128  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  Decl *Persistent = SourceMerger->FindOriginalDecl(FromD);
165  // FromD isn't from a persistent AST, so just do a normal import.
166  if (!Persistent)
167  return ASTImporter::ImportImpl(FromD);
168  // Now ask the current ExternalASTMerger to try import the persistent
169  // declaration into the target.
170  ASTContext &PersistentCtx = Persistent->getASTContext();
171  ASTImporter &OtherImporter = Parent.ImporterForOrigin(PersistentCtx);
172  // Check that we never end up in the current Importer again.
173  assert((&PersistentCtx != &getFromContext()) && (&OtherImporter != this) &&
174  "Delegated to same Importer?");
175  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  if (!DeclOrErr)
179  return DeclOrErr.takeError();
180  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  MapImported(FromD, D);
184  return D;
185  }
186 
187  /// Implements the ASTImporter interface for tracking back a declaration
188  /// to its original declaration it came from.
189  Decl *GetOriginalDecl(Decl *To) override {
190  auto It = ToOrigin.find(To);
191  if (It != ToOrigin.end())
192  return It->second;
193  return nullptr;
194  }
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  void Imported(Decl *From, Decl *To) override {
199  ToOrigin[To] = From;
200 
201  if (auto *ToDC = dyn_cast<DeclContext>(To)) {
202  const bool LoggingEnabled = Parent.LoggingEnabled();
203  if (LoggingEnabled)
204  logs() << "(ExternalASTMerger*)" << (void*)&Parent
205  << " imported (DeclContext*)" << (void*)ToDC
206  << ", (ASTContext*)" << (void*)&getToContext()
207  << " from (DeclContext*)" << (void*)llvm::cast<DeclContext>(From)
208  << ", (ASTContext*)" << (void*)&getFromContext()
209  << "\n";
210  Source<DeclContext *> FromDC(
211  cast<DeclContext>(From)->getPrimaryContext());
212  if (FromOrigins.count(FromDC) &&
213  Parent.HasImporterForOrigin(*FromOrigins.at(FromDC).AST)) {
214  if (LoggingEnabled)
215  logs() << "(ExternalASTMerger*)" << (void*)&Parent
216  << " forced origin (DeclContext*)"
217  << (void*)FromOrigins.at(FromDC).DC
218  << ", (ASTContext*)"
219  << (void*)FromOrigins.at(FromDC).AST
220  << "\n";
221  Parent.ForceRecordOrigin(ToDC, FromOrigins.at(FromDC));
222  } else {
223  if (LoggingEnabled)
224  logs() << "(ExternalASTMerger*)" << (void*)&Parent
225  << " maybe recording origin (DeclContext*)" << (void*)FromDC
226  << ", (ASTContext*)" << (void*)&getFromContext()
227  << "\n";
228  Parent.MaybeRecordOrigin(ToDC, {FromDC, &getFromContext()});
229  }
230  }
231  if (auto *ToTag = dyn_cast<TagDecl>(To)) {
232  ToTag->setHasExternalLexicalStorage();
233  ToTag->getPrimaryContext()->setMustBuildLookupTable();
234  assert(Parent.CanComplete(ToTag));
235  } else if (auto *ToNamespace = dyn_cast<NamespaceDecl>(To)) {
236  ToNamespace->setHasExternalVisibleStorage();
237  assert(Parent.CanComplete(ToNamespace));
238  } else if (auto *ToContainer = dyn_cast<ObjCContainerDecl>(To)) {
239  ToContainer->setHasExternalLexicalStorage();
240  ToContainer->getPrimaryContext()->setMustBuildLookupTable();
241  assert(Parent.CanComplete(ToContainer));
242  }
243  }
244  ASTImporter &GetReverse() { return Reverse; }
245 };
246 
247 bool HasDeclOfSameType(llvm::ArrayRef<Candidate> Decls, const Candidate &C) {
248  if (isa<FunctionDecl>(C.first.get()))
249  return false;
250  return llvm::any_of(Decls, [&](const Candidate &D) {
251  return C.first.get()->getKind() == D.first.get()->getKind();
252  });
253 }
254 
255 } // end namespace
256 
258  for (const std::unique_ptr<ASTImporter> &I : Importers)
259  if (&I->getFromContext() == &OriginContext)
260  return *I;
261  llvm_unreachable("We should have an importer for this origin!");
262 }
263 
264 namespace {
265 LazyASTImporter &LazyImporterForOrigin(ExternalASTMerger &Merger,
266  ASTContext &OriginContext) {
267  return static_cast<LazyASTImporter &>(
268  Merger.ImporterForOrigin(OriginContext));
269 }
270 }
271 
273  for (const std::unique_ptr<ASTImporter> &I : Importers)
274  if (&I->getFromContext() == &OriginContext)
275  return true;
276  return false;
277 }
278 
279 template <typename CallbackType>
280 void ExternalASTMerger::ForEachMatchingDC(const DeclContext *DC,
281  CallbackType Callback) {
282  if (Origins.count(DC)) {
283  ExternalASTMerger::DCOrigin Origin = Origins[DC];
284  LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
285  Callback(Importer, Importer.GetReverse(), Origin.DC);
286  } else {
287  bool DidCallback = false;
288  for (const std::unique_ptr<ASTImporter> &Importer : Importers) {
289  Source<TranslationUnitDecl *> SourceTU =
290  Importer->getFromContext().getTranslationUnitDecl();
291  ASTImporter &Reverse =
292  static_cast<LazyASTImporter *>(Importer.get())->GetReverse();
293  if (auto SourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
294  DidCallback = true;
295  if (Callback(*Importer, Reverse, SourceDC))
296  break;
297  }
298  }
299  if (!DidCallback && LoggingEnabled())
300  logs() << "(ExternalASTMerger*)" << (void*)this
301  << " asserting for (DeclContext*)" << (const void*)DC
302  << ", (ASTContext*)" << (void*)&Target.AST
303  << "\n";
304  assert(DidCallback && "Couldn't find a source context matching our DC");
305  }
306 }
307 
309  assert(Tag->hasExternalLexicalStorage());
310  ForEachMatchingDC(Tag, [&](ASTImporter &Forward, ASTImporter &Reverse,
311  Source<const DeclContext *> SourceDC) -> bool {
312  auto *SourceTag = const_cast<TagDecl *>(cast<TagDecl>(SourceDC.get()));
313  if (SourceTag->hasExternalLexicalStorage())
314  SourceTag->getASTContext().getExternalSource()->CompleteType(SourceTag);
315  if (!SourceTag->getDefinition())
316  return false;
317  Forward.MapImported(SourceTag, Tag);
318  if (llvm::Error Err = Forward.ImportDefinition(SourceTag))
319  llvm::consumeError(std::move(Err));
320  Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
321  return true;
322  });
323 }
324 
326  assert(Interface->hasExternalLexicalStorage());
327  ForEachMatchingDC(
328  Interface, [&](ASTImporter &Forward, ASTImporter &Reverse,
329  Source<const DeclContext *> SourceDC) -> bool {
330  auto *SourceInterface = const_cast<ObjCInterfaceDecl *>(
331  cast<ObjCInterfaceDecl>(SourceDC.get()));
332  if (SourceInterface->hasExternalLexicalStorage())
333  SourceInterface->getASTContext().getExternalSource()->CompleteType(
334  SourceInterface);
335  if (!SourceInterface->getDefinition())
336  return false;
337  Forward.MapImported(SourceInterface, Interface);
338  if (llvm::Error Err = Forward.ImportDefinition(SourceInterface))
339  llvm::consumeError(std::move(Err));
340  return true;
341  });
342 }
343 
345  assert(Interface->hasExternalLexicalStorage() ||
346  Interface->hasExternalVisibleStorage());
347  bool FoundMatchingDC = false;
348  ForEachMatchingDC(Interface,
349  [&](ASTImporter &Forward, ASTImporter &Reverse,
350  Source<const DeclContext *> SourceDC) -> bool {
351  FoundMatchingDC = true;
352  return true;
353  });
354  return FoundMatchingDC;
355 }
356 
357 namespace {
358 bool IsSameDC(const DeclContext *D1, const DeclContext *D2) {
359  if (isa<ObjCContainerDecl>(D1) && isa<ObjCContainerDecl>(D2))
360  return true; // There are many cases where Objective-C is ambiguous.
361  if (auto *T1 = dyn_cast<TagDecl>(D1))
362  if (auto *T2 = dyn_cast<TagDecl>(D2))
363  if (T1->getFirstDecl() == T2->getFirstDecl())
364  return true;
365  return D1 == D2 || D1 == CanonicalizeDC(D2);
366 }
367 }
368 
370  DCOrigin Origin) {
371  LazyASTImporter &Importer = LazyImporterForOrigin(*this, *Origin.AST);
372  ASTImporter &Reverse = Importer.GetReverse();
373  Source<const DeclContext *> FoundFromDC =
374  LookupSameContext(Origin.AST->getTranslationUnitDecl(), ToDC, Reverse);
375  const bool DoRecord = !FoundFromDC || !IsSameDC(FoundFromDC.get(), Origin.DC);
376  if (DoRecord)
377  RecordOriginImpl(ToDC, Origin, Importer);
378  if (LoggingEnabled())
379  logs() << "(ExternalASTMerger*)" << (void*)this
380  << (DoRecord ? " decided " : " decided NOT")
381  << " to record origin (DeclContext*)" << (void*)Origin.DC
382  << ", (ASTContext*)" << (void*)&Origin.AST
383  << "\n";
384 }
385 
387  DCOrigin Origin) {
388  RecordOriginImpl(ToDC, Origin, ImporterForOrigin(*Origin.AST));
389 }
390 
391 void ExternalASTMerger::RecordOriginImpl(const DeclContext *ToDC, DCOrigin Origin,
392  ASTImporter &Importer) {
393  Origins[ToDC] = Origin;
394  Importer.ASTImporter::MapImported(cast<Decl>(Origin.DC), const_cast<Decl*>(cast<Decl>(ToDC)));
395 }
396 
398  llvm::ArrayRef<ImporterSource> Sources) : LogStream(&llvm::nulls()), Target(Target) {
399  SharedState = std::make_shared<ASTImporterSharedState>(
400  *Target.AST.getTranslationUnitDecl());
401  AddSources(Sources);
402 }
403 
405  assert(&D->getASTContext() == &Target.AST);
406  for (const auto &I : Importers)
407  if (auto Result = I->GetOriginalDecl(D))
408  return Result;
409  return nullptr;
410 }
411 
413  for (const ImporterSource &S : Sources) {
414  assert(&S.getASTContext() != &Target.AST);
415  // Check that the associated merger actually imports into the source AST.
416  assert(!S.getMerger() || &S.getMerger()->Target.AST == &S.getASTContext());
417  Importers.push_back(std::make_unique<LazyASTImporter>(
418  *this, Target.AST, Target.FM, S, SharedState));
419  }
420 }
421 
423  if (LoggingEnabled())
424  for (const ImporterSource &S : Sources)
425  logs() << "(ExternalASTMerger*)" << (void *)this
426  << " removing source (ASTContext*)" << (void *)&S.getASTContext()
427  << "\n";
428  Importers.erase(
429  std::remove_if(Importers.begin(), Importers.end(),
430  [&Sources](std::unique_ptr<ASTImporter> &Importer) -> bool {
431  for (const ImporterSource &S : Sources) {
432  if (&Importer->getFromContext() == &S.getASTContext())
433  return true;
434  }
435  return false;
436  }),
437  Importers.end());
438  for (OriginMap::iterator OI = Origins.begin(), OE = Origins.end(); OI != OE; ) {
439  std::pair<const DeclContext *, DCOrigin> Origin = *OI;
440  bool Erase = false;
441  for (const ImporterSource &S : Sources) {
442  if (&S.getASTContext() == Origin.second.AST) {
443  Erase = true;
444  break;
445  }
446  }
447  if (Erase)
448  OI = Origins.erase(OI);
449  else
450  ++OI;
451  }
452 }
453 
454 template <typename DeclTy>
455 static bool importSpecializations(DeclTy *D, ASTImporter *Importer) {
456  for (auto *Spec : D->specializations()) {
457  auto ImportedSpecOrError = Importer->Import(Spec);
458  if (!ImportedSpecOrError) {
459  llvm::consumeError(ImportedSpecOrError.takeError());
460  return true;
461  }
462  }
463  return false;
464 }
465 
466 /// Imports specializations from template declarations that can be specialized.
467 static bool importSpecializationsIfNeeded(Decl *D, ASTImporter *Importer) {
468  if (!isa<TemplateDecl>(D))
469  return false;
470  if (auto *FunctionTD = dyn_cast<FunctionTemplateDecl>(D))
471  return importSpecializations(FunctionTD, Importer);
472  else if (auto *ClassTD = dyn_cast<ClassTemplateDecl>(D))
473  return importSpecializations(ClassTD, Importer);
474  else if (auto *VarTD = dyn_cast<VarTemplateDecl>(D))
475  return importSpecializations(VarTD, Importer);
476  return false;
477 }
478 
480  DeclarationName Name) {
483 
484  auto FilterFoundDecl = [&Candidates](const Candidate &C) {
485  if (!HasDeclOfSameType(Candidates, C))
486  Candidates.push_back(C);
487  };
488 
489  ForEachMatchingDC(DC,
490  [&](ASTImporter &Forward, ASTImporter &Reverse,
491  Source<const DeclContext *> SourceDC) -> bool {
492  auto FromNameOrErr = Reverse.Import(Name);
493  if (!FromNameOrErr) {
494  llvm::consumeError(FromNameOrErr.takeError());
495  return false;
496  }
498  SourceDC.get()->lookup(*FromNameOrErr);
499  for (NamedDecl *FromD : Result) {
500  FilterFoundDecl(std::make_pair(FromD, &Forward));
501  }
502  return false;
503  });
504 
505  if (Candidates.empty())
506  return false;
507 
508  Decls.reserve(Candidates.size());
509  for (const Candidate &C : Candidates) {
510  Decl *LookupRes = C.first.get();
511  ASTImporter *Importer = C.second;
512  auto NDOrErr = Importer->Import(LookupRes);
513  assert(NDOrErr);
514  (void)static_cast<bool>(NDOrErr);
515  NamedDecl *ND = cast_or_null<NamedDecl>(*NDOrErr);
516  assert(ND);
517  // If we don't import specialization, they are not available via lookup
518  // because the lookup result is imported TemplateDecl and it does not
519  // reference its specializations until they are imported explicitly.
520  bool IsSpecImportFailed =
521  importSpecializationsIfNeeded(LookupRes, Importer);
522  assert(!IsSpecImportFailed);
523  (void)IsSpecImportFailed;
524  Decls.push_back(ND);
525  }
526  SetExternalVisibleDeclsForName(DC, Name, Decls);
527  return true;
528 }
529 
531  const DeclContext *DC, llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
533  ForEachMatchingDC(DC, [&](ASTImporter &Forward, ASTImporter &Reverse,
534  Source<const DeclContext *> SourceDC) -> bool {
535  for (const Decl *SourceDecl : SourceDC.get()->decls()) {
536  if (IsKindWeWant(SourceDecl->getKind())) {
537  auto ImportedDeclOrErr = Forward.Import(SourceDecl);
538  if (ImportedDeclOrErr)
539  assert(!(*ImportedDeclOrErr) ||
540  IsSameDC((*ImportedDeclOrErr)->getDeclContext(), DC));
541  else
542  llvm::consumeError(ImportedDeclOrErr.takeError());
543  }
544  }
545  return false;
546  });
547 }
548 
virtual Expected< Decl * > ImportImpl(Decl *From)
Can be overwritten by subclasses to implement their own import logic.
Defines the clang::ASTContext interface.
void MaybeRecordOrigin(const DeclContext *ToDC, DCOrigin Origin)
Records an origin in Origins only if name lookup would find something different or nothing at all...
unsigned llvm::PointerUnion< const Decl *, const Expr * > DeclTy
Definition: Descriptor.h:26
void setCompleteDefinition(bool V=true)
True if this decl has its body fully specified.
Definition: Decl.h:3241
Implements support for file system lookup, file system caching, and directory search management...
Definition: FileManager.h:171
Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be placed into a PointerUnion...
Definition: Dominators.h:30
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:88
Defines the C++ template declaration subclasses.
bool HasImporterForOrigin(ASTContext &OriginContext)
Returns true if Importers contains an ASTImporter whose source is OriginContext.
bool hasExternalVisibleStorage() const
Whether this DeclContext has external storage containing additional declarations that are visible in ...
Definition: DeclBase.h:2355
static DeclContextLookupResult SetExternalVisibleDeclsForName(const DeclContext *DC, DeclarationName Name, ArrayRef< NamedDecl *> Decls)
Definition: DeclBase.cpp:1338
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
The results of name lookup within a DeclContext.
Definition: DeclBase.h:1195
void AddSources(llvm::ArrayRef< ImporterSource > Sources)
Add a set of ASTContexts as possible origins.
LLVM_NODISCARD llvm::Error ImportDefinition(Decl *From)
Import the definition of the given declaration, including all of the declarations it contains...
The target for an ExternalASTMerger.
Represents an ObjC class declaration.
Definition: DeclObjC.h:1171
bool LoggingEnabled()
True if the log stream is not llvm::nulls();.
NodeId Parent
Definition: ASTDiff.cpp:191
Decl * MapImported(Decl *From, Decl *To)
Store and assign the imported declaration to its counterpart.
A single origin for a DeclContext.
bool FindExternalVisibleDeclsByName(const DeclContext *DC, DeclarationName Name) override
Implementation of the ExternalASTSource API.
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1779
The result type of a method or function.
Decl::Kind getDeclKind() const
Definition: DeclBase.h:1772
ASTContext & getASTContext() const
Definition: Sema.h:1295
ASTImporter & ImporterForOrigin(ASTContext &OriginContext)
Returns a reference to the ASTImporter from Importers whose origin is OriginContext.
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3133
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:377
llvm::Expected< QualType > Import(QualType FromT)
Import the given type from the "from" context into the "to" context.
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
Definition: DeclBase.h:2343
std::map< const DeclContext *, DCOrigin > OriginMap
Dataflow Directional Tag Classes.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1271
bool CanComplete(DeclContext *DC)
Returns true if DC can be found in any source AST context.
static bool importSpecializations(DeclTy *D, ASTImporter *Importer)
The name of a declaration.
void RemoveSources(llvm::ArrayRef< ImporterSource > Sources)
Remove a set of ASTContexts as possible origins.
llvm::raw_ostream & logs()
Log something if there is a logging callback installed.
Kind getKind() const
Definition: DeclBase.h:432
A source for an ExternalASTMerger.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
Definition: ASTContext.h:1085
Imports selected nodes from one AST context into another context, merging AST nodes where appropriate...
Definition: ASTImporter.h:84
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
Definition: DeclBase.cpp:1744
void FindExternalLexicalDecls(const DeclContext *DC, llvm::function_ref< bool(Decl::Kind)> IsKindWeWant, SmallVectorImpl< Decl *> &Result) override
Implementation of the ExternalASTSource API.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1008
void CompleteType(TagDecl *Tag) override
Implementation of the ExternalASTSource API.
ASTContext & getFromContext() const
Retrieve the context that AST nodes are being imported from.
Definition: ASTImporter.h:536
void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin)
Regardless of any checks, override the Origin for a DeclContext.
static bool importSpecializationsIfNeeded(Decl *D, ASTImporter *Importer)
Imports specializations from template declarations that can be specialized.
Kind
Lists the kind of concrete classes of Decl.
Definition: DeclBase.h:91
DeclContext * getPrimaryContext()
getPrimaryContext - There may be many different declarations of the same entity (including forward de...
Definition: DeclBase.cpp:1169
#define true
Definition: stdbool.h:16
Decl * FindOriginalDecl(Decl *D)
Asks all connected ASTImporters if any of them imported the given declaration.
This represents a decl that may have a name.
Definition: Decl.h:248
bool isTranslationUnit() const
Definition: DeclBase.h:1854
ExternalASTSource implementation that merges information from several ASTContexts.
ExternalASTMerger(const ImporterTarget &Target, llvm::ArrayRef< ImporterSource > Sources)