;
25template<
typenameT>
structSource {
27Source(
Tt) : t(t) {}
28 operator T() {
returnt; }
29 template<
typenameU = T>
U&get() {
returnt; }
30 template<
typenameU = T>
const U&get()
const{
returnt; }
31 template<
typenameU>
operatorSource<U>() {
returnSource<U>(t); }
34typedefstd::pair<Source<NamedDecl *>,
ASTImporter*> Candidate;
39 if(isa<LinkageSpecDecl>(DC))
44Source<const DeclContext *>
45LookupSameContext(Source<TranslationUnitDecl *> SourceTU,
const DeclContext*DC,
47DC = CanonicalizeDC(DC);
51Source<const DeclContext *> SourceParentDC =
52LookupSameContext(SourceTU, DC->
getParent(), ReverseImporter);
53 if(!SourceParentDC) {
57 auto*ND = cast<NamedDecl>(DC);
59 autoSourceNameOrErr = ReverseImporter.
Import(Name);
60 if(!SourceNameOrErr) {
61llvm::consumeError(SourceNameOrErr.takeError());
64Source<DeclarationName> SourceName = *SourceNameOrErr;
66SourceParentDC.get()->lookup(SourceName.get());
79 if(isa<DeclContext>(SearchResultDecl) &&
81 returncast<DeclContext>(SearchResultDecl)->getPrimaryContext();
105 boolTemporarySource;
108llvm::DenseMap<Decl *, Decl *> ToOrigin;
111llvm::raw_ostream &logs() {
return Parent.logs(); }
116std::shared_ptr<ASTImporterSharedState> SharedState)
117:
ASTImporter(ToContext, ToFileManager, S.getASTContext(),
121Reverse(S.getASTContext(), S.getFileManager(), ToContext, ToFileManager,
123FromOrigins(S.getOriginMap()), TemporarySource(S.isTemporary()),
124SourceMerger(S.getMerger()) {}
127 if(!TemporarySource || !SourceMerger)
173assert((&PersistentCtx != &
getFromContext()) && (&OtherImporter !=
this) &&
174 "Delegated to same Importer?");
175 autoDeclOrErr = OtherImporter.
Import(Persistent);
179 returnDeclOrErr.takeError();
180 Decl*
D= *DeclOrErr;
190 returnToOrigin.lookup(To);
198 if(
auto*ToDC = dyn_cast<DeclContext>(To)) {
199 const boolLoggingEnabled =
Parent.LoggingEnabled();
201logs() <<
"(ExternalASTMerger*)"<< (
void*)&Parent
202<<
" imported (DeclContext*)"<< (
void*)ToDC
204<<
" from (DeclContext*)"<< (
void*)llvm::cast<DeclContext>(From)
207Source<DeclContext *> FromDC(
208cast<DeclContext>(From)->getPrimaryContext());
209 if(FromOrigins.count(FromDC) &&
210 Parent.HasImporterForOrigin(*FromOrigins.at(FromDC).AST)) {
212logs() <<
"(ExternalASTMerger*)"<< (
void*)&Parent
213<<
" forced origin (DeclContext*)" 214<< (
void*)FromOrigins.at(FromDC).DC
216<< (
void*)FromOrigins.at(FromDC).AST
218 Parent.ForceRecordOrigin(ToDC, FromOrigins.at(FromDC));
221logs() <<
"(ExternalASTMerger*)"<< (
void*)&Parent
222<<
" maybe recording origin (DeclContext*)"<< (
void*)FromDC
228 if(
auto*ToTag = dyn_cast<TagDecl>(To)) {
229ToTag->setHasExternalLexicalStorage();
230ToTag->getPrimaryContext()->setMustBuildLookupTable();
231assert(
Parent.CanComplete(ToTag));
232}
else if(
auto*ToNamespace = dyn_cast<NamespaceDecl>(To)) {
233ToNamespace->setHasExternalVisibleStorage();
234assert(
Parent.CanComplete(ToNamespace));
235}
else if(
auto*ToContainer = dyn_cast<ObjCContainerDecl>(To)) {
236ToContainer->setHasExternalLexicalStorage();
237ToContainer->getPrimaryContext()->setMustBuildLookupTable();
238assert(
Parent.CanComplete(ToContainer));
245 if(isa<FunctionDecl>(
C.first.get()))
247 returnllvm::any_of(Decls, [&](
constCandidate &
D) {
255 for(
conststd::unique_ptr<ASTImporter> &I : Importers)
256 if(&I->getFromContext() == &OriginContext)
258llvm_unreachable(
"We should have an importer for this origin!");
264 return static_cast<LazyASTImporter &
>(
270 for(
conststd::unique_ptr<ASTImporter> &I : Importers)
271 if(&I->getFromContext() == &OriginContext)
276template<
typenameCallbackType>
277voidExternalASTMerger::ForEachMatchingDC(
const DeclContext*DC,
278CallbackType Callback) {
279 if(
autoIt = Origins.find(DC); It != Origins.end()) {
281LazyASTImporter &Importer = LazyImporterForOrigin(*
this, *Origin.
AST);
282Callback(Importer, Importer.GetReverse(), Origin.
DC);
284 boolDidCallback =
false;
285 for(
conststd::unique_ptr<ASTImporter> &Importer : Importers) {
286Source<TranslationUnitDecl *> SourceTU =
287Importer->getFromContext().getTranslationUnitDecl();
289 static_cast<LazyASTImporter *
>(Importer.get())->GetReverse();
290 if(
autoSourceDC = LookupSameContext(SourceTU, DC, Reverse)) {
292 if(Callback(*Importer, Reverse, SourceDC))
297 logs() <<
"(ExternalASTMerger*)"<< (
void*)
this 298<<
" asserting for (DeclContext*)"<< (
const void*)DC
299<<
", (ASTContext*)"<< (
void*)&
Target.AST
301assert(DidCallback &&
"Couldn't find a source context matching our DC");
306assert(Tag->hasExternalLexicalStorage());
308Source<const DeclContext *> SourceDC) ->
bool{
309 auto*SourceTag =
const_cast<TagDecl*
>(cast<TagDecl>(SourceDC.get()));
310 if(SourceTag->hasExternalLexicalStorage())
312 if(!SourceTag->getDefinition())
316llvm::consumeError(std::move(Err));
317Tag->setCompleteDefinition(SourceTag->isCompleteDefinition());
323assert(
Interface->hasExternalLexicalStorage());
326Source<const DeclContext *> SourceDC) ->
bool{
328cast<ObjCInterfaceDecl>(SourceDC.get()));
329 if(SourceInterface->hasExternalLexicalStorage())
332 if(!SourceInterface->getDefinition())
336llvm::consumeError(std::move(Err));
342assert(
Interface->hasExternalLexicalStorage() ||
343 Interface->hasExternalVisibleStorage());
344 boolFoundMatchingDC =
false;
347Source<const DeclContext *> SourceDC) ->
bool{
348FoundMatchingDC =
true;
351 returnFoundMatchingDC;
356 if(isa<ObjCContainerDecl>(D1) && isa<ObjCContainerDecl>(D2))
358 if(
auto*T1 = dyn_cast<TagDecl>(D1))
359 if(
auto*T2 = dyn_cast<TagDecl>(D2))
360 if(T1->getFirstDecl() == T2->getFirstDecl())
362 returnD1 == D2 || D1 == CanonicalizeDC(D2);
368LazyASTImporter &Importer = LazyImporterForOrigin(*
this, *Origin.
AST);
370Source<const DeclContext *> FoundFromDC =
372 const boolDoRecord = !FoundFromDC || !IsSameDC(FoundFromDC.get(), Origin.
DC);
374RecordOriginImpl(ToDC, Origin, Importer);
376 logs() <<
"(ExternalASTMerger*)"<< (
void*)
this 377<< (DoRecord ?
" decided ":
" decided NOT")
378<<
" to record origin (DeclContext*)"<< (
void*)Origin.
DC 379<<
", (ASTContext*)"<< (
void*)&Origin.
AST 388voidExternalASTMerger::RecordOriginImpl(
const DeclContext*ToDC, DCOrigin Origin,
390Origins[ToDC] = Origin;
391Importer.ASTImporter::MapImported(cast<Decl>(Origin.DC),
const_cast<Decl*
>(cast<Decl>(ToDC)));
396SharedState = std::make_shared<ASTImporterSharedState>(
397*
Target.AST.getTranslationUnitDecl());
403 for(
const auto&I : Importers)
404 if(
auto Result= I->GetOriginalDecl(
D))
413assert(!S.getMerger() || &S.getMerger()->Target.AST == &S.
getASTContext());
414Importers.push_back(std::make_unique<LazyASTImporter>(
422 logs() <<
"(ExternalASTMerger*)"<< (
void*)
this 423<<
" removing source (ASTContext*)"<< (
void*)&S.
getASTContext()
425llvm::erase_if(Importers,
426[&Sources](std::unique_ptr<ASTImporter> &Importer) ->
bool{
433 for(OriginMap::iterator OI = Origins.begin(), OE = Origins.end(); OI != OE; ) {
434std::pair<const DeclContext *, DCOrigin> Origin = *OI;
443OI = Origins.erase(OI);
449template<
typenameDeclTy>
451 for(
auto*Spec :
D->specializations()) {
452 autoImportedSpecOrError = Importer->
Import(Spec);
453 if(!ImportedSpecOrError) {
454llvm::consumeError(ImportedSpecOrError.takeError());
463 if(!isa<TemplateDecl>(
D))
465 if(
auto*FunctionTD = dyn_cast<FunctionTemplateDecl>(
D))
467 else if(
auto*ClassTD = dyn_cast<ClassTemplateDecl>(
D))
469 else if(
auto*VarTD = dyn_cast<VarTemplateDecl>(
D))
480 autoFilterFoundDecl = [&Candidates](
constCandidate &
C) {
481 if(!HasDeclOfSameType(Candidates,
C))
482Candidates.push_back(
C);
485ForEachMatchingDC(DC,
487Source<const DeclContext *> SourceDC) ->
bool{
488 autoFromNameOrErr = Reverse.
Import(Name);
489 if(!FromNameOrErr) {
490llvm::consumeError(FromNameOrErr.takeError());
494SourceDC.get()->lookup(*FromNameOrErr);
496FilterFoundDecl(std::make_pair(FromD, &Forward));
501 if(Candidates.empty())
504Decls.reserve(Candidates.size());
505 for(
constCandidate &
C: Candidates) {
506 Decl*LookupRes =
C.first.get();
508 autoNDOrErr = Importer->
Import(LookupRes);
509 NamedDecl*ND = cast<NamedDecl>(llvm::cantFail(std::move(NDOrErr)));
514 boolIsSpecImportFailed =
516assert(!IsSpecImportFailed);
517(void)IsSpecImportFailed;
528Source<const DeclContext *> SourceDC) ->
bool{
529 for(
const Decl*SourceDecl : SourceDC.get()->decls()) {
530if (IsKindWeWant(SourceDecl->getKind())) {
531auto ImportedDeclOrErr = Forward.Import(SourceDecl);
532if (ImportedDeclOrErr)
533assert(!(*ImportedDeclOrErr) ||
534IsSameDC((*ImportedDeclOrErr)->getDeclContext(), DC));
536llvm::consumeError(ImportedDeclOrErr.takeError());
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
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.
llvm::MachO::Target Target
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...
ASTContext & getFromContext() const
Retrieve the context that AST nodes are being imported from.
ASTContext & getToContext() const
Retrieve the context that AST nodes are being imported into.
Decl * MapImported(Decl *From, Decl *To)
Store and assign the imported declaration to its counterpart.
llvm::Error ImportDefinition(Decl *From)
Import the definition of the given declaration, including all of the declarations it contains.
virtual Decl * GetOriginalDecl(Decl *To)
Called by StructuralEquivalenceContext.
virtual void Imported(Decl *From, Decl *To)
Subclasses can override this function to observe all of the From -> To declaration mappings as they a...
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.
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.
void AddSources(llvm::ArrayRef< ImporterSource > Sources)
Add a set of ASTContexts as possible origins.
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.
void RemoveSources(llvm::ArrayRef< ImporterSource > Sources)
Remove a set of ASTContexts as possible origins.
std::map< const DeclContext *, DCOrigin > OriginMap
void ForceRecordOrigin(const DeclContext *ToDC, DCOrigin Origin)
Regardless of any checks, override the Origin for a DeclContext.
ExternalASTMerger(const ImporterTarget &Target, llvm::ArrayRef< ImporterSource > Sources)
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();.
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.
Implements support for file system lookup, file system caching, and directory search management.
This represents a decl that may have a name.
Represents an ObjC class declaration.
ASTContext & getASTContext() const
Represents the declaration of a struct/union/class/enum.
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ 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.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4