blob: 33a7c66842f6452881febca0ff1f23af449e9969 [file] [log] [blame]
Douglas Gregor0b9247f2009-06-04 00:03:07 +00001//===------- SemaTemplateDeduction.cpp - Template Argument Deduction ------===/
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// This file implements C++ template argument deduction.
10//
11//===----------------------------------------------------------------------===/
12
13#include "Sema.h"
14#include "clang/AST/ASTContext.h"
15#include "clang/AST/DeclTemplate.h"
16#include "clang/AST/StmtVisitor.h"
17#include "clang/AST/Expr.h"
18#include "clang/AST/ExprCXX.h"
19#include "clang/Parse/DeclSpec.h"
20#include "llvm/Support/Compiler.h"
21using namespace clang;
22
Douglas Gregorf67875d2009-06-12 18:26:56 +000023static Sema::TemplateDeductionResult
24DeduceTemplateArguments(ASTContext &Context,
25 TemplateParameterList *TemplateParams,
26 const TemplateArgument &Param,
Douglas Gregord708c722009-06-09 16:35:58 +000027 const TemplateArgument &Arg,
Douglas Gregorf67875d2009-06-12 18:26:56 +000028 Sema::TemplateDeductionInfo &Info,
Douglas Gregord708c722009-06-09 16:35:58 +000029 llvm::SmallVectorImpl<TemplateArgument> &Deduced);
30
Douglas Gregor199d9912009-06-05 00:53:49 +000031/// \brief If the given expression is of a form that permits the deduction
32/// of a non-type template parameter, return the declaration of that
33/// non-type template parameter.
34static NonTypeTemplateParmDecl *getDeducedParameterFromExpr(Expr *E) {
35 if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E))
36 E = IC->getSubExpr();
37
38 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
39 return dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
40
41 return 0;
42}
43
44/// \brief Deduce the value of the given non-type template parameter
45/// from the given constant.
Douglas Gregorf67875d2009-06-12 18:26:56 +000046static Sema::TemplateDeductionResult
47DeduceNonTypeTemplateArgument(ASTContext &Context,
48 NonTypeTemplateParmDecl *NTTP,
Anders Carlsson335e24a2009-06-16 22:44:31 +000049 llvm::APSInt Value,
Douglas Gregorf67875d2009-06-12 18:26:56 +000050 Sema::TemplateDeductionInfo &Info,
51 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
Douglas Gregor199d9912009-06-05 00:53:49 +000052 assert(NTTP->getDepth() == 0 &&
53 "Cannot deduce non-type template argument with depth > 0");
54
55 if (Deduced[NTTP->getIndex()].isNull()) {
56 Deduced[NTTP->getIndex()] = TemplateArgument(SourceLocation(),
57 llvm::APSInt(Value),
58 NTTP->getType());
Douglas Gregorf67875d2009-06-12 18:26:56 +000059 return Sema::TDK_Success;
Douglas Gregor199d9912009-06-05 00:53:49 +000060 }
61
Douglas Gregorf67875d2009-06-12 18:26:56 +000062 assert(Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Integral);
Douglas Gregor199d9912009-06-05 00:53:49 +000063
64 // If the template argument was previously deduced to a negative value,
65 // then our deduction fails.
66 const llvm::APSInt *PrevValuePtr = Deduced[NTTP->getIndex()].getAsIntegral();
Anders Carlsson335e24a2009-06-16 22:44:31 +000067 if (PrevValuePtr->isNegative()) {
Douglas Gregorf67875d2009-06-12 18:26:56 +000068 Info.Param = NTTP;
69 Info.FirstArg = Deduced[NTTP->getIndex()];
Anders Carlsson335e24a2009-06-16 22:44:31 +000070 Info.SecondArg = TemplateArgument(SourceLocation(), Value, NTTP->getType());
Douglas Gregorf67875d2009-06-12 18:26:56 +000071 return Sema::TDK_Inconsistent;
72 }
73
Anders Carlsson335e24a2009-06-16 22:44:31 +000074 llvm::APSInt PrevValue = *PrevValuePtr;
Douglas Gregor199d9912009-06-05 00:53:49 +000075 if (Value.getBitWidth() > PrevValue.getBitWidth())
76 PrevValue.zext(Value.getBitWidth());
77 else if (Value.getBitWidth() < PrevValue.getBitWidth())
78 Value.zext(PrevValue.getBitWidth());
Douglas Gregorf67875d2009-06-12 18:26:56 +000079
80 if (Value != PrevValue) {
81 Info.Param = NTTP;
82 Info.FirstArg = Deduced[NTTP->getIndex()];
Anders Carlsson335e24a2009-06-16 22:44:31 +000083 Info.SecondArg = TemplateArgument(SourceLocation(), Value, NTTP->getType());
Douglas Gregorf67875d2009-06-12 18:26:56 +000084 return Sema::TDK_Inconsistent;
85 }
86
87 return Sema::TDK_Success;
Douglas Gregor199d9912009-06-05 00:53:49 +000088}
89
90/// \brief Deduce the value of the given non-type template parameter
91/// from the given type- or value-dependent expression.
92///
93/// \returns true if deduction succeeded, false otherwise.
94
Douglas Gregorf67875d2009-06-12 18:26:56 +000095static Sema::TemplateDeductionResult
96DeduceNonTypeTemplateArgument(ASTContext &Context,
97 NonTypeTemplateParmDecl *NTTP,
98 Expr *Value,
99 Sema::TemplateDeductionInfo &Info,
100 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000101 assert(NTTP->getDepth() == 0 &&
102 "Cannot deduce non-type template argument with depth > 0");
103 assert((Value->isTypeDependent() || Value->isValueDependent()) &&
104 "Expression template argument must be type- or value-dependent.");
105
106 if (Deduced[NTTP->getIndex()].isNull()) {
107 // FIXME: Clone the Value?
108 Deduced[NTTP->getIndex()] = TemplateArgument(Value);
Douglas Gregorf67875d2009-06-12 18:26:56 +0000109 return Sema::TDK_Success;
Douglas Gregor199d9912009-06-05 00:53:49 +0000110 }
111
112 if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Integral) {
113 // Okay, we deduced a constant in one case and a dependent expression
114 // in another case. FIXME: Later, we will check that instantiating the
115 // dependent expression gives us the constant value.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000116 return Sema::TDK_Success;
Douglas Gregor199d9912009-06-05 00:53:49 +0000117 }
118
119 // FIXME: Compare the expressions for equality!
Douglas Gregorf67875d2009-06-12 18:26:56 +0000120 return Sema::TDK_Success;
Douglas Gregor199d9912009-06-05 00:53:49 +0000121}
122
Douglas Gregorf67875d2009-06-12 18:26:56 +0000123static Sema::TemplateDeductionResult
124DeduceTemplateArguments(ASTContext &Context,
125 TemplateName Param,
126 TemplateName Arg,
127 Sema::TemplateDeductionInfo &Info,
128 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
Douglas Gregord708c722009-06-09 16:35:58 +0000129 // FIXME: Implement template argument deduction for template
130 // template parameters.
131
Douglas Gregorf67875d2009-06-12 18:26:56 +0000132 // FIXME: this routine does not have enough information to produce
133 // good diagnostics.
134
Douglas Gregord708c722009-06-09 16:35:58 +0000135 TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
136 TemplateDecl *ArgDecl = Arg.getAsTemplateDecl();
137
Douglas Gregorf67875d2009-06-12 18:26:56 +0000138 if (!ParamDecl || !ArgDecl) {
139 // FIXME: fill in Info.Param/Info.FirstArg
140 return Sema::TDK_Inconsistent;
141 }
Douglas Gregord708c722009-06-09 16:35:58 +0000142
143 ParamDecl = cast<TemplateDecl>(Context.getCanonicalDecl(ParamDecl));
144 ArgDecl = cast<TemplateDecl>(Context.getCanonicalDecl(ArgDecl));
Douglas Gregorf67875d2009-06-12 18:26:56 +0000145 if (ParamDecl != ArgDecl) {
146 // FIXME: fill in Info.Param/Info.FirstArg
147 return Sema::TDK_Inconsistent;
148 }
149
150 return Sema::TDK_Success;
Douglas Gregord708c722009-06-09 16:35:58 +0000151}
152
Douglas Gregorf67875d2009-06-12 18:26:56 +0000153static Sema::TemplateDeductionResult
154DeduceTemplateArguments(ASTContext &Context,
155 TemplateParameterList *TemplateParams,
156 QualType ParamIn, QualType ArgIn,
157 Sema::TemplateDeductionInfo &Info,
158 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000159 // We only want to look at the canonical types, since typedefs and
160 // sugar are not part of template argument deduction.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000161 QualType Param = Context.getCanonicalType(ParamIn);
162 QualType Arg = Context.getCanonicalType(ArgIn);
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000163
164 // If the parameter type is not dependent, just compare the types
165 // directly.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000166 if (!Param->isDependentType()) {
167 if (Param == Arg)
168 return Sema::TDK_Success;
169
170 Info.FirstArg = TemplateArgument(SourceLocation(), ParamIn);
171 Info.SecondArg = TemplateArgument(SourceLocation(), ArgIn);
172 return Sema::TDK_NonDeducedMismatch;
173 }
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000174
Douglas Gregor199d9912009-06-05 00:53:49 +0000175 // C++ [temp.deduct.type]p9:
Douglas Gregor199d9912009-06-05 00:53:49 +0000176 // A template type argument T, a template template argument TT or a
177 // template non-type argument i can be deduced if P and A have one of
178 // the following forms:
179 //
180 // T
181 // cv-list T
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000182 if (const TemplateTypeParmType *TemplateTypeParm
183 = Param->getAsTemplateTypeParmType()) {
Douglas Gregorf67875d2009-06-12 18:26:56 +0000184 unsigned Index = TemplateTypeParm->getIndex();
185
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000186 // The argument type can not be less qualified than the parameter
187 // type.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000188 if (Param.isMoreQualifiedThan(Arg)) {
189 Info.Param = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
190 Info.FirstArg = Deduced[Index];
191 Info.SecondArg = TemplateArgument(SourceLocation(), Arg);
192 return Sema::TDK_InconsistentQuals;
193 }
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000194
195 assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
196
197 unsigned Quals = Arg.getCVRQualifiers() & ~Param.getCVRQualifiers();
198 QualType DeducedType = Arg.getQualifiedType(Quals);
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000199
200 if (Deduced[Index].isNull())
201 Deduced[Index] = TemplateArgument(SourceLocation(), DeducedType);
202 else {
203 // C++ [temp.deduct.type]p2:
204 // [...] If type deduction cannot be done for any P/A pair, or if for
205 // any pair the deduction leads to more than one possible set of
206 // deduced values, or if different pairs yield different deduced
207 // values, or if any template argument remains neither deduced nor
208 // explicitly specified, template argument deduction fails.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000209 if (Deduced[Index].getAsType() != DeducedType) {
210 Info.Param
211 = cast<TemplateTypeParmDecl>(TemplateParams->getParam(Index));
212 Info.FirstArg = Deduced[Index];
213 Info.SecondArg = TemplateArgument(SourceLocation(), Arg);
214 return Sema::TDK_Inconsistent;
215 }
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000216 }
Douglas Gregorf67875d2009-06-12 18:26:56 +0000217 return Sema::TDK_Success;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000218 }
219
Douglas Gregorf67875d2009-06-12 18:26:56 +0000220 // Set up the template argument deduction information for a failure.
221 Info.FirstArg = TemplateArgument(SourceLocation(), ParamIn);
222 Info.SecondArg = TemplateArgument(SourceLocation(), ArgIn);
223
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000224 if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
Douglas Gregorf67875d2009-06-12 18:26:56 +0000225 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000226
Douglas Gregord560d502009-06-04 00:21:18 +0000227 switch (Param->getTypeClass()) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000228 // No deduction possible for these types
229 case Type::Builtin:
Douglas Gregorf67875d2009-06-12 18:26:56 +0000230 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor199d9912009-06-05 00:53:49 +0000231
232 // T *
Douglas Gregord560d502009-06-04 00:21:18 +0000233 case Type::Pointer: {
234 const PointerType *PointerArg = Arg->getAsPointerType();
235 if (!PointerArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000236 return Sema::TDK_NonDeducedMismatch;
Douglas Gregord560d502009-06-04 00:21:18 +0000237
Douglas Gregorf67875d2009-06-12 18:26:56 +0000238 return DeduceTemplateArguments(Context, TemplateParams,
Douglas Gregord560d502009-06-04 00:21:18 +0000239 cast<PointerType>(Param)->getPointeeType(),
240 PointerArg->getPointeeType(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000241 Info, Deduced);
Douglas Gregord560d502009-06-04 00:21:18 +0000242 }
243
Douglas Gregor199d9912009-06-05 00:53:49 +0000244 // T &
Douglas Gregord560d502009-06-04 00:21:18 +0000245 case Type::LValueReference: {
246 const LValueReferenceType *ReferenceArg = Arg->getAsLValueReferenceType();
247 if (!ReferenceArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000248 return Sema::TDK_NonDeducedMismatch;
Douglas Gregord560d502009-06-04 00:21:18 +0000249
Douglas Gregorf67875d2009-06-12 18:26:56 +0000250 return DeduceTemplateArguments(Context, TemplateParams,
Douglas Gregord560d502009-06-04 00:21:18 +0000251 cast<LValueReferenceType>(Param)->getPointeeType(),
252 ReferenceArg->getPointeeType(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000253 Info, Deduced);
Douglas Gregord560d502009-06-04 00:21:18 +0000254 }
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000255
Douglas Gregor199d9912009-06-05 00:53:49 +0000256 // T && [C++0x]
Douglas Gregord560d502009-06-04 00:21:18 +0000257 case Type::RValueReference: {
258 const RValueReferenceType *ReferenceArg = Arg->getAsRValueReferenceType();
259 if (!ReferenceArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000260 return Sema::TDK_NonDeducedMismatch;
Douglas Gregord560d502009-06-04 00:21:18 +0000261
Douglas Gregorf67875d2009-06-12 18:26:56 +0000262 return DeduceTemplateArguments(Context, TemplateParams,
Douglas Gregord560d502009-06-04 00:21:18 +0000263 cast<RValueReferenceType>(Param)->getPointeeType(),
264 ReferenceArg->getPointeeType(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000265 Info, Deduced);
Douglas Gregord560d502009-06-04 00:21:18 +0000266 }
267
Douglas Gregor199d9912009-06-05 00:53:49 +0000268 // T [] (implied, but not stated explicitly)
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000269 case Type::IncompleteArray: {
270 const IncompleteArrayType *IncompleteArrayArg =
271 Context.getAsIncompleteArrayType(Arg);
272 if (!IncompleteArrayArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000273 return Sema::TDK_NonDeducedMismatch;
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000274
Douglas Gregorf67875d2009-06-12 18:26:56 +0000275 return DeduceTemplateArguments(Context, TemplateParams,
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000276 Context.getAsIncompleteArrayType(Param)->getElementType(),
277 IncompleteArrayArg->getElementType(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000278 Info, Deduced);
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000279 }
Douglas Gregor199d9912009-06-05 00:53:49 +0000280
281 // T [integer-constant]
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000282 case Type::ConstantArray: {
283 const ConstantArrayType *ConstantArrayArg =
284 Context.getAsConstantArrayType(Arg);
285 if (!ConstantArrayArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000286 return Sema::TDK_NonDeducedMismatch;
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000287
288 const ConstantArrayType *ConstantArrayParm =
289 Context.getAsConstantArrayType(Param);
290 if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
Douglas Gregorf67875d2009-06-12 18:26:56 +0000291 return Sema::TDK_NonDeducedMismatch;
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000292
Douglas Gregorf67875d2009-06-12 18:26:56 +0000293 return DeduceTemplateArguments(Context, TemplateParams,
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000294 ConstantArrayParm->getElementType(),
295 ConstantArrayArg->getElementType(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000296 Info, Deduced);
Anders Carlsson4d6fb502009-06-04 04:11:30 +0000297 }
298
Douglas Gregor199d9912009-06-05 00:53:49 +0000299 // type [i]
300 case Type::DependentSizedArray: {
301 const ArrayType *ArrayArg = dyn_cast<ArrayType>(Arg);
302 if (!ArrayArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000303 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor199d9912009-06-05 00:53:49 +0000304
305 // Check the element type of the arrays
306 const DependentSizedArrayType *DependentArrayParm
307 = cast<DependentSizedArrayType>(Param);
Douglas Gregorf67875d2009-06-12 18:26:56 +0000308 if (Sema::TemplateDeductionResult Result
309 = DeduceTemplateArguments(Context, TemplateParams,
310 DependentArrayParm->getElementType(),
311 ArrayArg->getElementType(),
312 Info, Deduced))
313 return Result;
Douglas Gregor199d9912009-06-05 00:53:49 +0000314
315 // Determine the array bound is something we can deduce.
316 NonTypeTemplateParmDecl *NTTP
317 = getDeducedParameterFromExpr(DependentArrayParm->getSizeExpr());
318 if (!NTTP)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000319 return Sema::TDK_Success;
Douglas Gregor199d9912009-06-05 00:53:49 +0000320
321 // We can perform template argument deduction for the given non-type
322 // template parameter.
323 assert(NTTP->getDepth() == 0 &&
324 "Cannot deduce non-type template argument at depth > 0");
325 if (const ConstantArrayType *ConstantArrayArg
Anders Carlsson335e24a2009-06-16 22:44:31 +0000326 = dyn_cast<ConstantArrayType>(ArrayArg)) {
327 llvm::APSInt Size(ConstantArrayArg->getSize());
328 return DeduceNonTypeTemplateArgument(Context, NTTP, Size,
Douglas Gregorf67875d2009-06-12 18:26:56 +0000329 Info, Deduced);
Anders Carlsson335e24a2009-06-16 22:44:31 +0000330 }
Douglas Gregor199d9912009-06-05 00:53:49 +0000331 if (const DependentSizedArrayType *DependentArrayArg
332 = dyn_cast<DependentSizedArrayType>(ArrayArg))
333 return DeduceNonTypeTemplateArgument(Context, NTTP,
334 DependentArrayArg->getSizeExpr(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000335 Info, Deduced);
Douglas Gregor199d9912009-06-05 00:53:49 +0000336
337 // Incomplete type does not match a dependently-sized array type
Douglas Gregorf67875d2009-06-12 18:26:56 +0000338 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor199d9912009-06-05 00:53:49 +0000339 }
340
Douglas Gregor0fce0ae2009-06-08 15:59:14 +0000341 // type(*)(T)
342 // T(*)()
343 // T(*)(T)
Anders Carlssona27fad52009-06-08 15:19:08 +0000344 case Type::FunctionProto: {
345 const FunctionProtoType *FunctionProtoArg =
346 dyn_cast<FunctionProtoType>(Arg);
347 if (!FunctionProtoArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000348 return Sema::TDK_NonDeducedMismatch;
Anders Carlssona27fad52009-06-08 15:19:08 +0000349
350 const FunctionProtoType *FunctionProtoParam =
351 cast<FunctionProtoType>(Param);
Anders Carlsson994b6cb2009-06-08 19:22:23 +0000352
353 if (FunctionProtoParam->getTypeQuals() !=
354 FunctionProtoArg->getTypeQuals())
Douglas Gregorf67875d2009-06-12 18:26:56 +0000355 return Sema::TDK_NonDeducedMismatch;
Anders Carlssona27fad52009-06-08 15:19:08 +0000356
Anders Carlsson994b6cb2009-06-08 19:22:23 +0000357 if (FunctionProtoParam->getNumArgs() != FunctionProtoArg->getNumArgs())
Douglas Gregorf67875d2009-06-12 18:26:56 +0000358 return Sema::TDK_NonDeducedMismatch;
Anders Carlsson994b6cb2009-06-08 19:22:23 +0000359
360 if (FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
Douglas Gregorf67875d2009-06-12 18:26:56 +0000361 return Sema::TDK_NonDeducedMismatch;
Anders Carlsson994b6cb2009-06-08 19:22:23 +0000362
Anders Carlssona27fad52009-06-08 15:19:08 +0000363 // Check return types.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000364 if (Sema::TemplateDeductionResult Result
365 = DeduceTemplateArguments(Context, TemplateParams,
366 FunctionProtoParam->getResultType(),
367 FunctionProtoArg->getResultType(),
368 Info, Deduced))
369 return Result;
Anders Carlssona27fad52009-06-08 15:19:08 +0000370
Anders Carlssona27fad52009-06-08 15:19:08 +0000371 for (unsigned I = 0, N = FunctionProtoParam->getNumArgs(); I != N; ++I) {
372 // Check argument types.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000373 if (Sema::TemplateDeductionResult Result
374 = DeduceTemplateArguments(Context, TemplateParams,
375 FunctionProtoParam->getArgType(I),
376 FunctionProtoArg->getArgType(I),
377 Info, Deduced))
378 return Result;
Anders Carlssona27fad52009-06-08 15:19:08 +0000379 }
380
Douglas Gregorf67875d2009-06-12 18:26:56 +0000381 return Sema::TDK_Success;
Anders Carlssona27fad52009-06-08 15:19:08 +0000382 }
Douglas Gregord708c722009-06-09 16:35:58 +0000383
384 // template-name<T> (wheretemplate-name refers to a class template)
385 // template-name<i>
386 // TT<T> (TODO)
387 // TT<i> (TODO)
388 // TT<> (TODO)
389 case Type::TemplateSpecialization: {
390 const TemplateSpecializationType *SpecParam
391 = cast<TemplateSpecializationType>(Param);
392
393 // Check whether the template argument is a dependent template-id.
394 // FIXME: This is untested code; it can be tested when we implement
395 // partial ordering of class template partial specializations.
396 if (const TemplateSpecializationType *SpecArg
397 = dyn_cast<TemplateSpecializationType>(Arg)) {
398 // Perform template argument deduction for the template name.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000399 if (Sema::TemplateDeductionResult Result
400 = DeduceTemplateArguments(Context,
401 SpecParam->getTemplateName(),
402 SpecArg->getTemplateName(),
403 Info, Deduced))
404 return Result;
Douglas Gregord708c722009-06-09 16:35:58 +0000405
406 unsigned NumArgs = SpecParam->getNumArgs();
407
408 // FIXME: When one of the template-names refers to a
409 // declaration with default template arguments, do we need to
410 // fill in those default template arguments here? Most likely,
411 // the answer is "yes", but I don't see any references. This
412 // issue may be resolved elsewhere, because we may want to
413 // instantiate default template arguments when
414 if (SpecArg->getNumArgs() != NumArgs)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000415 return Sema::TDK_NonDeducedMismatch;
Douglas Gregord708c722009-06-09 16:35:58 +0000416
417 // Perform template argument deduction on each template
418 // argument.
419 for (unsigned I = 0; I != NumArgs; ++I)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000420 if (Sema::TemplateDeductionResult Result
421 = DeduceTemplateArguments(Context, TemplateParams,
422 SpecParam->getArg(I),
423 SpecArg->getArg(I),
424 Info, Deduced))
425 return Result;
Douglas Gregord708c722009-06-09 16:35:58 +0000426
Douglas Gregorf67875d2009-06-12 18:26:56 +0000427 return Sema::TDK_Success;
Douglas Gregord708c722009-06-09 16:35:58 +0000428 }
429
430 // If the argument type is a class template specialization, we
431 // perform template argument deduction using its template
432 // arguments.
433 const RecordType *RecordArg = dyn_cast<RecordType>(Arg);
434 if (!RecordArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000435 return Sema::TDK_NonDeducedMismatch;
Douglas Gregord708c722009-06-09 16:35:58 +0000436
437 ClassTemplateSpecializationDecl *SpecArg
438 = dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl());
439 if (!SpecArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000440 return Sema::TDK_NonDeducedMismatch;
Douglas Gregord708c722009-06-09 16:35:58 +0000441
442 // Perform template argument deduction for the template name.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000443 if (Sema::TemplateDeductionResult Result
444 = DeduceTemplateArguments(Context,
445 SpecParam->getTemplateName(),
446 TemplateName(SpecArg->getSpecializedTemplate()),
447 Info, Deduced))
448 return Result;
Douglas Gregord708c722009-06-09 16:35:58 +0000449
450 // FIXME: Can the # of arguments in the parameter and the argument differ?
451 unsigned NumArgs = SpecParam->getNumArgs();
452 const TemplateArgumentList &ArgArgs = SpecArg->getTemplateArgs();
453 if (NumArgs != ArgArgs.size())
Douglas Gregorf67875d2009-06-12 18:26:56 +0000454 return Sema::TDK_NonDeducedMismatch;
Douglas Gregord708c722009-06-09 16:35:58 +0000455
456 for (unsigned I = 0; I != NumArgs; ++I)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000457 if (Sema::TemplateDeductionResult Result
458 = DeduceTemplateArguments(Context, TemplateParams,
459 SpecParam->getArg(I),
460 ArgArgs.get(I),
461 Info, Deduced))
462 return Result;
Anders Carlssona27fad52009-06-08 15:19:08 +0000463
Douglas Gregorf67875d2009-06-12 18:26:56 +0000464 return Sema::TDK_Success;
Douglas Gregord708c722009-06-09 16:35:58 +0000465 }
466
Douglas Gregor637a4092009-06-10 23:47:09 +0000467 // T type::*
468 // T T::*
469 // T (type::*)()
470 // type (T::*)()
471 // type (type::*)(T)
472 // type (T::*)(T)
473 // T (type::*)(T)
474 // T (T::*)()
475 // T (T::*)(T)
476 case Type::MemberPointer: {
477 const MemberPointerType *MemPtrParam = cast<MemberPointerType>(Param);
478 const MemberPointerType *MemPtrArg = dyn_cast<MemberPointerType>(Arg);
479 if (!MemPtrArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000480 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor637a4092009-06-10 23:47:09 +0000481
Douglas Gregorf67875d2009-06-12 18:26:56 +0000482 if (Sema::TemplateDeductionResult Result
483 = DeduceTemplateArguments(Context, TemplateParams,
484 MemPtrParam->getPointeeType(),
485 MemPtrArg->getPointeeType(),
486 Info, Deduced))
487 return Result;
488
489 return DeduceTemplateArguments(Context, TemplateParams,
490 QualType(MemPtrParam->getClass(), 0),
491 QualType(MemPtrArg->getClass(), 0),
492 Info, Deduced);
Douglas Gregor637a4092009-06-10 23:47:09 +0000493 }
494
Anders Carlsson9a917e42009-06-12 22:56:54 +0000495 // (clang extension)
496 //
Anders Carlsson859ba502009-06-12 16:23:10 +0000497 // type(^)(T)
498 // T(^)()
499 // T(^)(T)
500 case Type::BlockPointer: {
501 const BlockPointerType *BlockPtrParam = cast<BlockPointerType>(Param);
502 const BlockPointerType *BlockPtrArg = dyn_cast<BlockPointerType>(Arg);
503
504 if (!BlockPtrArg)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000505 return Sema::TDK_NonDeducedMismatch;
Anders Carlsson859ba502009-06-12 16:23:10 +0000506
Douglas Gregorf67875d2009-06-12 18:26:56 +0000507 return DeduceTemplateArguments(Context, TemplateParams,
Anders Carlsson859ba502009-06-12 16:23:10 +0000508 BlockPtrParam->getPointeeType(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000509 BlockPtrArg->getPointeeType(), Info,
510 Deduced);
Anders Carlsson859ba502009-06-12 16:23:10 +0000511 }
512
Douglas Gregor637a4092009-06-10 23:47:09 +0000513 case Type::TypeOfExpr:
514 case Type::TypeOf:
515 case Type::Typename:
516 // No template argument deduction for these types
Douglas Gregorf67875d2009-06-12 18:26:56 +0000517 return Sema::TDK_Success;
Douglas Gregor637a4092009-06-10 23:47:09 +0000518
Douglas Gregord560d502009-06-04 00:21:18 +0000519 default:
520 break;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000521 }
522
523 // FIXME: Many more cases to go (to go).
Douglas Gregorf67875d2009-06-12 18:26:56 +0000524 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000525}
526
Douglas Gregorf67875d2009-06-12 18:26:56 +0000527static Sema::TemplateDeductionResult
528DeduceTemplateArguments(ASTContext &Context,
529 TemplateParameterList *TemplateParams,
530 const TemplateArgument &Param,
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000531 const TemplateArgument &Arg,
Douglas Gregorf67875d2009-06-12 18:26:56 +0000532 Sema::TemplateDeductionInfo &Info,
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000533 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000534 switch (Param.getKind()) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000535 case TemplateArgument::Null:
536 assert(false && "Null template argument in parameter list");
537 break;
538
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000539 case TemplateArgument::Type:
Douglas Gregor199d9912009-06-05 00:53:49 +0000540 assert(Arg.getKind() == TemplateArgument::Type && "Type/value mismatch");
Douglas Gregorf67875d2009-06-12 18:26:56 +0000541 return DeduceTemplateArguments(Context, TemplateParams,
542 Param.getAsType(),
543 Arg.getAsType(), Info, Deduced);
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000544
Douglas Gregor199d9912009-06-05 00:53:49 +0000545 case TemplateArgument::Declaration:
546 // FIXME: Implement this check
547 assert(false && "Unimplemented template argument deduction case");
Douglas Gregorf67875d2009-06-12 18:26:56 +0000548 Info.FirstArg = Param;
549 Info.SecondArg = Arg;
550 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor199d9912009-06-05 00:53:49 +0000551
552 case TemplateArgument::Integral:
553 if (Arg.getKind() == TemplateArgument::Integral) {
554 // FIXME: Zero extension + sign checking here?
Douglas Gregorf67875d2009-06-12 18:26:56 +0000555 if (*Param.getAsIntegral() == *Arg.getAsIntegral())
556 return Sema::TDK_Success;
557
558 Info.FirstArg = Param;
559 Info.SecondArg = Arg;
560 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor199d9912009-06-05 00:53:49 +0000561 }
Douglas Gregorf67875d2009-06-12 18:26:56 +0000562
563 if (Arg.getKind() == TemplateArgument::Expression) {
564 Info.FirstArg = Param;
565 Info.SecondArg = Arg;
566 return Sema::TDK_NonDeducedMismatch;
567 }
Douglas Gregor199d9912009-06-05 00:53:49 +0000568
569 assert(false && "Type/value mismatch");
Douglas Gregorf67875d2009-06-12 18:26:56 +0000570 Info.FirstArg = Param;
571 Info.SecondArg = Arg;
572 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor199d9912009-06-05 00:53:49 +0000573
574 case TemplateArgument::Expression: {
575 if (NonTypeTemplateParmDecl *NTTP
576 = getDeducedParameterFromExpr(Param.getAsExpr())) {
577 if (Arg.getKind() == TemplateArgument::Integral)
578 // FIXME: Sign problems here
579 return DeduceNonTypeTemplateArgument(Context, NTTP,
Douglas Gregorf67875d2009-06-12 18:26:56 +0000580 *Arg.getAsIntegral(),
581 Info, Deduced);
Douglas Gregor199d9912009-06-05 00:53:49 +0000582 if (Arg.getKind() == TemplateArgument::Expression)
583 return DeduceNonTypeTemplateArgument(Context, NTTP, Arg.getAsExpr(),
Douglas Gregorf67875d2009-06-12 18:26:56 +0000584 Info, Deduced);
Douglas Gregor199d9912009-06-05 00:53:49 +0000585
586 assert(false && "Type/value mismatch");
Douglas Gregorf67875d2009-06-12 18:26:56 +0000587 Info.FirstArg = Param;
588 Info.SecondArg = Arg;
589 return Sema::TDK_NonDeducedMismatch;
Douglas Gregor199d9912009-06-05 00:53:49 +0000590 }
591
592 // Can't deduce anything, but that's okay.
Douglas Gregorf67875d2009-06-12 18:26:56 +0000593 return Sema::TDK_Success;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000594 }
Anders Carlssond01b1da2009-06-15 17:04:53 +0000595 case TemplateArgument::Pack:
596 assert(0 && "FIXME: Implement!");
597 break;
Douglas Gregor199d9912009-06-05 00:53:49 +0000598 }
599
Douglas Gregorf67875d2009-06-12 18:26:56 +0000600 return Sema::TDK_Success;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000601}
602
Douglas Gregorf67875d2009-06-12 18:26:56 +0000603static Sema::TemplateDeductionResult
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000604DeduceTemplateArguments(ASTContext &Context,
Douglas Gregorf67875d2009-06-12 18:26:56 +0000605 TemplateParameterList *TemplateParams,
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000606 const TemplateArgumentList &ParamList,
607 const TemplateArgumentList &ArgList,
Douglas Gregorf67875d2009-06-12 18:26:56 +0000608 Sema::TemplateDeductionInfo &Info,
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000609 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
610 assert(ParamList.size() == ArgList.size());
611 for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
Douglas Gregorf67875d2009-06-12 18:26:56 +0000612 if (Sema::TemplateDeductionResult Result
613 = DeduceTemplateArguments(Context, TemplateParams,
614 ParamList[I], ArgList[I],
615 Info, Deduced))
616 return Result;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000617 }
Douglas Gregorf67875d2009-06-12 18:26:56 +0000618 return Sema::TDK_Success;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000619}
620
Douglas Gregorc1efb3f2009-06-12 22:31:52 +0000621/// \brief Perform template argument deduction to determine whether
622/// the given template arguments match the given class template
623/// partial specialization per C++ [temp.class.spec.match].
Douglas Gregorf67875d2009-06-12 18:26:56 +0000624Sema::TemplateDeductionResult
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000625Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
Douglas Gregorf67875d2009-06-12 18:26:56 +0000626 const TemplateArgumentList &TemplateArgs,
627 TemplateDeductionInfo &Info) {
Douglas Gregorc1efb3f2009-06-12 22:31:52 +0000628 // C++ [temp.class.spec.match]p2:
629 // A partial specialization matches a given actual template
630 // argument list if the template arguments of the partial
631 // specialization can be deduced from the actual template argument
632 // list (14.8.2).
Douglas Gregorbb260412009-06-14 08:02:22 +0000633 SFINAETrap Trap(*this);
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000634 llvm::SmallVector<TemplateArgument, 4> Deduced;
635 Deduced.resize(Partial->getTemplateParameters()->size());
Douglas Gregorf67875d2009-06-12 18:26:56 +0000636 if (TemplateDeductionResult Result
637 = ::DeduceTemplateArguments(Context,
638 Partial->getTemplateParameters(),
639 Partial->getTemplateArgs(),
640 TemplateArgs, Info, Deduced))
641 return Result;
Douglas Gregor637a4092009-06-10 23:47:09 +0000642
Douglas Gregor637a4092009-06-10 23:47:09 +0000643 InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
644 Deduced.data(), Deduced.size());
645 if (Inst)
Douglas Gregorf67875d2009-06-12 18:26:56 +0000646 return TDK_InstantiationDepth;
Douglas Gregor199d9912009-06-05 00:53:49 +0000647
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000648 // C++ [temp.deduct.type]p2:
649 // [...] or if any template argument remains neither deduced nor
650 // explicitly specified, template argument deduction fails.
651 TemplateArgumentListBuilder Builder(Context);
652 for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
Douglas Gregorf67875d2009-06-12 18:26:56 +0000653 if (Deduced[I].isNull()) {
654 Decl *Param
655 = const_cast<Decl *>(Partial->getTemplateParameters()->getParam(I));
656 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
657 Info.Param = TTP;
658 else if (NonTypeTemplateParmDecl *NTTP
659 = dyn_cast<NonTypeTemplateParmDecl>(Param))
660 Info.Param = NTTP;
661 else
662 Info.Param = cast<TemplateTemplateParmDecl>(Param);
663 return TDK_Incomplete;
664 }
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000665
666 Builder.push_back(Deduced[I]);
667 }
668
669 // Form the template argument list from the deduced template arguments.
670 TemplateArgumentList *DeducedArgumentList
671 = new (Context) TemplateArgumentList(Context, Builder, /*CopyArgs=*/true,
672 /*FlattenArgs=*/true);
Douglas Gregorf67875d2009-06-12 18:26:56 +0000673 Info.reset(DeducedArgumentList);
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000674
675 // Now that we have all of the deduced template arguments, take
676 // another pass through them to convert any integral template
677 // arguments to the appropriate type.
678 for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
679 TemplateArgument &Arg = Deduced[I];
Douglas Gregor199d9912009-06-05 00:53:49 +0000680 if (Arg.getKind() == TemplateArgument::Integral) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000681 const NonTypeTemplateParmDecl *Parm
682 = cast<NonTypeTemplateParmDecl>(Partial->getTemplateParameters()
683 ->getParam(I));
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000684 QualType T = InstantiateType(Parm->getType(), *DeducedArgumentList,
685 Parm->getLocation(), Parm->getDeclName());
Douglas Gregorf67875d2009-06-12 18:26:56 +0000686 if (T.isNull()) {
687 Info.Param = const_cast<NonTypeTemplateParmDecl*>(Parm);
688 Info.FirstArg = TemplateArgument(Parm->getLocation(), Parm->getType());
689 return TDK_SubstitutionFailure;
690 }
Douglas Gregor199d9912009-06-05 00:53:49 +0000691
692 // FIXME: Make sure we didn't overflow our data type!
693 llvm::APSInt &Value = *Arg.getAsIntegral();
694 unsigned AllowedBits = Context.getTypeSize(T);
695 if (Value.getBitWidth() != AllowedBits)
696 Value.extOrTrunc(AllowedBits);
697 Value.setIsSigned(T->isSignedIntegerType());
698 Arg.setIntegralType(T);
699 }
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000700
701 (*DeducedArgumentList)[I] = Arg;
Douglas Gregor199d9912009-06-05 00:53:49 +0000702 }
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000703
704 // Substitute the deduced template arguments into the template
705 // arguments of the class template partial specialization, and
706 // verify that the instantiated template arguments are both valid
707 // and are equivalent to the template arguments originally provided
Douglas Gregorc9e5d252009-06-13 00:59:32 +0000708 // to the class template.
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000709 ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
710 const TemplateArgumentList &PartialTemplateArgs = Partial->getTemplateArgs();
711 for (unsigned I = 0, N = PartialTemplateArgs.flat_size(); I != N; ++I) {
Douglas Gregorc9e5d252009-06-13 00:59:32 +0000712 Decl *Param = const_cast<Decl *>(
713 ClassTemplate->getTemplateParameters()->getParam(I));
714 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
715 TemplateArgument InstArg = Instantiate(PartialTemplateArgs[I],
716 *DeducedArgumentList);
717 if (InstArg.getKind() != TemplateArgument::Type) {
Douglas Gregorf67875d2009-06-12 18:26:56 +0000718 Info.Param = TTP;
Douglas Gregorc9e5d252009-06-13 00:59:32 +0000719 Info.FirstArg = PartialTemplateArgs[I];
720 return TDK_SubstitutionFailure;
721 }
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000722
Douglas Gregorc9e5d252009-06-13 00:59:32 +0000723 if (Context.getCanonicalType(InstArg.getAsType())
Douglas Gregorf67875d2009-06-12 18:26:56 +0000724 != Context.getCanonicalType(TemplateArgs[I].getAsType())) {
Douglas Gregorc9e5d252009-06-13 00:59:32 +0000725 Info.Param = TTP;
Douglas Gregorf67875d2009-06-12 18:26:56 +0000726 Info.FirstArg = TemplateArgs[I];
727 Info.SecondArg = InstArg;
728 return TDK_NonDeducedMismatch;
729 }
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000730
Douglas Gregorc9e5d252009-06-13 00:59:32 +0000731 continue;
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000732 }
Douglas Gregorc9e5d252009-06-13 00:59:32 +0000733
734 // FIXME: Check template template arguments?
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000735 }
736
Douglas Gregorbb260412009-06-14 08:02:22 +0000737 if (Trap.hasErrorOccurred())
738 return TDK_SubstitutionFailure;
739
Douglas Gregorf67875d2009-06-12 18:26:56 +0000740 return TDK_Success;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000741}
Douglas Gregor031a5882009-06-13 00:26:55 +0000742
743static void
744MarkDeducedTemplateParameters(Sema &SemaRef,
745 const TemplateArgument &TemplateArg,
746 llvm::SmallVectorImpl<bool> &Deduced);
747
748/// \brief Mark the template arguments that are deduced by the given
749/// expression.
750static void
751MarkDeducedTemplateParameters(Expr *E, llvm::SmallVectorImpl<bool> &Deduced) {
752 DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E);
753 if (!E)
754 return;
755
756 NonTypeTemplateParmDecl *NTTP
757 = dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
758 if (!NTTP)
759 return;
760
761 Deduced[NTTP->getIndex()] = true;
762}
763
764/// \brief Mark the template parameters that are deduced by the given
765/// type.
766static void
767MarkDeducedTemplateParameters(Sema &SemaRef, QualType T,
768 llvm::SmallVectorImpl<bool> &Deduced) {
769 // Non-dependent types have nothing deducible
770 if (!T->isDependentType())
771 return;
772
773 T = SemaRef.Context.getCanonicalType(T);
774 switch (T->getTypeClass()) {
775 case Type::ExtQual:
776 MarkDeducedTemplateParameters(SemaRef,
777 QualType(cast<ExtQualType>(T.getTypePtr())->getBaseType(), 0),
778 Deduced);
779 break;
780
781 case Type::Pointer:
782 MarkDeducedTemplateParameters(SemaRef,
783 cast<PointerType>(T.getTypePtr())->getPointeeType(),
784 Deduced);
785 break;
786
787 case Type::BlockPointer:
788 MarkDeducedTemplateParameters(SemaRef,
789 cast<BlockPointerType>(T.getTypePtr())->getPointeeType(),
790 Deduced);
791 break;
792
793 case Type::LValueReference:
794 case Type::RValueReference:
795 MarkDeducedTemplateParameters(SemaRef,
796 cast<ReferenceType>(T.getTypePtr())->getPointeeType(),
797 Deduced);
798 break;
799
800 case Type::MemberPointer: {
801 const MemberPointerType *MemPtr = cast<MemberPointerType>(T.getTypePtr());
802 MarkDeducedTemplateParameters(SemaRef, MemPtr->getPointeeType(), Deduced);
803 MarkDeducedTemplateParameters(SemaRef, QualType(MemPtr->getClass(), 0),
804 Deduced);
805 break;
806 }
807
808 case Type::DependentSizedArray:
809 MarkDeducedTemplateParameters(
810 cast<DependentSizedArrayType>(T.getTypePtr())->getSizeExpr(),
811 Deduced);
812 // Fall through to check the element type
813
814 case Type::ConstantArray:
815 case Type::IncompleteArray:
816 MarkDeducedTemplateParameters(SemaRef,
817 cast<ArrayType>(T.getTypePtr())->getElementType(),
818 Deduced);
819 break;
820
821 case Type::Vector:
822 case Type::ExtVector:
823 MarkDeducedTemplateParameters(SemaRef,
824 cast<VectorType>(T.getTypePtr())->getElementType(),
825 Deduced);
826 break;
827
828 case Type::FunctionProto: {
829 const FunctionProtoType *Proto = cast<FunctionProtoType>(T.getTypePtr());
830 MarkDeducedTemplateParameters(SemaRef, Proto->getResultType(), Deduced);
831 for (unsigned I = 0, N = Proto->getNumArgs(); I != N; ++I)
832 MarkDeducedTemplateParameters(SemaRef, Proto->getArgType(I), Deduced);
833 break;
834 }
835
836 case Type::TemplateTypeParm:
837 Deduced[cast<TemplateTypeParmType>(T.getTypePtr())->getIndex()] = true;
838 break;
839
840 case Type::TemplateSpecialization: {
841 const TemplateSpecializationType *Spec
842 = cast<TemplateSpecializationType>(T.getTypePtr());
843 if (TemplateDecl *Template = Spec->getTemplateName().getAsTemplateDecl())
844 if (TemplateTemplateParmDecl *TTP
845 = dyn_cast<TemplateTemplateParmDecl>(Template))
846 Deduced[TTP->getIndex()] = true;
847
848 for (unsigned I = 0, N = Spec->getNumArgs(); I != N; ++I)
849 MarkDeducedTemplateParameters(SemaRef, Spec->getArg(I), Deduced);
850
851 break;
852 }
853
854 // None of these types have any deducible parts.
855 case Type::Builtin:
856 case Type::FixedWidthInt:
857 case Type::Complex:
858 case Type::VariableArray:
859 case Type::FunctionNoProto:
860 case Type::Record:
861 case Type::Enum:
862 case Type::Typename:
863 case Type::ObjCInterface:
864 case Type::ObjCQualifiedInterface:
865 case Type::ObjCQualifiedId:
866#define TYPE(Class, Base)
867#define ABSTRACT_TYPE(Class, Base)
868#define DEPENDENT_TYPE(Class, Base)
869#define NON_CANONICAL_TYPE(Class, Base) case Type::Class:
870#include "clang/AST/TypeNodes.def"
871 break;
872 }
873}
874
875/// \brief Mark the template parameters that are deduced by this
876/// template argument.
877static void
878MarkDeducedTemplateParameters(Sema &SemaRef,
879 const TemplateArgument &TemplateArg,
880 llvm::SmallVectorImpl<bool> &Deduced) {
881 switch (TemplateArg.getKind()) {
882 case TemplateArgument::Null:
883 case TemplateArgument::Integral:
884 break;
885
886 case TemplateArgument::Type:
887 MarkDeducedTemplateParameters(SemaRef, TemplateArg.getAsType(), Deduced);
888 break;
889
890 case TemplateArgument::Declaration:
891 if (TemplateTemplateParmDecl *TTP
892 = dyn_cast<TemplateTemplateParmDecl>(TemplateArg.getAsDecl()))
893 Deduced[TTP->getIndex()] = true;
894 break;
895
896 case TemplateArgument::Expression:
897 MarkDeducedTemplateParameters(TemplateArg.getAsExpr(), Deduced);
898 break;
Anders Carlssond01b1da2009-06-15 17:04:53 +0000899 case TemplateArgument::Pack:
900 assert(0 && "FIXME: Implement!");
901 break;
Douglas Gregor031a5882009-06-13 00:26:55 +0000902 }
903}
904
905/// \brief Mark the template parameters can be deduced by the given
906/// template argument list.
907///
908/// \param TemplateArgs the template argument list from which template
909/// parameters will be deduced.
910///
911/// \param Deduced a bit vector whose elements will be set to \c true
912/// to indicate when the corresponding template parameter will be
913/// deduced.
914void
915Sema::MarkDeducedTemplateParameters(const TemplateArgumentList &TemplateArgs,
916 llvm::SmallVectorImpl<bool> &Deduced) {
917 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
918 ::MarkDeducedTemplateParameters(*this, TemplateArgs[I], Deduced);
919}