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