1 //===--- derived_function_tpl_args.cc - test input file for iwyu ----------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 // Tests calls to a templated function, especially ones where the
11 // calls do not specify the template args explicitly, but instead
12 // have them derived from the function arguments (including return
13 // type).  clang desugars the template types in this case, and we
14 // make some effort to undo this work and get back to what the
15 // template args 'logically' are.
16 
17 #include "tests/cxx/derived_function_tpl_args-d1.h"
18 
Fn(T t)19 template<typename T> void Fn(T t) {
20   T dummy;
21   (void)dummy;
22 }
23 
FnWithPtr(T * t)24 template<typename T> void FnWithPtr(T* t) {
25   T dummy;
26   (void)dummy;
27 }
28 
FnWithReference(const T & t)29 template<typename T> void FnWithReference(const T& t) {
30   T dummy;
31   (void)dummy;
32 }
33 
34 template<typename T> struct TplClass {
35   T t;
36 };
37 
main()38 int main() {
39   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
40   IndirectClass ic;
41   // IWYU: IndirectClass needs a declaration
42   IndirectClass* ic_ptr = 0;
43 
44   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
45   Fn(ic);
46   Fn(ic_ptr);
47   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
48   FnWithPtr(ic_ptr);
49   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
50   FnWithReference(ic);
51   FnWithReference(ic_ptr);
52 
53   // Do it again, to make sure that the template cache is working properly.
54   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
55   Fn(ic);
56   Fn(ic_ptr);
57   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
58   FnWithPtr(ic_ptr);
59   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
60   FnWithReference(ic);
61   FnWithReference(ic_ptr);
62 
63   // Now try again, but with a typedef.
64   // IWYU: IndirectClass is...*derived_function_tpl_args-i1.h
65   typedef IndirectClass LocalClass;
66   LocalClass lc;
67   LocalClass* lc_ptr = 0;
68   Fn(lc);
69   Fn(lc_ptr);
70   FnWithPtr(lc_ptr);
71   FnWithReference(lc);
72   FnWithReference(lc_ptr);
73 
74   // And try again, but with namespaces.  This makes sure we don't
75   // get tripped up by ElaboratedType's.
76   // IWYU: ns::NsClass is...*derived_function_tpl_args-i1.h
77   ns::NsClass ns_ic;
78   // IWYU: ns::NsClass needs a declaration
79   ns::NsClass* ns_ic_ptr = 0;
80 
81   // IWYU: ns::NsClass is...*derived_function_tpl_args-i1.h
82   Fn(ns_ic);
83   Fn(ns_ic_ptr);
84   // IWYU: ns::NsClass is...*derived_function_tpl_args-i1.h
85   FnWithPtr(ns_ic_ptr);
86   // IWYU: ns::NsClass is...*derived_function_tpl_args-i1.h
87   FnWithReference(ns_ic);
88   FnWithReference(ns_ic_ptr);
89 
90   // Handle the case where the sugaring is due to default template args.
91   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
92   // IWYU: IndirectClass needs a declaration
93   IndirectTplClass<IndirectClass> itc;
94   // We need the full type for IndirectTplClass because it has a default arg.
95   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
96   // IWYU: IndirectClass needs a declaration
97   IndirectTplClass<IndirectClass>* itc_ptr;
98   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
99   Fn(itc);
100   Fn(itc_ptr);
101   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
102   FnWithPtr(itc_ptr);
103   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
104   FnWithReference(itc);
105   FnWithReference(itc_ptr);
106 
107   // If we have the args explicitly, we're responsible for them.
108   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
109   // IWYU: IndirectClass needs a declaration
110   // IWYU: ns::NsClass needs a declaration
111   IndirectTplClass<IndirectClass, ns::NsClass> itc2;
112   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
113   // IWYU: IndirectClass needs a declaration
114   // IWYU: ns::NsClass needs a declaration
115   IndirectTplClass<IndirectClass, ns::NsClass>* itc2_ptr;
116   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
117   Fn(itc2);
118   Fn(itc2_ptr);
119   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
120   FnWithPtr(itc2_ptr);
121   // IWYU: IndirectTplClass is...*derived_function_tpl_args-i1.h
122   FnWithReference(itc2);
123   FnWithReference(itc2_ptr);
124 
125   // If we specify explicit template args, those should override everything.
126   FnWithPtr<LocalClass>(ic_ptr);
127   FnWithReference<LocalClass>(ic);
128 }
129 
130 /**** IWYU_SUMMARY
131 
132 tests/cxx/derived_function_tpl_args.cc should add these lines:
133 #include "tests/cxx/derived_function_tpl_args-i1.h"
134 
135 tests/cxx/derived_function_tpl_args.cc should remove these lines:
136 - #include "tests/cxx/derived_function_tpl_args-d1.h"  // lines XX-XX
137 
138 The full include-list for tests/cxx/derived_function_tpl_args.cc:
139 #include "tests/cxx/derived_function_tpl_args-i1.h"  // for IndirectClass, IndirectTplClass, NsClass
140 
141 ***** IWYU_SUMMARY */
142