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