[clang] [clang][ASTImporter] New fix for default template parameter values. (PR #101836)
Balázs Kéri via cfe-commits
cfe-commits at lists.llvm.org
Wed Aug 21 01:22:04 PDT 2024
================
@@ -5968,11 +5962,21 @@ ASTNodeImporter::VisitTemplateTypeParmDecl(TemplateTypeParmDecl *D) {
}
if (D->hasDefaultArgument()) {
+ // Default argument can be "inherited" when it has a reference to the
+ // previous declaration (of the default argument) which is stored only once.
+ // Here we import the default argument in any case, and the inherited state
+ // is updated later after the parent template was created. If the
+ // inherited-from object would be imported here it causes more difficulties
+ // (parent template may not be created yet and import loops can occur).
Expected<TemplateArgumentLoc> ToDefaultArgOrErr =
import(D->getDefaultArgument());
if (!ToDefaultArgOrErr)
return ToDefaultArgOrErr.takeError();
- ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr);
+ // The just called import process can trigger import of the parent template
+ // which can update the default argument value to "inherited". This should
+ // not be changed.
+ if (!ToD->hasDefaultArgument())
+ ToD->setDefaultArgument(ToD->getASTContext(), *ToDefaultArgOrErr);
----------------
balazske wrote:
I try to explain the source location problem with this code:
```
template <class P = Def> class X;
template <class P> class X {};
```
At the second `X` (definition) `P` has inherited default argument.
The import may reverse the order (this reversal looks hard to fix):
```
template <class P = Def> class X {};
template <class P> class X;
```
The default argument is now at the definition of `X`. I think this is the good behavior at import and this is how it currently works. The source location of `= Def` becomes inconsistent with the line where it originally was, and this can affect the "end" location of `<class P = Def>` too.
https://github.com/llvm/llvm-project/pull/101836
More information about the cfe-commits
mailing list