blob: 0ad79358cd563464cfd1c26d02a248d9bf769333 [file] [log] [blame]
Douglas Gregorbf23a8a2009-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 Gregor5069ae32009-06-09 16:35:58 +000023static bool
24DeduceTemplateArguments(ASTContext &Context, const TemplateArgument &Param,
25 const TemplateArgument &Arg,
26 llvm::SmallVectorImpl<TemplateArgument> &Deduced);
27
Douglas Gregorab9f71a2009-06-05 00:53:49 +000028/// \brief If the given expression is of a form that permits the deduction
29/// of a non-type template parameter, return the declaration of that
30/// non-type template parameter.
31static NonTypeTemplateParmDecl *getDeducedParameterFromExpr(Expr *E) {
32 if (ImplicitCastExpr *IC = dyn_cast<ImplicitCastExpr>(E))
33 E = IC->getSubExpr();
34
35 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E))
36 return dyn_cast<NonTypeTemplateParmDecl>(DRE->getDecl());
37
38 return 0;
39}
40
41/// \brief Deduce the value of the given non-type template parameter
42/// from the given constant.
43///
44/// \returns true if deduction succeeded, false otherwise.
45static bool DeduceNonTypeTemplateArgument(ASTContext &Context,
46 NonTypeTemplateParmDecl *NTTP,
47 llvm::APInt Value,
48 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
49 assert(NTTP->getDepth() == 0 &&
50 "Cannot deduce non-type template argument with depth > 0");
51
52 if (Deduced[NTTP->getIndex()].isNull()) {
53 Deduced[NTTP->getIndex()] = TemplateArgument(SourceLocation(),
54 llvm::APSInt(Value),
55 NTTP->getType());
56 return true;
57 }
58
59 if (Deduced[NTTP->getIndex()].getKind() != TemplateArgument::Integral)
60 return false;
61
62 // If the template argument was previously deduced to a negative value,
63 // then our deduction fails.
64 const llvm::APSInt *PrevValuePtr = Deduced[NTTP->getIndex()].getAsIntegral();
65 assert(PrevValuePtr && "Not an integral template argument?");
66 if (PrevValuePtr->isSigned() && PrevValuePtr->isNegative())
67 return false;
68
69 llvm::APInt PrevValue = *PrevValuePtr;
70 if (Value.getBitWidth() > PrevValue.getBitWidth())
71 PrevValue.zext(Value.getBitWidth());
72 else if (Value.getBitWidth() < PrevValue.getBitWidth())
73 Value.zext(PrevValue.getBitWidth());
74 return Value == PrevValue;
75}
76
77/// \brief Deduce the value of the given non-type template parameter
78/// from the given type- or value-dependent expression.
79///
80/// \returns true if deduction succeeded, false otherwise.
81
82static bool DeduceNonTypeTemplateArgument(ASTContext &Context,
83 NonTypeTemplateParmDecl *NTTP,
84 Expr *Value,
85 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
86 assert(NTTP->getDepth() == 0 &&
87 "Cannot deduce non-type template argument with depth > 0");
88 assert((Value->isTypeDependent() || Value->isValueDependent()) &&
89 "Expression template argument must be type- or value-dependent.");
90
91 if (Deduced[NTTP->getIndex()].isNull()) {
92 // FIXME: Clone the Value?
93 Deduced[NTTP->getIndex()] = TemplateArgument(Value);
94 return true;
95 }
96
97 if (Deduced[NTTP->getIndex()].getKind() == TemplateArgument::Integral) {
98 // Okay, we deduced a constant in one case and a dependent expression
99 // in another case. FIXME: Later, we will check that instantiating the
100 // dependent expression gives us the constant value.
101 return true;
102 }
103
104 // FIXME: Compare the expressions for equality!
105 return true;
106}
107
Douglas Gregor5069ae32009-06-09 16:35:58 +0000108static bool DeduceTemplateArguments(ASTContext &Context,
109 TemplateName Param,
110 TemplateName Arg,
111 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
112 // FIXME: Implement template argument deduction for template
113 // template parameters.
114
115 TemplateDecl *ParamDecl = Param.getAsTemplateDecl();
116 TemplateDecl *ArgDecl = Arg.getAsTemplateDecl();
117
118 if (!ParamDecl || !ArgDecl)
119 return false;
120
121 ParamDecl = cast<TemplateDecl>(Context.getCanonicalDecl(ParamDecl));
122 ArgDecl = cast<TemplateDecl>(Context.getCanonicalDecl(ArgDecl));
123 return ParamDecl == ArgDecl;
124}
125
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000126static bool DeduceTemplateArguments(ASTContext &Context, QualType Param,
127 QualType Arg,
128 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
129 // We only want to look at the canonical types, since typedefs and
130 // sugar are not part of template argument deduction.
131 Param = Context.getCanonicalType(Param);
132 Arg = Context.getCanonicalType(Arg);
133
134 // If the parameter type is not dependent, just compare the types
135 // directly.
136 if (!Param->isDependentType())
137 return Param == Arg;
138
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000139 // C++ [temp.deduct.type]p9:
140 //
141 // A template type argument T, a template template argument TT or a
142 // template non-type argument i can be deduced if P and A have one of
143 // the following forms:
144 //
145 // T
146 // cv-list T
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000147 if (const TemplateTypeParmType *TemplateTypeParm
148 = Param->getAsTemplateTypeParmType()) {
149 // The argument type can not be less qualified than the parameter
150 // type.
151 if (Param.isMoreQualifiedThan(Arg))
152 return false;
153
154 assert(TemplateTypeParm->getDepth() == 0 && "Can't deduce with depth > 0");
155
156 unsigned Quals = Arg.getCVRQualifiers() & ~Param.getCVRQualifiers();
157 QualType DeducedType = Arg.getQualifiedType(Quals);
158 unsigned Index = TemplateTypeParm->getIndex();
159
160 if (Deduced[Index].isNull())
161 Deduced[Index] = TemplateArgument(SourceLocation(), DeducedType);
162 else {
163 // C++ [temp.deduct.type]p2:
164 // [...] If type deduction cannot be done for any P/A pair, or if for
165 // any pair the deduction leads to more than one possible set of
166 // deduced values, or if different pairs yield different deduced
167 // values, or if any template argument remains neither deduced nor
168 // explicitly specified, template argument deduction fails.
169 if (Deduced[Index].getAsType() != DeducedType)
170 return false;
171 }
172 return true;
173 }
174
175 if (Param.getCVRQualifiers() != Arg.getCVRQualifiers())
176 return false;
177
Douglas Gregor4ea653d2009-06-04 00:21:18 +0000178 switch (Param->getTypeClass()) {
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000179 // No deduction possible for these types
180 case Type::Builtin:
181 return false;
182
183
184 // T *
Douglas Gregor4ea653d2009-06-04 00:21:18 +0000185 case Type::Pointer: {
186 const PointerType *PointerArg = Arg->getAsPointerType();
187 if (!PointerArg)
188 return false;
189
190 return DeduceTemplateArguments(Context,
191 cast<PointerType>(Param)->getPointeeType(),
192 PointerArg->getPointeeType(),
193 Deduced);
194 }
195
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000196 // T &
Douglas Gregor4ea653d2009-06-04 00:21:18 +0000197 case Type::LValueReference: {
198 const LValueReferenceType *ReferenceArg = Arg->getAsLValueReferenceType();
199 if (!ReferenceArg)
200 return false;
201
202 return DeduceTemplateArguments(Context,
203 cast<LValueReferenceType>(Param)->getPointeeType(),
204 ReferenceArg->getPointeeType(),
205 Deduced);
206 }
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000207
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000208 // T && [C++0x]
Douglas Gregor4ea653d2009-06-04 00:21:18 +0000209 case Type::RValueReference: {
210 const RValueReferenceType *ReferenceArg = Arg->getAsRValueReferenceType();
211 if (!ReferenceArg)
212 return false;
213
214 return DeduceTemplateArguments(Context,
215 cast<RValueReferenceType>(Param)->getPointeeType(),
216 ReferenceArg->getPointeeType(),
217 Deduced);
218 }
219
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000220 // T [] (implied, but not stated explicitly)
Anders Carlsson0bcee302009-06-04 04:11:30 +0000221 case Type::IncompleteArray: {
222 const IncompleteArrayType *IncompleteArrayArg =
223 Context.getAsIncompleteArrayType(Arg);
224 if (!IncompleteArrayArg)
225 return false;
226
227 return DeduceTemplateArguments(Context,
228 Context.getAsIncompleteArrayType(Param)->getElementType(),
229 IncompleteArrayArg->getElementType(),
230 Deduced);
231 }
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000232
233 // T [integer-constant]
Anders Carlsson0bcee302009-06-04 04:11:30 +0000234 case Type::ConstantArray: {
235 const ConstantArrayType *ConstantArrayArg =
236 Context.getAsConstantArrayType(Arg);
237 if (!ConstantArrayArg)
238 return false;
239
240 const ConstantArrayType *ConstantArrayParm =
241 Context.getAsConstantArrayType(Param);
242 if (ConstantArrayArg->getSize() != ConstantArrayParm->getSize())
243 return false;
244
245 return DeduceTemplateArguments(Context,
246 ConstantArrayParm->getElementType(),
247 ConstantArrayArg->getElementType(),
248 Deduced);
249 }
250
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000251 // type [i]
252 case Type::DependentSizedArray: {
253 const ArrayType *ArrayArg = dyn_cast<ArrayType>(Arg);
254 if (!ArrayArg)
255 return false;
256
257 // Check the element type of the arrays
258 const DependentSizedArrayType *DependentArrayParm
259 = cast<DependentSizedArrayType>(Param);
260 if (!DeduceTemplateArguments(Context,
261 DependentArrayParm->getElementType(),
262 ArrayArg->getElementType(),
263 Deduced))
264 return false;
265
266 // Determine the array bound is something we can deduce.
267 NonTypeTemplateParmDecl *NTTP
268 = getDeducedParameterFromExpr(DependentArrayParm->getSizeExpr());
269 if (!NTTP)
270 return true;
271
272 // We can perform template argument deduction for the given non-type
273 // template parameter.
274 assert(NTTP->getDepth() == 0 &&
275 "Cannot deduce non-type template argument at depth > 0");
276 if (const ConstantArrayType *ConstantArrayArg
277 = dyn_cast<ConstantArrayType>(ArrayArg))
278 return DeduceNonTypeTemplateArgument(Context, NTTP,
279 ConstantArrayArg->getSize(),
280 Deduced);
281 if (const DependentSizedArrayType *DependentArrayArg
282 = dyn_cast<DependentSizedArrayType>(ArrayArg))
283 return DeduceNonTypeTemplateArgument(Context, NTTP,
284 DependentArrayArg->getSizeExpr(),
285 Deduced);
286
287 // Incomplete type does not match a dependently-sized array type
288 return false;
289 }
290
Douglas Gregor1c67c002009-06-08 15:59:14 +0000291 // type(*)(T)
292 // T(*)()
293 // T(*)(T)
Anders Carlsson8574e7f2009-06-08 15:19:08 +0000294 case Type::FunctionProto: {
295 const FunctionProtoType *FunctionProtoArg =
296 dyn_cast<FunctionProtoType>(Arg);
297 if (!FunctionProtoArg)
298 return false;
299
300 const FunctionProtoType *FunctionProtoParam =
301 cast<FunctionProtoType>(Param);
Anders Carlsson3e39f922009-06-08 19:22:23 +0000302
303 if (FunctionProtoParam->getTypeQuals() !=
304 FunctionProtoArg->getTypeQuals())
305 return false;
Anders Carlsson8574e7f2009-06-08 15:19:08 +0000306
Anders Carlsson3e39f922009-06-08 19:22:23 +0000307 if (FunctionProtoParam->getNumArgs() != FunctionProtoArg->getNumArgs())
308 return false;
309
310 if (FunctionProtoParam->isVariadic() != FunctionProtoArg->isVariadic())
311 return false;
312
Anders Carlsson8574e7f2009-06-08 15:19:08 +0000313 // Check return types.
314 if (!DeduceTemplateArguments(Context,
315 FunctionProtoParam->getResultType(),
316 FunctionProtoArg->getResultType(),
317 Deduced))
318 return false;
319
Anders Carlsson8574e7f2009-06-08 15:19:08 +0000320 for (unsigned I = 0, N = FunctionProtoParam->getNumArgs(); I != N; ++I) {
321 // Check argument types.
322 if (!DeduceTemplateArguments(Context,
323 FunctionProtoParam->getArgType(I),
324 FunctionProtoArg->getArgType(I),
325 Deduced))
326 return false;
327 }
328
329 return true;
330 }
Douglas Gregor5069ae32009-06-09 16:35:58 +0000331
332 // template-name<T> (wheretemplate-name refers to a class template)
333 // template-name<i>
334 // TT<T> (TODO)
335 // TT<i> (TODO)
336 // TT<> (TODO)
337 case Type::TemplateSpecialization: {
338 const TemplateSpecializationType *SpecParam
339 = cast<TemplateSpecializationType>(Param);
340
341 // Check whether the template argument is a dependent template-id.
342 // FIXME: This is untested code; it can be tested when we implement
343 // partial ordering of class template partial specializations.
344 if (const TemplateSpecializationType *SpecArg
345 = dyn_cast<TemplateSpecializationType>(Arg)) {
346 // Perform template argument deduction for the template name.
347 if (!DeduceTemplateArguments(Context,
348 SpecParam->getTemplateName(),
349 SpecArg->getTemplateName(),
350 Deduced))
351 return false;
352
353 unsigned NumArgs = SpecParam->getNumArgs();
354
355 // FIXME: When one of the template-names refers to a
356 // declaration with default template arguments, do we need to
357 // fill in those default template arguments here? Most likely,
358 // the answer is "yes", but I don't see any references. This
359 // issue may be resolved elsewhere, because we may want to
360 // instantiate default template arguments when
361 if (SpecArg->getNumArgs() != NumArgs)
362 return false;
363
364 // Perform template argument deduction on each template
365 // argument.
366 for (unsigned I = 0; I != NumArgs; ++I)
367 if (!DeduceTemplateArguments(Context,
368 SpecParam->getArg(I),
369 SpecArg->getArg(I),
370 Deduced))
371 return false;
372
373 return true;
374 }
375
376 // If the argument type is a class template specialization, we
377 // perform template argument deduction using its template
378 // arguments.
379 const RecordType *RecordArg = dyn_cast<RecordType>(Arg);
380 if (!RecordArg)
381 return false;
382
383 ClassTemplateSpecializationDecl *SpecArg
384 = dyn_cast<ClassTemplateSpecializationDecl>(RecordArg->getDecl());
385 if (!SpecArg)
386 return false;
387
388 // Perform template argument deduction for the template name.
389 if (!DeduceTemplateArguments(Context,
390 SpecParam->getTemplateName(),
391 TemplateName(SpecArg->getSpecializedTemplate()),
392 Deduced))
393 return false;
394
395 // FIXME: Can the # of arguments in the parameter and the argument differ?
396 unsigned NumArgs = SpecParam->getNumArgs();
397 const TemplateArgumentList &ArgArgs = SpecArg->getTemplateArgs();
398 if (NumArgs != ArgArgs.size())
399 return false;
400
401 for (unsigned I = 0; I != NumArgs; ++I)
402 if (!DeduceTemplateArguments(Context,
403 SpecParam->getArg(I),
404 ArgArgs.get(I),
405 Deduced))
406 return false;
Anders Carlsson8574e7f2009-06-08 15:19:08 +0000407
Douglas Gregor5069ae32009-06-09 16:35:58 +0000408 return true;
409 }
410
Douglas Gregor4ea653d2009-06-04 00:21:18 +0000411 default:
412 break;
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000413 }
414
415 // FIXME: Many more cases to go (to go).
416 return false;
417}
418
419static bool
420DeduceTemplateArguments(ASTContext &Context, const TemplateArgument &Param,
421 const TemplateArgument &Arg,
422 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000423 switch (Param.getKind()) {
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000424 case TemplateArgument::Null:
425 assert(false && "Null template argument in parameter list");
426 break;
427
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000428 case TemplateArgument::Type:
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000429 assert(Arg.getKind() == TemplateArgument::Type && "Type/value mismatch");
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000430 return DeduceTemplateArguments(Context, Param.getAsType(),
431 Arg.getAsType(), Deduced);
432
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000433 case TemplateArgument::Declaration:
434 // FIXME: Implement this check
435 assert(false && "Unimplemented template argument deduction case");
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000436 return false;
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000437
438 case TemplateArgument::Integral:
439 if (Arg.getKind() == TemplateArgument::Integral) {
440 // FIXME: Zero extension + sign checking here?
441 return *Param.getAsIntegral() == *Arg.getAsIntegral();
442 }
443 if (Arg.getKind() == TemplateArgument::Expression)
444 return false;
445
446 assert(false && "Type/value mismatch");
447 return false;
448
449 case TemplateArgument::Expression: {
450 if (NonTypeTemplateParmDecl *NTTP
451 = getDeducedParameterFromExpr(Param.getAsExpr())) {
452 if (Arg.getKind() == TemplateArgument::Integral)
453 // FIXME: Sign problems here
454 return DeduceNonTypeTemplateArgument(Context, NTTP,
455 *Arg.getAsIntegral(), Deduced);
456 if (Arg.getKind() == TemplateArgument::Expression)
457 return DeduceNonTypeTemplateArgument(Context, NTTP, Arg.getAsExpr(),
458 Deduced);
459
460 assert(false && "Type/value mismatch");
461 return false;
462 }
463
464 // Can't deduce anything, but that's okay.
465 return true;
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000466 }
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000467 }
468
469 return true;
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000470}
471
472static bool
473DeduceTemplateArguments(ASTContext &Context,
474 const TemplateArgumentList &ParamList,
475 const TemplateArgumentList &ArgList,
476 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
477 assert(ParamList.size() == ArgList.size());
478 for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
479 if (!DeduceTemplateArguments(Context, ParamList[I], ArgList[I], Deduced))
480 return false;
481 }
482 return true;
483}
484
485
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000486TemplateArgumentList *
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000487Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
488 const TemplateArgumentList &TemplateArgs) {
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000489 // Deduce the template arguments for the partial specialization
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000490 llvm::SmallVector<TemplateArgument, 4> Deduced;
491 Deduced.resize(Partial->getTemplateParameters()->size());
Douglas Gregorab9f71a2009-06-05 00:53:49 +0000492 if (! ::DeduceTemplateArguments(Context, Partial->getTemplateArgs(),
493 TemplateArgs, Deduced))
494 return 0;
495
496 // FIXME: Substitute the deduced template arguments into the template
497 // arguments of the class template partial specialization; the resulting
498 // template arguments should match TemplateArgs exactly.
499
500 for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
501 TemplateArgument &Arg = Deduced[I];
502
503 // FIXME: If this template argument was not deduced, but the corresponding
504 // template parameter has a default argument, instantiate the default
505 // argument.
506 if (Arg.isNull()) // FIXME: Result->Destroy(Context);
507 return 0;
508
509 if (Arg.getKind() == TemplateArgument::Integral) {
510 // FIXME: Instantiate the type, but we need some context!
511 const NonTypeTemplateParmDecl *Parm
512 = cast<NonTypeTemplateParmDecl>(Partial->getTemplateParameters()
513 ->getParam(I));
514 // QualType T = InstantiateType(Parm->getType(), *Result,
515 // Parm->getLocation(), Parm->getDeclName());
516 // if (T.isNull()) // FIXME: Result->Destroy(Context);
517 // return 0;
518 QualType T = Parm->getType();
519
520 // FIXME: Make sure we didn't overflow our data type!
521 llvm::APSInt &Value = *Arg.getAsIntegral();
522 unsigned AllowedBits = Context.getTypeSize(T);
523 if (Value.getBitWidth() != AllowedBits)
524 Value.extOrTrunc(AllowedBits);
525 Value.setIsSigned(T->isSignedIntegerType());
526 Arg.setIntegralType(T);
527 }
528 }
529
Anders Carlsson0233eb62009-06-05 04:47:51 +0000530 // FIXME: This is terrible. DeduceTemplateArguments should use a
531 // TemplateArgumentListBuilder directly.
Anders Carlsson558a3a32009-06-05 05:31:27 +0000532 TemplateArgumentListBuilder Builder(Context);
Anders Carlsson0233eb62009-06-05 04:47:51 +0000533 for (unsigned I = 0, N = Deduced.size(); I != N; ++I)
534 Builder.push_back(Deduced[I]);
535
536 return new (Context) TemplateArgumentList(Context, Builder, /*CopyArgs=*/true,
537 /*FlattenArgs=*/true);
Douglas Gregorbf23a8a2009-06-04 00:03:07 +0000538}