Changeset View
Standalone View
clang/lib/AST/ASTImporter.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 6,060 Lines • ▼ Show 20 Lines | ASTNodeImporter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { | |||||||||||
if (!ParamsOrErr) | if (!ParamsOrErr) | |||||||||||
return ParamsOrErr.takeError(); | return ParamsOrErr.takeError(); | |||||||||||
TemplateParameterList *Params = *ParamsOrErr; | TemplateParameterList *Params = *ParamsOrErr; | |||||||||||
FunctionDecl *TemplatedFD; | FunctionDecl *TemplatedFD; | |||||||||||
if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl())) | if (Error Err = importInto(TemplatedFD, D->getTemplatedDecl())) | |||||||||||
return std::move(Err); | return std::move(Err); | |||||||||||
// Template parameters of the ClassTemplateDecl and FunctionTemplateDecl are | // At creation of the template the template parameters are "adopted" | |||||||||||
// shared, if the FunctionTemplateDecl is a deduction guide for the class. | // (DeclContext is changed). After this possible change the lookup table | |||||||||||
// At import the ClassTemplateDecl object is always created first (FIXME: is | // must be updated. | |||||||||||
// this really true?) because the dependency, then the FunctionTemplateDecl. | // At deduction guides the DeclContext of the template parameters may be | |||||||||||
// The DeclContext of the template parameters is changed when the | // different from what we would expect, it may be the class template, or a | |||||||||||
// FunctionTemplateDecl is created, but was set already when the class | // probably different CXXDeductionGuideDecl. This may come from the fact that | |||||||||||
// template was created. So here it is not the TU (default value) any more. | // the template parameter objects may be shared between deduction guides or | |||||||||||
// FIXME: The DeclContext of the parameters is now set finally to the | // the class template, and at creation of multiple FunctionTemplateDecl | |||||||||||
// CXXDeductionGuideDecl object that was imported later. This may not be the | // objects (for deduction guides) the same parameters are re-used. The | |||||||||||
// same that is in the original AST, specially if there are multiple deduction | // "adoption" happens multiple times with different parent, even recursively | |||||||||||
// guides. | // for TemplateTemplateParmDecl. The same happens at import when the | |||||||||||
DeclContext *OldParamDC = nullptr; | // FunctionTemplateDecl objects are created, but in different order. In this | |||||||||||
if (Params->size() > 0) | // way DeclContext of these template parameters may change relative to the | |||||||||||
martong: ? | ||||||||||||
balazskeAuthorUnsubmitted Probably better: balazske: Probably better:
In this way the DeclContext of these template parameters is not necessary the… | ||||||||||||
martongUnsubmitted Not Done ReplyInline Actionsokay, but necessary->necessarily martong: okay, but necessary->necessarily | ||||||||||||
OldParamDC = Params->getParam(0)->getDeclContext(); | // "from" context. Because these DeclContext values look already not stable | |||||||||||
// and unimportant this change looks acceptable. | ||||||||||||
// For these reasons the old DeclContext must be saved to change the lookup | ||||||||||||
// table later. | ||||||||||||
martongUnsubmitted Not Done ReplyInline Actions
I think this sentence does not provide any meaningful information and does not increase the understand-ability. Plus the word change is overloaded, first I though you meant the patch itself... martong: I think this sentence does not provide any meaningful information and does not increase the… | ||||||||||||
balazskeAuthorUnsubmitted It is still good to have an explanation of why the DeclContext is not exactly preserved at import. And the DeclContext is really not "stable", not easily predictable from the source code. balazske: It is still good to have an explanation of why the DeclContext is not exactly preserved at… | ||||||||||||
martongUnsubmitted Not Done ReplyInline ActionsOkay, then we could write "Consequently, the DeclContext of these Decls may change several times until the top-level import call is finished." martong: Okay, then we could write "Consequently, the DeclContext of these Decls may change several… | ||||||||||||
balazskeAuthorUnsubmitted The meaning of this is still different from what my original intent was: The DeclContext in the "To" context is different from the "From", even after the top-level import call. I wanted to emphasize here that this change of DeclContext after (top-level) import has no relevance, should cause no problems. balazske: The meaning of this is still different from what my original intent was: The DeclContext in the… | ||||||||||||
martongUnsubmitted Not Done ReplyInline ActionsSo, you say that is it possible that the DeclContext of the params are equal in the "from" context, but after the import we may end up having different DeclContexts for the imported params in the "to" context? martong: So, you say that is it possible that the DeclContext of the params are equal in the "from"… | ||||||||||||
balazskeAuthorUnsubmitted They can be (are in the current case) not all equal in the From context and can be different in the To context (related to the corresponding AST nodes in the From context). At least the code does not ensure that these will be the same. There was originally a FIXME at this place, I wanted to change it to this new comment. Because from semantic point of view it should not matter if the DeclContext of a template parameter is some implicit deduction guide or another one, probably both are correct (this is why I don't wanted to add assertion for exactly one case). balazske: They can be (are in the current case) not all equal in the **From** context and can be… | ||||||||||||
SmallVector<DeclContext *, 2> OldParamDC; | ||||||||||||
OldParamDC.reserve(Params->size()); | ||||||||||||
llvm::transform(*Params, std::back_inserter(OldParamDC), | ||||||||||||
[](NamedDecl *ND) { return ND->getDeclContext(); }); | ||||||||||||
FunctionTemplateDecl *ToFunc; | FunctionTemplateDecl *ToFunc; | |||||||||||
if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name, | if (GetImportedOrCreateDecl(ToFunc, D, Importer.getToContext(), DC, Loc, Name, | |||||||||||
Params, TemplatedFD)) | Params, TemplatedFD)) | |||||||||||
return ToFunc; | return ToFunc; | |||||||||||
TemplatedFD->setDescribedFunctionTemplate(ToFunc); | TemplatedFD->setDescribedFunctionTemplate(ToFunc); | |||||||||||
ToFunc->setAccess(D->getAccess()); | ToFunc->setAccess(D->getAccess()); | |||||||||||
ToFunc->setLexicalDeclContext(LexicalDC); | ToFunc->setLexicalDeclContext(LexicalDC); | |||||||||||
LexicalDC->addDeclInternal(ToFunc); | LexicalDC->addDeclInternal(ToFunc); | |||||||||||
updateLookupTableForTemplateParameters(*Params, OldParamDC); | ||||||||||||
ASTImporterLookupTable *LT = Importer.SharedState->getLookupTable(); | ||||||||||||
if (LT && !OldParamDC.empty()) { | ||||||||||||
for (unsigned int I = 0; I < OldParamDC.size(); ++I) | ||||||||||||
LT->updateForced(Params->getParam(I), OldParamDC[I]); | ||||||||||||
} | ||||||||||||
if (FoundByLookup) { | if (FoundByLookup) { | |||||||||||
auto *Recent = | auto *Recent = | |||||||||||
const_cast<FunctionTemplateDecl *>(FoundByLookup->getMostRecentDecl()); | const_cast<FunctionTemplateDecl *>(FoundByLookup->getMostRecentDecl()); | |||||||||||
if (!TemplatedFD->getPreviousDecl()) { | if (!TemplatedFD->getPreviousDecl()) { | |||||||||||
assert(FoundByLookup->getTemplatedDecl() && | assert(FoundByLookup->getTemplatedDecl() && | |||||||||||
"Found decl must have its templated decl set"); | "Found decl must have its templated decl set"); | |||||||||||
auto *PrevTemplated = | auto *PrevTemplated = | |||||||||||
▲ Show 20 Lines • Show All 3,641 Lines • Show Last 20 Lines |
?