================ @@ -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 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits