summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim Grasman <kim.grasman@gmail.com>2017-01-01 23:23:13 +0100
committerKim Gräsman <kim.grasman@gmail.com>2017-02-21 10:43:48 +0100
commit3a921410f4ad35030e1aa7ce2101fad947a7fa58 (patch)
tree8395f4e734a9ad95127c107322e3ebc5c89c7c76
parent8065e52a319e1666e77a9616033afd43a2d0e378 (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.cc19
-rw-r--r--tests/cxx/derived_function_tpl_args.cc2
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);