SemaTemplateInstantiateDecl.cpp revision 5545e166a956a20d7a6b58408e251a1119025485
1//===--- 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); 46 Decl *VisitCXXMethodDecl(CXXMethodDecl *D); 47 Decl *VisitCXXDestructorDecl(CXXDestructorDecl *D); 48 Decl *VisitParmVarDecl(ParmVarDecl *D); 49 Decl *VisitOriginalParmVarDecl(OriginalParmVarDecl *D); 50 51 // Base case. FIXME: Remove once we can instantiate everything. 52 Decl *VisitDecl(Decl *) { 53 return 0; 54 } 55 56 // Helper functions for instantiating methods. 57 QualType InstantiateFunctionType(FunctionDecl *D, 58 llvm::SmallVectorImpl<ParmVarDecl *> &Params); 59 bool InitMethodInstantiation(CXXMethodDecl *New, CXXMethodDecl *Tmpl); 60 }; 61} 62 63Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) { 64 bool Invalid = false; 65 QualType T = D->getUnderlyingType(); 66 if (T->isDependentType()) { 67 T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs, 68 D->getLocation(), 69 D->getDeclName()); 70 if (T.isNull()) { 71 Invalid = true; 72 T = SemaRef.Context.IntTy; 73 } 74 } 75 76 // Create the new typedef 77 TypedefDecl *Typedef 78 = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocation(), 79 D->getIdentifier(), T); 80 if (Invalid) 81 Typedef->setInvalidDecl(); 82 83 Owner->addDecl(Typedef); 84 return Typedef; 85} 86 87Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { 88 bool Invalid = false; 89 QualType T = D->getType(); 90 if (T->isDependentType()) { 91 T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs, 92 D->getLocation(), 93 D->getDeclName()); 94 if (!T.isNull() && T->isFunctionType()) { 95 // C++ [temp.arg.type]p3: 96 // If a declaration acquires a function type through a type 97 // dependent on a template-parameter and this causes a 98 // declaration that does not use the syntactic form of a 99 // function declarator to have function type, the program is 100 // ill-formed. 101 SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function) 102 << T; 103 T = QualType(); 104 Invalid = true; 105 } 106 } 107 108 Expr *BitWidth = D->getBitWidth(); 109 if (Invalid) 110 BitWidth = 0; 111 else if (BitWidth) { 112 OwningExprResult InstantiatedBitWidth 113 = SemaRef.InstantiateExpr(BitWidth, TemplateArgs, NumTemplateArgs); 114 if (InstantiatedBitWidth.isInvalid()) { 115 Invalid = true; 116 BitWidth = 0; 117 } else 118 BitWidth = (Expr *)InstantiatedBitWidth.release(); 119 } 120 121 FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), T, 122 cast<RecordDecl>(Owner), 123 D->getLocation(), 124 D->isMutable(), 125 BitWidth, 126 D->getAccess(), 127 0); 128 if (Field) { 129 if (Invalid) 130 Field->setInvalidDecl(); 131 132 Owner->addDecl(Field); 133 } 134 135 return Field; 136} 137 138Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) { 139 Expr *AssertExpr = D->getAssertExpr(); 140 141 OwningExprResult InstantiatedAssertExpr 142 = SemaRef.InstantiateExpr(AssertExpr, TemplateArgs, NumTemplateArgs); 143 if (InstantiatedAssertExpr.isInvalid()) 144 return 0; 145 146 OwningExprResult Message = SemaRef.Clone(D->getMessage()); 147 Decl *StaticAssert 148 = (Decl *)SemaRef.ActOnStaticAssertDeclaration(D->getLocation(), 149 move(InstantiatedAssertExpr), 150 move(Message)); 151 return StaticAssert; 152} 153 154Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { 155 EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner, 156 D->getLocation(), D->getIdentifier(), 157 /*PrevDecl=*/0); 158 Owner->addDecl(Enum); 159 Enum->startDefinition(); 160 161 llvm::SmallVector<Sema::DeclTy *, 16> Enumerators; 162 163 EnumConstantDecl *LastEnumConst = 0; 164 for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(), 165 ECEnd = D->enumerator_end(); 166 EC != ECEnd; ++EC) { 167 // The specified value for the enumerator. 168 OwningExprResult Value = SemaRef.Owned((Expr *)0); 169 if (Expr *UninstValue = EC->getInitExpr()) 170 Value = SemaRef.InstantiateExpr(UninstValue, 171 TemplateArgs, NumTemplateArgs); 172 173 // Drop the initial value and continue. 174 bool isInvalid = false; 175 if (Value.isInvalid()) { 176 Value = SemaRef.Owned((Expr *)0); 177 isInvalid = true; 178 } 179 180 EnumConstantDecl *EnumConst 181 = SemaRef.CheckEnumConstant(Enum, LastEnumConst, 182 EC->getLocation(), EC->getIdentifier(), 183 move(Value)); 184 185 if (isInvalid) { 186 if (EnumConst) 187 EnumConst->setInvalidDecl(); 188 Enum->setInvalidDecl(); 189 } 190 191 if (EnumConst) { 192 Enum->addDecl(EnumConst); 193 Enumerators.push_back(EnumConst); 194 LastEnumConst = EnumConst; 195 } 196 } 197 198 SemaRef.ActOnEnumBody(Enum->getLocation(), Enum, 199 &Enumerators[0], Enumerators.size()); 200 201 return Enum; 202} 203 204Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D) { 205 // Only handle actual methods; we'll deal with constructors, 206 // destructors, etc. separately. 207 if (D->getKind() != Decl::CXXMethod) 208 return 0; 209 210 llvm::SmallVector<ParmVarDecl *, 16> Params; 211 QualType T = InstantiateFunctionType(D, Params); 212 if (T.isNull()) 213 return 0; 214 215 // Build the instantiated method declaration. 216 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner); 217 CXXMethodDecl *Method 218 = CXXMethodDecl::Create(SemaRef.Context, Record, D->getLocation(), 219 D->getDeclName(), T, D->isStatic(), 220 D->isInline()); 221 222 // Attach the parameters 223 for (unsigned P = 0; P < Params.size(); ++P) 224 Params[P]->setOwningFunction(Method); 225 Method->setParams(SemaRef.Context, &Params[0], Params.size()); 226 227 if (InitMethodInstantiation(Method, D)) 228 Method->setInvalidDecl(); 229 230 NamedDecl *PrevDecl 231 = SemaRef.LookupQualifiedName(Owner, Method->getDeclName(), 232 Sema::LookupOrdinaryName, true); 233 // In C++, the previous declaration we find might be a tag type 234 // (class or enum). In this case, the new declaration will hide the 235 // tag type. Note that this does does not apply if we're declaring a 236 // typedef (C++ [dcl.typedef]p4). 237 if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag) 238 PrevDecl = 0; 239 bool Redeclaration = false; 240 bool OverloadableAttrRequired = false; 241 if (SemaRef.CheckFunctionDeclaration(Method, PrevDecl, Redeclaration, 242 /*FIXME:*/OverloadableAttrRequired)) 243 Method->setInvalidDecl(); 244 245 if (!Method->isInvalidDecl() || !PrevDecl) 246 Owner->addDecl(Method); 247 return Method; 248} 249 250Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) { 251 llvm::SmallVector<ParmVarDecl *, 16> Params; 252 QualType T = InstantiateFunctionType(D, Params); 253 if (T.isNull()) 254 return 0; 255 assert(Params.size() == 0 && "Destructor with parameters?"); 256 257 // Build the instantiated destructor declaration. 258 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner); 259 QualType ClassTy = SemaRef.Context.getTypeDeclType(Record); 260 CXXDestructorDecl *Destructor 261 = CXXDestructorDecl::Create(SemaRef.Context, Record, 262 D->getLocation(), 263 SemaRef.Context.DeclarationNames.getCXXDestructorName(ClassTy), 264 T, D->isInline(), false); 265 if (InitMethodInstantiation(Destructor, D)) 266 Destructor->setInvalidDecl(); 267 268 bool Redeclaration = false; 269 bool OverloadableAttrRequired = false; 270 NamedDecl *PrevDecl = 0; 271 if (SemaRef.CheckFunctionDeclaration(Destructor, PrevDecl, Redeclaration, 272 /*FIXME:*/OverloadableAttrRequired)) 273 Destructor->setInvalidDecl(); 274 Owner->addDecl(Destructor); 275 return Destructor; 276} 277 278Decl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { 279 QualType OrigT = SemaRef.InstantiateType(D->getOriginalType(), TemplateArgs, 280 NumTemplateArgs, D->getLocation(), 281 D->getDeclName()); 282 if (OrigT.isNull()) 283 return 0; 284 285 QualType T = SemaRef.adjustParameterType(OrigT); 286 287 if (D->getDefaultArg()) { 288 // FIXME: Leave a marker for "uninstantiated" default 289 // arguments. They only get instantiated on demand at the call 290 // site. 291 unsigned DiagID = SemaRef.Diags.getCustomDiagID(Diagnostic::Warning, 292 "sorry, dropping default argument during template instantiation"); 293 SemaRef.Diag(D->getDefaultArg()->getSourceRange().getBegin(), DiagID) 294 << D->getDefaultArg()->getSourceRange(); 295 } 296 297 // Allocate the parameter 298 ParmVarDecl *Param = 0; 299 if (T == OrigT) 300 Param = ParmVarDecl::Create(SemaRef.Context, Owner, D->getLocation(), 301 D->getIdentifier(), T, D->getStorageClass(), 302 0); 303 else 304 Param = OriginalParmVarDecl::Create(SemaRef.Context, Owner, 305 D->getLocation(), D->getIdentifier(), 306 T, OrigT, D->getStorageClass(), 0); 307 308 // Note: we don't try to instantiate function parameters until after 309 // we've instantiated the function's type. Therefore, we don't have 310 // to check for 'void' parameter types here. 311 return Param; 312} 313 314Decl * 315TemplateDeclInstantiator::VisitOriginalParmVarDecl(OriginalParmVarDecl *D) { 316 // Since parameter types can decay either before or after 317 // instantiation, we simply treat OriginalParmVarDecls as 318 // ParmVarDecls the same way, and create one or the other depending 319 // on what happens after template instantiation. 320 return VisitParmVarDecl(D); 321} 322 323Decl *Sema::InstantiateDecl(Decl *D, DeclContext *Owner, 324 const TemplateArgument *TemplateArgs, 325 unsigned NumTemplateArgs) { 326 TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs, 327 NumTemplateArgs); 328 return Instantiator.Visit(D); 329} 330 331/// \brief Instantiates the type of the given function, including 332/// instantiating all of the function parameters. 333/// 334/// \param D The function that we will be instantiated 335/// 336/// \param Params the instantiated parameter declarations 337 338/// \returns the instantiated function's type if successfull, a NULL 339/// type if there was an error. 340QualType 341TemplateDeclInstantiator::InstantiateFunctionType(FunctionDecl *D, 342 llvm::SmallVectorImpl<ParmVarDecl *> &Params) { 343 bool InvalidDecl = false; 344 345 // Instantiate the function parameters 346 TemplateDeclInstantiator ParamInstantiator(SemaRef, 0, 347 TemplateArgs, NumTemplateArgs); 348 llvm::SmallVector<QualType, 16> ParamTys; 349 for (FunctionDecl::param_iterator P = D->param_begin(), 350 PEnd = D->param_end(); 351 P != PEnd; ++P) { 352 if (ParmVarDecl *PInst = (ParmVarDecl *)ParamInstantiator.Visit(*P)) { 353 if (PInst->getType()->isVoidType()) { 354 SemaRef.Diag(PInst->getLocation(), diag::err_param_with_void_type); 355 PInst->setInvalidDecl(); 356 } 357 else if (SemaRef.RequireNonAbstractType(PInst->getLocation(), 358 PInst->getType(), 359 diag::err_abstract_type_in_decl, 360 1 /* parameter type */)) 361 PInst->setInvalidDecl(); 362 363 Params.push_back(PInst); 364 ParamTys.push_back(PInst->getType()); 365 366 if (PInst->isInvalidDecl()) 367 InvalidDecl = true; 368 } else 369 InvalidDecl = true; 370 } 371 372 // FIXME: Deallocate dead declarations. 373 if (InvalidDecl) 374 return QualType(); 375 376 const FunctionProtoType *Proto = D->getType()->getAsFunctionProtoType(); 377 assert(Proto && "Missing prototype?"); 378 QualType ResultType 379 = SemaRef.InstantiateType(Proto->getResultType(), 380 TemplateArgs, NumTemplateArgs, 381 D->getLocation(), D->getDeclName()); 382 if (ResultType.isNull()) 383 return QualType(); 384 385 return SemaRef.BuildFunctionType(ResultType, &ParamTys[0], ParamTys.size(), 386 Proto->isVariadic(), Proto->getTypeQuals(), 387 D->getLocation(), D->getDeclName()); 388} 389 390/// \brief Initializes common fields of an instantiated method 391/// declaration (New) from the corresponding fields of its template 392/// (Tmpl). 393/// 394/// \returns true if there was an error 395bool 396TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, 397 CXXMethodDecl *Tmpl) { 398 CXXRecordDecl *Record = cast<CXXRecordDecl>(Owner); 399 New->setAccess(Tmpl->getAccess()); 400 if (Tmpl->isVirtual()) { 401 New->setVirtual(); 402 Record->setAggregate(false); 403 Record->setPOD(false); 404 Record->setPolymorphic(true); 405 } 406 if (Tmpl->isDeleted()) 407 New->setDeleted(); 408 if (Tmpl->isPure()) { 409 New->setPure(); 410 Record->setAbstract(true); 411 } 412 413 // FIXME: attributes 414 // FIXME: New needs a pointer to Tmpl 415 return false; 416} 417