Improve resugaring of function template argument types

Clang commit 3ced23976aa8a86a17017c87821c873b4ca80bc2 removed sugar from
ImplicitCastExprs in certain situations.

The sugar still seems to be available from the DeclRefExpr used for
function arguments, so use a RAV to find the first ImplicitCastExpr or
DeclRefExpr that provides a sugared type.

This loses one diagnostic in badinc.cc. I haven't been able to form a
story around why it disappears, but it doesn't look critically useful,
so I removed it.
This commit is contained in:
Kim Grasman 2020-01-06 21:24:15 +01:00 committed by Kim Gräsman
parent 76673d5726
commit a40a28740c
2 changed files with 30 additions and 13 deletions

View File

@ -752,17 +752,38 @@ GetTplTypeResugarMapForFunctionExplicitTplArgs(
// possible. This was originally designed for use with function argument
// expressions, and so might not work in a more general context.
static const Type* GetSugaredTypeOf(const Expr* expr) {
// First, try to find an ImplicitCastExpr under the expr, and let that provide
// the type. This has a higher probability of yielding a sugared type.
for (const Stmt* child_expr : expr->children()) {
if (const auto* cast_expr = dyn_cast<ImplicitCastExpr>(child_expr)) {
return cast_expr->getType().getTypePtr();
// Search the expression subtree for better sugar; stop as soon as a type
// different from expr's type is found.
struct Visitor : public RecursiveASTVisitor<Visitor> {
Visitor(QualType origtype) : sugared(origtype.getLocalUnqualifiedType()) {
}
}
// If we didn't find a type via ImplicitCastExpr, just return the type of the
// expr itself.
return GetTypeOf(expr);
bool VisitDeclRefExpr(DeclRefExpr* e) {
return !CollectSugar(e);
}
bool VisitImplicitCastExpr(ImplicitCastExpr* e) {
return !CollectSugar(e->getSubExpr());
}
bool CollectSugar(const Expr* e) {
QualType exprtype = e->getType().getLocalUnqualifiedType();
if (!exprtype.isNull() && exprtype != sugared) {
sugared = exprtype;
return true;
}
return false;
}
QualType sugared;
};
// Default to the expr's type.
Visitor v(expr->getType());
v.TraverseStmt(const_cast<Expr*>(expr));
return v.sugared.getTypePtr();
}
map<const Type*, const Type*> GetTplTypeResugarMapForFunction(

View File

@ -1861,10 +1861,6 @@ int main() {
I1_TemplateFunction<I1_Class*>(i1_class_ptr);
// Try again, but with a typedef
Cc_typedef cc_typedef;
// TODO(csilvers): figure out the template arg here is really a
// typedef (tricky because we need to call the I1_Class ctor),
// and don't add it to tpl-types-of-interest.
// IWYU: I1_Class is...*badinc-i1.h
// IWYU: I1_TemplateFunction is...*badinc-i1.h
I1_TemplateFunction(cc_typedef);
// IWYU: I1_TemplateFunction is...*badinc-i1.h