blob: 97fd2ed5f40b5f7e85846559cd5863df42a4e62c [file] [log] [blame]
Douglas Gregor8dbc2692009-03-17 21:15:40 +00001//===--- SemaTemplateInstantiateDecl.cpp - C++ Template Decl Instantiation ===/
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 instantiation for declarations.
10//
11//===----------------------------------------------------------------------===/
12#include "Sema.h"
13#include "clang/AST/ASTContext.h"
14#include "clang/AST/DeclTemplate.h"
15#include "clang/AST/DeclVisitor.h"
16#include "clang/AST/Expr.h"
17#include "llvm/Support/Compiler.h"
18
19using namespace clang;
20
21namespace {
22 class VISIBILITY_HIDDEN TemplateDeclInstantiator
23 : public DeclVisitor<TemplateDeclInstantiator, Decl *>
24 {
25 Sema &SemaRef;
26 DeclContext *Owner;
27 const TemplateArgument *TemplateArgs;
28 unsigned NumTemplateArgs;
29
30 public:
31 typedef Sema::OwningExprResult OwningExprResult;
32
33 TemplateDeclInstantiator(Sema &SemaRef, DeclContext *Owner,
34 const TemplateArgument *TemplateArgs,
35 unsigned NumTemplateArgs)
36 : SemaRef(SemaRef), Owner(Owner), TemplateArgs(TemplateArgs),
37 NumTemplateArgs(NumTemplateArgs) { }
38
39 // FIXME: Once we get closer to completion, replace these
40 // manually-written declarations with automatically-generated ones
41 // from clang/AST/DeclNodes.def.
42 Decl *VisitTypedefDecl(TypedefDecl *D);
43 Decl *VisitFieldDecl(FieldDecl *D);
44 Decl *VisitStaticAssertDecl(StaticAssertDecl *D);
45 Decl *VisitEnumDecl(EnumDecl *D);
Douglas Gregor2dc0e642009-03-23 23:06:20 +000046 Decl *VisitCXXMethodDecl(CXXMethodDecl *D);
Douglas Gregor615c5d42009-03-24 16:43:20 +000047 Decl *VisitCXXConstructorDecl(CXXConstructorDecl *D);
Douglas Gregor03b2b072009-03-24 00:15:49 +000048 Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D);
Douglas Gregorbb969ed2009-03-25 00:34:44 +000049 Decl *VisitCXXConversionDecl(CXXConversionDecl *D);
Douglas Gregor2dc0e642009-03-23 23:06:20 +000050 Decl *VisitParmVarDecl(ParmVarDecl *D);
51 Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D);
Douglas Gregor5545e162009-03-24 00:38:23 +000052
Douglas Gregor8dbc2692009-03-17 21:15:40 +000053 // Base case. FIXME: Remove once we can instantiate everything.
54 Decl *VisitDecl(Decl *) {
55 return 0;
56 }
Douglas Gregor5545e162009-03-24 00:38:23 +000057
58 // Helper functions for instantiating methods.
59 QualType InstantiateFunctionType(FunctionDecl *D,
60 llvm::SmallVectorImpl<ParmVarDecl *> &Params);
61 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl);
Douglas Gregor8dbc2692009-03-17 21:15:40 +000062 };
63}
64
65Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
66 bool Invalid = false;
67 QualType T = D->getUnderlyingType();
68 if (T->isDependentType()) {
69 T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
70 D->getLocation(),
71 D->getDeclName());
72 if (T.isNull()) {
73 Invalid = true;
74 T = SemaRef.Context.IntTy;
75 }
76 }
77
78 // Create the new typedef
79 TypedefDecl *Typedef
80 = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(),
81 D->getIdentifier(), T);
82 if (Invalid)
83 Typedef->setInvalidDecl();
84
85 Owner->addDecl(Typedef);
86 return Typedef;
87}
88
89Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) {
90 bool Invalid = false;
91 QualType T = D->getType();
92 if (T->isDependentType()) {
93 T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs,
94 D->getLocation(),
95 D->getDeclName());
96 if (!T.isNull() && T->isFunctionType()) {
97 // C++ [temp.arg.type]p3:
98 // If a declaration acquires a function type through a type
99 // dependent on a template-parameter and this causes a
100 // declaration that does not use the syntactic form of a
101 // function declarator to have function type, the program is
102 // ill-formed.
103 SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function)
104 << T;
105 T = QualType();
106 Invalid = true;
107 }
108 }
109
110 Expr *BitWidth = D->getBitWidth();
111 if (Invalid)
112 BitWidth = 0;
113 else if (BitWidth) {
114 OwningExprResult InstantiatedBitWidth
115 = SemaRef.InstantiateExpr(BitWidth, TemplateArgs, NumTemplateArgs);
116 if (InstantiatedBitWidth.isInvalid()) {
117 Invalid = true;
118 BitWidth = 0;
119 } else
120 BitWidth = (Expr *)InstantiatedBitWidth.release();
121 }
122
123 FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), T,
124 cast<RecordDecl>(Owner),
125 D->getLocation(),
126 D->isMutable(),
127 BitWidth,
128 D->getAccess(),
129 0);
130 if (Field) {
131 if (Invalid)
132 Field->setInvalidDecl();
133
134 Owner->addDecl(Field);
135 }
136
137 return Field;
138}
139
140Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) {
141 Expr *AssertExpr = D->getAssertExpr();
142
143 OwningExprResult InstantiatedAssertExpr
144 = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs, NumTemplateArgs);
145 if (InstantiatedAssertExpr.isInvalid())
146 return 0;
147
148 OwningExprResult Message = SemaRef.Clone(D->getMessage());
149 Decl *StaticAssert
150 = (Decl *)SemaRef.ActOnStaticAssertDeclaration(D->getLocation(),
151 move(InstantiatedAssertExpr),
152 move(Message));
153 return StaticAssert;
154}
155
156Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
157 EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner,
158 D->getLocation(), D->getIdentifier(),
159 /*PrevDecl=*/0);
160 Owner->addDecl(Enum);
161 Enum->startDefinition();
162
163 llvm::SmallVector<Sema::DeclTy *, 16> Enumerators;
164
165 EnumConstantDecl *LastEnumConst = 0;
166 for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(),
167 ECEnd = D->enumerator_end();
168 EC != ECEnd; ++EC) {
169 // The specified value for the enumerator.
170 OwningExprResult Value = SemaRef.Owned((Expr *)0);
171 if (Expr *UninstValue = EC->getInitExpr())
172 Value = SemaRef.InstantiateExpr(UninstValue,
173 TemplateArgs, NumTemplateArgs);
174
175 // Drop the initial value and continue.
176 bool isInvalid = false;
177 if (Value.isInvalid()) {
178 Value = SemaRef.Owned((Expr *)0);
179 isInvalid = true;
180 }
181
182 EnumConstantDecl *EnumConst
183 = SemaRef.CheckEnumConstant(Enum, LastEnumConst,
184 EC->getLocation(), EC->getIdentifier(),
185 move(Value));
186
187 if (isInvalid) {
188 if (EnumConst)
189 EnumConst->setInvalidDecl();
190 Enum->setInvalidDecl();
191 }
192
193 if (EnumConst) {
194 Enum->addDecl(EnumConst);
195 Enumerators.push_back(EnumConst);
196 LastEnumConst = EnumConst;
197 }
198 }
199
200 SemaRef.ActOnEnumBody(Enum->getLocation(), Enum,
201 &Enumerators[0], Enumerators.size());
202
203 return Enum;
204}
205
Douglas Gregor2dc0e642009-03-23 23:06:20 +0000206Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) {
207 // Only handle actual methods; we'll deal with constructors,
208 // destructors, etc. separately.
209 if (D->getKind() != Decl::CXXMethod)
210 return 0;
211
Douglas Gregor5545e162009-03-24 00:38:23 +0000212 llvm::SmallVector<ParmVarDecl *, 16> Params;
213 QualType T = InstantiateFunctionType(D, Params);
Douglas Gregor2dc0e642009-03-23 23:06:20 +0000214 if (T.isNull())
215 return 0;
216
217 // Build the instantiated method declaration.
218 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
219 CXXMethodDecl *Method
220 = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(),
221 D->getDeclName(), T, D->isStatic(),
222 D->isInline());
Douglas Gregor2dc0e642009-03-23 23:06:20 +0000223
Douglas Gregor5545e162009-03-24 00:38:23 +0000224 // Attach the parameters
225 for (unsigned P = 0; P < Params.size(); ++P)
226 Params[P]->setOwningFunction(Method);
227 Method->setParams(SemaRef.Context, &Params[0], Params.size());
228
229 if (InitMethodInstantiation(Method, D))
230 Method->setInvalidDecl();
Douglas Gregor2dc0e642009-03-23 23:06:20 +0000231
232 NamedDecl *PrevDecl
233 = SemaRef.LookupQualifiedName(Owner, Method->getDeclName(),
234 Sema::LookupOrdinaryName, true);
235 // In C++, the previous declaration we find might be a tag type
236 // (class or enum). In this case, the new declaration will hide the
237 // tag type. Note that this does does not apply if we're declaring a
238 // typedef (C++ [dcl.typedef]p4).
239 if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
240 PrevDecl = 0;
241 bool Redeclaration = false;
242 bool OverloadableAttrRequired = false;
243 if (SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration,
244 /*FIXME:*/OverloadableAttrRequired))
245 Method->setInvalidDecl();
246
247 if (!Method->isInvalidDecl() || !PrevDecl)
248 Owner->addDecl(Method);
249 return Method;
250}
251
Douglas Gregor615c5d42009-03-24 16:43:20 +0000252Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) {
253 llvm::SmallVector<ParmVarDecl *, 16> Params;
254 QualType T = InstantiateFunctionType(D, Params);
255 if (T.isNull())
256 return 0;
257
258 // Build the instantiated method declaration.
259 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
260 QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
261 DeclarationName Name
262 = SemaRef.Context.DeclarationNames.getCXXConstructorName(ClassTy);
263 CXXConstructorDecl *Constructor
264 = CXXConstructorDecl::Create(SemaRef.Context, Record, D->getLocation(),
265 Name, T, D->isExplicit(), D->isInline(),
266 false);
267
268 // Attach the parameters
269 for (unsigned P = 0; P < Params.size(); ++P)
270 Params[P]->setOwningFunction(Constructor);
271 Constructor->setParams(SemaRef.Context, &Params[0], Params.size());
272
273 if (InitMethodInstantiation(Constructor, D))
274 Constructor->setInvalidDecl();
275
276 NamedDecl *PrevDecl
277 = SemaRef.LookupQualifiedName(Owner, Name, Sema::LookupOrdinaryName, true);
278
279 // In C++, the previous declaration we find might be a tag type
280 // (class or enum). In this case, the new declaration will hide the
281 // tag type. Note that this does does not apply if we're declaring a
282 // typedef (C++ [dcl.typedef]p4).
283 if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
284 PrevDecl = 0;
285 bool Redeclaration = false;
286 bool OverloadableAttrRequired = false;
287 if (SemaRef.CheckFunctionDeclaration(Constructor, PrevDecl, Redeclaration,
288 /*FIXME:*/OverloadableAttrRequired))
289 Constructor->setInvalidDecl();
290
291 if (!Constructor->isInvalidDecl())
292 Owner->addDecl(Constructor);
293 return Constructor;
294}
295
Douglas Gregor03b2b072009-03-24 00:15:49 +0000296Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) {
Douglas Gregor5545e162009-03-24 00:38:23 +0000297 llvm::SmallVector<ParmVarDecl *, 16> Params;
298 QualType T = InstantiateFunctionType(D, Params);
Douglas Gregor03b2b072009-03-24 00:15:49 +0000299 if (T.isNull())
300 return 0;
Douglas Gregor5545e162009-03-24 00:38:23 +0000301 assert(Params.size() == 0 && "Destructor with parameters?");
302
Douglas Gregor03b2b072009-03-24 00:15:49 +0000303 // Build the instantiated destructor declaration.
304 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
305 QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
306 CXXDestructorDecl *Destructor
307 = CXXDestructorDecl::Create(SemaRef.Context, Record,
308 D->getLocation(),
309 SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy),
310 T, D->isInline(), false);
Douglas Gregor5545e162009-03-24 00:38:23 +0000311 if (InitMethodInstantiation(Destructor, D))
312 Destructor->setInvalidDecl();
Douglas Gregor03b2b072009-03-24 00:15:49 +0000313
314 bool Redeclaration = false;
315 bool OverloadableAttrRequired = false;
316 NamedDecl *PrevDecl = 0;
317 if (SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration,
318 /*FIXME:*/OverloadableAttrRequired))
319 Destructor->setInvalidDecl();
320 Owner->addDecl(Destructor);
321 return Destructor;
322}
323
Douglas Gregorbb969ed2009-03-25 00:34:44 +0000324Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) {
325 llvm::SmallVector<ParmVarDecl *, 16> Params;
326 QualType T = InstantiateFunctionType(D, Params);
327 if (T.isNull())
328 return 0;
329 assert(Params.size() == 0 && "Destructor with parameters?");
330
331 // Build the instantiated conversion declaration.
332 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
333 QualType ClassTy = SemaRef.Context.getTypeDeclType(Record);
334 QualType ConvTy
335 = SemaRef.Context.getCanonicalType(T->getAsFunctionType()->getResultType());
336 CXXConversionDecl *Conversion
337 = CXXConversionDecl::Create(SemaRef.Context, Record,
338 D->getLocation(),
339 SemaRef.Context.DeclarationNames.getCXXConversionFunctionName(ConvTy),
340 T, D->isInline(), D->isExplicit());
341 if (InitMethodInstantiation(Conversion, D))
342 Conversion->setInvalidDecl();
343
344 bool Redeclaration = false;
345 bool OverloadableAttrRequired = false;
346 NamedDecl *PrevDecl = 0;
347 if (SemaRef.CheckFunctionDeclaration(Conversion, PrevDecl, Redeclaration,
348 /*FIXME:*/OverloadableAttrRequired))
349 Conversion->setInvalidDecl();
350 Owner->addDecl(Conversion);
351 return Conversion;
352}
353
Douglas Gregor2dc0e642009-03-23 23:06:20 +0000354Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) {
355 QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs,
356 NumTemplateArgs, D->getLocation(),
357 D->getDeclName());
358 if (OrigT.isNull())
359 return 0;
360
361 QualType T = SemaRef.adjustParameterType(OrigT);
362
363 if (D->getDefaultArg()) {
364 // FIXME: Leave a marker for "uninstantiated" default
365 // arguments. They only get instantiated on demand at the call
366 // site.
367 unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning,
368 "sorry, dropping default argument during template instantiation");
369 SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID)
370 << D->getDefaultArg()->getSourceRange();
371 }
372
373 // Allocate the parameter
374 ParmVarDecl *Param = 0;
375 if (T == OrigT)
376 Param = ParmVarDecl::Create(SemaRef.Context, Owner, D->getLocation(),
377 D->getIdentifier(), T, D->getStorageClass(),
378 0);
379 else
380 Param = OriginalParmVarDecl::Create(SemaRef.Context, Owner,
381 D->getLocation(), D->getIdentifier(),
382 T, OrigT, D->getStorageClass(), 0);
383
384 // Note: we don't try to instantiate function parameters until after
385 // we've instantiated the function's type. Therefore, we don't have
386 // to check for 'void' parameter types here.
387 return Param;
388}
389
390Decl *
391TemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) {
392 // Since parameter types can decay either before or after
393 // instantiation, we simply treat OriginalParmVarDecls as
394 // ParmVarDecls the same way, and create one or the other depending
395 // on what happens after template instantiation.
396 return VisitParmVarDecl(D);
397}
398
Douglas Gregor8dbc2692009-03-17 21:15:40 +0000399Decl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner,
400 const TemplateArgument *TemplateArgs,
401 unsigned NumTemplateArgs) {
402 TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs,
403 NumTemplateArgs);
404 return Instantiator.Visit(D);
405}
406
Douglas Gregor5545e162009-03-24 00:38:23 +0000407/// \brief Instantiates the type of the given function, including
408/// instantiating all of the function parameters.
409///
410/// \param D The function that we will be instantiated
411///
412/// \param Params the instantiated parameter declarations
413
414/// \returns the instantiated function's type if successfull, a NULL
415/// type if there was an error.
416QualType
417TemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D,
418 llvm::SmallVectorImpl<ParmVarDecl *> &Params) {
419 bool InvalidDecl = false;
420
421 // Instantiate the function parameters
422 TemplateDeclInstantiator ParamInstantiator(SemaRef, 0,
423 TemplateArgs, NumTemplateArgs);
424 llvm::SmallVector<QualType, 16> ParamTys;
425 for (FunctionDecl::param_iterator P = D->param_begin(),
426 PEnd = D->param_end();
427 P != PEnd; ++P) {
428 if (ParmVarDecl *PInst = (ParmVarDecl *)ParamInstantiator.Visit(*P)) {
429 if (PInst->getType()->isVoidType()) {
430 SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type);
431 PInst->setInvalidDecl();
432 }
433 else if (SemaRef.RequireNonAbstractType(PInst->getLocation(),
434 PInst->getType(),
435 diag::err_abstract_type_in_decl,
Anders Carlsson8211eff2009-03-24 01:19:16 +0000436 Sema::AbstractParamType))
Douglas Gregor5545e162009-03-24 00:38:23 +0000437 PInst->setInvalidDecl();
438
439 Params.push_back(PInst);
440 ParamTys.push_back(PInst->getType());
441
442 if (PInst->isInvalidDecl())
443 InvalidDecl = true;
444 } else
445 InvalidDecl = true;
446 }
447
448 // FIXME: Deallocate dead declarations.
449 if (InvalidDecl)
450 return QualType();
451
452 const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType();
453 assert(Proto && "Missing prototype?");
454 QualType ResultType
455 = SemaRef.InstantiateType(Proto->getResultType(),
456 TemplateArgs, NumTemplateArgs,
457 D->getLocation(), D->getDeclName());
458 if (ResultType.isNull())
459 return QualType();
460
461 return SemaRef.BuildFunctionType(ResultType, &ParamTys[0], ParamTys.size(),
462 Proto->isVariadic(), Proto->getTypeQuals(),
463 D->getLocation(), D->getDeclName());
464}
465
466/// \brief Initializes common fields of an instantiated method
467/// declaration (New) from the corresponding fields of its template
468/// (Tmpl).
469///
470/// \returns true if there was an error
471bool
472TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New,
473 CXXMethodDecl *Tmpl) {
474 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner);
475 New->setAccess(Tmpl->getAccess());
476 if (Tmpl->isVirtual()) {
477 New->setVirtual();
478 Record->setAggregate(false);
479 Record->setPOD(false);
480 Record->setPolymorphic(true);
481 }
482 if (Tmpl->isDeleted())
483 New->setDeleted();
484 if (Tmpl->isPure()) {
485 New->setPure();
486 Record->setAbstract(true);
487 }
488
489 // FIXME: attributes
490 // FIXME: New needs a pointer to Tmpl
491 return false;
492}