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