I think it would be equivalent and simpler to check only OldTypedefDecl->getDeclContext()->isDependentContext(). If we can resolve the name of the typedef to a dependently-scoped typedef, it must be a member of the current instantiation, and that's what we really care about here. This would also avoid any concerns about whether we're looking at the right declaration of the enclosing class (in the case where multiple definitions from different modules got merged), whether we need to skip over transparent contexts, and so on.
The check to see if we should clone a typedef or not should be moved into this function.
Hmm, we're only applying the logic in the case where the top-level type of a parameter is a typedef type. That doesn't seem right; this won't do the right thing for Constructor(Typedef*) and similar. Also, we don't want to skip the parameter transform entirely if we find a such a typedef; instead, we should only skip cloning the typedef itself.
@rsmith I have moved the check into TransformTypedefType. We do not add the typedef to the MaterializedTypedefs list if it's context is dependent because later we set the deduction guide as the DC for all typedefs in the list:
for (auto *TD : MaterializedTypedefs) TD->setDeclContext(Guide);
Also, we have to push the original TypedefDecl to the TypeLocBuilder, otherwise an assertion would fire:
llvm-project/clang/lib/Sema/TypeLocBuilder.h:103: clang::TypeSourceInfo* clang::TypeLocBuilder::getTypeSourceInfo(clang::ASTContext&, clang::QualType): Assertion `T == LastTy && "type doesn't match last type pushed!"' failed.