diff options
author | Kim Grasman <kim.grasman@gmail.com> | 2017-01-01 23:23:13 +0100 |
---|---|---|
committer | Kim Gräsman <kim.grasman@gmail.com> | 2017-02-21 10:43:48 +0100 |
commit | 3a921410f4ad35030e1aa7ce2101fad947a7fa58 (patch) | |
tree | 8395f4e734a9ad95127c107322e3ebc5c89c7c76 | |
parent | 8065e52a319e1666e77a9616033afd43a2d0e378 (diff) |
Pick up more sugar for function arguments
Type sugar (typedefs, more specifically) were previously lost for
arguments passed by value.
Introduce a new helper function to glean sugared type info from
ImplicitCastExpr nodes in the AST, as present in later revs of Clang.
Fixes a TODO in derived_function_tpl_args.
-rw-r--r-- | iwyu_ast_util.cc | 19 | ||||
-rw-r--r-- | tests/cxx/derived_function_tpl_args.cc | 2 |
2 files changed, 18 insertions, 3 deletions
diff --git a/iwyu_ast_util.cc b/iwyu_ast_util.cc index 23b9b05..9578de6 100644 --- a/iwyu_ast_util.cc +++ b/iwyu_ast_util.cc @@ -725,6 +725,23 @@ GetTplTypeResugarMapForFunctionExplicitTplArgs( return retval; } +// Get the type of an expression while preserving as much type sugar as +// 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(); + } + } + + // If we didn't find a type via ImplicitCastExpr, just return the type of the + // expr itself. + return GetTypeOf(expr); +} + map<const Type*, const Type*> GetTplTypeResugarMapForFunction( const FunctionDecl* decl, const Expr* calling_expr) { map<const Type*, const Type*> retval; @@ -794,7 +811,7 @@ map<const Type*, const Type*> GetTplTypeResugarMapForFunction( // under it, take the pre-cast type instead? set<const Type*> fn_arg_types; for (unsigned i = 0; i < num_args; ++i) { - const Type* argtype = GetTypeOf(fn_args[i]); + const Type* argtype = GetSugaredTypeOf(fn_args[i]); // TODO(csilvers): handle RecordTypes that are a TemplateSpecializationDecl InsertAllInto(GetComponentsOfType(argtype), &fn_arg_types); } diff --git a/tests/cxx/derived_function_tpl_args.cc b/tests/cxx/derived_function_tpl_args.cc index 8c0946b..ddfd5de 100644 --- a/tests/cxx/derived_function_tpl_args.cc +++ b/tests/cxx/derived_function_tpl_args.cc @@ -65,8 +65,6 @@ int main() { typedef IndirectClass LocalClass; LocalClass lc; LocalClass* lc_ptr = 0; - // TODO(csilvers): this is wrong. Figure out how to resugar in this case too. - // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h Fn(lc); Fn(lc_ptr); FnWithPtr(lc_ptr); |