| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 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 | //===----------------------------------------------------------------------===/ | 
| John McCall | 2d88708 | 2010-08-25 22:03:47 +0000 | [diff] [blame] | 12 | #include "clang/Sema/SemaInternal.h" | 
| Douglas Gregor | e737f50 | 2010-08-12 20:07:10 +0000 | [diff] [blame] | 13 | #include "clang/Sema/Lookup.h" | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 14 | #include "clang/Sema/PrettyDeclStackTrace.h" | 
| John McCall | 7cd088e | 2010-08-24 07:21:54 +0000 | [diff] [blame] | 15 | #include "clang/Sema/Template.h" | 
| Douglas Gregor | aba43bb | 2009-05-26 20:50:29 +0000 | [diff] [blame] | 16 | #include "clang/AST/ASTConsumer.h" | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 17 | #include "clang/AST/ASTContext.h" | 
 | 18 | #include "clang/AST/DeclTemplate.h" | 
 | 19 | #include "clang/AST/DeclVisitor.h" | 
| John McCall | 0c01d18 | 2010-03-24 05:22:00 +0000 | [diff] [blame] | 20 | #include "clang/AST/DependentDiagnostic.h" | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 21 | #include "clang/AST/Expr.h" | 
| Douglas Gregor | a88cfbf | 2009-12-12 18:16:41 +0000 | [diff] [blame] | 22 | #include "clang/AST/ExprCXX.h" | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 23 | #include "clang/AST/TypeLoc.h" | 
| Douglas Gregor | 83ddad3 | 2009-08-26 21:14:46 +0000 | [diff] [blame] | 24 | #include "clang/Lex/Preprocessor.h" | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 25 |  | 
 | 26 | using namespace clang; | 
 | 27 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 28 | bool TemplateDeclInstantiator::SubstQualifier(const DeclaratorDecl *OldDecl, | 
 | 29 |                                               DeclaratorDecl *NewDecl) { | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 30 |   if (!OldDecl->getQualifierLoc()) | 
 | 31 |     return false; | 
 | 32 |    | 
 | 33 |   NestedNameSpecifierLoc NewQualifierLoc | 
 | 34 |     = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),  | 
 | 35 |                                           TemplateArgs); | 
 | 36 |    | 
 | 37 |   if (!NewQualifierLoc) | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 38 |     return true; | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 39 |    | 
 | 40 |   NewDecl->setQualifierInfo(NewQualifierLoc); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 41 |   return false; | 
 | 42 | } | 
 | 43 |  | 
 | 44 | bool TemplateDeclInstantiator::SubstQualifier(const TagDecl *OldDecl, | 
 | 45 |                                               TagDecl *NewDecl) { | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 46 |   if (!OldDecl->getQualifierLoc()) | 
 | 47 |     return false; | 
 | 48 |    | 
 | 49 |   NestedNameSpecifierLoc NewQualifierLoc | 
 | 50 |   = SemaRef.SubstNestedNameSpecifierLoc(OldDecl->getQualifierLoc(),  | 
 | 51 |                                         TemplateArgs); | 
 | 52 |    | 
 | 53 |   if (!NewQualifierLoc) | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 54 |     return true; | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 55 |    | 
 | 56 |   NewDecl->setQualifierInfo(NewQualifierLoc); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 57 |   return false; | 
 | 58 | } | 
 | 59 |  | 
| Chandler Carruth | 4ced79f | 2010-06-25 03:22:07 +0000 | [diff] [blame] | 60 | // FIXME: Is this still too simple? | 
| John McCall | 1d8d1cc | 2010-08-01 02:01:53 +0000 | [diff] [blame] | 61 | void Sema::InstantiateAttrs(const MultiLevelTemplateArgumentList &TemplateArgs, | 
 | 62 |                             Decl *Tmpl, Decl *New) { | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 63 |   for (AttrVec::const_iterator i = Tmpl->attr_begin(), e = Tmpl->attr_end(); | 
 | 64 |        i != e; ++i) { | 
 | 65 |     const Attr *TmplAttr = *i; | 
| Chandler Carruth | 4ced79f | 2010-06-25 03:22:07 +0000 | [diff] [blame] | 66 |     // FIXME: This should be generalized to more than just the AlignedAttr. | 
 | 67 |     if (const AlignedAttr *Aligned = dyn_cast<AlignedAttr>(TmplAttr)) { | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 68 |       if (Aligned->isAlignmentDependent()) { | 
| Chandler Carruth | 4ced79f | 2010-06-25 03:22:07 +0000 | [diff] [blame] | 69 |         // The alignment expression is not potentially evaluated. | 
| John McCall | 1d8d1cc | 2010-08-01 02:01:53 +0000 | [diff] [blame] | 70 |         EnterExpressionEvaluationContext Unevaluated(*this, | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 71 |                                                      Sema::Unevaluated); | 
| Chandler Carruth | 4ced79f | 2010-06-25 03:22:07 +0000 | [diff] [blame] | 72 |  | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 73 |         if (Aligned->isAlignmentExpr()) { | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 74 |           ExprResult Result = SubstExpr(Aligned->getAlignmentExpr(), | 
| Nick Lewycky | 7663f39 | 2010-11-20 01:29:55 +0000 | [diff] [blame] | 75 |                                         TemplateArgs); | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 76 |           if (!Result.isInvalid()) | 
 | 77 |             AddAlignedAttr(Aligned->getLocation(), New, Result.takeAs<Expr>()); | 
 | 78 |         } | 
 | 79 |         else { | 
 | 80 |           TypeSourceInfo *Result = SubstType(Aligned->getAlignmentType(), | 
| Nick Lewycky | 7663f39 | 2010-11-20 01:29:55 +0000 | [diff] [blame] | 81 |                                              TemplateArgs, | 
 | 82 |                                              Aligned->getLocation(),  | 
 | 83 |                                              DeclarationName()); | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 84 |           if (Result) | 
 | 85 |             AddAlignedAttr(Aligned->getLocation(), New, Result); | 
 | 86 |         } | 
| Chandler Carruth | 4ced79f | 2010-06-25 03:22:07 +0000 | [diff] [blame] | 87 |         continue; | 
 | 88 |       } | 
 | 89 |     } | 
 | 90 |  | 
| Anders Carlsson | d8fe2d5 | 2009-11-07 06:07:58 +0000 | [diff] [blame] | 91 |     // FIXME: Is cloning correct for all attributes? | 
| John McCall | 1d8d1cc | 2010-08-01 02:01:53 +0000 | [diff] [blame] | 92 |     Attr *NewAttr = TmplAttr->clone(Context); | 
| Anders Carlsson | d8fe2d5 | 2009-11-07 06:07:58 +0000 | [diff] [blame] | 93 |     New->addAttr(NewAttr); | 
 | 94 |   } | 
 | 95 | } | 
 | 96 |  | 
| Douglas Gregor | 4f722be | 2009-03-25 15:45:12 +0000 | [diff] [blame] | 97 | Decl * | 
 | 98 | TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) { | 
 | 99 |   assert(false && "Translation units cannot be instantiated"); | 
 | 100 |   return D; | 
 | 101 | } | 
 | 102 |  | 
 | 103 | Decl * | 
| Chris Lattner | 57ad378 | 2011-02-17 20:34:02 +0000 | [diff] [blame] | 104 | TemplateDeclInstantiator::VisitLabelDecl(LabelDecl *D) { | 
 | 105 |   LabelDecl *Inst = LabelDecl::Create(SemaRef.Context, Owner, D->getLocation(), | 
 | 106 |                                       D->getIdentifier()); | 
 | 107 |   Owner->addDecl(Inst); | 
 | 108 |   return Inst; | 
 | 109 | } | 
 | 110 |  | 
 | 111 | Decl * | 
| Douglas Gregor | 4f722be | 2009-03-25 15:45:12 +0000 | [diff] [blame] | 112 | TemplateDeclInstantiator::VisitNamespaceDecl(NamespaceDecl *D) { | 
 | 113 |   assert(false && "Namespaces cannot be instantiated"); | 
 | 114 |   return D; | 
 | 115 | } | 
 | 116 |  | 
| John McCall | 3dbd3d5 | 2010-02-16 06:53:13 +0000 | [diff] [blame] | 117 | Decl * | 
 | 118 | TemplateDeclInstantiator::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { | 
 | 119 |   NamespaceAliasDecl *Inst | 
 | 120 |     = NamespaceAliasDecl::Create(SemaRef.Context, Owner, | 
 | 121 |                                  D->getNamespaceLoc(), | 
 | 122 |                                  D->getAliasLoc(), | 
| Douglas Gregor | 0cfaf6a | 2011-02-25 17:08:07 +0000 | [diff] [blame] | 123 |                                  D->getIdentifier(), | 
 | 124 |                                  D->getQualifierLoc(), | 
| John McCall | 3dbd3d5 | 2010-02-16 06:53:13 +0000 | [diff] [blame] | 125 |                                  D->getTargetNameLoc(), | 
 | 126 |                                  D->getNamespace()); | 
 | 127 |   Owner->addDecl(Inst); | 
 | 128 |   return Inst; | 
 | 129 | } | 
 | 130 |  | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 131 | Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D, | 
 | 132 |                                                            bool IsTypeAlias) { | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 133 |   bool Invalid = false; | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 134 |   TypeSourceInfo *DI = D->getTypeSourceInfo(); | 
| Douglas Gregor | 836adf6 | 2010-05-24 17:22:01 +0000 | [diff] [blame] | 135 |   if (DI->getType()->isDependentType() || | 
 | 136 |       DI->getType()->isVariablyModifiedType()) { | 
| John McCall | ba6a9bd | 2009-10-24 08:00:42 +0000 | [diff] [blame] | 137 |     DI = SemaRef.SubstType(DI, TemplateArgs, | 
 | 138 |                            D->getLocation(), D->getDeclName()); | 
 | 139 |     if (!DI) { | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 140 |       Invalid = true; | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 141 |       DI = SemaRef.Context.getTrivialTypeSourceInfo(SemaRef.Context.IntTy); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 142 |     } | 
| Douglas Gregor | b4eeaff | 2010-05-07 23:12:07 +0000 | [diff] [blame] | 143 |   } else { | 
 | 144 |     SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType()); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 145 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 146 |  | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 147 |   // Create the new typedef | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 148 |   TypedefNameDecl *Typedef; | 
 | 149 |   if (IsTypeAlias) | 
 | 150 |     Typedef = TypeAliasDecl::Create(SemaRef.Context, Owner, D->getLocStart(), | 
 | 151 |                                     D->getLocation(), D->getIdentifier(), DI); | 
 | 152 |   else | 
 | 153 |     Typedef = TypedefDecl::Create(SemaRef.Context, Owner, D->getLocStart(), | 
 | 154 |                                   D->getLocation(), D->getIdentifier(), DI); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 155 |   if (Invalid) | 
 | 156 |     Typedef->setInvalidDecl(); | 
 | 157 |  | 
| John McCall | cde5a40 | 2011-02-01 08:20:08 +0000 | [diff] [blame] | 158 |   // If the old typedef was the name for linkage purposes of an anonymous | 
 | 159 |   // tag decl, re-establish that relationship for the new typedef. | 
 | 160 |   if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) { | 
 | 161 |     TagDecl *oldTag = oldTagType->getDecl(); | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 162 |     if (oldTag->getTypedefNameForAnonDecl() == D) { | 
| John McCall | cde5a40 | 2011-02-01 08:20:08 +0000 | [diff] [blame] | 163 |       TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl(); | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 164 |       assert(!newTag->getIdentifier() && !newTag->getTypedefNameForAnonDecl()); | 
 | 165 |       newTag->setTypedefNameForAnonDecl(Typedef); | 
| John McCall | cde5a40 | 2011-02-01 08:20:08 +0000 | [diff] [blame] | 166 |     } | 
| Douglas Gregor | d57a38e | 2010-04-23 16:25:07 +0000 | [diff] [blame] | 167 |   } | 
 | 168 |    | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 169 |   if (TypedefNameDecl *Prev = D->getPreviousDeclaration()) { | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 170 |     NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev, | 
 | 171 |                                                        TemplateArgs); | 
| Douglas Gregor | b710722 | 2011-03-04 19:46:35 +0000 | [diff] [blame] | 172 |     if (!InstPrev) | 
 | 173 |       return 0; | 
 | 174 |      | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 175 |     Typedef->setPreviousDeclaration(cast<TypedefNameDecl>(InstPrev)); | 
| John McCall | 5126fd0 | 2009-12-30 00:31:22 +0000 | [diff] [blame] | 176 |   } | 
 | 177 |  | 
| John McCall | 1d8d1cc | 2010-08-01 02:01:53 +0000 | [diff] [blame] | 178 |   SemaRef.InstantiateAttrs(TemplateArgs, D, Typedef); | 
| Douglas Gregor | d57a38e | 2010-04-23 16:25:07 +0000 | [diff] [blame] | 179 |  | 
| John McCall | 46460a6 | 2010-01-20 21:53:11 +0000 | [diff] [blame] | 180 |   Typedef->setAccess(D->getAccess()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 181 |  | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 182 |   return Typedef; | 
 | 183 | } | 
 | 184 |  | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 185 | Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) { | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 186 |   Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false); | 
 | 187 |   Owner->addDecl(Typedef); | 
 | 188 |   return Typedef; | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 189 | } | 
 | 190 |  | 
 | 191 | Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) { | 
| Richard Smith | 3e4c6c4 | 2011-05-05 21:57:07 +0000 | [diff] [blame] | 192 |   Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true); | 
 | 193 |   Owner->addDecl(Typedef); | 
 | 194 |   return Typedef; | 
 | 195 | } | 
 | 196 |  | 
 | 197 | Decl * | 
 | 198 | TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) { | 
 | 199 |   // Create a local instantiation scope for this type alias template, which | 
 | 200 |   // will contain the instantiations of the template parameters. | 
 | 201 |   LocalInstantiationScope Scope(SemaRef); | 
 | 202 |  | 
 | 203 |   TemplateParameterList *TempParams = D->getTemplateParameters(); | 
 | 204 |   TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | 
 | 205 |   if (!InstParams) | 
 | 206 |     return 0; | 
 | 207 |  | 
 | 208 |   TypeAliasDecl *Pattern = D->getTemplatedDecl(); | 
 | 209 |  | 
 | 210 |   TypeAliasTemplateDecl *PrevAliasTemplate = 0; | 
 | 211 |   if (Pattern->getPreviousDeclaration()) { | 
 | 212 |     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); | 
 | 213 |     if (Found.first != Found.second) { | 
 | 214 |       PrevAliasTemplate = dyn_cast<TypeAliasTemplateDecl>(*Found.first); | 
 | 215 |     } | 
 | 216 |   } | 
 | 217 |  | 
 | 218 |   TypeAliasDecl *AliasInst = cast_or_null<TypeAliasDecl>( | 
 | 219 |     InstantiateTypedefNameDecl(Pattern, /*IsTypeAlias=*/true)); | 
 | 220 |   if (!AliasInst) | 
 | 221 |     return 0; | 
 | 222 |  | 
 | 223 |   TypeAliasTemplateDecl *Inst | 
 | 224 |     = TypeAliasTemplateDecl::Create(SemaRef.Context, Owner, D->getLocation(), | 
 | 225 |                                     D->getDeclName(), InstParams, AliasInst); | 
 | 226 |   if (PrevAliasTemplate) | 
 | 227 |     Inst->setPreviousDeclaration(PrevAliasTemplate); | 
 | 228 |  | 
 | 229 |   Inst->setAccess(D->getAccess()); | 
 | 230 |  | 
 | 231 |   if (!PrevAliasTemplate) | 
 | 232 |     Inst->setInstantiatedFromMemberTemplate(D); | 
 | 233 |    | 
 | 234 |   Owner->addDecl(Inst); | 
 | 235 |  | 
 | 236 |   return Inst; | 
| Richard Smith | 162e1c1 | 2011-04-15 14:24:37 +0000 | [diff] [blame] | 237 | } | 
 | 238 |  | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 239 | /// \brief Instantiate an initializer, breaking it into separate | 
 | 240 | /// initialization arguments. | 
 | 241 | /// | 
 | 242 | /// \param S The semantic analysis object. | 
 | 243 | /// | 
 | 244 | /// \param Init The initializer to instantiate. | 
 | 245 | /// | 
 | 246 | /// \param TemplateArgs Template arguments to be substituted into the | 
 | 247 | /// initializer. | 
 | 248 | /// | 
 | 249 | /// \param NewArgs Will be filled in with the instantiation arguments. | 
 | 250 | /// | 
 | 251 | /// \returns true if an error occurred, false otherwise | 
 | 252 | static bool InstantiateInitializer(Sema &S, Expr *Init, | 
 | 253 |                             const MultiLevelTemplateArgumentList &TemplateArgs, | 
 | 254 |                                    SourceLocation &LParenLoc, | 
| Nick Lewycky | 7663f39 | 2010-11-20 01:29:55 +0000 | [diff] [blame] | 255 |                                    ASTOwningVector<Expr*> &NewArgs, | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 256 |                                    SourceLocation &RParenLoc) { | 
 | 257 |   NewArgs.clear(); | 
 | 258 |   LParenLoc = SourceLocation(); | 
 | 259 |   RParenLoc = SourceLocation(); | 
 | 260 |  | 
 | 261 |   if (!Init) | 
 | 262 |     return false; | 
 | 263 |  | 
| John McCall | 4765fa0 | 2010-12-06 08:20:24 +0000 | [diff] [blame] | 264 |   if (ExprWithCleanups *ExprTemp = dyn_cast<ExprWithCleanups>(Init)) | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 265 |     Init = ExprTemp->getSubExpr(); | 
 | 266 |  | 
 | 267 |   while (CXXBindTemporaryExpr *Binder = dyn_cast<CXXBindTemporaryExpr>(Init)) | 
 | 268 |     Init = Binder->getSubExpr(); | 
 | 269 |  | 
 | 270 |   if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Init)) | 
 | 271 |     Init = ICE->getSubExprAsWritten(); | 
 | 272 |  | 
 | 273 |   if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { | 
 | 274 |     LParenLoc = ParenList->getLParenLoc(); | 
 | 275 |     RParenLoc = ParenList->getRParenLoc(); | 
| Douglas Gregor | 91fc73e | 2011-01-07 19:35:17 +0000 | [diff] [blame] | 276 |     return S.SubstExprs(ParenList->getExprs(), ParenList->getNumExprs(), | 
 | 277 |                         true, TemplateArgs, NewArgs); | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 278 |   } | 
 | 279 |  | 
 | 280 |   if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) { | 
| Douglas Gregor | 28329e5 | 2010-03-24 21:22:47 +0000 | [diff] [blame] | 281 |     if (!isa<CXXTemporaryObjectExpr>(Construct)) { | 
| Douglas Gregor | 91fc73e | 2011-01-07 19:35:17 +0000 | [diff] [blame] | 282 |       if (S.SubstExprs(Construct->getArgs(), Construct->getNumArgs(), true, | 
 | 283 |                        TemplateArgs, NewArgs)) | 
| Douglas Gregor | 28329e5 | 2010-03-24 21:22:47 +0000 | [diff] [blame] | 284 |         return true; | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 285 |  | 
| Douglas Gregor | 28329e5 | 2010-03-24 21:22:47 +0000 | [diff] [blame] | 286 |       // FIXME: Fake locations! | 
 | 287 |       LParenLoc = S.PP.getLocForEndOfToken(Init->getLocStart()); | 
| Douglas Gregor | a1a0478 | 2010-09-09 16:33:13 +0000 | [diff] [blame] | 288 |       RParenLoc = LParenLoc; | 
| Douglas Gregor | 28329e5 | 2010-03-24 21:22:47 +0000 | [diff] [blame] | 289 |       return false; | 
 | 290 |     } | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 291 |   } | 
 | 292 |   | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 293 |   ExprResult Result = S.SubstExpr(Init, TemplateArgs); | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 294 |   if (Result.isInvalid()) | 
 | 295 |     return true; | 
 | 296 |  | 
 | 297 |   NewArgs.push_back(Result.takeAs<Expr>()); | 
 | 298 |   return false; | 
 | 299 | } | 
 | 300 |  | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 301 | Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) { | 
| Douglas Gregor | 9901c57 | 2010-05-21 00:31:19 +0000 | [diff] [blame] | 302 |   // If this is the variable for an anonymous struct or union, | 
 | 303 |   // instantiate the anonymous struct/union type first. | 
 | 304 |   if (const RecordType *RecordTy = D->getType()->getAs<RecordType>()) | 
 | 305 |     if (RecordTy->getDecl()->isAnonymousStructOrUnion()) | 
 | 306 |       if (!VisitCXXRecordDecl(cast<CXXRecordDecl>(RecordTy->getDecl()))) | 
 | 307 |         return 0; | 
 | 308 |  | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 309 |   // Do substitution on the type of the declaration | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 310 |   TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(), | 
| John McCall | 0a5fa06 | 2009-10-21 02:39:02 +0000 | [diff] [blame] | 311 |                                          TemplateArgs, | 
 | 312 |                                          D->getTypeSpecStartLoc(), | 
 | 313 |                                          D->getDeclName()); | 
 | 314 |   if (!DI) | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 315 |     return 0; | 
 | 316 |  | 
| Douglas Gregor | c6dbc3f | 2010-09-12 07:37:24 +0000 | [diff] [blame] | 317 |   if (DI->getType()->isFunctionType()) { | 
 | 318 |     SemaRef.Diag(D->getLocation(), diag::err_variable_instantiates_to_function) | 
 | 319 |       << D->isStaticDataMember() << DI->getType(); | 
 | 320 |     return 0; | 
 | 321 |   } | 
 | 322 |    | 
| Douglas Gregor | b9f1b8d | 2009-05-15 00:01:03 +0000 | [diff] [blame] | 323 |   // Build the instantiated declaration | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 324 |   VarDecl *Var = VarDecl::Create(SemaRef.Context, Owner, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 325 |                                  D->getInnerLocStart(), | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 326 |                                  D->getLocation(), D->getIdentifier(), | 
| John McCall | 0a5fa06 | 2009-10-21 02:39:02 +0000 | [diff] [blame] | 327 |                                  DI->getType(), DI, | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 328 |                                  D->getStorageClass(), | 
 | 329 |                                  D->getStorageClassAsWritten()); | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 330 |   Var->setThreadSpecified(D->isThreadSpecified()); | 
 | 331 |   Var->setCXXDirectInitializer(D->hasCXXDirectInitializer()); | 
| Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 332 |   Var->setCXXForRangeDecl(D->isCXXForRangeDecl()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 333 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 334 |   // Substitute the nested name specifier, if any. | 
 | 335 |   if (SubstQualifier(D, Var)) | 
 | 336 |     return 0; | 
 | 337 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 338 |   // If we are instantiating a static data member defined | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 339 |   // out-of-line, the instantiation will have the same lexical | 
 | 340 |   // context (which will be a namespace scope) as the template. | 
 | 341 |   if (D->isOutOfLine()) | 
 | 342 |     Var->setLexicalDeclContext(D->getLexicalDeclContext()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 343 |  | 
| John McCall | 46460a6 | 2010-01-20 21:53:11 +0000 | [diff] [blame] | 344 |   Var->setAccess(D->getAccess()); | 
| Douglas Gregor | c070cc6 | 2010-06-17 23:14:26 +0000 | [diff] [blame] | 345 |    | 
| Argyrios Kyrtzidis | 6b6b42a | 2011-04-19 19:51:10 +0000 | [diff] [blame] | 346 |   if (!D->isStaticDataMember()) { | 
| Douglas Gregor | c070cc6 | 2010-06-17 23:14:26 +0000 | [diff] [blame] | 347 |     Var->setUsed(D->isUsed(false)); | 
| Argyrios Kyrtzidis | 6b6b42a | 2011-04-19 19:51:10 +0000 | [diff] [blame] | 348 |     Var->setReferenced(D->isReferenced()); | 
 | 349 |   } | 
| Douglas Gregor | 4469e8a | 2010-05-19 17:02:24 +0000 | [diff] [blame] | 350 |    | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 351 |   // FIXME: In theory, we could have a previous declaration for variables that | 
 | 352 |   // are not static data members. | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 353 |   bool Redeclaration = false; | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 354 |   // FIXME: having to fake up a LookupResult is dumb. | 
 | 355 |   LookupResult Previous(SemaRef, Var->getDeclName(), Var->getLocation(), | 
| Douglas Gregor | 449d0a8 | 2010-03-01 19:11:54 +0000 | [diff] [blame] | 356 |                         Sema::LookupOrdinaryName, Sema::ForRedeclaration); | 
| Douglas Gregor | 60c93c9 | 2010-02-09 07:26:29 +0000 | [diff] [blame] | 357 |   if (D->isStaticDataMember()) | 
 | 358 |     SemaRef.LookupQualifiedName(Previous, Owner, false); | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 359 |   SemaRef.CheckVariableDeclaration(Var, Previous, Redeclaration); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 360 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 361 |   if (D->isOutOfLine()) { | 
| Abramo Bagnara | ea7b488 | 2010-06-04 09:35:39 +0000 | [diff] [blame] | 362 |     if (!D->isStaticDataMember()) | 
 | 363 |       D->getLexicalDeclContext()->addDecl(Var); | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 364 |     Owner->makeDeclVisibleInContext(Var); | 
 | 365 |   } else { | 
 | 366 |     Owner->addDecl(Var); | 
| Douglas Gregor | f7d72f5 | 2010-05-03 20:22:41 +0000 | [diff] [blame] | 367 |     if (Owner->isFunctionOrMethod()) | 
 | 368 |       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Var); | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 369 |   } | 
| John McCall | 1d8d1cc | 2010-08-01 02:01:53 +0000 | [diff] [blame] | 370 |   SemaRef.InstantiateAttrs(TemplateArgs, D, Var); | 
| Fariborz Jahanian | 8dd0c56 | 2010-07-13 00:16:40 +0000 | [diff] [blame] | 371 |    | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 372 |   // Link instantiations of static data members back to the template from | 
 | 373 |   // which they were instantiated. | 
 | 374 |   if (Var->isStaticDataMember()) | 
 | 375 |     SemaRef.Context.setInstantiatedFromStaticDataMember(Var, D,  | 
| Douglas Gregor | cf3293e | 2009-11-01 20:32:48 +0000 | [diff] [blame] | 376 |                                                      TSK_ImplicitInstantiation); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 377 |    | 
| Douglas Gregor | 60c93c9 | 2010-02-09 07:26:29 +0000 | [diff] [blame] | 378 |   if (Var->getAnyInitializer()) { | 
 | 379 |     // We already have an initializer in the class. | 
 | 380 |   } else if (D->getInit()) { | 
| Douglas Gregor | 1f5f3a4 | 2009-12-03 17:10:37 +0000 | [diff] [blame] | 381 |     if (Var->isStaticDataMember() && !D->isOutOfLine()) | 
 | 382 |       SemaRef.PushExpressionEvaluationContext(Sema::Unevaluated); | 
 | 383 |     else | 
 | 384 |       SemaRef.PushExpressionEvaluationContext(Sema::PotentiallyEvaluated); | 
 | 385 |  | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 386 |     // Instantiate the initializer. | 
 | 387 |     SourceLocation LParenLoc, RParenLoc; | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 388 |     ASTOwningVector<Expr*> InitArgs(SemaRef); | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 389 |     if (!InstantiateInitializer(SemaRef, D->getInit(), TemplateArgs, LParenLoc, | 
| Douglas Gregor | a1a0478 | 2010-09-09 16:33:13 +0000 | [diff] [blame] | 390 |                                 InitArgs, RParenLoc)) { | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 391 |       bool TypeMayContainAuto = true; | 
| Douglas Gregor | 07a77b4 | 2011-01-14 17:12:22 +0000 | [diff] [blame] | 392 |       // Attach the initializer to the declaration, if we have one. | 
 | 393 |       if (InitArgs.size() == 0) | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 394 |         SemaRef.ActOnUninitializedDecl(Var, TypeMayContainAuto); | 
| Douglas Gregor | 07a77b4 | 2011-01-14 17:12:22 +0000 | [diff] [blame] | 395 |       else if (D->hasCXXDirectInitializer()) { | 
| Douglas Gregor | 6eef519 | 2009-12-14 19:27:10 +0000 | [diff] [blame] | 396 |         // Add the direct initializer to the declaration. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 397 |         SemaRef.AddCXXDirectInitializerToDecl(Var, | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 398 |                                               LParenLoc, | 
| Douglas Gregor | 6eef519 | 2009-12-14 19:27:10 +0000 | [diff] [blame] | 399 |                                               move_arg(InitArgs), | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 400 |                                               RParenLoc, | 
 | 401 |                                               TypeMayContainAuto); | 
| Douglas Gregor | 07a77b4 | 2011-01-14 17:12:22 +0000 | [diff] [blame] | 402 |       } else { | 
 | 403 |         assert(InitArgs.size() == 1); | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 404 |         Expr *Init = InitArgs.take()[0]; | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 405 |         SemaRef.AddInitializerToDecl(Var, Init, false, TypeMayContainAuto); | 
| Douglas Gregor | 6eef519 | 2009-12-14 19:27:10 +0000 | [diff] [blame] | 406 |       } | 
| Douglas Gregor | 6eef519 | 2009-12-14 19:27:10 +0000 | [diff] [blame] | 407 |     } else { | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 408 |       // FIXME: Not too happy about invalidating the declaration | 
 | 409 |       // because of a bogus initializer. | 
 | 410 |       Var->setInvalidDecl(); | 
| Douglas Gregor | 6eef519 | 2009-12-14 19:27:10 +0000 | [diff] [blame] | 411 |     } | 
 | 412 |      | 
| Douglas Gregor | 1f5f3a4 | 2009-12-03 17:10:37 +0000 | [diff] [blame] | 413 |     SemaRef.PopExpressionEvaluationContext(); | 
| Richard Smith | ad762fc | 2011-04-14 22:09:26 +0000 | [diff] [blame] | 414 |   } else if ((!Var->isStaticDataMember() || Var->isOutOfLine()) && | 
 | 415 |              !Var->isCXXForRangeDecl()) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 416 |     SemaRef.ActOnUninitializedDecl(Var, false); | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 417 |  | 
| Douglas Gregor | 5764f61 | 2010-05-08 23:05:03 +0000 | [diff] [blame] | 418 |   // Diagnose unused local variables. | 
 | 419 |   if (!Var->isInvalidDecl() && Owner->isFunctionOrMethod() && !Var->isUsed()) | 
 | 420 |     SemaRef.DiagnoseUnusedDecl(Var); | 
| Argyrios Kyrtzidis | bbc6454 | 2010-08-15 01:15:20 +0000 | [diff] [blame] | 421 |  | 
| Douglas Gregor | 3d7a12a | 2009-03-25 23:32:15 +0000 | [diff] [blame] | 422 |   return Var; | 
 | 423 | } | 
 | 424 |  | 
| Abramo Bagnara | 6206d53 | 2010-06-05 05:09:32 +0000 | [diff] [blame] | 425 | Decl *TemplateDeclInstantiator::VisitAccessSpecDecl(AccessSpecDecl *D) { | 
 | 426 |   AccessSpecDecl* AD | 
 | 427 |     = AccessSpecDecl::Create(SemaRef.Context, D->getAccess(), Owner, | 
 | 428 |                              D->getAccessSpecifierLoc(), D->getColonLoc()); | 
 | 429 |   Owner->addHiddenDecl(AD); | 
 | 430 |   return AD; | 
 | 431 | } | 
 | 432 |  | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 433 | Decl *TemplateDeclInstantiator::VisitFieldDecl(FieldDecl *D) { | 
 | 434 |   bool Invalid = false; | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 435 |   TypeSourceInfo *DI = D->getTypeSourceInfo(); | 
| Douglas Gregor | 836adf6 | 2010-05-24 17:22:01 +0000 | [diff] [blame] | 436 |   if (DI->getType()->isDependentType() || | 
 | 437 |       DI->getType()->isVariablyModifiedType())  { | 
| John McCall | 07fb6be | 2009-10-22 23:33:21 +0000 | [diff] [blame] | 438 |     DI = SemaRef.SubstType(DI, TemplateArgs, | 
 | 439 |                            D->getLocation(), D->getDeclName()); | 
 | 440 |     if (!DI) { | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 441 |       DI = D->getTypeSourceInfo(); | 
| John McCall | 07fb6be | 2009-10-22 23:33:21 +0000 | [diff] [blame] | 442 |       Invalid = true; | 
 | 443 |     } else if (DI->getType()->isFunctionType()) { | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 444 |       // C++ [temp.arg.type]p3: | 
 | 445 |       //   If a declaration acquires a function type through a type | 
 | 446 |       //   dependent on a template-parameter and this causes a | 
 | 447 |       //   declaration that does not use the syntactic form of a | 
 | 448 |       //   function declarator to have function type, the program is | 
 | 449 |       //   ill-formed. | 
 | 450 |       SemaRef.Diag(D->getLocation(), diag::err_field_instantiates_to_function) | 
| John McCall | 07fb6be | 2009-10-22 23:33:21 +0000 | [diff] [blame] | 451 |         << DI->getType(); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 452 |       Invalid = true; | 
 | 453 |     } | 
| Douglas Gregor | b4eeaff | 2010-05-07 23:12:07 +0000 | [diff] [blame] | 454 |   } else { | 
 | 455 |     SemaRef.MarkDeclarationsReferencedInType(D->getLocation(), DI->getType()); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 456 |   } | 
 | 457 |  | 
 | 458 |   Expr *BitWidth = D->getBitWidth(); | 
 | 459 |   if (Invalid) | 
 | 460 |     BitWidth = 0; | 
 | 461 |   else if (BitWidth) { | 
| Douglas Gregor | ac7610d | 2009-06-22 20:57:11 +0000 | [diff] [blame] | 462 |     // The bit-width expression is not potentially evaluated. | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 463 |     EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 464 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 465 |     ExprResult InstantiatedBitWidth | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 466 |       = SemaRef.SubstExpr(BitWidth, TemplateArgs); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 467 |     if (InstantiatedBitWidth.isInvalid()) { | 
 | 468 |       Invalid = true; | 
 | 469 |       BitWidth = 0; | 
 | 470 |     } else | 
| Anders Carlsson | e9146f2 | 2009-05-01 19:49:17 +0000 | [diff] [blame] | 471 |       BitWidth = InstantiatedBitWidth.takeAs<Expr>(); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 472 |   } | 
 | 473 |  | 
| John McCall | 07fb6be | 2009-10-22 23:33:21 +0000 | [diff] [blame] | 474 |   FieldDecl *Field = SemaRef.CheckFieldDecl(D->getDeclName(), | 
 | 475 |                                             DI->getType(), DI, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 476 |                                             cast<RecordDecl>(Owner), | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 477 |                                             D->getLocation(), | 
 | 478 |                                             D->isMutable(), | 
 | 479 |                                             BitWidth, | 
| Richard Smith | 7a614d8 | 2011-06-11 17:19:42 +0000 | [diff] [blame^] | 480 |                                             D->hasInClassInitializer(), | 
| Steve Naroff | ea218b8 | 2009-07-14 14:58:18 +0000 | [diff] [blame] | 481 |                                             D->getTypeSpecStartLoc(), | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 482 |                                             D->getAccess(), | 
 | 483 |                                             0); | 
| Douglas Gregor | 663b5a0 | 2009-10-14 20:14:33 +0000 | [diff] [blame] | 484 |   if (!Field) { | 
 | 485 |     cast<Decl>(Owner)->setInvalidDecl(); | 
| Anders Carlsson | f4b5f5c | 2009-09-02 19:17:55 +0000 | [diff] [blame] | 486 |     return 0; | 
| Douglas Gregor | 663b5a0 | 2009-10-14 20:14:33 +0000 | [diff] [blame] | 487 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 488 |  | 
| John McCall | 1d8d1cc | 2010-08-01 02:01:53 +0000 | [diff] [blame] | 489 |   SemaRef.InstantiateAttrs(TemplateArgs, D, Field); | 
| Anders Carlsson | d8fe2d5 | 2009-11-07 06:07:58 +0000 | [diff] [blame] | 490 |    | 
| Anders Carlsson | f4b5f5c | 2009-09-02 19:17:55 +0000 | [diff] [blame] | 491 |   if (Invalid) | 
 | 492 |     Field->setInvalidDecl(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 493 |  | 
| Anders Carlsson | f4b5f5c | 2009-09-02 19:17:55 +0000 | [diff] [blame] | 494 |   if (!Field->getDeclName()) { | 
 | 495 |     // Keep track of where this decl came from. | 
 | 496 |     SemaRef.Context.setInstantiatedFromUnnamedFieldDecl(Field, D); | 
| Douglas Gregor | 9901c57 | 2010-05-21 00:31:19 +0000 | [diff] [blame] | 497 |   }  | 
 | 498 |   if (CXXRecordDecl *Parent= dyn_cast<CXXRecordDecl>(Field->getDeclContext())) { | 
 | 499 |     if (Parent->isAnonymousStructOrUnion() && | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 500 |         Parent->getRedeclContext()->isFunctionOrMethod()) | 
| Douglas Gregor | 9901c57 | 2010-05-21 00:31:19 +0000 | [diff] [blame] | 501 |       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Field); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 502 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 503 |  | 
| Anders Carlsson | f4b5f5c | 2009-09-02 19:17:55 +0000 | [diff] [blame] | 504 |   Field->setImplicit(D->isImplicit()); | 
| John McCall | 46460a6 | 2010-01-20 21:53:11 +0000 | [diff] [blame] | 505 |   Field->setAccess(D->getAccess()); | 
| Anders Carlsson | f4b5f5c | 2009-09-02 19:17:55 +0000 | [diff] [blame] | 506 |   Owner->addDecl(Field); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 507 |  | 
 | 508 |   return Field; | 
 | 509 | } | 
 | 510 |  | 
| Francois Pichet | 87c2e12 | 2010-11-21 06:08:52 +0000 | [diff] [blame] | 511 | Decl *TemplateDeclInstantiator::VisitIndirectFieldDecl(IndirectFieldDecl *D) { | 
 | 512 |   NamedDecl **NamedChain = | 
 | 513 |     new (SemaRef.Context)NamedDecl*[D->getChainingSize()]; | 
 | 514 |  | 
 | 515 |   int i = 0; | 
 | 516 |   for (IndirectFieldDecl::chain_iterator PI = | 
 | 517 |        D->chain_begin(), PE = D->chain_end(); | 
| Douglas Gregor | b710722 | 2011-03-04 19:46:35 +0000 | [diff] [blame] | 518 |        PI != PE; ++PI) { | 
 | 519 |     NamedDecl *Next = SemaRef.FindInstantiatedDecl(D->getLocation(), *PI,  | 
 | 520 |                                               TemplateArgs); | 
 | 521 |     if (!Next) | 
 | 522 |       return 0; | 
 | 523 |      | 
 | 524 |     NamedChain[i++] = Next; | 
 | 525 |   } | 
| Francois Pichet | 87c2e12 | 2010-11-21 06:08:52 +0000 | [diff] [blame] | 526 |  | 
| Francois Pichet | 40e1775 | 2010-12-09 10:07:54 +0000 | [diff] [blame] | 527 |   QualType T = cast<FieldDecl>(NamedChain[i-1])->getType(); | 
| Francois Pichet | 87c2e12 | 2010-11-21 06:08:52 +0000 | [diff] [blame] | 528 |   IndirectFieldDecl* IndirectField | 
 | 529 |     = IndirectFieldDecl::Create(SemaRef.Context, Owner, D->getLocation(), | 
| Francois Pichet | 40e1775 | 2010-12-09 10:07:54 +0000 | [diff] [blame] | 530 |                                 D->getIdentifier(), T, | 
| Francois Pichet | 87c2e12 | 2010-11-21 06:08:52 +0000 | [diff] [blame] | 531 |                                 NamedChain, D->getChainingSize()); | 
 | 532 |  | 
 | 533 |  | 
 | 534 |   IndirectField->setImplicit(D->isImplicit()); | 
 | 535 |   IndirectField->setAccess(D->getAccess()); | 
 | 536 |   Owner->addDecl(IndirectField); | 
 | 537 |   return IndirectField; | 
 | 538 | } | 
 | 539 |  | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 540 | Decl *TemplateDeclInstantiator::VisitFriendDecl(FriendDecl *D) { | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 541 |   // Handle friend type expressions by simply substituting template | 
| Douglas Gregor | 06245bf | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 542 |   // parameters into the pattern type and checking the result. | 
| John McCall | 32f2fb5 | 2010-03-25 18:04:51 +0000 | [diff] [blame] | 543 |   if (TypeSourceInfo *Ty = D->getFriendType()) { | 
| Chandler Carruth | 4fb86f8 | 2011-05-01 00:51:33 +0000 | [diff] [blame] | 544 |     TypeSourceInfo *InstTy; | 
 | 545 |     // If this is an unsupported friend, don't bother substituting template | 
 | 546 |     // arguments into it. The actual type referred to won't be used by any | 
 | 547 |     // parts of Clang, and may not be valid for instantiating. Just use the | 
 | 548 |     // same info for the instantiated friend. | 
 | 549 |     if (D->isUnsupportedFriend()) { | 
 | 550 |       InstTy = Ty; | 
 | 551 |     } else { | 
 | 552 |       InstTy = SemaRef.SubstType(Ty, TemplateArgs, | 
 | 553 |                                  D->getLocation(), DeclarationName()); | 
 | 554 |     } | 
 | 555 |     if (!InstTy) | 
| Douglas Gregor | 7557a13 | 2009-12-24 20:56:24 +0000 | [diff] [blame] | 556 |       return 0; | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 557 |  | 
| Douglas Gregor | 06245bf | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 558 |     FriendDecl *FD = SemaRef.CheckFriendTypeDecl(D->getFriendLoc(), InstTy); | 
 | 559 |     if (!FD) | 
 | 560 |       return 0; | 
 | 561 |      | 
 | 562 |     FD->setAccess(AS_public); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 563 |     FD->setUnsupportedFriend(D->isUnsupportedFriend()); | 
| Douglas Gregor | 06245bf | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 564 |     Owner->addDecl(FD); | 
 | 565 |     return FD; | 
 | 566 |   }  | 
 | 567 |    | 
 | 568 |   NamedDecl *ND = D->getFriendDecl(); | 
 | 569 |   assert(ND && "friend decl must be a decl or a type!"); | 
 | 570 |  | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 571 |   // All of the Visit implementations for the various potential friend | 
 | 572 |   // declarations have to be carefully written to work for friend | 
 | 573 |   // objects, with the most important detail being that the target | 
 | 574 |   // decl should almost certainly not be placed in Owner. | 
 | 575 |   Decl *NewND = Visit(ND); | 
| Douglas Gregor | 06245bf | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 576 |   if (!NewND) return 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 577 |  | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 578 |   FriendDecl *FD = | 
| Douglas Gregor | 06245bf | 2010-04-07 17:57:12 +0000 | [diff] [blame] | 579 |     FriendDecl::Create(SemaRef.Context, Owner, D->getLocation(),  | 
 | 580 |                        cast<NamedDecl>(NewND), D->getFriendLoc()); | 
| John McCall | 5fee110 | 2009-08-29 03:50:18 +0000 | [diff] [blame] | 581 |   FD->setAccess(AS_public); | 
| John McCall | 9a34edb | 2010-10-19 01:40:49 +0000 | [diff] [blame] | 582 |   FD->setUnsupportedFriend(D->isUnsupportedFriend()); | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 583 |   Owner->addDecl(FD); | 
 | 584 |   return FD; | 
| John McCall | fd810b1 | 2009-08-14 02:03:10 +0000 | [diff] [blame] | 585 | } | 
 | 586 |  | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 587 | Decl *TemplateDeclInstantiator::VisitStaticAssertDecl(StaticAssertDecl *D) { | 
 | 588 |   Expr *AssertExpr = D->getAssertExpr(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 589 |  | 
| Douglas Gregor | ac7610d | 2009-06-22 20:57:11 +0000 | [diff] [blame] | 590 |   // The expression in a static assertion is not potentially evaluated. | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 591 |   EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 592 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 593 |   ExprResult InstantiatedAssertExpr | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 594 |     = SemaRef.SubstExpr(AssertExpr, TemplateArgs); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 595 |   if (InstantiatedAssertExpr.isInvalid()) | 
 | 596 |     return 0; | 
 | 597 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 598 |   ExprResult Message(D->getMessage()); | 
| John McCall | 3fa5cae | 2010-10-26 07:05:15 +0000 | [diff] [blame] | 599 |   D->getMessage(); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 600 |   return SemaRef.ActOnStaticAssertDeclaration(D->getLocation(), | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 601 |                                               InstantiatedAssertExpr.get(), | 
| Abramo Bagnara | a2026c9 | 2011-03-08 16:41:52 +0000 | [diff] [blame] | 602 |                                               Message.get(), | 
 | 603 |                                               D->getRParenLoc()); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 604 | } | 
 | 605 |  | 
 | 606 | Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) { | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 607 |   EnumDecl *Enum = EnumDecl::Create(SemaRef.Context, Owner, D->getLocStart(), | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 608 |                                     D->getLocation(), D->getIdentifier(), | 
| Abramo Bagnara | a88cefd | 2010-12-03 18:54:17 +0000 | [diff] [blame] | 609 |                                     /*PrevDecl=*/0, D->isScoped(), | 
 | 610 |                                     D->isScopedUsingClassTag(), D->isFixed()); | 
| Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 611 |   if (D->isFixed()) { | 
 | 612 |     if (TypeSourceInfo* TI = D->getIntegerTypeSourceInfo()) { | 
 | 613 |       // If we have type source information for the underlying type, it means it | 
 | 614 |       // has been explicitly set by the user. Perform substitution on it before | 
 | 615 |       // moving on. | 
 | 616 |       SourceLocation UnderlyingLoc = TI->getTypeLoc().getBeginLoc(); | 
 | 617 |       Enum->setIntegerTypeSourceInfo(SemaRef.SubstType(TI, | 
 | 618 |                                                        TemplateArgs, | 
 | 619 |                                                        UnderlyingLoc, | 
 | 620 |                                                        DeclarationName())); | 
 | 621 |        | 
 | 622 |       if (!Enum->getIntegerTypeSourceInfo()) | 
 | 623 |         Enum->setIntegerType(SemaRef.Context.IntTy); | 
 | 624 |     } | 
 | 625 |     else { | 
 | 626 |       assert(!D->getIntegerType()->isDependentType() | 
 | 627 |              && "Dependent type without type source info"); | 
 | 628 |       Enum->setIntegerType(D->getIntegerType()); | 
 | 629 |     } | 
 | 630 |   } | 
 | 631 |  | 
| John McCall | 5b629aa | 2010-10-22 23:36:17 +0000 | [diff] [blame] | 632 |   SemaRef.InstantiateAttrs(TemplateArgs, D, Enum); | 
 | 633 |  | 
| Douglas Gregor | 8dbc3c6 | 2009-05-27 17:20:35 +0000 | [diff] [blame] | 634 |   Enum->setInstantiationOfMemberEnum(D); | 
| Douglas Gregor | 06c0fec | 2009-03-25 22:00:53 +0000 | [diff] [blame] | 635 |   Enum->setAccess(D->getAccess()); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 636 |   if (SubstQualifier(D, Enum)) return 0; | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 637 |   Owner->addDecl(Enum); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 638 |   Enum->startDefinition(); | 
 | 639 |  | 
| Douglas Gregor | 96084f1 | 2010-03-01 19:00:07 +0000 | [diff] [blame] | 640 |   if (D->getDeclContext()->isFunctionOrMethod()) | 
 | 641 |     SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Enum); | 
 | 642 |      | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 643 |   llvm::SmallVector<Decl*, 4> Enumerators; | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 644 |  | 
 | 645 |   EnumConstantDecl *LastEnumConst = 0; | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 646 |   for (EnumDecl::enumerator_iterator EC = D->enumerator_begin(), | 
 | 647 |          ECEnd = D->enumerator_end(); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 648 |        EC != ECEnd; ++EC) { | 
 | 649 |     // The specified value for the enumerator. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 650 |     ExprResult Value = SemaRef.Owned((Expr *)0); | 
| Douglas Gregor | ac7610d | 2009-06-22 20:57:11 +0000 | [diff] [blame] | 651 |     if (Expr *UninstValue = EC->getInitExpr()) { | 
 | 652 |       // The enumerator's value expression is not potentially evaluated. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 653 |       EnterExpressionEvaluationContext Unevaluated(SemaRef, | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 654 |                                                    Sema::Unevaluated); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 655 |  | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 656 |       Value = SemaRef.SubstExpr(UninstValue, TemplateArgs); | 
| Douglas Gregor | ac7610d | 2009-06-22 20:57:11 +0000 | [diff] [blame] | 657 |     } | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 658 |  | 
 | 659 |     // Drop the initial value and continue. | 
 | 660 |     bool isInvalid = false; | 
 | 661 |     if (Value.isInvalid()) { | 
 | 662 |       Value = SemaRef.Owned((Expr *)0); | 
 | 663 |       isInvalid = true; | 
 | 664 |     } | 
 | 665 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 666 |     EnumConstantDecl *EnumConst | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 667 |       = SemaRef.CheckEnumConstant(Enum, LastEnumConst, | 
 | 668 |                                   EC->getLocation(), EC->getIdentifier(), | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 669 |                                   Value.get()); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 670 |  | 
 | 671 |     if (isInvalid) { | 
 | 672 |       if (EnumConst) | 
 | 673 |         EnumConst->setInvalidDecl(); | 
 | 674 |       Enum->setInvalidDecl(); | 
 | 675 |     } | 
 | 676 |  | 
 | 677 |     if (EnumConst) { | 
| John McCall | 5b629aa | 2010-10-22 23:36:17 +0000 | [diff] [blame] | 678 |       SemaRef.InstantiateAttrs(TemplateArgs, *EC, EnumConst); | 
 | 679 |  | 
| John McCall | 3b85ecf | 2010-01-23 22:37:59 +0000 | [diff] [blame] | 680 |       EnumConst->setAccess(Enum->getAccess()); | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 681 |       Enum->addDecl(EnumConst); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 682 |       Enumerators.push_back(EnumConst); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 683 |       LastEnumConst = EnumConst; | 
| Douglas Gregor | 96084f1 | 2010-03-01 19:00:07 +0000 | [diff] [blame] | 684 |        | 
 | 685 |       if (D->getDeclContext()->isFunctionOrMethod()) { | 
 | 686 |         // If the enumeration is within a function or method, record the enum | 
 | 687 |         // constant as a local. | 
 | 688 |         SemaRef.CurrentInstantiationScope->InstantiatedLocal(*EC, EnumConst); | 
 | 689 |       } | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 690 |     } | 
 | 691 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 692 |  | 
| Mike Stump | c6e35aa | 2009-05-16 07:06:02 +0000 | [diff] [blame] | 693 |   // FIXME: Fixup LBraceLoc and RBraceLoc | 
| Edward O'Callaghan | fee1381 | 2009-08-08 14:36:57 +0000 | [diff] [blame] | 694 |   // FIXME: Empty Scope and AttributeList (required to handle attribute packed). | 
| Mike Stump | c6e35aa | 2009-05-16 07:06:02 +0000 | [diff] [blame] | 695 |   SemaRef.ActOnEnumBody(Enum->getLocation(), SourceLocation(), SourceLocation(), | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 696 |                         Enum, | 
| Eli Friedman | de7a0fc | 2010-08-15 02:27:09 +0000 | [diff] [blame] | 697 |                         Enumerators.data(), Enumerators.size(), | 
| Edward O'Callaghan | fee1381 | 2009-08-08 14:36:57 +0000 | [diff] [blame] | 698 |                         0, 0); | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 699 |  | 
 | 700 |   return Enum; | 
 | 701 | } | 
 | 702 |  | 
| Douglas Gregor | 6477b69 | 2009-03-25 15:04:13 +0000 | [diff] [blame] | 703 | Decl *TemplateDeclInstantiator::VisitEnumConstantDecl(EnumConstantDecl *D) { | 
 | 704 |   assert(false && "EnumConstantDecls can only occur within EnumDecls."); | 
 | 705 |   return 0; | 
 | 706 | } | 
 | 707 |  | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 708 | Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) { | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 709 |   bool isFriend = (D->getFriendObjectKind() != Decl::FOK_None); | 
 | 710 |  | 
| Douglas Gregor | 550d9b2 | 2009-10-31 17:21:17 +0000 | [diff] [blame] | 711 |   // Create a local instantiation scope for this class template, which | 
 | 712 |   // will contain the instantiations of the template parameters. | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 713 |   LocalInstantiationScope Scope(SemaRef); | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 714 |   TemplateParameterList *TempParams = D->getTemplateParameters(); | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 715 |   TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 716 |   if (!InstParams) | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 717 |     return NULL; | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 718 |  | 
 | 719 |   CXXRecordDecl *Pattern = D->getTemplatedDecl(); | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 720 |  | 
 | 721 |   // Instantiate the qualifier.  We have to do this first in case | 
 | 722 |   // we're a friend declaration, because if we are then we need to put | 
 | 723 |   // the new declaration in the appropriate context. | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 724 |   NestedNameSpecifierLoc QualifierLoc = Pattern->getQualifierLoc(); | 
 | 725 |   if (QualifierLoc) { | 
 | 726 |     QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, | 
 | 727 |                                                        TemplateArgs); | 
 | 728 |     if (!QualifierLoc) | 
 | 729 |       return 0; | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 730 |   } | 
 | 731 |  | 
 | 732 |   CXXRecordDecl *PrevDecl = 0; | 
 | 733 |   ClassTemplateDecl *PrevClassTemplate = 0; | 
 | 734 |  | 
| Nick Lewycky | 37574f5 | 2010-11-08 23:29:42 +0000 | [diff] [blame] | 735 |   if (!isFriend && Pattern->getPreviousDeclaration()) { | 
 | 736 |     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName()); | 
 | 737 |     if (Found.first != Found.second) { | 
 | 738 |       PrevClassTemplate = dyn_cast<ClassTemplateDecl>(*Found.first); | 
 | 739 |       if (PrevClassTemplate) | 
 | 740 |         PrevDecl = PrevClassTemplate->getTemplatedDecl(); | 
 | 741 |     } | 
 | 742 |   } | 
 | 743 |  | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 744 |   // If this isn't a friend, then it's a member template, in which | 
 | 745 |   // case we just want to build the instantiation in the | 
 | 746 |   // specialization.  If it is a friend, we want to build it in | 
 | 747 |   // the appropriate context. | 
 | 748 |   DeclContext *DC = Owner; | 
 | 749 |   if (isFriend) { | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 750 |     if (QualifierLoc) { | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 751 |       CXXScopeSpec SS; | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 752 |       SS.Adopt(QualifierLoc); | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 753 |       DC = SemaRef.computeDeclContext(SS); | 
 | 754 |       if (!DC) return 0; | 
 | 755 |     } else { | 
 | 756 |       DC = SemaRef.FindInstantiatedContext(Pattern->getLocation(), | 
 | 757 |                                            Pattern->getDeclContext(), | 
 | 758 |                                            TemplateArgs); | 
 | 759 |     } | 
 | 760 |  | 
 | 761 |     // Look for a previous declaration of the template in the owning | 
 | 762 |     // context. | 
 | 763 |     LookupResult R(SemaRef, Pattern->getDeclName(), Pattern->getLocation(), | 
 | 764 |                    Sema::LookupOrdinaryName, Sema::ForRedeclaration); | 
 | 765 |     SemaRef.LookupQualifiedName(R, DC); | 
 | 766 |  | 
 | 767 |     if (R.isSingleResult()) { | 
 | 768 |       PrevClassTemplate = R.getAsSingle<ClassTemplateDecl>(); | 
 | 769 |       if (PrevClassTemplate) | 
 | 770 |         PrevDecl = PrevClassTemplate->getTemplatedDecl(); | 
 | 771 |     } | 
 | 772 |  | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 773 |     if (!PrevClassTemplate && QualifierLoc) { | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 774 |       SemaRef.Diag(Pattern->getLocation(), diag::err_not_tag_in_scope) | 
| Douglas Gregor | 1eabb7d | 2010-03-31 23:17:41 +0000 | [diff] [blame] | 775 |         << D->getTemplatedDecl()->getTagKind() << Pattern->getDeclName() << DC | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 776 |         << QualifierLoc.getSourceRange(); | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 777 |       return 0; | 
 | 778 |     } | 
 | 779 |  | 
| Douglas Gregor | c53d0d7 | 2010-04-08 18:16:15 +0000 | [diff] [blame] | 780 |     bool AdoptedPreviousTemplateParams = false; | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 781 |     if (PrevClassTemplate) { | 
| Douglas Gregor | c53d0d7 | 2010-04-08 18:16:15 +0000 | [diff] [blame] | 782 |       bool Complain = true; | 
 | 783 |  | 
 | 784 |       // HACK: libstdc++ 4.2.1 contains an ill-formed friend class | 
 | 785 |       // template for struct std::tr1::__detail::_Map_base, where the | 
 | 786 |       // template parameters of the friend declaration don't match the | 
 | 787 |       // template parameters of the original declaration. In this one | 
 | 788 |       // case, we don't complain about the ill-formed friend | 
 | 789 |       // declaration. | 
 | 790 |       if (isFriend && Pattern->getIdentifier() &&  | 
 | 791 |           Pattern->getIdentifier()->isStr("_Map_base") && | 
 | 792 |           DC->isNamespace() && | 
 | 793 |           cast<NamespaceDecl>(DC)->getIdentifier() && | 
 | 794 |           cast<NamespaceDecl>(DC)->getIdentifier()->isStr("__detail")) { | 
 | 795 |         DeclContext *DCParent = DC->getParent(); | 
 | 796 |         if (DCParent->isNamespace() && | 
 | 797 |             cast<NamespaceDecl>(DCParent)->getIdentifier() && | 
 | 798 |             cast<NamespaceDecl>(DCParent)->getIdentifier()->isStr("tr1")) { | 
 | 799 |           DeclContext *DCParent2 = DCParent->getParent(); | 
 | 800 |           if (DCParent2->isNamespace() && | 
 | 801 |               cast<NamespaceDecl>(DCParent2)->getIdentifier() && | 
 | 802 |               cast<NamespaceDecl>(DCParent2)->getIdentifier()->isStr("std") && | 
 | 803 |               DCParent2->getParent()->isTranslationUnit()) | 
 | 804 |             Complain = false; | 
 | 805 |         } | 
 | 806 |       } | 
 | 807 |  | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 808 |       TemplateParameterList *PrevParams | 
 | 809 |         = PrevClassTemplate->getTemplateParameters(); | 
 | 810 |  | 
 | 811 |       // Make sure the parameter lists match. | 
 | 812 |       if (!SemaRef.TemplateParameterListsAreEqual(InstParams, PrevParams, | 
| Douglas Gregor | c53d0d7 | 2010-04-08 18:16:15 +0000 | [diff] [blame] | 813 |                                                   Complain,  | 
 | 814 |                                                   Sema::TPL_TemplateMatch)) { | 
 | 815 |         if (Complain) | 
 | 816 |           return 0; | 
 | 817 |  | 
 | 818 |         AdoptedPreviousTemplateParams = true; | 
 | 819 |         InstParams = PrevParams; | 
 | 820 |       } | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 821 |  | 
 | 822 |       // Do some additional validation, then merge default arguments | 
 | 823 |       // from the existing declarations. | 
| Douglas Gregor | c53d0d7 | 2010-04-08 18:16:15 +0000 | [diff] [blame] | 824 |       if (!AdoptedPreviousTemplateParams && | 
 | 825 |           SemaRef.CheckTemplateParameterList(InstParams, PrevParams, | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 826 |                                              Sema::TPC_ClassTemplate)) | 
 | 827 |         return 0; | 
 | 828 |     } | 
 | 829 |   } | 
 | 830 |  | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 831 |   CXXRecordDecl *RecordInst | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 832 |     = CXXRecordDecl::Create(SemaRef.Context, Pattern->getTagKind(), DC, | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 833 |                             Pattern->getLocStart(), Pattern->getLocation(), | 
 | 834 |                             Pattern->getIdentifier(), PrevDecl, | 
| Douglas Gregor | f0510d4 | 2009-10-12 23:11:44 +0000 | [diff] [blame] | 835 |                             /*DelayTypeCreation=*/true); | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 836 |  | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 837 |   if (QualifierLoc) | 
 | 838 |     RecordInst->setQualifierInfo(QualifierLoc); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 839 |  | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 840 |   ClassTemplateDecl *Inst | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 841 |     = ClassTemplateDecl::Create(SemaRef.Context, DC, D->getLocation(), | 
 | 842 |                                 D->getIdentifier(), InstParams, RecordInst, | 
 | 843 |                                 PrevClassTemplate); | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 844 |   RecordInst->setDescribedClassTemplate(Inst); | 
| John McCall | ea7390c | 2010-04-08 20:25:50 +0000 | [diff] [blame] | 845 |  | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 846 |   if (isFriend) { | 
| John McCall | ea7390c | 2010-04-08 20:25:50 +0000 | [diff] [blame] | 847 |     if (PrevClassTemplate) | 
 | 848 |       Inst->setAccess(PrevClassTemplate->getAccess()); | 
 | 849 |     else | 
 | 850 |       Inst->setAccess(D->getAccess()); | 
 | 851 |  | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 852 |     Inst->setObjectOfFriendDecl(PrevClassTemplate != 0); | 
 | 853 |     // TODO: do we want to track the instantiation progeny of this | 
 | 854 |     // friend target decl? | 
 | 855 |   } else { | 
| Douglas Gregor | e8c01bd | 2009-10-30 21:07:27 +0000 | [diff] [blame] | 856 |     Inst->setAccess(D->getAccess()); | 
| Nick Lewycky | 37574f5 | 2010-11-08 23:29:42 +0000 | [diff] [blame] | 857 |     if (!PrevClassTemplate) | 
 | 858 |       Inst->setInstantiatedFromMemberTemplate(D); | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 859 |   } | 
| Douglas Gregor | f0510d4 | 2009-10-12 23:11:44 +0000 | [diff] [blame] | 860 |    | 
 | 861 |   // Trigger creation of the type for the instantiation. | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 862 |   SemaRef.Context.getInjectedClassNameType(RecordInst, | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 863 |                                     Inst->getInjectedClassNameSpecialization()); | 
| John McCall | ea7390c | 2010-04-08 20:25:50 +0000 | [diff] [blame] | 864 |  | 
| Douglas Gregor | 259571e | 2009-10-30 22:42:42 +0000 | [diff] [blame] | 865 |   // Finish handling of friends. | 
| John McCall | 93ba857 | 2010-03-25 06:39:04 +0000 | [diff] [blame] | 866 |   if (isFriend) { | 
 | 867 |     DC->makeDeclVisibleInContext(Inst, /*Recoverable*/ false); | 
| Douglas Gregor | e8c01bd | 2009-10-30 21:07:27 +0000 | [diff] [blame] | 868 |     return Inst; | 
| Douglas Gregor | 259571e | 2009-10-30 22:42:42 +0000 | [diff] [blame] | 869 |   } | 
| Douglas Gregor | e8c01bd | 2009-10-30 21:07:27 +0000 | [diff] [blame] | 870 |    | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 871 |   Owner->addDecl(Inst); | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 872 |  | 
 | 873 |   if (!PrevClassTemplate) { | 
 | 874 |     // Queue up any out-of-line partial specializations of this member | 
 | 875 |     // class template; the client will force their instantiation once | 
 | 876 |     // the enclosing class has been instantiated. | 
 | 877 |     llvm::SmallVector<ClassTemplatePartialSpecializationDecl *, 4> PartialSpecs; | 
 | 878 |     D->getPartialSpecializations(PartialSpecs); | 
 | 879 |     for (unsigned I = 0, N = PartialSpecs.size(); I != N; ++I) | 
 | 880 |       if (PartialSpecs[I]->isOutOfLine()) | 
 | 881 |         OutOfLinePartialSpecs.push_back(std::make_pair(Inst, PartialSpecs[I])); | 
 | 882 |   } | 
 | 883 |  | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 884 |   return Inst; | 
 | 885 | } | 
 | 886 |  | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 887 | Decl * | 
| Douglas Gregor | 7974c3b | 2009-10-07 17:21:34 +0000 | [diff] [blame] | 888 | TemplateDeclInstantiator::VisitClassTemplatePartialSpecializationDecl( | 
 | 889 |                                    ClassTemplatePartialSpecializationDecl *D) { | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 890 |   ClassTemplateDecl *ClassTemplate = D->getSpecializedTemplate(); | 
 | 891 |    | 
 | 892 |   // Lookup the already-instantiated declaration in the instantiation | 
 | 893 |   // of the class template and return that. | 
 | 894 |   DeclContext::lookup_result Found | 
 | 895 |     = Owner->lookup(ClassTemplate->getDeclName()); | 
 | 896 |   if (Found.first == Found.second) | 
 | 897 |     return 0; | 
 | 898 |    | 
 | 899 |   ClassTemplateDecl *InstClassTemplate | 
 | 900 |     = dyn_cast<ClassTemplateDecl>(*Found.first); | 
 | 901 |   if (!InstClassTemplate) | 
 | 902 |     return 0; | 
 | 903 |    | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 904 |   if (ClassTemplatePartialSpecializationDecl *Result | 
 | 905 |         = InstClassTemplate->findPartialSpecInstantiatedFromMember(D)) | 
 | 906 |     return Result; | 
 | 907 |  | 
 | 908 |   return InstantiateClassTemplatePartialSpecialization(InstClassTemplate, D); | 
| Douglas Gregor | 7974c3b | 2009-10-07 17:21:34 +0000 | [diff] [blame] | 909 | } | 
 | 910 |  | 
 | 911 | Decl * | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 912 | TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { | 
| Douglas Gregor | 550d9b2 | 2009-10-31 17:21:17 +0000 | [diff] [blame] | 913 |   // Create a local instantiation scope for this function template, which | 
 | 914 |   // will contain the instantiations of the template parameters and then get | 
 | 915 |   // merged with the local instantiation scope for the function template  | 
 | 916 |   // itself. | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 917 |   LocalInstantiationScope Scope(SemaRef); | 
| Douglas Gregor | 895162d | 2010-04-30 18:55:50 +0000 | [diff] [blame] | 918 |  | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 919 |   TemplateParameterList *TempParams = D->getTemplateParameters(); | 
 | 920 |   TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 921 |   if (!InstParams) | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 922 |     return NULL; | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 923 |    | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 924 |   FunctionDecl *Instantiated = 0; | 
 | 925 |   if (CXXMethodDecl *DMethod = dyn_cast<CXXMethodDecl>(D->getTemplatedDecl())) | 
 | 926 |     Instantiated = cast_or_null<FunctionDecl>(VisitCXXMethodDecl(DMethod,  | 
 | 927 |                                                                  InstParams)); | 
 | 928 |   else | 
 | 929 |     Instantiated = cast_or_null<FunctionDecl>(VisitFunctionDecl( | 
 | 930 |                                                           D->getTemplatedDecl(),  | 
 | 931 |                                                                 InstParams)); | 
 | 932 |    | 
 | 933 |   if (!Instantiated) | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 934 |     return 0; | 
 | 935 |  | 
| John McCall | 46460a6 | 2010-01-20 21:53:11 +0000 | [diff] [blame] | 936 |   Instantiated->setAccess(D->getAccess()); | 
 | 937 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 938 |   // Link the instantiated function template declaration to the function | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 939 |   // template from which it was instantiated. | 
| Douglas Gregor | 37d68185 | 2009-10-12 22:27:17 +0000 | [diff] [blame] | 940 |   FunctionTemplateDecl *InstTemplate  | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 941 |     = Instantiated->getDescribedFunctionTemplate(); | 
| Douglas Gregor | 37d68185 | 2009-10-12 22:27:17 +0000 | [diff] [blame] | 942 |   InstTemplate->setAccess(D->getAccess()); | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 943 |   assert(InstTemplate &&  | 
 | 944 |          "VisitFunctionDecl/CXXMethodDecl didn't create a template!"); | 
| John McCall | e976ffe | 2009-12-14 23:19:40 +0000 | [diff] [blame] | 945 |  | 
| John McCall | b1a56e7 | 2010-03-26 23:10:15 +0000 | [diff] [blame] | 946 |   bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None); | 
 | 947 |  | 
| John McCall | e976ffe | 2009-12-14 23:19:40 +0000 | [diff] [blame] | 948 |   // Link the instantiation back to the pattern *unless* this is a | 
 | 949 |   // non-definition friend declaration. | 
 | 950 |   if (!InstTemplate->getInstantiatedFromMemberTemplate() && | 
| John McCall | b1a56e7 | 2010-03-26 23:10:15 +0000 | [diff] [blame] | 951 |       !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition())) | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 952 |     InstTemplate->setInstantiatedFromMemberTemplate(D); | 
 | 953 |    | 
| John McCall | b1a56e7 | 2010-03-26 23:10:15 +0000 | [diff] [blame] | 954 |   // Make declarations visible in the appropriate context. | 
 | 955 |   if (!isFriend) | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 956 |     Owner->addDecl(InstTemplate); | 
| John McCall | b1a56e7 | 2010-03-26 23:10:15 +0000 | [diff] [blame] | 957 |  | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 958 |   return InstTemplate; | 
 | 959 | } | 
 | 960 |  | 
| Douglas Gregor | d475b8d | 2009-03-25 21:17:03 +0000 | [diff] [blame] | 961 | Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) { | 
 | 962 |   CXXRecordDecl *PrevDecl = 0; | 
 | 963 |   if (D->isInjectedClassName()) | 
 | 964 |     PrevDecl = cast<CXXRecordDecl>(Owner); | 
| John McCall | 6c1c1b8 | 2009-12-15 22:29:06 +0000 | [diff] [blame] | 965 |   else if (D->getPreviousDeclaration()) { | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 966 |     NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(), | 
 | 967 |                                                    D->getPreviousDeclaration(), | 
| John McCall | 6c1c1b8 | 2009-12-15 22:29:06 +0000 | [diff] [blame] | 968 |                                                    TemplateArgs); | 
 | 969 |     if (!Prev) return 0; | 
 | 970 |     PrevDecl = cast<CXXRecordDecl>(Prev); | 
 | 971 |   } | 
| Douglas Gregor | d475b8d | 2009-03-25 21:17:03 +0000 | [diff] [blame] | 972 |  | 
 | 973 |   CXXRecordDecl *Record | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 974 |     = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner, | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 975 |                             D->getLocStart(), D->getLocation(), | 
 | 976 |                             D->getIdentifier(), PrevDecl); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 977 |  | 
 | 978 |   // Substitute the nested name specifier, if any. | 
 | 979 |   if (SubstQualifier(D, Record)) | 
 | 980 |     return 0; | 
 | 981 |  | 
| Douglas Gregor | d475b8d | 2009-03-25 21:17:03 +0000 | [diff] [blame] | 982 |   Record->setImplicit(D->isImplicit()); | 
| Eli Friedman | eaba1af | 2009-08-27 19:11:42 +0000 | [diff] [blame] | 983 |   // FIXME: Check against AS_none is an ugly hack to work around the issue that | 
 | 984 |   // the tag decls introduced by friend class declarations don't have an access | 
 | 985 |   // specifier. Remove once this area of the code gets sorted out. | 
 | 986 |   if (D->getAccess() != AS_none) | 
 | 987 |     Record->setAccess(D->getAccess()); | 
| Douglas Gregor | d475b8d | 2009-03-25 21:17:03 +0000 | [diff] [blame] | 988 |   if (!D->isInjectedClassName()) | 
| Douglas Gregor | f6b1185 | 2009-10-08 15:14:33 +0000 | [diff] [blame] | 989 |     Record->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation); | 
| Douglas Gregor | d475b8d | 2009-03-25 21:17:03 +0000 | [diff] [blame] | 990 |  | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 991 |   // If the original function was part of a friend declaration, | 
 | 992 |   // inherit its namespace state. | 
 | 993 |   if (Decl::FriendObjectKind FOK = D->getFriendObjectKind()) | 
 | 994 |     Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared); | 
 | 995 |  | 
| Douglas Gregor | 9901c57 | 2010-05-21 00:31:19 +0000 | [diff] [blame] | 996 |   // Make sure that anonymous structs and unions are recorded. | 
 | 997 |   if (D->isAnonymousStructOrUnion()) { | 
 | 998 |     Record->setAnonymousStructOrUnion(true); | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 999 |     if (Record->getDeclContext()->getRedeclContext()->isFunctionOrMethod()) | 
| Douglas Gregor | 9901c57 | 2010-05-21 00:31:19 +0000 | [diff] [blame] | 1000 |       SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Record); | 
 | 1001 |   } | 
| Anders Carlsson | d8b285f | 2009-09-01 04:26:58 +0000 | [diff] [blame] | 1002 |  | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 1003 |   Owner->addDecl(Record); | 
| Douglas Gregor | d475b8d | 2009-03-25 21:17:03 +0000 | [diff] [blame] | 1004 |   return Record; | 
 | 1005 | } | 
 | 1006 |  | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 1007 | /// Normal class members are of more specific types and therefore | 
 | 1008 | /// don't make it here.  This function serves two purposes: | 
 | 1009 | ///   1) instantiating function templates | 
 | 1010 | ///   2) substituting friend declarations | 
 | 1011 | /// FIXME: preserve function definitions in case #2 | 
| Douglas Gregor | 7557a13 | 2009-12-24 20:56:24 +0000 | [diff] [blame] | 1012 | Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D, | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1013 |                                        TemplateParameterList *TemplateParams) { | 
| Douglas Gregor | 127102b | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 1014 |   // Check whether there is already a function template specialization for | 
 | 1015 |   // this declaration. | 
 | 1016 |   FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); | 
 | 1017 |   void *InsertPos = 0; | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1018 |   if (FunctionTemplate && !TemplateParams) { | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 1019 |     std::pair<const TemplateArgument *, unsigned> Innermost  | 
 | 1020 |       = TemplateArgs.getInnermost(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1021 |  | 
| Argyrios Kyrtzidis | 2c853e4 | 2010-07-20 13:59:58 +0000 | [diff] [blame] | 1022 |     FunctionDecl *SpecFunc | 
 | 1023 |       = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second, | 
 | 1024 |                                              InsertPos); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1025 |  | 
| Douglas Gregor | 127102b | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 1026 |     // If we already have a function template specialization, return it. | 
| Argyrios Kyrtzidis | 2c853e4 | 2010-07-20 13:59:58 +0000 | [diff] [blame] | 1027 |     if (SpecFunc) | 
 | 1028 |       return SpecFunc; | 
| Douglas Gregor | 127102b | 2009-06-29 20:59:39 +0000 | [diff] [blame] | 1029 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1030 |  | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1031 |   bool isFriend; | 
 | 1032 |   if (FunctionTemplate) | 
 | 1033 |     isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None); | 
 | 1034 |   else | 
 | 1035 |     isFriend = (D->getFriendObjectKind() != Decl::FOK_None); | 
 | 1036 |  | 
| Douglas Gregor | 79c2278 | 2010-01-16 20:21:20 +0000 | [diff] [blame] | 1037 |   bool MergeWithParentScope = (TemplateParams != 0) || | 
| Douglas Gregor | b212d9a | 2010-05-21 21:25:08 +0000 | [diff] [blame] | 1038 |     Owner->isFunctionOrMethod() || | 
| Douglas Gregor | 79c2278 | 2010-01-16 20:21:20 +0000 | [diff] [blame] | 1039 |     !(isa<Decl>(Owner) &&  | 
 | 1040 |       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 1041 |   LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1042 |  | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 1043 |   llvm::SmallVector<ParmVarDecl *, 4> Params; | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 1044 |   TypeSourceInfo *TInfo = D->getTypeSourceInfo(); | 
 | 1045 |   TInfo = SubstFunctionType(D, Params); | 
 | 1046 |   if (!TInfo) | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1047 |     return 0; | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 1048 |   QualType T = TInfo->getType(); | 
| John McCall | fd810b1 | 2009-08-14 02:03:10 +0000 | [diff] [blame] | 1049 |  | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1050 |   NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); | 
 | 1051 |   if (QualifierLoc) { | 
 | 1052 |     QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, | 
 | 1053 |                                                        TemplateArgs); | 
 | 1054 |     if (!QualifierLoc) | 
 | 1055 |       return 0; | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1056 |   } | 
 | 1057 |  | 
| John McCall | 68b6b87 | 2010-02-06 01:50:47 +0000 | [diff] [blame] | 1058 |   // If we're instantiating a local function declaration, put the result | 
 | 1059 |   // in the owner;  otherwise we need to find the instantiated context. | 
 | 1060 |   DeclContext *DC; | 
 | 1061 |   if (D->getDeclContext()->isFunctionOrMethod()) | 
 | 1062 |     DC = Owner; | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1063 |   else if (isFriend && QualifierLoc) { | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1064 |     CXXScopeSpec SS; | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1065 |     SS.Adopt(QualifierLoc); | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1066 |     DC = SemaRef.computeDeclContext(SS); | 
 | 1067 |     if (!DC) return 0; | 
 | 1068 |   } else { | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 1069 |     DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(),  | 
 | 1070 |                                          TemplateArgs); | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1071 |   } | 
| John McCall | 68b6b87 | 2010-02-06 01:50:47 +0000 | [diff] [blame] | 1072 |  | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 1073 |   FunctionDecl *Function = | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1074 |       FunctionDecl::Create(SemaRef.Context, DC, D->getInnerLocStart(), | 
 | 1075 |                            D->getLocation(), D->getDeclName(), T, TInfo, | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 1076 |                            D->getStorageClass(), D->getStorageClassAsWritten(), | 
| Douglas Gregor | 0130f3c | 2009-10-27 21:01:01 +0000 | [diff] [blame] | 1077 |                            D->isInlineSpecified(), D->hasWrittenPrototype()); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1078 |  | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1079 |   if (QualifierLoc) | 
 | 1080 |     Function->setQualifierInfo(QualifierLoc); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1081 |  | 
| John McCall | b1a56e7 | 2010-03-26 23:10:15 +0000 | [diff] [blame] | 1082 |   DeclContext *LexicalDC = Owner; | 
 | 1083 |   if (!isFriend && D->isOutOfLine()) { | 
 | 1084 |     assert(D->getDeclContext()->isFileContext()); | 
 | 1085 |     LexicalDC = D->getDeclContext(); | 
 | 1086 |   } | 
 | 1087 |  | 
 | 1088 |   Function->setLexicalDeclContext(LexicalDC); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1089 |  | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 1090 |   // Attach the parameters | 
 | 1091 |   for (unsigned P = 0; P < Params.size(); ++P) | 
| John McCall | 3019c44 | 2010-09-17 00:50:28 +0000 | [diff] [blame] | 1092 |     if (Params[P]) | 
 | 1093 |       Params[P]->setOwningFunction(Function); | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1094 |   Function->setParams(Params.data(), Params.size()); | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 1095 |  | 
| Douglas Gregor | ac7c2c8 | 2010-05-17 16:38:00 +0000 | [diff] [blame] | 1096 |   SourceLocation InstantiateAtPOI; | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1097 |   if (TemplateParams) { | 
 | 1098 |     // Our resulting instantiation is actually a function template, since we | 
 | 1099 |     // are substituting only the outer template parameters. For example, given | 
 | 1100 |     // | 
 | 1101 |     //   template<typename T> | 
 | 1102 |     //   struct X { | 
 | 1103 |     //     template<typename U> friend void f(T, U); | 
 | 1104 |     //   }; | 
 | 1105 |     // | 
 | 1106 |     //   X<int> x; | 
 | 1107 |     // | 
 | 1108 |     // We are instantiating the friend function template "f" within X<int>,  | 
 | 1109 |     // which means substituting int for T, but leaving "f" as a friend function | 
 | 1110 |     // template. | 
 | 1111 |     // Build the function template itself. | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1112 |     FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, DC, | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1113 |                                                     Function->getLocation(), | 
 | 1114 |                                                     Function->getDeclName(), | 
 | 1115 |                                                     TemplateParams, Function); | 
 | 1116 |     Function->setDescribedFunctionTemplate(FunctionTemplate); | 
| John McCall | b1a56e7 | 2010-03-26 23:10:15 +0000 | [diff] [blame] | 1117 |  | 
 | 1118 |     FunctionTemplate->setLexicalDeclContext(LexicalDC); | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1119 |  | 
 | 1120 |     if (isFriend && D->isThisDeclarationADefinition()) { | 
 | 1121 |       // TODO: should we remember this connection regardless of whether | 
 | 1122 |       // the friend declaration provided a body? | 
 | 1123 |       FunctionTemplate->setInstantiatedFromMemberTemplate( | 
 | 1124 |                                            D->getDescribedFunctionTemplate()); | 
 | 1125 |     } | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 1126 |   } else if (FunctionTemplate) { | 
 | 1127 |     // Record this function template specialization. | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 1128 |     std::pair<const TemplateArgument *, unsigned> Innermost  | 
 | 1129 |       = TemplateArgs.getInnermost(); | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1130 |     Function->setFunctionTemplateSpecialization(FunctionTemplate, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1131 |                             TemplateArgumentList::CreateCopy(SemaRef.Context, | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 1132 |                                                              Innermost.first, | 
 | 1133 |                                                              Innermost.second), | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 1134 |                                                 InsertPos); | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1135 |   } else if (isFriend && D->isThisDeclarationADefinition()) { | 
 | 1136 |     // TODO: should we remember this connection regardless of whether | 
 | 1137 |     // the friend declaration provided a body? | 
 | 1138 |     Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 1139 |   } | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1140 |      | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 1141 |   if (InitFunctionInstantiation(Function, D)) | 
 | 1142 |     Function->setInvalidDecl(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1143 |  | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 1144 |   bool Redeclaration = false; | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 1145 |   bool isExplicitSpecialization = false; | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1146 |      | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 1147 |   LookupResult Previous(SemaRef, Function->getDeclName(), SourceLocation(), | 
 | 1148 |                         Sema::LookupOrdinaryName, Sema::ForRedeclaration); | 
 | 1149 |  | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 1150 |   if (DependentFunctionTemplateSpecializationInfo *Info | 
 | 1151 |         = D->getDependentSpecializationInfo()) { | 
 | 1152 |     assert(isFriend && "non-friend has dependent specialization info?"); | 
 | 1153 |  | 
 | 1154 |     // This needs to be set now for future sanity. | 
 | 1155 |     Function->setObjectOfFriendDecl(/*HasPrevious*/ true); | 
 | 1156 |  | 
 | 1157 |     // Instantiate the explicit template arguments. | 
 | 1158 |     TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(), | 
 | 1159 |                                           Info->getRAngleLoc()); | 
| Douglas Gregor | e02e262 | 2010-12-22 21:19:48 +0000 | [diff] [blame] | 1160 |     if (SemaRef.Subst(Info->getTemplateArgs(), Info->getNumTemplateArgs(), | 
 | 1161 |                       ExplicitArgs, TemplateArgs)) | 
 | 1162 |       return 0; | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 1163 |  | 
 | 1164 |     // Map the candidate templates to their instantiations. | 
 | 1165 |     for (unsigned I = 0, E = Info->getNumTemplates(); I != E; ++I) { | 
 | 1166 |       Decl *Temp = SemaRef.FindInstantiatedDecl(D->getLocation(), | 
 | 1167 |                                                 Info->getTemplate(I), | 
 | 1168 |                                                 TemplateArgs); | 
 | 1169 |       if (!Temp) return 0; | 
 | 1170 |  | 
 | 1171 |       Previous.addDecl(cast<FunctionTemplateDecl>(Temp)); | 
 | 1172 |     } | 
 | 1173 |  | 
 | 1174 |     if (SemaRef.CheckFunctionTemplateSpecialization(Function, | 
 | 1175 |                                                     &ExplicitArgs, | 
 | 1176 |                                                     Previous)) | 
 | 1177 |       Function->setInvalidDecl(); | 
 | 1178 |                                            | 
 | 1179 |     isExplicitSpecialization = true; | 
 | 1180 |  | 
 | 1181 |   } else if (TemplateParams || !FunctionTemplate) { | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1182 |     // Look only into the namespace where the friend would be declared to  | 
 | 1183 |     // find a previous declaration. This is the innermost enclosing namespace,  | 
 | 1184 |     // as described in ActOnFriendFunctionDecl. | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 1185 |     SemaRef.LookupQualifiedName(Previous, DC); | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1186 |      | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1187 |     // In C++, the previous declaration we find might be a tag type | 
 | 1188 |     // (class or enum). In this case, the new declaration will hide the | 
 | 1189 |     // tag type. Note that this does does not apply if we're declaring a | 
 | 1190 |     // typedef (C++ [dcl.typedef]p4). | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 1191 |     if (Previous.isSingleTagDecl()) | 
 | 1192 |       Previous.clear(); | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1193 |   } | 
 | 1194 |    | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1195 |   SemaRef.CheckFunctionDeclaration(/*Scope*/ 0, Function, Previous, | 
| Peter Collingbourne | c80e811 | 2011-01-21 02:08:54 +0000 | [diff] [blame] | 1196 |                                    isExplicitSpecialization, Redeclaration); | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1197 |  | 
| John McCall | 76d3264 | 2010-04-24 01:30:58 +0000 | [diff] [blame] | 1198 |   NamedDecl *PrincipalDecl = (TemplateParams | 
 | 1199 |                               ? cast<NamedDecl>(FunctionTemplate) | 
 | 1200 |                               : Function); | 
 | 1201 |  | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1202 |   // If the original function was part of a friend declaration, | 
 | 1203 |   // inherit its namespace state and add it to the owner. | 
| John McCall | d325daa | 2010-03-26 04:53:08 +0000 | [diff] [blame] | 1204 |   if (isFriend) { | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 1205 |     NamedDecl *PrevDecl; | 
| John McCall | 76d3264 | 2010-04-24 01:30:58 +0000 | [diff] [blame] | 1206 |     if (TemplateParams) | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1207 |       PrevDecl = FunctionTemplate->getPreviousDeclaration(); | 
| John McCall | 76d3264 | 2010-04-24 01:30:58 +0000 | [diff] [blame] | 1208 |     else | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1209 |       PrevDecl = Function->getPreviousDeclaration(); | 
| John McCall | 76d3264 | 2010-04-24 01:30:58 +0000 | [diff] [blame] | 1210 |  | 
 | 1211 |     PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0); | 
 | 1212 |     DC->makeDeclVisibleInContext(PrincipalDecl, /*Recoverable=*/ false); | 
| Gabor Greif | ab297ac | 2010-08-30 21:10:05 +0000 | [diff] [blame] | 1213 |  | 
| Gabor Greif | 77535df | 2010-08-30 22:25:56 +0000 | [diff] [blame] | 1214 |     bool queuedInstantiation = false; | 
| Gabor Greif | ab297ac | 2010-08-30 21:10:05 +0000 | [diff] [blame] | 1215 |  | 
| Douglas Gregor | 238058c | 2010-05-18 05:45:02 +0000 | [diff] [blame] | 1216 |     if (!SemaRef.getLangOptions().CPlusPlus0x && | 
 | 1217 |         D->isThisDeclarationADefinition()) { | 
 | 1218 |       // Check for a function body. | 
 | 1219 |       const FunctionDecl *Definition = 0; | 
| Sean Hunt | 10620eb | 2011-05-06 20:44:56 +0000 | [diff] [blame] | 1220 |       if (Function->isDefined(Definition) && | 
| Douglas Gregor | 238058c | 2010-05-18 05:45:02 +0000 | [diff] [blame] | 1221 |           Definition->getTemplateSpecializationKind() == TSK_Undeclared) { | 
 | 1222 |         SemaRef.Diag(Function->getLocation(), diag::err_redefinition)  | 
 | 1223 |           << Function->getDeclName(); | 
 | 1224 |         SemaRef.Diag(Definition->getLocation(), diag::note_previous_definition); | 
 | 1225 |         Function->setInvalidDecl();         | 
 | 1226 |       }  | 
 | 1227 |       // Check for redefinitions due to other instantiations of this or | 
 | 1228 |       // a similar friend function. | 
 | 1229 |       else for (FunctionDecl::redecl_iterator R = Function->redecls_begin(), | 
 | 1230 |                                            REnd = Function->redecls_end(); | 
 | 1231 |                 R != REnd; ++R) { | 
| Gabor Greif | 13a8aff | 2010-08-28 15:42:30 +0000 | [diff] [blame] | 1232 |         if (*R == Function) | 
 | 1233 |           continue; | 
| Gabor Greif | ab297ac | 2010-08-30 21:10:05 +0000 | [diff] [blame] | 1234 |         switch (R->getFriendObjectKind()) { | 
 | 1235 |         case Decl::FOK_None: | 
 | 1236 |           if (!queuedInstantiation && R->isUsed(false)) { | 
 | 1237 |             if (MemberSpecializationInfo *MSInfo | 
 | 1238 |                 = Function->getMemberSpecializationInfo()) { | 
 | 1239 |               if (MSInfo->getPointOfInstantiation().isInvalid()) { | 
 | 1240 |                 SourceLocation Loc = R->getLocation(); // FIXME | 
 | 1241 |                 MSInfo->setPointOfInstantiation(Loc); | 
 | 1242 |                 SemaRef.PendingLocalImplicitInstantiations.push_back( | 
 | 1243 |                                                  std::make_pair(Function, Loc)); | 
 | 1244 |                 queuedInstantiation = true; | 
 | 1245 |               } | 
 | 1246 |             } | 
 | 1247 |           } | 
 | 1248 |           break; | 
 | 1249 |         default: | 
| Douglas Gregor | 238058c | 2010-05-18 05:45:02 +0000 | [diff] [blame] | 1250 |           if (const FunctionDecl *RPattern | 
| Gabor Greif | 6a557d8 | 2010-08-28 15:46:56 +0000 | [diff] [blame] | 1251 |               = R->getTemplateInstantiationPattern()) | 
| Sean Hunt | 10620eb | 2011-05-06 20:44:56 +0000 | [diff] [blame] | 1252 |             if (RPattern->isDefined(RPattern)) { | 
| Douglas Gregor | 238058c | 2010-05-18 05:45:02 +0000 | [diff] [blame] | 1253 |               SemaRef.Diag(Function->getLocation(), diag::err_redefinition)  | 
 | 1254 |                 << Function->getDeclName(); | 
| Gabor Greif | 6a557d8 | 2010-08-28 15:46:56 +0000 | [diff] [blame] | 1255 |               SemaRef.Diag(R->getLocation(), diag::note_previous_definition); | 
| Douglas Gregor | 238058c | 2010-05-18 05:45:02 +0000 | [diff] [blame] | 1256 |               Function->setInvalidDecl(); | 
 | 1257 |               break; | 
 | 1258 |             } | 
 | 1259 |         } | 
 | 1260 |       } | 
 | 1261 |     } | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 1262 |   } | 
 | 1263 |  | 
| John McCall | 76d3264 | 2010-04-24 01:30:58 +0000 | [diff] [blame] | 1264 |   if (Function->isOverloadedOperator() && !DC->isRecord() && | 
 | 1265 |       PrincipalDecl->isInIdentifierNamespace(Decl::IDNS_Ordinary)) | 
 | 1266 |     PrincipalDecl->setNonMemberOperator(); | 
 | 1267 |  | 
| Sean Hunt | eb88ae5 | 2011-05-23 21:07:59 +0000 | [diff] [blame] | 1268 |   assert(!D->isDefaulted() && "only methods should be defaulted"); | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 1269 |   return Function; | 
 | 1270 | } | 
 | 1271 |  | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 1272 | Decl * | 
 | 1273 | TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, | 
 | 1274 |                                       TemplateParameterList *TemplateParams) { | 
| Douglas Gregor | 6b90686 | 2009-08-21 00:16:32 +0000 | [diff] [blame] | 1275 |   FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate(); | 
 | 1276 |   void *InsertPos = 0; | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 1277 |   if (FunctionTemplate && !TemplateParams) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1278 |     // We are creating a function template specialization from a function | 
 | 1279 |     // template. Check whether there is already a function template | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 1280 |     // specialization for this particular set of template arguments. | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 1281 |     std::pair<const TemplateArgument *, unsigned> Innermost  | 
 | 1282 |       = TemplateArgs.getInnermost(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1283 |  | 
| Argyrios Kyrtzidis | 2c853e4 | 2010-07-20 13:59:58 +0000 | [diff] [blame] | 1284 |     FunctionDecl *SpecFunc | 
 | 1285 |       = FunctionTemplate->findSpecialization(Innermost.first, Innermost.second, | 
 | 1286 |                                              InsertPos); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1287 |  | 
| Douglas Gregor | 6b90686 | 2009-08-21 00:16:32 +0000 | [diff] [blame] | 1288 |     // If we already have a function template specialization, return it. | 
| Argyrios Kyrtzidis | 2c853e4 | 2010-07-20 13:59:58 +0000 | [diff] [blame] | 1289 |     if (SpecFunc) | 
 | 1290 |       return SpecFunc; | 
| Douglas Gregor | 6b90686 | 2009-08-21 00:16:32 +0000 | [diff] [blame] | 1291 |   } | 
 | 1292 |  | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1293 |   bool isFriend; | 
 | 1294 |   if (FunctionTemplate) | 
 | 1295 |     isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None); | 
 | 1296 |   else | 
 | 1297 |     isFriend = (D->getFriendObjectKind() != Decl::FOK_None); | 
 | 1298 |  | 
| Douglas Gregor | 79c2278 | 2010-01-16 20:21:20 +0000 | [diff] [blame] | 1299 |   bool MergeWithParentScope = (TemplateParams != 0) || | 
 | 1300 |     !(isa<Decl>(Owner) &&  | 
 | 1301 |       cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 1302 |   LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); | 
| Douglas Gregor | 48dd19b | 2009-05-14 21:44:34 +0000 | [diff] [blame] | 1303 |  | 
| John McCall | 4eab39f | 2010-10-19 02:26:41 +0000 | [diff] [blame] | 1304 |   // Instantiate enclosing template arguments for friends. | 
 | 1305 |   llvm::SmallVector<TemplateParameterList *, 4> TempParamLists; | 
 | 1306 |   unsigned NumTempParamLists = 0; | 
 | 1307 |   if (isFriend && (NumTempParamLists = D->getNumTemplateParameterLists())) { | 
 | 1308 |     TempParamLists.set_size(NumTempParamLists); | 
 | 1309 |     for (unsigned I = 0; I != NumTempParamLists; ++I) { | 
 | 1310 |       TemplateParameterList *TempParams = D->getTemplateParameterList(I); | 
 | 1311 |       TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | 
 | 1312 |       if (!InstParams) | 
 | 1313 |         return NULL; | 
 | 1314 |       TempParamLists[I] = InstParams; | 
 | 1315 |     } | 
 | 1316 |   } | 
 | 1317 |  | 
| Douglas Gregor | 0ca20ac | 2009-05-29 18:27:38 +0000 | [diff] [blame] | 1318 |   llvm::SmallVector<ParmVarDecl *, 4> Params; | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 1319 |   TypeSourceInfo *TInfo = D->getTypeSourceInfo(); | 
 | 1320 |   TInfo = SubstFunctionType(D, Params); | 
 | 1321 |   if (!TInfo) | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1322 |     return 0; | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 1323 |   QualType T = TInfo->getType(); | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1324 |  | 
| Abramo Bagnara | 723df24 | 2010-12-14 22:11:44 +0000 | [diff] [blame] | 1325 |   // \brief If the type of this function, after ignoring parentheses, | 
 | 1326 |   // is not *directly* a function type, then we're instantiating a function | 
 | 1327 |   // that was declared via a typedef, e.g., | 
| Douglas Gregor | 5f970ee | 2010-05-04 18:18:31 +0000 | [diff] [blame] | 1328 |   // | 
 | 1329 |   //   typedef int functype(int, int); | 
 | 1330 |   //   functype func; | 
 | 1331 |   // | 
 | 1332 |   // In this case, we'll just go instantiate the ParmVarDecls that we | 
 | 1333 |   // synthesized in the method declaration. | 
| Abramo Bagnara | 723df24 | 2010-12-14 22:11:44 +0000 | [diff] [blame] | 1334 |   if (!isa<FunctionProtoType>(T.IgnoreParens())) { | 
| Douglas Gregor | 5f970ee | 2010-05-04 18:18:31 +0000 | [diff] [blame] | 1335 |     assert(!Params.size() && "Instantiating type could not yield parameters"); | 
| Douglas Gregor | 12c9c00 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 1336 |     llvm::SmallVector<QualType, 4> ParamTypes; | 
 | 1337 |     if (SemaRef.SubstParmTypes(D->getLocation(), D->param_begin(),  | 
 | 1338 |                                D->getNumParams(), TemplateArgs, ParamTypes,  | 
 | 1339 |                                &Params)) | 
 | 1340 |       return 0;     | 
| Douglas Gregor | 5f970ee | 2010-05-04 18:18:31 +0000 | [diff] [blame] | 1341 |   } | 
 | 1342 |  | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1343 |   NestedNameSpecifierLoc QualifierLoc = D->getQualifierLoc(); | 
 | 1344 |   if (QualifierLoc) { | 
 | 1345 |     QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1346 |                                                  TemplateArgs); | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1347 |     if (!QualifierLoc)  | 
 | 1348 |       return 0; | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1349 |   } | 
 | 1350 |  | 
 | 1351 |   DeclContext *DC = Owner; | 
 | 1352 |   if (isFriend) { | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1353 |     if (QualifierLoc) { | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1354 |       CXXScopeSpec SS; | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1355 |       SS.Adopt(QualifierLoc); | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1356 |       DC = SemaRef.computeDeclContext(SS); | 
| John McCall | c54d688 | 2010-10-19 05:01:53 +0000 | [diff] [blame] | 1357 |  | 
 | 1358 |       if (DC && SemaRef.RequireCompleteDeclContext(SS, DC)) | 
 | 1359 |         return 0; | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1360 |     } else { | 
 | 1361 |       DC = SemaRef.FindInstantiatedContext(D->getLocation(), | 
 | 1362 |                                            D->getDeclContext(), | 
 | 1363 |                                            TemplateArgs); | 
 | 1364 |     } | 
 | 1365 |     if (!DC) return 0; | 
 | 1366 |   } | 
 | 1367 |  | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1368 |   // Build the instantiated method declaration. | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1369 |   CXXRecordDecl *Record = cast<CXXRecordDecl>(DC); | 
| Douglas Gregor | dec0666 | 2009-08-21 18:42:58 +0000 | [diff] [blame] | 1370 |   CXXMethodDecl *Method = 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1371 |  | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1372 |   SourceLocation StartLoc = D->getInnerLocStart(); | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1373 |   DeclarationNameInfo NameInfo | 
 | 1374 |     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); | 
| Douglas Gregor | 17e32f3 | 2009-08-21 22:43:28 +0000 | [diff] [blame] | 1375 |   if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(D)) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1376 |     Method = CXXConstructorDecl::Create(SemaRef.Context, Record, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1377 |                                         StartLoc, NameInfo, T, TInfo, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1378 |                                         Constructor->isExplicit(), | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 1379 |                                         Constructor->isInlineSpecified(), | 
| Sean Hunt | 5f802e5 | 2011-05-06 00:11:07 +0000 | [diff] [blame] | 1380 |                                         false); | 
| Douglas Gregor | 17e32f3 | 2009-08-21 22:43:28 +0000 | [diff] [blame] | 1381 |   } else if (CXXDestructorDecl *Destructor = dyn_cast<CXXDestructorDecl>(D)) { | 
| Douglas Gregor | 17e32f3 | 2009-08-21 22:43:28 +0000 | [diff] [blame] | 1382 |     Method = CXXDestructorDecl::Create(SemaRef.Context, Record, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1383 |                                        StartLoc, NameInfo, T, TInfo, | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1384 |                                        Destructor->isInlineSpecified(), | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 1385 |                                        false); | 
| Douglas Gregor | 65ec1fd | 2009-08-21 23:19:43 +0000 | [diff] [blame] | 1386 |   } else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) { | 
| Douglas Gregor | 65ec1fd | 2009-08-21 23:19:43 +0000 | [diff] [blame] | 1387 |     Method = CXXConversionDecl::Create(SemaRef.Context, Record, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1388 |                                        StartLoc, NameInfo, T, TInfo, | 
| Douglas Gregor | 0130f3c | 2009-10-27 21:01:01 +0000 | [diff] [blame] | 1389 |                                        Conversion->isInlineSpecified(), | 
| Douglas Gregor | f525160 | 2011-03-08 17:10:18 +0000 | [diff] [blame] | 1390 |                                        Conversion->isExplicit(), | 
 | 1391 |                                        Conversion->getLocEnd()); | 
| Douglas Gregor | dec0666 | 2009-08-21 18:42:58 +0000 | [diff] [blame] | 1392 |   } else { | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1393 |     Method = CXXMethodDecl::Create(SemaRef.Context, Record, | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1394 |                                    StartLoc, NameInfo, T, TInfo, | 
| Douglas Gregor | 16573fa | 2010-04-19 22:54:31 +0000 | [diff] [blame] | 1395 |                                    D->isStatic(), | 
 | 1396 |                                    D->getStorageClassAsWritten(), | 
| Douglas Gregor | f525160 | 2011-03-08 17:10:18 +0000 | [diff] [blame] | 1397 |                                    D->isInlineSpecified(), | 
 | 1398 |                                    D->getLocEnd()); | 
| Douglas Gregor | dec0666 | 2009-08-21 18:42:58 +0000 | [diff] [blame] | 1399 |   } | 
| Douglas Gregor | 6b90686 | 2009-08-21 00:16:32 +0000 | [diff] [blame] | 1400 |  | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 1401 |   if (QualifierLoc) | 
 | 1402 |     Method->setQualifierInfo(QualifierLoc); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 1403 |  | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 1404 |   if (TemplateParams) { | 
 | 1405 |     // Our resulting instantiation is actually a function template, since we | 
 | 1406 |     // are substituting only the outer template parameters. For example, given | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1407 |     // | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 1408 |     //   template<typename T> | 
 | 1409 |     //   struct X { | 
 | 1410 |     //     template<typename U> void f(T, U); | 
 | 1411 |     //   }; | 
 | 1412 |     // | 
 | 1413 |     //   X<int> x; | 
 | 1414 |     // | 
 | 1415 |     // We are instantiating the member template "f" within X<int>, which means | 
 | 1416 |     // substituting int for T, but leaving "f" as a member function template. | 
 | 1417 |     // Build the function template itself. | 
 | 1418 |     FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, Record, | 
 | 1419 |                                                     Method->getLocation(), | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1420 |                                                     Method->getDeclName(), | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 1421 |                                                     TemplateParams, Method); | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1422 |     if (isFriend) { | 
 | 1423 |       FunctionTemplate->setLexicalDeclContext(Owner); | 
 | 1424 |       FunctionTemplate->setObjectOfFriendDecl(true); | 
 | 1425 |     } else if (D->isOutOfLine()) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1426 |       FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext()); | 
| Douglas Gregor | d60e105 | 2009-08-27 16:57:43 +0000 | [diff] [blame] | 1427 |     Method->setDescribedFunctionTemplate(FunctionTemplate); | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 1428 |   } else if (FunctionTemplate) { | 
 | 1429 |     // Record this function template specialization. | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 1430 |     std::pair<const TemplateArgument *, unsigned> Innermost  | 
 | 1431 |       = TemplateArgs.getInnermost(); | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1432 |     Method->setFunctionTemplateSpecialization(FunctionTemplate, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1433 |                          TemplateArgumentList::CreateCopy(SemaRef.Context, | 
 | 1434 |                                                           Innermost.first, | 
 | 1435 |                                                           Innermost.second), | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 1436 |                                               InsertPos); | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1437 |   } else if (!isFriend) { | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 1438 |     // Record that this is an instantiation of a member function. | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 1439 |     Method->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation); | 
| Douglas Gregor | 66724ea | 2009-11-14 01:20:54 +0000 | [diff] [blame] | 1440 |   } | 
 | 1441 |    | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1442 |   // If we are instantiating a member function defined | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 1443 |   // out-of-line, the instantiation will have the same lexical | 
 | 1444 |   // context (which will be a namespace scope) as the template. | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1445 |   if (isFriend) { | 
| John McCall | 4eab39f | 2010-10-19 02:26:41 +0000 | [diff] [blame] | 1446 |     if (NumTempParamLists) | 
 | 1447 |       Method->setTemplateParameterListsInfo(SemaRef.Context, | 
 | 1448 |                                             NumTempParamLists, | 
 | 1449 |                                             TempParamLists.data()); | 
 | 1450 |  | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1451 |     Method->setLexicalDeclContext(Owner); | 
 | 1452 |     Method->setObjectOfFriendDecl(true); | 
 | 1453 |   } else if (D->isOutOfLine()) | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 1454 |     Method->setLexicalDeclContext(D->getLexicalDeclContext()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1455 |  | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 1456 |   // Attach the parameters | 
 | 1457 |   for (unsigned P = 0; P < Params.size(); ++P) | 
 | 1458 |     Params[P]->setOwningFunction(Method); | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 1459 |   Method->setParams(Params.data(), Params.size()); | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 1460 |  | 
 | 1461 |   if (InitMethodInstantiation(Method, D)) | 
 | 1462 |     Method->setInvalidDecl(); | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1463 |  | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1464 |   LookupResult Previous(SemaRef, NameInfo, Sema::LookupOrdinaryName, | 
 | 1465 |                         Sema::ForRedeclaration); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1466 |  | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1467 |   if (!FunctionTemplate || TemplateParams || isFriend) { | 
 | 1468 |     SemaRef.LookupQualifiedName(Previous, Record); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1469 |  | 
| Douglas Gregor | dec0666 | 2009-08-21 18:42:58 +0000 | [diff] [blame] | 1470 |     // In C++, the previous declaration we find might be a tag type | 
 | 1471 |     // (class or enum). In this case, the new declaration will hide the | 
 | 1472 |     // tag type. Note that this does does not apply if we're declaring a | 
 | 1473 |     // typedef (C++ [dcl.typedef]p4). | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 1474 |     if (Previous.isSingleTagDecl()) | 
 | 1475 |       Previous.clear(); | 
| Douglas Gregor | dec0666 | 2009-08-21 18:42:58 +0000 | [diff] [blame] | 1476 |   } | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1477 |  | 
| Douglas Gregor | 65ec1fd | 2009-08-21 23:19:43 +0000 | [diff] [blame] | 1478 |   bool Redeclaration = false; | 
| Peter Collingbourne | c80e811 | 2011-01-21 02:08:54 +0000 | [diff] [blame] | 1479 |   SemaRef.CheckFunctionDeclaration(0, Method, Previous, false, Redeclaration); | 
| Douglas Gregor | 65ec1fd | 2009-08-21 23:19:43 +0000 | [diff] [blame] | 1480 |  | 
| Douglas Gregor | 4ba3136 | 2009-12-01 17:24:26 +0000 | [diff] [blame] | 1481 |   if (D->isPure()) | 
 | 1482 |     SemaRef.CheckPureMethod(Method, SourceRange()); | 
 | 1483 |  | 
| John McCall | 46460a6 | 2010-01-20 21:53:11 +0000 | [diff] [blame] | 1484 |   Method->setAccess(D->getAccess()); | 
 | 1485 |  | 
| Anders Carlsson | 9eefa22 | 2011-01-20 06:52:44 +0000 | [diff] [blame] | 1486 |   SemaRef.CheckOverrideControl(Method); | 
 | 1487 |  | 
| John McCall | b0cb022 | 2010-03-27 05:57:59 +0000 | [diff] [blame] | 1488 |   if (FunctionTemplate) { | 
 | 1489 |     // If there's a function template, let our caller handle it. | 
 | 1490 |   } else if (Method->isInvalidDecl() && !Previous.empty()) { | 
 | 1491 |     // Don't hide a (potentially) valid declaration with an invalid one. | 
 | 1492 |   } else { | 
 | 1493 |     NamedDecl *DeclToAdd = (TemplateParams | 
 | 1494 |                             ? cast<NamedDecl>(FunctionTemplate) | 
 | 1495 |                             : Method); | 
 | 1496 |     if (isFriend) | 
 | 1497 |       Record->makeDeclVisibleInContext(DeclToAdd); | 
 | 1498 |     else | 
 | 1499 |       Owner->addDecl(DeclToAdd); | 
 | 1500 |   } | 
| Sean Hunt | eb88ae5 | 2011-05-23 21:07:59 +0000 | [diff] [blame] | 1501 |  | 
 | 1502 |   if (D->isExplicitlyDefaulted()) { | 
 | 1503 |     SemaRef.SetDeclDefaulted(Method, Method->getLocation()); | 
 | 1504 |   } else { | 
 | 1505 |     assert(!D->isDefaulted() && | 
 | 1506 |            "should not implicitly default uninstantiated function"); | 
 | 1507 |   } | 
 | 1508 |  | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1509 |   return Method; | 
 | 1510 | } | 
 | 1511 |  | 
| Douglas Gregor | 615c5d4 | 2009-03-24 16:43:20 +0000 | [diff] [blame] | 1512 | Decl *TemplateDeclInstantiator::VisitCXXConstructorDecl(CXXConstructorDecl *D) { | 
| Douglas Gregor | dec0666 | 2009-08-21 18:42:58 +0000 | [diff] [blame] | 1513 |   return VisitCXXMethodDecl(D); | 
| Douglas Gregor | 615c5d4 | 2009-03-24 16:43:20 +0000 | [diff] [blame] | 1514 | } | 
 | 1515 |  | 
| Douglas Gregor | 03b2b07 | 2009-03-24 00:15:49 +0000 | [diff] [blame] | 1516 | Decl *TemplateDeclInstantiator::VisitCXXDestructorDecl(CXXDestructorDecl *D) { | 
| Douglas Gregor | 17e32f3 | 2009-08-21 22:43:28 +0000 | [diff] [blame] | 1517 |   return VisitCXXMethodDecl(D); | 
| Douglas Gregor | 03b2b07 | 2009-03-24 00:15:49 +0000 | [diff] [blame] | 1518 | } | 
 | 1519 |  | 
| Douglas Gregor | bb969ed | 2009-03-25 00:34:44 +0000 | [diff] [blame] | 1520 | Decl *TemplateDeclInstantiator::VisitCXXConversionDecl(CXXConversionDecl *D) { | 
| Douglas Gregor | 65ec1fd | 2009-08-21 23:19:43 +0000 | [diff] [blame] | 1521 |   return VisitCXXMethodDecl(D); | 
| Douglas Gregor | bb969ed | 2009-03-25 00:34:44 +0000 | [diff] [blame] | 1522 | } | 
 | 1523 |  | 
| Douglas Gregor | 6477b69 | 2009-03-25 15:04:13 +0000 | [diff] [blame] | 1524 | ParmVarDecl *TemplateDeclInstantiator::VisitParmVarDecl(ParmVarDecl *D) { | 
| John McCall | fb44de9 | 2011-05-01 22:35:37 +0000 | [diff] [blame] | 1525 |   return SemaRef.SubstParmVarDecl(D, TemplateArgs, /*indexAdjustment*/ 0, | 
 | 1526 |                                   llvm::Optional<unsigned>()); | 
| Douglas Gregor | 2dc0e64 | 2009-03-23 23:06:20 +0000 | [diff] [blame] | 1527 | } | 
 | 1528 |  | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1529 | Decl *TemplateDeclInstantiator::VisitTemplateTypeParmDecl( | 
 | 1530 |                                                     TemplateTypeParmDecl *D) { | 
 | 1531 |   // TODO: don't always clone when decls are refcounted. | 
| Chandler Carruth | 4fb86f8 | 2011-05-01 00:51:33 +0000 | [diff] [blame] | 1532 |   assert(D->getTypeForDecl()->isTemplateTypeParmType()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1533 |  | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1534 |   TemplateTypeParmDecl *Inst = | 
| Abramo Bagnara | 344577e | 2011-03-06 15:48:19 +0000 | [diff] [blame] | 1535 |     TemplateTypeParmDecl::Create(SemaRef.Context, Owner, | 
 | 1536 |                                  D->getLocStart(), D->getLocation(), | 
| Chandler Carruth | 4fb86f8 | 2011-05-01 00:51:33 +0000 | [diff] [blame] | 1537 |                                  D->getDepth() - TemplateArgs.getNumLevels(), | 
 | 1538 |                                  D->getIndex(), D->getIdentifier(), | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1539 |                                  D->wasDeclaredWithTypename(), | 
 | 1540 |                                  D->isParameterPack()); | 
| Douglas Gregor | 9a299e0 | 2011-03-04 17:52:15 +0000 | [diff] [blame] | 1541 |   Inst->setAccess(AS_public); | 
 | 1542 |    | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 1543 |   if (D->hasDefaultArgument()) | 
 | 1544 |     Inst->setDefaultArgument(D->getDefaultArgumentInfo(), false);   | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1545 |  | 
| Douglas Gregor | 550d9b2 | 2009-10-31 17:21:17 +0000 | [diff] [blame] | 1546 |   // Introduce this template parameter's instantiation into the instantiation  | 
 | 1547 |   // scope. | 
 | 1548 |   SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Inst); | 
 | 1549 |    | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1550 |   return Inst; | 
 | 1551 | } | 
 | 1552 |  | 
| Douglas Gregor | 33642df | 2009-10-23 23:25:44 +0000 | [diff] [blame] | 1553 | Decl *TemplateDeclInstantiator::VisitNonTypeTemplateParmDecl( | 
 | 1554 |                                                  NonTypeTemplateParmDecl *D) { | 
 | 1555 |   // Substitute into the type of the non-type template parameter. | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 1556 |   TypeLoc TL = D->getTypeSourceInfo()->getTypeLoc(); | 
 | 1557 |   llvm::SmallVector<TypeSourceInfo *, 4> ExpandedParameterPackTypesAsWritten; | 
 | 1558 |   llvm::SmallVector<QualType, 4> ExpandedParameterPackTypes; | 
 | 1559 |   bool IsExpandedParameterPack = false; | 
 | 1560 |   TypeSourceInfo *DI;   | 
| Douglas Gregor | 33642df | 2009-10-23 23:25:44 +0000 | [diff] [blame] | 1561 |   QualType T; | 
| Douglas Gregor | 33642df | 2009-10-23 23:25:44 +0000 | [diff] [blame] | 1562 |   bool Invalid = false; | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 1563 |  | 
 | 1564 |   if (D->isExpandedParameterPack()) { | 
 | 1565 |     // The non-type template parameter pack is an already-expanded pack  | 
 | 1566 |     // expansion of types. Substitute into each of the expanded types. | 
 | 1567 |     ExpandedParameterPackTypes.reserve(D->getNumExpansionTypes()); | 
 | 1568 |     ExpandedParameterPackTypesAsWritten.reserve(D->getNumExpansionTypes()); | 
 | 1569 |     for (unsigned I = 0, N = D->getNumExpansionTypes(); I != N; ++I) { | 
 | 1570 |       TypeSourceInfo *NewDI =SemaRef.SubstType(D->getExpansionTypeSourceInfo(I), | 
 | 1571 |                                                TemplateArgs, | 
 | 1572 |                                                D->getLocation(),  | 
 | 1573 |                                                D->getDeclName()); | 
 | 1574 |       if (!NewDI) | 
 | 1575 |         return 0; | 
 | 1576 |        | 
 | 1577 |       ExpandedParameterPackTypesAsWritten.push_back(NewDI); | 
 | 1578 |       QualType NewT =SemaRef.CheckNonTypeTemplateParameterType(NewDI->getType(), | 
 | 1579 |                                                               D->getLocation()); | 
 | 1580 |       if (NewT.isNull()) | 
 | 1581 |         return 0; | 
 | 1582 |       ExpandedParameterPackTypes.push_back(NewT); | 
 | 1583 |     } | 
 | 1584 |      | 
 | 1585 |     IsExpandedParameterPack = true; | 
 | 1586 |     DI = D->getTypeSourceInfo(); | 
 | 1587 |     T = DI->getType(); | 
 | 1588 |   } else if (isa<PackExpansionTypeLoc>(TL)) { | 
 | 1589 |     // The non-type template parameter pack's type is a pack expansion of types. | 
 | 1590 |     // Determine whether we need to expand this parameter pack into separate | 
 | 1591 |     // types. | 
 | 1592 |     PackExpansionTypeLoc Expansion = cast<PackExpansionTypeLoc>(TL); | 
 | 1593 |     TypeLoc Pattern = Expansion.getPatternLoc(); | 
 | 1594 |     llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
 | 1595 |     SemaRef.collectUnexpandedParameterPacks(Pattern, Unexpanded); | 
 | 1596 |      | 
 | 1597 |     // Determine whether the set of unexpanded parameter packs can and should | 
 | 1598 |     // be expanded. | 
 | 1599 |     bool Expand = true; | 
 | 1600 |     bool RetainExpansion = false; | 
 | 1601 |     llvm::Optional<unsigned> OrigNumExpansions | 
 | 1602 |       = Expansion.getTypePtr()->getNumExpansions(); | 
 | 1603 |     llvm::Optional<unsigned> NumExpansions = OrigNumExpansions; | 
 | 1604 |     if (SemaRef.CheckParameterPacksForExpansion(Expansion.getEllipsisLoc(), | 
 | 1605 |                                                 Pattern.getSourceRange(), | 
 | 1606 |                                                 Unexpanded.data(), | 
 | 1607 |                                                 Unexpanded.size(), | 
 | 1608 |                                                 TemplateArgs, | 
 | 1609 |                                                 Expand, RetainExpansion,  | 
 | 1610 |                                                 NumExpansions)) | 
 | 1611 |       return 0; | 
 | 1612 |      | 
 | 1613 |     if (Expand) { | 
 | 1614 |       for (unsigned I = 0; I != *NumExpansions; ++I) { | 
 | 1615 |         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, I); | 
 | 1616 |         TypeSourceInfo *NewDI = SemaRef.SubstType(Pattern, TemplateArgs, | 
 | 1617 |                                                   D->getLocation(),  | 
 | 1618 |                                                   D->getDeclName()); | 
 | 1619 |         if (!NewDI) | 
 | 1620 |           return 0; | 
 | 1621 |          | 
 | 1622 |         ExpandedParameterPackTypesAsWritten.push_back(NewDI); | 
 | 1623 |         QualType NewT = SemaRef.CheckNonTypeTemplateParameterType( | 
 | 1624 |                                                               NewDI->getType(), | 
 | 1625 |                                                               D->getLocation()); | 
 | 1626 |         if (NewT.isNull()) | 
 | 1627 |           return 0; | 
 | 1628 |         ExpandedParameterPackTypes.push_back(NewT); | 
 | 1629 |       } | 
 | 1630 |        | 
 | 1631 |       // Note that we have an expanded parameter pack. The "type" of this | 
 | 1632 |       // expanded parameter pack is the original expansion type, but callers | 
 | 1633 |       // will end up using the expanded parameter pack types for type-checking. | 
 | 1634 |       IsExpandedParameterPack = true; | 
 | 1635 |       DI = D->getTypeSourceInfo(); | 
 | 1636 |       T = DI->getType(); | 
 | 1637 |     } else { | 
 | 1638 |       // We cannot fully expand the pack expansion now, so substitute into the | 
 | 1639 |       // pattern and create a new pack expansion type. | 
 | 1640 |       Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); | 
 | 1641 |       TypeSourceInfo *NewPattern = SemaRef.SubstType(Pattern, TemplateArgs, | 
 | 1642 |                                                      D->getLocation(),  | 
 | 1643 |                                                      D->getDeclName()); | 
 | 1644 |       if (!NewPattern) | 
 | 1645 |         return 0; | 
 | 1646 |        | 
 | 1647 |       DI = SemaRef.CheckPackExpansion(NewPattern, Expansion.getEllipsisLoc(), | 
 | 1648 |                                       NumExpansions); | 
 | 1649 |       if (!DI) | 
 | 1650 |         return 0; | 
 | 1651 |        | 
 | 1652 |       T = DI->getType(); | 
 | 1653 |     } | 
 | 1654 |   } else { | 
 | 1655 |     // Simple case: substitution into a parameter that is not a parameter pack. | 
 | 1656 |     DI = SemaRef.SubstType(D->getTypeSourceInfo(), TemplateArgs,  | 
 | 1657 |                            D->getLocation(), D->getDeclName()); | 
 | 1658 |     if (!DI) | 
 | 1659 |       return 0; | 
 | 1660 |      | 
 | 1661 |     // Check that this type is acceptable for a non-type template parameter. | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 1662 |     T = SemaRef.CheckNonTypeTemplateParameterType(DI->getType(),  | 
 | 1663 |                                                   D->getLocation()); | 
 | 1664 |     if (T.isNull()) { | 
 | 1665 |       T = SemaRef.Context.IntTy; | 
 | 1666 |       Invalid = true; | 
 | 1667 |     } | 
| Douglas Gregor | 33642df | 2009-10-23 23:25:44 +0000 | [diff] [blame] | 1668 |   } | 
 | 1669 |    | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 1670 |   NonTypeTemplateParmDecl *Param; | 
 | 1671 |   if (IsExpandedParameterPack) | 
 | 1672 |     Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,  | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1673 |                                             D->getInnerLocStart(), | 
 | 1674 |                                             D->getLocation(), | 
| Douglas Gregor | 71b87e4 | 2010-08-30 23:23:59 +0000 | [diff] [blame] | 1675 |                                     D->getDepth() - TemplateArgs.getNumLevels(),  | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 1676 |                                             D->getPosition(),  | 
 | 1677 |                                             D->getIdentifier(), T, | 
 | 1678 |                                             DI, | 
 | 1679 |                                             ExpandedParameterPackTypes.data(), | 
 | 1680 |                                             ExpandedParameterPackTypes.size(), | 
 | 1681 |                                     ExpandedParameterPackTypesAsWritten.data()); | 
 | 1682 |   else | 
 | 1683 |     Param = NonTypeTemplateParmDecl::Create(SemaRef.Context, Owner,  | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 1684 |                                             D->getInnerLocStart(), | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 1685 |                                             D->getLocation(), | 
 | 1686 |                                     D->getDepth() - TemplateArgs.getNumLevels(),  | 
 | 1687 |                                             D->getPosition(),  | 
 | 1688 |                                             D->getIdentifier(), T,  | 
 | 1689 |                                             D->isParameterPack(), DI); | 
 | 1690 |    | 
| Douglas Gregor | 9a299e0 | 2011-03-04 17:52:15 +0000 | [diff] [blame] | 1691 |   Param->setAccess(AS_public); | 
| Douglas Gregor | 33642df | 2009-10-23 23:25:44 +0000 | [diff] [blame] | 1692 |   if (Invalid) | 
 | 1693 |     Param->setInvalidDecl(); | 
 | 1694 |    | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 1695 |   Param->setDefaultArgument(D->getDefaultArgument(), false); | 
| Douglas Gregor | 550d9b2 | 2009-10-31 17:21:17 +0000 | [diff] [blame] | 1696 |    | 
 | 1697 |   // Introduce this template parameter's instantiation into the instantiation  | 
 | 1698 |   // scope. | 
 | 1699 |   SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); | 
| Douglas Gregor | 33642df | 2009-10-23 23:25:44 +0000 | [diff] [blame] | 1700 |   return Param; | 
 | 1701 | } | 
 | 1702 |  | 
| Anders Carlsson | 0dde18e | 2009-08-28 15:18:15 +0000 | [diff] [blame] | 1703 | Decl * | 
| Douglas Gregor | 9106ef7 | 2009-11-11 16:58:32 +0000 | [diff] [blame] | 1704 | TemplateDeclInstantiator::VisitTemplateTemplateParmDecl( | 
 | 1705 |                                                   TemplateTemplateParmDecl *D) { | 
 | 1706 |   // Instantiate the template parameter list of the template template parameter. | 
 | 1707 |   TemplateParameterList *TempParams = D->getTemplateParameters(); | 
 | 1708 |   TemplateParameterList *InstParams; | 
 | 1709 |   { | 
 | 1710 |     // Perform the actual substitution of template parameters within a new, | 
 | 1711 |     // local instantiation scope. | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 1712 |     LocalInstantiationScope Scope(SemaRef); | 
| Douglas Gregor | 9106ef7 | 2009-11-11 16:58:32 +0000 | [diff] [blame] | 1713 |     InstParams = SubstTemplateParams(TempParams); | 
 | 1714 |     if (!InstParams) | 
 | 1715 |       return NULL; | 
 | 1716 |   }   | 
 | 1717 |    | 
 | 1718 |   // Build the template template parameter. | 
 | 1719 |   TemplateTemplateParmDecl *Param | 
 | 1720 |     = TemplateTemplateParmDecl::Create(SemaRef.Context, Owner, D->getLocation(), | 
| Douglas Gregor | 71b87e4 | 2010-08-30 23:23:59 +0000 | [diff] [blame] | 1721 |                                    D->getDepth() - TemplateArgs.getNumLevels(),  | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 1722 |                                        D->getPosition(), D->isParameterPack(),  | 
 | 1723 |                                        D->getIdentifier(), InstParams); | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 1724 |   Param->setDefaultArgument(D->getDefaultArgument(), false); | 
| Douglas Gregor | 9a299e0 | 2011-03-04 17:52:15 +0000 | [diff] [blame] | 1725 |   Param->setAccess(AS_public); | 
| Douglas Gregor | 4469e8a | 2010-05-19 17:02:24 +0000 | [diff] [blame] | 1726 |    | 
| Douglas Gregor | 9106ef7 | 2009-11-11 16:58:32 +0000 | [diff] [blame] | 1727 |   // Introduce this template parameter's instantiation into the instantiation  | 
 | 1728 |   // scope. | 
 | 1729 |   SemaRef.CurrentInstantiationScope->InstantiatedLocal(D, Param); | 
 | 1730 |    | 
 | 1731 |   return Param; | 
 | 1732 | } | 
 | 1733 |  | 
| Douglas Gregor | 48c32a7 | 2009-11-17 06:07:40 +0000 | [diff] [blame] | 1734 | Decl *TemplateDeclInstantiator::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { | 
| Douglas Gregor | db99241 | 2011-02-25 16:33:46 +0000 | [diff] [blame] | 1735 |   // Using directives are never dependent (and never contain any types or | 
 | 1736 |   // expressions), so they require no explicit instantiation work. | 
| Douglas Gregor | 48c32a7 | 2009-11-17 06:07:40 +0000 | [diff] [blame] | 1737 |    | 
 | 1738 |   UsingDirectiveDecl *Inst | 
 | 1739 |     = UsingDirectiveDecl::Create(SemaRef.Context, Owner, D->getLocation(), | 
 | 1740 |                                  D->getNamespaceKeyLocation(),  | 
| Douglas Gregor | db99241 | 2011-02-25 16:33:46 +0000 | [diff] [blame] | 1741 |                                  D->getQualifierLoc(), | 
| Douglas Gregor | 48c32a7 | 2009-11-17 06:07:40 +0000 | [diff] [blame] | 1742 |                                  D->getIdentLocation(),  | 
 | 1743 |                                  D->getNominatedNamespace(),  | 
 | 1744 |                                  D->getCommonAncestor()); | 
 | 1745 |   Owner->addDecl(Inst); | 
 | 1746 |   return Inst; | 
 | 1747 | } | 
 | 1748 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1749 | Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) { | 
| Douglas Gregor | 1b39820 | 2010-09-29 17:58:28 +0000 | [diff] [blame] | 1750 |  | 
 | 1751 |   // The nested name specifier may be dependent, for example | 
 | 1752 |   //     template <typename T> struct t { | 
 | 1753 |   //       struct s1 { T f1(); }; | 
 | 1754 |   //       struct s2 : s1 { using s1::f1; }; | 
 | 1755 |   //     }; | 
 | 1756 |   //     template struct t<int>; | 
 | 1757 |   // Here, in using s1::f1, s1 refers to t<T>::s1; | 
 | 1758 |   // we need to substitute for t<int>::s1. | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1759 |   NestedNameSpecifierLoc QualifierLoc | 
 | 1760 |     = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), | 
 | 1761 |                                           TemplateArgs); | 
 | 1762 |   if (!QualifierLoc) | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 1763 |     return 0; | 
| Douglas Gregor | 1b39820 | 2010-09-29 17:58:28 +0000 | [diff] [blame] | 1764 |  | 
 | 1765 |   // The name info is non-dependent, so no transformation | 
 | 1766 |   // is required. | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 1767 |   DeclarationNameInfo NameInfo = D->getNameInfo(); | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1768 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1769 |   // We only need to do redeclaration lookups if we're in a class | 
 | 1770 |   // scope (in fact, it's not really even possible in non-class | 
 | 1771 |   // scopes). | 
 | 1772 |   bool CheckRedeclaration = Owner->isRecord(); | 
 | 1773 |  | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 1774 |   LookupResult Prev(SemaRef, NameInfo, Sema::LookupUsingDeclName, | 
 | 1775 |                     Sema::ForRedeclaration); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1776 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1777 |   UsingDecl *NewUD = UsingDecl::Create(SemaRef.Context, Owner, | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1778 |                                        D->getUsingLocation(), | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1779 |                                        QualifierLoc, | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 1780 |                                        NameInfo, | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1781 |                                        D->isTypeName()); | 
 | 1782 |  | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1783 |   CXXScopeSpec SS; | 
 | 1784 |   SS.Adopt(QualifierLoc); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1785 |   if (CheckRedeclaration) { | 
 | 1786 |     Prev.setHideTags(false); | 
 | 1787 |     SemaRef.LookupQualifiedName(Prev, Owner); | 
 | 1788 |  | 
 | 1789 |     // Check for invalid redeclarations. | 
 | 1790 |     if (SemaRef.CheckUsingDeclRedeclaration(D->getUsingLocation(), | 
 | 1791 |                                             D->isTypeName(), SS, | 
 | 1792 |                                             D->getLocation(), Prev)) | 
 | 1793 |       NewUD->setInvalidDecl(); | 
 | 1794 |  | 
 | 1795 |   } | 
 | 1796 |  | 
 | 1797 |   if (!NewUD->isInvalidDecl() && | 
 | 1798 |       SemaRef.CheckUsingDeclQualifier(D->getUsingLocation(), SS, | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1799 |                                       D->getLocation())) | 
 | 1800 |     NewUD->setInvalidDecl(); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1801 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1802 |   SemaRef.Context.setInstantiatedFromUsingDecl(NewUD, D); | 
 | 1803 |   NewUD->setAccess(D->getAccess()); | 
 | 1804 |   Owner->addDecl(NewUD); | 
 | 1805 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1806 |   // Don't process the shadow decls for an invalid decl. | 
 | 1807 |   if (NewUD->isInvalidDecl()) | 
 | 1808 |     return NewUD; | 
 | 1809 |  | 
| John McCall | 323c310 | 2009-12-22 22:26:37 +0000 | [diff] [blame] | 1810 |   bool isFunctionScope = Owner->isFunctionOrMethod(); | 
 | 1811 |  | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1812 |   // Process the shadow decls. | 
 | 1813 |   for (UsingDecl::shadow_iterator I = D->shadow_begin(), E = D->shadow_end(); | 
 | 1814 |          I != E; ++I) { | 
 | 1815 |     UsingShadowDecl *Shadow = *I; | 
 | 1816 |     NamedDecl *InstTarget = | 
| Douglas Gregor | b710722 | 2011-03-04 19:46:35 +0000 | [diff] [blame] | 1817 |       cast_or_null<NamedDecl>(SemaRef.FindInstantiatedDecl( | 
 | 1818 |                                                           Shadow->getLocation(), | 
 | 1819 |                                                         Shadow->getTargetDecl(), | 
 | 1820 |                                                            TemplateArgs)); | 
 | 1821 |     if (!InstTarget) | 
 | 1822 |       return 0; | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1823 |  | 
 | 1824 |     if (CheckRedeclaration && | 
 | 1825 |         SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev)) | 
 | 1826 |       continue; | 
 | 1827 |  | 
 | 1828 |     UsingShadowDecl *InstShadow | 
 | 1829 |       = SemaRef.BuildUsingShadowDecl(/*Scope*/ 0, NewUD, InstTarget); | 
 | 1830 |     SemaRef.Context.setInstantiatedFromUsingShadowDecl(InstShadow, Shadow); | 
| John McCall | 323c310 | 2009-12-22 22:26:37 +0000 | [diff] [blame] | 1831 |  | 
 | 1832 |     if (isFunctionScope) | 
 | 1833 |       SemaRef.CurrentInstantiationScope->InstantiatedLocal(Shadow, InstShadow); | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1834 |   } | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1835 |  | 
 | 1836 |   return NewUD; | 
 | 1837 | } | 
 | 1838 |  | 
 | 1839 | Decl *TemplateDeclInstantiator::VisitUsingShadowDecl(UsingShadowDecl *D) { | 
| John McCall | 9f54ad4 | 2009-12-10 09:41:52 +0000 | [diff] [blame] | 1840 |   // Ignore these;  we handle them in bulk when processing the UsingDecl. | 
 | 1841 |   return 0; | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1842 | } | 
 | 1843 |  | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1844 | Decl * TemplateDeclInstantiator | 
 | 1845 |     ::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1846 |   NestedNameSpecifierLoc QualifierLoc | 
 | 1847 |     = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(),  | 
 | 1848 |                                           TemplateArgs); | 
 | 1849 |   if (!QualifierLoc) | 
| Anders Carlsson | 0dde18e | 2009-08-28 15:18:15 +0000 | [diff] [blame] | 1850 |     return 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1851 |  | 
| Anders Carlsson | 0dde18e | 2009-08-28 15:18:15 +0000 | [diff] [blame] | 1852 |   CXXScopeSpec SS; | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1853 |   SS.Adopt(QualifierLoc); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1854 |  | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 1855 |   // Since NameInfo refers to a typename, it cannot be a C++ special name. | 
 | 1856 |   // Hence, no tranformation is required for it. | 
 | 1857 |   DeclarationNameInfo NameInfo(D->getDeclName(), D->getLocation()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1858 |   NamedDecl *UD = | 
| John McCall | 9488ea1 | 2009-11-17 05:59:44 +0000 | [diff] [blame] | 1859 |     SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(), | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 1860 |                                   D->getUsingLoc(), SS, NameInfo, 0, | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1861 |                                   /*instantiation*/ true, | 
 | 1862 |                                   /*typename*/ true, D->getTypenameLoc()); | 
| Douglas Gregor | 4469e8a | 2010-05-19 17:02:24 +0000 | [diff] [blame] | 1863 |   if (UD) | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1864 |     SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D); | 
 | 1865 |  | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1866 |   return UD; | 
 | 1867 | } | 
 | 1868 |  | 
 | 1869 | Decl * TemplateDeclInstantiator | 
 | 1870 |     ::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1871 |   NestedNameSpecifierLoc QualifierLoc | 
 | 1872 |       = SemaRef.SubstNestedNameSpecifierLoc(D->getQualifierLoc(), TemplateArgs); | 
 | 1873 |   if (!QualifierLoc) | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1874 |     return 0; | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1875 |    | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1876 |   CXXScopeSpec SS; | 
| Douglas Gregor | 5149f37 | 2011-02-25 15:54:31 +0000 | [diff] [blame] | 1877 |   SS.Adopt(QualifierLoc); | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1878 |  | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 1879 |   DeclarationNameInfo NameInfo | 
 | 1880 |     = SemaRef.SubstDeclarationNameInfo(D->getNameInfo(), TemplateArgs); | 
 | 1881 |  | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1882 |   NamedDecl *UD = | 
 | 1883 |     SemaRef.BuildUsingDeclaration(/*Scope*/ 0, D->getAccess(), | 
| Abramo Bagnara | ef3dce8 | 2010-08-12 11:46:03 +0000 | [diff] [blame] | 1884 |                                   D->getUsingLoc(), SS, NameInfo, 0, | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 1885 |                                   /*instantiation*/ true, | 
 | 1886 |                                   /*typename*/ false, SourceLocation()); | 
| Douglas Gregor | 4469e8a | 2010-05-19 17:02:24 +0000 | [diff] [blame] | 1887 |   if (UD) | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 1888 |     SemaRef.Context.setInstantiatedFromUsingDecl(cast<UsingDecl>(UD), D); | 
 | 1889 |  | 
| Anders Carlsson | 0d8df78 | 2009-08-29 19:37:28 +0000 | [diff] [blame] | 1890 |   return UD; | 
| Anders Carlsson | 0dde18e | 2009-08-28 15:18:15 +0000 | [diff] [blame] | 1891 | } | 
 | 1892 |  | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 1893 | Decl *Sema::SubstDecl(Decl *D, DeclContext *Owner, | 
| Douglas Gregor | d6350ae | 2009-08-28 20:31:08 +0000 | [diff] [blame] | 1894 |                       const MultiLevelTemplateArgumentList &TemplateArgs) { | 
| Douglas Gregor | 7e06390 | 2009-05-11 23:53:27 +0000 | [diff] [blame] | 1895 |   TemplateDeclInstantiator Instantiator(*this, Owner, TemplateArgs); | 
| Douglas Gregor | 2fa9800 | 2010-02-16 19:28:15 +0000 | [diff] [blame] | 1896 |   if (D->isInvalidDecl()) | 
 | 1897 |     return 0; | 
 | 1898 |  | 
| Douglas Gregor | 8dbc269 | 2009-03-17 21:15:40 +0000 | [diff] [blame] | 1899 |   return Instantiator.Visit(D); | 
 | 1900 | } | 
 | 1901 |  | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1902 | /// \brief Instantiates a nested template parameter list in the current | 
 | 1903 | /// instantiation context. | 
 | 1904 | /// | 
 | 1905 | /// \param L The parameter list to instantiate | 
 | 1906 | /// | 
 | 1907 | /// \returns NULL if there was an error | 
 | 1908 | TemplateParameterList * | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 1909 | TemplateDeclInstantiator::SubstTemplateParams(TemplateParameterList *L) { | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1910 |   // Get errors for all the parameters before bailing out. | 
 | 1911 |   bool Invalid = false; | 
 | 1912 |  | 
 | 1913 |   unsigned N = L->size(); | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 1914 |   typedef llvm::SmallVector<NamedDecl *, 8> ParamVector; | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1915 |   ParamVector Params; | 
 | 1916 |   Params.reserve(N); | 
 | 1917 |   for (TemplateParameterList::iterator PI = L->begin(), PE = L->end(); | 
 | 1918 |        PI != PE; ++PI) { | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 1919 |     NamedDecl *D = cast_or_null<NamedDecl>(Visit(*PI)); | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1920 |     Params.push_back(D); | 
| Douglas Gregor | 9148c3f | 2009-11-11 19:13:48 +0000 | [diff] [blame] | 1921 |     Invalid = Invalid || !D || D->isInvalidDecl(); | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1922 |   } | 
 | 1923 |  | 
 | 1924 |   // Clean up if we had an error. | 
| Douglas Gregor | ff331c1 | 2010-07-25 18:17:45 +0000 | [diff] [blame] | 1925 |   if (Invalid) | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1926 |     return NULL; | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1927 |  | 
 | 1928 |   TemplateParameterList *InstL | 
 | 1929 |     = TemplateParameterList::Create(SemaRef.Context, L->getTemplateLoc(), | 
 | 1930 |                                     L->getLAngleLoc(), &Params.front(), N, | 
 | 1931 |                                     L->getRAngleLoc()); | 
 | 1932 |   return InstL; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1933 | } | 
| John McCall | e29ba20 | 2009-08-20 01:44:21 +0000 | [diff] [blame] | 1934 |  | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1935 | /// \brief Instantiate the declaration of a class template partial  | 
 | 1936 | /// specialization. | 
 | 1937 | /// | 
 | 1938 | /// \param ClassTemplate the (instantiated) class template that is partially | 
 | 1939 | // specialized by the instantiation of \p PartialSpec. | 
 | 1940 | /// | 
 | 1941 | /// \param PartialSpec the (uninstantiated) class template partial  | 
 | 1942 | /// specialization that we are instantiating. | 
 | 1943 | /// | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 1944 | /// \returns The instantiated partial specialization, if successful; otherwise, | 
 | 1945 | /// NULL to indicate an error. | 
 | 1946 | ClassTemplatePartialSpecializationDecl * | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1947 | TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization( | 
 | 1948 |                                             ClassTemplateDecl *ClassTemplate, | 
 | 1949 |                           ClassTemplatePartialSpecializationDecl *PartialSpec) { | 
| Douglas Gregor | 550d9b2 | 2009-10-31 17:21:17 +0000 | [diff] [blame] | 1950 |   // Create a local instantiation scope for this class template partial | 
 | 1951 |   // specialization, which will contain the instantiations of the template | 
 | 1952 |   // parameters. | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 1953 |   LocalInstantiationScope Scope(SemaRef); | 
| Douglas Gregor | 550d9b2 | 2009-10-31 17:21:17 +0000 | [diff] [blame] | 1954 |    | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1955 |   // Substitute into the template parameters of the class template partial | 
 | 1956 |   // specialization. | 
 | 1957 |   TemplateParameterList *TempParams = PartialSpec->getTemplateParameters(); | 
 | 1958 |   TemplateParameterList *InstParams = SubstTemplateParams(TempParams); | 
 | 1959 |   if (!InstParams) | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 1960 |     return 0; | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1961 |    | 
 | 1962 |   // Substitute into the template arguments of the class template partial | 
 | 1963 |   // specialization. | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1964 |   TemplateArgumentListInfo InstTemplateArgs; // no angle locations | 
| Douglas Gregor | e02e262 | 2010-12-22 21:19:48 +0000 | [diff] [blame] | 1965 |   if (SemaRef.Subst(PartialSpec->getTemplateArgsAsWritten(),  | 
 | 1966 |                     PartialSpec->getNumTemplateArgsAsWritten(),  | 
 | 1967 |                     InstTemplateArgs, TemplateArgs)) | 
 | 1968 |     return 0; | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1969 |    | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1970 |   // Check that the template argument list is well-formed for this | 
 | 1971 |   // class template. | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1972 |   llvm::SmallVector<TemplateArgument, 4> Converted; | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1973 |   if (SemaRef.CheckTemplateArgumentList(ClassTemplate,  | 
 | 1974 |                                         PartialSpec->getLocation(), | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1975 |                                         InstTemplateArgs,  | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1976 |                                         false, | 
 | 1977 |                                         Converted)) | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 1978 |     return 0; | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1979 |  | 
 | 1980 |   // Figure out where to insert this class template partial specialization | 
 | 1981 |   // in the member template's set of class template partial specializations. | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1982 |   void *InsertPos = 0; | 
 | 1983 |   ClassTemplateSpecializationDecl *PrevDecl | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1984 |     = ClassTemplate->findPartialSpecialization(Converted.data(), | 
 | 1985 |                                                Converted.size(), InsertPos); | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1986 |    | 
 | 1987 |   // Build the canonical type that describes the converted template | 
 | 1988 |   // arguments of the class template partial specialization. | 
 | 1989 |   QualType CanonType  | 
 | 1990 |     = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate), | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1991 |                                                     Converted.data(), | 
 | 1992 |                                                     Converted.size()); | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 1993 |  | 
 | 1994 |   // Build the fully-sugared type for this class template | 
 | 1995 |   // specialization as the user wrote in the specialization | 
 | 1996 |   // itself. This means that we'll pretty-print the type retrieved | 
 | 1997 |   // from the specialization's declaration the way that the user | 
 | 1998 |   // actually wrote the specialization, rather than formatting the | 
 | 1999 |   // name based on the "canonical" representation used to store the | 
 | 2000 |   // template arguments in the specialization. | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 2001 |   TypeSourceInfo *WrittenTy | 
 | 2002 |     = SemaRef.Context.getTemplateSpecializationTypeInfo( | 
 | 2003 |                                                     TemplateName(ClassTemplate), | 
 | 2004 |                                                     PartialSpec->getLocation(), | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 2005 |                                                     InstTemplateArgs, | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2006 |                                                     CanonType); | 
 | 2007 |    | 
 | 2008 |   if (PrevDecl) { | 
 | 2009 |     // We've already seen a partial specialization with the same template | 
 | 2010 |     // parameters and template arguments. This can happen, for example, when | 
 | 2011 |     // substituting the outer template arguments ends up causing two | 
 | 2012 |     // class template partial specializations of a member class template | 
 | 2013 |     // to have identical forms, e.g., | 
 | 2014 |     // | 
 | 2015 |     //   template<typename T, typename U> | 
 | 2016 |     //   struct Outer { | 
 | 2017 |     //     template<typename X, typename Y> struct Inner; | 
 | 2018 |     //     template<typename Y> struct Inner<T, Y>; | 
 | 2019 |     //     template<typename Y> struct Inner<U, Y>; | 
 | 2020 |     //   }; | 
 | 2021 |     // | 
 | 2022 |     //   Outer<int, int> outer; // error: the partial specializations of Inner | 
 | 2023 |     //                          // have the same signature. | 
 | 2024 |     SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared) | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 2025 |       << WrittenTy->getType(); | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2026 |     SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here) | 
 | 2027 |       << SemaRef.Context.getTypeDeclType(PrevDecl); | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 2028 |     return 0; | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2029 |   } | 
 | 2030 |    | 
 | 2031 |    | 
 | 2032 |   // Create the class template partial specialization declaration. | 
 | 2033 |   ClassTemplatePartialSpecializationDecl *InstPartialSpec | 
| Douglas Gregor | 13c8577 | 2010-05-06 00:28:52 +0000 | [diff] [blame] | 2034 |     = ClassTemplatePartialSpecializationDecl::Create(SemaRef.Context,  | 
 | 2035 |                                                      PartialSpec->getTagKind(), | 
 | 2036 |                                                      Owner,  | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 2037 |                                                      PartialSpec->getLocStart(), | 
 | 2038 |                                                      PartialSpec->getLocation(), | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2039 |                                                      InstParams, | 
 | 2040 |                                                      ClassTemplate,  | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2041 |                                                      Converted.data(), | 
 | 2042 |                                                      Converted.size(), | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 2043 |                                                      InstTemplateArgs, | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 2044 |                                                      CanonType, | 
| Douglas Gregor | dc60c1e | 2010-04-30 05:56:50 +0000 | [diff] [blame] | 2045 |                                                      0, | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 2046 |                              ClassTemplate->getNextPartialSpecSequenceNumber()); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 2047 |   // Substitute the nested name specifier, if any. | 
 | 2048 |   if (SubstQualifier(PartialSpec, InstPartialSpec)) | 
 | 2049 |     return 0; | 
 | 2050 |  | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2051 |   InstPartialSpec->setInstantiatedFromMember(PartialSpec); | 
| Douglas Gregor | 4469e8a | 2010-05-19 17:02:24 +0000 | [diff] [blame] | 2052 |   InstPartialSpec->setTypeAsWritten(WrittenTy); | 
 | 2053 |    | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2054 |   // Add this partial specialization to the set of class template partial | 
 | 2055 |   // specializations. | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 2056 |   ClassTemplate->AddPartialSpecialization(InstPartialSpec, InsertPos); | 
| Douglas Gregor | d65587f | 2010-11-10 19:44:59 +0000 | [diff] [blame] | 2057 |   return InstPartialSpec; | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2058 | } | 
 | 2059 |  | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 2060 | TypeSourceInfo* | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 2061 | TemplateDeclInstantiator::SubstFunctionType(FunctionDecl *D, | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 2062 |                               llvm::SmallVectorImpl<ParmVarDecl *> &Params) { | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 2063 |   TypeSourceInfo *OldTInfo = D->getTypeSourceInfo(); | 
 | 2064 |   assert(OldTInfo && "substituting function without type source info"); | 
 | 2065 |   assert(Params.empty() && "parameter vector is non-empty at start"); | 
| John McCall | 6cd3b9f | 2010-04-09 17:38:44 +0000 | [diff] [blame] | 2066 |   TypeSourceInfo *NewTInfo | 
 | 2067 |     = SemaRef.SubstFunctionDeclType(OldTInfo, TemplateArgs, | 
 | 2068 |                                     D->getTypeSpecStartLoc(), | 
 | 2069 |                                     D->getDeclName()); | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 2070 |   if (!NewTInfo) | 
 | 2071 |     return 0; | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 2072 |  | 
| Douglas Gregor | cb27b0f | 2010-04-12 07:48:19 +0000 | [diff] [blame] | 2073 |   if (NewTInfo != OldTInfo) { | 
 | 2074 |     // Get parameters from the new type info. | 
| Abramo Bagnara | 140a2bd | 2010-12-13 22:27:55 +0000 | [diff] [blame] | 2075 |     TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); | 
| Douglas Gregor | 6920cdc | 2010-05-03 15:32:18 +0000 | [diff] [blame] | 2076 |     if (FunctionProtoTypeLoc *OldProtoLoc | 
 | 2077 |                                   = dyn_cast<FunctionProtoTypeLoc>(&OldTL)) { | 
| Abramo Bagnara | 140a2bd | 2010-12-13 22:27:55 +0000 | [diff] [blame] | 2078 |       TypeLoc NewTL = NewTInfo->getTypeLoc().IgnoreParens(); | 
| Douglas Gregor | 6920cdc | 2010-05-03 15:32:18 +0000 | [diff] [blame] | 2079 |       FunctionProtoTypeLoc *NewProtoLoc = cast<FunctionProtoTypeLoc>(&NewTL); | 
 | 2080 |       assert(NewProtoLoc && "Missing prototype?"); | 
| Douglas Gregor | 12c9c00 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 2081 |       unsigned NewIdx = 0, NumNewParams = NewProtoLoc->getNumArgs(); | 
 | 2082 |       for (unsigned OldIdx = 0, NumOldParams = OldProtoLoc->getNumArgs(); | 
 | 2083 |            OldIdx != NumOldParams; ++OldIdx) { | 
 | 2084 |         ParmVarDecl *OldParam = OldProtoLoc->getArg(OldIdx); | 
 | 2085 |         if (!OldParam->isParameterPack() || | 
 | 2086 |             (NewIdx < NumNewParams && | 
 | 2087 |              NewProtoLoc->getArg(NewIdx)->isParameterPack())) { | 
 | 2088 |           // Simple case: normal parameter, or a parameter pack that's  | 
 | 2089 |           // instantiated to a (still-dependent) parameter pack. | 
 | 2090 |           ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++); | 
 | 2091 |           Params.push_back(NewParam); | 
 | 2092 |           SemaRef.CurrentInstantiationScope->InstantiatedLocal(OldParam, | 
 | 2093 |                                                                NewParam); | 
 | 2094 |           continue; | 
 | 2095 |         } | 
 | 2096 |          | 
 | 2097 |         // Parameter pack: make the instantiation an argument pack. | 
 | 2098 |         SemaRef.CurrentInstantiationScope->MakeInstantiatedLocalArgPack( | 
 | 2099 |                                                                       OldParam); | 
| Douglas Gregor | 21371ea | 2011-01-11 03:14:20 +0000 | [diff] [blame] | 2100 |         unsigned NumArgumentsInExpansion | 
 | 2101 |           = SemaRef.getNumArgumentsInExpansion(OldParam->getType(), | 
 | 2102 |                                                TemplateArgs); | 
 | 2103 |         while (NumArgumentsInExpansion--) { | 
| Douglas Gregor | 12c9c00 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 2104 |           ParmVarDecl *NewParam = NewProtoLoc->getArg(NewIdx++); | 
 | 2105 |           Params.push_back(NewParam); | 
 | 2106 |           SemaRef.CurrentInstantiationScope->InstantiatedLocalPackArg(OldParam, | 
 | 2107 |                                                                       NewParam); | 
 | 2108 |         } | 
| Douglas Gregor | 6920cdc | 2010-05-03 15:32:18 +0000 | [diff] [blame] | 2109 |       } | 
| Douglas Gregor | 895162d | 2010-04-30 18:55:50 +0000 | [diff] [blame] | 2110 |     } | 
| Douglas Gregor | cb27b0f | 2010-04-12 07:48:19 +0000 | [diff] [blame] | 2111 |   } else { | 
 | 2112 |     // The function type itself was not dependent and therefore no | 
 | 2113 |     // substitution occurred. However, we still need to instantiate | 
 | 2114 |     // the function parameters themselves. | 
| Abramo Bagnara | 140a2bd | 2010-12-13 22:27:55 +0000 | [diff] [blame] | 2115 |     TypeLoc OldTL = OldTInfo->getTypeLoc().IgnoreParens(); | 
| Douglas Gregor | 6920cdc | 2010-05-03 15:32:18 +0000 | [diff] [blame] | 2116 |     if (FunctionProtoTypeLoc *OldProtoLoc | 
 | 2117 |                                     = dyn_cast<FunctionProtoTypeLoc>(&OldTL)) { | 
 | 2118 |       for (unsigned i = 0, i_end = OldProtoLoc->getNumArgs(); i != i_end; ++i) { | 
 | 2119 |         ParmVarDecl *Parm = VisitParmVarDecl(OldProtoLoc->getArg(i)); | 
 | 2120 |         if (!Parm) | 
 | 2121 |           return 0; | 
 | 2122 |         Params.push_back(Parm); | 
 | 2123 |       } | 
| Douglas Gregor | cb27b0f | 2010-04-12 07:48:19 +0000 | [diff] [blame] | 2124 |     } | 
 | 2125 |   } | 
| John McCall | 21ef0fa | 2010-03-11 09:03:00 +0000 | [diff] [blame] | 2126 |   return NewTInfo; | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 2127 | } | 
 | 2128 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2129 | /// \brief Initializes the common fields of an instantiation function | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 2130 | /// declaration (New) from the corresponding fields of its template (Tmpl). | 
 | 2131 | /// | 
 | 2132 | /// \returns true if there was an error | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2133 | bool | 
 | 2134 | TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New, | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 2135 |                                                     FunctionDecl *Tmpl) { | 
| Sean Hunt | 10620eb | 2011-05-06 20:44:56 +0000 | [diff] [blame] | 2136 |   if (Tmpl->isDeletedAsWritten()) | 
 | 2137 |     New->setDeletedAsWritten(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2138 |  | 
| Douglas Gregor | cca9e96 | 2009-07-01 22:01:06 +0000 | [diff] [blame] | 2139 |   // If we are performing substituting explicitly-specified template arguments | 
 | 2140 |   // or deduced template arguments into a function template and we reach this | 
 | 2141 |   // point, we are now past the point where SFINAE applies and have committed | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2142 |   // to keeping the new function template specialization. We therefore | 
 | 2143 |   // convert the active template instantiation for the function template | 
| Douglas Gregor | cca9e96 | 2009-07-01 22:01:06 +0000 | [diff] [blame] | 2144 |   // into a template instantiation for this specific function template | 
 | 2145 |   // specialization, which is not a SFINAE context, so that we diagnose any | 
 | 2146 |   // further errors in the declaration itself. | 
 | 2147 |   typedef Sema::ActiveTemplateInstantiation ActiveInstType; | 
 | 2148 |   ActiveInstType &ActiveInst = SemaRef.ActiveTemplateInstantiations.back(); | 
 | 2149 |   if (ActiveInst.Kind == ActiveInstType::ExplicitTemplateArgumentSubstitution || | 
 | 2150 |       ActiveInst.Kind == ActiveInstType::DeducedTemplateArgumentSubstitution) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2151 |     if (FunctionTemplateDecl *FunTmpl | 
| Douglas Gregor | cca9e96 | 2009-07-01 22:01:06 +0000 | [diff] [blame] | 2152 |           = dyn_cast<FunctionTemplateDecl>((Decl *)ActiveInst.Entity)) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2153 |       assert(FunTmpl->getTemplatedDecl() == Tmpl && | 
| Douglas Gregor | cca9e96 | 2009-07-01 22:01:06 +0000 | [diff] [blame] | 2154 |              "Deduction from the wrong function template?"); | 
| Daniel Dunbar | bcbb8bd | 2009-07-16 22:10:11 +0000 | [diff] [blame] | 2155 |       (void) FunTmpl; | 
| Douglas Gregor | cca9e96 | 2009-07-01 22:01:06 +0000 | [diff] [blame] | 2156 |       ActiveInst.Kind = ActiveInstType::TemplateInstantiation; | 
 | 2157 |       ActiveInst.Entity = reinterpret_cast<uintptr_t>(New); | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2158 |       --SemaRef.NonInstantiationEntries; | 
| Douglas Gregor | cca9e96 | 2009-07-01 22:01:06 +0000 | [diff] [blame] | 2159 |     } | 
 | 2160 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2161 |  | 
| Douglas Gregor | 0ae7b3f | 2009-12-08 17:45:32 +0000 | [diff] [blame] | 2162 |   const FunctionProtoType *Proto = Tmpl->getType()->getAs<FunctionProtoType>(); | 
 | 2163 |   assert(Proto && "Function template without prototype?"); | 
 | 2164 |  | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2165 |   if (Proto->hasExceptionSpec() || Proto->getNoReturnAttr()) { | 
| Douglas Gregor | 0ae7b3f | 2009-12-08 17:45:32 +0000 | [diff] [blame] | 2166 |     // The function has an exception specification or a "noreturn" | 
 | 2167 |     // attribute. Substitute into each of the exception types. | 
 | 2168 |     llvm::SmallVector<QualType, 4> Exceptions; | 
 | 2169 |     for (unsigned I = 0, N = Proto->getNumExceptions(); I != N; ++I) { | 
 | 2170 |       // FIXME: Poor location information! | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2171 |       if (const PackExpansionType *PackExpansion | 
 | 2172 |             = Proto->getExceptionType(I)->getAs<PackExpansionType>()) { | 
 | 2173 |         // We have a pack expansion. Instantiate it. | 
 | 2174 |         llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
 | 2175 |         SemaRef.collectUnexpandedParameterPacks(PackExpansion->getPattern(), | 
 | 2176 |                                                 Unexpanded); | 
 | 2177 |         assert(!Unexpanded.empty() &&  | 
 | 2178 |                "Pack expansion without parameter packs?"); | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2179 |  | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2180 |         bool Expand = false; | 
| Douglas Gregor | d373119 | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 2181 |         bool RetainExpansion = false; | 
| Douglas Gregor | cded4f6 | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 2182 |         llvm::Optional<unsigned> NumExpansions | 
 | 2183 |                                           = PackExpansion->getNumExpansions(); | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2184 |         if (SemaRef.CheckParameterPacksForExpansion(New->getLocation(),  | 
 | 2185 |                                                     SourceRange(), | 
 | 2186 |                                                     Unexpanded.data(),  | 
 | 2187 |                                                     Unexpanded.size(), | 
 | 2188 |                                                     TemplateArgs, | 
| Douglas Gregor | d373119 | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 2189 |                                                     Expand,  | 
 | 2190 |                                                     RetainExpansion, | 
 | 2191 |                                                     NumExpansions)) | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2192 |           break; | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2193 |  | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2194 |         if (!Expand) { | 
 | 2195 |           // We can't expand this pack expansion into separate arguments yet; | 
| Douglas Gregor | cded4f6 | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 2196 |           // just substitute into the pattern and create a new pack expansion  | 
 | 2197 |           // type. | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2198 |           Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, -1); | 
 | 2199 |           QualType T = SemaRef.SubstType(PackExpansion->getPattern(),  | 
 | 2200 |                                          TemplateArgs, | 
 | 2201 |                                        New->getLocation(), New->getDeclName()); | 
 | 2202 |           if (T.isNull()) | 
 | 2203 |             break; | 
 | 2204 |            | 
| Douglas Gregor | cded4f6 | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 2205 |           T = SemaRef.Context.getPackExpansionType(T, NumExpansions); | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2206 |           Exceptions.push_back(T); | 
 | 2207 |           continue; | 
 | 2208 |         } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2209 |  | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2210 |         // Substitute into the pack expansion pattern for each template | 
 | 2211 |         bool Invalid = false; | 
| Douglas Gregor | cded4f6 | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 2212 |         for (unsigned ArgIdx = 0; ArgIdx != *NumExpansions; ++ArgIdx) { | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2213 |           Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(SemaRef, ArgIdx); | 
 | 2214 |            | 
 | 2215 |           QualType T = SemaRef.SubstType(PackExpansion->getPattern(),  | 
 | 2216 |                                          TemplateArgs, | 
 | 2217 |                                        New->getLocation(), New->getDeclName()); | 
 | 2218 |           if (T.isNull()) { | 
 | 2219 |             Invalid = true; | 
 | 2220 |             break; | 
 | 2221 |           } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2222 |  | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2223 |           Exceptions.push_back(T); | 
 | 2224 |         } | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2225 |  | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2226 |         if (Invalid) | 
 | 2227 |           break; | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2228 |  | 
| Douglas Gregor | b99268b | 2010-12-21 00:52:54 +0000 | [diff] [blame] | 2229 |         continue; | 
 | 2230 |       } | 
 | 2231 |        | 
| Douglas Gregor | 0ae7b3f | 2009-12-08 17:45:32 +0000 | [diff] [blame] | 2232 |       QualType T | 
 | 2233 |         = SemaRef.SubstType(Proto->getExceptionType(I), TemplateArgs, | 
 | 2234 |                             New->getLocation(), New->getDeclName()); | 
 | 2235 |       if (T.isNull() ||  | 
 | 2236 |           SemaRef.CheckSpecifiedExceptionType(T, New->getLocation())) | 
 | 2237 |         continue; | 
 | 2238 |  | 
 | 2239 |       Exceptions.push_back(T); | 
 | 2240 |     } | 
| Sebastian Redl | 56fb926 | 2011-03-14 18:51:50 +0000 | [diff] [blame] | 2241 |     Expr *NoexceptExpr = 0; | 
 | 2242 |     if (Expr *OldNoexceptExpr = Proto->getNoexceptExpr()) { | 
| Douglas Gregor | 3617e19 | 2011-06-01 15:55:51 +0000 | [diff] [blame] | 2243 |       EnterExpressionEvaluationContext Unevaluated(SemaRef, Sema::Unevaluated); | 
| Sebastian Redl | 56fb926 | 2011-03-14 18:51:50 +0000 | [diff] [blame] | 2244 |       ExprResult E = SemaRef.SubstExpr(OldNoexceptExpr, TemplateArgs); | 
 | 2245 |       if (E.isUsable()) | 
 | 2246 |         NoexceptExpr = E.take(); | 
 | 2247 |     } | 
| Douglas Gregor | 0ae7b3f | 2009-12-08 17:45:32 +0000 | [diff] [blame] | 2248 |  | 
 | 2249 |     // Rebuild the function type  | 
 | 2250 |  | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 2251 |     FunctionProtoType::ExtProtoInfo EPI = Proto->getExtProtoInfo(); | 
| Sebastian Redl | 60618fa | 2011-03-12 11:50:43 +0000 | [diff] [blame] | 2252 |     EPI.ExceptionSpecType = Proto->getExceptionSpecType(); | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 2253 |     EPI.NumExceptions = Exceptions.size(); | 
 | 2254 |     EPI.Exceptions = Exceptions.data(); | 
| Sebastian Redl | 56fb926 | 2011-03-14 18:51:50 +0000 | [diff] [blame] | 2255 |     EPI.NoexceptExpr = NoexceptExpr; | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 2256 |     EPI.ExtInfo = Proto->getExtInfo(); | 
 | 2257 |  | 
| Douglas Gregor | 0ae7b3f | 2009-12-08 17:45:32 +0000 | [diff] [blame] | 2258 |     const FunctionProtoType *NewProto | 
 | 2259 |       = New->getType()->getAs<FunctionProtoType>(); | 
 | 2260 |     assert(NewProto && "Template instantiation without function prototype?"); | 
 | 2261 |     New->setType(SemaRef.Context.getFunctionType(NewProto->getResultType(), | 
 | 2262 |                                                  NewProto->arg_type_begin(), | 
 | 2263 |                                                  NewProto->getNumArgs(), | 
| John McCall | e23cf43 | 2010-12-14 08:05:40 +0000 | [diff] [blame] | 2264 |                                                  EPI)); | 
| Douglas Gregor | 0ae7b3f | 2009-12-08 17:45:32 +0000 | [diff] [blame] | 2265 |   } | 
 | 2266 |  | 
| John McCall | 1d8d1cc | 2010-08-01 02:01:53 +0000 | [diff] [blame] | 2267 |   SemaRef.InstantiateAttrs(TemplateArgs, Tmpl, New); | 
| Douglas Gregor | 7cf84d6 | 2010-06-15 17:05:35 +0000 | [diff] [blame] | 2268 |  | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 2269 |   return false; | 
 | 2270 | } | 
 | 2271 |  | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 2272 | /// \brief Initializes common fields of an instantiated method | 
 | 2273 | /// declaration (New) from the corresponding fields of its template | 
 | 2274 | /// (Tmpl). | 
 | 2275 | /// | 
 | 2276 | /// \returns true if there was an error | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2277 | bool | 
 | 2278 | TemplateDeclInstantiator::InitMethodInstantiation(CXXMethodDecl *New, | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 2279 |                                                   CXXMethodDecl *Tmpl) { | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 2280 |   if (InitFunctionInstantiation(New, Tmpl)) | 
 | 2281 |     return true; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2282 |  | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 2283 |   New->setAccess(Tmpl->getAccess()); | 
| Fariborz Jahanian | e7184df | 2009-12-03 18:44:40 +0000 | [diff] [blame] | 2284 |   if (Tmpl->isVirtualAsWritten()) | 
| Douglas Gregor | 85606eb | 2010-09-28 20:50:54 +0000 | [diff] [blame] | 2285 |     New->setVirtualAsWritten(true); | 
| Douglas Gregor | 5545e16 | 2009-03-24 00:38:23 +0000 | [diff] [blame] | 2286 |  | 
 | 2287 |   // FIXME: attributes | 
 | 2288 |   // FIXME: New needs a pointer to Tmpl | 
 | 2289 |   return false; | 
 | 2290 | } | 
| Douglas Gregor | a58861f | 2009-05-13 20:28:22 +0000 | [diff] [blame] | 2291 |  | 
 | 2292 | /// \brief Instantiate the definition of the given function from its | 
 | 2293 | /// template. | 
 | 2294 | /// | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2295 | /// \param PointOfInstantiation the point at which the instantiation was | 
 | 2296 | /// required. Note that this is not precisely a "point of instantiation" | 
 | 2297 | /// for the function, but it's close. | 
 | 2298 | /// | 
| Douglas Gregor | a58861f | 2009-05-13 20:28:22 +0000 | [diff] [blame] | 2299 | /// \param Function the already-instantiated declaration of a | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2300 | /// function template specialization or member function of a class template | 
 | 2301 | /// specialization. | 
 | 2302 | /// | 
 | 2303 | /// \param Recursive if true, recursively instantiates any functions that | 
 | 2304 | /// are required by this instantiation. | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2305 | /// | 
 | 2306 | /// \param DefinitionRequired if true, then we are performing an explicit | 
 | 2307 | /// instantiation where the body of the function is required. Complain if | 
 | 2308 | /// there is no such body. | 
| Douglas Gregor | f3e7ce4 | 2009-05-18 17:01:57 +0000 | [diff] [blame] | 2309 | void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2310 |                                          FunctionDecl *Function, | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2311 |                                          bool Recursive, | 
 | 2312 |                                          bool DefinitionRequired) { | 
| Sean Hunt | 10620eb | 2011-05-06 20:44:56 +0000 | [diff] [blame] | 2313 |   if (Function->isInvalidDecl() || Function->isDefined()) | 
| Douglas Gregor | 54dabfc | 2009-05-14 23:26:13 +0000 | [diff] [blame] | 2314 |     return; | 
 | 2315 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 2316 |   // Never instantiate an explicit specialization. | 
 | 2317 |   if (Function->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) | 
 | 2318 |     return; | 
| Douglas Gregor | 6cfacfe | 2010-05-17 17:34:56 +0000 | [diff] [blame] | 2319 |  | 
| Douglas Gregor | 1eee0e7 | 2009-05-14 21:06:31 +0000 | [diff] [blame] | 2320 |   // Find the function body that we'll be substituting. | 
| Douglas Gregor | 3b846b6 | 2009-10-27 20:53:28 +0000 | [diff] [blame] | 2321 |   const FunctionDecl *PatternDecl = Function->getTemplateInstantiationPattern(); | 
| Sean Hunt | f996e05 | 2011-05-27 20:00:14 +0000 | [diff] [blame] | 2322 |   assert(PatternDecl && "instantiating a non-template"); | 
 | 2323 |  | 
 | 2324 |   Stmt *Pattern = PatternDecl->getBody(PatternDecl); | 
 | 2325 |   assert(PatternDecl && "template definition is not a template"); | 
 | 2326 |   if (!Pattern) { | 
 | 2327 |     // Try to find a defaulted definition | 
 | 2328 |     PatternDecl->isDefined(PatternDecl); | 
| Sean Hunt | dfab854 | 2011-05-25 22:02:25 +0000 | [diff] [blame] | 2329 |   } | 
| Sean Hunt | f996e05 | 2011-05-27 20:00:14 +0000 | [diff] [blame] | 2330 |   assert(PatternDecl && "template definition is not a template"); | 
| Douglas Gregor | 1eee0e7 | 2009-05-14 21:06:31 +0000 | [diff] [blame] | 2331 |  | 
| Francois Pichet | 8387e2a | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 2332 |   // Postpone late parsed template instantiations. | 
| Sean Hunt | f996e05 | 2011-05-27 20:00:14 +0000 | [diff] [blame] | 2333 |   if (PatternDecl->isLateTemplateParsed() && | 
| Nick Lewycky | 8a29bc0 | 2011-05-12 03:51:24 +0000 | [diff] [blame] | 2334 |       !LateTemplateParser) { | 
| Francois Pichet | 8387e2a | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 2335 |     PendingInstantiations.push_back( | 
 | 2336 |       std::make_pair(Function, PointOfInstantiation)); | 
 | 2337 |     return; | 
 | 2338 |   } | 
 | 2339 |  | 
 | 2340 |   // Call the LateTemplateParser callback if there a need to late parse | 
 | 2341 |   // a templated function definition.  | 
| Sean Hunt | f996e05 | 2011-05-27 20:00:14 +0000 | [diff] [blame] | 2342 |   if (!Pattern && PatternDecl->isLateTemplateParsed() && | 
| Francois Pichet | 8387e2a | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 2343 |       LateTemplateParser) { | 
| Francois Pichet | 4a47e8d | 2011-04-23 11:52:20 +0000 | [diff] [blame] | 2344 |     LateTemplateParser(OpaqueParser, PatternDecl); | 
| Francois Pichet | 8387e2a | 2011-04-22 22:18:13 +0000 | [diff] [blame] | 2345 |     Pattern = PatternDecl->getBody(PatternDecl); | 
 | 2346 |   } | 
 | 2347 |  | 
| Sean Hunt | f996e05 | 2011-05-27 20:00:14 +0000 | [diff] [blame] | 2348 |   if (!Pattern && !PatternDecl->isDefaulted()) { | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2349 |     if (DefinitionRequired) { | 
 | 2350 |       if (Function->getPrimaryTemplate()) | 
 | 2351 |         Diag(PointOfInstantiation,  | 
 | 2352 |              diag::err_explicit_instantiation_undefined_func_template) | 
 | 2353 |           << Function->getPrimaryTemplate(); | 
 | 2354 |       else | 
 | 2355 |         Diag(PointOfInstantiation,  | 
 | 2356 |              diag::err_explicit_instantiation_undefined_member) | 
 | 2357 |           << 1 << Function->getDeclName() << Function->getDeclContext(); | 
 | 2358 |        | 
 | 2359 |       if (PatternDecl) | 
 | 2360 |         Diag(PatternDecl->getLocation(),  | 
 | 2361 |              diag::note_explicit_instantiation_here); | 
| Douglas Gregor | cfe833b | 2010-05-17 17:57:54 +0000 | [diff] [blame] | 2362 |       Function->setInvalidDecl(); | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 2363 |     } else if (Function->getTemplateSpecializationKind() | 
 | 2364 |                  == TSK_ExplicitInstantiationDefinition) { | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2365 |       PendingInstantiations.push_back( | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 2366 |         std::make_pair(Function, PointOfInstantiation)); | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2367 |     } | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 2368 |  | 
| Douglas Gregor | 1eee0e7 | 2009-05-14 21:06:31 +0000 | [diff] [blame] | 2369 |     return; | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2370 |   } | 
| Douglas Gregor | 1eee0e7 | 2009-05-14 21:06:31 +0000 | [diff] [blame] | 2371 |  | 
| Douglas Gregor | d0e3daf | 2009-09-04 22:48:11 +0000 | [diff] [blame] | 2372 |   // C++0x [temp.explicit]p9: | 
 | 2373 |   //   Except for inline functions, other explicit instantiation declarations | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2374 |   //   have the effect of suppressing the implicit instantiation of the entity | 
| Douglas Gregor | d0e3daf | 2009-09-04 22:48:11 +0000 | [diff] [blame] | 2375 |   //   to which they refer. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2376 |   if (Function->getTemplateSpecializationKind() | 
| Douglas Gregor | d0e3daf | 2009-09-04 22:48:11 +0000 | [diff] [blame] | 2377 |         == TSK_ExplicitInstantiationDeclaration && | 
| Douglas Gregor | 7ced9c8 | 2009-10-27 21:11:48 +0000 | [diff] [blame] | 2378 |       !PatternDecl->isInlined()) | 
| Douglas Gregor | d0e3daf | 2009-09-04 22:48:11 +0000 | [diff] [blame] | 2379 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2380 |  | 
| Douglas Gregor | f3e7ce4 | 2009-05-18 17:01:57 +0000 | [diff] [blame] | 2381 |   InstantiatingTemplate Inst(*this, PointOfInstantiation, Function); | 
 | 2382 |   if (Inst) | 
| Douglas Gregor | e7089b0 | 2010-05-03 23:29:10 +0000 | [diff] [blame] | 2383 |     return;   | 
 | 2384 |    | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2385 |   // If we're performing recursive template instantiation, create our own | 
 | 2386 |   // queue of pending implicit instantiations that we will instantiate later, | 
 | 2387 |   // while we're still within our own instantiation context. | 
| Nick Lewycky | 2a5f99e | 2010-11-25 00:35:20 +0000 | [diff] [blame] | 2388 |   llvm::SmallVector<VTableUse, 16> SavedVTableUses; | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2389 |   std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; | 
| Nick Lewycky | 2a5f99e | 2010-11-25 00:35:20 +0000 | [diff] [blame] | 2390 |   if (Recursive) { | 
 | 2391 |     VTableUses.swap(SavedVTableUses); | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2392 |     PendingInstantiations.swap(SavedPendingInstantiations); | 
| Nick Lewycky | 2a5f99e | 2010-11-25 00:35:20 +0000 | [diff] [blame] | 2393 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2394 |  | 
| Douglas Gregor | 9679caf | 2010-05-12 17:27:19 +0000 | [diff] [blame] | 2395 |   EnterExpressionEvaluationContext EvalContext(*this,  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 2396 |                                                Sema::PotentiallyEvaluated); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 2397 |   ActOnStartOfFunctionDef(0, Function); | 
| Douglas Gregor | e2c31ff | 2009-05-15 17:59:04 +0000 | [diff] [blame] | 2398 |  | 
| Douglas Gregor | 54dabfc | 2009-05-14 23:26:13 +0000 | [diff] [blame] | 2399 |   // Introduce a new scope where local variable instantiations will be | 
| Douglas Gregor | 60406be | 2010-01-16 22:29:39 +0000 | [diff] [blame] | 2400 |   // recorded, unless we're actually a member function within a local | 
 | 2401 |   // class, in which case we need to merge our results with the parent | 
 | 2402 |   // scope (of the enclosing function). | 
 | 2403 |   bool MergeWithParentScope = false; | 
 | 2404 |   if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Function->getDeclContext())) | 
 | 2405 |     MergeWithParentScope = Rec->isLocalClass(); | 
 | 2406 |  | 
 | 2407 |   LocalInstantiationScope Scope(*this, MergeWithParentScope); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2408 |  | 
| Douglas Gregor | 54dabfc | 2009-05-14 23:26:13 +0000 | [diff] [blame] | 2409 |   // Introduce the instantiated function parameters into the local | 
| Peter Collingbourne | 8a6c0f1 | 2010-07-18 16:45:46 +0000 | [diff] [blame] | 2410 |   // instantiation scope, and set the parameter names to those used | 
 | 2411 |   // in the template. | 
| Douglas Gregor | 12c9c00 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 2412 |   unsigned FParamIdx = 0; | 
| Peter Collingbourne | 8a6c0f1 | 2010-07-18 16:45:46 +0000 | [diff] [blame] | 2413 |   for (unsigned I = 0, N = PatternDecl->getNumParams(); I != N; ++I) { | 
 | 2414 |     const ParmVarDecl *PatternParam = PatternDecl->getParamDecl(I); | 
| Douglas Gregor | 12c9c00 | 2011-01-07 16:43:16 +0000 | [diff] [blame] | 2415 |     if (!PatternParam->isParameterPack()) { | 
 | 2416 |       // Simple case: not a parameter pack. | 
 | 2417 |       assert(FParamIdx < Function->getNumParams()); | 
 | 2418 |       ParmVarDecl *FunctionParam = Function->getParamDecl(I); | 
 | 2419 |       FunctionParam->setDeclName(PatternParam->getDeclName()); | 
 | 2420 |       Scope.InstantiatedLocal(PatternParam, FunctionParam); | 
 | 2421 |       ++FParamIdx; | 
 | 2422 |       continue; | 
 | 2423 |     } | 
 | 2424 |      | 
 | 2425 |     // Expand the parameter pack. | 
 | 2426 |     Scope.MakeInstantiatedLocalArgPack(PatternParam); | 
 | 2427 |     for (unsigned NumFParams = Function->getNumParams();  | 
 | 2428 |          FParamIdx < NumFParams;  | 
 | 2429 |          ++FParamIdx) { | 
 | 2430 |       ParmVarDecl *FunctionParam = Function->getParamDecl(FParamIdx); | 
 | 2431 |       FunctionParam->setDeclName(PatternParam->getDeclName()); | 
 | 2432 |       Scope.InstantiatedLocalPackArg(PatternParam, FunctionParam); | 
 | 2433 |     } | 
| Peter Collingbourne | 8a6c0f1 | 2010-07-18 16:45:46 +0000 | [diff] [blame] | 2434 |   } | 
| Douglas Gregor | 54dabfc | 2009-05-14 23:26:13 +0000 | [diff] [blame] | 2435 |  | 
| Douglas Gregor | b9f1b8d | 2009-05-15 00:01:03 +0000 | [diff] [blame] | 2436 |   // Enter the scope of this instantiation. We don't use | 
 | 2437 |   // PushDeclContext because we don't have a scope. | 
| John McCall | eee1d54 | 2011-02-14 07:13:47 +0000 | [diff] [blame] | 2438 |   Sema::ContextRAII savedContext(*this, Function); | 
| Douglas Gregor | b9f1b8d | 2009-05-15 00:01:03 +0000 | [diff] [blame] | 2439 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2440 |   MultiLevelTemplateArgumentList TemplateArgs = | 
| Douglas Gregor | e7089b0 | 2010-05-03 23:29:10 +0000 | [diff] [blame] | 2441 |     getTemplateInstantiationArgs(Function, 0, false, PatternDecl); | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2442 |  | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 2443 |   if (PatternDecl->isDefaulted()) { | 
 | 2444 |     ActOnFinishFunctionBody(Function, 0, /*IsInstantiation=*/true); | 
 | 2445 |  | 
 | 2446 |     SetDeclDefaulted(Function, PatternDecl->getLocation()); | 
| Sean Hunt | cd10dec | 2011-05-23 23:14:04 +0000 | [diff] [blame] | 2447 |   } else { | 
 | 2448 |     // If this is a constructor, instantiate the member initializers. | 
 | 2449 |     if (const CXXConstructorDecl *Ctor = | 
 | 2450 |           dyn_cast<CXXConstructorDecl>(PatternDecl)) { | 
 | 2451 |       InstantiateMemInitializers(cast<CXXConstructorDecl>(Function), Ctor, | 
 | 2452 |                                  TemplateArgs); | 
 | 2453 |     } | 
 | 2454 |  | 
 | 2455 |     // Instantiate the function body. | 
 | 2456 |     StmtResult Body = SubstStmt(Pattern, TemplateArgs); | 
 | 2457 |  | 
 | 2458 |     if (Body.isInvalid()) | 
 | 2459 |       Function->setInvalidDecl(); | 
 | 2460 |      | 
 | 2461 |     ActOnFinishFunctionBody(Function, Body.get(), | 
 | 2462 |                             /*IsInstantiation=*/true); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2463 |   } | 
 | 2464 |  | 
| John McCall | 0c01d18 | 2010-03-24 05:22:00 +0000 | [diff] [blame] | 2465 |   PerformDependentDiagnostics(PatternDecl, TemplateArgs); | 
 | 2466 |  | 
| John McCall | eee1d54 | 2011-02-14 07:13:47 +0000 | [diff] [blame] | 2467 |   savedContext.pop(); | 
| Douglas Gregor | aba43bb | 2009-05-26 20:50:29 +0000 | [diff] [blame] | 2468 |  | 
 | 2469 |   DeclGroupRef DG(Function); | 
 | 2470 |   Consumer.HandleTopLevelDecl(DG); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2471 |  | 
| Douglas Gregor | 60406be | 2010-01-16 22:29:39 +0000 | [diff] [blame] | 2472 |   // This class may have local implicit instantiations that need to be | 
 | 2473 |   // instantiation within this scope. | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2474 |   PerformPendingInstantiations(/*LocalOnly=*/true); | 
| Douglas Gregor | 60406be | 2010-01-16 22:29:39 +0000 | [diff] [blame] | 2475 |   Scope.Exit(); | 
 | 2476 |  | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2477 |   if (Recursive) { | 
| Nick Lewycky | 2a5f99e | 2010-11-25 00:35:20 +0000 | [diff] [blame] | 2478 |     // Define any pending vtables. | 
 | 2479 |     DefineUsedVTables(); | 
 | 2480 |  | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2481 |     // Instantiate any pending implicit instantiations found during the | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2482 |     // instantiation of this template. | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2483 |     PerformPendingInstantiations(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2484 |  | 
| Nick Lewycky | 2a5f99e | 2010-11-25 00:35:20 +0000 | [diff] [blame] | 2485 |     // Restore the set of pending vtables. | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2486 |     assert(VTableUses.empty() && | 
 | 2487 |            "VTableUses should be empty before it is discarded."); | 
| Nick Lewycky | 2a5f99e | 2010-11-25 00:35:20 +0000 | [diff] [blame] | 2488 |     VTableUses.swap(SavedVTableUses); | 
 | 2489 |  | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2490 |     // Restore the set of pending implicit instantiations. | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2491 |     assert(PendingInstantiations.empty() && | 
 | 2492 |            "PendingInstantiations should be empty before it is discarded."); | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2493 |     PendingInstantiations.swap(SavedPendingInstantiations); | 
| Douglas Gregor | b33fe2f | 2009-06-30 17:20:14 +0000 | [diff] [blame] | 2494 |   } | 
| Douglas Gregor | a58861f | 2009-05-13 20:28:22 +0000 | [diff] [blame] | 2495 | } | 
 | 2496 |  | 
 | 2497 | /// \brief Instantiate the definition of the given variable from its | 
 | 2498 | /// template. | 
 | 2499 | /// | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2500 | /// \param PointOfInstantiation the point at which the instantiation was | 
 | 2501 | /// required. Note that this is not precisely a "point of instantiation" | 
 | 2502 | /// for the function, but it's close. | 
 | 2503 | /// | 
 | 2504 | /// \param Var the already-instantiated declaration of a static member | 
 | 2505 | /// variable of a class template specialization. | 
 | 2506 | /// | 
 | 2507 | /// \param Recursive if true, recursively instantiates any functions that | 
 | 2508 | /// are required by this instantiation. | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2509 | /// | 
 | 2510 | /// \param DefinitionRequired if true, then we are performing an explicit | 
 | 2511 | /// instantiation where an out-of-line definition of the member variable | 
 | 2512 | /// is required. Complain if there is no such definition. | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2513 | void Sema::InstantiateStaticDataMemberDefinition( | 
 | 2514 |                                           SourceLocation PointOfInstantiation, | 
 | 2515 |                                                  VarDecl *Var, | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2516 |                                                  bool Recursive, | 
 | 2517 |                                                  bool DefinitionRequired) { | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2518 |   if (Var->isInvalidDecl()) | 
 | 2519 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2520 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2521 |   // Find the out-of-line definition of this static data member. | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2522 |   VarDecl *Def = Var->getInstantiatedFromStaticDataMember(); | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2523 |   assert(Def && "This data member was not instantiated from a template?"); | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 2524 |   assert(Def->isStaticDataMember() && "Not a static data member?");   | 
 | 2525 |   Def = Def->getOutOfLineDefinition(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2526 |  | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 2527 |   if (!Def) { | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2528 |     // We did not find an out-of-line definition of this static data member, | 
 | 2529 |     // so we won't perform any instantiation. Rather, we rely on the user to | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2530 |     // instantiate this definition (or provide a specialization for it) in | 
 | 2531 |     // another translation unit. | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2532 |     if (DefinitionRequired) { | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 2533 |       Def = Var->getInstantiatedFromStaticDataMember(); | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 2534 |       Diag(PointOfInstantiation,  | 
 | 2535 |            diag::err_explicit_instantiation_undefined_member) | 
 | 2536 |         << 2 << Var->getDeclName() << Var->getDeclContext(); | 
 | 2537 |       Diag(Def->getLocation(), diag::note_explicit_instantiation_here); | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 2538 |     } else if (Var->getTemplateSpecializationKind() | 
 | 2539 |                  == TSK_ExplicitInstantiationDefinition) { | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2540 |       PendingInstantiations.push_back( | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 2541 |         std::make_pair(Var, PointOfInstantiation)); | 
 | 2542 |     } | 
 | 2543 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2544 |     return; | 
 | 2545 |   } | 
 | 2546 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 2547 |   // Never instantiate an explicit specialization. | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 2548 |   if (Var->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 2549 |     return; | 
 | 2550 |    | 
 | 2551 |   // C++0x [temp.explicit]p9: | 
 | 2552 |   //   Except for inline functions, other explicit instantiation declarations | 
 | 2553 |   //   have the effect of suppressing the implicit instantiation of the entity | 
 | 2554 |   //   to which they refer. | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 2555 |   if (Var->getTemplateSpecializationKind()  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 2556 |         == TSK_ExplicitInstantiationDeclaration) | 
 | 2557 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2558 |  | 
| Douglas Gregor | f15748a | 2011-06-03 03:35:07 +0000 | [diff] [blame] | 2559 |   // If we already have a definition, we're done. | 
 | 2560 |   if (Var->getDefinition()) | 
 | 2561 |     return; | 
 | 2562 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2563 |   InstantiatingTemplate Inst(*this, PointOfInstantiation, Var); | 
 | 2564 |   if (Inst) | 
 | 2565 |     return; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2566 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2567 |   // If we're performing recursive template instantiation, create our own | 
 | 2568 |   // queue of pending implicit instantiations that we will instantiate later, | 
 | 2569 |   // while we're still within our own instantiation context. | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2570 |   llvm::SmallVector<VTableUse, 16> SavedVTableUses; | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2571 |   std::deque<PendingImplicitInstantiation> SavedPendingInstantiations; | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2572 |   if (Recursive) { | 
 | 2573 |     VTableUses.swap(SavedVTableUses); | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2574 |     PendingInstantiations.swap(SavedPendingInstantiations); | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2575 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2576 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2577 |   // Enter the scope of this instantiation. We don't use | 
 | 2578 |   // PushDeclContext because we don't have a scope. | 
| John McCall | f5ba7e0 | 2011-02-14 20:37:25 +0000 | [diff] [blame] | 2579 |   ContextRAII previousContext(*this, Var->getDeclContext()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2580 |  | 
| Douglas Gregor | 1028c9f | 2009-10-14 21:29:40 +0000 | [diff] [blame] | 2581 |   VarDecl *OldVar = Var; | 
| John McCall | ce3ff2b | 2009-08-25 22:02:44 +0000 | [diff] [blame] | 2582 |   Var = cast_or_null<VarDecl>(SubstDecl(Def, Var->getDeclContext(), | 
| Nico Weber | 6bb4dcb | 2010-11-28 22:53:37 +0000 | [diff] [blame] | 2583 |                                         getTemplateInstantiationArgs(Var))); | 
| John McCall | f5ba7e0 | 2011-02-14 20:37:25 +0000 | [diff] [blame] | 2584 |  | 
 | 2585 |   previousContext.pop(); | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2586 |  | 
 | 2587 |   if (Var) { | 
| Douglas Gregor | 583f33b | 2009-10-15 18:07:02 +0000 | [diff] [blame] | 2588 |     MemberSpecializationInfo *MSInfo = OldVar->getMemberSpecializationInfo(); | 
 | 2589 |     assert(MSInfo && "Missing member specialization information?"); | 
 | 2590 |     Var->setTemplateSpecializationKind(MSInfo->getTemplateSpecializationKind(), | 
 | 2591 |                                        MSInfo->getPointOfInstantiation()); | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2592 |     DeclGroupRef DG(Var); | 
 | 2593 |     Consumer.HandleTopLevelDecl(DG); | 
 | 2594 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2595 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2596 |   if (Recursive) { | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2597 |     // Define any newly required vtables. | 
 | 2598 |     DefineUsedVTables(); | 
 | 2599 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2600 |     // Instantiate any pending implicit instantiations found during the | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2601 |     // instantiation of this template. | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2602 |     PerformPendingInstantiations(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2603 |  | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2604 |     // Restore the set of pending vtables. | 
 | 2605 |     assert(VTableUses.empty() && | 
 | 2606 |            "VTableUses should be empty before it is discarded, " | 
 | 2607 |            "while instantiating static data member."); | 
 | 2608 |     VTableUses.swap(SavedVTableUses); | 
 | 2609 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2610 |     // Restore the set of pending implicit instantiations. | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 2611 |     assert(PendingInstantiations.empty() && | 
 | 2612 |            "PendingInstantiations should be empty before it is discarded, " | 
 | 2613 |            "while instantiating static data member."); | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 2614 |     PendingInstantiations.swap(SavedPendingInstantiations); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2615 |   } | 
| Douglas Gregor | a58861f | 2009-05-13 20:28:22 +0000 | [diff] [blame] | 2616 | } | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2617 |  | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2618 | void | 
 | 2619 | Sema::InstantiateMemInitializers(CXXConstructorDecl *New, | 
 | 2620 |                                  const CXXConstructorDecl *Tmpl, | 
 | 2621 |                            const MultiLevelTemplateArgumentList &TemplateArgs) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2622 |  | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2623 |   llvm::SmallVector<MemInitTy*, 4> NewInits; | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2624 |   bool AnyErrors = false; | 
 | 2625 |    | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2626 |   // Instantiate all the initializers. | 
 | 2627 |   for (CXXConstructorDecl::init_const_iterator Inits = Tmpl->init_begin(), | 
| Douglas Gregor | 72f6d67 | 2009-09-01 21:04:42 +0000 | [diff] [blame] | 2628 |                                             InitsEnd = Tmpl->init_end(); | 
 | 2629 |        Inits != InitsEnd; ++Inits) { | 
| Sean Hunt | cbb6748 | 2011-01-08 20:30:50 +0000 | [diff] [blame] | 2630 |     CXXCtorInitializer *Init = *Inits; | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2631 |  | 
| Chandler Carruth | 030ef47 | 2010-09-03 21:54:20 +0000 | [diff] [blame] | 2632 |     // Only instantiate written initializers, let Sema re-construct implicit | 
 | 2633 |     // ones. | 
 | 2634 |     if (!Init->isWritten()) | 
 | 2635 |       continue; | 
 | 2636 |  | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 2637 |     SourceLocation LParenLoc, RParenLoc; | 
| John McCall | ca0408f | 2010-08-23 06:44:23 +0000 | [diff] [blame] | 2638 |     ASTOwningVector<Expr*> NewArgs(*this); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2639 |  | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2640 |     SourceLocation EllipsisLoc; | 
 | 2641 |      | 
 | 2642 |     if (Init->isPackExpansion()) { | 
 | 2643 |       // This is a pack expansion. We should expand it now. | 
 | 2644 |       TypeLoc BaseTL = Init->getBaseClassInfo()->getTypeLoc(); | 
 | 2645 |       llvm::SmallVector<UnexpandedParameterPack, 2> Unexpanded; | 
 | 2646 |       collectUnexpandedParameterPacks(BaseTL, Unexpanded); | 
 | 2647 |       bool ShouldExpand = false; | 
| Douglas Gregor | d373119 | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 2648 |       bool RetainExpansion = false; | 
| Douglas Gregor | cded4f6 | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 2649 |       llvm::Optional<unsigned> NumExpansions; | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2650 |       if (CheckParameterPacksForExpansion(Init->getEllipsisLoc(),  | 
 | 2651 |                                           BaseTL.getSourceRange(), | 
 | 2652 |                                           Unexpanded.data(),  | 
 | 2653 |                                           Unexpanded.size(), | 
 | 2654 |                                           TemplateArgs, ShouldExpand,  | 
| Douglas Gregor | d373119 | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 2655 |                                           RetainExpansion, | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2656 |                                           NumExpansions)) { | 
 | 2657 |         AnyErrors = true; | 
 | 2658 |         New->setInvalidDecl(); | 
 | 2659 |         continue; | 
 | 2660 |       } | 
 | 2661 |       assert(ShouldExpand && "Partial instantiation of base initializer?"); | 
 | 2662 |        | 
 | 2663 |       // Loop over all of the arguments in the argument pack(s),  | 
| Douglas Gregor | cded4f6 | 2011-01-14 17:04:44 +0000 | [diff] [blame] | 2664 |       for (unsigned I = 0; I != *NumExpansions; ++I) { | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2665 |         Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, I); | 
 | 2666 |  | 
 | 2667 |         // Instantiate the initializer. | 
 | 2668 |         if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs,  | 
 | 2669 |                                    LParenLoc, NewArgs, RParenLoc)) { | 
 | 2670 |           AnyErrors = true; | 
 | 2671 |           break; | 
 | 2672 |         } | 
 | 2673 |  | 
 | 2674 |         // Instantiate the base type. | 
 | 2675 |         TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(),  | 
 | 2676 |                                               TemplateArgs,  | 
 | 2677 |                                               Init->getSourceLocation(),  | 
 | 2678 |                                               New->getDeclName()); | 
 | 2679 |         if (!BaseTInfo) { | 
 | 2680 |           AnyErrors = true; | 
 | 2681 |           break; | 
 | 2682 |         } | 
 | 2683 |  | 
 | 2684 |         // Build the initializer. | 
 | 2685 |         MemInitResult NewInit = BuildBaseInitializer(BaseTInfo->getType(),  | 
 | 2686 |                                                      BaseTInfo, | 
 | 2687 |                                                      (Expr **)NewArgs.data(), | 
 | 2688 |                                                      NewArgs.size(), | 
 | 2689 |                                                      Init->getLParenLoc(), | 
 | 2690 |                                                      Init->getRParenLoc(), | 
 | 2691 |                                                      New->getParent(), | 
 | 2692 |                                                      SourceLocation()); | 
 | 2693 |         if (NewInit.isInvalid()) { | 
 | 2694 |           AnyErrors = true; | 
 | 2695 |           break; | 
 | 2696 |         } | 
 | 2697 |          | 
 | 2698 |         NewInits.push_back(NewInit.get()); | 
 | 2699 |         NewArgs.clear(); | 
 | 2700 |       } | 
 | 2701 |        | 
 | 2702 |       continue; | 
 | 2703 |     } | 
 | 2704 |  | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 2705 |     // Instantiate the initializer. | 
 | 2706 |     if (InstantiateInitializer(*this, Init->getInit(), TemplateArgs,  | 
| Douglas Gregor | a1a0478 | 2010-09-09 16:33:13 +0000 | [diff] [blame] | 2707 |                                LParenLoc, NewArgs, RParenLoc)) { | 
| Douglas Gregor | 6b98b2e | 2010-03-02 07:38:39 +0000 | [diff] [blame] | 2708 |       AnyErrors = true; | 
 | 2709 |       continue; | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2710 |     } | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2711 |      | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2712 |     MemInitResult NewInit; | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2713 |     if (Init->isBaseInitializer()) { | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2714 |       TypeSourceInfo *BaseTInfo = SubstType(Init->getBaseClassInfo(),  | 
| Douglas Gregor | 802ab45 | 2009-12-02 22:36:29 +0000 | [diff] [blame] | 2715 |                                             TemplateArgs,  | 
 | 2716 |                                             Init->getSourceLocation(),  | 
 | 2717 |                                             New->getDeclName()); | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2718 |       if (!BaseTInfo) { | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2719 |         AnyErrors = true; | 
| Douglas Gregor | 802ab45 | 2009-12-02 22:36:29 +0000 | [diff] [blame] | 2720 |         New->setInvalidDecl(); | 
 | 2721 |         continue; | 
 | 2722 |       } | 
 | 2723 |        | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2724 |       NewInit = BuildBaseInitializer(BaseTInfo->getType(), BaseTInfo, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2725 |                                      (Expr **)NewArgs.data(), | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2726 |                                      NewArgs.size(), | 
| Douglas Gregor | 802ab45 | 2009-12-02 22:36:29 +0000 | [diff] [blame] | 2727 |                                      Init->getLParenLoc(), | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2728 |                                      Init->getRParenLoc(), | 
| Douglas Gregor | 3fb9e4b | 2011-01-04 00:32:56 +0000 | [diff] [blame] | 2729 |                                      New->getParent(), | 
 | 2730 |                                      EllipsisLoc); | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2731 |     } else if (Init->isMemberInitializer()) { | 
| Douglas Gregor | b710722 | 2011-03-04 19:46:35 +0000 | [diff] [blame] | 2732 |       FieldDecl *Member = cast_or_null<FieldDecl>(FindInstantiatedDecl( | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 2733 |                                                      Init->getMemberLocation(), | 
 | 2734 |                                                      Init->getMember(), | 
 | 2735 |                                                      TemplateArgs)); | 
| Douglas Gregor | b710722 | 2011-03-04 19:46:35 +0000 | [diff] [blame] | 2736 |       if (!Member) { | 
 | 2737 |         AnyErrors = true; | 
 | 2738 |         New->setInvalidDecl(); | 
 | 2739 |         continue; | 
 | 2740 |       } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2741 |  | 
 | 2742 |       NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(), | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2743 |                                        NewArgs.size(), | 
 | 2744 |                                        Init->getSourceLocation(), | 
| Douglas Gregor | 802ab45 | 2009-12-02 22:36:29 +0000 | [diff] [blame] | 2745 |                                        Init->getLParenLoc(), | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2746 |                                        Init->getRParenLoc()); | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 2747 |     } else if (Init->isIndirectMemberInitializer()) { | 
 | 2748 |       IndirectFieldDecl *IndirectMember = | 
| Douglas Gregor | b710722 | 2011-03-04 19:46:35 +0000 | [diff] [blame] | 2749 |          cast_or_null<IndirectFieldDecl>(FindInstantiatedDecl( | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 2750 |                                  Init->getMemberLocation(), | 
 | 2751 |                                  Init->getIndirectMember(), TemplateArgs)); | 
 | 2752 |  | 
| Douglas Gregor | b710722 | 2011-03-04 19:46:35 +0000 | [diff] [blame] | 2753 |       if (!IndirectMember) { | 
 | 2754 |         AnyErrors = true; | 
 | 2755 |         New->setInvalidDecl(); | 
 | 2756 |         continue;         | 
 | 2757 |       } | 
 | 2758 |        | 
| Francois Pichet | 00eb3f9 | 2010-12-04 09:14:42 +0000 | [diff] [blame] | 2759 |       NewInit = BuildMemberInitializer(IndirectMember, (Expr **)NewArgs.data(), | 
 | 2760 |                                        NewArgs.size(), | 
 | 2761 |                                        Init->getSourceLocation(), | 
 | 2762 |                                        Init->getLParenLoc(), | 
 | 2763 |                                        Init->getRParenLoc()); | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2764 |     } | 
 | 2765 |  | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2766 |     if (NewInit.isInvalid()) { | 
 | 2767 |       AnyErrors = true; | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2768 |       New->setInvalidDecl(); | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2769 |     } else { | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2770 |       // FIXME: It would be nice if ASTOwningVector had a release function. | 
 | 2771 |       NewArgs.take(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2772 |  | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2773 |       NewInits.push_back((MemInitTy *)NewInit.get()); | 
 | 2774 |     } | 
 | 2775 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2776 |  | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2777 |   // Assign all the initializers to the new constructor. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 2778 |   ActOnMemInitializers(New, | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2779 |                        /*FIXME: ColonLoc */ | 
 | 2780 |                        SourceLocation(), | 
| Douglas Gregor | 9db7dbb | 2010-01-31 09:12:51 +0000 | [diff] [blame] | 2781 |                        NewInits.data(), NewInits.size(), | 
 | 2782 |                        AnyErrors); | 
| Anders Carlsson | 0902531 | 2009-08-29 05:16:22 +0000 | [diff] [blame] | 2783 | } | 
 | 2784 |  | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 2785 | // TODO: this could be templated if the various decl types used the | 
 | 2786 | // same method name. | 
 | 2787 | static bool isInstantiationOf(ClassTemplateDecl *Pattern, | 
 | 2788 |                               ClassTemplateDecl *Instance) { | 
 | 2789 |   Pattern = Pattern->getCanonicalDecl(); | 
 | 2790 |  | 
 | 2791 |   do { | 
 | 2792 |     Instance = Instance->getCanonicalDecl(); | 
 | 2793 |     if (Pattern == Instance) return true; | 
 | 2794 |     Instance = Instance->getInstantiatedFromMemberTemplate(); | 
 | 2795 |   } while (Instance); | 
 | 2796 |  | 
 | 2797 |   return false; | 
 | 2798 | } | 
 | 2799 |  | 
| Douglas Gregor | 0d69653 | 2009-09-28 06:34:35 +0000 | [diff] [blame] | 2800 | static bool isInstantiationOf(FunctionTemplateDecl *Pattern, | 
 | 2801 |                               FunctionTemplateDecl *Instance) { | 
 | 2802 |   Pattern = Pattern->getCanonicalDecl(); | 
 | 2803 |    | 
 | 2804 |   do { | 
 | 2805 |     Instance = Instance->getCanonicalDecl(); | 
 | 2806 |     if (Pattern == Instance) return true; | 
 | 2807 |     Instance = Instance->getInstantiatedFromMemberTemplate(); | 
 | 2808 |   } while (Instance); | 
 | 2809 |    | 
 | 2810 |   return false; | 
 | 2811 | } | 
 | 2812 |  | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2813 | static bool  | 
 | 2814 | isInstantiationOf(ClassTemplatePartialSpecializationDecl *Pattern, | 
 | 2815 |                   ClassTemplatePartialSpecializationDecl *Instance) { | 
 | 2816 |   Pattern  | 
 | 2817 |     = cast<ClassTemplatePartialSpecializationDecl>(Pattern->getCanonicalDecl()); | 
 | 2818 |   do { | 
 | 2819 |     Instance = cast<ClassTemplatePartialSpecializationDecl>( | 
 | 2820 |                                                 Instance->getCanonicalDecl()); | 
 | 2821 |     if (Pattern == Instance) | 
 | 2822 |       return true; | 
 | 2823 |     Instance = Instance->getInstantiatedFromMember(); | 
 | 2824 |   } while (Instance); | 
 | 2825 |    | 
 | 2826 |   return false; | 
 | 2827 | } | 
 | 2828 |  | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 2829 | static bool isInstantiationOf(CXXRecordDecl *Pattern, | 
 | 2830 |                               CXXRecordDecl *Instance) { | 
 | 2831 |   Pattern = Pattern->getCanonicalDecl(); | 
 | 2832 |  | 
 | 2833 |   do { | 
 | 2834 |     Instance = Instance->getCanonicalDecl(); | 
 | 2835 |     if (Pattern == Instance) return true; | 
 | 2836 |     Instance = Instance->getInstantiatedFromMemberClass(); | 
 | 2837 |   } while (Instance); | 
 | 2838 |  | 
 | 2839 |   return false; | 
 | 2840 | } | 
 | 2841 |  | 
 | 2842 | static bool isInstantiationOf(FunctionDecl *Pattern, | 
 | 2843 |                               FunctionDecl *Instance) { | 
 | 2844 |   Pattern = Pattern->getCanonicalDecl(); | 
 | 2845 |  | 
 | 2846 |   do { | 
 | 2847 |     Instance = Instance->getCanonicalDecl(); | 
 | 2848 |     if (Pattern == Instance) return true; | 
 | 2849 |     Instance = Instance->getInstantiatedFromMemberFunction(); | 
 | 2850 |   } while (Instance); | 
 | 2851 |  | 
 | 2852 |   return false; | 
 | 2853 | } | 
 | 2854 |  | 
 | 2855 | static bool isInstantiationOf(EnumDecl *Pattern, | 
 | 2856 |                               EnumDecl *Instance) { | 
 | 2857 |   Pattern = Pattern->getCanonicalDecl(); | 
 | 2858 |  | 
 | 2859 |   do { | 
 | 2860 |     Instance = Instance->getCanonicalDecl(); | 
 | 2861 |     if (Pattern == Instance) return true; | 
 | 2862 |     Instance = Instance->getInstantiatedFromMemberEnum(); | 
 | 2863 |   } while (Instance); | 
 | 2864 |  | 
 | 2865 |   return false; | 
 | 2866 | } | 
 | 2867 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 2868 | static bool isInstantiationOf(UsingShadowDecl *Pattern, | 
 | 2869 |                               UsingShadowDecl *Instance, | 
 | 2870 |                               ASTContext &C) { | 
 | 2871 |   return C.getInstantiatedFromUsingShadowDecl(Instance) == Pattern; | 
 | 2872 | } | 
 | 2873 |  | 
 | 2874 | static bool isInstantiationOf(UsingDecl *Pattern, | 
 | 2875 |                               UsingDecl *Instance, | 
 | 2876 |                               ASTContext &C) { | 
 | 2877 |   return C.getInstantiatedFromUsingDecl(Instance) == Pattern; | 
 | 2878 | } | 
 | 2879 |  | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 2880 | static bool isInstantiationOf(UnresolvedUsingValueDecl *Pattern, | 
 | 2881 |                               UsingDecl *Instance, | 
 | 2882 |                               ASTContext &C) { | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 2883 |   return C.getInstantiatedFromUsingDecl(Instance) == Pattern; | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 2884 | } | 
 | 2885 |  | 
 | 2886 | static bool isInstantiationOf(UnresolvedUsingTypenameDecl *Pattern, | 
| Anders Carlsson | 0d8df78 | 2009-08-29 19:37:28 +0000 | [diff] [blame] | 2887 |                               UsingDecl *Instance, | 
 | 2888 |                               ASTContext &C) { | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 2889 |   return C.getInstantiatedFromUsingDecl(Instance) == Pattern; | 
| Anders Carlsson | 0d8df78 | 2009-08-29 19:37:28 +0000 | [diff] [blame] | 2890 | } | 
 | 2891 |  | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 2892 | static bool isInstantiationOfStaticDataMember(VarDecl *Pattern, | 
 | 2893 |                                               VarDecl *Instance) { | 
 | 2894 |   assert(Instance->isStaticDataMember()); | 
 | 2895 |  | 
 | 2896 |   Pattern = Pattern->getCanonicalDecl(); | 
 | 2897 |  | 
 | 2898 |   do { | 
 | 2899 |     Instance = Instance->getCanonicalDecl(); | 
 | 2900 |     if (Pattern == Instance) return true; | 
 | 2901 |     Instance = Instance->getInstantiatedFromStaticDataMember(); | 
 | 2902 |   } while (Instance); | 
 | 2903 |  | 
 | 2904 |   return false; | 
 | 2905 | } | 
 | 2906 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 2907 | // Other is the prospective instantiation | 
 | 2908 | // D is the prospective pattern | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2909 | static bool isInstantiationOf(ASTContext &Ctx, NamedDecl *D, Decl *Other) { | 
| Anders Carlsson | 0d8df78 | 2009-08-29 19:37:28 +0000 | [diff] [blame] | 2910 |   if (D->getKind() != Other->getKind()) { | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 2911 |     if (UnresolvedUsingTypenameDecl *UUD | 
 | 2912 |           = dyn_cast<UnresolvedUsingTypenameDecl>(D)) { | 
 | 2913 |       if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) { | 
 | 2914 |         return isInstantiationOf(UUD, UD, Ctx); | 
 | 2915 |       } | 
 | 2916 |     } | 
 | 2917 |  | 
 | 2918 |     if (UnresolvedUsingValueDecl *UUD | 
 | 2919 |           = dyn_cast<UnresolvedUsingValueDecl>(D)) { | 
| Anders Carlsson | 0d8df78 | 2009-08-29 19:37:28 +0000 | [diff] [blame] | 2920 |       if (UsingDecl *UD = dyn_cast<UsingDecl>(Other)) { | 
 | 2921 |         return isInstantiationOf(UUD, UD, Ctx); | 
 | 2922 |       } | 
 | 2923 |     } | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2924 |  | 
| Anders Carlsson | 0d8df78 | 2009-08-29 19:37:28 +0000 | [diff] [blame] | 2925 |     return false; | 
 | 2926 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2927 |  | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 2928 |   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Other)) | 
 | 2929 |     return isInstantiationOf(cast<CXXRecordDecl>(D), Record); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2930 |  | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 2931 |   if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Other)) | 
 | 2932 |     return isInstantiationOf(cast<FunctionDecl>(D), Function); | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2933 |  | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 2934 |   if (EnumDecl *Enum = dyn_cast<EnumDecl>(Other)) | 
 | 2935 |     return isInstantiationOf(cast<EnumDecl>(D), Enum); | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2936 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 2937 |   if (VarDecl *Var = dyn_cast<VarDecl>(Other)) | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 2938 |     if (Var->isStaticDataMember()) | 
 | 2939 |       return isInstantiationOfStaticDataMember(cast<VarDecl>(D), Var); | 
 | 2940 |  | 
 | 2941 |   if (ClassTemplateDecl *Temp = dyn_cast<ClassTemplateDecl>(Other)) | 
 | 2942 |     return isInstantiationOf(cast<ClassTemplateDecl>(D), Temp); | 
| Douglas Gregor | a5bf7f1 | 2009-08-28 22:03:51 +0000 | [diff] [blame] | 2943 |  | 
| Douglas Gregor | 0d69653 | 2009-09-28 06:34:35 +0000 | [diff] [blame] | 2944 |   if (FunctionTemplateDecl *Temp = dyn_cast<FunctionTemplateDecl>(Other)) | 
 | 2945 |     return isInstantiationOf(cast<FunctionTemplateDecl>(D), Temp); | 
 | 2946 |  | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 2947 |   if (ClassTemplatePartialSpecializationDecl *PartialSpec | 
 | 2948 |         = dyn_cast<ClassTemplatePartialSpecializationDecl>(Other)) | 
 | 2949 |     return isInstantiationOf(cast<ClassTemplatePartialSpecializationDecl>(D), | 
 | 2950 |                              PartialSpec); | 
 | 2951 |  | 
| Anders Carlsson | d8b285f | 2009-09-01 04:26:58 +0000 | [diff] [blame] | 2952 |   if (FieldDecl *Field = dyn_cast<FieldDecl>(Other)) { | 
 | 2953 |     if (!Field->getDeclName()) { | 
 | 2954 |       // This is an unnamed field. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2955 |       return Ctx.getInstantiatedFromUnnamedFieldDecl(Field) == | 
| Anders Carlsson | d8b285f | 2009-09-01 04:26:58 +0000 | [diff] [blame] | 2956 |         cast<FieldDecl>(D); | 
 | 2957 |     } | 
 | 2958 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2959 |  | 
| John McCall | ed97649 | 2009-12-04 22:46:56 +0000 | [diff] [blame] | 2960 |   if (UsingDecl *Using = dyn_cast<UsingDecl>(Other)) | 
 | 2961 |     return isInstantiationOf(cast<UsingDecl>(D), Using, Ctx); | 
 | 2962 |  | 
 | 2963 |   if (UsingShadowDecl *Shadow = dyn_cast<UsingShadowDecl>(Other)) | 
 | 2964 |     return isInstantiationOf(cast<UsingShadowDecl>(D), Shadow, Ctx); | 
 | 2965 |  | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2966 |   return D->getDeclName() && isa<NamedDecl>(Other) && | 
 | 2967 |     D->getDeclName() == cast<NamedDecl>(Other)->getDeclName(); | 
 | 2968 | } | 
 | 2969 |  | 
 | 2970 | template<typename ForwardIterator> | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2971 | static NamedDecl *findInstantiationOf(ASTContext &Ctx, | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2972 |                                       NamedDecl *D, | 
 | 2973 |                                       ForwardIterator first, | 
 | 2974 |                                       ForwardIterator last) { | 
 | 2975 |   for (; first != last; ++first) | 
 | 2976 |     if (isInstantiationOf(Ctx, D, *first)) | 
 | 2977 |       return cast<NamedDecl>(*first); | 
 | 2978 |  | 
 | 2979 |   return 0; | 
 | 2980 | } | 
 | 2981 |  | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 2982 | /// \brief Finds the instantiation of the given declaration context | 
 | 2983 | /// within the current instantiation. | 
 | 2984 | /// | 
 | 2985 | /// \returns NULL if there was an error | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 2986 | DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC, | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 2987 |                           const MultiLevelTemplateArgumentList &TemplateArgs) { | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 2988 |   if (NamedDecl *D = dyn_cast<NamedDecl>(DC)) { | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 2989 |     Decl* ID = FindInstantiatedDecl(Loc, D, TemplateArgs); | 
| John McCall | 02cace7 | 2009-08-28 07:59:38 +0000 | [diff] [blame] | 2990 |     return cast_or_null<DeclContext>(ID); | 
 | 2991 |   } else return DC; | 
 | 2992 | } | 
 | 2993 |  | 
| Douglas Gregor | ed961e7 | 2009-05-27 17:54:46 +0000 | [diff] [blame] | 2994 | /// \brief Find the instantiation of the given declaration within the | 
 | 2995 | /// current instantiation. | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 2996 | /// | 
 | 2997 | /// This routine is intended to be used when \p D is a declaration | 
 | 2998 | /// referenced from within a template, that needs to mapped into the | 
 | 2999 | /// corresponding declaration within an instantiation. For example, | 
 | 3000 | /// given: | 
 | 3001 | /// | 
 | 3002 | /// \code | 
 | 3003 | /// template<typename T> | 
 | 3004 | /// struct X { | 
 | 3005 | ///   enum Kind { | 
 | 3006 | ///     KnownValue = sizeof(T) | 
 | 3007 | ///   }; | 
 | 3008 | /// | 
 | 3009 | ///   bool getKind() const { return KnownValue; } | 
 | 3010 | /// }; | 
 | 3011 | /// | 
 | 3012 | /// template struct X<int>; | 
 | 3013 | /// \endcode | 
 | 3014 | /// | 
 | 3015 | /// In the instantiation of X<int>::getKind(), we need to map the | 
 | 3016 | /// EnumConstantDecl for KnownValue (which refers to | 
 | 3017 | /// X<T>::<Kind>::KnownValue) to its instantiation | 
| Douglas Gregor | ed961e7 | 2009-05-27 17:54:46 +0000 | [diff] [blame] | 3018 | /// (X<int>::<Kind>::KnownValue). InstantiateCurrentDeclRef() performs | 
 | 3019 | /// this mapping from within the instantiation of X<int>. | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 3020 | NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D, | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3021 |                           const MultiLevelTemplateArgumentList &TemplateArgs) { | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3022 |   DeclContext *ParentDC = D->getDeclContext(); | 
| Douglas Gregor | 550d9b2 | 2009-10-31 17:21:17 +0000 | [diff] [blame] | 3023 |   if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) || | 
| Douglas Gregor | 6d3e627 | 2010-02-05 19:54:12 +0000 | [diff] [blame] | 3024 |       isa<TemplateTypeParmDecl>(D) || isa<TemplateTemplateParmDecl>(D) || | 
| John McCall | 7667245 | 2010-08-19 23:06:02 +0000 | [diff] [blame] | 3025 |       (ParentDC->isFunctionOrMethod() && ParentDC->isDependentContext())) { | 
| Douglas Gregor | 2bba76b | 2009-05-27 17:07:49 +0000 | [diff] [blame] | 3026 |     // D is a local of some kind. Look into the map of local | 
 | 3027 |     // declarations to their instantiations. | 
| Chris Lattner | d8e5499 | 2011-02-17 19:47:42 +0000 | [diff] [blame] | 3028 |     typedef LocalInstantiationScope::DeclArgumentPack DeclArgumentPack; | 
 | 3029 |     llvm::PointerUnion<Decl *, DeclArgumentPack *> *Found | 
 | 3030 |       = CurrentInstantiationScope->findInstantiationOf(D); | 
| Chris Lattner | d8e5499 | 2011-02-17 19:47:42 +0000 | [diff] [blame] | 3031 |      | 
| Chris Lattner | 57ad378 | 2011-02-17 20:34:02 +0000 | [diff] [blame] | 3032 |     if (Found) { | 
 | 3033 |       if (Decl *FD = Found->dyn_cast<Decl *>()) | 
 | 3034 |         return cast<NamedDecl>(FD); | 
 | 3035 |        | 
 | 3036 |       unsigned PackIdx = ArgumentPackSubstitutionIndex; | 
 | 3037 |       return cast<NamedDecl>((*Found->get<DeclArgumentPack *>())[PackIdx]); | 
 | 3038 |     } | 
 | 3039 |  | 
 | 3040 |     // If we didn't find the decl, then we must have a label decl that hasn't | 
 | 3041 |     // been found yet.  Lazily instantiate it and return it now. | 
 | 3042 |     assert(isa<LabelDecl>(D)); | 
| Chris Lattner | d8e5499 | 2011-02-17 19:47:42 +0000 | [diff] [blame] | 3043 |      | 
| Chris Lattner | 57ad378 | 2011-02-17 20:34:02 +0000 | [diff] [blame] | 3044 |     Decl *Inst = SubstDecl(D, CurContext, TemplateArgs); | 
 | 3045 |     assert(Inst && "Failed to instantiate label??"); | 
 | 3046 |      | 
 | 3047 |     CurrentInstantiationScope->InstantiatedLocal(D, Inst); | 
 | 3048 |     return cast<LabelDecl>(Inst); | 
| Douglas Gregor | 2bba76b | 2009-05-27 17:07:49 +0000 | [diff] [blame] | 3049 |   } | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3050 |  | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3051 |   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { | 
 | 3052 |     if (!Record->isDependentContext()) | 
 | 3053 |       return D; | 
 | 3054 |      | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3055 |     // If the RecordDecl is actually the injected-class-name or a | 
 | 3056 |     // "templated" declaration for a class template, class template | 
 | 3057 |     // partial specialization, or a member class of a class template, | 
 | 3058 |     // substitute into the injected-class-name of the class template | 
 | 3059 |     // or partial specialization to find the new DeclContext. | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3060 |     QualType T; | 
 | 3061 |     ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate(); | 
 | 3062 |      | 
 | 3063 |     if (ClassTemplate) { | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 3064 |       T = ClassTemplate->getInjectedClassNameSpecialization(); | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3065 |     } else if (ClassTemplatePartialSpecializationDecl *PartialSpec | 
 | 3066 |                  = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) { | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3067 |       ClassTemplate = PartialSpec->getSpecializedTemplate(); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 3068 |  | 
 | 3069 |       // If we call SubstType with an InjectedClassNameType here we | 
 | 3070 |       // can end up in an infinite loop. | 
 | 3071 |       T = Context.getTypeDeclType(Record); | 
 | 3072 |       assert(isa<InjectedClassNameType>(T) && | 
 | 3073 |              "type of partial specialization is not an InjectedClassNameType"); | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 3074 |       T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType(); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 3075 |     }   | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3076 |      | 
 | 3077 |     if (!T.isNull()) { | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3078 |       // Substitute into the injected-class-name to get the type | 
 | 3079 |       // corresponding to the instantiation we want, which may also be | 
 | 3080 |       // the current instantiation (if we're in a template | 
 | 3081 |       // definition). This substitution should never fail, since we | 
 | 3082 |       // know we can instantiate the injected-class-name or we | 
 | 3083 |       // wouldn't have gotten to the injected-class-name!   | 
 | 3084 |  | 
 | 3085 |       // FIXME: Can we use the CurrentInstantiationScope to avoid this | 
 | 3086 |       // extra instantiation in the common case? | 
| Douglas Gregor | b46ae39 | 2011-03-03 21:48:55 +0000 | [diff] [blame] | 3087 |       T = SubstType(T, TemplateArgs, Loc, DeclarationName()); | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3088 |       assert(!T.isNull() && "Instantiation of injected-class-name cannot fail."); | 
 | 3089 |      | 
 | 3090 |       if (!T->isDependentType()) { | 
 | 3091 |         assert(T->isRecordType() && "Instantiation must produce a record type"); | 
 | 3092 |         return T->getAs<RecordType>()->getDecl(); | 
 | 3093 |       } | 
 | 3094 |      | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3095 |       // We are performing "partial" template instantiation to create | 
 | 3096 |       // the member declarations for the members of a class template | 
 | 3097 |       // specialization. Therefore, D is actually referring to something | 
 | 3098 |       // in the current instantiation. Look through the current | 
 | 3099 |       // context, which contains actual instantiations, to find the | 
 | 3100 |       // instantiation of the "current instantiation" that D refers | 
 | 3101 |       // to. | 
 | 3102 |       bool SawNonDependentContext = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3103 |       for (DeclContext *DC = CurContext; !DC->isFileContext(); | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 3104 |            DC = DC->getParent()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3105 |         if (ClassTemplateSpecializationDecl *Spec | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3106 |                           = dyn_cast<ClassTemplateSpecializationDecl>(DC)) | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3107 |           if (isInstantiationOf(ClassTemplate,  | 
 | 3108 |                                 Spec->getSpecializedTemplate())) | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 3109 |             return Spec; | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3110 |  | 
 | 3111 |         if (!DC->isDependentContext()) | 
 | 3112 |           SawNonDependentContext = true; | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 3113 |       } | 
 | 3114 |  | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3115 |       // We're performing "instantiation" of a member of the current | 
 | 3116 |       // instantiation while we are type-checking the | 
 | 3117 |       // definition. Compute the declaration context and return that. | 
 | 3118 |       assert(!SawNonDependentContext &&  | 
 | 3119 |              "No dependent context while instantiating record"); | 
 | 3120 |       DeclContext *DC = computeDeclContext(T); | 
 | 3121 |       assert(DC &&  | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 3122 |              "Unable to find declaration for the current instantiation"); | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3123 |       return cast<CXXRecordDecl>(DC); | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 3124 |     } | 
| Douglas Gregor | 8b013bd | 2010-02-05 22:40:03 +0000 | [diff] [blame] | 3125 |  | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3126 |     // Fall through to deal with other dependent record types (e.g., | 
 | 3127 |     // anonymous unions in class templates). | 
 | 3128 |   } | 
| John McCall | 52a575a | 2009-08-29 08:11:13 +0000 | [diff] [blame] | 3129 |  | 
| Douglas Gregor | e95b409 | 2009-09-16 18:34:49 +0000 | [diff] [blame] | 3130 |   if (!ParentDC->isDependentContext()) | 
 | 3131 |     return D; | 
 | 3132 |    | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 3133 |   ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3134 |   if (!ParentDC) | 
| Douglas Gregor | 44c7384 | 2009-09-01 17:53:10 +0000 | [diff] [blame] | 3135 |     return 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3136 |  | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3137 |   if (ParentDC != D->getDeclContext()) { | 
 | 3138 |     // We performed some kind of instantiation in the parent context, | 
 | 3139 |     // so now we need to look into the instantiated parent context to | 
 | 3140 |     // find the instantiation of the declaration D. | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 3141 |  | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 3142 |     // If our context used to be dependent, we may need to instantiate | 
 | 3143 |     // it before performing lookup into that context. | 
| Douglas Gregor | eff1dbe | 2011-03-06 20:12:45 +0000 | [diff] [blame] | 3144 |     bool IsBeingInstantiated = false; | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 3145 |     if (CXXRecordDecl *Spec = dyn_cast<CXXRecordDecl>(ParentDC)) { | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 3146 |       if (!Spec->isDependentContext()) { | 
 | 3147 |         QualType T = Context.getTypeDeclType(Spec); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 3148 |         const RecordType *Tag = T->getAs<RecordType>(); | 
 | 3149 |         assert(Tag && "type of non-dependent record is not a RecordType"); | 
| Douglas Gregor | eff1dbe | 2011-03-06 20:12:45 +0000 | [diff] [blame] | 3150 |         if (Tag->isBeingDefined()) | 
 | 3151 |           IsBeingInstantiated = true; | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 3152 |         if (!Tag->isBeingDefined() && | 
 | 3153 |             RequireCompleteType(Loc, T, diag::err_incomplete_type)) | 
 | 3154 |           return 0; | 
| Douglas Gregor | a43064c | 2010-11-05 23:22:45 +0000 | [diff] [blame] | 3155 |  | 
 | 3156 |         ParentDC = Tag->getDecl(); | 
| Douglas Gregor | 7c1e98f | 2010-03-01 15:56:25 +0000 | [diff] [blame] | 3157 |       } | 
 | 3158 |     } | 
 | 3159 |  | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3160 |     NamedDecl *Result = 0; | 
 | 3161 |     if (D->getDeclName()) { | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 3162 |       DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName()); | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3163 |       Result = findInstantiationOf(Context, D, Found.first, Found.second); | 
 | 3164 |     } else { | 
 | 3165 |       // Since we don't have a name for the entity we're looking for, | 
 | 3166 |       // our only option is to walk through all of the declarations to | 
 | 3167 |       // find that name. This will occur in a few cases: | 
 | 3168 |       // | 
 | 3169 |       //   - anonymous struct/union within a template | 
 | 3170 |       //   - unnamed class/struct/union/enum within a template | 
 | 3171 |       // | 
 | 3172 |       // FIXME: Find a better way to find these instantiations! | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3173 |       Result = findInstantiationOf(Context, D, | 
| Argyrios Kyrtzidis | 17945a0 | 2009-06-30 02:36:12 +0000 | [diff] [blame] | 3174 |                                    ParentDC->decls_begin(), | 
 | 3175 |                                    ParentDC->decls_end()); | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3176 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3177 |  | 
| Douglas Gregor | eff1dbe | 2011-03-06 20:12:45 +0000 | [diff] [blame] | 3178 |     if (!Result) { | 
 | 3179 |       if (isa<UsingShadowDecl>(D)) { | 
 | 3180 |         // UsingShadowDecls can instantiate to nothing because of using hiding. | 
 | 3181 |       } else if (Diags.hasErrorOccurred()) { | 
 | 3182 |         // We've already complained about something, so most likely this | 
 | 3183 |         // declaration failed to instantiate. There's no point in complaining | 
 | 3184 |         // further, since this is normal in invalid code. | 
 | 3185 |       } else if (IsBeingInstantiated) { | 
 | 3186 |         // The class in which this member exists is currently being  | 
 | 3187 |         // instantiated, and we haven't gotten around to instantiating this | 
 | 3188 |         // member yet. This can happen when the code uses forward declarations | 
 | 3189 |         // of member classes, and introduces ordering dependencies via | 
 | 3190 |         // template instantiation. | 
 | 3191 |         Diag(Loc, diag::err_member_not_yet_instantiated) | 
 | 3192 |           << D->getDeclName() | 
 | 3193 |           << Context.getTypeDeclType(cast<CXXRecordDecl>(ParentDC)); | 
 | 3194 |         Diag(D->getLocation(), diag::note_non_instantiated_member_here); | 
 | 3195 |       } else { | 
 | 3196 |         // We should have found something, but didn't. | 
 | 3197 |         llvm_unreachable("Unable to find instantiation of declaration!"); | 
 | 3198 |       } | 
 | 3199 |     } | 
 | 3200 |      | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3201 |     D = Result; | 
 | 3202 |   } | 
 | 3203 |  | 
| Douglas Gregor | 815215d | 2009-05-27 05:35:12 +0000 | [diff] [blame] | 3204 |   return D; | 
 | 3205 | } | 
| Douglas Gregor | d7f37bf | 2009-06-22 23:06:13 +0000 | [diff] [blame] | 3206 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3207 | /// \brief Performs template instantiation for all implicit template | 
| Douglas Gregor | d7f37bf | 2009-06-22 23:06:13 +0000 | [diff] [blame] | 3208 | /// instantiations we have seen until this point. | 
| Nick Lewycky | 8155910 | 2011-05-31 07:58:42 +0000 | [diff] [blame] | 3209 | void Sema::PerformPendingInstantiations(bool LocalOnly) { | 
| Douglas Gregor | 60406be | 2010-01-16 22:29:39 +0000 | [diff] [blame] | 3210 |   while (!PendingLocalImplicitInstantiations.empty() || | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 3211 |          (!LocalOnly && !PendingInstantiations.empty())) { | 
| Douglas Gregor | 60406be | 2010-01-16 22:29:39 +0000 | [diff] [blame] | 3212 |     PendingImplicitInstantiation Inst; | 
 | 3213 |  | 
 | 3214 |     if (PendingLocalImplicitInstantiations.empty()) { | 
| Chandler Carruth | 62c78d5 | 2010-08-25 08:44:16 +0000 | [diff] [blame] | 3215 |       Inst = PendingInstantiations.front(); | 
 | 3216 |       PendingInstantiations.pop_front(); | 
| Douglas Gregor | 60406be | 2010-01-16 22:29:39 +0000 | [diff] [blame] | 3217 |     } else { | 
 | 3218 |       Inst = PendingLocalImplicitInstantiations.front(); | 
 | 3219 |       PendingLocalImplicitInstantiations.pop_front(); | 
 | 3220 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3221 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 3222 |     // Instantiate function definitions | 
 | 3223 |     if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Inst.first)) { | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 3224 |       PrettyDeclStackTraceEntry CrashInfo(*this, Function, SourceLocation(), | 
 | 3225 |                                           "instantiating function definition"); | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 3226 |       bool DefinitionRequired = Function->getTemplateSpecializationKind() == | 
 | 3227 |                                 TSK_ExplicitInstantiationDefinition; | 
 | 3228 |       InstantiateFunctionDefinition(/*FIXME:*/Inst.second, Function, true, | 
 | 3229 |                                     DefinitionRequired); | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 3230 |       continue; | 
 | 3231 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3232 |  | 
| Douglas Gregor | 7caa682 | 2009-07-24 20:34:43 +0000 | [diff] [blame] | 3233 |     // Instantiate static data member definitions. | 
 | 3234 |     VarDecl *Var = cast<VarDecl>(Inst.first); | 
 | 3235 |     assert(Var->isStaticDataMember() && "Not a static data member?"); | 
| Anders Carlsson | c17fb7b | 2009-09-01 05:12:24 +0000 | [diff] [blame] | 3236 |  | 
| Chandler Carruth | 291b441 | 2010-02-13 10:17:50 +0000 | [diff] [blame] | 3237 |     // Don't try to instantiate declarations if the most recent redeclaration | 
 | 3238 |     // is invalid. | 
 | 3239 |     if (Var->getMostRecentDeclaration()->isInvalidDecl()) | 
 | 3240 |       continue; | 
 | 3241 |  | 
 | 3242 |     // Check if the most recent declaration has changed the specialization kind | 
 | 3243 |     // and removed the need for implicit instantiation. | 
 | 3244 |     switch (Var->getMostRecentDeclaration()->getTemplateSpecializationKind()) { | 
 | 3245 |     case TSK_Undeclared: | 
 | 3246 |       assert(false && "Cannot instantitiate an undeclared specialization."); | 
 | 3247 |     case TSK_ExplicitInstantiationDeclaration: | 
| Chandler Carruth | 291b441 | 2010-02-13 10:17:50 +0000 | [diff] [blame] | 3248 |     case TSK_ExplicitSpecialization: | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 3249 |       continue;  // No longer need to instantiate this type. | 
 | 3250 |     case TSK_ExplicitInstantiationDefinition: | 
 | 3251 |       // We only need an instantiation if the pending instantiation *is* the | 
 | 3252 |       // explicit instantiation. | 
 | 3253 |       if (Var != Var->getMostRecentDeclaration()) continue; | 
| Chandler Carruth | 291b441 | 2010-02-13 10:17:50 +0000 | [diff] [blame] | 3254 |     case TSK_ImplicitInstantiation: | 
 | 3255 |       break; | 
 | 3256 |     } | 
 | 3257 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 3258 |     PrettyDeclStackTraceEntry CrashInfo(*this, Var, Var->getLocation(), | 
 | 3259 |                                         "instantiating static data member " | 
 | 3260 |                                         "definition"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3261 |  | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 3262 |     bool DefinitionRequired = Var->getTemplateSpecializationKind() == | 
 | 3263 |                               TSK_ExplicitInstantiationDefinition; | 
 | 3264 |     InstantiateStaticDataMemberDefinition(/*FIXME:*/Inst.second, Var, true, | 
 | 3265 |                                           DefinitionRequired); | 
| Douglas Gregor | d7f37bf | 2009-06-22 23:06:13 +0000 | [diff] [blame] | 3266 |   } | 
 | 3267 | } | 
| John McCall | 0c01d18 | 2010-03-24 05:22:00 +0000 | [diff] [blame] | 3268 |  | 
 | 3269 | void Sema::PerformDependentDiagnostics(const DeclContext *Pattern, | 
 | 3270 |                        const MultiLevelTemplateArgumentList &TemplateArgs) { | 
 | 3271 |   for (DeclContext::ddiag_iterator I = Pattern->ddiag_begin(), | 
 | 3272 |          E = Pattern->ddiag_end(); I != E; ++I) { | 
 | 3273 |     DependentDiagnostic *DD = *I; | 
 | 3274 |  | 
 | 3275 |     switch (DD->getKind()) { | 
 | 3276 |     case DependentDiagnostic::Access: | 
 | 3277 |       HandleDependentAccessCheck(*DD, TemplateArgs); | 
 | 3278 |       break; | 
 | 3279 |     } | 
 | 3280 |   } | 
 | 3281 | } |