blob: 0bef27c7261d8ee531de2c1b2957537d7a25752c [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 Gregord708c722009-06-09 16:35:58 +000023static bool
24DeduceTemplateArguments(ASTContext &Context, const TemplateArgument &Param,
25 const TemplateArgument &Arg,
26 llvm::SmallVectorImpl<TemplateArgument> &Deduced);
27
Douglas Gregor199d9912009-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 Gregord708c722009-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 Gregor0b9247f2009-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 Gregor199d9912009-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 Gregor0b9247f2009-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 Gregord560d502009-06-04 00:21:18 +0000178 switch (Param->getTypeClass()) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000179 // No deduction possible for these types
180 case Type::Builtin:
181 return false;
182
183
184 // T *
Douglas Gregord560d502009-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 Gregor199d9912009-06-05 00:53:49 +0000196 // T &
Douglas Gregord560d502009-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 Gregor0b9247f2009-06-04 00:03:07 +0000207
Douglas Gregor199d9912009-06-05 00:53:49 +0000208 // T && [C++0x]
Douglas Gregord560d502009-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 Gregor199d9912009-06-05 00:53:49 +0000220 // T [] (implied, but not stated explicitly)
Anders Carlsson4d6fb502009-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 Gregor199d9912009-06-05 00:53:49 +0000232
233 // T [integer-constant]
Anders Carlsson4d6fb502009-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 Gregor199d9912009-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 Gregor0fce0ae2009-06-08 15:59:14 +0000291 // type(*)(T)
292 // T(*)()
293 // T(*)(T)
Anders Carlssona27fad52009-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 Carlsson994b6cb2009-06-08 19:22:23 +0000302
303 if (FunctionProtoParam->getTypeQuals() !=
304 FunctionProtoArg->getTypeQuals())
305 return false;
Anders Carlssona27fad52009-06-08 15:19:08 +0000306
Anders Carlsson994b6cb2009-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 Carlssona27fad52009-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 Carlssona27fad52009-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 Gregord708c722009-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 Carlssona27fad52009-06-08 15:19:08 +0000407
Douglas Gregord708c722009-06-09 16:35:58 +0000408 return true;
409 }
410
Douglas Gregor637a4092009-06-10 23:47:09 +0000411 // T type::*
412 // T T::*
413 // T (type::*)()
414 // type (T::*)()
415 // type (type::*)(T)
416 // type (T::*)(T)
417 // T (type::*)(T)
418 // T (T::*)()
419 // T (T::*)(T)
420 case Type::MemberPointer: {
421 const MemberPointerType *MemPtrParam = cast<MemberPointerType>(Param);
422 const MemberPointerType *MemPtrArg = dyn_cast<MemberPointerType>(Arg);
423 if (!MemPtrArg)
424 return false;
425
426 return DeduceTemplateArguments(Context,
427 MemPtrParam->getPointeeType(),
428 MemPtrArg->getPointeeType(),
429 Deduced) &&
430 DeduceTemplateArguments(Context,
431 QualType(MemPtrParam->getClass(), 0),
432 QualType(MemPtrArg->getClass(), 0),
433 Deduced);
434 }
435
Anders Carlsson859ba502009-06-12 16:23:10 +0000436 // type(^)(T)
437 // T(^)()
438 // T(^)(T)
439 case Type::BlockPointer: {
440 const BlockPointerType *BlockPtrParam = cast<BlockPointerType>(Param);
441 const BlockPointerType *BlockPtrArg = dyn_cast<BlockPointerType>(Arg);
442
443 if (!BlockPtrArg)
444 return false;
445
446 return DeduceTemplateArguments(Context,
447 BlockPtrParam->getPointeeType(),
448 BlockPtrArg->getPointeeType(), Deduced);
449 }
450
Douglas Gregor637a4092009-06-10 23:47:09 +0000451 case Type::TypeOfExpr:
452 case Type::TypeOf:
453 case Type::Typename:
454 // No template argument deduction for these types
455 return true;
456
Douglas Gregord560d502009-06-04 00:21:18 +0000457 default:
458 break;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000459 }
460
461 // FIXME: Many more cases to go (to go).
462 return false;
463}
464
465static bool
466DeduceTemplateArguments(ASTContext &Context, const TemplateArgument &Param,
467 const TemplateArgument &Arg,
468 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000469 switch (Param.getKind()) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000470 case TemplateArgument::Null:
471 assert(false && "Null template argument in parameter list");
472 break;
473
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000474 case TemplateArgument::Type:
Douglas Gregor199d9912009-06-05 00:53:49 +0000475 assert(Arg.getKind() == TemplateArgument::Type && "Type/value mismatch");
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000476 return DeduceTemplateArguments(Context, Param.getAsType(),
477 Arg.getAsType(), Deduced);
478
Douglas Gregor199d9912009-06-05 00:53:49 +0000479 case TemplateArgument::Declaration:
480 // FIXME: Implement this check
481 assert(false && "Unimplemented template argument deduction case");
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000482 return false;
Douglas Gregor199d9912009-06-05 00:53:49 +0000483
484 case TemplateArgument::Integral:
485 if (Arg.getKind() == TemplateArgument::Integral) {
486 // FIXME: Zero extension + sign checking here?
487 return *Param.getAsIntegral() == *Arg.getAsIntegral();
488 }
489 if (Arg.getKind() == TemplateArgument::Expression)
490 return false;
491
492 assert(false && "Type/value mismatch");
493 return false;
494
495 case TemplateArgument::Expression: {
496 if (NonTypeTemplateParmDecl *NTTP
497 = getDeducedParameterFromExpr(Param.getAsExpr())) {
498 if (Arg.getKind() == TemplateArgument::Integral)
499 // FIXME: Sign problems here
500 return DeduceNonTypeTemplateArgument(Context, NTTP,
501 *Arg.getAsIntegral(), Deduced);
502 if (Arg.getKind() == TemplateArgument::Expression)
503 return DeduceNonTypeTemplateArgument(Context, NTTP, Arg.getAsExpr(),
504 Deduced);
505
506 assert(false && "Type/value mismatch");
507 return false;
508 }
509
510 // Can't deduce anything, but that's okay.
511 return true;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000512 }
Douglas Gregor199d9912009-06-05 00:53:49 +0000513 }
514
515 return true;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000516}
517
518static bool
519DeduceTemplateArguments(ASTContext &Context,
520 const TemplateArgumentList &ParamList,
521 const TemplateArgumentList &ArgList,
522 llvm::SmallVectorImpl<TemplateArgument> &Deduced) {
523 assert(ParamList.size() == ArgList.size());
524 for (unsigned I = 0, N = ParamList.size(); I != N; ++I) {
525 if (!DeduceTemplateArguments(Context, ParamList[I], ArgList[I], Deduced))
526 return false;
527 }
528 return true;
529}
530
531
Douglas Gregor199d9912009-06-05 00:53:49 +0000532TemplateArgumentList *
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000533Sema::DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial,
534 const TemplateArgumentList &TemplateArgs) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000535 // Deduce the template arguments for the partial specialization
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000536 llvm::SmallVector<TemplateArgument, 4> Deduced;
537 Deduced.resize(Partial->getTemplateParameters()->size());
Douglas Gregor199d9912009-06-05 00:53:49 +0000538 if (! ::DeduceTemplateArguments(Context, Partial->getTemplateArgs(),
539 TemplateArgs, Deduced))
540 return 0;
Douglas Gregor637a4092009-06-10 23:47:09 +0000541
542 // FIXME: It isn't clear whether we want the diagnostic to point at
543 // the partial specialization itself or at the actual point of
544 // instantiation.
545 InstantiatingTemplate Inst(*this, Partial->getLocation(), Partial,
546 Deduced.data(), Deduced.size());
547 if (Inst)
548 return 0;
Douglas Gregor199d9912009-06-05 00:53:49 +0000549
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000550 // C++ [temp.deduct.type]p2:
551 // [...] or if any template argument remains neither deduced nor
552 // explicitly specified, template argument deduction fails.
553 TemplateArgumentListBuilder Builder(Context);
554 for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
555 if (Deduced[I].isNull())
Douglas Gregor199d9912009-06-05 00:53:49 +0000556 return 0;
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000557
558 Builder.push_back(Deduced[I]);
559 }
560
561 // Form the template argument list from the deduced template arguments.
562 TemplateArgumentList *DeducedArgumentList
563 = new (Context) TemplateArgumentList(Context, Builder, /*CopyArgs=*/true,
564 /*FlattenArgs=*/true);
565
566 // Now that we have all of the deduced template arguments, take
567 // another pass through them to convert any integral template
568 // arguments to the appropriate type.
569 for (unsigned I = 0, N = Deduced.size(); I != N; ++I) {
570 TemplateArgument &Arg = Deduced[I];
Douglas Gregor199d9912009-06-05 00:53:49 +0000571 if (Arg.getKind() == TemplateArgument::Integral) {
Douglas Gregor199d9912009-06-05 00:53:49 +0000572 const NonTypeTemplateParmDecl *Parm
573 = cast<NonTypeTemplateParmDecl>(Partial->getTemplateParameters()
574 ->getParam(I));
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000575 QualType T = InstantiateType(Parm->getType(), *DeducedArgumentList,
576 Parm->getLocation(), Parm->getDeclName());
577 if (T.isNull()) // FIXME: DeducedArgumentList->Destroy(Context);
578 return 0;
Douglas Gregor199d9912009-06-05 00:53:49 +0000579
580 // FIXME: Make sure we didn't overflow our data type!
581 llvm::APSInt &Value = *Arg.getAsIntegral();
582 unsigned AllowedBits = Context.getTypeSize(T);
583 if (Value.getBitWidth() != AllowedBits)
584 Value.extOrTrunc(AllowedBits);
585 Value.setIsSigned(T->isSignedIntegerType());
586 Arg.setIntegralType(T);
587 }
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000588
589 (*DeducedArgumentList)[I] = Arg;
Douglas Gregor199d9912009-06-05 00:53:49 +0000590 }
Douglas Gregor02cbbd22009-06-11 18:10:32 +0000591
592 // Substitute the deduced template arguments into the template
593 // arguments of the class template partial specialization, and
594 // verify that the instantiated template arguments are both valid
595 // and are equivalent to the template arguments originally provided
596 // to the class template.
597 ClassTemplateDecl *ClassTemplate = Partial->getSpecializedTemplate();
598 const TemplateArgumentList &PartialTemplateArgs = Partial->getTemplateArgs();
599 for (unsigned I = 0, N = PartialTemplateArgs.flat_size(); I != N; ++I) {
600 TemplateArgument InstArg = Instantiate(PartialTemplateArgs[I],
601 *DeducedArgumentList);
602 if (InstArg.isNull()) {
603 // FIXME: DeducedArgumentList->Destroy(Context); (or use RAII)
604 return 0;
605 }
606
607 Decl *Param
608 = const_cast<Decl *>(ClassTemplate->getTemplateParameters()->getParam(I));
609 if (isa<TemplateTypeParmDecl>(Param)) {
610 if (InstArg.getKind() != TemplateArgument::Type ||
611 Context.getCanonicalType(InstArg.getAsType())
612 != Context.getCanonicalType(TemplateArgs[I].getAsType()))
613 // FIXME: DeducedArgumentList->Destroy(Context); (or use RAII)
614 return 0;
615 } else if (NonTypeTemplateParmDecl *NTTP
616 = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
617 QualType T = InstantiateType(NTTP->getType(), TemplateArgs,
618 NTTP->getLocation(), NTTP->getDeclName());
619 if (T.isNull())
620 // FIXME: DeducedArgumentList->Destroy(Context); (or use RAII)
621 return 0;
622
623 if (InstArg.getKind() == TemplateArgument::Declaration ||
624 InstArg.getKind() == TemplateArgument::Expression) {
625 // Turn the template argument into an expression, so that we can
626 // perform type checking on it and convert it to the type of the
627 // non-type template parameter. FIXME: Will this expression be
628 // leaked? It's hard to tell, since our ownership model for
629 // expressions in template arguments is so poor.
630 Expr *E = 0;
631 if (InstArg.getKind() == TemplateArgument::Declaration) {
632 NamedDecl *D = cast<NamedDecl>(InstArg.getAsDecl());
633 QualType T = Context.OverloadTy;
634 if (ValueDecl *VD = dyn_cast<ValueDecl>(D))
635 T = VD->getType().getNonReferenceType();
636 E = new (Context) DeclRefExpr(D, T, InstArg.getLocation());
637 } else {
638 E = InstArg.getAsExpr();
639 }
640
641 // Check that the template argument can be used to initialize
642 // the corresponding template parameter.
643 if (CheckTemplateArgument(NTTP, T, E, InstArg))
644 return 0;
645 }
646
647 switch (InstArg.getKind()) {
648 case TemplateArgument::Null:
649 assert(false && "Null template arguments cannot get here");
650 return 0;
651
652 case TemplateArgument::Type:
653 assert(false && "Type/value mismatch");
654 return 0;
655
656 case TemplateArgument::Integral: {
657 llvm::APSInt &Value = *InstArg.getAsIntegral();
658 if (T->isIntegralType() || T->isEnumeralType()) {
659 QualType IntegerType = Context.getCanonicalType(T);
660 if (const EnumType *Enum = dyn_cast<EnumType>(IntegerType))
661 IntegerType = Context.getCanonicalType(
662 Enum->getDecl()->getIntegerType());
663
664 // Check that an unsigned parameter does not receive a negative
665 // value.
666 if (IntegerType->isUnsignedIntegerType()
667 && (Value.isSigned() && Value.isNegative()))
668 return 0;
669
670 // Check for truncation. If the number of bits in the
671 // instantiated template argument exceeds what is allowed by
672 // the type, template argument deduction fails.
673 unsigned AllowedBits = Context.getTypeSize(IntegerType);
674 if (Value.getActiveBits() > AllowedBits)
675 return 0;
676
677 if (Value.getBitWidth() != AllowedBits)
678 Value.extOrTrunc(AllowedBits);
679 Value.setIsSigned(IntegerType->isSignedIntegerType());
680
681 // Check that the instantiated value is the same as the
682 // value provided as a template argument.
683 if (Value != *TemplateArgs[I].getAsIntegral())
684 return 0;
685 } else if (T->isPointerType() || T->isMemberPointerType()) {
686 // Deal with NULL pointers that are used to initialize
687 // pointer and pointer-to-member non-type template
688 // parameters (C++0x).
689 if (TemplateArgs[I].getAsDecl())
690 return 0; // Not a NULL declaration
691
692 // Check that the integral value is 0, the NULL pointer
693 // constant.
694 if (Value != 0)
695 return 0;
696 } else
697 return 0;
698 break;
699 }
700
701 case TemplateArgument::Declaration:
702 if (Context.getCanonicalDecl(InstArg.getAsDecl())
703 != Context.getCanonicalDecl(TemplateArgs[I].getAsDecl()))
704 return 0;
705 break;
706
707 case TemplateArgument::Expression:
708 // FIXME: Check equality of expressions
709 break;
710 }
711 } else {
712 assert(isa<TemplateTemplateParmDecl>(Param));
713 // FIXME: Check template template arguments
714 }
715 }
716
717 return DeducedArgumentList;
Douglas Gregor0b9247f2009-06-04 00:03:07 +0000718}