| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 1 | //===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===/ | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 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. | 
| Douglas Gregor | 99ebf65 | 2009-02-27 19:31:52 +0000 | [diff] [blame] | 7 | //===----------------------------------------------------------------------===/ | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 8 | // | 
 | 9 | //  This file implements semantic analysis for C++ templates. | 
| Douglas Gregor | 99ebf65 | 2009-02-27 19:31:52 +0000 | [diff] [blame] | 10 | //===----------------------------------------------------------------------===/ | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 11 |  | 
| John McCall | 2d88708 | 2010-08-25 22:03:47 +0000 | [diff] [blame] | 12 | #include "clang/Sema/SemaInternal.h" | 
| Douglas Gregor | e737f50 | 2010-08-12 20:07:10 +0000 | [diff] [blame] | 13 | #include "clang/Sema/Lookup.h" | 
| John McCall | 5f1e094 | 2010-08-24 08:50:51 +0000 | [diff] [blame] | 14 | #include "clang/Sema/Scope.h" | 
| John McCall | 7cd088e | 2010-08-24 07:21:54 +0000 | [diff] [blame] | 15 | #include "clang/Sema/Template.h" | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 16 | #include "clang/Sema/TemplateDeduction.h" | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 17 | #include "TreeTransform.h" | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 18 | #include "clang/AST/ASTContext.h" | 
| Douglas Gregor | 898574e | 2008-12-05 23:32:09 +0000 | [diff] [blame] | 19 | #include "clang/AST/Expr.h" | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 20 | #include "clang/AST/ExprCXX.h" | 
| John McCall | 92b7f70 | 2010-03-11 07:50:04 +0000 | [diff] [blame] | 21 | #include "clang/AST/DeclFriend.h" | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 22 | #include "clang/AST/DeclTemplate.h" | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 23 | #include "clang/AST/RecursiveASTVisitor.h" | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 24 | #include "clang/AST/TypeVisitor.h" | 
| John McCall | 1951085 | 2010-08-20 18:27:03 +0000 | [diff] [blame] | 25 | #include "clang/Sema/DeclSpec.h" | 
 | 26 | #include "clang/Sema/ParsedTemplate.h" | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 27 | #include "clang/Basic/LangOptions.h" | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 28 | #include "clang/Basic/PartialDiagnostic.h" | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 29 | #include "llvm/ADT/StringExtras.h" | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 30 | using namespace clang; | 
| John McCall | 2a7fb27 | 2010-08-25 05:32:35 +0000 | [diff] [blame] | 31 | using namespace sema; | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 32 |  | 
| John McCall | 78b8105 | 2010-11-10 02:40:36 +0000 | [diff] [blame] | 33 | // Exported for use by Parser. | 
 | 34 | SourceRange | 
 | 35 | clang::getTemplateParamsRange(TemplateParameterList const * const *Ps, | 
 | 36 |                               unsigned N) { | 
 | 37 |   if (!N) return SourceRange(); | 
 | 38 |   return SourceRange(Ps[0]->getTemplateLoc(), Ps[N-1]->getRAngleLoc()); | 
 | 39 | } | 
 | 40 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 41 | /// \brief Determine whether the declaration found is acceptable as the name | 
 | 42 | /// of a template and, if so, return that template declaration. Otherwise, | 
 | 43 | /// returns NULL. | 
| John McCall | ad00b77 | 2010-06-16 08:42:20 +0000 | [diff] [blame] | 44 | static NamedDecl *isAcceptableTemplateName(ASTContext &Context, | 
 | 45 |                                            NamedDecl *Orig) { | 
 | 46 |   NamedDecl *D = Orig->getUnderlyingDecl(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 47 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 48 |   if (isa<TemplateDecl>(D)) | 
| John McCall | ad00b77 | 2010-06-16 08:42:20 +0000 | [diff] [blame] | 49 |     return Orig; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 50 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 51 |   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) { | 
 | 52 |     // C++ [temp.local]p1: | 
 | 53 |     //   Like normal (non-template) classes, class templates have an | 
 | 54 |     //   injected-class-name (Clause 9). The injected-class-name | 
 | 55 |     //   can be used with or without a template-argument-list. When | 
 | 56 |     //   it is used without a template-argument-list, it is | 
 | 57 |     //   equivalent to the injected-class-name followed by the | 
 | 58 |     //   template-parameters of the class template enclosed in | 
 | 59 |     //   <>. When it is used with a template-argument-list, it | 
 | 60 |     //   refers to the specified class template specialization, | 
 | 61 |     //   which could be the current specialization or another | 
 | 62 |     //   specialization. | 
 | 63 |     if (Record->isInjectedClassName()) { | 
| Douglas Gregor | 542b548 | 2009-10-14 17:30:58 +0000 | [diff] [blame] | 64 |       Record = cast<CXXRecordDecl>(Record->getDeclContext()); | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 65 |       if (Record->getDescribedClassTemplate()) | 
 | 66 |         return Record->getDescribedClassTemplate(); | 
 | 67 |  | 
 | 68 |       if (ClassTemplateSpecializationDecl *Spec | 
 | 69 |             = dyn_cast<ClassTemplateSpecializationDecl>(Record)) | 
 | 70 |         return Spec->getSpecializedTemplate(); | 
 | 71 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 72 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 73 |     return 0; | 
 | 74 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 75 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 76 |   return 0; | 
 | 77 | } | 
 | 78 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 79 | static void FilterAcceptableTemplateNames(ASTContext &C, LookupResult &R) { | 
| Douglas Gregor | 01e56ae | 2010-04-12 20:54:26 +0000 | [diff] [blame] | 80 |   // The set of class templates we've already seen. | 
 | 81 |   llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates; | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 82 |   LookupResult::Filter filter = R.makeFilter(); | 
 | 83 |   while (filter.hasNext()) { | 
 | 84 |     NamedDecl *Orig = filter.next(); | 
| John McCall | ad00b77 | 2010-06-16 08:42:20 +0000 | [diff] [blame] | 85 |     NamedDecl *Repl = isAcceptableTemplateName(C, Orig); | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 86 |     if (!Repl) | 
 | 87 |       filter.erase(); | 
| Douglas Gregor | 01e56ae | 2010-04-12 20:54:26 +0000 | [diff] [blame] | 88 |     else if (Repl != Orig) { | 
 | 89 |  | 
 | 90 |       // C++ [temp.local]p3: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 91 |       //   A lookup that finds an injected-class-name (10.2) can result in an | 
| Douglas Gregor | 01e56ae | 2010-04-12 20:54:26 +0000 | [diff] [blame] | 92 |       //   ambiguity in certain cases (for example, if it is found in more than | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 93 |       //   one base class). If all of the injected-class-names that are found | 
 | 94 |       //   refer to specializations of the same class template, and if the name | 
 | 95 |       //   is followed by a template-argument-list, the reference refers to the | 
 | 96 |       //   class template itself and not a specialization thereof, and is not | 
| Douglas Gregor | 01e56ae | 2010-04-12 20:54:26 +0000 | [diff] [blame] | 97 |       //   ambiguous. | 
 | 98 |       // | 
 | 99 |       // FIXME: Will we eventually have to do the same for alias templates? | 
 | 100 |       if (ClassTemplateDecl *ClassTmpl = dyn_cast<ClassTemplateDecl>(Repl)) | 
 | 101 |         if (!ClassTemplates.insert(ClassTmpl)) { | 
 | 102 |           filter.erase(); | 
 | 103 |           continue; | 
 | 104 |         } | 
| John McCall | 8ba6691 | 2010-08-13 07:02:08 +0000 | [diff] [blame] | 105 |  | 
 | 106 |       // FIXME: we promote access to public here as a workaround to | 
 | 107 |       // the fact that LookupResult doesn't let us remember that we | 
 | 108 |       // found this template through a particular injected class name, | 
 | 109 |       // which means we end up doing nasty things to the invariants. | 
 | 110 |       // Pretending that access is public is *much* safer. | 
 | 111 |       filter.replace(Repl, AS_public); | 
| Douglas Gregor | 01e56ae | 2010-04-12 20:54:26 +0000 | [diff] [blame] | 112 |     } | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 113 |   } | 
 | 114 |   filter.done(); | 
 | 115 | } | 
 | 116 |  | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 117 | TemplateNameKind Sema::isTemplateName(Scope *S, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 118 |                                       CXXScopeSpec &SS, | 
| Abramo Bagnara | 7c15353 | 2010-08-06 12:11:11 +0000 | [diff] [blame] | 119 |                                       bool hasTemplateKeyword, | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 120 |                                       UnqualifiedId &Name, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 121 |                                       ParsedType ObjectTypePtr, | 
| Douglas Gregor | 495c35d | 2009-08-25 22:51:20 +0000 | [diff] [blame] | 122 |                                       bool EnteringContext, | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 123 |                                       TemplateTy &TemplateResult, | 
 | 124 |                                       bool &MemberOfUnknownSpecialization) { | 
| Douglas Gregor | b862b8f | 2010-01-11 23:29:10 +0000 | [diff] [blame] | 125 |   assert(getLangOptions().CPlusPlus && "No template names in C!"); | 
 | 126 |  | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 127 |   DeclarationName TName; | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 128 |   MemberOfUnknownSpecialization = false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 129 |  | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 130 |   switch (Name.getKind()) { | 
 | 131 |   case UnqualifiedId::IK_Identifier: | 
 | 132 |     TName = DeclarationName(Name.Identifier); | 
 | 133 |     break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 134 |  | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 135 |   case UnqualifiedId::IK_OperatorFunctionId: | 
 | 136 |     TName = Context.DeclarationNames.getCXXOperatorName( | 
 | 137 |                                               Name.OperatorFunctionId.Operator); | 
 | 138 |     break; | 
 | 139 |  | 
| Sean Hunt | e6252d1 | 2009-11-28 08:58:14 +0000 | [diff] [blame] | 140 |   case UnqualifiedId::IK_LiteralOperatorId: | 
| Sean Hunt | 3e518bd | 2009-11-29 07:34:05 +0000 | [diff] [blame] | 141 |     TName = Context.DeclarationNames.getCXXLiteralOperatorName(Name.Identifier); | 
 | 142 |     break; | 
| Sean Hunt | e6252d1 | 2009-11-28 08:58:14 +0000 | [diff] [blame] | 143 |  | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 144 |   default: | 
 | 145 |     return TNK_Non_template; | 
 | 146 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 147 |  | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 148 |   QualType ObjectType = ObjectTypePtr.get(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 149 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 150 |   LookupResult R(*this, TName, Name.getSourceRange().getBegin(), | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 151 |                  LookupOrdinaryName); | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 152 |   LookupTemplateName(R, S, SS, ObjectType, EnteringContext, | 
 | 153 |                      MemberOfUnknownSpecialization); | 
| John McCall | 67d22fb | 2010-08-28 20:17:00 +0000 | [diff] [blame] | 154 |   if (R.empty()) return TNK_Non_template; | 
 | 155 |   if (R.isAmbiguous()) { | 
 | 156 |     // Suppress diagnostics;  we'll redo this lookup later. | 
| John McCall | b859206 | 2010-08-13 02:23:42 +0000 | [diff] [blame] | 157 |     R.suppressDiagnostics(); | 
| John McCall | 67d22fb | 2010-08-28 20:17:00 +0000 | [diff] [blame] | 158 |  | 
 | 159 |     // FIXME: we might have ambiguous templates, in which case we | 
 | 160 |     // should at least parse them properly! | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 161 |     return TNK_Non_template; | 
| John McCall | b859206 | 2010-08-13 02:23:42 +0000 | [diff] [blame] | 162 |   } | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 163 |  | 
| John McCall | 0bd6feb | 2009-12-02 08:04:21 +0000 | [diff] [blame] | 164 |   TemplateName Template; | 
 | 165 |   TemplateNameKind TemplateKind; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 166 |  | 
| John McCall | 0bd6feb | 2009-12-02 08:04:21 +0000 | [diff] [blame] | 167 |   unsigned ResultCount = R.end() - R.begin(); | 
 | 168 |   if (ResultCount > 1) { | 
 | 169 |     // We assume that we'll preserve the qualifier from a function | 
 | 170 |     // template name in other ways. | 
 | 171 |     Template = Context.getOverloadedTemplateName(R.begin(), R.end()); | 
 | 172 |     TemplateKind = TNK_Function_template; | 
| John McCall | b859206 | 2010-08-13 02:23:42 +0000 | [diff] [blame] | 173 |  | 
 | 174 |     // We'll do this lookup again later. | 
 | 175 |     R.suppressDiagnostics(); | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 176 |   } else { | 
| John McCall | 0bd6feb | 2009-12-02 08:04:21 +0000 | [diff] [blame] | 177 |     TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl()); | 
 | 178 |  | 
 | 179 |     if (SS.isSet() && !SS.isInvalid()) { | 
 | 180 |       NestedNameSpecifier *Qualifier | 
 | 181 |         = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); | 
| Abramo Bagnara | 7c15353 | 2010-08-06 12:11:11 +0000 | [diff] [blame] | 182 |       Template = Context.getQualifiedTemplateName(Qualifier, | 
 | 183 |                                                   hasTemplateKeyword, TD); | 
| John McCall | 0bd6feb | 2009-12-02 08:04:21 +0000 | [diff] [blame] | 184 |     } else { | 
 | 185 |       Template = TemplateName(TD); | 
 | 186 |     } | 
 | 187 |  | 
| John McCall | b859206 | 2010-08-13 02:23:42 +0000 | [diff] [blame] | 188 |     if (isa<FunctionTemplateDecl>(TD)) { | 
| John McCall | 0bd6feb | 2009-12-02 08:04:21 +0000 | [diff] [blame] | 189 |       TemplateKind = TNK_Function_template; | 
| John McCall | b859206 | 2010-08-13 02:23:42 +0000 | [diff] [blame] | 190 |  | 
 | 191 |       // We'll do this lookup again later. | 
 | 192 |       R.suppressDiagnostics(); | 
 | 193 |     } else { | 
| John McCall | 0bd6feb | 2009-12-02 08:04:21 +0000 | [diff] [blame] | 194 |       assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD)); | 
 | 195 |       TemplateKind = TNK_Type_template; | 
 | 196 |     } | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 197 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 198 |  | 
| John McCall | 0bd6feb | 2009-12-02 08:04:21 +0000 | [diff] [blame] | 199 |   TemplateResult = TemplateTy::make(Template); | 
 | 200 |   return TemplateKind; | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 201 | } | 
 | 202 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 203 | bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II, | 
| Douglas Gregor | 84d0a19 | 2010-01-12 21:28:44 +0000 | [diff] [blame] | 204 |                                        SourceLocation IILoc, | 
 | 205 |                                        Scope *S, | 
 | 206 |                                        const CXXScopeSpec *SS, | 
 | 207 |                                        TemplateTy &SuggestedTemplate, | 
 | 208 |                                        TemplateNameKind &SuggestedKind) { | 
 | 209 |   // We can't recover unless there's a dependent scope specifier preceding the | 
 | 210 |   // template name. | 
| Douglas Gregor | d5ab9b0 | 2010-05-21 23:43:39 +0000 | [diff] [blame] | 211 |   // FIXME: Typo correction? | 
| Douglas Gregor | 84d0a19 | 2010-01-12 21:28:44 +0000 | [diff] [blame] | 212 |   if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) || | 
 | 213 |       computeDeclContext(*SS)) | 
 | 214 |     return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 215 |  | 
| Douglas Gregor | 84d0a19 | 2010-01-12 21:28:44 +0000 | [diff] [blame] | 216 |   // The code is missing a 'template' keyword prior to the dependent template | 
 | 217 |   // name. | 
 | 218 |   NestedNameSpecifier *Qualifier = (NestedNameSpecifier*)SS->getScopeRep(); | 
 | 219 |   Diag(IILoc, diag::err_template_kw_missing) | 
 | 220 |     << Qualifier << II.getName() | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 221 |     << FixItHint::CreateInsertion(IILoc, "template "); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 222 |   SuggestedTemplate | 
| Douglas Gregor | 84d0a19 | 2010-01-12 21:28:44 +0000 | [diff] [blame] | 223 |     = TemplateTy::make(Context.getDependentTemplateName(Qualifier, &II)); | 
 | 224 |   SuggestedKind = TNK_Dependent_template_name; | 
 | 225 |   return true; | 
 | 226 | } | 
 | 227 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 228 | void Sema::LookupTemplateName(LookupResult &Found, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 229 |                               Scope *S, CXXScopeSpec &SS, | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 230 |                               QualType ObjectType, | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 231 |                               bool EnteringContext, | 
 | 232 |                               bool &MemberOfUnknownSpecialization) { | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 233 |   // Determine where to perform name lookup | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 234 |   MemberOfUnknownSpecialization = false; | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 235 |   DeclContext *LookupCtx = 0; | 
 | 236 |   bool isDependent = false; | 
 | 237 |   if (!ObjectType.isNull()) { | 
 | 238 |     // This nested-name-specifier occurs in a member access expression, e.g., | 
 | 239 |     // x->B::f, and we are looking into the type of the object. | 
 | 240 |     assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist"); | 
 | 241 |     LookupCtx = computeDeclContext(ObjectType); | 
 | 242 |     isDependent = ObjectType->isDependentType(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 243 |     assert((isDependent || !ObjectType->isIncompleteType()) && | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 244 |            "Caller should have completed object type"); | 
 | 245 |   } else if (SS.isSet()) { | 
 | 246 |     // This nested-name-specifier occurs after another nested-name-specifier, | 
 | 247 |     // so long into the context associated with the prior nested-name-specifier. | 
 | 248 |     LookupCtx = computeDeclContext(SS, EnteringContext); | 
 | 249 |     isDependent = isDependentScopeSpecifier(SS); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 250 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 251 |     // The declaration context must be complete. | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 252 |     if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx)) | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 253 |       return; | 
 | 254 |   } | 
 | 255 |  | 
 | 256 |   bool ObjectTypeSearchedInScope = false; | 
 | 257 |   if (LookupCtx) { | 
 | 258 |     // Perform "qualified" name lookup into the declaration context we | 
 | 259 |     // computed, which is either the type of the base of a member access | 
 | 260 |     // expression or the declaration context associated with a prior | 
 | 261 |     // nested-name-specifier. | 
 | 262 |     LookupQualifiedName(Found, LookupCtx); | 
 | 263 |  | 
 | 264 |     if (!ObjectType.isNull() && Found.empty()) { | 
 | 265 |       // C++ [basic.lookup.classref]p1: | 
 | 266 |       //   In a class member access expression (5.2.5), if the . or -> token is | 
 | 267 |       //   immediately followed by an identifier followed by a <, the | 
 | 268 |       //   identifier must be looked up to determine whether the < is the | 
 | 269 |       //   beginning of a template argument list (14.2) or a less-than operator. | 
 | 270 |       //   The identifier is first looked up in the class of the object | 
 | 271 |       //   expression. If the identifier is not found, it is then looked up in | 
 | 272 |       //   the context of the entire postfix-expression and shall name a class | 
 | 273 |       //   or function template. | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 274 |       if (S) LookupName(Found, S); | 
 | 275 |       ObjectTypeSearchedInScope = true; | 
 | 276 |     } | 
| Douglas Gregor | f9f97a0 | 2010-07-16 16:54:17 +0000 | [diff] [blame] | 277 |   } else if (isDependent && (!S || ObjectType.isNull())) { | 
| Douglas Gregor | 2e93388 | 2010-01-12 17:06:20 +0000 | [diff] [blame] | 278 |     // We cannot look into a dependent object type or nested nme | 
 | 279 |     // specifier. | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 280 |     MemberOfUnknownSpecialization = true; | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 281 |     return; | 
 | 282 |   } else { | 
 | 283 |     // Perform unqualified name lookup in the current scope. | 
 | 284 |     LookupName(Found, S); | 
 | 285 |   } | 
 | 286 |  | 
| Douglas Gregor | 2e93388 | 2010-01-12 17:06:20 +0000 | [diff] [blame] | 287 |   if (Found.empty() && !isDependent) { | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 288 |     // If we did not find any names, attempt to correct any typos. | 
 | 289 |     DeclarationName Name = Found.getLookupName(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 290 |     if (DeclarationName Corrected = CorrectTypo(Found, S, &SS, LookupCtx, | 
| Douglas Gregor | 12eb5d6 | 2010-06-29 19:27:42 +0000 | [diff] [blame] | 291 |                                                 false, CTC_CXXCasts)) { | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 292 |       FilterAcceptableTemplateNames(Context, Found); | 
| John McCall | ad00b77 | 2010-06-16 08:42:20 +0000 | [diff] [blame] | 293 |       if (!Found.empty()) { | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 294 |         if (LookupCtx) | 
 | 295 |           Diag(Found.getNameLoc(), diag::err_no_member_template_suggest) | 
 | 296 |             << Name << LookupCtx << Found.getLookupName() << SS.getRange() | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 297 |             << FixItHint::CreateReplacement(Found.getNameLoc(), | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 298 |                                           Found.getLookupName().getAsString()); | 
 | 299 |         else | 
 | 300 |           Diag(Found.getNameLoc(), diag::err_no_template_suggest) | 
 | 301 |             << Name << Found.getLookupName() | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 302 |             << FixItHint::CreateReplacement(Found.getNameLoc(), | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 303 |                                           Found.getLookupName().getAsString()); | 
| Douglas Gregor | 67dd1d4 | 2010-01-07 00:17:44 +0000 | [diff] [blame] | 304 |         if (TemplateDecl *Template = Found.getAsSingle<TemplateDecl>()) | 
 | 305 |           Diag(Template->getLocation(), diag::note_previous_decl) | 
 | 306 |             << Template->getDeclName(); | 
| John McCall | ad00b77 | 2010-06-16 08:42:20 +0000 | [diff] [blame] | 307 |       } | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 308 |     } else { | 
 | 309 |       Found.clear(); | 
| Douglas Gregor | 12eb5d6 | 2010-06-29 19:27:42 +0000 | [diff] [blame] | 310 |       Found.setLookupName(Name); | 
| Douglas Gregor | bfea239 | 2009-12-31 08:11:17 +0000 | [diff] [blame] | 311 |     } | 
 | 312 |   } | 
 | 313 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 314 |   FilterAcceptableTemplateNames(Context, Found); | 
| Douglas Gregor | f9f97a0 | 2010-07-16 16:54:17 +0000 | [diff] [blame] | 315 |   if (Found.empty()) { | 
 | 316 |     if (isDependent) | 
 | 317 |       MemberOfUnknownSpecialization = true; | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 318 |     return; | 
| Douglas Gregor | f9f97a0 | 2010-07-16 16:54:17 +0000 | [diff] [blame] | 319 |   } | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 320 |  | 
 | 321 |   if (S && !ObjectType.isNull() && !ObjectTypeSearchedInScope) { | 
 | 322 |     // C++ [basic.lookup.classref]p1: | 
 | 323 |     //   [...] If the lookup in the class of the object expression finds a | 
 | 324 |     //   template, the name is also looked up in the context of the entire | 
 | 325 |     //   postfix-expression and [...] | 
 | 326 |     // | 
 | 327 |     LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(), | 
 | 328 |                             LookupOrdinaryName); | 
 | 329 |     LookupName(FoundOuter, S); | 
 | 330 |     FilterAcceptableTemplateNames(Context, FoundOuter); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 331 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 332 |     if (FoundOuter.empty()) { | 
 | 333 |       //   - if the name is not found, the name found in the class of the | 
 | 334 |       //     object expression is used, otherwise | 
 | 335 |     } else if (!FoundOuter.getAsSingle<ClassTemplateDecl>()) { | 
 | 336 |       //   - if the name is found in the context of the entire | 
 | 337 |       //     postfix-expression and does not name a class template, the name | 
 | 338 |       //     found in the class of the object expression is used, otherwise | 
| John McCall | ad00b77 | 2010-06-16 08:42:20 +0000 | [diff] [blame] | 339 |     } else if (!Found.isSuppressingDiagnostics()) { | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 340 |       //   - if the name found is a class template, it must refer to the same | 
 | 341 |       //     entity as the one found in the class of the object expression, | 
 | 342 |       //     otherwise the program is ill-formed. | 
 | 343 |       if (!Found.isSingleResult() || | 
 | 344 |           Found.getFoundDecl()->getCanonicalDecl() | 
 | 345 |             != FoundOuter.getFoundDecl()->getCanonicalDecl()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 346 |         Diag(Found.getNameLoc(), | 
| Jeffrey Yasskin | 21d07e4 | 2010-06-05 01:39:57 +0000 | [diff] [blame] | 347 |              diag::ext_nested_name_member_ref_lookup_ambiguous) | 
 | 348 |           << Found.getLookupName() | 
 | 349 |           << ObjectType; | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 350 |         Diag(Found.getRepresentativeDecl()->getLocation(), | 
 | 351 |              diag::note_ambig_member_ref_object_type) | 
 | 352 |           << ObjectType; | 
 | 353 |         Diag(FoundOuter.getFoundDecl()->getLocation(), | 
 | 354 |              diag::note_ambig_member_ref_scope); | 
 | 355 |  | 
 | 356 |         // Recover by taking the template that we found in the object | 
 | 357 |         // expression's type. | 
 | 358 |       } | 
 | 359 |     } | 
 | 360 |   } | 
 | 361 | } | 
 | 362 |  | 
| John McCall | 2f841ba | 2009-12-02 03:53:29 +0000 | [diff] [blame] | 363 | /// ActOnDependentIdExpression - Handle a dependent id-expression that | 
 | 364 | /// was just parsed.  This is only possible with an explicit scope | 
 | 365 | /// specifier naming a dependent type. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 366 | ExprResult | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 367 | Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS, | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 368 |                                  const DeclarationNameInfo &NameInfo, | 
| John McCall | 2f841ba | 2009-12-02 03:53:29 +0000 | [diff] [blame] | 369 |                                  bool isAddressOfOperand, | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 370 |                            const TemplateArgumentListInfo *TemplateArgs) { | 
| John McCall | ea1471e | 2010-05-20 01:18:31 +0000 | [diff] [blame] | 371 |   DeclContext *DC = getFunctionLevelDeclContext(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 372 |  | 
| John McCall | 2f841ba | 2009-12-02 03:53:29 +0000 | [diff] [blame] | 373 |   if (!isAddressOfOperand && | 
| John McCall | ea1471e | 2010-05-20 01:18:31 +0000 | [diff] [blame] | 374 |       isa<CXXMethodDecl>(DC) && | 
 | 375 |       cast<CXXMethodDecl>(DC)->isInstance()) { | 
 | 376 |     QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 377 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 378 |     // Since the 'this' expression is synthesized, we don't need to | 
 | 379 |     // perform the double-lookup check. | 
 | 380 |     NamedDecl *FirstQualifierInScope = 0; | 
 | 381 |  | 
| John McCall | aa81e16 | 2009-12-01 22:10:20 +0000 | [diff] [blame] | 382 |     return Owned(CXXDependentScopeMemberExpr::Create(Context, | 
 | 383 |                                                      /*This*/ 0, ThisType, | 
 | 384 |                                                      /*IsArrow*/ true, | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 385 |                                                      /*Op*/ SourceLocation(), | 
| Douglas Gregor | 7c3179c | 2011-02-28 18:50:33 +0000 | [diff] [blame] | 386 |                                                SS.getWithLocInContext(Context), | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 387 |                                                      FirstQualifierInScope, | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 388 |                                                      NameInfo, | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 389 |                                                      TemplateArgs)); | 
 | 390 |   } | 
 | 391 |  | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 392 |   return BuildDependentDeclRefExpr(SS, NameInfo, TemplateArgs); | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 393 | } | 
 | 394 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 395 | ExprResult | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 396 | Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS, | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 397 |                                 const DeclarationNameInfo &NameInfo, | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 398 |                                 const TemplateArgumentListInfo *TemplateArgs) { | 
 | 399 |   return Owned(DependentScopeDeclRefExpr::Create(Context, | 
| Douglas Gregor | 00cf3cc | 2011-02-25 20:49:16 +0000 | [diff] [blame] | 400 |                                                SS.getWithLocInContext(Context), | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 401 |                                                  NameInfo, | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 402 |                                                  TemplateArgs)); | 
| Douglas Gregor | d6fb7ef | 2008-12-18 19:37:40 +0000 | [diff] [blame] | 403 | } | 
 | 404 |  | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 405 | /// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining | 
 | 406 | /// that the template parameter 'PrevDecl' is being shadowed by a new | 
 | 407 | /// declaration at location Loc. Returns true to indicate that this is | 
 | 408 | /// an error, and false otherwise. | 
 | 409 | bool Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) { | 
| Douglas Gregor | f57172b | 2008-12-08 18:40:42 +0000 | [diff] [blame] | 410 |   assert(PrevDecl->isTemplateParameter() && "Not a template parameter"); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 411 |  | 
 | 412 |   // Microsoft Visual C++ permits template parameters to be shadowed. | 
 | 413 |   if (getLangOptions().Microsoft) | 
 | 414 |     return false; | 
 | 415 |  | 
 | 416 |   // C++ [temp.local]p4: | 
 | 417 |   //   A template-parameter shall not be redeclared within its | 
 | 418 |   //   scope (including nested scopes). | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 419 |   Diag(Loc, diag::err_template_param_shadow) | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 420 |     << cast<NamedDecl>(PrevDecl)->getDeclName(); | 
 | 421 |   Diag(PrevDecl->getLocation(), diag::note_template_param_here); | 
 | 422 |   return true; | 
 | 423 | } | 
 | 424 |  | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 425 | /// AdjustDeclIfTemplate - If the given decl happens to be a template, reset | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 426 | /// the parameter D to reference the templated declaration and return a pointer | 
 | 427 | /// to the template declaration. Otherwise, do nothing to D and return null. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 428 | TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) { | 
 | 429 |   if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D)) { | 
 | 430 |     D = Temp->getTemplatedDecl(); | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 431 |     return Temp; | 
 | 432 |   } | 
 | 433 |   return 0; | 
 | 434 | } | 
 | 435 |  | 
| Douglas Gregor | ba68eca | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 436 | ParsedTemplateArgument ParsedTemplateArgument::getTemplatePackExpansion( | 
 | 437 |                                              SourceLocation EllipsisLoc) const { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 438 |   assert(Kind == Template && | 
| Douglas Gregor | ba68eca | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 439 |          "Only template template arguments can be pack expansions here"); | 
 | 440 |   assert(getAsTemplate().get().containsUnexpandedParameterPack() && | 
 | 441 |          "Template template argument pack expansion without packs"); | 
 | 442 |   ParsedTemplateArgument Result(*this); | 
 | 443 |   Result.EllipsisLoc = EllipsisLoc; | 
 | 444 |   return Result; | 
 | 445 | } | 
 | 446 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 447 | static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef, | 
 | 448 |                                             const ParsedTemplateArgument &Arg) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 449 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 450 |   switch (Arg.getKind()) { | 
 | 451 |   case ParsedTemplateArgument::Type: { | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 452 |     TypeSourceInfo *DI; | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 453 |     QualType T = SemaRef.GetTypeFromParser(Arg.getAsType(), &DI); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 454 |     if (!DI) | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 455 |       DI = SemaRef.Context.getTrivialTypeSourceInfo(T, Arg.getLocation()); | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 456 |     return TemplateArgumentLoc(TemplateArgument(T), DI); | 
 | 457 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 458 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 459 |   case ParsedTemplateArgument::NonType: { | 
 | 460 |     Expr *E = static_cast<Expr *>(Arg.getAsExpr()); | 
 | 461 |     return TemplateArgumentLoc(TemplateArgument(E), E); | 
 | 462 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 463 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 464 |   case ParsedTemplateArgument::Template: { | 
| John McCall | 2b5289b | 2010-08-23 07:28:44 +0000 | [diff] [blame] | 465 |     TemplateName Template = Arg.getAsTemplate().get(); | 
| Douglas Gregor | 2be29f4 | 2011-01-14 23:41:42 +0000 | [diff] [blame] | 466 |     TemplateArgument TArg; | 
 | 467 |     if (Arg.getEllipsisLoc().isValid()) | 
 | 468 |       TArg = TemplateArgument(Template, llvm::Optional<unsigned int>()); | 
 | 469 |     else | 
 | 470 |       TArg = Template; | 
 | 471 |     return TemplateArgumentLoc(TArg, | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 472 |                                Arg.getScopeSpec().getWithLocInContext( | 
 | 473 |                                                               SemaRef.Context), | 
| Douglas Gregor | ba68eca | 2011-01-05 17:40:24 +0000 | [diff] [blame] | 474 |                                Arg.getLocation(), | 
 | 475 |                                Arg.getEllipsisLoc()); | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 476 |   } | 
 | 477 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 478 |  | 
| Jeffrey Yasskin | 9f61aa9 | 2009-12-12 05:05:38 +0000 | [diff] [blame] | 479 |   llvm_unreachable("Unhandled parsed template argument"); | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 480 |   return TemplateArgumentLoc(); | 
 | 481 | } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 482 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 483 | /// \brief Translates template arguments as provided by the parser | 
 | 484 | /// into template arguments used by semantic analysis. | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 485 | void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn, | 
 | 486 |                                       TemplateArgumentListInfo &TemplateArgs) { | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 487 |  for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I) | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 488 |    TemplateArgs.addArgument(translateTemplateArgument(*this, | 
 | 489 |                                                       TemplateArgsIn[I])); | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 490 | } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 491 |  | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 492 | /// ActOnTypeParameter - Called when a C++ template type parameter | 
 | 493 | /// (e.g., "typename T") has been parsed. Typename specifies whether | 
 | 494 | /// the keyword "typename" was used to declare the type parameter | 
 | 495 | /// (otherwise, "class" was used), and KeyLoc is the location of the | 
 | 496 | /// "class" or "typename" keyword. ParamName is the name of the | 
 | 497 | /// parameter (NULL indicates an unnamed template parameter) and | 
| Douglas Gregor | efed5c8 | 2010-06-16 15:23:05 +0000 | [diff] [blame] | 498 | /// ParamName is the location of the parameter name (if any). | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 499 | /// If the type parameter has a default argument, it will be added | 
 | 500 | /// later via ActOnTypeParameterDefault. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 501 | Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis, | 
 | 502 |                                SourceLocation EllipsisLoc, | 
 | 503 |                                SourceLocation KeyLoc, | 
 | 504 |                                IdentifierInfo *ParamName, | 
 | 505 |                                SourceLocation ParamNameLoc, | 
 | 506 |                                unsigned Depth, unsigned Position, | 
 | 507 |                                SourceLocation EqualLoc, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 508 |                                ParsedType DefaultArg) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 509 |   assert(S->isTemplateParamScope() && | 
 | 510 |          "Template type parameter not in template parameter scope!"); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 511 |   bool Invalid = false; | 
 | 512 |  | 
 | 513 |   if (ParamName) { | 
| Douglas Gregor | c83c687 | 2010-04-15 22:33:43 +0000 | [diff] [blame] | 514 |     NamedDecl *PrevDecl = LookupSingleName(S, ParamName, ParamNameLoc, | 
| Douglas Gregor | c0b3964 | 2010-04-15 23:40:53 +0000 | [diff] [blame] | 515 |                                            LookupOrdinaryName, | 
 | 516 |                                            ForRedeclaration); | 
| Douglas Gregor | f57172b | 2008-12-08 18:40:42 +0000 | [diff] [blame] | 517 |     if (PrevDecl && PrevDecl->isTemplateParameter()) | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 518 |       Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 519 |                                                            PrevDecl); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 520 |   } | 
 | 521 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 522 |   SourceLocation Loc = ParamNameLoc; | 
 | 523 |   if (!ParamName) | 
 | 524 |     Loc = KeyLoc; | 
 | 525 |  | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 526 |   TemplateTypeParmDecl *Param | 
| John McCall | 7a9813c | 2010-01-22 00:28:27 +0000 | [diff] [blame] | 527 |     = TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(), | 
| Abramo Bagnara | 344577e | 2011-03-06 15:48:19 +0000 | [diff] [blame] | 528 |                                    KeyLoc, Loc, Depth, Position, ParamName, | 
 | 529 |                                    Typename, Ellipsis); | 
| Douglas Gregor | 9a299e0 | 2011-03-04 17:52:15 +0000 | [diff] [blame] | 530 |   Param->setAccess(AS_public); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 531 |   if (Invalid) | 
 | 532 |     Param->setInvalidDecl(); | 
 | 533 |  | 
 | 534 |   if (ParamName) { | 
 | 535 |     // Add the template parameter into the current scope. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 536 |     S->AddDecl(Param); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 537 |     IdResolver.AddDecl(Param); | 
 | 538 |   } | 
 | 539 |  | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 540 |   // C++0x [temp.param]p9: | 
 | 541 |   //   A default template-argument may be specified for any kind of | 
 | 542 |   //   template-parameter that is not a template parameter pack. | 
 | 543 |   if (DefaultArg && Ellipsis) { | 
 | 544 |     Diag(EqualLoc, diag::err_template_param_pack_default_arg); | 
 | 545 |     DefaultArg = ParsedType(); | 
 | 546 |   } | 
 | 547 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 548 |   // Handle the default argument, if provided. | 
 | 549 |   if (DefaultArg) { | 
 | 550 |     TypeSourceInfo *DefaultTInfo; | 
 | 551 |     GetTypeFromParser(DefaultArg, &DefaultTInfo); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 552 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 553 |     assert(DefaultTInfo && "expected source information for type"); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 554 |  | 
| Douglas Gregor | 6f52675 | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 555 |     // Check for unexpanded parameter packs. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 556 |     if (DiagnoseUnexpandedParameterPack(Loc, DefaultTInfo, | 
| Douglas Gregor | 6f52675 | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 557 |                                         UPPC_DefaultArgument)) | 
 | 558 |       return Param; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 559 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 560 |     // Check the template argument itself. | 
 | 561 |     if (CheckTemplateArgument(Param, DefaultTInfo)) { | 
 | 562 |       Param->setInvalidDecl(); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 563 |       return Param; | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 564 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 565 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 566 |     Param->setDefaultArgument(DefaultTInfo, false); | 
 | 567 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 568 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 569 |   return Param; | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 570 | } | 
 | 571 |  | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 572 | /// \brief Check that the type of a non-type template parameter is | 
 | 573 | /// well-formed. | 
 | 574 | /// | 
 | 575 | /// \returns the (possibly-promoted) parameter type if valid; | 
 | 576 | /// otherwise, produces a diagnostic and returns a NULL type. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 577 | QualType | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 578 | Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) { | 
| Douglas Gregor | a481ec4 | 2010-05-23 19:57:01 +0000 | [diff] [blame] | 579 |   // We don't allow variably-modified types as the type of non-type template | 
 | 580 |   // parameters. | 
 | 581 |   if (T->isVariablyModifiedType()) { | 
 | 582 |     Diag(Loc, diag::err_variably_modified_nontype_template_param) | 
 | 583 |       << T; | 
 | 584 |     return QualType(); | 
 | 585 |   } | 
 | 586 |  | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 587 |   // C++ [temp.param]p4: | 
 | 588 |   // | 
 | 589 |   // A non-type template-parameter shall have one of the following | 
 | 590 |   // (optionally cv-qualified) types: | 
 | 591 |   // | 
 | 592 |   //       -- integral or enumeration type, | 
| Douglas Gregor | 2ade35e | 2010-06-16 00:17:44 +0000 | [diff] [blame] | 593 |   if (T->isIntegralOrEnumerationType() || | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 594 |       //   -- pointer to object or pointer to function, | 
| Eli Friedman | 1357869 | 2010-08-05 02:49:48 +0000 | [diff] [blame] | 595 |       T->isPointerType() || | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 596 |       //   -- reference to object or reference to function, | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 597 |       T->isReferenceType() || | 
 | 598 |       //   -- pointer to member. | 
 | 599 |       T->isMemberPointerType() || | 
 | 600 |       // If T is a dependent type, we can't do the check now, so we | 
 | 601 |       // assume that it is well-formed. | 
 | 602 |       T->isDependentType()) | 
 | 603 |     return T; | 
 | 604 |   // C++ [temp.param]p8: | 
 | 605 |   // | 
 | 606 |   //   A non-type template-parameter of type "array of T" or | 
 | 607 |   //   "function returning T" is adjusted to be of type "pointer to | 
 | 608 |   //   T" or "pointer to function returning T", respectively. | 
 | 609 |   else if (T->isArrayType()) | 
 | 610 |     // FIXME: Keep the type prior to promotion? | 
 | 611 |     return Context.getArrayDecayedType(T); | 
 | 612 |   else if (T->isFunctionType()) | 
 | 613 |     // FIXME: Keep the type prior to promotion? | 
 | 614 |     return Context.getPointerType(T); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 615 |  | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 616 |   Diag(Loc, diag::err_template_nontype_parm_bad_type) | 
 | 617 |     << T; | 
 | 618 |  | 
 | 619 |   return QualType(); | 
 | 620 | } | 
 | 621 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 622 | Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D, | 
 | 623 |                                           unsigned Depth, | 
 | 624 |                                           unsigned Position, | 
 | 625 |                                           SourceLocation EqualLoc, | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 626 |                                           Expr *Default) { | 
| John McCall | bf1a028 | 2010-06-04 23:28:52 +0000 | [diff] [blame] | 627 |   TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); | 
 | 628 |   QualType T = TInfo->getType(); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 629 |  | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 630 |   assert(S->isTemplateParamScope() && | 
 | 631 |          "Non-type template parameter not in template parameter scope!"); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 632 |   bool Invalid = false; | 
 | 633 |  | 
 | 634 |   IdentifierInfo *ParamName = D.getIdentifier(); | 
 | 635 |   if (ParamName) { | 
| Douglas Gregor | c83c687 | 2010-04-15 22:33:43 +0000 | [diff] [blame] | 636 |     NamedDecl *PrevDecl = LookupSingleName(S, ParamName, D.getIdentifierLoc(), | 
| Douglas Gregor | c0b3964 | 2010-04-15 23:40:53 +0000 | [diff] [blame] | 637 |                                            LookupOrdinaryName, | 
 | 638 |                                            ForRedeclaration); | 
| Douglas Gregor | f57172b | 2008-12-08 18:40:42 +0000 | [diff] [blame] | 639 |     if (PrevDecl && PrevDecl->isTemplateParameter()) | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 640 |       Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 641 |                                                            PrevDecl); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 642 |   } | 
 | 643 |  | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 644 |   T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc()); | 
 | 645 |   if (T.isNull()) { | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 646 |     T = Context.IntTy; // Recover with an 'int' type. | 
| Douglas Gregor | ceef30c | 2009-03-09 16:46:39 +0000 | [diff] [blame] | 647 |     Invalid = true; | 
 | 648 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 649 |  | 
| Douglas Gregor | 10738d3 | 2010-12-23 23:51:58 +0000 | [diff] [blame] | 650 |   bool IsParameterPack = D.hasEllipsis(); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 651 |   NonTypeTemplateParmDecl *Param | 
| John McCall | 7a9813c | 2010-01-22 00:28:27 +0000 | [diff] [blame] | 652 |     = NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(), | 
| Abramo Bagnara | ff676cb | 2011-03-08 08:55:46 +0000 | [diff] [blame] | 653 |                                       D.getSourceRange().getBegin(), | 
| John McCall | 7a9813c | 2010-01-22 00:28:27 +0000 | [diff] [blame] | 654 |                                       D.getIdentifierLoc(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 655 |                                       Depth, Position, ParamName, T, | 
| Douglas Gregor | 10738d3 | 2010-12-23 23:51:58 +0000 | [diff] [blame] | 656 |                                       IsParameterPack, TInfo); | 
| Douglas Gregor | 9a299e0 | 2011-03-04 17:52:15 +0000 | [diff] [blame] | 657 |   Param->setAccess(AS_public); | 
 | 658 |    | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 659 |   if (Invalid) | 
 | 660 |     Param->setInvalidDecl(); | 
 | 661 |  | 
 | 662 |   if (D.getIdentifier()) { | 
 | 663 |     // Add the template parameter into the current scope. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 664 |     S->AddDecl(Param); | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 665 |     IdResolver.AddDecl(Param); | 
 | 666 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 667 |  | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 668 |   // C++0x [temp.param]p9: | 
 | 669 |   //   A default template-argument may be specified for any kind of | 
 | 670 |   //   template-parameter that is not a template parameter pack. | 
 | 671 |   if (Default && IsParameterPack) { | 
 | 672 |     Diag(EqualLoc, diag::err_template_param_pack_default_arg); | 
 | 673 |     Default = 0; | 
 | 674 |   } | 
 | 675 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 676 |   // Check the well-formedness of the default template argument, if provided. | 
| Douglas Gregor | 10738d3 | 2010-12-23 23:51:58 +0000 | [diff] [blame] | 677 |   if (Default) { | 
| Douglas Gregor | 6f52675 | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 678 |     // Check for unexpanded parameter packs. | 
 | 679 |     if (DiagnoseUnexpandedParameterPack(Default, UPPC_DefaultArgument)) | 
 | 680 |       return Param; | 
 | 681 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 682 |     TemplateArgument Converted; | 
 | 683 |     if (CheckTemplateArgument(Param, Param->getType(), Default, Converted)) { | 
 | 684 |       Param->setInvalidDecl(); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 685 |       return Param; | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 686 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 687 |  | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 688 |     Param->setDefaultArgument(Default, false); | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 689 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 690 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 691 |   return Param; | 
| Douglas Gregor | 72c3f31 | 2008-12-05 18:15:24 +0000 | [diff] [blame] | 692 | } | 
| Douglas Gregor | c4b4e7b | 2008-12-24 02:52:09 +0000 | [diff] [blame] | 693 |  | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 694 | /// ActOnTemplateTemplateParameter - Called when a C++ template template | 
 | 695 | /// parameter (e.g. T in template <template <typename> class T> class array) | 
 | 696 | /// has been parsed. S is the current scope. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 697 | Decl *Sema::ActOnTemplateTemplateParameter(Scope* S, | 
 | 698 |                                            SourceLocation TmpLoc, | 
 | 699 |                                            TemplateParamsTy *Params, | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 700 |                                            SourceLocation EllipsisLoc, | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 701 |                                            IdentifierInfo *Name, | 
 | 702 |                                            SourceLocation NameLoc, | 
 | 703 |                                            unsigned Depth, | 
 | 704 |                                            unsigned Position, | 
 | 705 |                                            SourceLocation EqualLoc, | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 706 |                                            ParsedTemplateArgument Default) { | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 707 |   assert(S->isTemplateParamScope() && | 
 | 708 |          "Template template parameter not in template parameter scope!"); | 
 | 709 |  | 
 | 710 |   // Construct the parameter object. | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 711 |   bool IsParameterPack = EllipsisLoc.isValid(); | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 712 |   TemplateTemplateParmDecl *Param = | 
| John McCall | 7a9813c | 2010-01-22 00:28:27 +0000 | [diff] [blame] | 713 |     TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 714 |                                      NameLoc.isInvalid()? TmpLoc : NameLoc, | 
 | 715 |                                      Depth, Position, IsParameterPack, | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 716 |                                      Name, Params); | 
| Douglas Gregor | 9a299e0 | 2011-03-04 17:52:15 +0000 | [diff] [blame] | 717 |   Param->setAccess(AS_public); | 
 | 718 |    | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 719 |   // If the template template parameter has a name, then link the identifier | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 720 |   // into the scope and lookup mechanisms. | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 721 |   if (Name) { | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 722 |     S->AddDecl(Param); | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 723 |     IdResolver.AddDecl(Param); | 
 | 724 |   } | 
 | 725 |  | 
| Douglas Gregor | 6f52675 | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 726 |   if (Params->size() == 0) { | 
 | 727 |     Diag(Param->getLocation(), diag::err_template_template_parm_no_parms) | 
 | 728 |     << SourceRange(Params->getLAngleLoc(), Params->getRAngleLoc()); | 
 | 729 |     Param->setInvalidDecl(); | 
 | 730 |   } | 
 | 731 |  | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 732 |   // C++0x [temp.param]p9: | 
 | 733 |   //   A default template-argument may be specified for any kind of | 
 | 734 |   //   template-parameter that is not a template parameter pack. | 
 | 735 |   if (IsParameterPack && !Default.isInvalid()) { | 
 | 736 |     Diag(EqualLoc, diag::err_template_param_pack_default_arg); | 
 | 737 |     Default = ParsedTemplateArgument(); | 
 | 738 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 739 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 740 |   if (!Default.isInvalid()) { | 
 | 741 |     // Check only that we have a template template argument. We don't want to | 
 | 742 |     // try to check well-formedness now, because our template template parameter | 
 | 743 |     // might have dependent types in its template parameters, which we wouldn't | 
 | 744 |     // be able to match now. | 
 | 745 |     // | 
 | 746 |     // If none of the template template parameter's template arguments mention | 
 | 747 |     // other template parameters, we could actually perform more checking here. | 
 | 748 |     // However, it isn't worth doing. | 
 | 749 |     TemplateArgumentLoc DefaultArg = translateTemplateArgument(*this, Default); | 
 | 750 |     if (DefaultArg.getArgument().getAsTemplate().isNull()) { | 
 | 751 |       Diag(DefaultArg.getLocation(), diag::err_template_arg_not_class_template) | 
 | 752 |         << DefaultArg.getSourceRange(); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 753 |       return Param; | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 754 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 755 |  | 
| Douglas Gregor | 6f52675 | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 756 |     // Check for unexpanded parameter packs. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 757 |     if (DiagnoseUnexpandedParameterPack(DefaultArg.getLocation(), | 
| Douglas Gregor | 6f52675 | 2010-12-16 08:48:57 +0000 | [diff] [blame] | 758 |                                         DefaultArg.getArgument().getAsTemplate(), | 
 | 759 |                                         UPPC_DefaultArgument)) | 
 | 760 |       return Param; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 761 |  | 
| Douglas Gregor | bb3310a | 2010-07-01 00:00:45 +0000 | [diff] [blame] | 762 |     Param->setDefaultArgument(DefaultArg, false); | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 763 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 764 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 765 |   return Param; | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 766 | } | 
 | 767 |  | 
| Douglas Gregor | c4b4e7b | 2008-12-24 02:52:09 +0000 | [diff] [blame] | 768 | /// ActOnTemplateParameterList - Builds a TemplateParameterList that | 
 | 769 | /// contains the template parameters in Params/NumParams. | 
 | 770 | Sema::TemplateParamsTy * | 
 | 771 | Sema::ActOnTemplateParameterList(unsigned Depth, | 
 | 772 |                                  SourceLocation ExportLoc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 773 |                                  SourceLocation TemplateLoc, | 
| Douglas Gregor | c4b4e7b | 2008-12-24 02:52:09 +0000 | [diff] [blame] | 774 |                                  SourceLocation LAngleLoc, | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 775 |                                  Decl **Params, unsigned NumParams, | 
| Douglas Gregor | c4b4e7b | 2008-12-24 02:52:09 +0000 | [diff] [blame] | 776 |                                  SourceLocation RAngleLoc) { | 
 | 777 |   if (ExportLoc.isValid()) | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 778 |     Diag(ExportLoc, diag::warn_template_export_unsupported); | 
| Douglas Gregor | c4b4e7b | 2008-12-24 02:52:09 +0000 | [diff] [blame] | 779 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 780 |   return TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 781 |                                        (NamedDecl**)Params, NumParams, | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 782 |                                        RAngleLoc); | 
| Douglas Gregor | c4b4e7b | 2008-12-24 02:52:09 +0000 | [diff] [blame] | 783 | } | 
| Douglas Gregor | aaba5e3 | 2009-02-04 19:02:06 +0000 | [diff] [blame] | 784 |  | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 785 | static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) { | 
 | 786 |   if (SS.isSet()) | 
| Douglas Gregor | c22b5ff | 2011-02-25 02:25:35 +0000 | [diff] [blame] | 787 |     T->setQualifierInfo(SS.getWithLocInContext(T->getASTContext())); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 788 | } | 
 | 789 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 790 | DeclResult | 
| John McCall | 0f434ec | 2009-07-31 02:45:11 +0000 | [diff] [blame] | 791 | Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 792 |                          SourceLocation KWLoc, CXXScopeSpec &SS, | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 793 |                          IdentifierInfo *Name, SourceLocation NameLoc, | 
 | 794 |                          AttributeList *Attr, | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 795 |                          TemplateParameterList *TemplateParams, | 
| Abramo Bagnara | c57c17d | 2011-03-10 13:28:31 +0000 | [diff] [blame^] | 796 |                          AccessSpecifier AS, | 
 | 797 |                          unsigned NumOuterTemplateParamLists, | 
 | 798 |                          TemplateParameterList** OuterTemplateParamLists) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 799 |   assert(TemplateParams && TemplateParams->size() > 0 && | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 800 |          "No template parameters"); | 
| John McCall | 0f434ec | 2009-07-31 02:45:11 +0000 | [diff] [blame] | 801 |   assert(TUK != TUK_Reference && "Can only declare or define class templates"); | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 802 |   bool Invalid = false; | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 803 |  | 
 | 804 |   // Check that we can declare a template here. | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 805 |   if (CheckTemplateDeclScope(S, TemplateParams)) | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 806 |     return true; | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 807 |  | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 808 |   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); | 
 | 809 |   assert(Kind != TTK_Enum && "can't build template of enumerated type"); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 810 |  | 
 | 811 |   // There is no such thing as an unnamed class template. | 
 | 812 |   if (!Name) { | 
 | 813 |     Diag(KWLoc, diag::err_template_unnamed_class); | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 814 |     return true; | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 815 |   } | 
 | 816 |  | 
 | 817 |   // Find any previous declaration with this name. | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 818 |   DeclContext *SemanticContext; | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 819 |   LookupResult Previous(*this, Name, NameLoc, LookupOrdinaryName, | 
| John McCall | 7d384dd | 2009-11-18 07:57:50 +0000 | [diff] [blame] | 820 |                         ForRedeclaration); | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 821 |   if (SS.isNotEmpty() && !SS.isInvalid()) { | 
 | 822 |     SemanticContext = computeDeclContext(SS, true); | 
 | 823 |     if (!SemanticContext) { | 
 | 824 |       // FIXME: Produce a reasonable diagnostic here | 
 | 825 |       return true; | 
 | 826 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 827 |  | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 828 |     if (RequireCompleteDeclContext(SS, SemanticContext)) | 
 | 829 |       return true; | 
 | 830 |  | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 831 |     LookupQualifiedName(Previous, SemanticContext); | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 832 |   } else { | 
 | 833 |     SemanticContext = CurContext; | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 834 |     LookupName(Previous, S); | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 835 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 836 |  | 
| Douglas Gregor | 57265e3 | 2010-04-12 16:00:01 +0000 | [diff] [blame] | 837 |   if (Previous.isAmbiguous()) | 
 | 838 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 839 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 840 |   NamedDecl *PrevDecl = 0; | 
 | 841 |   if (Previous.begin() != Previous.end()) | 
| Douglas Gregor | 57265e3 | 2010-04-12 16:00:01 +0000 | [diff] [blame] | 842 |     PrevDecl = (*Previous.begin())->getUnderlyingDecl(); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 843 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 844 |   // If there is a previous declaration with the same name, check | 
 | 845 |   // whether this is a valid redeclaration. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 846 |   ClassTemplateDecl *PrevClassTemplate | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 847 |     = dyn_cast_or_null<ClassTemplateDecl>(PrevDecl); | 
| Douglas Gregor | d7e5bdb | 2009-10-09 21:11:42 +0000 | [diff] [blame] | 848 |  | 
 | 849 |   // We may have found the injected-class-name of a class template, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 850 |   // class template partial specialization, or class template specialization. | 
| Douglas Gregor | d7e5bdb | 2009-10-09 21:11:42 +0000 | [diff] [blame] | 851 |   // In these cases, grab the template that is being defined or specialized. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 852 |   if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) && | 
| Douglas Gregor | d7e5bdb | 2009-10-09 21:11:42 +0000 | [diff] [blame] | 853 |       cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) { | 
 | 854 |     PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 855 |     PrevClassTemplate | 
| Douglas Gregor | d7e5bdb | 2009-10-09 21:11:42 +0000 | [diff] [blame] | 856 |       = cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate(); | 
 | 857 |     if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) { | 
 | 858 |       PrevClassTemplate | 
 | 859 |         = cast<ClassTemplateSpecializationDecl>(PrevDecl) | 
 | 860 |             ->getSpecializedTemplate(); | 
 | 861 |     } | 
 | 862 |   } | 
 | 863 |  | 
| John McCall | 65c4946 | 2009-12-18 11:25:59 +0000 | [diff] [blame] | 864 |   if (TUK == TUK_Friend) { | 
| John McCall | e129d44 | 2009-12-17 23:21:11 +0000 | [diff] [blame] | 865 |     // C++ [namespace.memdef]p3: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 866 |     //   [...] When looking for a prior declaration of a class or a function | 
 | 867 |     //   declared as a friend, and when the name of the friend class or | 
| John McCall | e129d44 | 2009-12-17 23:21:11 +0000 | [diff] [blame] | 868 |     //   function is neither a qualified name nor a template-id, scopes outside | 
 | 869 |     //   the innermost enclosing namespace scope are not considered. | 
| Douglas Gregor | c1c9df7 | 2010-04-18 17:37:40 +0000 | [diff] [blame] | 870 |     if (!SS.isSet()) { | 
 | 871 |       DeclContext *OutermostContext = CurContext; | 
 | 872 |       while (!OutermostContext->isFileContext()) | 
 | 873 |         OutermostContext = OutermostContext->getLookupParent(); | 
| John McCall | 65c4946 | 2009-12-18 11:25:59 +0000 | [diff] [blame] | 874 |  | 
| Douglas Gregor | c1c9df7 | 2010-04-18 17:37:40 +0000 | [diff] [blame] | 875 |       if (PrevDecl && | 
 | 876 |           (OutermostContext->Equals(PrevDecl->getDeclContext()) || | 
 | 877 |            OutermostContext->Encloses(PrevDecl->getDeclContext()))) { | 
 | 878 |         SemanticContext = PrevDecl->getDeclContext(); | 
 | 879 |       } else { | 
 | 880 |         // Declarations in outer scopes don't matter. However, the outermost | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 881 |         // context we computed is the semantic context for our new | 
| Douglas Gregor | c1c9df7 | 2010-04-18 17:37:40 +0000 | [diff] [blame] | 882 |         // declaration. | 
 | 883 |         PrevDecl = PrevClassTemplate = 0; | 
 | 884 |         SemanticContext = OutermostContext; | 
 | 885 |       } | 
| John McCall | e129d44 | 2009-12-17 23:21:11 +0000 | [diff] [blame] | 886 |     } | 
| Douglas Gregor | c1c9df7 | 2010-04-18 17:37:40 +0000 | [diff] [blame] | 887 |  | 
| John McCall | e129d44 | 2009-12-17 23:21:11 +0000 | [diff] [blame] | 888 |     if (CurContext->isDependentContext()) { | 
 | 889 |       // If this is a dependent context, we don't want to link the friend | 
 | 890 |       // class template to the template in scope, because that would perform | 
 | 891 |       // checking of the template parameter lists that can't be performed | 
 | 892 |       // until the outer context is instantiated. | 
 | 893 |       PrevDecl = PrevClassTemplate = 0; | 
 | 894 |     } | 
 | 895 |   } else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S)) | 
 | 896 |     PrevDecl = PrevClassTemplate = 0; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 897 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 898 |   if (PrevClassTemplate) { | 
 | 899 |     // Ensure that the template parameter lists are compatible. | 
 | 900 |     if (!TemplateParameterListsAreEqual(TemplateParams, | 
 | 901 |                                    PrevClassTemplate->getTemplateParameters(), | 
| Douglas Gregor | fb898e1 | 2009-11-12 16:20:59 +0000 | [diff] [blame] | 902 |                                         /*Complain=*/true, | 
 | 903 |                                         TPL_TemplateMatch)) | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 904 |       return true; | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 905 |  | 
 | 906 |     // C++ [temp.class]p4: | 
 | 907 |     //   In a redeclaration, partial specialization, explicit | 
 | 908 |     //   specialization or explicit instantiation of a class template, | 
 | 909 |     //   the class-key shall agree in kind with the original class | 
 | 910 |     //   template declaration (7.1.5.3). | 
 | 911 |     RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl(); | 
| Douglas Gregor | 501c5ce | 2009-05-14 16:41:31 +0000 | [diff] [blame] | 912 |     if (!isAcceptableTagRedeclaration(PrevRecordDecl, Kind, KWLoc, *Name)) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 913 |       Diag(KWLoc, diag::err_use_with_wrong_tag) | 
| Douglas Gregor | a3a8351 | 2009-04-01 23:51:29 +0000 | [diff] [blame] | 914 |         << Name | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 915 |         << FixItHint::CreateReplacement(KWLoc, PrevRecordDecl->getKindName()); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 916 |       Diag(PrevRecordDecl->getLocation(), diag::note_previous_use); | 
| Douglas Gregor | a3a8351 | 2009-04-01 23:51:29 +0000 | [diff] [blame] | 917 |       Kind = PrevRecordDecl->getTagKind(); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 918 |     } | 
 | 919 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 920 |     // Check for redefinition of this class template. | 
| John McCall | 0f434ec | 2009-07-31 02:45:11 +0000 | [diff] [blame] | 921 |     if (TUK == TUK_Definition) { | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 922 |       if (TagDecl *Def = PrevRecordDecl->getDefinition()) { | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 923 |         Diag(NameLoc, diag::err_redefinition) << Name; | 
 | 924 |         Diag(Def->getLocation(), diag::note_previous_definition); | 
 | 925 |         // FIXME: Would it make sense to try to "forget" the previous | 
 | 926 |         // definition, as part of error recovery? | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 927 |         return true; | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 928 |       } | 
 | 929 |     } | 
 | 930 |   } else if (PrevDecl && PrevDecl->isTemplateParameter()) { | 
 | 931 |     // Maybe we will complain about the shadowed template parameter. | 
 | 932 |     DiagnoseTemplateParameterShadow(NameLoc, PrevDecl); | 
 | 933 |     // Just pretend that we didn't see the previous declaration. | 
 | 934 |     PrevDecl = 0; | 
 | 935 |   } else if (PrevDecl) { | 
 | 936 |     // C++ [temp]p5: | 
 | 937 |     //   A class template shall not have the same name as any other | 
 | 938 |     //   template, class, function, object, enumeration, enumerator, | 
 | 939 |     //   namespace, or type in the same scope (3.3), except as specified | 
 | 940 |     //   in (14.5.4). | 
 | 941 |     Diag(NameLoc, diag::err_redefinition_different_kind) << Name; | 
 | 942 |     Diag(PrevDecl->getLocation(), diag::note_previous_definition); | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 943 |     return true; | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 944 |   } | 
 | 945 |  | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 946 |   // Check the template parameter list of this declaration, possibly | 
 | 947 |   // merging in the template parameter list from the previous class | 
 | 948 |   // template declaration. | 
 | 949 |   if (CheckTemplateParameterList(TemplateParams, | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 950 |             PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0, | 
| Douglas Gregor | d89d86f | 2011-02-04 04:20:44 +0000 | [diff] [blame] | 951 |                                  (SS.isSet() && SemanticContext && | 
| Douglas Gregor | 461bf2e | 2011-02-04 12:22:53 +0000 | [diff] [blame] | 952 |                                   SemanticContext->isRecord() && | 
 | 953 |                                   SemanticContext->isDependentContext()) | 
| Douglas Gregor | d89d86f | 2011-02-04 04:20:44 +0000 | [diff] [blame] | 954 |                                    ? TPC_ClassTemplateMember | 
 | 955 |                                    : TPC_ClassTemplate)) | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 956 |     Invalid = true; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 957 |  | 
| Douglas Gregor | 57265e3 | 2010-04-12 16:00:01 +0000 | [diff] [blame] | 958 |   if (SS.isSet()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 959 |     // If the name of the template was qualified, we must be defining the | 
| Douglas Gregor | 57265e3 | 2010-04-12 16:00:01 +0000 | [diff] [blame] | 960 |     // template out-of-line. | 
 | 961 |     if (!SS.isInvalid() && !Invalid && !PrevClassTemplate && | 
 | 962 |         !(TUK == TUK_Friend && CurContext->isDependentContext())) | 
 | 963 |       Diag(NameLoc, diag::err_member_def_does_not_match) | 
 | 964 |         << Name << SemanticContext << SS.getRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 965 |   } | 
 | 966 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 967 |   CXXRecordDecl *NewClass = | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 968 |     CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 969 |                           PrevClassTemplate? | 
| Douglas Gregor | aafc0cc | 2009-05-15 19:11:46 +0000 | [diff] [blame] | 970 |                             PrevClassTemplate->getTemplatedDecl() : 0, | 
 | 971 |                           /*DelayTypeCreation=*/true); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 972 |   SetNestedNameSpecifier(NewClass, SS); | 
| Abramo Bagnara | c57c17d | 2011-03-10 13:28:31 +0000 | [diff] [blame^] | 973 |   if (NumOuterTemplateParamLists > 0) | 
 | 974 |     NewClass->setTemplateParameterListsInfo(Context, | 
 | 975 |                                             NumOuterTemplateParamLists, | 
 | 976 |                                             OuterTemplateParamLists); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 977 |  | 
 | 978 |   ClassTemplateDecl *NewTemplate | 
 | 979 |     = ClassTemplateDecl::Create(Context, SemanticContext, NameLoc, | 
 | 980 |                                 DeclarationName(Name), TemplateParams, | 
| Douglas Gregor | 5953d8b | 2009-03-19 17:26:29 +0000 | [diff] [blame] | 981 |                                 NewClass, PrevClassTemplate); | 
| Douglas Gregor | befc20e | 2009-03-26 00:10:35 +0000 | [diff] [blame] | 982 |   NewClass->setDescribedClassTemplate(NewTemplate); | 
 | 983 |  | 
| Douglas Gregor | aafc0cc | 2009-05-15 19:11:46 +0000 | [diff] [blame] | 984 |   // Build the type for the class template declaration now. | 
| Douglas Gregor | 24bae92 | 2010-07-08 18:37:38 +0000 | [diff] [blame] | 985 |   QualType T = NewTemplate->getInjectedClassNameSpecialization(); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 986 |   T = Context.getInjectedClassNameType(NewClass, T); | 
| Douglas Gregor | aafc0cc | 2009-05-15 19:11:46 +0000 | [diff] [blame] | 987 |   assert(T->isDependentType() && "Class template type is not dependent?"); | 
 | 988 |   (void)T; | 
 | 989 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 990 |   // If we are providing an explicit specialization of a member that is a | 
| Douglas Gregor | fd056bc | 2009-10-13 16:30:37 +0000 | [diff] [blame] | 991 |   // class template, make a note of that. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 992 |   if (PrevClassTemplate && | 
| Douglas Gregor | fd056bc | 2009-10-13 16:30:37 +0000 | [diff] [blame] | 993 |       PrevClassTemplate->getInstantiatedFromMemberTemplate()) | 
 | 994 |     PrevClassTemplate->setMemberSpecialization(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 995 |  | 
| Anders Carlsson | 4cbe82c | 2009-03-26 01:24:28 +0000 | [diff] [blame] | 996 |   // Set the access specifier. | 
| Douglas Gregor | d85bea2 | 2009-09-26 06:47:28 +0000 | [diff] [blame] | 997 |   if (!Invalid && TUK != TUK_Friend) | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 998 |     SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 999 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 1000 |   // Set the lexical context of these templates | 
 | 1001 |   NewClass->setLexicalDeclContext(CurContext); | 
 | 1002 |   NewTemplate->setLexicalDeclContext(CurContext); | 
 | 1003 |  | 
| John McCall | 0f434ec | 2009-07-31 02:45:11 +0000 | [diff] [blame] | 1004 |   if (TUK == TUK_Definition) | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 1005 |     NewClass->startDefinition(); | 
 | 1006 |  | 
 | 1007 |   if (Attr) | 
| Douglas Gregor | 9cdda0c | 2009-06-17 21:51:59 +0000 | [diff] [blame] | 1008 |     ProcessDeclAttributeList(S, NewClass, Attr); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 1009 |  | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 1010 |   if (TUK != TUK_Friend) | 
 | 1011 |     PushOnScopeChains(NewTemplate, S); | 
 | 1012 |   else { | 
| Douglas Gregor | d85bea2 | 2009-09-26 06:47:28 +0000 | [diff] [blame] | 1013 |     if (PrevClassTemplate && PrevClassTemplate->getAccess() != AS_none) { | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 1014 |       NewTemplate->setAccess(PrevClassTemplate->getAccess()); | 
| Douglas Gregor | d85bea2 | 2009-09-26 06:47:28 +0000 | [diff] [blame] | 1015 |       NewClass->setAccess(PrevClassTemplate->getAccess()); | 
 | 1016 |     } | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 1017 |  | 
| Douglas Gregor | d85bea2 | 2009-09-26 06:47:28 +0000 | [diff] [blame] | 1018 |     NewTemplate->setObjectOfFriendDecl(/* PreviouslyDeclared = */ | 
 | 1019 |                                        PrevClassTemplate != NULL); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1020 |  | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 1021 |     // Friend templates are visible in fairly strange ways. | 
 | 1022 |     if (!CurContext->isDependentContext()) { | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 1023 |       DeclContext *DC = SemanticContext->getRedeclContext(); | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 1024 |       DC->makeDeclVisibleInContext(NewTemplate, /* Recoverable = */ false); | 
 | 1025 |       if (Scope *EnclosingScope = getScopeForDeclContext(S, DC)) | 
 | 1026 |         PushOnScopeChains(NewTemplate, EnclosingScope, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1027 |                           /* AddToContext = */ false); | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 1028 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1029 |  | 
| Douglas Gregor | d85bea2 | 2009-09-26 06:47:28 +0000 | [diff] [blame] | 1030 |     FriendDecl *Friend = FriendDecl::Create(Context, CurContext, | 
 | 1031 |                                             NewClass->getLocation(), | 
 | 1032 |                                             NewTemplate, | 
 | 1033 |                                     /*FIXME:*/NewClass->getLocation()); | 
 | 1034 |     Friend->setAccess(AS_public); | 
 | 1035 |     CurContext->addDecl(Friend); | 
| John McCall | 05b23ea | 2009-09-14 21:59:20 +0000 | [diff] [blame] | 1036 |   } | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 1037 |  | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1038 |   if (Invalid) { | 
 | 1039 |     NewTemplate->setInvalidDecl(); | 
 | 1040 |     NewClass->setInvalidDecl(); | 
 | 1041 |   } | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 1042 |   return NewTemplate; | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 1043 | } | 
 | 1044 |  | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1045 | /// \brief Diagnose the presence of a default template argument on a | 
 | 1046 | /// template parameter, which is ill-formed in certain contexts. | 
 | 1047 | /// | 
 | 1048 | /// \returns true if the default template argument should be dropped. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1049 | static bool DiagnoseDefaultTemplateArgument(Sema &S, | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1050 |                                             Sema::TemplateParamListContext TPC, | 
 | 1051 |                                             SourceLocation ParamLoc, | 
 | 1052 |                                             SourceRange DefArgRange) { | 
 | 1053 |   switch (TPC) { | 
 | 1054 |   case Sema::TPC_ClassTemplate: | 
 | 1055 |     return false; | 
 | 1056 |  | 
 | 1057 |   case Sema::TPC_FunctionTemplate: | 
| Douglas Gregor | d89d86f | 2011-02-04 04:20:44 +0000 | [diff] [blame] | 1058 |   case Sema::TPC_FriendFunctionTemplateDefinition: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1059 |     // C++ [temp.param]p9: | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1060 |     //   A default template-argument shall not be specified in a | 
 | 1061 |     //   function template declaration or a function template | 
 | 1062 |     //   definition [...] | 
| Douglas Gregor | d89d86f | 2011-02-04 04:20:44 +0000 | [diff] [blame] | 1063 |     //   If a friend function template declaration specifies a default  | 
 | 1064 |     //   template-argument, that declaration shall be a definition and shall be | 
 | 1065 |     //   the only declaration of the function template in the translation unit. | 
 | 1066 |     // (C++98/03 doesn't have this wording; see DR226). | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1067 |     if (!S.getLangOptions().CPlusPlus0x) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1068 |       S.Diag(ParamLoc, | 
| Douglas Gregor | ee5d21f | 2011-02-04 03:57:22 +0000 | [diff] [blame] | 1069 |              diag::ext_template_parameter_default_in_function_template) | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1070 |         << DefArgRange; | 
 | 1071 |     return false; | 
 | 1072 |  | 
 | 1073 |   case Sema::TPC_ClassTemplateMember: | 
 | 1074 |     // C++0x [temp.param]p9: | 
 | 1075 |     //   A default template-argument shall not be specified in the | 
 | 1076 |     //   template-parameter-lists of the definition of a member of a | 
 | 1077 |     //   class template that appears outside of the member's class. | 
 | 1078 |     S.Diag(ParamLoc, diag::err_template_parameter_default_template_member) | 
 | 1079 |       << DefArgRange; | 
 | 1080 |     return true; | 
 | 1081 |  | 
 | 1082 |   case Sema::TPC_FriendFunctionTemplate: | 
 | 1083 |     // C++ [temp.param]p9: | 
 | 1084 |     //   A default template-argument shall not be specified in a | 
 | 1085 |     //   friend template declaration. | 
 | 1086 |     S.Diag(ParamLoc, diag::err_template_parameter_default_friend_template) | 
 | 1087 |       << DefArgRange; | 
 | 1088 |     return true; | 
 | 1089 |  | 
 | 1090 |     // FIXME: C++0x [temp.param]p9 allows default template-arguments | 
 | 1091 |     // for friend function templates if there is only a single | 
 | 1092 |     // declaration (and it is a definition). Strange! | 
 | 1093 |   } | 
 | 1094 |  | 
 | 1095 |   return false; | 
 | 1096 | } | 
 | 1097 |  | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1098 | /// \brief Check for unexpanded parameter packs within the template parameters | 
 | 1099 | /// of a template template parameter, recursively. | 
 | 1100 | bool DiagnoseUnexpandedParameterPacks(Sema &S, TemplateTemplateParmDecl *TTP){ | 
 | 1101 |   TemplateParameterList *Params = TTP->getTemplateParameters(); | 
 | 1102 |   for (unsigned I = 0, N = Params->size(); I != N; ++I) { | 
 | 1103 |     NamedDecl *P = Params->getParam(I); | 
 | 1104 |     if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1105 |       if (S.DiagnoseUnexpandedParameterPack(NTTP->getLocation(), | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1106 |                                             NTTP->getTypeSourceInfo(), | 
 | 1107 |                                       Sema::UPPC_NonTypeTemplateParameterType)) | 
 | 1108 |         return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1109 |  | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1110 |       continue; | 
 | 1111 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1112 |  | 
 | 1113 |     if (TemplateTemplateParmDecl *InnerTTP | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1114 |                                         = dyn_cast<TemplateTemplateParmDecl>(P)) | 
 | 1115 |       if (DiagnoseUnexpandedParameterPacks(S, InnerTTP)) | 
 | 1116 |         return true; | 
 | 1117 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1118 |  | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1119 |   return false; | 
 | 1120 | } | 
 | 1121 |  | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1122 | /// \brief Checks the validity of a template parameter list, possibly | 
 | 1123 | /// considering the template parameter list from a previous | 
 | 1124 | /// declaration. | 
 | 1125 | /// | 
 | 1126 | /// If an "old" template parameter list is provided, it must be | 
 | 1127 | /// equivalent (per TemplateParameterListsAreEqual) to the "new" | 
 | 1128 | /// template parameter list. | 
 | 1129 | /// | 
 | 1130 | /// \param NewParams Template parameter list for a new template | 
 | 1131 | /// declaration. This template parameter list will be updated with any | 
 | 1132 | /// default arguments that are carried through from the previous | 
 | 1133 | /// template parameter list. | 
 | 1134 | /// | 
 | 1135 | /// \param OldParams If provided, template parameter list from a | 
 | 1136 | /// previous declaration of the same template. Default template | 
 | 1137 | /// arguments will be merged from the old template parameter list to | 
 | 1138 | /// the new template parameter list. | 
 | 1139 | /// | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1140 | /// \param TPC Describes the context in which we are checking the given | 
 | 1141 | /// template parameter list. | 
 | 1142 | /// | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1143 | /// \returns true if an error occurred, false otherwise. | 
 | 1144 | bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams, | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1145 |                                       TemplateParameterList *OldParams, | 
 | 1146 |                                       TemplateParamListContext TPC) { | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1147 |   bool Invalid = false; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1148 |  | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1149 |   // C++ [temp.param]p10: | 
 | 1150 |   //   The set of default template-arguments available for use with a | 
 | 1151 |   //   template declaration or definition is obtained by merging the | 
 | 1152 |   //   default arguments from the definition (if in scope) and all | 
 | 1153 |   //   declarations in scope in the same way default function | 
 | 1154 |   //   arguments are (8.3.6). | 
 | 1155 |   bool SawDefaultArgument = false; | 
 | 1156 |   SourceLocation PreviousDefaultArgLoc; | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 1157 |  | 
| Anders Carlsson | 49d2557 | 2009-06-12 23:20:15 +0000 | [diff] [blame] | 1158 |   bool SawParameterPack = false; | 
 | 1159 |   SourceLocation ParameterPackLoc; | 
 | 1160 |  | 
| Mike Stump | 1a35fde | 2009-02-11 23:03:27 +0000 | [diff] [blame] | 1161 |   // Dummy initialization to avoid warnings. | 
| Douglas Gregor | 1bc6913 | 2009-02-11 20:46:19 +0000 | [diff] [blame] | 1162 |   TemplateParameterList::iterator OldParam = NewParams->end(); | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1163 |   if (OldParams) | 
 | 1164 |     OldParam = OldParams->begin(); | 
 | 1165 |  | 
| Douglas Gregor | fd1a8fd | 2011-01-27 01:40:17 +0000 | [diff] [blame] | 1166 |   bool RemoveDefaultArguments = false; | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1167 |   for (TemplateParameterList::iterator NewParam = NewParams->begin(), | 
 | 1168 |                                     NewParamEnd = NewParams->end(); | 
 | 1169 |        NewParam != NewParamEnd; ++NewParam) { | 
 | 1170 |     // Variables used to diagnose redundant default arguments | 
 | 1171 |     bool RedundantDefaultArg = false; | 
 | 1172 |     SourceLocation OldDefaultLoc; | 
 | 1173 |     SourceLocation NewDefaultLoc; | 
 | 1174 |  | 
 | 1175 |     // Variables used to diagnose missing default arguments | 
 | 1176 |     bool MissingDefaultArg = false; | 
 | 1177 |  | 
| Anders Carlsson | 49d2557 | 2009-06-12 23:20:15 +0000 | [diff] [blame] | 1178 |     // C++0x [temp.param]p11: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1179 |     //   If a template parameter of a primary class template is a template | 
| Douglas Gregor | 1ed6476 | 2011-01-05 16:19:19 +0000 | [diff] [blame] | 1180 |     //   parameter pack, it shall be the last template parameter. | 
 | 1181 |     if (SawParameterPack && TPC == TPC_ClassTemplate) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1182 |       Diag(ParameterPackLoc, | 
| Anders Carlsson | 49d2557 | 2009-06-12 23:20:15 +0000 | [diff] [blame] | 1183 |            diag::err_template_param_pack_must_be_last_template_parameter); | 
 | 1184 |       Invalid = true; | 
 | 1185 |     } | 
 | 1186 |  | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1187 |     if (TemplateTypeParmDecl *NewTypeParm | 
 | 1188 |           = dyn_cast<TemplateTypeParmDecl>(*NewParam)) { | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1189 |       // Check the presence of a default argument here. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1190 |       if (NewTypeParm->hasDefaultArgument() && | 
 | 1191 |           DiagnoseDefaultTemplateArgument(*this, TPC, | 
 | 1192 |                                           NewTypeParm->getLocation(), | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1193 |                NewTypeParm->getDefaultArgumentInfo()->getTypeLoc() | 
| Abramo Bagnara | bd054db | 2010-05-20 10:00:11 +0000 | [diff] [blame] | 1194 |                                                        .getSourceRange())) | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1195 |         NewTypeParm->removeDefaultArgument(); | 
 | 1196 |  | 
 | 1197 |       // Merge default arguments for template type parameters. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1198 |       TemplateTypeParmDecl *OldTypeParm | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1199 |           = OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1200 |  | 
| Anders Carlsson | 49d2557 | 2009-06-12 23:20:15 +0000 | [diff] [blame] | 1201 |       if (NewTypeParm->isParameterPack()) { | 
 | 1202 |         assert(!NewTypeParm->hasDefaultArgument() && | 
 | 1203 |                "Parameter packs can't have a default argument!"); | 
 | 1204 |         SawParameterPack = true; | 
 | 1205 |         ParameterPackLoc = NewTypeParm->getLocation(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1206 |       } else if (OldTypeParm && OldTypeParm->hasDefaultArgument() && | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1207 |                  NewTypeParm->hasDefaultArgument()) { | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1208 |         OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc(); | 
 | 1209 |         NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc(); | 
 | 1210 |         SawDefaultArgument = true; | 
 | 1211 |         RedundantDefaultArg = true; | 
 | 1212 |         PreviousDefaultArgLoc = NewDefaultLoc; | 
 | 1213 |       } else if (OldTypeParm && OldTypeParm->hasDefaultArgument()) { | 
 | 1214 |         // Merge the default argument from the old declaration to the | 
 | 1215 |         // new declaration. | 
 | 1216 |         SawDefaultArgument = true; | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1217 |         NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgumentInfo(), | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1218 |                                         true); | 
 | 1219 |         PreviousDefaultArgLoc = OldTypeParm->getDefaultArgumentLoc(); | 
 | 1220 |       } else if (NewTypeParm->hasDefaultArgument()) { | 
 | 1221 |         SawDefaultArgument = true; | 
 | 1222 |         PreviousDefaultArgLoc = NewTypeParm->getDefaultArgumentLoc(); | 
 | 1223 |       } else if (SawDefaultArgument) | 
 | 1224 |         MissingDefaultArg = true; | 
| Mike Stump | ac5fc7c | 2009-08-04 21:02:39 +0000 | [diff] [blame] | 1225 |     } else if (NonTypeTemplateParmDecl *NewNonTypeParm | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1226 |                = dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) { | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1227 |       // Check for unexpanded parameter packs. | 
 | 1228 |       if (DiagnoseUnexpandedParameterPack(NewNonTypeParm->getLocation(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1229 |                                           NewNonTypeParm->getTypeSourceInfo(), | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1230 |                                           UPPC_NonTypeTemplateParameterType)) { | 
 | 1231 |         Invalid = true; | 
 | 1232 |         continue; | 
 | 1233 |       } | 
 | 1234 |  | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1235 |       // Check the presence of a default argument here. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1236 |       if (NewNonTypeParm->hasDefaultArgument() && | 
 | 1237 |           DiagnoseDefaultTemplateArgument(*this, TPC, | 
 | 1238 |                                           NewNonTypeParm->getLocation(), | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1239 |                     NewNonTypeParm->getDefaultArgument()->getSourceRange())) { | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 1240 |         NewNonTypeParm->removeDefaultArgument(); | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1241 |       } | 
 | 1242 |  | 
| Mike Stump | ac5fc7c | 2009-08-04 21:02:39 +0000 | [diff] [blame] | 1243 |       // Merge default arguments for non-type template parameters | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1244 |       NonTypeTemplateParmDecl *OldNonTypeParm | 
 | 1245 |         = OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0; | 
| Douglas Gregor | 1ed6476 | 2011-01-05 16:19:19 +0000 | [diff] [blame] | 1246 |       if (NewNonTypeParm->isParameterPack()) { | 
 | 1247 |         assert(!NewNonTypeParm->hasDefaultArgument() && | 
 | 1248 |                "Parameter packs can't have a default argument!"); | 
 | 1249 |         SawParameterPack = true; | 
 | 1250 |         ParameterPackLoc = NewNonTypeParm->getLocation(); | 
 | 1251 |       } else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() && | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1252 |           NewNonTypeParm->hasDefaultArgument()) { | 
 | 1253 |         OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc(); | 
 | 1254 |         NewDefaultLoc = NewNonTypeParm->getDefaultArgumentLoc(); | 
 | 1255 |         SawDefaultArgument = true; | 
 | 1256 |         RedundantDefaultArg = true; | 
 | 1257 |         PreviousDefaultArgLoc = NewDefaultLoc; | 
 | 1258 |       } else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument()) { | 
 | 1259 |         // Merge the default argument from the old declaration to the | 
 | 1260 |         // new declaration. | 
 | 1261 |         SawDefaultArgument = true; | 
 | 1262 |         // FIXME: We need to create a new kind of "default argument" | 
| Douglas Gregor | 61c4d28 | 2011-01-05 15:48:55 +0000 | [diff] [blame] | 1263 |         // expression that points to a previous non-type template | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1264 |         // parameter. | 
 | 1265 |         NewNonTypeParm->setDefaultArgument( | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 1266 |                                          OldNonTypeParm->getDefaultArgument(), | 
 | 1267 |                                          /*Inherited=*/ true); | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1268 |         PreviousDefaultArgLoc = OldNonTypeParm->getDefaultArgumentLoc(); | 
 | 1269 |       } else if (NewNonTypeParm->hasDefaultArgument()) { | 
 | 1270 |         SawDefaultArgument = true; | 
 | 1271 |         PreviousDefaultArgLoc = NewNonTypeParm->getDefaultArgumentLoc(); | 
 | 1272 |       } else if (SawDefaultArgument) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1273 |         MissingDefaultArg = true; | 
| Mike Stump | ac5fc7c | 2009-08-04 21:02:39 +0000 | [diff] [blame] | 1274 |     } else { | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1275 |       // Check the presence of a default argument here. | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1276 |       TemplateTemplateParmDecl *NewTemplateParm | 
 | 1277 |         = cast<TemplateTemplateParmDecl>(*NewParam); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1278 |  | 
| Douglas Gregor | 4d2abba | 2010-12-16 15:36:43 +0000 | [diff] [blame] | 1279 |       // Check for unexpanded parameter packs, recursively. | 
 | 1280 |       if (DiagnoseUnexpandedParameterPacks(*this, NewTemplateParm)) { | 
 | 1281 |         Invalid = true; | 
 | 1282 |         continue; | 
 | 1283 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1284 |  | 
 | 1285 |       if (NewTemplateParm->hasDefaultArgument() && | 
 | 1286 |           DiagnoseDefaultTemplateArgument(*this, TPC, | 
 | 1287 |                                           NewTemplateParm->getLocation(), | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1288 |                      NewTemplateParm->getDefaultArgument().getSourceRange())) | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 1289 |         NewTemplateParm->removeDefaultArgument(); | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1290 |  | 
 | 1291 |       // Merge default arguments for template template parameters | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1292 |       TemplateTemplateParmDecl *OldTemplateParm | 
 | 1293 |         = OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0; | 
| Douglas Gregor | 1ed6476 | 2011-01-05 16:19:19 +0000 | [diff] [blame] | 1294 |       if (NewTemplateParm->isParameterPack()) { | 
 | 1295 |         assert(!NewTemplateParm->hasDefaultArgument() && | 
 | 1296 |                "Parameter packs can't have a default argument!"); | 
 | 1297 |         SawParameterPack = true; | 
 | 1298 |         ParameterPackLoc = NewTemplateParm->getLocation(); | 
 | 1299 |       } else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() && | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1300 |           NewTemplateParm->hasDefaultArgument()) { | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 1301 |         OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation(); | 
 | 1302 |         NewDefaultLoc = NewTemplateParm->getDefaultArgument().getLocation(); | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1303 |         SawDefaultArgument = true; | 
 | 1304 |         RedundantDefaultArg = true; | 
 | 1305 |         PreviousDefaultArgLoc = NewDefaultLoc; | 
 | 1306 |       } else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument()) { | 
 | 1307 |         // Merge the default argument from the old declaration to the | 
 | 1308 |         // new declaration. | 
 | 1309 |         SawDefaultArgument = true; | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 1310 |         // FIXME: We need to create a new kind of "default argument" expression | 
 | 1311 |         // that points to a previous template template parameter. | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1312 |         NewTemplateParm->setDefaultArgument( | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 1313 |                                           OldTemplateParm->getDefaultArgument(), | 
 | 1314 |                                           /*Inherited=*/ true); | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 1315 |         PreviousDefaultArgLoc | 
 | 1316 |           = OldTemplateParm->getDefaultArgument().getLocation(); | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1317 |       } else if (NewTemplateParm->hasDefaultArgument()) { | 
 | 1318 |         SawDefaultArgument = true; | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 1319 |         PreviousDefaultArgLoc | 
 | 1320 |           = NewTemplateParm->getDefaultArgument().getLocation(); | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1321 |       } else if (SawDefaultArgument) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1322 |         MissingDefaultArg = true; | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1323 |     } | 
 | 1324 |  | 
 | 1325 |     if (RedundantDefaultArg) { | 
 | 1326 |       // C++ [temp.param]p12: | 
 | 1327 |       //   A template-parameter shall not be given default arguments | 
 | 1328 |       //   by two different declarations in the same scope. | 
 | 1329 |       Diag(NewDefaultLoc, diag::err_template_param_default_arg_redefinition); | 
 | 1330 |       Diag(OldDefaultLoc, diag::note_template_param_prev_default_arg); | 
 | 1331 |       Invalid = true; | 
| Douglas Gregor | ee5d21f | 2011-02-04 03:57:22 +0000 | [diff] [blame] | 1332 |     } else if (MissingDefaultArg && TPC != TPC_FunctionTemplate) { | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1333 |       // C++ [temp.param]p11: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1334 |       //   If a template-parameter of a class template has a default | 
 | 1335 |       //   template-argument, each subsequent template-parameter shall either | 
| Douglas Gregor | b49e415 | 2011-01-05 16:21:17 +0000 | [diff] [blame] | 1336 |       //   have a default template-argument supplied or be a template parameter | 
 | 1337 |       //   pack. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1338 |       Diag((*NewParam)->getLocation(), | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1339 |            diag::err_template_param_default_arg_missing); | 
 | 1340 |       Diag(PreviousDefaultArgLoc, diag::note_template_param_prev_default_arg); | 
 | 1341 |       Invalid = true; | 
| Douglas Gregor | fd1a8fd | 2011-01-27 01:40:17 +0000 | [diff] [blame] | 1342 |       RemoveDefaultArguments = true; | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1343 |     } | 
 | 1344 |  | 
 | 1345 |     // If we have an old template parameter list that we're merging | 
 | 1346 |     // in, move on to the next parameter. | 
 | 1347 |     if (OldParams) | 
 | 1348 |       ++OldParam; | 
 | 1349 |   } | 
 | 1350 |  | 
| Douglas Gregor | fd1a8fd | 2011-01-27 01:40:17 +0000 | [diff] [blame] | 1351 |   // We were missing some default arguments at the end of the list, so remove | 
 | 1352 |   // all of the default arguments. | 
 | 1353 |   if (RemoveDefaultArguments) { | 
 | 1354 |     for (TemplateParameterList::iterator NewParam = NewParams->begin(), | 
 | 1355 |                                       NewParamEnd = NewParams->end(); | 
 | 1356 |          NewParam != NewParamEnd; ++NewParam) { | 
 | 1357 |       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*NewParam)) | 
 | 1358 |         TTP->removeDefaultArgument(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1359 |       else if (NonTypeTemplateParmDecl *NTTP | 
| Douglas Gregor | fd1a8fd | 2011-01-27 01:40:17 +0000 | [diff] [blame] | 1360 |                                 = dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) | 
 | 1361 |         NTTP->removeDefaultArgument(); | 
 | 1362 |       else | 
 | 1363 |         cast<TemplateTemplateParmDecl>(*NewParam)->removeDefaultArgument(); | 
 | 1364 |     } | 
 | 1365 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1366 |  | 
| Douglas Gregor | d684b00 | 2009-02-10 19:49:53 +0000 | [diff] [blame] | 1367 |   return Invalid; | 
 | 1368 | } | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 1369 |  | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1370 | namespace { | 
 | 1371 |  | 
 | 1372 | /// A class which looks for a use of a certain level of template | 
 | 1373 | /// parameter. | 
 | 1374 | struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> { | 
 | 1375 |   typedef RecursiveASTVisitor<DependencyChecker> super; | 
 | 1376 |  | 
 | 1377 |   unsigned Depth; | 
 | 1378 |   bool Match; | 
 | 1379 |  | 
 | 1380 |   DependencyChecker(TemplateParameterList *Params) : Match(false) { | 
 | 1381 |     NamedDecl *ND = Params->getParam(0); | 
 | 1382 |     if (TemplateTypeParmDecl *PD = dyn_cast<TemplateTypeParmDecl>(ND)) { | 
 | 1383 |       Depth = PD->getDepth(); | 
 | 1384 |     } else if (NonTypeTemplateParmDecl *PD = | 
 | 1385 |                  dyn_cast<NonTypeTemplateParmDecl>(ND)) { | 
 | 1386 |       Depth = PD->getDepth(); | 
 | 1387 |     } else { | 
 | 1388 |       Depth = cast<TemplateTemplateParmDecl>(ND)->getDepth(); | 
 | 1389 |     } | 
 | 1390 |   } | 
 | 1391 |  | 
 | 1392 |   bool Matches(unsigned ParmDepth) { | 
 | 1393 |     if (ParmDepth >= Depth) { | 
 | 1394 |       Match = true; | 
 | 1395 |       return true; | 
 | 1396 |     } | 
 | 1397 |     return false; | 
 | 1398 |   } | 
 | 1399 |  | 
 | 1400 |   bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) { | 
 | 1401 |     return !Matches(T->getDepth()); | 
 | 1402 |   } | 
 | 1403 |  | 
 | 1404 |   bool TraverseTemplateName(TemplateName N) { | 
 | 1405 |     if (TemplateTemplateParmDecl *PD = | 
 | 1406 |           dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl())) | 
 | 1407 |       if (Matches(PD->getDepth())) return false; | 
 | 1408 |     return super::TraverseTemplateName(N); | 
 | 1409 |   } | 
 | 1410 |  | 
 | 1411 |   bool VisitDeclRefExpr(DeclRefExpr *E) { | 
 | 1412 |     if (NonTypeTemplateParmDecl *PD = | 
 | 1413 |           dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) { | 
 | 1414 |       if (PD->getDepth() == Depth) { | 
 | 1415 |         Match = true; | 
 | 1416 |         return false; | 
 | 1417 |       } | 
 | 1418 |     } | 
 | 1419 |     return super::VisitDeclRefExpr(E); | 
 | 1420 |   } | 
 | 1421 | }; | 
 | 1422 | } | 
 | 1423 |  | 
 | 1424 | /// Determines whether a template-id depends on the given parameter | 
 | 1425 | /// list. | 
 | 1426 | static bool | 
 | 1427 | DependsOnTemplateParameters(const TemplateSpecializationType *TemplateId, | 
 | 1428 |                             TemplateParameterList *Params) { | 
 | 1429 |   DependencyChecker Checker(Params); | 
 | 1430 |   Checker.TraverseType(QualType(TemplateId, 0)); | 
 | 1431 |   return Checker.Match; | 
 | 1432 | } | 
 | 1433 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1434 | /// \brief Match the given template parameter lists to the given scope | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1435 | /// specifier, returning the template parameter list that applies to the | 
 | 1436 | /// name. | 
 | 1437 | /// | 
 | 1438 | /// \param DeclStartLoc the start of the declaration that has a scope | 
 | 1439 | /// specifier or a template parameter list. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1440 | /// | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1441 | /// \param SS the scope specifier that will be matched to the given template | 
 | 1442 | /// parameter lists. This scope specifier precedes a qualified name that is | 
 | 1443 | /// being declared. | 
 | 1444 | /// | 
 | 1445 | /// \param ParamLists the template parameter lists, from the outermost to the | 
 | 1446 | /// innermost template parameter lists. | 
 | 1447 | /// | 
 | 1448 | /// \param NumParamLists the number of template parameter lists in ParamLists. | 
 | 1449 | /// | 
| John McCall | 77e8b11 | 2010-04-13 20:37:33 +0000 | [diff] [blame] | 1450 | /// \param IsFriend Whether to apply the slightly different rules for | 
 | 1451 | /// matching template parameters to scope specifiers in friend | 
 | 1452 | /// declarations. | 
 | 1453 | /// | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 1454 | /// \param IsExplicitSpecialization will be set true if the entity being | 
 | 1455 | /// declared is an explicit specialization, false otherwise. | 
 | 1456 | /// | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1457 | /// \returns the template parameter list, if any, that corresponds to the | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1458 | /// name that is preceded by the scope specifier @p SS. This template | 
 | 1459 | /// parameter list may be have template parameters (if we're declaring a | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1460 | /// template) or may have no template parameters (if we're declaring a | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1461 | /// template specialization), or may be NULL (if we were's declaring isn't | 
 | 1462 | /// itself a template). | 
 | 1463 | TemplateParameterList * | 
 | 1464 | Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, | 
 | 1465 |                                               const CXXScopeSpec &SS, | 
 | 1466 |                                           TemplateParameterList **ParamLists, | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 1467 |                                               unsigned NumParamLists, | 
| John McCall | 77e8b11 | 2010-04-13 20:37:33 +0000 | [diff] [blame] | 1468 |                                               bool IsFriend, | 
| Douglas Gregor | 0167f3c | 2010-07-14 23:14:12 +0000 | [diff] [blame] | 1469 |                                               bool &IsExplicitSpecialization, | 
 | 1470 |                                               bool &Invalid) { | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 1471 |   IsExplicitSpecialization = false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1472 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1473 |   // Find the template-ids that occur within the nested-name-specifier. These | 
 | 1474 |   // template-ids will match up with the template parameter lists. | 
 | 1475 |   llvm::SmallVector<const TemplateSpecializationType *, 4> | 
 | 1476 |     TemplateIdsInSpecifier; | 
| Douglas Gregor | 3ebd753 | 2009-11-23 12:11:45 +0000 | [diff] [blame] | 1477 |   llvm::SmallVector<ClassTemplateSpecializationDecl *, 4> | 
 | 1478 |     ExplicitSpecializationsInSpecifier; | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1479 |   for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep(); | 
 | 1480 |        NNS; NNS = NNS->getPrefix()) { | 
| John McCall | 4b2b02b | 2009-12-15 02:19:47 +0000 | [diff] [blame] | 1481 |     const Type *T = NNS->getAsType(); | 
 | 1482 |     if (!T) break; | 
 | 1483 |  | 
 | 1484 |     // C++0x [temp.expl.spec]p17: | 
 | 1485 |     //   A member or a member template may be nested within many | 
 | 1486 |     //   enclosing class templates. In an explicit specialization for | 
 | 1487 |     //   such a member, the member declaration shall be preceded by a | 
 | 1488 |     //   template<> for each enclosing class template that is | 
 | 1489 |     //   explicitly specialized. | 
| Douglas Gregor | fe33106 | 2010-02-13 05:23:25 +0000 | [diff] [blame] | 1490 |     // | 
 | 1491 |     // Following the existing practice of GNU and EDG, we allow a typedef of a | 
 | 1492 |     // template specialization type. | 
| John McCall | 49f4e1c | 2010-12-10 11:01:00 +0000 | [diff] [blame] | 1493 |     while (const TypedefType *TT = dyn_cast<TypedefType>(T)) | 
 | 1494 |       T = TT->getDecl()->getUnderlyingType().getTypePtr(); | 
| John McCall | 4b2b02b | 2009-12-15 02:19:47 +0000 | [diff] [blame] | 1495 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1496 |     if (const TemplateSpecializationType *SpecType | 
| Douglas Gregor | fe33106 | 2010-02-13 05:23:25 +0000 | [diff] [blame] | 1497 |                                   = dyn_cast<TemplateSpecializationType>(T)) { | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1498 |       TemplateDecl *Template = SpecType->getTemplateName().getAsTemplateDecl(); | 
 | 1499 |       if (!Template) | 
 | 1500 |         continue; // FIXME: should this be an error? probably... | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1501 |  | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 1502 |       if (const RecordType *Record = SpecType->getAs<RecordType>()) { | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1503 |         ClassTemplateSpecializationDecl *SpecDecl | 
 | 1504 |           = cast<ClassTemplateSpecializationDecl>(Record->getDecl()); | 
 | 1505 |         // If the nested name specifier refers to an explicit specialization, | 
 | 1506 |         // we don't need a template<> header. | 
| Douglas Gregor | 3ebd753 | 2009-11-23 12:11:45 +0000 | [diff] [blame] | 1507 |         if (SpecDecl->getSpecializationKind() == TSK_ExplicitSpecialization) { | 
 | 1508 |           ExplicitSpecializationsInSpecifier.push_back(SpecDecl); | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1509 |           continue; | 
| Douglas Gregor | 3ebd753 | 2009-11-23 12:11:45 +0000 | [diff] [blame] | 1510 |         } | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1511 |       } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1512 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1513 |       TemplateIdsInSpecifier.push_back(SpecType); | 
 | 1514 |     } | 
 | 1515 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1516 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1517 |   // Reverse the list of template-ids in the scope specifier, so that we can | 
 | 1518 |   // more easily match up the template-ids and the template parameter lists. | 
 | 1519 |   std::reverse(TemplateIdsInSpecifier.begin(), TemplateIdsInSpecifier.end()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1520 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1521 |   SourceLocation FirstTemplateLoc = DeclStartLoc; | 
 | 1522 |   if (NumParamLists) | 
 | 1523 |     FirstTemplateLoc = ParamLists[0]->getTemplateLoc(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1524 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1525 |   // Match the template-ids found in the specifier to the template parameter | 
 | 1526 |   // lists. | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1527 |   unsigned ParamIdx = 0, TemplateIdx = 0; | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1528 |   for (unsigned NumTemplateIds = TemplateIdsInSpecifier.size(); | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1529 |        TemplateIdx != NumTemplateIds; ++TemplateIdx) { | 
 | 1530 |     const TemplateSpecializationType *TemplateId | 
 | 1531 |       = TemplateIdsInSpecifier[TemplateIdx]; | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 1532 |     bool DependentTemplateId = TemplateId->isDependentType(); | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1533 |  | 
 | 1534 |     // In friend declarations we can have template-ids which don't | 
 | 1535 |     // depend on the corresponding template parameter lists.  But | 
 | 1536 |     // assume that empty parameter lists are supposed to match this | 
 | 1537 |     // template-id. | 
 | 1538 |     if (IsFriend && ParamIdx < NumParamLists && ParamLists[ParamIdx]->size()) { | 
 | 1539 |       if (!DependentTemplateId || | 
 | 1540 |           !DependsOnTemplateParameters(TemplateId, ParamLists[ParamIdx])) | 
 | 1541 |         continue; | 
 | 1542 |     } | 
 | 1543 |  | 
 | 1544 |     if (ParamIdx >= NumParamLists) { | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1545 |       // We have a template-id without a corresponding template parameter | 
 | 1546 |       // list. | 
| John McCall | 77e8b11 | 2010-04-13 20:37:33 +0000 | [diff] [blame] | 1547 |  | 
 | 1548 |       // ...which is fine if this is a friend declaration. | 
 | 1549 |       if (IsFriend) { | 
 | 1550 |         IsExplicitSpecialization = true; | 
 | 1551 |         break; | 
 | 1552 |       } | 
 | 1553 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1554 |       if (DependentTemplateId) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1555 |         // FIXME: the location information here isn't great. | 
 | 1556 |         Diag(SS.getRange().getBegin(), | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1557 |              diag::err_template_spec_needs_template_parameters) | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1558 |           << QualType(TemplateId, 0) | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1559 |           << SS.getRange(); | 
| Douglas Gregor | 0167f3c | 2010-07-14 23:14:12 +0000 | [diff] [blame] | 1560 |         Invalid = true; | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1561 |       } else { | 
 | 1562 |         Diag(SS.getRange().getBegin(), diag::err_template_spec_needs_header) | 
 | 1563 |           << SS.getRange() | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 1564 |           << FixItHint::CreateInsertion(FirstTemplateLoc, "template<> "); | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 1565 |         IsExplicitSpecialization = true; | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1566 |       } | 
 | 1567 |       return 0; | 
 | 1568 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1569 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1570 |     // Check the template parameter list against its corresponding template-id. | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 1571 |     if (DependentTemplateId) { | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 1572 |       TemplateParameterList *ExpectedTemplateParams = 0; | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 1573 |  | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 1574 |       // Are there cases in (e.g.) friends where this won't match? | 
 | 1575 |       if (const InjectedClassNameType *Injected | 
 | 1576 |             = TemplateId->getAs<InjectedClassNameType>()) { | 
 | 1577 |         CXXRecordDecl *Record = Injected->getDecl(); | 
 | 1578 |         if (ClassTemplatePartialSpecializationDecl *Partial = | 
 | 1579 |               dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) | 
 | 1580 |           ExpectedTemplateParams = Partial->getTemplateParameters(); | 
 | 1581 |         else | 
 | 1582 |           ExpectedTemplateParams = Record->getDescribedClassTemplate() | 
 | 1583 |             ->getTemplateParameters(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1584 |       } | 
| Douglas Gregor | 5b6d70e | 2009-11-25 17:50:39 +0000 | [diff] [blame] | 1585 |  | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 1586 |       if (ExpectedTemplateParams) | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1587 |         TemplateParameterListsAreEqual(ParamLists[ParamIdx], | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 1588 |                                        ExpectedTemplateParams, | 
 | 1589 |                                        true, TPL_TemplateMatch); | 
 | 1590 |  | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1591 |       CheckTemplateParameterList(ParamLists[ParamIdx], 0, | 
 | 1592 |                                  TPC_ClassTemplateMember); | 
 | 1593 |     } else if (ParamLists[ParamIdx]->size() > 0) | 
 | 1594 |       Diag(ParamLists[ParamIdx]->getTemplateLoc(), | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 1595 |            diag::err_template_param_list_matches_nontemplate) | 
 | 1596 |         << TemplateId | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1597 |         << ParamLists[ParamIdx]->getSourceRange(); | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 1598 |     else | 
 | 1599 |       IsExplicitSpecialization = true; | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1600 |  | 
 | 1601 |     ++ParamIdx; | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1602 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1603 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1604 |   // If there were at least as many template-ids as there were template | 
 | 1605 |   // parameter lists, then there are no template parameter lists remaining for | 
 | 1606 |   // the declaration itself. | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1607 |   if (ParamIdx >= NumParamLists) | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1608 |     return 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1609 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1610 |   // If there were too many template parameter lists, complain about that now. | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1611 |   if (ParamIdx != NumParamLists - 1) { | 
 | 1612 |     while (ParamIdx < NumParamLists - 1) { | 
 | 1613 |       bool isExplicitSpecHeader = ParamLists[ParamIdx]->size() == 0; | 
 | 1614 |       Diag(ParamLists[ParamIdx]->getTemplateLoc(), | 
| Douglas Gregor | 3ebd753 | 2009-11-23 12:11:45 +0000 | [diff] [blame] | 1615 |            isExplicitSpecHeader? diag::warn_template_spec_extra_headers | 
 | 1616 |                                : diag::err_template_spec_extra_headers) | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1617 |         << SourceRange(ParamLists[ParamIdx]->getTemplateLoc(), | 
 | 1618 |                        ParamLists[ParamIdx]->getRAngleLoc()); | 
| Douglas Gregor | 3ebd753 | 2009-11-23 12:11:45 +0000 | [diff] [blame] | 1619 |  | 
 | 1620 |       if (isExplicitSpecHeader && !ExplicitSpecializationsInSpecifier.empty()) { | 
 | 1621 |         Diag(ExplicitSpecializationsInSpecifier.back()->getLocation(), | 
 | 1622 |              diag::note_explicit_template_spec_does_not_need_header) | 
 | 1623 |           << ExplicitSpecializationsInSpecifier.back(); | 
 | 1624 |         ExplicitSpecializationsInSpecifier.pop_back(); | 
 | 1625 |       } | 
| Douglas Gregor | 0167f3c | 2010-07-14 23:14:12 +0000 | [diff] [blame] | 1626 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1627 |       // We have a template parameter list with no corresponding scope, which | 
| Douglas Gregor | 0167f3c | 2010-07-14 23:14:12 +0000 | [diff] [blame] | 1628 |       // means that the resulting template declaration can't be instantiated | 
 | 1629 |       // properly (we'll end up with dependent nodes when we shouldn't). | 
 | 1630 |       if (!isExplicitSpecHeader) | 
 | 1631 |         Invalid = true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1632 |  | 
| John McCall | 4e2cbb2 | 2010-10-20 05:44:58 +0000 | [diff] [blame] | 1633 |       ++ParamIdx; | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1634 |     } | 
 | 1635 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1636 |  | 
| Douglas Gregor | f59a56e | 2009-07-21 23:53:31 +0000 | [diff] [blame] | 1637 |   // Return the last template parameter list, which corresponds to the | 
 | 1638 |   // entity being declared. | 
 | 1639 |   return ParamLists[NumParamLists - 1]; | 
 | 1640 | } | 
 | 1641 |  | 
| Douglas Gregor | 6cd9d4a | 2011-03-04 21:37:14 +0000 | [diff] [blame] | 1642 | void Sema::NoteAllFoundTemplates(TemplateName Name) { | 
 | 1643 |   if (TemplateDecl *Template = Name.getAsTemplateDecl()) { | 
 | 1644 |     Diag(Template->getLocation(), diag::note_template_declared_here) | 
 | 1645 |       << (isa<FunctionTemplateDecl>(Template)? 0 | 
 | 1646 |           : isa<ClassTemplateDecl>(Template)? 1 | 
 | 1647 |           : 2) | 
 | 1648 |       << Template->getDeclName(); | 
 | 1649 |     return; | 
 | 1650 |   } | 
 | 1651 |    | 
 | 1652 |   if (OverloadedTemplateStorage *OST = Name.getAsOverloadedTemplate()) { | 
 | 1653 |     for (OverloadedTemplateStorage::iterator I = OST->begin(),  | 
 | 1654 |                                           IEnd = OST->end(); | 
 | 1655 |          I != IEnd; ++I) | 
 | 1656 |       Diag((*I)->getLocation(), diag::note_template_declared_here) | 
 | 1657 |         << 0 << (*I)->getDeclName(); | 
 | 1658 |      | 
 | 1659 |     return; | 
 | 1660 |   } | 
 | 1661 | } | 
 | 1662 |  | 
 | 1663 |  | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1664 | QualType Sema::CheckTemplateIdType(TemplateName Name, | 
 | 1665 |                                    SourceLocation TemplateLoc, | 
| Douglas Gregor | 6771423 | 2011-03-03 02:41:12 +0000 | [diff] [blame] | 1666 |                                    TemplateArgumentListInfo &TemplateArgs) { | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1667 |   TemplateDecl *Template = Name.getAsTemplateDecl(); | 
| Douglas Gregor | 6cd9d4a | 2011-03-04 21:37:14 +0000 | [diff] [blame] | 1668 |   if (!Template || isa<FunctionTemplateDecl>(Template)) { | 
 | 1669 |     // We might have a substituted template template parameter pack. If so, | 
 | 1670 |     // build a template specialization type for it. | 
 | 1671 |     if (Name.getAsSubstTemplateTemplateParmPack()) | 
 | 1672 |       return Context.getTemplateSpecializationType(Name, TemplateArgs); | 
 | 1673 |      | 
 | 1674 |     Diag(TemplateLoc, diag::err_template_id_not_a_type) | 
 | 1675 |       << Name; | 
 | 1676 |     NoteAllFoundTemplates(Name); | 
 | 1677 |     return QualType(); | 
| Douglas Gregor | c45c232 | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 1678 |   } | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1679 |  | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1680 |   // Check that the template argument list is well-formed for this | 
 | 1681 |   // template. | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1682 |   llvm::SmallVector<TemplateArgument, 4> Converted; | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1683 |   if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs, | 
| Douglas Gregor | 16134c6 | 2009-07-01 00:28:38 +0000 | [diff] [blame] | 1684 |                                 false, Converted)) | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1685 |     return QualType(); | 
 | 1686 |  | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1687 |   assert((Converted.size() == Template->getTemplateParameters()->size()) && | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1688 |          "Converted template argument list is too short!"); | 
 | 1689 |  | 
 | 1690 |   QualType CanonType; | 
 | 1691 |  | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 1692 |   if (Name.isDependent() || | 
 | 1693 |       TemplateSpecializationType::anyDependentTemplateArguments( | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1694 |                                                       TemplateArgs)) { | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1695 |     // This class template specialization is a dependent | 
 | 1696 |     // type. Therefore, its canonical type is another class template | 
 | 1697 |     // specialization type that contains all of the converted | 
 | 1698 |     // arguments in canonical form. This ensures that, e.g., A<T> and | 
 | 1699 |     // A<T, T> have identical types when A is declared as: | 
 | 1700 |     // | 
 | 1701 |     //   template<typename T, typename U = T> struct A; | 
| Douglas Gregor | 25a3ef7 | 2009-05-07 06:41:52 +0000 | [diff] [blame] | 1702 |     TemplateName CanonName = Context.getCanonicalTemplateName(Name); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1703 |     CanonType = Context.getTemplateSpecializationType(CanonName, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1704 |                                                       Converted.data(), | 
 | 1705 |                                                       Converted.size()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1706 |  | 
| Douglas Gregor | 1275ae0 | 2009-07-28 23:00:59 +0000 | [diff] [blame] | 1707 |     // FIXME: CanonType is not actually the canonical type, and unfortunately | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1708 |     // it is a TemplateSpecializationType that we will never use again. | 
| Douglas Gregor | 1275ae0 | 2009-07-28 23:00:59 +0000 | [diff] [blame] | 1709 |     // In the future, we need to teach getTemplateSpecializationType to only | 
 | 1710 |     // build the canonical type and return that to us. | 
 | 1711 |     CanonType = Context.getCanonicalType(CanonType); | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 1712 |  | 
 | 1713 |     // This might work out to be a current instantiation, in which | 
 | 1714 |     // case the canonical type needs to be the InjectedClassNameType. | 
 | 1715 |     // | 
 | 1716 |     // TODO: in theory this could be a simple hashtable lookup; most | 
 | 1717 |     // changes to CurContext don't change the set of current | 
 | 1718 |     // instantiations. | 
 | 1719 |     if (isa<ClassTemplateDecl>(Template)) { | 
 | 1720 |       for (DeclContext *Ctx = CurContext; Ctx; Ctx = Ctx->getLookupParent()) { | 
 | 1721 |         // If we get out to a namespace, we're done. | 
 | 1722 |         if (Ctx->isFileContext()) break; | 
 | 1723 |  | 
 | 1724 |         // If this isn't a record, keep looking. | 
 | 1725 |         CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx); | 
 | 1726 |         if (!Record) continue; | 
 | 1727 |  | 
 | 1728 |         // Look for one of the two cases with InjectedClassNameTypes | 
 | 1729 |         // and check whether it's the same template. | 
 | 1730 |         if (!isa<ClassTemplatePartialSpecializationDecl>(Record) && | 
 | 1731 |             !Record->getDescribedClassTemplate()) | 
 | 1732 |           continue; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1733 |  | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 1734 |         // Fetch the injected class name type and check whether its | 
 | 1735 |         // injected type is equal to the type we just built. | 
 | 1736 |         QualType ICNT = Context.getTypeDeclType(Record); | 
 | 1737 |         QualType Injected = cast<InjectedClassNameType>(ICNT) | 
 | 1738 |           ->getInjectedSpecializationType(); | 
 | 1739 |  | 
 | 1740 |         if (CanonType != Injected->getCanonicalTypeInternal()) | 
 | 1741 |           continue; | 
 | 1742 |  | 
 | 1743 |         // If so, the canonical type of this TST is the injected | 
 | 1744 |         // class name type of the record we just found. | 
 | 1745 |         assert(ICNT.isCanonical()); | 
 | 1746 |         CanonType = ICNT; | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 1747 |         break; | 
 | 1748 |       } | 
 | 1749 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1750 |   } else if (ClassTemplateDecl *ClassTemplate | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1751 |                = dyn_cast<ClassTemplateDecl>(Template)) { | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1752 |     // Find the class template specialization declaration that | 
 | 1753 |     // corresponds to these arguments. | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1754 |     void *InsertPos = 0; | 
 | 1755 |     ClassTemplateSpecializationDecl *Decl | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1756 |       = ClassTemplate->findSpecialization(Converted.data(), Converted.size(), | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1757 |                                           InsertPos); | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1758 |     if (!Decl) { | 
 | 1759 |       // This is the first time we have referenced this class template | 
 | 1760 |       // specialization. Create the canonical declaration and add it to | 
 | 1761 |       // the set of specializations. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1762 |       Decl = ClassTemplateSpecializationDecl::Create(Context, | 
| Douglas Gregor | 13c8577 | 2010-05-06 00:28:52 +0000 | [diff] [blame] | 1763 |                             ClassTemplate->getTemplatedDecl()->getTagKind(), | 
 | 1764 |                                                 ClassTemplate->getDeclContext(), | 
 | 1765 |                                                 ClassTemplate->getLocation(), | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 1766 |                                                 ClassTemplate->getLocation(), | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1767 |                                                      ClassTemplate, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1768 |                                                      Converted.data(), | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 1769 |                                                      Converted.size(), 0); | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 1770 |       ClassTemplate->AddSpecialization(Decl, InsertPos); | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1771 |       Decl->setLexicalDeclContext(CurContext); | 
 | 1772 |     } | 
 | 1773 |  | 
 | 1774 |     CanonType = Context.getTypeDeclType(Decl); | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 1775 |     assert(isa<RecordType>(CanonType) && | 
 | 1776 |            "type of non-dependent specialization is not a RecordType"); | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1777 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1778 |  | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1779 |   // Build the fully-sugared type for this class template | 
 | 1780 |   // specialization, which refers back to the class template | 
 | 1781 |   // specialization we created or found. | 
| John McCall | 71d74bc | 2010-06-13 09:25:03 +0000 | [diff] [blame] | 1782 |   return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType); | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1783 | } | 
 | 1784 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1785 | TypeResult | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1786 | Sema::ActOnTemplateIdType(CXXScopeSpec &SS, | 
 | 1787 |                           TemplateTy TemplateD, SourceLocation TemplateLoc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1788 |                           SourceLocation LAngleLoc, | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1789 |                           ASTTemplateArgsPtr TemplateArgsIn, | 
| John McCall | 6b2becf | 2009-09-08 17:47:29 +0000 | [diff] [blame] | 1790 |                           SourceLocation RAngleLoc) { | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1791 |   if (SS.isInvalid()) | 
 | 1792 |     return true; | 
 | 1793 |  | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 1794 |   TemplateName Template = TemplateD.getAsVal<TemplateName>(); | 
| Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1795 |  | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1796 |   // Translate the parser's template argument list in our AST format. | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1797 |   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); | 
| Douglas Gregor | 314b97f | 2009-11-10 19:49:08 +0000 | [diff] [blame] | 1798 |   translateTemplateArguments(TemplateArgsIn, TemplateArgs); | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 1799 |  | 
| Douglas Gregor | a88f09f | 2011-02-28 17:23:35 +0000 | [diff] [blame] | 1800 |   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { | 
 | 1801 |     QualType T = Context.getDependentTemplateSpecializationType(ETK_None, | 
 | 1802 |                                                            DTN->getQualifier(),  | 
 | 1803 |                                                            DTN->getIdentifier(),  | 
 | 1804 |                                                                 TemplateArgs); | 
 | 1805 |      | 
 | 1806 |     // Build type-source information.     | 
 | 1807 |     TypeLocBuilder TLB; | 
 | 1808 |     DependentTemplateSpecializationTypeLoc SpecTL | 
 | 1809 |       = TLB.push<DependentTemplateSpecializationTypeLoc>(T); | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1810 |     SpecTL.setKeywordLoc(SourceLocation()); | 
| Douglas Gregor | a88f09f | 2011-02-28 17:23:35 +0000 | [diff] [blame] | 1811 |     SpecTL.setNameLoc(TemplateLoc); | 
 | 1812 |     SpecTL.setLAngleLoc(LAngleLoc); | 
 | 1813 |     SpecTL.setRAngleLoc(RAngleLoc); | 
| Douglas Gregor | 94fdffa | 2011-03-01 20:11:18 +0000 | [diff] [blame] | 1814 |     SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
| Douglas Gregor | a88f09f | 2011-02-28 17:23:35 +0000 | [diff] [blame] | 1815 |     for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I) | 
 | 1816 |       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); | 
 | 1817 |     return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T)); | 
 | 1818 |   } | 
 | 1819 |    | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1820 |   QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs); | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 1821 |   TemplateArgsIn.release(); | 
| Douglas Gregor | 31a19b6 | 2009-04-01 21:51:26 +0000 | [diff] [blame] | 1822 |  | 
 | 1823 |   if (Result.isNull()) | 
 | 1824 |     return true; | 
 | 1825 |  | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1826 |   // Build type-source information. | 
 | 1827 |   TypeLocBuilder TLB;   | 
 | 1828 |   TemplateSpecializationTypeLoc SpecTL | 
 | 1829 |     = TLB.push<TemplateSpecializationTypeLoc>(Result); | 
 | 1830 |   SpecTL.setTemplateNameLoc(TemplateLoc); | 
 | 1831 |   SpecTL.setLAngleLoc(LAngleLoc); | 
 | 1832 |   SpecTL.setRAngleLoc(RAngleLoc); | 
 | 1833 |   for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i) | 
 | 1834 |     SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 1835 |  | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1836 |   if (SS.isNotEmpty()) { | 
 | 1837 |     // Create an elaborated-type-specifier containing the nested-name-specifier. | 
 | 1838 |     Result = Context.getElaboratedType(ETK_None, SS.getScopeRep(), Result); | 
 | 1839 |     ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result); | 
 | 1840 |     ElabTL.setKeywordLoc(SourceLocation()); | 
 | 1841 |     ElabTL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
 | 1842 |   } | 
 | 1843 |    | 
 | 1844 |   return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); | 
| John McCall | 6b2becf | 2009-09-08 17:47:29 +0000 | [diff] [blame] | 1845 | } | 
| John McCall | f1bbbb4 | 2009-09-04 01:14:41 +0000 | [diff] [blame] | 1846 |  | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1847 | TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK, | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 1848 |                                         TypeSpecifierType TagSpec, | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1849 |                                         SourceLocation TagLoc, | 
 | 1850 |                                         CXXScopeSpec &SS, | 
 | 1851 |                                         TemplateTy TemplateD,  | 
 | 1852 |                                         SourceLocation TemplateLoc, | 
 | 1853 |                                         SourceLocation LAngleLoc, | 
 | 1854 |                                         ASTTemplateArgsPtr TemplateArgsIn, | 
 | 1855 |                                         SourceLocation RAngleLoc) { | 
 | 1856 |   TemplateName Template = TemplateD.getAsVal<TemplateName>(); | 
 | 1857 |    | 
 | 1858 |   // Translate the parser's template argument list in our AST format. | 
 | 1859 |   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); | 
 | 1860 |   translateTemplateArguments(TemplateArgsIn, TemplateArgs); | 
 | 1861 |    | 
 | 1862 |   // Determine the tag kind | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 1863 |   TagTypeKind TagKind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1864 |   ElaboratedTypeKeyword Keyword | 
 | 1865 |     = TypeWithKeyword::getKeywordForTagTypeKind(TagKind); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1866 |  | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1867 |   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { | 
 | 1868 |     QualType T = Context.getDependentTemplateSpecializationType(Keyword, | 
 | 1869 |                                                           DTN->getQualifier(),  | 
 | 1870 |                                                           DTN->getIdentifier(),  | 
 | 1871 |                                                                 TemplateArgs); | 
 | 1872 |      | 
 | 1873 |     // Build type-source information.     | 
 | 1874 |     TypeLocBuilder TLB; | 
 | 1875 |     DependentTemplateSpecializationTypeLoc SpecTL | 
 | 1876 |     = TLB.push<DependentTemplateSpecializationTypeLoc>(T); | 
 | 1877 |     SpecTL.setKeywordLoc(TagLoc); | 
 | 1878 |     SpecTL.setNameLoc(TemplateLoc); | 
 | 1879 |     SpecTL.setLAngleLoc(LAngleLoc); | 
 | 1880 |     SpecTL.setRAngleLoc(RAngleLoc); | 
 | 1881 |     SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
 | 1882 |     for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I) | 
 | 1883 |       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); | 
 | 1884 |     return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T)); | 
 | 1885 |   } | 
 | 1886 |    | 
 | 1887 |   QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs); | 
 | 1888 |   if (Result.isNull()) | 
 | 1889 |     return TypeResult(); | 
 | 1890 |    | 
 | 1891 |   // Check the tag kind | 
 | 1892 |   if (const RecordType *RT = Result->getAs<RecordType>()) { | 
| John McCall | 6b2becf | 2009-09-08 17:47:29 +0000 | [diff] [blame] | 1893 |     RecordDecl *D = RT->getDecl(); | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1894 |      | 
| John McCall | 6b2becf | 2009-09-08 17:47:29 +0000 | [diff] [blame] | 1895 |     IdentifierInfo *Id = D->getIdentifier(); | 
 | 1896 |     assert(Id && "templated class must have an identifier"); | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1897 |      | 
| John McCall | 6b2becf | 2009-09-08 17:47:29 +0000 | [diff] [blame] | 1898 |     if (!isAcceptableTagRedeclaration(D, TagKind, TagLoc, *Id)) { | 
 | 1899 |       Diag(TagLoc, diag::err_use_with_wrong_tag) | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1900 |         << Result | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 1901 |         << FixItHint::CreateReplacement(SourceRange(TagLoc), D->getKindName()); | 
| John McCall | c4e7019 | 2009-09-11 04:59:25 +0000 | [diff] [blame] | 1902 |       Diag(D->getLocation(), diag::note_previous_use); | 
| John McCall | f1bbbb4 | 2009-09-04 01:14:41 +0000 | [diff] [blame] | 1903 |     } | 
 | 1904 |   } | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1905 |    | 
 | 1906 |   // Provide source-location information for the template specialization. | 
 | 1907 |   TypeLocBuilder TLB; | 
 | 1908 |   TemplateSpecializationTypeLoc SpecTL | 
 | 1909 |     = TLB.push<TemplateSpecializationTypeLoc>(Result); | 
 | 1910 |   SpecTL.setTemplateNameLoc(TemplateLoc); | 
 | 1911 |   SpecTL.setLAngleLoc(LAngleLoc); | 
 | 1912 |   SpecTL.setRAngleLoc(RAngleLoc); | 
 | 1913 |   for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i) | 
 | 1914 |     SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo()); | 
| John McCall | f1bbbb4 | 2009-09-04 01:14:41 +0000 | [diff] [blame] | 1915 |  | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 1916 |   // Construct an elaborated type containing the nested-name-specifier (if any) | 
 | 1917 |   // and keyword. | 
 | 1918 |   Result = Context.getElaboratedType(Keyword, SS.getScopeRep(), Result); | 
 | 1919 |   ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result); | 
 | 1920 |   ElabTL.setKeywordLoc(TagLoc); | 
 | 1921 |   ElabTL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
 | 1922 |   return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); | 
| Douglas Gregor | 55f6b14 | 2009-02-09 18:46:07 +0000 | [diff] [blame] | 1923 | } | 
 | 1924 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 1925 | ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS, | 
| Douglas Gregor | 4c9be89 | 2011-02-28 20:01:57 +0000 | [diff] [blame] | 1926 |                                      LookupResult &R, | 
 | 1927 |                                      bool RequiresADL, | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 1928 |                                  const TemplateArgumentListInfo &TemplateArgs) { | 
| Douglas Gregor | edce4dd | 2009-06-30 22:34:41 +0000 | [diff] [blame] | 1929 |   // FIXME: Can we do any checking at this point? I guess we could check the | 
 | 1930 |   // template arguments that we have against the template name, if the template | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1931 |   // name refers to a single template. That's not a terribly common case, | 
| Douglas Gregor | edce4dd | 2009-06-30 22:34:41 +0000 | [diff] [blame] | 1932 |   // though. | 
| Douglas Gregor | 1be8eec | 2011-02-19 21:32:49 +0000 | [diff] [blame] | 1933 |   // foo<int> could identify a single function unambiguously | 
 | 1934 |   // This approach does NOT work, since f<int>(1); | 
 | 1935 |   // gets resolved prior to resorting to overload resolution | 
 | 1936 |   // i.e., template<class T> void f(double); | 
 | 1937 |   //       vs template<class T, class U> void f(U); | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1938 |  | 
 | 1939 |   // These should be filtered out by our callers. | 
 | 1940 |   assert(!R.empty() && "empty lookup results when building templateid"); | 
 | 1941 |   assert(!R.isAmbiguous() && "ambiguous lookup when building templateid"); | 
 | 1942 |  | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 1943 |   // We don't want lookup warnings at this point. | 
 | 1944 |   R.suppressDiagnostics(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1945 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1946 |   UnresolvedLookupExpr *ULE | 
| Douglas Gregor | bebbe0d | 2010-12-15 01:34:56 +0000 | [diff] [blame] | 1947 |     = UnresolvedLookupExpr::Create(Context, R.getNamingClass(), | 
| Douglas Gregor | 4c9be89 | 2011-02-28 20:01:57 +0000 | [diff] [blame] | 1948 |                                    SS.getWithLocInContext(Context), | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1949 |                                    R.getLookupNameInfo(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1950 |                                    RequiresADL, TemplateArgs, | 
| Douglas Gregor | 5a84dec | 2010-05-23 18:57:34 +0000 | [diff] [blame] | 1951 |                                    R.begin(), R.end()); | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1952 |  | 
 | 1953 |   return Owned(ULE); | 
| Douglas Gregor | edce4dd | 2009-06-30 22:34:41 +0000 | [diff] [blame] | 1954 | } | 
 | 1955 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1956 | // We actually only call this from template instantiation. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 1957 | ExprResult | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 1958 | Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS, | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1959 |                                    const DeclarationNameInfo &NameInfo, | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1960 |                              const TemplateArgumentListInfo &TemplateArgs) { | 
 | 1961 |   DeclContext *DC; | 
 | 1962 |   if (!(DC = computeDeclContext(SS, false)) || | 
 | 1963 |       DC->isDependentContext() || | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 1964 |       RequireCompleteDeclContext(SS, DC)) | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1965 |     return BuildDependentDeclRefExpr(SS, NameInfo, &TemplateArgs); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1966 |  | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 1967 |   bool MemberOfUnknownSpecialization; | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1968 |   LookupResult R(*this, NameInfo, LookupOrdinaryName); | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 1969 |   LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false, | 
 | 1970 |                      MemberOfUnknownSpecialization); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 1971 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1972 |   if (R.isAmbiguous()) | 
 | 1973 |     return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1974 |  | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1975 |   if (R.empty()) { | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1976 |     Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_non_template) | 
 | 1977 |       << NameInfo.getName() << SS.getRange(); | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1978 |     return ExprError(); | 
 | 1979 |   } | 
 | 1980 |  | 
 | 1981 |   if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) { | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 1982 |     Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template) | 
 | 1983 |       << (NestedNameSpecifier*) SS.getScopeRep() | 
 | 1984 |       << NameInfo.getName() << SS.getRange(); | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 1985 |     Diag(Temp->getLocation(), diag::note_referenced_class_template); | 
 | 1986 |     return ExprError(); | 
 | 1987 |   } | 
 | 1988 |  | 
 | 1989 |   return BuildTemplateIdExpr(SS, R, /* ADL */ false, TemplateArgs); | 
| Douglas Gregor | edce4dd | 2009-06-30 22:34:41 +0000 | [diff] [blame] | 1990 | } | 
 | 1991 |  | 
| Douglas Gregor | c45c232 | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 1992 | /// \brief Form a dependent template name. | 
 | 1993 | /// | 
 | 1994 | /// This action forms a dependent template name given the template | 
 | 1995 | /// name and its (presumably dependent) scope specifier. For | 
 | 1996 | /// example, given "MetaFun::template apply", the scope specifier \p | 
 | 1997 | /// SS will be "MetaFun::", \p TemplateKWLoc contains the location | 
 | 1998 | /// of the "template" keyword, and "apply" is the \p Name. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 1999 | TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S, | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2000 |                                                   SourceLocation TemplateKWLoc, | 
 | 2001 |                                                   CXXScopeSpec &SS, | 
 | 2002 |                                                   UnqualifiedId &Name, | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 2003 |                                                   ParsedType ObjectType, | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2004 |                                                   bool EnteringContext, | 
 | 2005 |                                                   TemplateTy &Result) { | 
| Douglas Gregor | 1a15dae | 2010-06-16 22:31:08 +0000 | [diff] [blame] | 2006 |   if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent() && | 
 | 2007 |       !getLangOptions().CPlusPlus0x) | 
 | 2008 |     Diag(TemplateKWLoc, diag::ext_template_outside_of_template) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2009 |       << FixItHint::CreateRemoval(TemplateKWLoc); | 
 | 2010 |  | 
| Douglas Gregor | 0707bc5 | 2010-01-19 16:01:07 +0000 | [diff] [blame] | 2011 |   DeclContext *LookupCtx = 0; | 
 | 2012 |   if (SS.isSet()) | 
 | 2013 |     LookupCtx = computeDeclContext(SS, EnteringContext); | 
 | 2014 |   if (!LookupCtx && ObjectType) | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 2015 |     LookupCtx = computeDeclContext(ObjectType.get()); | 
| Douglas Gregor | 0707bc5 | 2010-01-19 16:01:07 +0000 | [diff] [blame] | 2016 |   if (LookupCtx) { | 
| Douglas Gregor | c45c232 | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 2017 |     // C++0x [temp.names]p5: | 
 | 2018 |     //   If a name prefixed by the keyword template is not the name of | 
 | 2019 |     //   a template, the program is ill-formed. [Note: the keyword | 
 | 2020 |     //   template may not be applied to non-template members of class | 
 | 2021 |     //   templates. -end note ] [ Note: as is the case with the | 
 | 2022 |     //   typename prefix, the template prefix is allowed in cases | 
 | 2023 |     //   where it is not strictly necessary; i.e., when the | 
 | 2024 |     //   nested-name-specifier or the expression on the left of the -> | 
 | 2025 |     //   or . is not dependent on a template-parameter, or the use | 
 | 2026 |     //   does not appear in the scope of a template. -end note] | 
 | 2027 |     // | 
 | 2028 |     // Note: C++03 was more strict here, because it banned the use of | 
 | 2029 |     // the "template" keyword prior to a template-name that was not a | 
 | 2030 |     // dependent name. C++ DR468 relaxed this requirement (the | 
 | 2031 |     // "template" keyword is now permitted). We follow the C++0x | 
| Douglas Gregor | 732281d | 2010-06-14 22:07:54 +0000 | [diff] [blame] | 2032 |     // rules, even in C++03 mode with a warning, retroactively applying the DR. | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 2033 |     bool MemberOfUnknownSpecialization; | 
| Abramo Bagnara | 7c15353 | 2010-08-06 12:11:11 +0000 | [diff] [blame] | 2034 |     TemplateNameKind TNK = isTemplateName(0, SS, TemplateKWLoc.isValid(), Name, | 
 | 2035 |                                           ObjectType, EnteringContext, Result, | 
| Douglas Gregor | 1fd6d44 | 2010-05-21 23:18:07 +0000 | [diff] [blame] | 2036 |                                           MemberOfUnknownSpecialization); | 
| Douglas Gregor | 0707bc5 | 2010-01-19 16:01:07 +0000 | [diff] [blame] | 2037 |     if (TNK == TNK_Non_template && LookupCtx->isDependentContext() && | 
 | 2038 |         isa<CXXRecordDecl>(LookupCtx) && | 
 | 2039 |         cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases()) { | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2040 |       // This is a dependent template. Handle it below. | 
| Douglas Gregor | 9edad9b | 2010-01-14 17:47:39 +0000 | [diff] [blame] | 2041 |     } else if (TNK == TNK_Non_template) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2042 |       Diag(Name.getSourceRange().getBegin(), | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 2043 |            diag::err_template_kw_refers_to_non_template) | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 2044 |         << GetNameFromUnqualifiedId(Name).getName() | 
| Douglas Gregor | 0278e12 | 2010-05-05 05:58:24 +0000 | [diff] [blame] | 2045 |         << Name.getSourceRange() | 
 | 2046 |         << TemplateKWLoc; | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2047 |       return TNK_Non_template; | 
| Douglas Gregor | 9edad9b | 2010-01-14 17:47:39 +0000 | [diff] [blame] | 2048 |     } else { | 
 | 2049 |       // We found something; return it. | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2050 |       return TNK; | 
| Douglas Gregor | c45c232 | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 2051 |     } | 
| Douglas Gregor | c45c232 | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 2052 |   } | 
 | 2053 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2054 |   NestedNameSpecifier *Qualifier | 
| Douglas Gregor | 2dd078a | 2009-09-02 22:59:36 +0000 | [diff] [blame] | 2055 |     = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2056 |  | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 2057 |   switch (Name.getKind()) { | 
 | 2058 |   case UnqualifiedId::IK_Identifier: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2059 |     Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2060 |                                                               Name.Identifier)); | 
 | 2061 |     return TNK_Dependent_template_name; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2062 |  | 
| Douglas Gregor | ca1bdd7 | 2009-11-04 00:56:37 +0000 | [diff] [blame] | 2063 |   case UnqualifiedId::IK_OperatorFunctionId: | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2064 |     Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier, | 
| Douglas Gregor | ca1bdd7 | 2009-11-04 00:56:37 +0000 | [diff] [blame] | 2065 |                                              Name.OperatorFunctionId.Operator)); | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2066 |     return TNK_Dependent_template_name; | 
| Sean Hunt | e6252d1 | 2009-11-28 08:58:14 +0000 | [diff] [blame] | 2067 |  | 
 | 2068 |   case UnqualifiedId::IK_LiteralOperatorId: | 
 | 2069 |     assert(false && "We don't support these; Parse shouldn't have allowed propagation"); | 
 | 2070 |  | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 2071 |   default: | 
 | 2072 |     break; | 
 | 2073 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2074 |  | 
 | 2075 |   Diag(Name.getSourceRange().getBegin(), | 
| Douglas Gregor | 014e88d | 2009-11-03 23:16:33 +0000 | [diff] [blame] | 2076 |        diag::err_template_kw_refers_to_non_template) | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 2077 |     << GetNameFromUnqualifiedId(Name).getName() | 
| Douglas Gregor | 0278e12 | 2010-05-05 05:58:24 +0000 | [diff] [blame] | 2078 |     << Name.getSourceRange() | 
 | 2079 |     << TemplateKWLoc; | 
| Douglas Gregor | d6ab232 | 2010-06-16 23:00:59 +0000 | [diff] [blame] | 2080 |   return TNK_Non_template; | 
| Douglas Gregor | c45c232 | 2009-03-31 00:43:58 +0000 | [diff] [blame] | 2081 | } | 
 | 2082 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2083 | bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param, | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 2084 |                                      const TemplateArgumentLoc &AL, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2085 |                           llvm::SmallVectorImpl<TemplateArgument> &Converted) { | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 2086 |   const TemplateArgument &Arg = AL.getArgument(); | 
 | 2087 |  | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2088 |   // Check template type parameter. | 
| Jeffrey Yasskin | db88d8a | 2010-04-08 00:03:06 +0000 | [diff] [blame] | 2089 |   switch(Arg.getKind()) { | 
 | 2090 |   case TemplateArgument::Type: | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2091 |     // C++ [temp.arg.type]p1: | 
 | 2092 |     //   A template-argument for a template-parameter which is a | 
 | 2093 |     //   type shall be a type-id. | 
| Jeffrey Yasskin | db88d8a | 2010-04-08 00:03:06 +0000 | [diff] [blame] | 2094 |     break; | 
 | 2095 |   case TemplateArgument::Template: { | 
 | 2096 |     // We have a template type parameter but the template argument | 
 | 2097 |     // is a template without any arguments. | 
 | 2098 |     SourceRange SR = AL.getSourceRange(); | 
 | 2099 |     TemplateName Name = Arg.getAsTemplate(); | 
 | 2100 |     Diag(SR.getBegin(), diag::err_template_missing_args) | 
 | 2101 |       << Name << SR; | 
 | 2102 |     if (TemplateDecl *Decl = Name.getAsTemplateDecl()) | 
 | 2103 |       Diag(Decl->getLocation(), diag::note_template_decl_here); | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2104 |  | 
| Jeffrey Yasskin | db88d8a | 2010-04-08 00:03:06 +0000 | [diff] [blame] | 2105 |     return true; | 
 | 2106 |   } | 
 | 2107 |   default: { | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2108 |     // We have a template type parameter but the template argument | 
 | 2109 |     // is not a type. | 
| John McCall | 828bff2 | 2009-10-29 18:45:58 +0000 | [diff] [blame] | 2110 |     SourceRange SR = AL.getSourceRange(); | 
 | 2111 |     Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR; | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2112 |     Diag(Param->getLocation(), diag::note_template_param_here); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2113 |  | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2114 |     return true; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2115 |   } | 
| Jeffrey Yasskin | db88d8a | 2010-04-08 00:03:06 +0000 | [diff] [blame] | 2116 |   } | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2117 |  | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2118 |   if (CheckTemplateArgument(Param, AL.getTypeSourceInfo())) | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2119 |     return true; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2120 |  | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2121 |   // Add the converted template type argument. | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2122 |   Converted.push_back( | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 2123 |                  TemplateArgument(Context.getCanonicalType(Arg.getAsType()))); | 
| Anders Carlsson | 436b156 | 2009-06-13 00:33:33 +0000 | [diff] [blame] | 2124 |   return false; | 
 | 2125 | } | 
 | 2126 |  | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2127 | /// \brief Substitute template arguments into the default template argument for | 
 | 2128 | /// the given template type parameter. | 
 | 2129 | /// | 
 | 2130 | /// \param SemaRef the semantic analysis object for which we are performing | 
 | 2131 | /// the substitution. | 
 | 2132 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2133 | /// \param Template the template that we are synthesizing template arguments | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2134 | /// for. | 
 | 2135 | /// | 
 | 2136 | /// \param TemplateLoc the location of the template name that started the | 
 | 2137 | /// template-id we are checking. | 
 | 2138 | /// | 
 | 2139 | /// \param RAngleLoc the location of the right angle bracket ('>') that | 
 | 2140 | /// terminates the template-id. | 
 | 2141 | /// | 
 | 2142 | /// \param Param the template template parameter whose default we are | 
 | 2143 | /// substituting into. | 
 | 2144 | /// | 
 | 2145 | /// \param Converted the list of template arguments provided for template | 
 | 2146 | /// parameters that precede \p Param in the template parameter list. | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2147 | /// \returns the substituted template argument, or NULL if an error occurred. | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2148 | static TypeSourceInfo * | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2149 | SubstDefaultTemplateArgument(Sema &SemaRef, | 
 | 2150 |                              TemplateDecl *Template, | 
 | 2151 |                              SourceLocation TemplateLoc, | 
 | 2152 |                              SourceLocation RAngleLoc, | 
 | 2153 |                              TemplateTypeParmDecl *Param, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2154 |                          llvm::SmallVectorImpl<TemplateArgument> &Converted) { | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2155 |   TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo(); | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2156 |  | 
 | 2157 |   // If the argument type is dependent, instantiate it now based | 
 | 2158 |   // on the previously-computed template arguments. | 
 | 2159 |   if (ArgType->getType()->isDependentType()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2160 |     TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2161 |                                       Converted.data(), Converted.size()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2162 |  | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2163 |     MultiLevelTemplateArgumentList AllTemplateArgs | 
 | 2164 |       = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); | 
 | 2165 |  | 
 | 2166 |     Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2167 |                                      Template, Converted.data(), | 
 | 2168 |                                      Converted.size(), | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2169 |                                      SourceRange(TemplateLoc, RAngleLoc)); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2170 |  | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2171 |     ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs, | 
 | 2172 |                                 Param->getDefaultArgumentLoc(), | 
 | 2173 |                                 Param->getDeclName()); | 
 | 2174 |   } | 
 | 2175 |  | 
 | 2176 |   return ArgType; | 
 | 2177 | } | 
 | 2178 |  | 
 | 2179 | /// \brief Substitute template arguments into the default template argument for | 
 | 2180 | /// the given non-type template parameter. | 
 | 2181 | /// | 
 | 2182 | /// \param SemaRef the semantic analysis object for which we are performing | 
 | 2183 | /// the substitution. | 
 | 2184 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2185 | /// \param Template the template that we are synthesizing template arguments | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2186 | /// for. | 
 | 2187 | /// | 
 | 2188 | /// \param TemplateLoc the location of the template name that started the | 
 | 2189 | /// template-id we are checking. | 
 | 2190 | /// | 
 | 2191 | /// \param RAngleLoc the location of the right angle bracket ('>') that | 
 | 2192 | /// terminates the template-id. | 
 | 2193 | /// | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2194 | /// \param Param the non-type template parameter whose default we are | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2195 | /// substituting into. | 
 | 2196 | /// | 
 | 2197 | /// \param Converted the list of template arguments provided for template | 
 | 2198 | /// parameters that precede \p Param in the template parameter list. | 
 | 2199 | /// | 
 | 2200 | /// \returns the substituted template argument, or NULL if an error occurred. | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 2201 | static ExprResult | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2202 | SubstDefaultTemplateArgument(Sema &SemaRef, | 
 | 2203 |                              TemplateDecl *Template, | 
 | 2204 |                              SourceLocation TemplateLoc, | 
 | 2205 |                              SourceLocation RAngleLoc, | 
 | 2206 |                              NonTypeTemplateParmDecl *Param, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2207 |                         llvm::SmallVectorImpl<TemplateArgument> &Converted) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2208 |   TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2209 |                                     Converted.data(), Converted.size()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2210 |  | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2211 |   MultiLevelTemplateArgumentList AllTemplateArgs | 
 | 2212 |     = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2213 |  | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2214 |   Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2215 |                                    Template, Converted.data(), | 
 | 2216 |                                    Converted.size(), | 
| Douglas Gregor | 0f8716b | 2009-11-09 19:17:50 +0000 | [diff] [blame] | 2217 |                                    SourceRange(TemplateLoc, RAngleLoc)); | 
 | 2218 |  | 
 | 2219 |   return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs); | 
 | 2220 | } | 
 | 2221 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2222 | /// \brief Substitute template arguments into the default template argument for | 
 | 2223 | /// the given template template parameter. | 
 | 2224 | /// | 
 | 2225 | /// \param SemaRef the semantic analysis object for which we are performing | 
 | 2226 | /// the substitution. | 
 | 2227 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2228 | /// \param Template the template that we are synthesizing template arguments | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2229 | /// for. | 
 | 2230 | /// | 
 | 2231 | /// \param TemplateLoc the location of the template name that started the | 
 | 2232 | /// template-id we are checking. | 
 | 2233 | /// | 
 | 2234 | /// \param RAngleLoc the location of the right angle bracket ('>') that | 
 | 2235 | /// terminates the template-id. | 
 | 2236 | /// | 
 | 2237 | /// \param Param the template template parameter whose default we are | 
 | 2238 | /// substituting into. | 
 | 2239 | /// | 
 | 2240 | /// \param Converted the list of template arguments provided for template | 
 | 2241 | /// parameters that precede \p Param in the template parameter list. | 
 | 2242 | /// | 
| Douglas Gregor | 1d752d7 | 2011-03-02 18:46:51 +0000 | [diff] [blame] | 2243 | /// \param QualifierLoc Will be set to the nested-name-specifier (with  | 
 | 2244 | /// source-location information) that precedes the template name. | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2245 | /// | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2246 | /// \returns the substituted template argument, or NULL if an error occurred. | 
 | 2247 | static TemplateName | 
 | 2248 | SubstDefaultTemplateArgument(Sema &SemaRef, | 
 | 2249 |                              TemplateDecl *Template, | 
 | 2250 |                              SourceLocation TemplateLoc, | 
 | 2251 |                              SourceLocation RAngleLoc, | 
 | 2252 |                              TemplateTemplateParmDecl *Param, | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2253 |                        llvm::SmallVectorImpl<TemplateArgument> &Converted, | 
 | 2254 |                              NestedNameSpecifierLoc &QualifierLoc) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2255 |   TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2256 |                                     Converted.data(), Converted.size()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2257 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2258 |   MultiLevelTemplateArgumentList AllTemplateArgs | 
 | 2259 |     = SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2260 |  | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2261 |   Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2262 |                                    Template, Converted.data(), | 
 | 2263 |                                    Converted.size(), | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2264 |                                    SourceRange(TemplateLoc, RAngleLoc)); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2265 |  | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2266 |   // Substitute into the nested-name-specifier first,  | 
| Douglas Gregor | 1d752d7 | 2011-03-02 18:46:51 +0000 | [diff] [blame] | 2267 |   QualifierLoc = Param->getDefaultArgument().getTemplateQualifierLoc(); | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2268 |   if (QualifierLoc) { | 
 | 2269 |     QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,  | 
 | 2270 |                                                        AllTemplateArgs); | 
 | 2271 |     if (!QualifierLoc) | 
 | 2272 |       return TemplateName(); | 
 | 2273 |   } | 
 | 2274 |    | 
| Douglas Gregor | 1d752d7 | 2011-03-02 18:46:51 +0000 | [diff] [blame] | 2275 |   return SemaRef.SubstTemplateName(QualifierLoc, | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2276 |                       Param->getDefaultArgument().getArgument().getAsTemplate(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2277 |                               Param->getDefaultArgument().getTemplateNameLoc(), | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 2278 |                                    AllTemplateArgs); | 
 | 2279 | } | 
 | 2280 |  | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2281 | /// \brief If the given template parameter has a default template | 
 | 2282 | /// argument, substitute into that default template argument and | 
 | 2283 | /// return the corresponding template argument. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2284 | TemplateArgumentLoc | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2285 | Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template, | 
 | 2286 |                                               SourceLocation TemplateLoc, | 
 | 2287 |                                               SourceLocation RAngleLoc, | 
 | 2288 |                                               Decl *Param, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2289 |                       llvm::SmallVectorImpl<TemplateArgument> &Converted) { | 
 | 2290 |    if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) { | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2291 |     if (!TypeParm->hasDefaultArgument()) | 
 | 2292 |       return TemplateArgumentLoc(); | 
 | 2293 |  | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 2294 |     TypeSourceInfo *DI = SubstDefaultTemplateArgument(*this, Template, | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2295 |                                                       TemplateLoc, | 
 | 2296 |                                                       RAngleLoc, | 
 | 2297 |                                                       TypeParm, | 
 | 2298 |                                                       Converted); | 
 | 2299 |     if (DI) | 
 | 2300 |       return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI); | 
 | 2301 |  | 
 | 2302 |     return TemplateArgumentLoc(); | 
 | 2303 |   } | 
 | 2304 |  | 
 | 2305 |   if (NonTypeTemplateParmDecl *NonTypeParm | 
 | 2306 |         = dyn_cast<NonTypeTemplateParmDecl>(Param)) { | 
 | 2307 |     if (!NonTypeParm->hasDefaultArgument()) | 
 | 2308 |       return TemplateArgumentLoc(); | 
 | 2309 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 2310 |     ExprResult Arg = SubstDefaultTemplateArgument(*this, Template, | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2311 |                                                   TemplateLoc, | 
 | 2312 |                                                   RAngleLoc, | 
 | 2313 |                                                   NonTypeParm, | 
 | 2314 |                                                   Converted); | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2315 |     if (Arg.isInvalid()) | 
 | 2316 |       return TemplateArgumentLoc(); | 
 | 2317 |  | 
 | 2318 |     Expr *ArgE = Arg.takeAs<Expr>(); | 
 | 2319 |     return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE); | 
 | 2320 |   } | 
 | 2321 |  | 
 | 2322 |   TemplateTemplateParmDecl *TempTempParm | 
 | 2323 |     = cast<TemplateTemplateParmDecl>(Param); | 
 | 2324 |   if (!TempTempParm->hasDefaultArgument()) | 
 | 2325 |     return TemplateArgumentLoc(); | 
 | 2326 |  | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2327 |  | 
| Douglas Gregor | 1d752d7 | 2011-03-02 18:46:51 +0000 | [diff] [blame] | 2328 |   NestedNameSpecifierLoc QualifierLoc; | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2329 |   TemplateName TName = SubstDefaultTemplateArgument(*this, Template, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2330 |                                                     TemplateLoc, | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2331 |                                                     RAngleLoc, | 
 | 2332 |                                                     TempTempParm, | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2333 |                                                     Converted, | 
 | 2334 |                                                     QualifierLoc); | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2335 |   if (TName.isNull()) | 
 | 2336 |     return TemplateArgumentLoc(); | 
 | 2337 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2338 |   return TemplateArgumentLoc(TemplateArgument(TName), | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2339 |                 TempTempParm->getDefaultArgument().getTemplateQualifierLoc(), | 
| Douglas Gregor | 51ffb0c | 2009-11-25 18:55:14 +0000 | [diff] [blame] | 2340 |                 TempTempParm->getDefaultArgument().getTemplateNameLoc()); | 
 | 2341 | } | 
 | 2342 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2343 | /// \brief Check that the given template argument corresponds to the given | 
 | 2344 | /// template parameter. | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2345 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2346 | /// \param Param The template parameter against which the argument will be | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2347 | /// checked. | 
 | 2348 | /// | 
 | 2349 | /// \param Arg The template argument. | 
 | 2350 | /// | 
 | 2351 | /// \param Template The template in which the template argument resides. | 
 | 2352 | /// | 
 | 2353 | /// \param TemplateLoc The location of the template name for the template | 
 | 2354 | /// whose argument list we're matching. | 
 | 2355 | /// | 
 | 2356 | /// \param RAngleLoc The location of the right angle bracket ('>') that closes | 
 | 2357 | /// the template argument list. | 
 | 2358 | /// | 
 | 2359 | /// \param ArgumentPackIndex The index into the argument pack where this | 
 | 2360 | /// argument will be placed. Only valid if the parameter is a parameter pack. | 
 | 2361 | /// | 
 | 2362 | /// \param Converted The checked, converted argument will be added to the | 
 | 2363 | /// end of this small vector. | 
 | 2364 | /// | 
 | 2365 | /// \param CTAK Describes how we arrived at this particular template argument: | 
 | 2366 | /// explicitly written, deduced, etc. | 
 | 2367 | /// | 
 | 2368 | /// \returns true on error, false otherwise. | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2369 | bool Sema::CheckTemplateArgument(NamedDecl *Param, | 
 | 2370 |                                  const TemplateArgumentLoc &Arg, | 
| Douglas Gregor | 54c53cc | 2011-01-04 23:35:54 +0000 | [diff] [blame] | 2371 |                                  NamedDecl *Template, | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2372 |                                  SourceLocation TemplateLoc, | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2373 |                                  SourceLocation RAngleLoc, | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2374 |                                  unsigned ArgumentPackIndex, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2375 |                             llvm::SmallVectorImpl<TemplateArgument> &Converted, | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 2376 |                                  CheckTemplateArgumentKind CTAK) { | 
| Douglas Gregor | d9e1530 | 2009-11-11 19:41:09 +0000 | [diff] [blame] | 2377 |   // Check template type parameters. | 
 | 2378 |   if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2379 |     return CheckTemplateTypeArgument(TTP, Arg, Converted); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2380 |  | 
| Douglas Gregor | d9e1530 | 2009-11-11 19:41:09 +0000 | [diff] [blame] | 2381 |   // Check non-type template parameters. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2382 |   if (NonTypeTemplateParmDecl *NTTP =dyn_cast<NonTypeTemplateParmDecl>(Param)) { | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2383 |     // Do substitution on the type of the non-type template parameter | 
| Peter Collingbourne | 9f6f6a1 | 2010-12-10 17:08:53 +0000 | [diff] [blame] | 2384 |     // with the template arguments we've seen thus far.  But if the | 
 | 2385 |     // template has a dependent context then we cannot substitute yet. | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2386 |     QualType NTTPType = NTTP->getType(); | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2387 |     if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack()) | 
 | 2388 |       NTTPType = NTTP->getExpansionType(ArgumentPackIndex); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2389 |  | 
| Peter Collingbourne | 9f6f6a1 | 2010-12-10 17:08:53 +0000 | [diff] [blame] | 2390 |     if (NTTPType->isDependentType() && | 
 | 2391 |         !isa<TemplateTemplateParmDecl>(Template) && | 
 | 2392 |         !Template->getDeclContext()->isDependentContext()) { | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2393 |       // Do substitution on the type of the non-type template parameter. | 
 | 2394 |       InstantiatingTemplate Inst(*this, TemplateLoc, Template, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2395 |                                  NTTP, Converted.data(), Converted.size(), | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2396 |                                  SourceRange(TemplateLoc, RAngleLoc)); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2397 |  | 
 | 2398 |       TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2399 |                                         Converted.data(), Converted.size()); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2400 |       NTTPType = SubstType(NTTPType, | 
 | 2401 |                            MultiLevelTemplateArgumentList(TemplateArgs), | 
 | 2402 |                            NTTP->getLocation(), | 
 | 2403 |                            NTTP->getDeclName()); | 
 | 2404 |       // If that worked, check the non-type template parameter type | 
 | 2405 |       // for validity. | 
 | 2406 |       if (!NTTPType.isNull()) | 
 | 2407 |         NTTPType = CheckNonTypeTemplateParameterType(NTTPType, | 
 | 2408 |                                                      NTTP->getLocation()); | 
 | 2409 |       if (NTTPType.isNull()) | 
 | 2410 |         return true; | 
 | 2411 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2412 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2413 |     switch (Arg.getArgument().getKind()) { | 
 | 2414 |     case TemplateArgument::Null: | 
 | 2415 |       assert(false && "Should never see a NULL template argument here"); | 
 | 2416 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2417 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2418 |     case TemplateArgument::Expression: { | 
 | 2419 |       Expr *E = Arg.getArgument().getAsExpr(); | 
 | 2420 |       TemplateArgument Result; | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 2421 |       if (CheckTemplateArgument(NTTP, NTTPType, E, Result, CTAK)) | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2422 |         return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2423 |  | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2424 |       Converted.push_back(Result); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2425 |       break; | 
 | 2426 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2427 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2428 |     case TemplateArgument::Declaration: | 
 | 2429 |     case TemplateArgument::Integral: | 
 | 2430 |       // We've already checked this template argument, so just copy | 
 | 2431 |       // it to the list of converted arguments. | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2432 |       Converted.push_back(Arg.getArgument()); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2433 |       break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2434 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2435 |     case TemplateArgument::Template: | 
| Douglas Gregor | a7fc901 | 2011-01-05 18:58:31 +0000 | [diff] [blame] | 2436 |     case TemplateArgument::TemplateExpansion: | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2437 |       // We were given a template template argument. It may not be ill-formed; | 
 | 2438 |       // see below. | 
 | 2439 |       if (DependentTemplateName *DTN | 
| Douglas Gregor | a7fc901 | 2011-01-05 18:58:31 +0000 | [diff] [blame] | 2440 |             = Arg.getArgument().getAsTemplateOrTemplatePattern() | 
 | 2441 |                                               .getAsDependentTemplateName()) { | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2442 |         // We have a template argument such as \c T::template X, which we | 
 | 2443 |         // parsed as a template template argument. However, since we now | 
 | 2444 |         // know that we need a non-type template argument, convert this | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 2445 |         // template name into an expression. | 
 | 2446 |  | 
 | 2447 |         DeclarationNameInfo NameInfo(DTN->getIdentifier(), | 
 | 2448 |                                      Arg.getTemplateNameLoc()); | 
 | 2449 |  | 
| Douglas Gregor | 00cf3cc | 2011-02-25 20:49:16 +0000 | [diff] [blame] | 2450 |         CXXScopeSpec SS; | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2451 |         SS.Adopt(Arg.getTemplateQualifierLoc()); | 
| John McCall | f7a1a74 | 2009-11-24 19:00:30 +0000 | [diff] [blame] | 2452 |         Expr *E = DependentScopeDeclRefExpr::Create(Context, | 
| Douglas Gregor | 00cf3cc | 2011-02-25 20:49:16 +0000 | [diff] [blame] | 2453 |                                                 SS.getWithLocInContext(Context), | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 2454 |                                                     NameInfo); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2455 |  | 
| Douglas Gregor | a7fc901 | 2011-01-05 18:58:31 +0000 | [diff] [blame] | 2456 |         // If we parsed the template argument as a pack expansion, create a | 
 | 2457 |         // pack expansion expression. | 
 | 2458 |         if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){ | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2459 |           ExprResult Expansion = ActOnPackExpansion(E, | 
| Douglas Gregor | a7fc901 | 2011-01-05 18:58:31 +0000 | [diff] [blame] | 2460 |                                                   Arg.getTemplateEllipsisLoc()); | 
 | 2461 |           if (Expansion.isInvalid()) | 
 | 2462 |             return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2463 |  | 
| Douglas Gregor | a7fc901 | 2011-01-05 18:58:31 +0000 | [diff] [blame] | 2464 |           E = Expansion.get(); | 
 | 2465 |         } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2466 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2467 |         TemplateArgument Result; | 
 | 2468 |         if (CheckTemplateArgument(NTTP, NTTPType, E, Result)) | 
 | 2469 |           return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2470 |  | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2471 |         Converted.push_back(Result); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2472 |         break; | 
 | 2473 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2474 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2475 |       // We have a template argument that actually does refer to a class | 
 | 2476 |       // template, template alias, or template template parameter, and | 
 | 2477 |       // therefore cannot be a non-type template argument. | 
 | 2478 |       Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr) | 
 | 2479 |         << Arg.getSourceRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2480 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2481 |       Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 2482 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2483 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2484 |     case TemplateArgument::Type: { | 
 | 2485 |       // We have a non-type template parameter but the template | 
 | 2486 |       // argument is a type. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2487 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2488 |       // C++ [temp.arg]p2: | 
 | 2489 |       //   In a template-argument, an ambiguity between a type-id and | 
 | 2490 |       //   an expression is resolved to a type-id, regardless of the | 
 | 2491 |       //   form of the corresponding template-parameter. | 
 | 2492 |       // | 
 | 2493 |       // We warn specifically about this case, since it can be rather | 
 | 2494 |       // confusing for users. | 
 | 2495 |       QualType T = Arg.getArgument().getAsType(); | 
 | 2496 |       SourceRange SR = Arg.getSourceRange(); | 
 | 2497 |       if (T->isFunctionType()) | 
 | 2498 |         Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) << SR << T; | 
 | 2499 |       else | 
 | 2500 |         Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR; | 
 | 2501 |       Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 2502 |       return true; | 
 | 2503 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2504 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2505 |     case TemplateArgument::Pack: | 
| Jeffrey Yasskin | 9f61aa9 | 2009-12-12 05:05:38 +0000 | [diff] [blame] | 2506 |       llvm_unreachable("Caller must expand template argument packs"); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2507 |       break; | 
 | 2508 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2509 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2510 |     return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2511 |   } | 
 | 2512 |  | 
 | 2513 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2514 |   // Check template template parameters. | 
 | 2515 |   TemplateTemplateParmDecl *TempParm = cast<TemplateTemplateParmDecl>(Param); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2516 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2517 |   // Substitute into the template parameter list of the template | 
 | 2518 |   // template parameter, since previously-supplied template arguments | 
 | 2519 |   // may appear within the template template parameter. | 
 | 2520 |   { | 
 | 2521 |     // Set up a template instantiation context. | 
 | 2522 |     LocalInstantiationScope Scope(*this); | 
 | 2523 |     InstantiatingTemplate Inst(*this, TemplateLoc, Template, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2524 |                                TempParm, Converted.data(), Converted.size(), | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2525 |                                SourceRange(TemplateLoc, RAngleLoc)); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2526 |  | 
 | 2527 |     TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2528 |                                       Converted.data(), Converted.size()); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2529 |     TempParm = cast_or_null<TemplateTemplateParmDecl>( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2530 |                       SubstDecl(TempParm, CurContext, | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2531 |                                 MultiLevelTemplateArgumentList(TemplateArgs))); | 
 | 2532 |     if (!TempParm) | 
 | 2533 |       return true; | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2534 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2535 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2536 |   switch (Arg.getArgument().getKind()) { | 
 | 2537 |   case TemplateArgument::Null: | 
 | 2538 |     assert(false && "Should never see a NULL template argument here"); | 
 | 2539 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2540 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2541 |   case TemplateArgument::Template: | 
| Douglas Gregor | a7fc901 | 2011-01-05 18:58:31 +0000 | [diff] [blame] | 2542 |   case TemplateArgument::TemplateExpansion: | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2543 |     if (CheckTemplateArgument(TempParm, Arg)) | 
 | 2544 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2545 |  | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2546 |     Converted.push_back(Arg.getArgument()); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2547 |     break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2548 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2549 |   case TemplateArgument::Expression: | 
 | 2550 |   case TemplateArgument::Type: | 
 | 2551 |     // We have a template template parameter but the template | 
 | 2552 |     // argument does not refer to a template. | 
 | 2553 |     Diag(Arg.getLocation(), diag::err_template_arg_must_be_template); | 
 | 2554 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2555 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2556 |   case TemplateArgument::Declaration: | 
| Jeffrey Yasskin | 9f61aa9 | 2009-12-12 05:05:38 +0000 | [diff] [blame] | 2557 |     llvm_unreachable( | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2558 |                        "Declaration argument with template template parameter"); | 
 | 2559 |     break; | 
 | 2560 |   case TemplateArgument::Integral: | 
| Jeffrey Yasskin | 9f61aa9 | 2009-12-12 05:05:38 +0000 | [diff] [blame] | 2561 |     llvm_unreachable( | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2562 |                           "Integral argument with template template parameter"); | 
 | 2563 |     break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2564 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2565 |   case TemplateArgument::Pack: | 
| Jeffrey Yasskin | 9f61aa9 | 2009-12-12 05:05:38 +0000 | [diff] [blame] | 2566 |     llvm_unreachable("Caller must expand template argument packs"); | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2567 |     break; | 
 | 2568 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2569 |  | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2570 |   return false; | 
 | 2571 | } | 
 | 2572 |  | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2573 | /// \brief Check that the given template argument list is well-formed | 
 | 2574 | /// for specializing the given template. | 
 | 2575 | bool Sema::CheckTemplateArgumentList(TemplateDecl *Template, | 
 | 2576 |                                      SourceLocation TemplateLoc, | 
| Douglas Gregor | 6771423 | 2011-03-03 02:41:12 +0000 | [diff] [blame] | 2577 |                                      TemplateArgumentListInfo &TemplateArgs, | 
| Douglas Gregor | 16134c6 | 2009-07-01 00:28:38 +0000 | [diff] [blame] | 2578 |                                      bool PartialTemplateArgs, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2579 |                           llvm::SmallVectorImpl<TemplateArgument> &Converted) { | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2580 |   TemplateParameterList *Params = Template->getTemplateParameters(); | 
 | 2581 |   unsigned NumParams = Params->size(); | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 2582 |   unsigned NumArgs = TemplateArgs.size(); | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2583 |   bool Invalid = false; | 
 | 2584 |  | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 2585 |   SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc(); | 
 | 2586 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2587 |   bool HasParameterPack = | 
| Anders Carlsson | 0ceffb5 | 2009-06-13 02:08:00 +0000 | [diff] [blame] | 2588 |     NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2589 |  | 
| Anders Carlsson | 0ceffb5 | 2009-06-13 02:08:00 +0000 | [diff] [blame] | 2590 |   if ((NumArgs > NumParams && !HasParameterPack) || | 
| Douglas Gregor | 16134c6 | 2009-07-01 00:28:38 +0000 | [diff] [blame] | 2591 |       (NumArgs < Params->getMinRequiredArguments() && | 
 | 2592 |        !PartialTemplateArgs)) { | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2593 |     // FIXME: point at either the first arg beyond what we can handle, | 
 | 2594 |     // or the '>', depending on whether we have too many or too few | 
 | 2595 |     // arguments. | 
 | 2596 |     SourceRange Range; | 
 | 2597 |     if (NumArgs > NumParams) | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 2598 |       Range = SourceRange(TemplateArgs[NumParams].getLocation(), RAngleLoc); | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2599 |     Diag(TemplateLoc, diag::err_template_arg_list_different_arity) | 
 | 2600 |       << (NumArgs > NumParams) | 
 | 2601 |       << (isa<ClassTemplateDecl>(Template)? 0 : | 
 | 2602 |           isa<FunctionTemplateDecl>(Template)? 1 : | 
 | 2603 |           isa<TemplateTemplateParmDecl>(Template)? 2 : 3) | 
 | 2604 |       << Template << Range; | 
| Douglas Gregor | 62cb18d | 2009-02-11 18:16:40 +0000 | [diff] [blame] | 2605 |     Diag(Template->getLocation(), diag::note_template_decl_here) | 
 | 2606 |       << Params->getSourceRange(); | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2607 |     Invalid = true; | 
 | 2608 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2609 |  | 
 | 2610 |   // C++ [temp.arg]p1: | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2611 |   //   [...] The type and form of each template-argument specified in | 
 | 2612 |   //   a template-id shall match the type and form specified for the | 
 | 2613 |   //   corresponding parameter declared by the template in its | 
 | 2614 |   //   template-parameter-list. | 
| Douglas Gregor | 6771423 | 2011-03-03 02:41:12 +0000 | [diff] [blame] | 2615 |   bool isTemplateTemplateParameter = isa<TemplateTemplateParmDecl>(Template); | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2616 |   llvm::SmallVector<TemplateArgument, 2> ArgumentPack; | 
 | 2617 |   TemplateParameterList::iterator Param = Params->begin(), | 
 | 2618 |                                ParamEnd = Params->end(); | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2619 |   unsigned ArgIdx = 0; | 
| Douglas Gregor | 8dde14e | 2011-01-24 16:14:37 +0000 | [diff] [blame] | 2620 |   LocalInstantiationScope InstScope(*this, true); | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2621 |   while (Param != ParamEnd) { | 
| Douglas Gregor | 16134c6 | 2009-07-01 00:28:38 +0000 | [diff] [blame] | 2622 |     if (ArgIdx > NumArgs && PartialTemplateArgs) | 
 | 2623 |       break; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 2624 |  | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2625 |     if (ArgIdx < NumArgs) { | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2626 |       // If we have an expanded parameter pack, make sure we don't have too | 
 | 2627 |       // many arguments. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2628 |       if (NonTypeTemplateParmDecl *NTTP | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2629 |                                 = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2630 |         if (NTTP->isExpandedParameterPack() && | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2631 |             ArgumentPack.size() >= NTTP->getNumExpansionTypes()) { | 
 | 2632 |           Diag(TemplateLoc, diag::err_template_arg_list_different_arity) | 
 | 2633 |             << true | 
 | 2634 |             << (isa<ClassTemplateDecl>(Template)? 0 : | 
 | 2635 |                 isa<FunctionTemplateDecl>(Template)? 1 : | 
 | 2636 |                 isa<TemplateTemplateParmDecl>(Template)? 2 : 3) | 
 | 2637 |             << Template; | 
 | 2638 |           Diag(Template->getLocation(), diag::note_template_decl_here) | 
 | 2639 |             << Params->getSourceRange(); | 
 | 2640 |           return true; | 
 | 2641 |         } | 
 | 2642 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2643 |  | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2644 |       // Check the template argument we were given. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2645 |       if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template, | 
 | 2646 |                                 TemplateLoc, RAngleLoc, | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2647 |                                 ArgumentPack.size(), Converted)) | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2648 |         return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2649 |  | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2650 |       if ((*Param)->isTemplateParameterPack()) { | 
 | 2651 |         // The template parameter was a template parameter pack, so take the | 
 | 2652 |         // deduced argument and place it on the argument pack. Note that we | 
 | 2653 |         // stay on the same template parameter so that we can deduce more | 
 | 2654 |         // arguments. | 
 | 2655 |         ArgumentPack.push_back(Converted.back()); | 
 | 2656 |         Converted.pop_back(); | 
 | 2657 |       } else { | 
 | 2658 |         // Move to the next template parameter. | 
 | 2659 |         ++Param; | 
 | 2660 |       } | 
 | 2661 |       ++ArgIdx; | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2662 |       continue; | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 2663 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2664 |  | 
 | 2665 |     // If we have a template parameter pack with no more corresponding | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2666 |     // arguments, just break out now and we'll fill in the argument pack below. | 
 | 2667 |     if ((*Param)->isTemplateParameterPack()) | 
 | 2668 |       break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2669 |  | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2670 |     // We have a default template argument that we will use. | 
 | 2671 |     TemplateArgumentLoc Arg; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2672 |  | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2673 |     // Retrieve the default template argument from the template | 
 | 2674 |     // parameter. For each kind of template parameter, we substitute the | 
 | 2675 |     // template arguments provided thus far and any "outer" template arguments | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2676 |     // (when the template parameter was part of a nested template) into | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2677 |     // the default argument. | 
 | 2678 |     if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) { | 
 | 2679 |       if (!TTP->hasDefaultArgument()) { | 
 | 2680 |         assert((Invalid || PartialTemplateArgs) && "Missing default argument"); | 
 | 2681 |         break; | 
 | 2682 |       } | 
 | 2683 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2684 |       TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(*this, | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2685 |                                                              Template, | 
 | 2686 |                                                              TemplateLoc, | 
 | 2687 |                                                              RAngleLoc, | 
 | 2688 |                                                              TTP, | 
 | 2689 |                                                              Converted); | 
 | 2690 |       if (!ArgType) | 
 | 2691 |         return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2692 |  | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2693 |       Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()), | 
 | 2694 |                                 ArgType); | 
 | 2695 |     } else if (NonTypeTemplateParmDecl *NTTP | 
 | 2696 |                  = dyn_cast<NonTypeTemplateParmDecl>(*Param)) { | 
 | 2697 |       if (!NTTP->hasDefaultArgument()) { | 
 | 2698 |         assert((Invalid || PartialTemplateArgs) && "Missing default argument"); | 
 | 2699 |         break; | 
 | 2700 |       } | 
 | 2701 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 2702 |       ExprResult E = SubstDefaultTemplateArgument(*this, Template, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2703 |                                                               TemplateLoc, | 
 | 2704 |                                                               RAngleLoc, | 
 | 2705 |                                                               NTTP, | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2706 |                                                               Converted); | 
 | 2707 |       if (E.isInvalid()) | 
 | 2708 |         return true; | 
 | 2709 |  | 
 | 2710 |       Expr *Ex = E.takeAs<Expr>(); | 
 | 2711 |       Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex); | 
 | 2712 |     } else { | 
 | 2713 |       TemplateTemplateParmDecl *TempParm | 
 | 2714 |         = cast<TemplateTemplateParmDecl>(*Param); | 
 | 2715 |  | 
 | 2716 |       if (!TempParm->hasDefaultArgument()) { | 
 | 2717 |         assert((Invalid || PartialTemplateArgs) && "Missing default argument"); | 
 | 2718 |         break; | 
 | 2719 |       } | 
 | 2720 |  | 
| Douglas Gregor | 1d752d7 | 2011-03-02 18:46:51 +0000 | [diff] [blame] | 2721 |       NestedNameSpecifierLoc QualifierLoc; | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2722 |       TemplateName Name = SubstDefaultTemplateArgument(*this, Template, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2723 |                                                        TemplateLoc, | 
 | 2724 |                                                        RAngleLoc, | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2725 |                                                        TempParm, | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2726 |                                                        Converted, | 
 | 2727 |                                                        QualifierLoc); | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2728 |       if (Name.isNull()) | 
 | 2729 |         return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2730 |  | 
| Douglas Gregor | b6744ef | 2011-03-02 17:09:35 +0000 | [diff] [blame] | 2731 |       Arg = TemplateArgumentLoc(TemplateArgument(Name), QualifierLoc, | 
 | 2732 |                            TempParm->getDefaultArgument().getTemplateNameLoc()); | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2733 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2734 |  | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2735 |     // Introduce an instantiation record that describes where we are using | 
 | 2736 |     // the default template argument. | 
 | 2737 |     InstantiatingTemplate Instantiating(*this, RAngleLoc, Template, *Param, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 2738 |                                         Converted.data(), Converted.size(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2739 |                                         SourceRange(TemplateLoc, RAngleLoc)); | 
 | 2740 |  | 
| Douglas Gregor | f35f828 | 2009-11-11 21:54:23 +0000 | [diff] [blame] | 2741 |     // Check the default template argument. | 
| Douglas Gregor | d9e1530 | 2009-11-11 19:41:09 +0000 | [diff] [blame] | 2742 |     if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc, | 
| Douglas Gregor | 6952f1e | 2011-01-19 20:10:05 +0000 | [diff] [blame] | 2743 |                               RAngleLoc, 0, Converted)) | 
| Douglas Gregor | e752641 | 2009-11-11 19:31:23 +0000 | [diff] [blame] | 2744 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2745 |  | 
| Douglas Gregor | 6771423 | 2011-03-03 02:41:12 +0000 | [diff] [blame] | 2746 |     // Core issue 150 (assumed resolution): if this is a template template  | 
 | 2747 |     // parameter, keep track of the default template arguments from the  | 
 | 2748 |     // template definition. | 
 | 2749 |     if (isTemplateTemplateParameter) | 
 | 2750 |       TemplateArgs.addArgument(Arg); | 
 | 2751 |      | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2752 |     // Move to the next template parameter and argument. | 
 | 2753 |     ++Param; | 
 | 2754 |     ++ArgIdx; | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2755 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2756 |  | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2757 |   // Form argument packs for each of the parameter packs remaining. | 
 | 2758 |   while (Param != ParamEnd) { | 
| Douglas Gregor | d373119 | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 2759 |     // If we're checking a partial list of template arguments, don't fill | 
 | 2760 |     // in arguments for non-template parameter packs. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2761 |  | 
 | 2762 |     if ((*Param)->isTemplateParameterPack()) { | 
| Douglas Gregor | d373119 | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 2763 |       if (PartialTemplateArgs && ArgumentPack.empty()) { | 
 | 2764 |         Converted.push_back(TemplateArgument()); | 
| Douglas Gregor | 203e6a3 | 2011-01-11 23:09:57 +0000 | [diff] [blame] | 2765 |       } else if (ArgumentPack.empty()) | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2766 |         Converted.push_back(TemplateArgument(0, 0)); | 
| Douglas Gregor | 203e6a3 | 2011-01-11 23:09:57 +0000 | [diff] [blame] | 2767 |       else { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2768 |         Converted.push_back(TemplateArgument::CreatePackCopy(Context, | 
 | 2769 |                                                           ArgumentPack.data(), | 
| Douglas Gregor | 203e6a3 | 2011-01-11 23:09:57 +0000 | [diff] [blame] | 2770 |                                                          ArgumentPack.size())); | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2771 |         ArgumentPack.clear(); | 
 | 2772 |       } | 
 | 2773 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2774 |  | 
| Douglas Gregor | 14be16b | 2010-12-20 16:57:52 +0000 | [diff] [blame] | 2775 |     ++Param; | 
 | 2776 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2777 |  | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 2778 |   return Invalid; | 
 | 2779 | } | 
 | 2780 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2781 | namespace { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2782 |   class UnnamedLocalNoLinkageFinder | 
 | 2783 |     : public TypeVisitor<UnnamedLocalNoLinkageFinder, bool> | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2784 |   { | 
 | 2785 |     Sema &S; | 
 | 2786 |     SourceRange SR; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2787 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2788 |     typedef TypeVisitor<UnnamedLocalNoLinkageFinder, bool> inherited; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2789 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2790 |   public: | 
 | 2791 |     UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { } | 
 | 2792 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2793 |     bool Visit(QualType T) { | 
 | 2794 |       return inherited::Visit(T.getTypePtr()); | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2795 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2796 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2797 | #define TYPE(Class, Parent) \ | 
 | 2798 |     bool Visit##Class##Type(const Class##Type *); | 
 | 2799 | #define ABSTRACT_TYPE(Class, Parent) \ | 
 | 2800 |     bool Visit##Class##Type(const Class##Type *) { return false; } | 
 | 2801 | #define NON_CANONICAL_TYPE(Class, Parent) \ | 
 | 2802 |     bool Visit##Class##Type(const Class##Type *) { return false; } | 
 | 2803 | #include "clang/AST/TypeNodes.def" | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2804 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2805 |     bool VisitTagDecl(const TagDecl *Tag); | 
 | 2806 |     bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS); | 
 | 2807 |   }; | 
 | 2808 | } | 
 | 2809 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2810 | bool UnnamedLocalNoLinkageFinder::VisitBuiltinType(const BuiltinType*) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2811 |   return false; | 
 | 2812 | } | 
 | 2813 |  | 
 | 2814 | bool UnnamedLocalNoLinkageFinder::VisitComplexType(const ComplexType* T) { | 
 | 2815 |   return Visit(T->getElementType()); | 
 | 2816 | } | 
 | 2817 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2818 | bool UnnamedLocalNoLinkageFinder::VisitPointerType(const PointerType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2819 |   return Visit(T->getPointeeType()); | 
 | 2820 | } | 
 | 2821 |  | 
 | 2822 | bool UnnamedLocalNoLinkageFinder::VisitBlockPointerType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2823 |                                                     const BlockPointerType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2824 |   return Visit(T->getPointeeType()); | 
 | 2825 | } | 
 | 2826 |  | 
 | 2827 | bool UnnamedLocalNoLinkageFinder::VisitLValueReferenceType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2828 |                                                 const LValueReferenceType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2829 |   return Visit(T->getPointeeType()); | 
 | 2830 | } | 
 | 2831 |  | 
 | 2832 | bool UnnamedLocalNoLinkageFinder::VisitRValueReferenceType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2833 |                                                 const RValueReferenceType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2834 |   return Visit(T->getPointeeType()); | 
 | 2835 | } | 
 | 2836 |  | 
 | 2837 | bool UnnamedLocalNoLinkageFinder::VisitMemberPointerType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2838 |                                                   const MemberPointerType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2839 |   return Visit(T->getPointeeType()) || Visit(QualType(T->getClass(), 0)); | 
 | 2840 | } | 
 | 2841 |  | 
 | 2842 | bool UnnamedLocalNoLinkageFinder::VisitConstantArrayType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2843 |                                                   const ConstantArrayType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2844 |   return Visit(T->getElementType()); | 
 | 2845 | } | 
 | 2846 |  | 
 | 2847 | bool UnnamedLocalNoLinkageFinder::VisitIncompleteArrayType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2848 |                                                  const IncompleteArrayType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2849 |   return Visit(T->getElementType()); | 
 | 2850 | } | 
 | 2851 |  | 
 | 2852 | bool UnnamedLocalNoLinkageFinder::VisitVariableArrayType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2853 |                                                    const VariableArrayType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2854 |   return Visit(T->getElementType()); | 
 | 2855 | } | 
 | 2856 |  | 
 | 2857 | bool UnnamedLocalNoLinkageFinder::VisitDependentSizedArrayType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2858 |                                             const DependentSizedArrayType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2859 |   return Visit(T->getElementType()); | 
 | 2860 | } | 
 | 2861 |  | 
 | 2862 | bool UnnamedLocalNoLinkageFinder::VisitDependentSizedExtVectorType( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2863 |                                          const DependentSizedExtVectorType* T) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2864 |   return Visit(T->getElementType()); | 
 | 2865 | } | 
 | 2866 |  | 
 | 2867 | bool UnnamedLocalNoLinkageFinder::VisitVectorType(const VectorType* T) { | 
 | 2868 |   return Visit(T->getElementType()); | 
 | 2869 | } | 
 | 2870 |  | 
 | 2871 | bool UnnamedLocalNoLinkageFinder::VisitExtVectorType(const ExtVectorType* T) { | 
 | 2872 |   return Visit(T->getElementType()); | 
 | 2873 | } | 
 | 2874 |  | 
 | 2875 | bool UnnamedLocalNoLinkageFinder::VisitFunctionProtoType( | 
 | 2876 |                                                   const FunctionProtoType* T) { | 
 | 2877 |   for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2878 |                                          AEnd = T->arg_type_end(); | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2879 |        A != AEnd; ++A) { | 
 | 2880 |     if (Visit(*A)) | 
 | 2881 |       return true; | 
 | 2882 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2883 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2884 |   return Visit(T->getResultType()); | 
 | 2885 | } | 
 | 2886 |  | 
 | 2887 | bool UnnamedLocalNoLinkageFinder::VisitFunctionNoProtoType( | 
 | 2888 |                                                const FunctionNoProtoType* T) { | 
 | 2889 |   return Visit(T->getResultType()); | 
 | 2890 | } | 
 | 2891 |  | 
 | 2892 | bool UnnamedLocalNoLinkageFinder::VisitUnresolvedUsingType( | 
 | 2893 |                                                   const UnresolvedUsingType*) { | 
 | 2894 |   return false; | 
 | 2895 | } | 
 | 2896 |  | 
 | 2897 | bool UnnamedLocalNoLinkageFinder::VisitTypeOfExprType(const TypeOfExprType*) { | 
 | 2898 |   return false; | 
 | 2899 | } | 
 | 2900 |  | 
 | 2901 | bool UnnamedLocalNoLinkageFinder::VisitTypeOfType(const TypeOfType* T) { | 
 | 2902 |   return Visit(T->getUnderlyingType()); | 
 | 2903 | } | 
 | 2904 |  | 
 | 2905 | bool UnnamedLocalNoLinkageFinder::VisitDecltypeType(const DecltypeType*) { | 
 | 2906 |   return false; | 
 | 2907 | } | 
 | 2908 |  | 
| Richard Smith | 34b41d9 | 2011-02-20 03:19:35 +0000 | [diff] [blame] | 2909 | bool UnnamedLocalNoLinkageFinder::VisitAutoType(const AutoType *T) { | 
 | 2910 |   return Visit(T->getDeducedType()); | 
 | 2911 | } | 
 | 2912 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2913 | bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* T) { | 
 | 2914 |   return VisitTagDecl(T->getDecl()); | 
 | 2915 | } | 
 | 2916 |  | 
 | 2917 | bool UnnamedLocalNoLinkageFinder::VisitEnumType(const EnumType* T) { | 
 | 2918 |   return VisitTagDecl(T->getDecl()); | 
 | 2919 | } | 
 | 2920 |  | 
 | 2921 | bool UnnamedLocalNoLinkageFinder::VisitTemplateTypeParmType( | 
 | 2922 |                                                  const TemplateTypeParmType*) { | 
 | 2923 |   return false; | 
 | 2924 | } | 
 | 2925 |  | 
| Douglas Gregor | c3069d6 | 2011-01-14 02:55:32 +0000 | [diff] [blame] | 2926 | bool UnnamedLocalNoLinkageFinder::VisitSubstTemplateTypeParmPackType( | 
 | 2927 |                                         const SubstTemplateTypeParmPackType *) { | 
 | 2928 |   return false; | 
 | 2929 | } | 
 | 2930 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2931 | bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType( | 
 | 2932 |                                             const TemplateSpecializationType*) { | 
 | 2933 |   return false; | 
 | 2934 | } | 
 | 2935 |  | 
 | 2936 | bool UnnamedLocalNoLinkageFinder::VisitInjectedClassNameType( | 
 | 2937 |                                               const InjectedClassNameType* T) { | 
 | 2938 |   return VisitTagDecl(T->getDecl()); | 
 | 2939 | } | 
 | 2940 |  | 
 | 2941 | bool UnnamedLocalNoLinkageFinder::VisitDependentNameType( | 
 | 2942 |                                                    const DependentNameType* T) { | 
 | 2943 |   return VisitNestedNameSpecifier(T->getQualifier()); | 
 | 2944 | } | 
 | 2945 |  | 
 | 2946 | bool UnnamedLocalNoLinkageFinder::VisitDependentTemplateSpecializationType( | 
 | 2947 |                                  const DependentTemplateSpecializationType* T) { | 
 | 2948 |   return VisitNestedNameSpecifier(T->getQualifier()); | 
 | 2949 | } | 
 | 2950 |  | 
| Douglas Gregor | 7536dd5 | 2010-12-20 02:24:11 +0000 | [diff] [blame] | 2951 | bool UnnamedLocalNoLinkageFinder::VisitPackExpansionType( | 
 | 2952 |                                                    const PackExpansionType* T) { | 
 | 2953 |   return Visit(T->getPattern()); | 
 | 2954 | } | 
 | 2955 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2956 | bool UnnamedLocalNoLinkageFinder::VisitObjCObjectType(const ObjCObjectType *) { | 
 | 2957 |   return false; | 
 | 2958 | } | 
 | 2959 |  | 
 | 2960 | bool UnnamedLocalNoLinkageFinder::VisitObjCInterfaceType( | 
 | 2961 |                                                    const ObjCInterfaceType *) { | 
 | 2962 |   return false; | 
 | 2963 | } | 
 | 2964 |  | 
 | 2965 | bool UnnamedLocalNoLinkageFinder::VisitObjCObjectPointerType( | 
 | 2966 |                                                 const ObjCObjectPointerType *) { | 
 | 2967 |   return false; | 
 | 2968 | } | 
 | 2969 |  | 
 | 2970 | bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) { | 
 | 2971 |   if (Tag->getDeclContext()->isFunctionOrMethod()) { | 
 | 2972 |     S.Diag(SR.getBegin(), diag::ext_template_arg_local_type) | 
 | 2973 |       << S.Context.getTypeDeclType(Tag) << SR; | 
 | 2974 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2975 |   } | 
 | 2976 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2977 |   if (!Tag->getDeclName() && !Tag->getTypedefForAnonDecl()) { | 
 | 2978 |     S.Diag(SR.getBegin(), diag::ext_template_arg_unnamed_type) << SR; | 
 | 2979 |     S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here); | 
 | 2980 |     return true; | 
 | 2981 |   } | 
 | 2982 |  | 
 | 2983 |   return false; | 
 | 2984 | } | 
 | 2985 |  | 
 | 2986 | bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier( | 
 | 2987 |                                                     NestedNameSpecifier *NNS) { | 
 | 2988 |   if (NNS->getPrefix() && VisitNestedNameSpecifier(NNS->getPrefix())) | 
 | 2989 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2990 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2991 |   switch (NNS->getKind()) { | 
 | 2992 |   case NestedNameSpecifier::Identifier: | 
 | 2993 |   case NestedNameSpecifier::Namespace: | 
| Douglas Gregor | 14aba76 | 2011-02-24 02:36:08 +0000 | [diff] [blame] | 2994 |   case NestedNameSpecifier::NamespaceAlias: | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2995 |   case NestedNameSpecifier::Global: | 
 | 2996 |     return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 2997 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 2998 |   case NestedNameSpecifier::TypeSpec: | 
 | 2999 |   case NestedNameSpecifier::TypeSpecWithTemplate: | 
 | 3000 |     return Visit(QualType(NNS->getAsType(), 0)); | 
 | 3001 |   } | 
| Fariborz Jahanian | 7b1ec6c | 2010-10-13 16:19:16 +0000 | [diff] [blame] | 3002 |   return false; | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 3003 | } | 
 | 3004 |  | 
 | 3005 |  | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 3006 | /// \brief Check a template argument against its corresponding | 
 | 3007 | /// template type parameter. | 
 | 3008 | /// | 
 | 3009 | /// This routine implements the semantics of C++ [temp.arg.type]. It | 
 | 3010 | /// returns true if an error occurred, and false otherwise. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3011 | bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param, | 
| John McCall | a93c934 | 2009-12-07 02:54:59 +0000 | [diff] [blame] | 3012 |                                  TypeSourceInfo *ArgInfo) { | 
 | 3013 |   assert(ArgInfo && "invalid TypeSourceInfo"); | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 3014 |   QualType Arg = ArgInfo->getType(); | 
| Douglas Gregor | 0fddb97 | 2010-05-22 16:17:30 +0000 | [diff] [blame] | 3015 |   SourceRange SR = ArgInfo->getTypeLoc().getSourceRange(); | 
| Chandler Carruth | 17fb855 | 2010-09-03 21:12:34 +0000 | [diff] [blame] | 3016 |  | 
 | 3017 |   if (Arg->isVariablyModifiedType()) { | 
 | 3018 |     return Diag(SR.getBegin(), diag::err_variably_modified_template_arg) << Arg; | 
| Douglas Gregor | 4b52e25 | 2009-12-21 23:17:24 +0000 | [diff] [blame] | 3019 |   } else if (Context.hasSameUnqualifiedType(Arg, Context.OverloadTy)) { | 
| Douglas Gregor | 4b52e25 | 2009-12-21 23:17:24 +0000 | [diff] [blame] | 3020 |     return Diag(SR.getBegin(), diag::err_template_arg_overload_type) << SR; | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 3021 |   } | 
 | 3022 |  | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 3023 |   // C++03 [temp.arg.type]p2: | 
 | 3024 |   //   A local type, a type with no linkage, an unnamed type or a type | 
 | 3025 |   //   compounded from any of these types shall not be used as a | 
 | 3026 |   //   template-argument for a template type-parameter. | 
 | 3027 |   // | 
 | 3028 |   // C++0x allows these, and even in C++03 we allow them as an extension with | 
 | 3029 |   // a warning. | 
| Douglas Gregor | db4d4bb | 2010-10-13 18:05:20 +0000 | [diff] [blame] | 3030 |   if (!LangOpts.CPlusPlus0x && Arg->hasUnnamedOrLocalType()) { | 
| Douglas Gregor | 5f3aeb6 | 2010-10-13 00:27:52 +0000 | [diff] [blame] | 3031 |     UnnamedLocalNoLinkageFinder Finder(*this, SR); | 
 | 3032 |     (void)Finder.Visit(Context.getCanonicalType(Arg)); | 
 | 3033 |   } | 
 | 3034 |  | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 3035 |   return false; | 
 | 3036 | } | 
 | 3037 |  | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3038 | /// \brief Checks whether the given template argument is the address | 
 | 3039 | /// of an object or function according to C++ [temp.arg.nontype]p1. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3040 | static bool | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3041 | CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S, | 
 | 3042 |                                                NonTypeTemplateParmDecl *Param, | 
 | 3043 |                                                QualType ParamType, | 
 | 3044 |                                                Expr *ArgIn, | 
 | 3045 |                                                TemplateArgument &Converted) { | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3046 |   bool Invalid = false; | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3047 |   Expr *Arg = ArgIn; | 
 | 3048 |   QualType ArgType = Arg->getType(); | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3049 |  | 
 | 3050 |   // See through any implicit casts we added to fix the type. | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 3051 |   while (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg)) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3052 |     Arg = Cast->getSubExpr(); | 
 | 3053 |  | 
 | 3054 |   // C++ [temp.arg.nontype]p1: | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3055 |   // | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3056 |   //   A template-argument for a non-type, non-template | 
 | 3057 |   //   template-parameter shall be one of: [...] | 
 | 3058 |   // | 
 | 3059 |   //     -- the address of an object or function with external | 
 | 3060 |   //        linkage, including function templates and function | 
 | 3061 |   //        template-ids but excluding non-static class members, | 
 | 3062 |   //        expressed as & id-expression where the & is optional if | 
 | 3063 |   //        the name refers to a function or array, or if the | 
 | 3064 |   //        corresponding template-parameter is a reference; or | 
 | 3065 |   DeclRefExpr *DRE = 0; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3066 |  | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3067 |   // In C++98/03 mode, give an extension warning on any extra parentheses. | 
 | 3068 |   // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773 | 
 | 3069 |   bool ExtraParens = false; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3070 |   while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) { | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3071 |     if (!Invalid && !ExtraParens && !S.getLangOptions().CPlusPlus0x) { | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3072 |       S.Diag(Arg->getSourceRange().getBegin(), | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3073 |              diag::ext_template_arg_extra_parens) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3074 |         << Arg->getSourceRange(); | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3075 |       ExtraParens = true; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3076 |     } | 
 | 3077 |  | 
 | 3078 |     Arg = Parens->getSubExpr(); | 
 | 3079 |   } | 
 | 3080 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3081 |   bool AddressTaken = false; | 
 | 3082 |   SourceLocation AddrOpLoc; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3083 |   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3084 |     if (UnOp->getOpcode() == UO_AddrOf) { | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3085 |       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr()); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3086 |       AddressTaken = true; | 
 | 3087 |       AddrOpLoc = UnOp->getOperatorLoc(); | 
 | 3088 |     } | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3089 |   } else | 
 | 3090 |     DRE = dyn_cast<DeclRefExpr>(Arg); | 
 | 3091 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3092 |   if (!DRE) { | 
| Douglas Gregor | 1a8cf73 | 2010-04-14 23:11:21 +0000 | [diff] [blame] | 3093 |     S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref) | 
 | 3094 |       << Arg->getSourceRange(); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3095 |     S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3096 |     return true; | 
 | 3097 |   } | 
| Chandler Carruth | 038cc39 | 2010-01-31 10:01:20 +0000 | [diff] [blame] | 3098 |  | 
 | 3099 |   // Stop checking the precise nature of the argument if it is value dependent, | 
 | 3100 |   // it should be checked when instantiated. | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3101 |   if (Arg->isValueDependent()) { | 
| John McCall | 3fa5cae | 2010-10-26 07:05:15 +0000 | [diff] [blame] | 3102 |     Converted = TemplateArgument(ArgIn); | 
| Chandler Carruth | 038cc39 | 2010-01-31 10:01:20 +0000 | [diff] [blame] | 3103 |     return false; | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3104 |   } | 
| Chandler Carruth | 038cc39 | 2010-01-31 10:01:20 +0000 | [diff] [blame] | 3105 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3106 |   if (!isa<ValueDecl>(DRE->getDecl())) { | 
 | 3107 |     S.Diag(Arg->getSourceRange().getBegin(), | 
 | 3108 |            diag::err_template_arg_not_object_or_func_form) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3109 |       << Arg->getSourceRange(); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3110 |     S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3111 |     return true; | 
 | 3112 |   } | 
 | 3113 |  | 
 | 3114 |   NamedDecl *Entity = 0; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3115 |  | 
 | 3116 |   // Cannot refer to non-static data members | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3117 |   if (FieldDecl *Field = dyn_cast<FieldDecl>(DRE->getDecl())) { | 
 | 3118 |     S.Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_field) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3119 |       << Field << Arg->getSourceRange(); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3120 |     S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3121 |     return true; | 
 | 3122 |   } | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3123 |  | 
 | 3124 |   // Cannot refer to non-static member functions | 
 | 3125 |   if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(DRE->getDecl())) | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3126 |     if (!Method->isStatic()) { | 
 | 3127 |       S.Diag(Arg->getSourceRange().getBegin(), diag::err_template_arg_method) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3128 |         << Method << Arg->getSourceRange(); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3129 |       S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3130 |       return true; | 
 | 3131 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3132 |  | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3133 |   // Functions must have external linkage. | 
 | 3134 |   if (FunctionDecl *Func = dyn_cast<FunctionDecl>(DRE->getDecl())) { | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 3135 |     if (!isExternalLinkage(Func->getLinkage())) { | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3136 |       S.Diag(Arg->getSourceRange().getBegin(), | 
 | 3137 |              diag::err_template_arg_function_not_extern) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3138 |         << Func << Arg->getSourceRange(); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3139 |       S.Diag(Func->getLocation(), diag::note_template_arg_internal_object) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3140 |         << true; | 
 | 3141 |       return true; | 
 | 3142 |     } | 
 | 3143 |  | 
 | 3144 |     // Okay: we've named a function with external linkage. | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 3145 |     Entity = Func; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3146 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3147 |     // If the template parameter has pointer type, the function decays. | 
 | 3148 |     if (ParamType->isPointerType() && !AddressTaken) | 
 | 3149 |       ArgType = S.Context.getPointerType(Func->getType()); | 
 | 3150 |     else if (AddressTaken && ParamType->isReferenceType()) { | 
 | 3151 |       // If we originally had an address-of operator, but the | 
 | 3152 |       // parameter has reference type, complain and (if things look | 
 | 3153 |       // like they will work) drop the address-of operator. | 
 | 3154 |       if (!S.Context.hasSameUnqualifiedType(Func->getType(), | 
 | 3155 |                                             ParamType.getNonReferenceType())) { | 
 | 3156 |         S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) | 
 | 3157 |           << ParamType; | 
 | 3158 |         S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3159 |         return true; | 
 | 3160 |       } | 
 | 3161 |  | 
 | 3162 |       S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) | 
 | 3163 |         << ParamType | 
 | 3164 |         << FixItHint::CreateRemoval(AddrOpLoc); | 
 | 3165 |       S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3166 |  | 
 | 3167 |       ArgType = Func->getType(); | 
 | 3168 |     } | 
 | 3169 |   } else if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) { | 
| Douglas Gregor | 0b6bc8b | 2010-02-03 09:33:45 +0000 | [diff] [blame] | 3170 |     if (!isExternalLinkage(Var->getLinkage())) { | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3171 |       S.Diag(Arg->getSourceRange().getBegin(), | 
 | 3172 |              diag::err_template_arg_object_not_extern) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3173 |         << Var << Arg->getSourceRange(); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3174 |       S.Diag(Var->getLocation(), diag::note_template_arg_internal_object) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3175 |         << true; | 
 | 3176 |       return true; | 
 | 3177 |     } | 
 | 3178 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3179 |     // A value of reference type is not an object. | 
 | 3180 |     if (Var->getType()->isReferenceType()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3181 |       S.Diag(Arg->getSourceRange().getBegin(), | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3182 |              diag::err_template_arg_reference_var) | 
 | 3183 |         << Var->getType() << Arg->getSourceRange(); | 
 | 3184 |       S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3185 |       return true; | 
 | 3186 |     } | 
 | 3187 |  | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3188 |     // Okay: we've named an object with external linkage | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 3189 |     Entity = Var; | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3190 |  | 
 | 3191 |     // If the template parameter has pointer type, we must have taken | 
 | 3192 |     // the address of this object. | 
 | 3193 |     if (ParamType->isReferenceType()) { | 
 | 3194 |       if (AddressTaken) { | 
 | 3195 |         // If we originally had an address-of operator, but the | 
 | 3196 |         // parameter has reference type, complain and (if things look | 
 | 3197 |         // like they will work) drop the address-of operator. | 
 | 3198 |         if (!S.Context.hasSameUnqualifiedType(Var->getType(), | 
 | 3199 |                                             ParamType.getNonReferenceType())) { | 
 | 3200 |           S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) | 
 | 3201 |             << ParamType; | 
 | 3202 |           S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3203 |           return true; | 
 | 3204 |         } | 
 | 3205 |  | 
 | 3206 |         S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer) | 
 | 3207 |           << ParamType | 
 | 3208 |           << FixItHint::CreateRemoval(AddrOpLoc); | 
 | 3209 |         S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3210 |  | 
 | 3211 |         ArgType = Var->getType(); | 
 | 3212 |       } | 
 | 3213 |     } else if (!AddressTaken && ParamType->isPointerType()) { | 
 | 3214 |       if (Var->getType()->isArrayType()) { | 
 | 3215 |         // Array-to-pointer decay. | 
 | 3216 |         ArgType = S.Context.getArrayDecayedType(Var->getType()); | 
 | 3217 |       } else { | 
 | 3218 |         // If the template parameter has pointer type but the address of | 
 | 3219 |         // this object was not taken, complain and (possibly) recover by | 
 | 3220 |         // taking the address of the entity. | 
 | 3221 |         ArgType = S.Context.getPointerType(Var->getType()); | 
 | 3222 |         if (!S.Context.hasSameUnqualifiedType(ArgType, ParamType)) { | 
 | 3223 |           S.Diag(Arg->getLocStart(), diag::err_template_arg_not_address_of) | 
 | 3224 |             << ParamType; | 
 | 3225 |           S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3226 |           return true; | 
 | 3227 |         } | 
 | 3228 |  | 
 | 3229 |         S.Diag(Arg->getLocStart(), diag::err_template_arg_not_address_of) | 
 | 3230 |           << ParamType | 
 | 3231 |           << FixItHint::CreateInsertion(Arg->getLocStart(), "&"); | 
 | 3232 |  | 
 | 3233 |         S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3234 |       } | 
 | 3235 |     } | 
 | 3236 |   } else { | 
 | 3237 |     // We found something else, but we don't know specifically what it is. | 
 | 3238 |     S.Diag(Arg->getSourceRange().getBegin(), | 
 | 3239 |            diag::err_template_arg_not_object_or_func) | 
 | 3240 |       << Arg->getSourceRange(); | 
 | 3241 |     S.Diag(DRE->getDecl()->getLocation(), diag::note_template_arg_refers_here); | 
 | 3242 |     return true; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3243 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3244 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3245 |   if (ParamType->isPointerType() && | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3246 |       !ParamType->getAs<PointerType>()->getPointeeType()->isFunctionType() && | 
| Douglas Gregor | 14d0aee | 2011-01-27 00:58:17 +0000 | [diff] [blame] | 3247 |       S.IsQualificationConversion(ArgType, ParamType, false)) { | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3248 |     // For pointer-to-object types, qualification conversions are | 
 | 3249 |     // permitted. | 
 | 3250 |   } else { | 
 | 3251 |     if (const ReferenceType *ParamRef = ParamType->getAs<ReferenceType>()) { | 
 | 3252 |       if (!ParamRef->getPointeeType()->isFunctionType()) { | 
 | 3253 |         // C++ [temp.arg.nontype]p5b3: | 
 | 3254 |         //   For a non-type template-parameter of type reference to | 
 | 3255 |         //   object, no conversions apply. The type referred to by the | 
 | 3256 |         //   reference may be more cv-qualified than the (otherwise | 
 | 3257 |         //   identical) type of the template- argument. The | 
 | 3258 |         //   template-parameter is bound directly to the | 
 | 3259 |         //   template-argument, which shall be an lvalue. | 
 | 3260 |  | 
 | 3261 |         // FIXME: Other qualifiers? | 
 | 3262 |         unsigned ParamQuals = ParamRef->getPointeeType().getCVRQualifiers(); | 
 | 3263 |         unsigned ArgQuals = ArgType.getCVRQualifiers(); | 
 | 3264 |  | 
 | 3265 |         if ((ParamQuals | ArgQuals) != ParamQuals) { | 
 | 3266 |           S.Diag(Arg->getSourceRange().getBegin(), | 
 | 3267 |                  diag::err_template_arg_ref_bind_ignores_quals) | 
 | 3268 |             << ParamType << Arg->getType() | 
 | 3269 |             << Arg->getSourceRange(); | 
 | 3270 |           S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3271 |           return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3272 |         } | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3273 |       } | 
 | 3274 |     } | 
 | 3275 |  | 
 | 3276 |     // At this point, the template argument refers to an object or | 
 | 3277 |     // function with external linkage. We now need to check whether the | 
 | 3278 |     // argument and parameter types are compatible. | 
 | 3279 |     if (!S.Context.hasSameUnqualifiedType(ArgType, | 
 | 3280 |                                           ParamType.getNonReferenceType())) { | 
 | 3281 |       // We can't perform this conversion or binding. | 
 | 3282 |       if (ParamType->isReferenceType()) | 
 | 3283 |         S.Diag(Arg->getLocStart(), diag::err_template_arg_no_ref_bind) | 
 | 3284 |           << ParamType << Arg->getType() << Arg->getSourceRange(); | 
 | 3285 |       else | 
 | 3286 |         S.Diag(Arg->getLocStart(),  diag::err_template_arg_not_convertible) | 
 | 3287 |           << Arg->getType() << ParamType << Arg->getSourceRange(); | 
 | 3288 |       S.Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3289 |       return true; | 
 | 3290 |     } | 
 | 3291 |   } | 
 | 3292 |  | 
 | 3293 |   // Create the template argument. | 
 | 3294 |   Converted = TemplateArgument(Entity->getCanonicalDecl()); | 
| Douglas Gregor | 77c13e0 | 2010-04-24 18:20:53 +0000 | [diff] [blame] | 3295 |   S.MarkDeclarationReferenced(Arg->getLocStart(), Entity); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3296 |   return false; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3297 | } | 
 | 3298 |  | 
 | 3299 | /// \brief Checks whether the given template argument is a pointer to | 
 | 3300 | /// member constant according to C++ [temp.arg.nontype]p1. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3301 | bool Sema::CheckTemplateArgumentPointerToMember(Expr *Arg, | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3302 |                                                 TemplateArgument &Converted) { | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3303 |   bool Invalid = false; | 
 | 3304 |  | 
 | 3305 |   // See through any implicit casts we added to fix the type. | 
| Eli Friedman | 73c39ab | 2009-10-20 08:27:19 +0000 | [diff] [blame] | 3306 |   while (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg)) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3307 |     Arg = Cast->getSubExpr(); | 
 | 3308 |  | 
 | 3309 |   // C++ [temp.arg.nontype]p1: | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3310 |   // | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3311 |   //   A template-argument for a non-type, non-template | 
 | 3312 |   //   template-parameter shall be one of: [...] | 
 | 3313 |   // | 
 | 3314 |   //     -- a pointer to member expressed as described in 5.3.1. | 
| Douglas Gregor | a2813ce | 2009-10-23 18:54:35 +0000 | [diff] [blame] | 3315 |   DeclRefExpr *DRE = 0; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3316 |  | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3317 |   // In C++98/03 mode, give an extension warning on any extra parentheses. | 
 | 3318 |   // See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773 | 
 | 3319 |   bool ExtraParens = false; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3320 |   while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) { | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3321 |     if (!Invalid && !ExtraParens && !getLangOptions().CPlusPlus0x) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3322 |       Diag(Arg->getSourceRange().getBegin(), | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3323 |            diag::ext_template_arg_extra_parens) | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3324 |         << Arg->getSourceRange(); | 
| Abramo Bagnara | 2c5399f | 2010-09-13 06:06:58 +0000 | [diff] [blame] | 3325 |       ExtraParens = true; | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3326 |     } | 
 | 3327 |  | 
 | 3328 |     Arg = Parens->getSubExpr(); | 
 | 3329 |   } | 
 | 3330 |  | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3331 |   // A pointer-to-member constant written &Class::member. | 
 | 3332 |   if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3333 |     if (UnOp->getOpcode() == UO_AddrOf) { | 
| Douglas Gregor | a2813ce | 2009-10-23 18:54:35 +0000 | [diff] [blame] | 3334 |       DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr()); | 
 | 3335 |       if (DRE && !DRE->getQualifier()) | 
 | 3336 |         DRE = 0; | 
 | 3337 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3338 |   } | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3339 |   // A constant of pointer-to-member type. | 
 | 3340 |   else if ((DRE = dyn_cast<DeclRefExpr>(Arg))) { | 
 | 3341 |     if (ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) { | 
 | 3342 |       if (VD->getType()->isMemberPointerType()) { | 
 | 3343 |         if (isa<NonTypeTemplateParmDecl>(VD) || | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3344 |             (isa<VarDecl>(VD) && | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3345 |              Context.getCanonicalType(VD->getType()).isConstQualified())) { | 
 | 3346 |           if (Arg->isTypeDependent() || Arg->isValueDependent()) | 
| John McCall | 3fa5cae | 2010-10-26 07:05:15 +0000 | [diff] [blame] | 3347 |             Converted = TemplateArgument(Arg); | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3348 |           else | 
 | 3349 |             Converted = TemplateArgument(VD->getCanonicalDecl()); | 
 | 3350 |           return Invalid; | 
 | 3351 |         } | 
 | 3352 |       } | 
 | 3353 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3354 |  | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3355 |     DRE = 0; | 
 | 3356 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3357 |  | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3358 |   if (!DRE) | 
 | 3359 |     return Diag(Arg->getSourceRange().getBegin(), | 
 | 3360 |                 diag::err_template_arg_not_pointer_to_member_form) | 
 | 3361 |       << Arg->getSourceRange(); | 
 | 3362 |  | 
 | 3363 |   if (isa<FieldDecl>(DRE->getDecl()) || isa<CXXMethodDecl>(DRE->getDecl())) { | 
 | 3364 |     assert((isa<FieldDecl>(DRE->getDecl()) || | 
 | 3365 |             !cast<CXXMethodDecl>(DRE->getDecl())->isStatic()) && | 
 | 3366 |            "Only non-static member pointers can make it here"); | 
 | 3367 |  | 
 | 3368 |     // Okay: this is the address of a non-static member, and therefore | 
 | 3369 |     // a member pointer constant. | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3370 |     if (Arg->isTypeDependent() || Arg->isValueDependent()) | 
| John McCall | 3fa5cae | 2010-10-26 07:05:15 +0000 | [diff] [blame] | 3371 |       Converted = TemplateArgument(Arg); | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3372 |     else | 
 | 3373 |       Converted = TemplateArgument(DRE->getDecl()->getCanonicalDecl()); | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3374 |     return Invalid; | 
 | 3375 |   } | 
 | 3376 |  | 
 | 3377 |   // We found something else, but we don't know specifically what it is. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3378 |   Diag(Arg->getSourceRange().getBegin(), | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3379 |        diag::err_template_arg_not_pointer_to_member_form) | 
 | 3380 |       << Arg->getSourceRange(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3381 |   Diag(DRE->getDecl()->getLocation(), | 
| Douglas Gregor | cc45cb3 | 2009-02-11 19:52:55 +0000 | [diff] [blame] | 3382 |        diag::note_template_arg_refers_here); | 
 | 3383 |   return true; | 
 | 3384 | } | 
 | 3385 |  | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 3386 | /// \brief Check a template argument against its corresponding | 
 | 3387 | /// non-type template parameter. | 
 | 3388 | /// | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 3389 | /// This routine implements the semantics of C++ [temp.arg.nontype]. | 
 | 3390 | /// It returns true if an error occurred, and false otherwise. \p | 
 | 3391 | /// InstantiatedParamType is the type of the non-type template | 
 | 3392 | /// parameter after it has been instantiated. | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 3393 | /// | 
| Douglas Gregor | 02cbbd2 | 2009-06-11 18:10:32 +0000 | [diff] [blame] | 3394 | /// If no error was detected, Converted receives the converted template argument. | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 3395 | bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3396 |                                  QualType InstantiatedParamType, Expr *&Arg, | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3397 |                                  TemplateArgument &Converted, | 
 | 3398 |                                  CheckTemplateArgumentKind CTAK) { | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 3399 |   SourceLocation StartLoc = Arg->getSourceRange().getBegin(); | 
 | 3400 |  | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3401 |   // If either the parameter has a dependent type or the argument is | 
 | 3402 |   // type-dependent, there's nothing we can check now. | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 3403 |   if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) { | 
 | 3404 |     // FIXME: Produce a cloned, canonical expression? | 
| Douglas Gregor | 02cbbd2 | 2009-06-11 18:10:32 +0000 | [diff] [blame] | 3405 |     Converted = TemplateArgument(Arg); | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3406 |     return false; | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 3407 |   } | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3408 |  | 
 | 3409 |   // C++ [temp.arg.nontype]p5: | 
 | 3410 |   //   The following conversions are performed on each expression used | 
 | 3411 |   //   as a non-type template-argument. If a non-type | 
 | 3412 |   //   template-argument cannot be converted to the type of the | 
 | 3413 |   //   corresponding template-parameter then the program is | 
 | 3414 |   //   ill-formed. | 
 | 3415 |   // | 
 | 3416 |   //     -- for a non-type template-parameter of integral or | 
 | 3417 |   //        enumeration type, integral promotions (4.5) and integral | 
 | 3418 |   //        conversions (4.7) are applied. | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 3419 |   QualType ParamType = InstantiatedParamType; | 
| Douglas Gregor | a35284b | 2009-02-11 00:19:33 +0000 | [diff] [blame] | 3420 |   QualType ArgType = Arg->getType(); | 
| Douglas Gregor | 2ade35e | 2010-06-16 00:17:44 +0000 | [diff] [blame] | 3421 |   if (ParamType->isIntegralOrEnumerationType()) { | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3422 |     // C++ [temp.arg.nontype]p1: | 
 | 3423 |     //   A template-argument for a non-type, non-template | 
 | 3424 |     //   template-parameter shall be one of: | 
 | 3425 |     // | 
 | 3426 |     //     -- an integral constant-expression of integral or enumeration | 
 | 3427 |     //        type; or | 
 | 3428 |     //     -- the name of a non-type template-parameter; or | 
 | 3429 |     SourceLocation NonConstantLoc; | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 3430 |     llvm::APSInt Value; | 
| Douglas Gregor | 2ade35e | 2010-06-16 00:17:44 +0000 | [diff] [blame] | 3431 |     if (!ArgType->isIntegralOrEnumerationType()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3432 |       Diag(Arg->getSourceRange().getBegin(), | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3433 |            diag::err_template_arg_not_integral_or_enumeral) | 
 | 3434 |         << ArgType << Arg->getSourceRange(); | 
 | 3435 |       Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3436 |       return true; | 
 | 3437 |     } else if (!Arg->isValueDependent() && | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 3438 |                !Arg->isIntegerConstantExpr(Value, Context, &NonConstantLoc)) { | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3439 |       Diag(NonConstantLoc, diag::err_template_arg_not_ice) | 
 | 3440 |         << ArgType << Arg->getSourceRange(); | 
 | 3441 |       return true; | 
 | 3442 |     } | 
 | 3443 |  | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3444 |     // From here on out, all we care about are the unqualified forms | 
 | 3445 |     // of the parameter and argument types. | 
 | 3446 |     ParamType = ParamType.getUnqualifiedType(); | 
 | 3447 |     ArgType = ArgType.getUnqualifiedType(); | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3448 |  | 
 | 3449 |     // Try to convert the argument to the parameter's type. | 
| Douglas Gregor | ff52439 | 2009-11-04 21:50:46 +0000 | [diff] [blame] | 3450 |     if (Context.hasSameType(ParamType, ArgType)) { | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3451 |       // Okay: no conversion necessary | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3452 |     } else if (CTAK == CTAK_Deduced) { | 
 | 3453 |       // C++ [temp.deduct.type]p17: | 
 | 3454 |       //   If, in the declaration of a function template with a non-type | 
 | 3455 |       //   template-parameter, the non-type template- parameter is used | 
 | 3456 |       //   in an expression in the function parameter-list and, if the | 
 | 3457 |       //   corresponding template-argument is deduced, the | 
 | 3458 |       //   template-argument type shall match the type of the | 
 | 3459 |       //   template-parameter exactly, except that a template-argument | 
 | 3460 |       //   deduced from an array bound may be of any integral type. | 
 | 3461 |       Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch) | 
 | 3462 |         << ArgType << ParamType; | 
 | 3463 |       Diag(Param->getLocation(), diag::note_template_param_here); | 
| John McCall | daa8e4e | 2010-11-15 09:13:47 +0000 | [diff] [blame] | 3464 |       return true; | 
 | 3465 |     } else if (ParamType->isBooleanType()) { | 
 | 3466 |       // This is an integral-to-boolean conversion. | 
 | 3467 |       ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean); | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3468 |     } else if (IsIntegralPromotion(Arg, ArgType, ParamType) || | 
 | 3469 |                !ParamType->isEnumeralType()) { | 
 | 3470 |       // This is an integral promotion or conversion. | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3471 |       ImpCastExprToType(Arg, ParamType, CK_IntegralCast); | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3472 |     } else { | 
 | 3473 |       // We can't perform this conversion. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3474 |       Diag(Arg->getSourceRange().getBegin(), | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3475 |            diag::err_template_arg_not_convertible) | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 3476 |         << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3477 |       Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3478 |       return true; | 
 | 3479 |     } | 
 | 3480 |  | 
| Douglas Gregor | f80a9d5 | 2009-03-14 00:20:21 +0000 | [diff] [blame] | 3481 |     QualType IntegerType = Context.getCanonicalType(ParamType); | 
| John McCall | 183700f | 2009-09-21 23:43:11 +0000 | [diff] [blame] | 3482 |     if (const EnumType *Enum = IntegerType->getAs<EnumType>()) | 
| Douglas Gregor | 02cbbd2 | 2009-06-11 18:10:32 +0000 | [diff] [blame] | 3483 |       IntegerType = Context.getCanonicalType(Enum->getDecl()->getIntegerType()); | 
| Douglas Gregor | f80a9d5 | 2009-03-14 00:20:21 +0000 | [diff] [blame] | 3484 |  | 
 | 3485 |     if (!Arg->isValueDependent()) { | 
| Douglas Gregor | 1a6e034 | 2010-03-26 02:38:37 +0000 | [diff] [blame] | 3486 |       llvm::APSInt OldValue = Value; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3487 |  | 
 | 3488 |       // Coerce the template argument's value to the value it will have | 
| Douglas Gregor | 1a6e034 | 2010-03-26 02:38:37 +0000 | [diff] [blame] | 3489 |       // based on the template parameter's type. | 
| Douglas Gregor | 0d4fd8e | 2010-03-26 00:39:40 +0000 | [diff] [blame] | 3490 |       unsigned AllowedBits = Context.getTypeSize(IntegerType); | 
| Douglas Gregor | 0d4fd8e | 2010-03-26 00:39:40 +0000 | [diff] [blame] | 3491 |       if (Value.getBitWidth() != AllowedBits) | 
| Jay Foad | 9f71a8f | 2010-12-07 08:25:34 +0000 | [diff] [blame] | 3492 |         Value = Value.extOrTrunc(AllowedBits); | 
| Douglas Gregor | 0d4fd8e | 2010-03-26 00:39:40 +0000 | [diff] [blame] | 3493 |       Value.setIsSigned(IntegerType->isSignedIntegerType()); | 
| Douglas Gregor | 1a6e034 | 2010-03-26 02:38:37 +0000 | [diff] [blame] | 3494 |  | 
 | 3495 |       // Complain if an unsigned parameter received a negative value. | 
 | 3496 |       if (IntegerType->isUnsignedIntegerType() | 
 | 3497 |           && (OldValue.isSigned() && OldValue.isNegative())) { | 
 | 3498 |         Diag(Arg->getSourceRange().getBegin(), diag::warn_template_arg_negative) | 
 | 3499 |           << OldValue.toString(10) << Value.toString(10) << Param->getType() | 
 | 3500 |           << Arg->getSourceRange(); | 
 | 3501 |         Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3502 |       } | 
 | 3503 |  | 
 | 3504 |       // Complain if we overflowed the template parameter's type. | 
 | 3505 |       unsigned RequiredBits; | 
 | 3506 |       if (IntegerType->isUnsignedIntegerType()) | 
 | 3507 |         RequiredBits = OldValue.getActiveBits(); | 
 | 3508 |       else if (OldValue.isUnsigned()) | 
 | 3509 |         RequiredBits = OldValue.getActiveBits() + 1; | 
 | 3510 |       else | 
 | 3511 |         RequiredBits = OldValue.getMinSignedBits(); | 
 | 3512 |       if (RequiredBits > AllowedBits) { | 
 | 3513 |         Diag(Arg->getSourceRange().getBegin(), | 
 | 3514 |              diag::warn_template_arg_too_large) | 
 | 3515 |           << OldValue.toString(10) << Value.toString(10) << Param->getType() | 
 | 3516 |           << Arg->getSourceRange(); | 
 | 3517 |         Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3518 |       } | 
| Douglas Gregor | f80a9d5 | 2009-03-14 00:20:21 +0000 | [diff] [blame] | 3519 |     } | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 3520 |  | 
| Douglas Gregor | 02cbbd2 | 2009-06-11 18:10:32 +0000 | [diff] [blame] | 3521 |     // Add the value of this argument to the list of converted | 
 | 3522 |     // arguments. We use the bitwidth and signedness of the template | 
 | 3523 |     // parameter. | 
 | 3524 |     if (Arg->isValueDependent()) { | 
 | 3525 |       // The argument is value-dependent. Create a new | 
 | 3526 |       // TemplateArgument with the converted expression. | 
 | 3527 |       Converted = TemplateArgument(Arg); | 
 | 3528 |       return false; | 
| Douglas Gregor | 3e00bad | 2009-02-17 01:05:43 +0000 | [diff] [blame] | 3529 |     } | 
 | 3530 |  | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 3531 |     Converted = TemplateArgument(Value, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3532 |                                  ParamType->isEnumeralType() ? ParamType | 
| Douglas Gregor | 02cbbd2 | 2009-06-11 18:10:32 +0000 | [diff] [blame] | 3533 |                                                              : IntegerType); | 
| Douglas Gregor | 6ae5e66 | 2009-02-10 23:36:10 +0000 | [diff] [blame] | 3534 |     return false; | 
 | 3535 |   } | 
| Douglas Gregor | a35284b | 2009-02-11 00:19:33 +0000 | [diff] [blame] | 3536 |  | 
| John McCall | 6bb8017 | 2010-03-30 21:47:33 +0000 | [diff] [blame] | 3537 |   DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction | 
 | 3538 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3539 |   // C++0x [temp.arg.nontype]p5 bullets 2, 4 and 6 permit conversion | 
 | 3540 |   // from a template argument of type std::nullptr_t to a non-type | 
 | 3541 |   // template parameter of type pointer to object, pointer to | 
 | 3542 |   // function, or pointer-to-member, respectively. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3543 |   if (ArgType->isNullPtrType() && | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3544 |       (ParamType->isPointerType() || ParamType->isMemberPointerType())) { | 
 | 3545 |     Converted = TemplateArgument((NamedDecl *)0); | 
 | 3546 |     return false; | 
 | 3547 |   } | 
 | 3548 |  | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3549 |   // Handle pointer-to-function, reference-to-function, and | 
 | 3550 |   // pointer-to-member-function all in (roughly) the same way. | 
 | 3551 |   if (// -- For a non-type template-parameter of type pointer to | 
 | 3552 |       //    function, only the function-to-pointer conversion (4.3) is | 
 | 3553 |       //    applied. If the template-argument represents a set of | 
 | 3554 |       //    overloaded functions (or a pointer to such), the matching | 
 | 3555 |       //    function is selected from the set (13.4). | 
 | 3556 |       (ParamType->isPointerType() && | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 3557 |        ParamType->getAs<PointerType>()->getPointeeType()->isFunctionType()) || | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3558 |       // -- For a non-type template-parameter of type reference to | 
 | 3559 |       //    function, no conversions apply. If the template-argument | 
 | 3560 |       //    represents a set of overloaded functions, the matching | 
 | 3561 |       //    function is selected from the set (13.4). | 
 | 3562 |       (ParamType->isReferenceType() && | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 3563 |        ParamType->getAs<ReferenceType>()->getPointeeType()->isFunctionType()) || | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3564 |       // -- For a non-type template-parameter of type pointer to | 
 | 3565 |       //    member function, no conversions apply. If the | 
 | 3566 |       //    template-argument represents a set of overloaded member | 
 | 3567 |       //    functions, the matching member function is selected from | 
 | 3568 |       //    the set (13.4). | 
 | 3569 |       (ParamType->isMemberPointerType() && | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 3570 |        ParamType->getAs<MemberPointerType>()->getPointeeType() | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3571 |          ->isFunctionType())) { | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3572 |  | 
| Douglas Gregor | 1a8cf73 | 2010-04-14 23:11:21 +0000 | [diff] [blame] | 3573 |     if (Arg->getType() == Context.OverloadTy) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3574 |       if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, ParamType, | 
| Douglas Gregor | 1a8cf73 | 2010-04-14 23:11:21 +0000 | [diff] [blame] | 3575 |                                                                 true, | 
 | 3576 |                                                                 FoundResult)) { | 
 | 3577 |         if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) | 
 | 3578 |           return true; | 
 | 3579 |  | 
 | 3580 |         Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn); | 
 | 3581 |         ArgType = Arg->getType(); | 
 | 3582 |       } else | 
| Douglas Gregor | 48f3bb9 | 2009-02-18 21:56:37 +0000 | [diff] [blame] | 3583 |         return true; | 
| Douglas Gregor | a35284b | 2009-02-11 00:19:33 +0000 | [diff] [blame] | 3584 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3585 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3586 |     if (!ParamType->isMemberPointerType()) | 
 | 3587 |       return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3588 |                                                             ParamType, | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3589 |                                                             Arg, Converted); | 
 | 3590 |  | 
| Douglas Gregor | 14d0aee | 2011-01-27 00:58:17 +0000 | [diff] [blame] | 3591 |     if (IsQualificationConversion(ArgType, ParamType.getNonReferenceType(), | 
 | 3592 |                                   false)) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3593 |       ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3594 |     } else if (!Context.hasSameUnqualifiedType(ArgType, | 
 | 3595 |                                            ParamType.getNonReferenceType())) { | 
| Douglas Gregor | a35284b | 2009-02-11 00:19:33 +0000 | [diff] [blame] | 3596 |       // We can't perform this conversion. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3597 |       Diag(Arg->getSourceRange().getBegin(), | 
| Douglas Gregor | a35284b | 2009-02-11 00:19:33 +0000 | [diff] [blame] | 3598 |            diag::err_template_arg_not_convertible) | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 3599 |         << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); | 
| Douglas Gregor | a35284b | 2009-02-11 00:19:33 +0000 | [diff] [blame] | 3600 |       Diag(Param->getLocation(), diag::note_template_param_here); | 
 | 3601 |       return true; | 
 | 3602 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3603 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3604 |     return CheckTemplateArgumentPointerToMember(Arg, Converted); | 
| Douglas Gregor | a35284b | 2009-02-11 00:19:33 +0000 | [diff] [blame] | 3605 |   } | 
 | 3606 |  | 
| Chris Lattner | fe90de7 | 2009-02-20 21:37:53 +0000 | [diff] [blame] | 3607 |   if (ParamType->isPointerType()) { | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3608 |     //   -- for a non-type template-parameter of type pointer to | 
 | 3609 |     //      object, qualification conversions (4.4) and the | 
 | 3610 |     //      array-to-pointer conversion (4.2) are applied. | 
| Sebastian Redl | 6e8ed16 | 2009-05-10 18:38:11 +0000 | [diff] [blame] | 3611 |     // C++0x also allows a value of std::nullptr_t. | 
| Eli Friedman | 1357869 | 2010-08-05 02:49:48 +0000 | [diff] [blame] | 3612 |     assert(ParamType->getPointeeType()->isIncompleteOrObjectType() && | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3613 |            "Only object pointers allowed here"); | 
| Douglas Gregor | f684e6e | 2009-02-11 00:44:29 +0000 | [diff] [blame] | 3614 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3615 |     return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3616 |                                                           ParamType, | 
 | 3617 |                                                           Arg, Converted); | 
| Douglas Gregor | f684e6e | 2009-02-11 00:44:29 +0000 | [diff] [blame] | 3618 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3619 |  | 
| Ted Kremenek | 6217b80 | 2009-07-29 21:53:49 +0000 | [diff] [blame] | 3620 |   if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) { | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3621 |     //   -- For a non-type template-parameter of type reference to | 
 | 3622 |     //      object, no conversions apply. The type referred to by the | 
 | 3623 |     //      reference may be more cv-qualified than the (otherwise | 
 | 3624 |     //      identical) type of the template-argument. The | 
 | 3625 |     //      template-parameter is bound directly to the | 
 | 3626 |     //      template-argument, which must be an lvalue. | 
| Eli Friedman | 1357869 | 2010-08-05 02:49:48 +0000 | [diff] [blame] | 3627 |     assert(ParamRefType->getPointeeType()->isIncompleteOrObjectType() && | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3628 |            "Only object references allowed here"); | 
| Douglas Gregor | f684e6e | 2009-02-11 00:44:29 +0000 | [diff] [blame] | 3629 |  | 
| Douglas Gregor | 1a8cf73 | 2010-04-14 23:11:21 +0000 | [diff] [blame] | 3630 |     if (Arg->getType() == Context.OverloadTy) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3631 |       if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, | 
 | 3632 |                                                  ParamRefType->getPointeeType(), | 
| Douglas Gregor | 1a8cf73 | 2010-04-14 23:11:21 +0000 | [diff] [blame] | 3633 |                                                                 true, | 
 | 3634 |                                                                 FoundResult)) { | 
 | 3635 |         if (DiagnoseUseOfDecl(Fn, Arg->getSourceRange().getBegin())) | 
 | 3636 |           return true; | 
 | 3637 |  | 
 | 3638 |         Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn); | 
 | 3639 |         ArgType = Arg->getType(); | 
 | 3640 |       } else | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3641 |         return true; | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3642 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3643 |  | 
 | 3644 |     return CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param, | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3645 |                                                           ParamType, | 
 | 3646 |                                                           Arg, Converted); | 
| Douglas Gregor | b86b057 | 2009-02-11 01:18:59 +0000 | [diff] [blame] | 3647 |   } | 
| Douglas Gregor | 658bbb5 | 2009-02-11 16:16:59 +0000 | [diff] [blame] | 3648 |  | 
 | 3649 |   //     -- For a non-type template-parameter of type pointer to data | 
 | 3650 |   //        member, qualification conversions (4.4) are applied. | 
 | 3651 |   assert(ParamType->isMemberPointerType() && "Only pointers to members remain"); | 
 | 3652 |  | 
| Douglas Gregor | 8e6563b | 2009-02-11 18:22:40 +0000 | [diff] [blame] | 3653 |   if (Context.hasSameUnqualifiedType(ParamType, ArgType)) { | 
| Douglas Gregor | 658bbb5 | 2009-02-11 16:16:59 +0000 | [diff] [blame] | 3654 |     // Types match exactly: nothing more to do here. | 
| Douglas Gregor | 14d0aee | 2011-01-27 00:58:17 +0000 | [diff] [blame] | 3655 |   } else if (IsQualificationConversion(ArgType, ParamType, false)) { | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3656 |     ImpCastExprToType(Arg, ParamType, CK_NoOp, CastCategory(Arg)); | 
| Douglas Gregor | 658bbb5 | 2009-02-11 16:16:59 +0000 | [diff] [blame] | 3657 |   } else { | 
 | 3658 |     // We can't perform this conversion. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3659 |     Diag(Arg->getSourceRange().getBegin(), | 
| Douglas Gregor | 658bbb5 | 2009-02-11 16:16:59 +0000 | [diff] [blame] | 3660 |          diag::err_template_arg_not_convertible) | 
| Douglas Gregor | 2943aed | 2009-03-03 04:44:36 +0000 | [diff] [blame] | 3661 |       << Arg->getType() << InstantiatedParamType << Arg->getSourceRange(); | 
| Douglas Gregor | 658bbb5 | 2009-02-11 16:16:59 +0000 | [diff] [blame] | 3662 |     Diag(Param->getLocation(), diag::note_template_param_here); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3663 |     return true; | 
| Douglas Gregor | 658bbb5 | 2009-02-11 16:16:59 +0000 | [diff] [blame] | 3664 |   } | 
 | 3665 |  | 
| Douglas Gregor | caddba0 | 2009-11-12 18:38:13 +0000 | [diff] [blame] | 3666 |   return CheckTemplateArgumentPointerToMember(Arg, Converted); | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 3667 | } | 
 | 3668 |  | 
 | 3669 | /// \brief Check a template argument against its corresponding | 
 | 3670 | /// template template parameter. | 
 | 3671 | /// | 
 | 3672 | /// This routine implements the semantics of C++ [temp.arg.template]. | 
 | 3673 | /// It returns true if an error occurred, and false otherwise. | 
 | 3674 | bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param, | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 3675 |                                  const TemplateArgumentLoc &Arg) { | 
 | 3676 |   TemplateName Name = Arg.getArgument().getAsTemplate(); | 
 | 3677 |   TemplateDecl *Template = Name.getAsTemplateDecl(); | 
 | 3678 |   if (!Template) { | 
 | 3679 |     // Any dependent template name is fine. | 
 | 3680 |     assert(Name.isDependent() && "Non-dependent template isn't a declaration?"); | 
 | 3681 |     return false; | 
 | 3682 |   } | 
| Douglas Gregor | dd0574e | 2009-02-10 00:24:35 +0000 | [diff] [blame] | 3683 |  | 
 | 3684 |   // C++ [temp.arg.template]p1: | 
 | 3685 |   //   A template-argument for a template template-parameter shall be | 
 | 3686 |   //   the name of a class template, expressed as id-expression. Only | 
 | 3687 |   //   primary class templates are considered when matching the | 
 | 3688 |   //   template template argument with the corresponding parameter; | 
 | 3689 |   //   partial specializations are not considered even if their | 
 | 3690 |   //   parameter lists match that of the template template parameter. | 
| Douglas Gregor | ba1ecb5 | 2009-06-12 19:43:02 +0000 | [diff] [blame] | 3691 |   // | 
 | 3692 |   // Note that we also allow template template parameters here, which | 
 | 3693 |   // will happen when we are dealing with, e.g., class template | 
 | 3694 |   // partial specializations. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3695 |   if (!isa<ClassTemplateDecl>(Template) && | 
| Douglas Gregor | ba1ecb5 | 2009-06-12 19:43:02 +0000 | [diff] [blame] | 3696 |       !isa<TemplateTemplateParmDecl>(Template)) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3697 |     assert(isa<FunctionTemplateDecl>(Template) && | 
| Douglas Gregor | dd0574e | 2009-02-10 00:24:35 +0000 | [diff] [blame] | 3698 |            "Only function templates are possible here"); | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 3699 |     Diag(Arg.getLocation(), diag::err_template_arg_not_class_template); | 
| Douglas Gregor | e53060f | 2009-06-25 22:08:12 +0000 | [diff] [blame] | 3700 |     Diag(Template->getLocation(), diag::note_template_arg_refers_here_func) | 
| Douglas Gregor | dd0574e | 2009-02-10 00:24:35 +0000 | [diff] [blame] | 3701 |       << Template; | 
 | 3702 |   } | 
 | 3703 |  | 
 | 3704 |   return !TemplateParameterListsAreEqual(Template->getTemplateParameters(), | 
 | 3705 |                                          Param->getTemplateParameters(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3706 |                                          true, | 
| Douglas Gregor | fb898e1 | 2009-11-12 16:20:59 +0000 | [diff] [blame] | 3707 |                                          TPL_TemplateTemplateArgumentMatch, | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 3708 |                                          Arg.getLocation()); | 
| Douglas Gregor | c15cb38 | 2009-02-09 23:23:08 +0000 | [diff] [blame] | 3709 | } | 
 | 3710 |  | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3711 | /// \brief Given a non-type template argument that refers to a | 
 | 3712 | /// declaration and the type of its corresponding non-type template | 
 | 3713 | /// parameter, produce an expression that properly refers to that | 
 | 3714 | /// declaration. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3715 | ExprResult | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3716 | Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg, | 
 | 3717 |                                               QualType ParamType, | 
 | 3718 |                                               SourceLocation Loc) { | 
 | 3719 |   assert(Arg.getKind() == TemplateArgument::Declaration && | 
 | 3720 |          "Only declaration template arguments permitted here"); | 
 | 3721 |   ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl()); | 
 | 3722 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3723 |   if (VD->getDeclContext()->isRecord() && | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3724 |       (isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD))) { | 
 | 3725 |     // If the value is a class member, we might have a pointer-to-member. | 
 | 3726 |     // Determine whether the non-type template template parameter is of | 
 | 3727 |     // pointer-to-member type. If so, we need to build an appropriate | 
 | 3728 |     // expression for a pointer-to-member, since a "normal" DeclRefExpr | 
 | 3729 |     // would refer to the member itself. | 
 | 3730 |     if (ParamType->isMemberPointerType()) { | 
 | 3731 |       QualType ClassType | 
 | 3732 |         = Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext())); | 
 | 3733 |       NestedNameSpecifier *Qualifier | 
| John McCall | 9ae2f07 | 2010-08-23 23:25:46 +0000 | [diff] [blame] | 3734 |         = NestedNameSpecifier::Create(Context, 0, false, | 
 | 3735 |                                       ClassType.getTypePtr()); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3736 |       CXXScopeSpec SS; | 
| Douglas Gregor | c34348a | 2011-02-24 17:54:50 +0000 | [diff] [blame] | 3737 |       SS.MakeTrivial(Context, Qualifier, Loc); | 
| John McCall | dfa1edb | 2010-11-23 20:48:44 +0000 | [diff] [blame] | 3738 |  | 
 | 3739 |       // The actual value-ness of this is unimportant, but for | 
 | 3740 |       // internal consistency's sake, references to instance methods | 
 | 3741 |       // are r-values. | 
 | 3742 |       ExprValueKind VK = VK_LValue; | 
 | 3743 |       if (isa<CXXMethodDecl>(VD) && cast<CXXMethodDecl>(VD)->isInstance()) | 
 | 3744 |         VK = VK_RValue; | 
 | 3745 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3746 |       ExprResult RefExpr = BuildDeclRefExpr(VD, | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3747 |                                             VD->getType().getNonReferenceType(), | 
| John McCall | dfa1edb | 2010-11-23 20:48:44 +0000 | [diff] [blame] | 3748 |                                             VK, | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3749 |                                             Loc, | 
 | 3750 |                                             &SS); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3751 |       if (RefExpr.isInvalid()) | 
 | 3752 |         return ExprError(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3753 |  | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3754 |       RefExpr = CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3755 |  | 
| Douglas Gregor | c0c8300 | 2010-04-30 21:46:38 +0000 | [diff] [blame] | 3756 |       // We might need to perform a trailing qualification conversion, since | 
 | 3757 |       // the element type on the parameter could be more qualified than the | 
 | 3758 |       // element type in the expression we constructed. | 
 | 3759 |       if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(), | 
| Douglas Gregor | 14d0aee | 2011-01-27 00:58:17 +0000 | [diff] [blame] | 3760 |                                     ParamType.getUnqualifiedType(), false)) { | 
| Douglas Gregor | c0c8300 | 2010-04-30 21:46:38 +0000 | [diff] [blame] | 3761 |         Expr *RefE = RefExpr.takeAs<Expr>(); | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3762 |         ImpCastExprToType(RefE, ParamType.getUnqualifiedType(), CK_NoOp); | 
| Douglas Gregor | c0c8300 | 2010-04-30 21:46:38 +0000 | [diff] [blame] | 3763 |         RefExpr = Owned(RefE); | 
 | 3764 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3765 |  | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3766 |       assert(!RefExpr.isInvalid() && | 
 | 3767 |              Context.hasSameType(((Expr*) RefExpr.get())->getType(), | 
| Douglas Gregor | c0c8300 | 2010-04-30 21:46:38 +0000 | [diff] [blame] | 3768 |                                  ParamType.getUnqualifiedType())); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3769 |       return move(RefExpr); | 
 | 3770 |     } | 
 | 3771 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3772 |  | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3773 |   QualType T = VD->getType().getNonReferenceType(); | 
 | 3774 |   if (ParamType->isPointerType()) { | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3775 |     // When the non-type template parameter is a pointer, take the | 
 | 3776 |     // address of the declaration. | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3777 |     ExprResult RefExpr = BuildDeclRefExpr(VD, T, VK_LValue, Loc); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3778 |     if (RefExpr.isInvalid()) | 
 | 3779 |       return ExprError(); | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3780 |  | 
 | 3781 |     if (T->isFunctionType() || T->isArrayType()) { | 
 | 3782 |       // Decay functions and arrays. | 
 | 3783 |       Expr *RefE = (Expr *)RefExpr.get(); | 
 | 3784 |       DefaultFunctionArrayConversion(RefE); | 
 | 3785 |       if (RefE != RefExpr.get()) { | 
 | 3786 |         RefExpr.release(); | 
 | 3787 |         RefExpr = Owned(RefE); | 
 | 3788 |       } | 
 | 3789 |  | 
 | 3790 |       return move(RefExpr); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3791 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3792 |  | 
| Douglas Gregor | b7a0926 | 2010-04-01 18:32:35 +0000 | [diff] [blame] | 3793 |     // Take the address of everything else | 
| John McCall | 2de56d1 | 2010-08-25 11:45:40 +0000 | [diff] [blame] | 3794 |     return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get()); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3795 |   } | 
 | 3796 |  | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3797 |   ExprValueKind VK = VK_RValue; | 
 | 3798 |  | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3799 |   // If the non-type template parameter has reference type, qualify the | 
 | 3800 |   // resulting declaration reference with the extra qualifiers on the | 
 | 3801 |   // type that the reference refers to. | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3802 |   if (const ReferenceType *TargetRef = ParamType->getAs<ReferenceType>()) { | 
 | 3803 |     VK = VK_LValue; | 
 | 3804 |     T = Context.getQualifiedType(T, | 
 | 3805 |                               TargetRef->getPointeeType().getQualifiers()); | 
 | 3806 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3807 |  | 
| John McCall | f89e55a | 2010-11-18 06:31:45 +0000 | [diff] [blame] | 3808 |   return BuildDeclRefExpr(VD, T, VK, Loc); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3809 | } | 
 | 3810 |  | 
 | 3811 | /// \brief Construct a new expression that refers to the given | 
 | 3812 | /// integral template argument with the given source-location | 
 | 3813 | /// information. | 
 | 3814 | /// | 
 | 3815 | /// This routine takes care of the mapping from an integral template | 
 | 3816 | /// argument (which may have any integral type) to the appropriate | 
 | 3817 | /// literal value. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3818 | ExprResult | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3819 | Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg, | 
 | 3820 |                                                   SourceLocation Loc) { | 
 | 3821 |   assert(Arg.getKind() == TemplateArgument::Integral && | 
| Douglas Gregor | d373119 | 2011-01-10 07:32:04 +0000 | [diff] [blame] | 3822 |          "Operation is only valid for integral template arguments"); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3823 |   QualType T = Arg.getIntegralType(); | 
 | 3824 |   if (T->isCharType() || T->isWideCharType()) | 
 | 3825 |     return Owned(new (Context) CharacterLiteral( | 
 | 3826 |                                              Arg.getAsIntegral()->getZExtValue(), | 
 | 3827 |                                              T->isWideCharType(), | 
 | 3828 |                                              T, | 
 | 3829 |                                              Loc)); | 
 | 3830 |   if (T->isBooleanType()) | 
 | 3831 |     return Owned(new (Context) CXXBoolLiteralExpr( | 
 | 3832 |                                             Arg.getAsIntegral()->getBoolValue(), | 
 | 3833 |                                             T, | 
 | 3834 |                                             Loc)); | 
 | 3835 |  | 
| Peter Collingbourne | fb7b363 | 2010-12-15 15:06:14 +0000 | [diff] [blame] | 3836 |   QualType BT; | 
 | 3837 |   if (const EnumType *ET = T->getAs<EnumType>()) | 
 | 3838 |     BT = ET->getDecl()->getPromotionType(); | 
 | 3839 |   else | 
 | 3840 |     BT = T; | 
 | 3841 |  | 
 | 3842 |   Expr *E = IntegerLiteral::Create(Context, *Arg.getAsIntegral(), BT, Loc); | 
| Douglas Gregor | 8f5667d | 2011-02-18 02:12:44 +0000 | [diff] [blame] | 3843 |   if (T->isEnumeralType()) { | 
 | 3844 |     // FIXME: This is a hack. We need a better way to handle substituted | 
 | 3845 |     // non-type template parameters. | 
 | 3846 |     E = CStyleCastExpr::Create(Context, T, VK_RValue, CK_IntegralCast, | 
 | 3847 |                                       E, 0,  | 
 | 3848 |                                       Context.getTrivialTypeSourceInfo(T, Loc), | 
 | 3849 |                                       Loc, Loc); | 
 | 3850 |   } | 
 | 3851 |    | 
| Peter Collingbourne | fb7b363 | 2010-12-15 15:06:14 +0000 | [diff] [blame] | 3852 |   return Owned(E); | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3853 | } | 
 | 3854 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3855 | /// \brief Match two template parameters within template parameter lists. | 
 | 3856 | static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old, | 
 | 3857 |                                        bool Complain, | 
 | 3858 |                                      Sema::TemplateParameterListEqualKind Kind, | 
 | 3859 |                                        SourceLocation TemplateArgLoc) { | 
 | 3860 |   // Check the actual kind (type, non-type, template). | 
 | 3861 |   if (Old->getKind() != New->getKind()) { | 
 | 3862 |     if (Complain) { | 
 | 3863 |       unsigned NextDiag = diag::err_template_param_different_kind; | 
 | 3864 |       if (TemplateArgLoc.isValid()) { | 
 | 3865 |         S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch); | 
 | 3866 |         NextDiag = diag::note_template_param_different_kind; | 
 | 3867 |       } | 
 | 3868 |       S.Diag(New->getLocation(), NextDiag) | 
 | 3869 |         << (Kind != Sema::TPL_TemplateMatch); | 
 | 3870 |       S.Diag(Old->getLocation(), diag::note_template_prev_declaration) | 
 | 3871 |         << (Kind != Sema::TPL_TemplateMatch); | 
 | 3872 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3873 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3874 |     return false; | 
 | 3875 |   } | 
 | 3876 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3877 |   // Check that both are parameter packs are neither are parameter packs. | 
 | 3878 |   // However, if we are matching a template template argument to a | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 3879 |   // template template parameter, the template template parameter can have | 
 | 3880 |   // a parameter pack where the template template argument does not. | 
 | 3881 |   if (Old->isTemplateParameterPack() != New->isTemplateParameterPack() && | 
 | 3882 |       !(Kind == Sema::TPL_TemplateTemplateArgumentMatch && | 
 | 3883 |         Old->isTemplateParameterPack())) { | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3884 |     if (Complain) { | 
 | 3885 |       unsigned NextDiag = diag::err_template_parameter_pack_non_pack; | 
 | 3886 |       if (TemplateArgLoc.isValid()) { | 
 | 3887 |         S.Diag(TemplateArgLoc, | 
 | 3888 |              diag::err_template_arg_template_params_mismatch); | 
 | 3889 |         NextDiag = diag::note_template_parameter_pack_non_pack; | 
 | 3890 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3891 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3892 |       unsigned ParamKind = isa<TemplateTypeParmDecl>(New)? 0 | 
 | 3893 |                       : isa<NonTypeTemplateParmDecl>(New)? 1 | 
 | 3894 |                       : 2; | 
 | 3895 |       S.Diag(New->getLocation(), NextDiag) | 
 | 3896 |         << ParamKind << New->isParameterPack(); | 
 | 3897 |       S.Diag(Old->getLocation(), diag::note_template_parameter_pack_here) | 
 | 3898 |         << ParamKind << Old->isParameterPack(); | 
 | 3899 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3900 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3901 |     return false; | 
 | 3902 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3903 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3904 |   // For non-type template parameters, check the type of the parameter. | 
 | 3905 |   if (NonTypeTemplateParmDecl *OldNTTP | 
 | 3906 |                                     = dyn_cast<NonTypeTemplateParmDecl>(Old)) { | 
 | 3907 |     NonTypeTemplateParmDecl *NewNTTP = cast<NonTypeTemplateParmDecl>(New); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3908 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3909 |     // If we are matching a template template argument to a template | 
 | 3910 |     // template parameter and one of the non-type template parameter types | 
 | 3911 |     // is dependent, then we must wait until template instantiation time | 
 | 3912 |     // to actually compare the arguments. | 
 | 3913 |     if (Kind == Sema::TPL_TemplateTemplateArgumentMatch && | 
 | 3914 |         (OldNTTP->getType()->isDependentType() || | 
 | 3915 |          NewNTTP->getType()->isDependentType())) | 
 | 3916 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3917 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3918 |     if (!S.Context.hasSameType(OldNTTP->getType(), NewNTTP->getType())) { | 
 | 3919 |       if (Complain) { | 
 | 3920 |         unsigned NextDiag = diag::err_template_nontype_parm_different_type; | 
 | 3921 |         if (TemplateArgLoc.isValid()) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3922 |           S.Diag(TemplateArgLoc, | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3923 |                  diag::err_template_arg_template_params_mismatch); | 
 | 3924 |           NextDiag = diag::note_template_nontype_parm_different_type; | 
 | 3925 |         } | 
 | 3926 |         S.Diag(NewNTTP->getLocation(), NextDiag) | 
 | 3927 |           << NewNTTP->getType() | 
 | 3928 |           << (Kind != Sema::TPL_TemplateMatch); | 
 | 3929 |         S.Diag(OldNTTP->getLocation(), | 
 | 3930 |                diag::note_template_nontype_parm_prev_declaration) | 
 | 3931 |           << OldNTTP->getType(); | 
 | 3932 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3933 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3934 |       return false; | 
 | 3935 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3936 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3937 |     return true; | 
 | 3938 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3939 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3940 |   // For template template parameters, check the template parameter types. | 
 | 3941 |   // The template parameter lists of template template | 
 | 3942 |   // parameters must agree. | 
 | 3943 |   if (TemplateTemplateParmDecl *OldTTP | 
 | 3944 |                                     = dyn_cast<TemplateTemplateParmDecl>(Old)) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3945 |     TemplateTemplateParmDecl *NewTTP = cast<TemplateTemplateParmDecl>(New); | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3946 |     return S.TemplateParameterListsAreEqual(NewTTP->getTemplateParameters(), | 
 | 3947 |                                             OldTTP->getTemplateParameters(), | 
 | 3948 |                                             Complain, | 
 | 3949 |                                         (Kind == Sema::TPL_TemplateMatch | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3950 |                                            ? Sema::TPL_TemplateTemplateParmMatch | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3951 |                                            : Kind), | 
 | 3952 |                                             TemplateArgLoc); | 
 | 3953 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3954 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 3955 |   return true; | 
 | 3956 | } | 
| Douglas Gregor | 02024a9 | 2010-03-28 02:42:43 +0000 | [diff] [blame] | 3957 |  | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 3958 | /// \brief Diagnose a known arity mismatch when comparing template argument | 
 | 3959 | /// lists. | 
 | 3960 | static | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 3961 | void DiagnoseTemplateParameterListArityMismatch(Sema &S, | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 3962 |                                                 TemplateParameterList *New, | 
 | 3963 |                                                 TemplateParameterList *Old, | 
 | 3964 |                                       Sema::TemplateParameterListEqualKind Kind, | 
 | 3965 |                                                 SourceLocation TemplateArgLoc) { | 
 | 3966 |   unsigned NextDiag = diag::err_template_param_list_different_arity; | 
 | 3967 |   if (TemplateArgLoc.isValid()) { | 
 | 3968 |     S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch); | 
 | 3969 |     NextDiag = diag::note_template_param_list_different_arity; | 
 | 3970 |   } | 
 | 3971 |   S.Diag(New->getTemplateLoc(), NextDiag) | 
 | 3972 |     << (New->size() > Old->size()) | 
 | 3973 |     << (Kind != Sema::TPL_TemplateMatch) | 
 | 3974 |     << SourceRange(New->getTemplateLoc(), New->getRAngleLoc()); | 
 | 3975 |   S.Diag(Old->getTemplateLoc(), diag::note_template_prev_declaration) | 
 | 3976 |     << (Kind != Sema::TPL_TemplateMatch) | 
 | 3977 |     << SourceRange(Old->getTemplateLoc(), Old->getRAngleLoc()); | 
 | 3978 | } | 
 | 3979 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 3980 | /// \brief Determine whether the given template parameter lists are | 
 | 3981 | /// equivalent. | 
 | 3982 | /// | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 3983 | /// \param New  The new template parameter list, typically written in the | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 3984 | /// source code as part of a new template declaration. | 
 | 3985 | /// | 
 | 3986 | /// \param Old  The old template parameter list, typically found via | 
 | 3987 | /// name lookup of the template declared with this template parameter | 
 | 3988 | /// list. | 
 | 3989 | /// | 
 | 3990 | /// \param Complain  If true, this routine will produce a diagnostic if | 
 | 3991 | /// the template parameter lists are not equivalent. | 
 | 3992 | /// | 
| Douglas Gregor | fb898e1 | 2009-11-12 16:20:59 +0000 | [diff] [blame] | 3993 | /// \param Kind describes how we are to match the template parameter lists. | 
| Douglas Gregor | dd0574e | 2009-02-10 00:24:35 +0000 | [diff] [blame] | 3994 | /// | 
 | 3995 | /// \param TemplateArgLoc If this source location is valid, then we | 
 | 3996 | /// are actually checking the template parameter list of a template | 
 | 3997 | /// argument (New) against the template parameter list of its | 
 | 3998 | /// corresponding template template parameter (Old). We produce | 
 | 3999 | /// slightly different diagnostics in this scenario. | 
 | 4000 | /// | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4001 | /// \returns True if the template parameter lists are equal, false | 
 | 4002 | /// otherwise. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4003 | bool | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4004 | Sema::TemplateParameterListsAreEqual(TemplateParameterList *New, | 
 | 4005 |                                      TemplateParameterList *Old, | 
 | 4006 |                                      bool Complain, | 
| Douglas Gregor | fb898e1 | 2009-11-12 16:20:59 +0000 | [diff] [blame] | 4007 |                                      TemplateParameterListEqualKind Kind, | 
| Douglas Gregor | dd0574e | 2009-02-10 00:24:35 +0000 | [diff] [blame] | 4008 |                                      SourceLocation TemplateArgLoc) { | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4009 |   if (Old->size() != New->size() && Kind != TPL_TemplateTemplateArgumentMatch) { | 
 | 4010 |     if (Complain) | 
 | 4011 |       DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, | 
 | 4012 |                                                  TemplateArgLoc); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4013 |  | 
 | 4014 |     return false; | 
 | 4015 |   } | 
 | 4016 |  | 
| Douglas Gregor | ab7ddf0 | 2011-01-12 23:45:44 +0000 | [diff] [blame] | 4017 |   // C++0x [temp.arg.template]p3: | 
 | 4018 |   //   A template-argument matches a template template-parameter (call it P) | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 4019 |   //   when each of the template parameters in the template-parameter-list of | 
 | 4020 |   //   the template-argument's corresponding class template or template alias | 
 | 4021 |   //   (call it A) matches the corresponding template parameter in the | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4022 |   //   template-parameter-list of P. [...] | 
 | 4023 |   TemplateParameterList::iterator NewParm = New->begin(); | 
 | 4024 |   TemplateParameterList::iterator NewParmEnd = New->end(); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4025 |   for (TemplateParameterList::iterator OldParm = Old->begin(), | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4026 |                                     OldParmEnd = Old->end(); | 
 | 4027 |        OldParm != OldParmEnd; ++OldParm) { | 
| Douglas Gregor | c421f54 | 2011-01-13 18:47:47 +0000 | [diff] [blame] | 4028 |     if (Kind != TPL_TemplateTemplateArgumentMatch || | 
 | 4029 |         !(*OldParm)->isTemplateParameterPack()) { | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4030 |       if (NewParm == NewParmEnd) { | 
 | 4031 |         if (Complain) | 
 | 4032 |           DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, | 
 | 4033 |                                                      TemplateArgLoc); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4034 |  | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4035 |         return false; | 
 | 4036 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4037 |  | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4038 |       if (!MatchTemplateParameterKind(*this, *NewParm, *OldParm, Complain, | 
 | 4039 |                                       Kind, TemplateArgLoc)) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4040 |         return false; | 
 | 4041 |  | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4042 |       ++NewParm; | 
 | 4043 |       continue; | 
 | 4044 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4045 |  | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4046 |     // C++0x [temp.arg.template]p3: | 
| NAKAMURA Takumi | 0099530 | 2011-01-27 07:09:49 +0000 | [diff] [blame] | 4047 |     //   [...] When P's template- parameter-list contains a template parameter | 
 | 4048 |     //   pack (14.5.3), the template parameter pack will match zero or more | 
 | 4049 |     //   template parameters or template parameter packs in the | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4050 |     //   template-parameter-list of A with the same type and form as the | 
 | 4051 |     //   template parameter pack in P (ignoring whether those template | 
 | 4052 |     //   parameters are template parameter packs). | 
 | 4053 |     for (; NewParm != NewParmEnd; ++NewParm) { | 
 | 4054 |       if (!MatchTemplateParameterKind(*this, *NewParm, *OldParm, Complain, | 
 | 4055 |                                       Kind, TemplateArgLoc)) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4056 |         return false; | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4057 |     } | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4058 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4059 |  | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4060 |   // Make sure we exhausted all of the arguments. | 
 | 4061 |   if (NewParm != NewParmEnd) { | 
 | 4062 |     if (Complain) | 
 | 4063 |       DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind, | 
 | 4064 |                                                  TemplateArgLoc); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4065 |  | 
| Douglas Gregor | a034782 | 2011-01-13 00:08:50 +0000 | [diff] [blame] | 4066 |     return false; | 
 | 4067 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4068 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4069 |   return true; | 
 | 4070 | } | 
 | 4071 |  | 
 | 4072 | /// \brief Check whether a template can be declared within this scope. | 
 | 4073 | /// | 
 | 4074 | /// If the template declaration is valid in this scope, returns | 
 | 4075 | /// false. Otherwise, issues a diagnostic and returns true. | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4076 | bool | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4077 | Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) { | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4078 |   // Find the nearest enclosing declaration scope. | 
 | 4079 |   while ((S->getFlags() & Scope::DeclScope) == 0 || | 
 | 4080 |          (S->getFlags() & Scope::TemplateParamScope) != 0) | 
 | 4081 |     S = S->getParent(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4082 |  | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4083 |   // C++ [temp]p2: | 
 | 4084 |   //   A template-declaration can appear only as a namespace scope or | 
 | 4085 |   //   class scope declaration. | 
 | 4086 |   DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity()); | 
| Eli Friedman | 1503f77 | 2009-07-31 01:43:05 +0000 | [diff] [blame] | 4087 |   if (Ctx && isa<LinkageSpecDecl>(Ctx) && | 
 | 4088 |       cast<LinkageSpecDecl>(Ctx)->getLanguage() != LinkageSpecDecl::lang_cxx) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4089 |     return Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage) | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4090 |              << TemplateParams->getSourceRange(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4091 |  | 
| Eli Friedman | 1503f77 | 2009-07-31 01:43:05 +0000 | [diff] [blame] | 4092 |   while (Ctx && isa<LinkageSpecDecl>(Ctx)) | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4093 |     Ctx = Ctx->getParent(); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4094 |  | 
 | 4095 |   if (Ctx && (Ctx->isFileContext() || Ctx->isRecord())) | 
 | 4096 |     return false; | 
 | 4097 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4098 |   return Diag(TemplateParams->getTemplateLoc(), | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4099 |               diag::err_template_outside_namespace_or_class_scope) | 
 | 4100 |     << TemplateParams->getSourceRange(); | 
| Douglas Gregor | ddc29e1 | 2009-02-06 22:42:48 +0000 | [diff] [blame] | 4101 | } | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4102 |  | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4103 | /// \brief Determine what kind of template specialization the given declaration | 
 | 4104 | /// is. | 
 | 4105 | static TemplateSpecializationKind getTemplateSpecializationKind(NamedDecl *D) { | 
 | 4106 |   if (!D) | 
 | 4107 |     return TSK_Undeclared; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4108 |  | 
| Douglas Gregor | f6b1185 | 2009-10-08 15:14:33 +0000 | [diff] [blame] | 4109 |   if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) | 
 | 4110 |     return Record->getTemplateSpecializationKind(); | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4111 |   if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D)) | 
 | 4112 |     return Function->getTemplateSpecializationKind(); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 4113 |   if (VarDecl *Var = dyn_cast<VarDecl>(D)) | 
 | 4114 |     return Var->getTemplateSpecializationKind(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4115 |  | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4116 |   return TSK_Undeclared; | 
 | 4117 | } | 
 | 4118 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4119 | /// \brief Check whether a specialization is well-formed in the current | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4120 | /// context. | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4121 | /// | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4122 | /// This routine determines whether a template specialization can be declared | 
 | 4123 | /// in the current context (C++ [temp.expl.spec]p2). | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4124 | /// | 
 | 4125 | /// \param S the semantic analysis object for which this check is being | 
 | 4126 | /// performed. | 
 | 4127 | /// | 
 | 4128 | /// \param Specialized the entity being specialized or instantiated, which | 
 | 4129 | /// may be a kind of template (class template, function template, etc.) or | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4130 | /// a member of a class template (member function, static data member, | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4131 | /// member class). | 
 | 4132 | /// | 
 | 4133 | /// \param PrevDecl the previous declaration of this entity, if any. | 
 | 4134 | /// | 
 | 4135 | /// \param Loc the location of the explicit specialization or instantiation of | 
 | 4136 | /// this entity. | 
 | 4137 | /// | 
 | 4138 | /// \param IsPartialSpecialization whether this is a partial specialization of | 
 | 4139 | /// a class template. | 
 | 4140 | /// | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4141 | /// \returns true if there was an error that we cannot recover from, false | 
 | 4142 | /// otherwise. | 
 | 4143 | static bool CheckTemplateSpecializationScope(Sema &S, | 
 | 4144 |                                              NamedDecl *Specialized, | 
 | 4145 |                                              NamedDecl *PrevDecl, | 
 | 4146 |                                              SourceLocation Loc, | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4147 |                                              bool IsPartialSpecialization) { | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4148 |   // Keep these "kind" numbers in sync with the %select statements in the | 
 | 4149 |   // various diagnostics emitted by this routine. | 
 | 4150 |   int EntityKind = 0; | 
| Ted Kremenek | fe62b06 | 2011-01-14 22:31:36 +0000 | [diff] [blame] | 4151 |   if (isa<ClassTemplateDecl>(Specialized)) | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4152 |     EntityKind = IsPartialSpecialization? 1 : 0; | 
| Ted Kremenek | fe62b06 | 2011-01-14 22:31:36 +0000 | [diff] [blame] | 4153 |   else if (isa<FunctionTemplateDecl>(Specialized)) | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4154 |     EntityKind = 2; | 
| Ted Kremenek | fe62b06 | 2011-01-14 22:31:36 +0000 | [diff] [blame] | 4155 |   else if (isa<CXXMethodDecl>(Specialized)) | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4156 |     EntityKind = 3; | 
 | 4157 |   else if (isa<VarDecl>(Specialized)) | 
 | 4158 |     EntityKind = 4; | 
 | 4159 |   else if (isa<RecordDecl>(Specialized)) | 
 | 4160 |     EntityKind = 5; | 
 | 4161 |   else { | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4162 |     S.Diag(Loc, diag::err_template_spec_unknown_kind); | 
 | 4163 |     S.Diag(Specialized->getLocation(), diag::note_specialized_entity); | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4164 |     return true; | 
 | 4165 |   } | 
 | 4166 |  | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4167 |   // C++ [temp.expl.spec]p2: | 
 | 4168 |   //   An explicit specialization shall be declared in the namespace | 
 | 4169 |   //   of which the template is a member, or, for member templates, in | 
 | 4170 |   //   the namespace of which the enclosing class or enclosing class | 
 | 4171 |   //   template is a member. An explicit specialization of a member | 
 | 4172 |   //   function, member class or static data member of a class | 
 | 4173 |   //   template shall be declared in the namespace of which the class | 
 | 4174 |   //   template is a member. Such a declaration may also be a | 
 | 4175 |   //   definition. If the declaration is not a definition, the | 
 | 4176 |   //   specialization may be defined later in the name- space in which | 
 | 4177 |   //   the explicit specialization was declared, or in a namespace | 
 | 4178 |   //   that encloses the one in which the explicit specialization was | 
 | 4179 |   //   declared. | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 4180 |   if (S.CurContext->getRedeclContext()->isFunctionOrMethod()) { | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4181 |     S.Diag(Loc, diag::err_template_spec_decl_function_scope) | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4182 |       << Specialized; | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4183 |     return true; | 
 | 4184 |   } | 
| Douglas Gregor | 7974c3b | 2009-10-07 17:21:34 +0000 | [diff] [blame] | 4185 |  | 
| Douglas Gregor | 0a40747 | 2009-10-07 17:30:37 +0000 | [diff] [blame] | 4186 |   if (S.CurContext->isRecord() && !IsPartialSpecialization) { | 
 | 4187 |     S.Diag(Loc, diag::err_template_spec_decl_class_scope) | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4188 |       << Specialized; | 
| Douglas Gregor | 0a40747 | 2009-10-07 17:30:37 +0000 | [diff] [blame] | 4189 |     return true; | 
 | 4190 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4191 |  | 
| Douglas Gregor | 7974c3b | 2009-10-07 17:21:34 +0000 | [diff] [blame] | 4192 |   // C++ [temp.class.spec]p6: | 
 | 4193 |   //   A class template partial specialization may be declared or redeclared | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4194 |   //   in any namespace scope in which its definition may be defined (14.5.1 | 
 | 4195 |   //   and 14.5.2). | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4196 |   bool ComplainedAboutScope = false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4197 |   DeclContext *SpecializedContext | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4198 |     = Specialized->getDeclContext()->getEnclosingNamespaceContext(); | 
| Douglas Gregor | 7974c3b | 2009-10-07 17:21:34 +0000 | [diff] [blame] | 4199 |   DeclContext *DC = S.CurContext->getEnclosingNamespaceContext(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4200 |   if ((!PrevDecl || | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4201 |        getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared || | 
 | 4202 |        getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){ | 
| Douglas Gregor | 121dc9a | 2010-09-12 05:08:28 +0000 | [diff] [blame] | 4203 |     // C++ [temp.exp.spec]p2: | 
 | 4204 |     //   An explicit specialization shall be declared in the namespace of which | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4205 |     //   the template is a member, or, for member templates, in the namespace | 
| Douglas Gregor | 121dc9a | 2010-09-12 05:08:28 +0000 | [diff] [blame] | 4206 |     //   of which the enclosing class or enclosing class template is a member. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4207 |     //   An explicit specialization of a member function, member class or | 
 | 4208 |     //   static data member of a class template shall be declared in the | 
| Douglas Gregor | 121dc9a | 2010-09-12 05:08:28 +0000 | [diff] [blame] | 4209 |     //   namespace of which the class template is a member. | 
 | 4210 |     // | 
 | 4211 |     // C++0x [temp.expl.spec]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4212 |     //   An explicit specialization shall be declared in a namespace enclosing | 
| Douglas Gregor | 121dc9a | 2010-09-12 05:08:28 +0000 | [diff] [blame] | 4213 |     //   the specialized template. | 
 | 4214 |     if (!DC->InEnclosingNamespaceSetOf(SpecializedContext) && | 
 | 4215 |         !(S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext))) { | 
| Douglas Gregor | a4d5de5 | 2010-09-12 05:24:55 +0000 | [diff] [blame] | 4216 |       bool IsCPlusPlus0xExtension | 
 | 4217 |         = !S.getLangOptions().CPlusPlus0x && DC->Encloses(SpecializedContext); | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4218 |       if (isa<TranslationUnitDecl>(SpecializedContext)) | 
| Douglas Gregor | a4d5de5 | 2010-09-12 05:24:55 +0000 | [diff] [blame] | 4219 |         S.Diag(Loc, IsCPlusPlus0xExtension | 
 | 4220 |                       ? diag::ext_template_spec_decl_out_of_scope_global | 
 | 4221 |                       : diag::err_template_spec_decl_out_of_scope_global) | 
 | 4222 |           << EntityKind << Specialized; | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4223 |       else if (isa<NamespaceDecl>(SpecializedContext)) | 
| Douglas Gregor | a4d5de5 | 2010-09-12 05:24:55 +0000 | [diff] [blame] | 4224 |         S.Diag(Loc, IsCPlusPlus0xExtension | 
 | 4225 |                       ? diag::ext_template_spec_decl_out_of_scope | 
 | 4226 |                       : diag::err_template_spec_decl_out_of_scope) | 
 | 4227 |           << EntityKind << Specialized | 
 | 4228 |           << cast<NamedDecl>(SpecializedContext); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4229 |  | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4230 |       S.Diag(Specialized->getLocation(), diag::note_specialized_entity); | 
 | 4231 |       ComplainedAboutScope = true; | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4232 |     } | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4233 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4234 |  | 
 | 4235 |   // Make sure that this redeclaration (or definition) occurs in an enclosing | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4236 |   // namespace. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4237 |   // Note that HandleDeclarator() performs this check for explicit | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4238 |   // specializations of function templates, static data members, and member | 
 | 4239 |   // functions, so we skip the check here for those kinds of entities. | 
 | 4240 |   // FIXME: HandleDeclarator's diagnostics aren't quite as good, though. | 
| Douglas Gregor | 7974c3b | 2009-10-07 17:21:34 +0000 | [diff] [blame] | 4241 |   // Should we refactor that check, so that it occurs later? | 
 | 4242 |   if (!ComplainedAboutScope && !DC->Encloses(SpecializedContext) && | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4243 |       !(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) || | 
 | 4244 |         isa<FunctionDecl>(Specialized))) { | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4245 |     if (isa<TranslationUnitDecl>(SpecializedContext)) | 
 | 4246 |       S.Diag(Loc, diag::err_template_spec_redecl_global_scope) | 
 | 4247 |         << EntityKind << Specialized; | 
 | 4248 |     else if (isa<NamespaceDecl>(SpecializedContext)) | 
 | 4249 |       S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope) | 
 | 4250 |         << EntityKind << Specialized | 
 | 4251 |         << cast<NamedDecl>(SpecializedContext); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4252 |  | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4253 |     S.Diag(Specialized->getLocation(), diag::note_specialized_entity); | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4254 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4255 |  | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 4256 |   // FIXME: check for specialization-after-instantiation errors and such. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4257 |  | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4258 |   return false; | 
 | 4259 | } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4260 |  | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4261 | /// \brief Subroutine of Sema::CheckClassTemplatePartialSpecializationArgs | 
 | 4262 | /// that checks non-type template partial specialization arguments. | 
 | 4263 | static bool CheckNonTypeClassTemplatePartialSpecializationArgs(Sema &S, | 
 | 4264 |                                                 NonTypeTemplateParmDecl *Param, | 
 | 4265 |                                                   const TemplateArgument *Args, | 
 | 4266 |                                                         unsigned NumArgs) { | 
 | 4267 |   for (unsigned I = 0; I != NumArgs; ++I) { | 
 | 4268 |     if (Args[I].getKind() == TemplateArgument::Pack) { | 
 | 4269 |       if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4270 |                                                            Args[I].pack_begin(), | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4271 |                                                            Args[I].pack_size())) | 
 | 4272 |         return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4273 |  | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4274 |       continue; | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4275 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4276 |  | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4277 |     Expr *ArgExpr = Args[I].getAsExpr(); | 
| Douglas Gregor | 6aa75cf | 2009-06-12 22:08:06 +0000 | [diff] [blame] | 4278 |     if (!ArgExpr) { | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4279 |       continue; | 
| Douglas Gregor | 6aa75cf | 2009-06-12 22:08:06 +0000 | [diff] [blame] | 4280 |     } | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4281 |  | 
| Douglas Gregor | 7a21fd4 | 2011-01-03 21:37:45 +0000 | [diff] [blame] | 4282 |     // We can have a pack expansion of any of the bullets below. | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4283 |     if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(ArgExpr)) | 
 | 4284 |       ArgExpr = Expansion->getPattern(); | 
| Douglas Gregor | 54c53cc | 2011-01-04 23:35:54 +0000 | [diff] [blame] | 4285 |  | 
 | 4286 |     // Strip off any implicit casts we added as part of type checking. | 
 | 4287 |     while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr)) | 
 | 4288 |       ArgExpr = ICE->getSubExpr(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4289 |  | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4290 |     // C++ [temp.class.spec]p8: | 
 | 4291 |     //   A non-type argument is non-specialized if it is the name of a | 
 | 4292 |     //   non-type parameter. All other non-type arguments are | 
 | 4293 |     //   specialized. | 
 | 4294 |     // | 
 | 4295 |     // Below, we check the two conditions that only apply to | 
 | 4296 |     // specialized non-type arguments, so skip any non-specialized | 
 | 4297 |     // arguments. | 
 | 4298 |     if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr)) | 
| Douglas Gregor | 54c53cc | 2011-01-04 23:35:54 +0000 | [diff] [blame] | 4299 |       if (isa<NonTypeTemplateParmDecl>(DRE->getDecl())) | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4300 |         continue; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4301 |  | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4302 |     // C++ [temp.class.spec]p9: | 
 | 4303 |     //   Within the argument list of a class template partial | 
 | 4304 |     //   specialization, the following restrictions apply: | 
 | 4305 |     //     -- A partially specialized non-type argument expression | 
 | 4306 |     //        shall not involve a template parameter of the partial | 
 | 4307 |     //        specialization except when the argument expression is a | 
 | 4308 |     //        simple identifier. | 
 | 4309 |     if (ArgExpr->isTypeDependent() || ArgExpr->isValueDependent()) { | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4310 |       S.Diag(ArgExpr->getLocStart(), | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4311 |            diag::err_dependent_non_type_arg_in_partial_spec) | 
 | 4312 |         << ArgExpr->getSourceRange(); | 
 | 4313 |       return true; | 
 | 4314 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4315 |  | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4316 |     //     -- The type of a template parameter corresponding to a | 
 | 4317 |     //        specialized non-type argument shall not be dependent on a | 
 | 4318 |     //        parameter of the specialization. | 
 | 4319 |     if (Param->getType()->isDependentType()) { | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4320 |       S.Diag(ArgExpr->getLocStart(), | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4321 |            diag::err_dependent_typed_non_type_arg_in_partial_spec) | 
 | 4322 |         << Param->getType() | 
 | 4323 |         << ArgExpr->getSourceRange(); | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4324 |       S.Diag(Param->getLocation(), diag::note_template_param_here); | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4325 |       return true; | 
 | 4326 |     } | 
 | 4327 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4328 |  | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4329 |   return false; | 
 | 4330 | } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4331 |  | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4332 | /// \brief Check the non-type template arguments of a class template | 
 | 4333 | /// partial specialization according to C++ [temp.class.spec]p9. | 
 | 4334 | /// | 
 | 4335 | /// \param TemplateParams the template parameters of the primary class | 
 | 4336 | /// template. | 
 | 4337 | /// | 
 | 4338 | /// \param TemplateArg the template arguments of the class template | 
 | 4339 | /// partial specialization. | 
 | 4340 | /// | 
 | 4341 | /// \returns true if there was an error, false otherwise. | 
 | 4342 | static bool CheckClassTemplatePartialSpecializationArgs(Sema &S, | 
 | 4343 |                                         TemplateParameterList *TemplateParams, | 
 | 4344 |                        llvm::SmallVectorImpl<TemplateArgument> &TemplateArgs) { | 
 | 4345 |   const TemplateArgument *ArgList = TemplateArgs.data(); | 
 | 4346 |  | 
 | 4347 |   for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) { | 
 | 4348 |     NonTypeTemplateParmDecl *Param | 
 | 4349 |       = dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I)); | 
 | 4350 |     if (!Param) | 
 | 4351 |       continue; | 
 | 4352 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4353 |     if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param, | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4354 |                                                            &ArgList[I], 1)) | 
 | 4355 |       return true; | 
 | 4356 |   } | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4357 |  | 
 | 4358 |   return false; | 
 | 4359 | } | 
 | 4360 |  | 
| Douglas Gregor | dc0a11c | 2010-02-26 06:03:23 +0000 | [diff] [blame] | 4361 | /// \brief Retrieve the previous declaration of the given declaration. | 
 | 4362 | static NamedDecl *getPreviousDecl(NamedDecl *ND) { | 
 | 4363 |   if (VarDecl *VD = dyn_cast<VarDecl>(ND)) | 
 | 4364 |     return VD->getPreviousDeclaration(); | 
 | 4365 |   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) | 
 | 4366 |     return FD->getPreviousDeclaration(); | 
 | 4367 |   if (TagDecl *TD = dyn_cast<TagDecl>(ND)) | 
 | 4368 |     return TD->getPreviousDeclaration(); | 
 | 4369 |   if (TypedefDecl *TD = dyn_cast<TypedefDecl>(ND)) | 
 | 4370 |     return TD->getPreviousDeclaration(); | 
 | 4371 |   if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND)) | 
 | 4372 |     return FTD->getPreviousDeclaration(); | 
 | 4373 |   if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND)) | 
 | 4374 |     return CTD->getPreviousDeclaration(); | 
 | 4375 |   return 0; | 
 | 4376 | } | 
 | 4377 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4378 | DeclResult | 
| John McCall | 0f434ec | 2009-07-31 02:45:11 +0000 | [diff] [blame] | 4379 | Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec, | 
 | 4380 |                                        TagUseKind TUK, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4381 |                                        SourceLocation KWLoc, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 4382 |                                        CXXScopeSpec &SS, | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 4383 |                                        TemplateTy TemplateD, | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4384 |                                        SourceLocation TemplateNameLoc, | 
 | 4385 |                                        SourceLocation LAngleLoc, | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 4386 |                                        ASTTemplateArgsPtr TemplateArgsIn, | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4387 |                                        SourceLocation RAngleLoc, | 
 | 4388 |                                        AttributeList *Attr, | 
 | 4389 |                                MultiTemplateParamsArg TemplateParameterLists) { | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4390 |   assert(TUK != TUK_Reference && "References are not specializations"); | 
| John McCall | f1bbbb4 | 2009-09-04 01:14:41 +0000 | [diff] [blame] | 4391 |  | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4392 |   // Find the class template we're specializing | 
| Douglas Gregor | 7532dc6 | 2009-03-30 22:58:21 +0000 | [diff] [blame] | 4393 |   TemplateName Name = TemplateD.getAsVal<TemplateName>(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4394 |   ClassTemplateDecl *ClassTemplate | 
| Douglas Gregor | 8b13c08 | 2009-11-12 00:46:20 +0000 | [diff] [blame] | 4395 |     = dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl()); | 
 | 4396 |  | 
 | 4397 |   if (!ClassTemplate) { | 
 | 4398 |     Diag(TemplateNameLoc, diag::err_not_class_template_specialization) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4399 |       << (Name.getAsTemplateDecl() && | 
| Douglas Gregor | 8b13c08 | 2009-11-12 00:46:20 +0000 | [diff] [blame] | 4400 |           isa<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())); | 
 | 4401 |     return true; | 
 | 4402 |   } | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4403 |  | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 4404 |   bool isExplicitSpecialization = false; | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4405 |   bool isPartialSpecialization = false; | 
 | 4406 |  | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4407 |   // Check the validity of the template headers that introduce this | 
 | 4408 |   // template. | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4409 |   // FIXME: We probably shouldn't complain about these headers for | 
 | 4410 |   // friend declarations. | 
| Douglas Gregor | 0167f3c | 2010-07-14 23:14:12 +0000 | [diff] [blame] | 4411 |   bool Invalid = false; | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4412 |   TemplateParameterList *TemplateParams | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4413 |     = MatchTemplateParametersToScopeSpecifier(TemplateNameLoc, SS, | 
 | 4414 |                         (TemplateParameterList**)TemplateParameterLists.get(), | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 4415 |                                               TemplateParameterLists.size(), | 
| John McCall | 77e8b11 | 2010-04-13 20:37:33 +0000 | [diff] [blame] | 4416 |                                               TUK == TUK_Friend, | 
| Douglas Gregor | 0167f3c | 2010-07-14 23:14:12 +0000 | [diff] [blame] | 4417 |                                               isExplicitSpecialization, | 
 | 4418 |                                               Invalid); | 
 | 4419 |   if (Invalid) | 
 | 4420 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4421 |  | 
| Abramo Bagnara | 9b93488 | 2010-06-12 08:15:14 +0000 | [diff] [blame] | 4422 |   unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size(); | 
 | 4423 |   if (TemplateParams) | 
 | 4424 |     --NumMatchedTemplateParamLists; | 
 | 4425 |  | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4426 |   if (TemplateParams && TemplateParams->size() > 0) { | 
 | 4427 |     isPartialSpecialization = true; | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4428 |  | 
| Douglas Gregor | b0ee93c | 2010-12-21 08:14:57 +0000 | [diff] [blame] | 4429 |     if (TUK == TUK_Friend) { | 
 | 4430 |       Diag(KWLoc, diag::err_partial_specialization_friend) | 
 | 4431 |         << SourceRange(LAngleLoc, RAngleLoc); | 
 | 4432 |       return true; | 
 | 4433 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4434 |  | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4435 |     // C++ [temp.class.spec]p10: | 
 | 4436 |     //   The template parameter list of a specialization shall not | 
 | 4437 |     //   contain default template argument values. | 
 | 4438 |     for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) { | 
 | 4439 |       Decl *Param = TemplateParams->getParam(I); | 
 | 4440 |       if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) { | 
 | 4441 |         if (TTP->hasDefaultArgument()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4442 |           Diag(TTP->getDefaultArgumentLoc(), | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4443 |                diag::err_default_arg_in_partial_spec); | 
| John McCall | 833ca99 | 2009-10-29 08:12:44 +0000 | [diff] [blame] | 4444 |           TTP->removeDefaultArgument(); | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4445 |         } | 
 | 4446 |       } else if (NonTypeTemplateParmDecl *NTTP | 
 | 4447 |                    = dyn_cast<NonTypeTemplateParmDecl>(Param)) { | 
 | 4448 |         if (Expr *DefArg = NTTP->getDefaultArgument()) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4449 |           Diag(NTTP->getDefaultArgumentLoc(), | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4450 |                diag::err_default_arg_in_partial_spec) | 
 | 4451 |             << DefArg->getSourceRange(); | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 4452 |           NTTP->removeDefaultArgument(); | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4453 |         } | 
 | 4454 |       } else { | 
 | 4455 |         TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param); | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 4456 |         if (TTP->hasDefaultArgument()) { | 
 | 4457 |           Diag(TTP->getDefaultArgument().getLocation(), | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4458 |                diag::err_default_arg_in_partial_spec) | 
| Douglas Gregor | 788cd06 | 2009-11-11 01:00:40 +0000 | [diff] [blame] | 4459 |             << TTP->getDefaultArgument().getSourceRange(); | 
| Abramo Bagnara | d92f7a2 | 2010-06-09 09:26:05 +0000 | [diff] [blame] | 4460 |           TTP->removeDefaultArgument(); | 
| Douglas Gregor | ba1ecb5 | 2009-06-12 19:43:02 +0000 | [diff] [blame] | 4461 |         } | 
 | 4462 |       } | 
 | 4463 |     } | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 4464 |   } else if (TemplateParams) { | 
 | 4465 |     if (TUK == TUK_Friend) | 
 | 4466 |       Diag(KWLoc, diag::err_template_spec_friend) | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 4467 |         << FixItHint::CreateRemoval( | 
| Douglas Gregor | a735b20 | 2009-10-13 14:39:41 +0000 | [diff] [blame] | 4468 |                                 SourceRange(TemplateParams->getTemplateLoc(), | 
 | 4469 |                                             TemplateParams->getRAngleLoc())) | 
 | 4470 |         << SourceRange(LAngleLoc, RAngleLoc); | 
 | 4471 |     else | 
 | 4472 |       isExplicitSpecialization = true; | 
 | 4473 |   } else if (TUK != TUK_Friend) { | 
| Douglas Gregor | 05396e2 | 2009-08-25 17:23:04 +0000 | [diff] [blame] | 4474 |     Diag(KWLoc, diag::err_template_spec_needs_header) | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 4475 |       << FixItHint::CreateInsertion(KWLoc, "template<> "); | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 4476 |     isExplicitSpecialization = true; | 
 | 4477 |   } | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4478 |  | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4479 |   // Check that the specialization uses the same tag kind as the | 
 | 4480 |   // original template. | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 4481 |   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); | 
 | 4482 |   assert(Kind != TTK_Enum && "Invalid enum tag in class template spec!"); | 
| Douglas Gregor | 501c5ce | 2009-05-14 16:41:31 +0000 | [diff] [blame] | 4483 |   if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4484 |                                     Kind, KWLoc, | 
| Douglas Gregor | 501c5ce | 2009-05-14 16:41:31 +0000 | [diff] [blame] | 4485 |                                     *ClassTemplate->getIdentifier())) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4486 |     Diag(KWLoc, diag::err_use_with_wrong_tag) | 
| Douglas Gregor | a3a8351 | 2009-04-01 23:51:29 +0000 | [diff] [blame] | 4487 |       << ClassTemplate | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 4488 |       << FixItHint::CreateReplacement(KWLoc, | 
| Douglas Gregor | a3a8351 | 2009-04-01 23:51:29 +0000 | [diff] [blame] | 4489 |                             ClassTemplate->getTemplatedDecl()->getKindName()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4490 |     Diag(ClassTemplate->getTemplatedDecl()->getLocation(), | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4491 |          diag::note_previous_use); | 
 | 4492 |     Kind = ClassTemplate->getTemplatedDecl()->getTagKind(); | 
 | 4493 |   } | 
 | 4494 |  | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 4495 |   // Translate the parser's template argument list in our AST format. | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 4496 |   TemplateArgumentListInfo TemplateArgs; | 
 | 4497 |   TemplateArgs.setLAngleLoc(LAngleLoc); | 
 | 4498 |   TemplateArgs.setRAngleLoc(RAngleLoc); | 
| Douglas Gregor | 314b97f | 2009-11-10 19:49:08 +0000 | [diff] [blame] | 4499 |   translateTemplateArguments(TemplateArgsIn, TemplateArgs); | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 4500 |  | 
| Douglas Gregor | 925910d | 2011-01-03 20:35:03 +0000 | [diff] [blame] | 4501 |   // Check for unexpanded parameter packs in any of the template arguments. | 
 | 4502 |   for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4503 |     if (DiagnoseUnexpandedParameterPack(TemplateArgs[I], | 
| Douglas Gregor | 925910d | 2011-01-03 20:35:03 +0000 | [diff] [blame] | 4504 |                                         UPPC_PartialSpecialization)) | 
 | 4505 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4506 |  | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4507 |   // Check that the template argument list is well-formed for this | 
 | 4508 |   // template. | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 4509 |   llvm::SmallVector<TemplateArgument, 4> Converted; | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 4510 |   if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, | 
 | 4511 |                                 TemplateArgs, false, Converted)) | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 4512 |     return true; | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4513 |  | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 4514 |   assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) && | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4515 |          "Converted template argument list is too short!"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4516 |  | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4517 |   // Find the class template (partial) specialization declaration that | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4518 |   // corresponds to these arguments. | 
| Douglas Gregor | ba1ecb5 | 2009-06-12 19:43:02 +0000 | [diff] [blame] | 4519 |   if (isPartialSpecialization) { | 
| Douglas Gregor | bacb949 | 2011-01-03 21:13:47 +0000 | [diff] [blame] | 4520 |     if (CheckClassTemplatePartialSpecializationArgs(*this, | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4521 |                                          ClassTemplate->getTemplateParameters(), | 
| Douglas Gregor | b9c6631 | 2010-12-23 17:13:55 +0000 | [diff] [blame] | 4522 |                                          Converted)) | 
| Douglas Gregor | e94866f | 2009-06-12 21:21:02 +0000 | [diff] [blame] | 4523 |       return true; | 
 | 4524 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4525 |     if (!Name.isDependent() && | 
| Douglas Gregor | de09096 | 2010-02-09 00:37:32 +0000 | [diff] [blame] | 4526 |         !TemplateSpecializationType::anyDependentTemplateArguments( | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4527 |                                              TemplateArgs.getArgumentArray(), | 
| Douglas Gregor | de09096 | 2010-02-09 00:37:32 +0000 | [diff] [blame] | 4528 |                                                          TemplateArgs.size())) { | 
 | 4529 |       Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized) | 
 | 4530 |         << ClassTemplate->getDeclName(); | 
 | 4531 |       isPartialSpecialization = false; | 
| Douglas Gregor | de09096 | 2010-02-09 00:37:32 +0000 | [diff] [blame] | 4532 |     } | 
 | 4533 |   } | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 4534 |  | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4535 |   void *InsertPos = 0; | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4536 |   ClassTemplateSpecializationDecl *PrevDecl = 0; | 
 | 4537 |  | 
 | 4538 |   if (isPartialSpecialization) | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 4539 |     // FIXME: Template parameter list matters, too | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4540 |     PrevDecl | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 4541 |       = ClassTemplate->findPartialSpecialization(Converted.data(), | 
 | 4542 |                                                  Converted.size(), | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 4543 |                                                  InsertPos); | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4544 |   else | 
 | 4545 |     PrevDecl | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 4546 |       = ClassTemplate->findSpecialization(Converted.data(), | 
 | 4547 |                                           Converted.size(), InsertPos); | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4548 |  | 
 | 4549 |   ClassTemplateSpecializationDecl *Specialization = 0; | 
 | 4550 |  | 
| Douglas Gregor | 88b7094 | 2009-02-25 22:02:03 +0000 | [diff] [blame] | 4551 |   // Check whether we can declare a class template specialization in | 
 | 4552 |   // the current scope. | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4553 |   if (TUK != TUK_Friend && | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4554 |       CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl, | 
 | 4555 |                                        TemplateNameLoc, | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 4556 |                                        isPartialSpecialization)) | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 4557 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4558 |  | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 4559 |   // The canonical type | 
 | 4560 |   QualType CanonType; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4561 |   if (PrevDecl && | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4562 |       (PrevDecl->getSpecializationKind() == TSK_Undeclared || | 
| Douglas Gregor | de09096 | 2010-02-09 00:37:32 +0000 | [diff] [blame] | 4563 |                TUK == TUK_Friend)) { | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4564 |     // Since the only prior class template specialization with these | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4565 |     // arguments was referenced but not declared, or we're only | 
 | 4566 |     // referencing this specialization as a friend, reuse that | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4567 |     // declaration node as our own, updating its source location to | 
 | 4568 |     // reflect our new declaration. | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4569 |     Specialization = PrevDecl; | 
| Douglas Gregor | 6bc9f7e | 2009-02-25 22:18:32 +0000 | [diff] [blame] | 4570 |     Specialization->setLocation(TemplateNameLoc); | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4571 |     PrevDecl = 0; | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 4572 |     CanonType = Context.getTypeDeclType(Specialization); | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4573 |   } else if (isPartialSpecialization) { | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 4574 |     // Build the canonical type that describes the converted template | 
 | 4575 |     // arguments of the class template partial specialization. | 
| Douglas Gregor | de09096 | 2010-02-09 00:37:32 +0000 | [diff] [blame] | 4576 |     TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name); | 
 | 4577 |     CanonType = Context.getTemplateSpecializationType(CanonTemplate, | 
| Douglas Gregor | b9c6631 | 2010-12-23 17:13:55 +0000 | [diff] [blame] | 4578 |                                                       Converted.data(), | 
 | 4579 |                                                       Converted.size()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4580 |  | 
 | 4581 |     if (Context.hasSameType(CanonType, | 
| Douglas Gregor | b9c6631 | 2010-12-23 17:13:55 +0000 | [diff] [blame] | 4582 |                         ClassTemplate->getInjectedClassNameSpecialization())) { | 
 | 4583 |       // C++ [temp.class.spec]p9b3: | 
 | 4584 |       // | 
 | 4585 |       //   -- The argument list of the specialization shall not be identical | 
 | 4586 |       //      to the implicit argument list of the primary template. | 
 | 4587 |       Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template) | 
 | 4588 |       << (TUK == TUK_Definition) | 
 | 4589 |       << FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc)); | 
 | 4590 |       return CheckClassTemplate(S, TagSpec, TUK, KWLoc, SS, | 
 | 4591 |                                 ClassTemplate->getIdentifier(), | 
 | 4592 |                                 TemplateNameLoc, | 
 | 4593 |                                 Attr, | 
 | 4594 |                                 TemplateParams, | 
| Abramo Bagnara | c57c17d | 2011-03-10 13:28:31 +0000 | [diff] [blame^] | 4595 |                                 AS_none, | 
 | 4596 |                                 NumMatchedTemplateParamLists, | 
 | 4597 |                   (TemplateParameterList**) TemplateParameterLists.release()); | 
| Douglas Gregor | b9c6631 | 2010-12-23 17:13:55 +0000 | [diff] [blame] | 4598 |     } | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 4599 |  | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4600 |     // Create a new class template partial specialization declaration node. | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4601 |     ClassTemplatePartialSpecializationDecl *PrevPartial | 
 | 4602 |       = cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl); | 
| Douglas Gregor | dc60c1e | 2010-04-30 05:56:50 +0000 | [diff] [blame] | 4603 |     unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber() | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 4604 |                             : ClassTemplate->getNextPartialSpecSequenceNumber(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4605 |     ClassTemplatePartialSpecializationDecl *Partial | 
| Douglas Gregor | 13c8577 | 2010-05-06 00:28:52 +0000 | [diff] [blame] | 4606 |       = ClassTemplatePartialSpecializationDecl::Create(Context, Kind, | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4607 |                                              ClassTemplate->getDeclContext(), | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 4608 |                                                        KWLoc, TemplateNameLoc, | 
| Anders Carlsson | 91fdf6f | 2009-06-05 04:06:48 +0000 | [diff] [blame] | 4609 |                                                        TemplateParams, | 
 | 4610 |                                                        ClassTemplate, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 4611 |                                                        Converted.data(), | 
 | 4612 |                                                        Converted.size(), | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 4613 |                                                        TemplateArgs, | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 4614 |                                                        CanonType, | 
| Douglas Gregor | dc60c1e | 2010-04-30 05:56:50 +0000 | [diff] [blame] | 4615 |                                                        PrevPartial, | 
 | 4616 |                                                        SequenceNumber); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 4617 |     SetNestedNameSpecifier(Partial, SS); | 
| Douglas Gregor | 98c2e62 | 2010-07-28 23:59:57 +0000 | [diff] [blame] | 4618 |     if (NumMatchedTemplateParamLists > 0 && SS.isSet()) { | 
| Douglas Gregor | c722ea4 | 2010-06-15 17:44:38 +0000 | [diff] [blame] | 4619 |       Partial->setTemplateParameterListsInfo(Context, | 
 | 4620 |                                              NumMatchedTemplateParamLists, | 
| Abramo Bagnara | 9b93488 | 2010-06-12 08:15:14 +0000 | [diff] [blame] | 4621 |                     (TemplateParameterList**) TemplateParameterLists.release()); | 
 | 4622 |     } | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4623 |  | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 4624 |     if (!PrevPartial) | 
 | 4625 |       ClassTemplate->AddPartialSpecialization(Partial, InsertPos); | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4626 |     Specialization = Partial; | 
| Douglas Gregor | 031a588 | 2009-06-13 00:26:55 +0000 | [diff] [blame] | 4627 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4628 |     // If we are providing an explicit specialization of a member class | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 4629 |     // template specialization, make a note of that. | 
 | 4630 |     if (PrevPartial && PrevPartial->getInstantiatedFromMember()) | 
 | 4631 |       PrevPartial->setMemberSpecialization(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4632 |  | 
| Douglas Gregor | 031a588 | 2009-06-13 00:26:55 +0000 | [diff] [blame] | 4633 |     // Check that all of the template parameters of the class template | 
 | 4634 |     // partial specialization are deducible from the template | 
 | 4635 |     // arguments. If not, this class template partial specialization | 
 | 4636 |     // will never be used. | 
 | 4637 |     llvm::SmallVector<bool, 8> DeducibleParams; | 
 | 4638 |     DeducibleParams.resize(TemplateParams->size()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4639 |     MarkUsedTemplateParameters(Partial->getTemplateArgs(), true, | 
| Douglas Gregor | ed9c0f9 | 2009-10-29 00:04:11 +0000 | [diff] [blame] | 4640 |                                TemplateParams->getDepth(), | 
| Douglas Gregor | e73bb60 | 2009-09-14 21:25:05 +0000 | [diff] [blame] | 4641 |                                DeducibleParams); | 
| Douglas Gregor | 031a588 | 2009-06-13 00:26:55 +0000 | [diff] [blame] | 4642 |     unsigned NumNonDeducible = 0; | 
 | 4643 |     for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) | 
 | 4644 |       if (!DeducibleParams[I]) | 
 | 4645 |         ++NumNonDeducible; | 
 | 4646 |  | 
 | 4647 |     if (NumNonDeducible) { | 
 | 4648 |       Diag(TemplateNameLoc, diag::warn_partial_specs_not_deducible) | 
 | 4649 |         << (NumNonDeducible > 1) | 
 | 4650 |         << SourceRange(TemplateNameLoc, RAngleLoc); | 
 | 4651 |       for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) { | 
 | 4652 |         if (!DeducibleParams[I]) { | 
 | 4653 |           NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I)); | 
 | 4654 |           if (Param->getDeclName()) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4655 |             Diag(Param->getLocation(), | 
| Douglas Gregor | 031a588 | 2009-06-13 00:26:55 +0000 | [diff] [blame] | 4656 |                  diag::note_partial_spec_unused_parameter) | 
 | 4657 |               << Param->getDeclName(); | 
 | 4658 |           else | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4659 |             Diag(Param->getLocation(), | 
| Douglas Gregor | 031a588 | 2009-06-13 00:26:55 +0000 | [diff] [blame] | 4660 |                  diag::note_partial_spec_unused_parameter) | 
| Benjamin Kramer | 476d8b8 | 2010-08-11 14:47:12 +0000 | [diff] [blame] | 4661 |               << "<anonymous>"; | 
| Douglas Gregor | 031a588 | 2009-06-13 00:26:55 +0000 | [diff] [blame] | 4662 |         } | 
 | 4663 |       } | 
 | 4664 |     } | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4665 |   } else { | 
 | 4666 |     // Create a new class template specialization declaration node for | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4667 |     // this explicit specialization or friend declaration. | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4668 |     Specialization | 
| Douglas Gregor | 13c8577 | 2010-05-06 00:28:52 +0000 | [diff] [blame] | 4669 |       = ClassTemplateSpecializationDecl::Create(Context, Kind, | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4670 |                                              ClassTemplate->getDeclContext(), | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 4671 |                                                 KWLoc, TemplateNameLoc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4672 |                                                 ClassTemplate, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 4673 |                                                 Converted.data(), | 
 | 4674 |                                                 Converted.size(), | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4675 |                                                 PrevDecl); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 4676 |     SetNestedNameSpecifier(Specialization, SS); | 
| Douglas Gregor | 98c2e62 | 2010-07-28 23:59:57 +0000 | [diff] [blame] | 4677 |     if (NumMatchedTemplateParamLists > 0 && SS.isSet()) { | 
| Douglas Gregor | c722ea4 | 2010-06-15 17:44:38 +0000 | [diff] [blame] | 4678 |       Specialization->setTemplateParameterListsInfo(Context, | 
 | 4679 |                                                   NumMatchedTemplateParamLists, | 
| Abramo Bagnara | 9b93488 | 2010-06-12 08:15:14 +0000 | [diff] [blame] | 4680 |                     (TemplateParameterList**) TemplateParameterLists.release()); | 
 | 4681 |     } | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4682 |  | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 4683 |     if (!PrevDecl) | 
 | 4684 |       ClassTemplate->AddSpecialization(Specialization, InsertPos); | 
| Douglas Gregor | b88e888 | 2009-07-30 17:40:51 +0000 | [diff] [blame] | 4685 |  | 
 | 4686 |     CanonType = Context.getTypeDeclType(Specialization); | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4687 |   } | 
 | 4688 |  | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 4689 |   // C++ [temp.expl.spec]p6: | 
 | 4690 |   //   If a template, a member template or the member of a class template is | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4691 |   //   explicitly specialized then that specialization shall be declared | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 4692 |   //   before the first use of that specialization that would cause an implicit | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4693 |   //   instantiation to take place, in every translation unit in which such a | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 4694 |   //   use occurs; no diagnostic is required. | 
 | 4695 |   if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) { | 
| Douglas Gregor | dc0a11c | 2010-02-26 06:03:23 +0000 | [diff] [blame] | 4696 |     bool Okay = false; | 
 | 4697 |     for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { | 
 | 4698 |       // Is there any previous explicit specialization declaration? | 
 | 4699 |       if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) { | 
 | 4700 |         Okay = true; | 
 | 4701 |         break; | 
 | 4702 |       } | 
 | 4703 |     } | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 4704 |  | 
| Douglas Gregor | dc0a11c | 2010-02-26 06:03:23 +0000 | [diff] [blame] | 4705 |     if (!Okay) { | 
 | 4706 |       SourceRange Range(TemplateNameLoc, RAngleLoc); | 
 | 4707 |       Diag(TemplateNameLoc, diag::err_specialization_after_instantiation) | 
 | 4708 |         << Context.getTypeDeclType(Specialization) << Range; | 
 | 4709 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4710 |       Diag(PrevDecl->getPointOfInstantiation(), | 
| Douglas Gregor | dc0a11c | 2010-02-26 06:03:23 +0000 | [diff] [blame] | 4711 |            diag::note_instantiation_required_here) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4712 |         << (PrevDecl->getTemplateSpecializationKind() | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 4713 |                                                 != TSK_ImplicitInstantiation); | 
| Douglas Gregor | dc0a11c | 2010-02-26 06:03:23 +0000 | [diff] [blame] | 4714 |       return true; | 
 | 4715 |     } | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 4716 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4717 |  | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4718 |   // If this is not a friend, note that this is an explicit specialization. | 
 | 4719 |   if (TUK != TUK_Friend) | 
 | 4720 |     Specialization->setSpecializationKind(TSK_ExplicitSpecialization); | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4721 |  | 
 | 4722 |   // Check that this isn't a redefinition of this specialization. | 
| John McCall | 0f434ec | 2009-07-31 02:45:11 +0000 | [diff] [blame] | 4723 |   if (TUK == TUK_Definition) { | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 4724 |     if (RecordDecl *Def = Specialization->getDefinition()) { | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4725 |       SourceRange Range(TemplateNameLoc, RAngleLoc); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4726 |       Diag(TemplateNameLoc, diag::err_redefinition) | 
| Douglas Gregor | c8ab256 | 2009-05-31 09:31:02 +0000 | [diff] [blame] | 4727 |         << Context.getTypeDeclType(Specialization) << Range; | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4728 |       Diag(Def->getLocation(), diag::note_previous_definition); | 
 | 4729 |       Specialization->setInvalidDecl(); | 
| Douglas Gregor | 212e81c | 2009-03-25 00:13:59 +0000 | [diff] [blame] | 4730 |       return true; | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4731 |     } | 
 | 4732 |   } | 
 | 4733 |  | 
| John McCall | 7f1b987 | 2010-12-18 03:30:47 +0000 | [diff] [blame] | 4734 |   if (Attr) | 
 | 4735 |     ProcessDeclAttributeList(S, Specialization, Attr); | 
 | 4736 |  | 
| Douglas Gregor | fc705b8 | 2009-02-26 22:19:44 +0000 | [diff] [blame] | 4737 |   // Build the fully-sugared type for this class template | 
 | 4738 |   // specialization as the user wrote in the specialization | 
 | 4739 |   // itself. This means that we'll pretty-print the type retrieved | 
 | 4740 |   // from the specialization's declaration the way that the user | 
 | 4741 |   // actually wrote the specialization, rather than formatting the | 
 | 4742 |   // name based on the "canonical" representation used to store the | 
 | 4743 |   // template arguments in the specialization. | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 4744 |   TypeSourceInfo *WrittenTy | 
 | 4745 |     = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc, | 
 | 4746 |                                                 TemplateArgs, CanonType); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4747 |   if (TUK != TUK_Friend) { | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4748 |     Specialization->setTypeAsWritten(WrittenTy); | 
| Douglas Gregor | 7e9b57b | 2010-07-06 18:33:12 +0000 | [diff] [blame] | 4749 |     if (TemplateParams) | 
 | 4750 |       Specialization->setTemplateKeywordLoc(TemplateParams->getTemplateLoc()); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4751 |   } | 
| Douglas Gregor | 40808ce | 2009-03-09 23:48:35 +0000 | [diff] [blame] | 4752 |   TemplateArgsIn.release(); | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4753 |  | 
| Douglas Gregor | 6bc9f7e | 2009-02-25 22:18:32 +0000 | [diff] [blame] | 4754 |   // C++ [temp.expl.spec]p9: | 
 | 4755 |   //   A template explicit specialization is in the scope of the | 
 | 4756 |   //   namespace in which the template was defined. | 
 | 4757 |   // | 
 | 4758 |   // We actually implement this paragraph where we set the semantic | 
 | 4759 |   // context (in the creation of the ClassTemplateSpecializationDecl), | 
 | 4760 |   // but we also maintain the lexical context where the actual | 
 | 4761 |   // definition occurs. | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4762 |   Specialization->setLexicalDeclContext(CurContext); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4763 |  | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4764 |   // We may be starting the definition of this specialization. | 
| John McCall | 0f434ec | 2009-07-31 02:45:11 +0000 | [diff] [blame] | 4765 |   if (TUK == TUK_Definition) | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4766 |     Specialization->startDefinition(); | 
 | 4767 |  | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4768 |   if (TUK == TUK_Friend) { | 
 | 4769 |     FriendDecl *Friend = FriendDecl::Create(Context, CurContext, | 
 | 4770 |                                             TemplateNameLoc, | 
| John McCall | 32f2fb5 | 2010-03-25 18:04:51 +0000 | [diff] [blame] | 4771 |                                             WrittenTy, | 
| Douglas Gregor | fc9cd61 | 2009-09-26 20:57:03 +0000 | [diff] [blame] | 4772 |                                             /*FIXME:*/KWLoc); | 
 | 4773 |     Friend->setAccess(AS_public); | 
 | 4774 |     CurContext->addDecl(Friend); | 
 | 4775 |   } else { | 
 | 4776 |     // Add the specialization into its lexical context, so that it can | 
 | 4777 |     // be seen when iterating through the list of declarations in that | 
 | 4778 |     // context. However, specializations are not found by name lookup. | 
 | 4779 |     CurContext->addDecl(Specialization); | 
 | 4780 |   } | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4781 |   return Specialization; | 
| Douglas Gregor | cc63668 | 2009-02-17 23:15:12 +0000 | [diff] [blame] | 4782 | } | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 4783 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4784 | Decl *Sema::ActOnTemplateDeclarator(Scope *S, | 
| Douglas Gregor | e542c86 | 2009-06-23 23:11:28 +0000 | [diff] [blame] | 4785 |                               MultiTemplateParamsArg TemplateParameterLists, | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4786 |                                     Declarator &D) { | 
| Douglas Gregor | e542c86 | 2009-06-23 23:11:28 +0000 | [diff] [blame] | 4787 |   return HandleDeclarator(S, D, move(TemplateParameterLists), false); | 
 | 4788 | } | 
 | 4789 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4790 | Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope, | 
| Douglas Gregor | 52591bf | 2009-06-24 00:54:41 +0000 | [diff] [blame] | 4791 |                                MultiTemplateParamsArg TemplateParameterLists, | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4792 |                                             Declarator &D) { | 
| Douglas Gregor | 52591bf | 2009-06-24 00:54:41 +0000 | [diff] [blame] | 4793 |   assert(getCurFunctionDecl() == 0 && "Function parsing confused"); | 
| Abramo Bagnara | 075f8f1 | 2010-12-10 16:29:40 +0000 | [diff] [blame] | 4794 |   DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4795 |  | 
| Douglas Gregor | 52591bf | 2009-06-24 00:54:41 +0000 | [diff] [blame] | 4796 |   if (FTI.hasPrototype) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4797 |     // FIXME: Diagnose arguments without names in C. | 
| Douglas Gregor | 52591bf | 2009-06-24 00:54:41 +0000 | [diff] [blame] | 4798 |   } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4799 |  | 
| Douglas Gregor | 52591bf | 2009-06-24 00:54:41 +0000 | [diff] [blame] | 4800 |   Scope *ParentScope = FnBodyScope->getParent(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4801 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4802 |   Decl *DP = HandleDeclarator(ParentScope, D, | 
 | 4803 |                               move(TemplateParameterLists), | 
 | 4804 |                               /*IsFunctionDefinition=*/true); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4805 |   if (FunctionTemplateDecl *FunctionTemplate | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4806 |         = dyn_cast_or_null<FunctionTemplateDecl>(DP)) | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 4807 |     return ActOnStartOfFunctionDef(FnBodyScope, | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 4808 |                                    FunctionTemplate->getTemplatedDecl()); | 
 | 4809 |   if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP)) | 
 | 4810 |     return ActOnStartOfFunctionDef(FnBodyScope, Function); | 
 | 4811 |   return 0; | 
| Douglas Gregor | 52591bf | 2009-06-24 00:54:41 +0000 | [diff] [blame] | 4812 | } | 
 | 4813 |  | 
| John McCall | 7504239 | 2010-02-11 01:33:53 +0000 | [diff] [blame] | 4814 | /// \brief Strips various properties off an implicit instantiation | 
 | 4815 | /// that has just been explicitly specialized. | 
 | 4816 | static void StripImplicitInstantiation(NamedDecl *D) { | 
| Sean Hunt | cf807c4 | 2010-08-18 23:23:40 +0000 | [diff] [blame] | 4817 |   D->dropAttrs(); | 
| John McCall | 7504239 | 2010-02-11 01:33:53 +0000 | [diff] [blame] | 4818 |  | 
 | 4819 |   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { | 
 | 4820 |     FD->setInlineSpecified(false); | 
 | 4821 |   } | 
 | 4822 | } | 
 | 4823 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4824 | /// \brief Diagnose cases where we have an explicit template specialization | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4825 | /// before/after an explicit template instantiation, producing diagnostics | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4826 | /// for those cases where they are required and determining whether the | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4827 | /// new specialization/instantiation will have any effect. | 
 | 4828 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4829 | /// \param NewLoc the location of the new explicit specialization or | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4830 | /// instantiation. | 
 | 4831 | /// | 
 | 4832 | /// \param NewTSK the kind of the new explicit specialization or instantiation. | 
 | 4833 | /// | 
 | 4834 | /// \param PrevDecl the previous declaration of the entity. | 
 | 4835 | /// | 
 | 4836 | /// \param PrevTSK the kind of the old explicit specialization or instantiatin. | 
 | 4837 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4838 | /// \param PrevPointOfInstantiation if valid, indicates where the previus | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4839 | /// declaration was instantiated (either implicitly or explicitly). | 
 | 4840 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4841 | /// \param HasNoEffect will be set to true to indicate that the new | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4842 | /// specialization or instantiation has no effect and should be ignored. | 
 | 4843 | /// | 
 | 4844 | /// \returns true if there was an error that should prevent the introduction of | 
 | 4845 | /// the new declaration into the AST, false otherwise. | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4846 | bool | 
 | 4847 | Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc, | 
 | 4848 |                                              TemplateSpecializationKind NewTSK, | 
 | 4849 |                                              NamedDecl *PrevDecl, | 
 | 4850 |                                              TemplateSpecializationKind PrevTSK, | 
 | 4851 |                                         SourceLocation PrevPointOfInstantiation, | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4852 |                                              bool &HasNoEffect) { | 
 | 4853 |   HasNoEffect = false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4854 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4855 |   switch (NewTSK) { | 
 | 4856 |   case TSK_Undeclared: | 
 | 4857 |   case TSK_ImplicitInstantiation: | 
 | 4858 |     assert(false && "Don't check implicit instantiations here"); | 
 | 4859 |     return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4860 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4861 |   case TSK_ExplicitSpecialization: | 
 | 4862 |     switch (PrevTSK) { | 
 | 4863 |     case TSK_Undeclared: | 
 | 4864 |     case TSK_ExplicitSpecialization: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4865 |       // Okay, we're just specializing something that is either already | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4866 |       // explicitly specialized or has merely been mentioned without any | 
 | 4867 |       // instantiation. | 
 | 4868 |       return false; | 
 | 4869 |  | 
 | 4870 |     case TSK_ImplicitInstantiation: | 
 | 4871 |       if (PrevPointOfInstantiation.isInvalid()) { | 
 | 4872 |         // The declaration itself has not actually been instantiated, so it is | 
 | 4873 |         // still okay to specialize it. | 
| John McCall | 7504239 | 2010-02-11 01:33:53 +0000 | [diff] [blame] | 4874 |         StripImplicitInstantiation(PrevDecl); | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4875 |         return false; | 
 | 4876 |       } | 
 | 4877 |       // Fall through | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4878 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4879 |     case TSK_ExplicitInstantiationDeclaration: | 
 | 4880 |     case TSK_ExplicitInstantiationDefinition: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4881 |       assert((PrevTSK == TSK_ImplicitInstantiation || | 
 | 4882 |               PrevPointOfInstantiation.isValid()) && | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4883 |              "Explicit instantiation without point of instantiation?"); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4884 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4885 |       // C++ [temp.expl.spec]p6: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4886 |       //   If a template, a member template or the member of a class template | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4887 |       //   is explicitly specialized then that specialization shall be declared | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4888 |       //   before the first use of that specialization that would cause an | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4889 |       //   implicit instantiation to take place, in every translation unit in | 
 | 4890 |       //   which such a use occurs; no diagnostic is required. | 
| Douglas Gregor | dc0a11c | 2010-02-26 06:03:23 +0000 | [diff] [blame] | 4891 |       for (NamedDecl *Prev = PrevDecl; Prev; Prev = getPreviousDecl(Prev)) { | 
 | 4892 |         // Is there any previous explicit specialization declaration? | 
 | 4893 |         if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) | 
 | 4894 |           return false; | 
 | 4895 |       } | 
 | 4896 |  | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4897 |       Diag(NewLoc, diag::err_specialization_after_instantiation) | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4898 |         << PrevDecl; | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4899 |       Diag(PrevPointOfInstantiation, diag::note_instantiation_required_here) | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4900 |         << (PrevTSK != TSK_ImplicitInstantiation); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4901 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4902 |       return true; | 
 | 4903 |     } | 
 | 4904 |     break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4905 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4906 |   case TSK_ExplicitInstantiationDeclaration: | 
 | 4907 |     switch (PrevTSK) { | 
 | 4908 |     case TSK_ExplicitInstantiationDeclaration: | 
 | 4909 |       // This explicit instantiation declaration is redundant (that's okay). | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4910 |       HasNoEffect = true; | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4911 |       return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4912 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4913 |     case TSK_Undeclared: | 
 | 4914 |     case TSK_ImplicitInstantiation: | 
 | 4915 |       // We're explicitly instantiating something that may have already been | 
 | 4916 |       // implicitly instantiated; that's fine. | 
 | 4917 |       return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4918 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4919 |     case TSK_ExplicitSpecialization: | 
 | 4920 |       // C++0x [temp.explicit]p4: | 
 | 4921 |       //   For a given set of template parameters, if an explicit instantiation | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4922 |       //   of a template appears after a declaration of an explicit | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4923 |       //   specialization for that template, the explicit instantiation has no | 
 | 4924 |       //   effect. | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4925 |       HasNoEffect = true; | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4926 |       return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4927 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4928 |     case TSK_ExplicitInstantiationDefinition: | 
 | 4929 |       // C++0x [temp.explicit]p10: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4930 |       //   If an entity is the subject of both an explicit instantiation | 
 | 4931 |       //   declaration and an explicit instantiation definition in the same | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4932 |       //   translation unit, the definition shall follow the declaration. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4933 |       Diag(NewLoc, | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4934 |            diag::err_explicit_instantiation_declaration_after_definition); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4935 |       Diag(PrevPointOfInstantiation, | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4936 |            diag::note_explicit_instantiation_definition_here); | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4937 |       assert(PrevPointOfInstantiation.isValid() && | 
 | 4938 |              "Explicit instantiation without point of instantiation?"); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4939 |       HasNoEffect = true; | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4940 |       return false; | 
 | 4941 |     } | 
 | 4942 |     break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4943 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4944 |   case TSK_ExplicitInstantiationDefinition: | 
 | 4945 |     switch (PrevTSK) { | 
 | 4946 |     case TSK_Undeclared: | 
 | 4947 |     case TSK_ImplicitInstantiation: | 
 | 4948 |       // We're explicitly instantiating something that may have already been | 
 | 4949 |       // implicitly instantiated; that's fine. | 
 | 4950 |       return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4951 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4952 |     case TSK_ExplicitSpecialization: | 
 | 4953 |       // C++ DR 259, C++0x [temp.explicit]p4: | 
 | 4954 |       //   For a given set of template parameters, if an explicit | 
 | 4955 |       //   instantiation of a template appears after a declaration of | 
 | 4956 |       //   an explicit specialization for that template, the explicit | 
 | 4957 |       //   instantiation has no effect. | 
 | 4958 |       // | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4959 |       // In C++98/03 mode, we only give an extension warning here, because it | 
| Douglas Gregor | c42b652 | 2010-04-09 21:02:29 +0000 | [diff] [blame] | 4960 |       // is not harmful to try to explicitly instantiate something that | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4961 |       // has been explicitly specialized. | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4962 |       if (!getLangOptions().CPlusPlus0x) { | 
 | 4963 |         Diag(NewLoc, diag::ext_explicit_instantiation_after_specialization) | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4964 |           << PrevDecl; | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4965 |         Diag(PrevDecl->getLocation(), | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4966 |              diag::note_previous_template_specialization); | 
 | 4967 |       } | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4968 |       HasNoEffect = true; | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4969 |       return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4970 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4971 |     case TSK_ExplicitInstantiationDeclaration: | 
 | 4972 |       // We're explicity instantiating a definition for something for which we | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4973 |       // were previously asked to suppress instantiations. That's fine. | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4974 |       return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4975 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4976 |     case TSK_ExplicitInstantiationDefinition: | 
 | 4977 |       // C++0x [temp.spec]p5: | 
 | 4978 |       //   For a given template and a given set of template-arguments, | 
 | 4979 |       //     - an explicit instantiation definition shall appear at most once | 
 | 4980 |       //       in a program, | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4981 |       Diag(NewLoc, diag::err_explicit_instantiation_duplicate) | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4982 |         << PrevDecl; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4983 |       Diag(PrevPointOfInstantiation, | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 4984 |            diag::note_previous_explicit_instantiation); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 4985 |       HasNoEffect = true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4986 |       return false; | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4987 |     } | 
 | 4988 |     break; | 
 | 4989 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4990 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4991 |   assert(false && "Missing specialization/instantiation case?"); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 4992 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 4993 |   return false; | 
 | 4994 | } | 
 | 4995 |  | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 4996 | /// \brief Perform semantic analysis for the given dependent function | 
 | 4997 | /// template specialization.  The only possible way to get a dependent | 
 | 4998 | /// function template specialization is with a friend declaration, | 
 | 4999 | /// like so: | 
 | 5000 | /// | 
 | 5001 | ///   template <class T> void foo(T); | 
 | 5002 | ///   template <class T> class A { | 
 | 5003 | ///     friend void foo<>(T); | 
 | 5004 | ///   }; | 
 | 5005 | /// | 
 | 5006 | /// There really isn't any useful analysis we can do here, so we | 
 | 5007 | /// just store the information. | 
 | 5008 | bool | 
 | 5009 | Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD, | 
 | 5010 |                    const TemplateArgumentListInfo &ExplicitTemplateArgs, | 
 | 5011 |                                                    LookupResult &Previous) { | 
 | 5012 |   // Remove anything from Previous that isn't a function template in | 
 | 5013 |   // the correct context. | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5014 |   DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext(); | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 5015 |   LookupResult::Filter F = Previous.makeFilter(); | 
 | 5016 |   while (F.hasNext()) { | 
 | 5017 |     NamedDecl *D = F.next()->getUnderlyingDecl(); | 
 | 5018 |     if (!isa<FunctionTemplateDecl>(D) || | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5019 |         !FDLookupContext->InEnclosingNamespaceSetOf( | 
 | 5020 |                               D->getDeclContext()->getRedeclContext())) | 
| John McCall | af2094e | 2010-04-08 09:05:18 +0000 | [diff] [blame] | 5021 |       F.erase(); | 
 | 5022 |   } | 
 | 5023 |   F.done(); | 
 | 5024 |  | 
 | 5025 |   // Should this be diagnosed here? | 
 | 5026 |   if (Previous.empty()) return true; | 
 | 5027 |  | 
 | 5028 |   FD->setDependentTemplateSpecialization(Context, Previous.asUnresolvedSet(), | 
 | 5029 |                                          ExplicitTemplateArgs); | 
 | 5030 |   return false; | 
 | 5031 | } | 
 | 5032 |  | 
| Abramo Bagnara | e03db98 | 2010-05-20 15:32:11 +0000 | [diff] [blame] | 5033 | /// \brief Perform semantic analysis for the given function template | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5034 | /// specialization. | 
 | 5035 | /// | 
| Abramo Bagnara | e03db98 | 2010-05-20 15:32:11 +0000 | [diff] [blame] | 5036 | /// This routine performs all of the semantic analysis required for an | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5037 | /// explicit function template specialization. On successful completion, | 
 | 5038 | /// the function declaration \p FD will become a function template | 
 | 5039 | /// specialization. | 
 | 5040 | /// | 
 | 5041 | /// \param FD the function declaration, which will be updated to become a | 
 | 5042 | /// function template specialization. | 
 | 5043 | /// | 
| Abramo Bagnara | e03db98 | 2010-05-20 15:32:11 +0000 | [diff] [blame] | 5044 | /// \param ExplicitTemplateArgs the explicitly-provided template arguments, | 
 | 5045 | /// if any. Note that this may be valid info even when 0 arguments are | 
 | 5046 | /// explicitly provided as in, e.g., \c void sort<>(char*, char*); | 
 | 5047 | /// as it anyway contains info on the angle brackets locations. | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5048 | /// | 
| Abramo Bagnara | e03db98 | 2010-05-20 15:32:11 +0000 | [diff] [blame] | 5049 | /// \param PrevDecl the set of declarations that may be specialized by | 
 | 5050 | /// this function specialization. | 
 | 5051 | bool | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5052 | Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD, | 
| Douglas Gregor | 6771423 | 2011-03-03 02:41:12 +0000 | [diff] [blame] | 5053 |                                  TemplateArgumentListInfo *ExplicitTemplateArgs, | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5054 |                                           LookupResult &Previous) { | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5055 |   // The set of function template specializations that could match this | 
 | 5056 |   // explicit function template specialization. | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5057 |   UnresolvedSet<8> Candidates; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5058 |  | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5059 |   DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext(); | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5060 |   for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); | 
 | 5061 |          I != E; ++I) { | 
 | 5062 |     NamedDecl *Ovl = (*I)->getUnderlyingDecl(); | 
 | 5063 |     if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5064 |       // Only consider templates found within the same semantic lookup scope as | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5065 |       // FD. | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5066 |       if (!FDLookupContext->InEnclosingNamespaceSetOf( | 
 | 5067 |                                 Ovl->getDeclContext()->getRedeclContext())) | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5068 |         continue; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5069 |  | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5070 |       // C++ [temp.expl.spec]p11: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5071 |       //   A trailing template-argument can be left unspecified in the | 
 | 5072 |       //   template-id naming an explicit function template specialization | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5073 |       //   provided it can be deduced from the function argument type. | 
 | 5074 |       // Perform template argument deduction to determine whether we may be | 
 | 5075 |       // specializing this template. | 
 | 5076 |       // FIXME: It is somewhat wasteful to build | 
| John McCall | 5769d61 | 2010-02-08 23:07:23 +0000 | [diff] [blame] | 5077 |       TemplateDeductionInfo Info(Context, FD->getLocation()); | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5078 |       FunctionDecl *Specialization = 0; | 
 | 5079 |       if (TemplateDeductionResult TDK | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5080 |             = DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs, | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5081 |                                       FD->getType(), | 
 | 5082 |                                       Specialization, | 
 | 5083 |                                       Info)) { | 
 | 5084 |         // FIXME: Template argument deduction failed; record why it failed, so | 
 | 5085 |         // that we can provide nifty diagnostics. | 
 | 5086 |         (void)TDK; | 
 | 5087 |         continue; | 
 | 5088 |       } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5089 |  | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5090 |       // Record this candidate. | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5091 |       Candidates.addDecl(Specialization, I.getAccess()); | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5092 |     } | 
 | 5093 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5094 |  | 
| Douglas Gregor | c5df30f | 2009-09-26 03:41:46 +0000 | [diff] [blame] | 5095 |   // Find the most specialized function template. | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5096 |   UnresolvedSetIterator Result | 
 | 5097 |     = getMostSpecialized(Candidates.begin(), Candidates.end(), | 
| Douglas Gregor | 5c7bf42 | 2011-01-11 17:34:58 +0000 | [diff] [blame] | 5098 |                          TPOC_Other, 0, FD->getLocation(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5099 |                   PDiag(diag::err_function_template_spec_no_match) | 
| Douglas Gregor | c5df30f | 2009-09-26 03:41:46 +0000 | [diff] [blame] | 5100 |                     << FD->getDeclName(), | 
| Douglas Gregor | fe6b2d4 | 2010-03-29 23:34:08 +0000 | [diff] [blame] | 5101 |                   PDiag(diag::err_function_template_spec_ambiguous) | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5102 |                     << FD->getDeclName() << (ExplicitTemplateArgs != 0), | 
| Douglas Gregor | fe6b2d4 | 2010-03-29 23:34:08 +0000 | [diff] [blame] | 5103 |                   PDiag(diag::note_function_template_spec_matched)); | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5104 |   if (Result == Candidates.end()) | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5105 |     return true; | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5106 |  | 
 | 5107 |   // Ignore access information;  it doesn't figure into redeclaration checking. | 
 | 5108 |   FunctionDecl *Specialization = cast<FunctionDecl>(*Result); | 
| Abramo Bagnara | abfb405 | 2011-03-04 17:20:30 +0000 | [diff] [blame] | 5109 |  | 
 | 5110 |   FunctionTemplateSpecializationInfo *SpecInfo | 
 | 5111 |     = Specialization->getTemplateSpecializationInfo(); | 
 | 5112 |   assert(SpecInfo && "Function template specialization info missing?"); | 
 | 5113 |   { | 
 | 5114 |     // Note: do not overwrite location info if previous template | 
 | 5115 |     // specialization kind was explicit. | 
 | 5116 |     TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind(); | 
 | 5117 |     if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) | 
 | 5118 |       Specialization->setLocation(FD->getLocation()); | 
 | 5119 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5120 |  | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5121 |   // FIXME: Check if the prior specialization has a point of instantiation. | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5122 |   // If so, we have run afoul of . | 
| John McCall | 7ad650f | 2010-03-24 07:46:06 +0000 | [diff] [blame] | 5123 |  | 
 | 5124 |   // If this is a friend declaration, then we're not really declaring | 
 | 5125 |   // an explicit specialization. | 
 | 5126 |   bool isFriend = (FD->getFriendObjectKind() != Decl::FOK_None); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5127 |  | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 5128 |   // Check the scope of this explicit specialization. | 
| John McCall | 7ad650f | 2010-03-24 07:46:06 +0000 | [diff] [blame] | 5129 |   if (!isFriend && | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5130 |       CheckTemplateSpecializationScope(*this, | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 5131 |                                        Specialization->getPrimaryTemplate(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5132 |                                        Specialization, FD->getLocation(), | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 5133 |                                        false)) | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 5134 |     return true; | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5135 |  | 
 | 5136 |   // C++ [temp.expl.spec]p6: | 
 | 5137 |   //   If a template, a member template or the member of a class template is | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5138 |   //   explicitly specialized then that specialization shall be declared | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5139 |   //   before the first use of that specialization that would cause an implicit | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5140 |   //   instantiation to take place, in every translation unit in which such a | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5141 |   //   use occurs; no diagnostic is required. | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5142 |   bool HasNoEffect = false; | 
| John McCall | 7ad650f | 2010-03-24 07:46:06 +0000 | [diff] [blame] | 5143 |   if (!isFriend && | 
 | 5144 |       CheckSpecializationInstantiationRedecl(FD->getLocation(), | 
| John McCall | 7504239 | 2010-02-11 01:33:53 +0000 | [diff] [blame] | 5145 |                                              TSK_ExplicitSpecialization, | 
 | 5146 |                                              Specialization, | 
 | 5147 |                                    SpecInfo->getTemplateSpecializationKind(), | 
 | 5148 |                                          SpecInfo->getPointOfInstantiation(), | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5149 |                                              HasNoEffect)) | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5150 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5151 |  | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5152 |   // Mark the prior declaration as an explicit specialization, so that later | 
 | 5153 |   // clients know that this is an explicit specialization. | 
| Argyrios Kyrtzidis | bbc6454 | 2010-08-15 01:15:20 +0000 | [diff] [blame] | 5154 |   if (!isFriend) { | 
| John McCall | 7ad650f | 2010-03-24 07:46:06 +0000 | [diff] [blame] | 5155 |     SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization); | 
| Argyrios Kyrtzidis | bbc6454 | 2010-08-15 01:15:20 +0000 | [diff] [blame] | 5156 |     MarkUnusedFileScopedDecl(Specialization); | 
 | 5157 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5158 |  | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5159 |   // Turn the given function declaration into a function template | 
 | 5160 |   // specialization, with the template arguments from the previous | 
 | 5161 |   // specialization. | 
| Abramo Bagnara | e03db98 | 2010-05-20 15:32:11 +0000 | [diff] [blame] | 5162 |   // Take copies of (semantic and syntactic) template argument lists. | 
 | 5163 |   const TemplateArgumentList* TemplArgs = new (Context) | 
 | 5164 |     TemplateArgumentList(Specialization->getTemplateSpecializationArgs()); | 
 | 5165 |   const TemplateArgumentListInfo* TemplArgsAsWritten = ExplicitTemplateArgs | 
 | 5166 |     ? new (Context) TemplateArgumentListInfo(*ExplicitTemplateArgs) : 0; | 
| Douglas Gregor | 838db38 | 2010-02-11 01:19:42 +0000 | [diff] [blame] | 5167 |   FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(), | 
| Abramo Bagnara | e03db98 | 2010-05-20 15:32:11 +0000 | [diff] [blame] | 5168 |                                         TemplArgs, /*InsertPos=*/0, | 
 | 5169 |                                     SpecInfo->getTemplateSpecializationKind(), | 
 | 5170 |                                         TemplArgsAsWritten); | 
 | 5171 |  | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5172 |   // The "previous declaration" for this function template specialization is | 
 | 5173 |   // the prior function template specialization. | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5174 |   Previous.clear(); | 
 | 5175 |   Previous.addDecl(Specialization); | 
| Douglas Gregor | b9aa6b2 | 2009-09-24 23:14:47 +0000 | [diff] [blame] | 5176 |   return false; | 
 | 5177 | } | 
 | 5178 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5179 | /// \brief Perform semantic analysis for the given non-template member | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5180 | /// specialization. | 
 | 5181 | /// | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5182 | /// This routine performs all of the semantic analysis required for an | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5183 | /// explicit member function specialization. On successful completion, | 
 | 5184 | /// the function declaration \p FD will become a member function | 
 | 5185 | /// specialization. | 
 | 5186 | /// | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5187 | /// \param Member the member declaration, which will be updated to become a | 
 | 5188 | /// specialization. | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5189 | /// | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5190 | /// \param Previous the set of declarations, one of which may be specialized | 
 | 5191 | /// by this function specialization;  the set will be modified to contain the | 
 | 5192 | /// redeclared member. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5193 | bool | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5194 | Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) { | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5195 |   assert(!isa<TemplateDecl>(Member) && "Only for non-template members"); | 
| John McCall | 77e8b11 | 2010-04-13 20:37:33 +0000 | [diff] [blame] | 5196 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5197 |   // Try to find the member we are instantiating. | 
 | 5198 |   NamedDecl *Instantiation = 0; | 
 | 5199 |   NamedDecl *InstantiatedFrom = 0; | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5200 |   MemberSpecializationInfo *MSInfo = 0; | 
 | 5201 |  | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5202 |   if (Previous.empty()) { | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5203 |     // Nowhere to look anyway. | 
 | 5204 |   } else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Member)) { | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5205 |     for (LookupResult::iterator I = Previous.begin(), E = Previous.end(); | 
 | 5206 |            I != E; ++I) { | 
 | 5207 |       NamedDecl *D = (*I)->getUnderlyingDecl(); | 
 | 5208 |       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) { | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5209 |         if (Context.hasSameType(Function->getType(), Method->getType())) { | 
 | 5210 |           Instantiation = Method; | 
 | 5211 |           InstantiatedFrom = Method->getInstantiatedFromMemberFunction(); | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5212 |           MSInfo = Method->getMemberSpecializationInfo(); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5213 |           break; | 
 | 5214 |         } | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5215 |       } | 
 | 5216 |     } | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5217 |   } else if (isa<VarDecl>(Member)) { | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5218 |     VarDecl *PrevVar; | 
 | 5219 |     if (Previous.isSingleResult() && | 
 | 5220 |         (PrevVar = dyn_cast<VarDecl>(Previous.getFoundDecl()))) | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5221 |       if (PrevVar->isStaticDataMember()) { | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5222 |         Instantiation = PrevVar; | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5223 |         InstantiatedFrom = PrevVar->getInstantiatedFromStaticDataMember(); | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5224 |         MSInfo = PrevVar->getMemberSpecializationInfo(); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5225 |       } | 
 | 5226 |   } else if (isa<RecordDecl>(Member)) { | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5227 |     CXXRecordDecl *PrevRecord; | 
 | 5228 |     if (Previous.isSingleResult() && | 
 | 5229 |         (PrevRecord = dyn_cast<CXXRecordDecl>(Previous.getFoundDecl()))) { | 
 | 5230 |       Instantiation = PrevRecord; | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5231 |       InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass(); | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5232 |       MSInfo = PrevRecord->getMemberSpecializationInfo(); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5233 |     } | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5234 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5235 |  | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5236 |   if (!Instantiation) { | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5237 |     // There is no previous declaration that matches. Since member | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5238 |     // specializations are always out-of-line, the caller will complain about | 
 | 5239 |     // this mismatch later. | 
 | 5240 |     return false; | 
 | 5241 |   } | 
| John McCall | 77e8b11 | 2010-04-13 20:37:33 +0000 | [diff] [blame] | 5242 |  | 
 | 5243 |   // If this is a friend, just bail out here before we start turning | 
 | 5244 |   // things into explicit specializations. | 
 | 5245 |   if (Member->getFriendObjectKind() != Decl::FOK_None) { | 
 | 5246 |     // Preserve instantiation information. | 
 | 5247 |     if (InstantiatedFrom && isa<CXXMethodDecl>(Member)) { | 
 | 5248 |       cast<CXXMethodDecl>(Member)->setInstantiationOfMemberFunction( | 
 | 5249 |                                       cast<CXXMethodDecl>(InstantiatedFrom), | 
 | 5250 |         cast<CXXMethodDecl>(Instantiation)->getTemplateSpecializationKind()); | 
 | 5251 |     } else if (InstantiatedFrom && isa<CXXRecordDecl>(Member)) { | 
 | 5252 |       cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass( | 
 | 5253 |                                       cast<CXXRecordDecl>(InstantiatedFrom), | 
 | 5254 |         cast<CXXRecordDecl>(Instantiation)->getTemplateSpecializationKind()); | 
 | 5255 |     } | 
 | 5256 |  | 
 | 5257 |     Previous.clear(); | 
 | 5258 |     Previous.addDecl(Instantiation); | 
 | 5259 |     return false; | 
 | 5260 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5261 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5262 |   // Make sure that this is a specialization of a member. | 
 | 5263 |   if (!InstantiatedFrom) { | 
 | 5264 |     Diag(Member->getLocation(), diag::err_spec_member_not_instantiated) | 
 | 5265 |       << Member; | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5266 |     Diag(Instantiation->getLocation(), diag::note_specialized_decl); | 
 | 5267 |     return true; | 
 | 5268 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5269 |  | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5270 |   // C++ [temp.expl.spec]p6: | 
 | 5271 |   //   If a template, a member template or the member of a class template is | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5272 |   //   explicitly specialized then that spe- cialization shall be declared | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5273 |   //   before the first use of that specialization that would cause an implicit | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5274 |   //   instantiation to take place, in every translation unit in which such a | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5275 |   //   use occurs; no diagnostic is required. | 
 | 5276 |   assert(MSInfo && "Member specialization info missing?"); | 
| John McCall | 7504239 | 2010-02-11 01:33:53 +0000 | [diff] [blame] | 5277 |  | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5278 |   bool HasNoEffect = false; | 
| John McCall | 7504239 | 2010-02-11 01:33:53 +0000 | [diff] [blame] | 5279 |   if (CheckSpecializationInstantiationRedecl(Member->getLocation(), | 
 | 5280 |                                              TSK_ExplicitSpecialization, | 
 | 5281 |                                              Instantiation, | 
 | 5282 |                                      MSInfo->getTemplateSpecializationKind(), | 
 | 5283 |                                            MSInfo->getPointOfInstantiation(), | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5284 |                                              HasNoEffect)) | 
| Douglas Gregor | b3ae4fc | 2009-10-12 20:18:28 +0000 | [diff] [blame] | 5285 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5286 |  | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5287 |   // Check the scope of this explicit specialization. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5288 |   if (CheckTemplateSpecializationScope(*this, | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5289 |                                        InstantiatedFrom, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5290 |                                        Instantiation, Member->getLocation(), | 
| Douglas Gregor | 9302da6 | 2009-10-14 23:50:59 +0000 | [diff] [blame] | 5291 |                                        false)) | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5292 |     return true; | 
| Douglas Gregor | 2db3232 | 2009-10-07 23:56:10 +0000 | [diff] [blame] | 5293 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5294 |   // Note that this is an explicit instantiation of a member. | 
| Douglas Gregor | f6b1185 | 2009-10-08 15:14:33 +0000 | [diff] [blame] | 5295 |   // the original declaration to note that it is an explicit specialization | 
 | 5296 |   // (if it was previously an implicit instantiation). This latter step | 
 | 5297 |   // makes bookkeeping easier. | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5298 |   if (isa<FunctionDecl>(Member)) { | 
| Douglas Gregor | f6b1185 | 2009-10-08 15:14:33 +0000 | [diff] [blame] | 5299 |     FunctionDecl *InstantiationFunction = cast<FunctionDecl>(Instantiation); | 
 | 5300 |     if (InstantiationFunction->getTemplateSpecializationKind() == | 
 | 5301 |           TSK_ImplicitInstantiation) { | 
 | 5302 |       InstantiationFunction->setTemplateSpecializationKind( | 
 | 5303 |                                                   TSK_ExplicitSpecialization); | 
 | 5304 |       InstantiationFunction->setLocation(Member->getLocation()); | 
 | 5305 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5306 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5307 |     cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction( | 
 | 5308 |                                         cast<CXXMethodDecl>(InstantiatedFrom), | 
 | 5309 |                                                   TSK_ExplicitSpecialization); | 
| Argyrios Kyrtzidis | bbc6454 | 2010-08-15 01:15:20 +0000 | [diff] [blame] | 5310 |     MarkUnusedFileScopedDecl(InstantiationFunction); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5311 |   } else if (isa<VarDecl>(Member)) { | 
| Douglas Gregor | f6b1185 | 2009-10-08 15:14:33 +0000 | [diff] [blame] | 5312 |     VarDecl *InstantiationVar = cast<VarDecl>(Instantiation); | 
 | 5313 |     if (InstantiationVar->getTemplateSpecializationKind() == | 
 | 5314 |           TSK_ImplicitInstantiation) { | 
 | 5315 |       InstantiationVar->setTemplateSpecializationKind( | 
 | 5316 |                                                   TSK_ExplicitSpecialization); | 
 | 5317 |       InstantiationVar->setLocation(Member->getLocation()); | 
 | 5318 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5319 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5320 |     Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member), | 
 | 5321 |                                                 cast<VarDecl>(InstantiatedFrom), | 
 | 5322 |                                                 TSK_ExplicitSpecialization); | 
| Argyrios Kyrtzidis | bbc6454 | 2010-08-15 01:15:20 +0000 | [diff] [blame] | 5323 |     MarkUnusedFileScopedDecl(InstantiationVar); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5324 |   } else { | 
 | 5325 |     assert(isa<CXXRecordDecl>(Member) && "Only member classes remain"); | 
| Douglas Gregor | f6b1185 | 2009-10-08 15:14:33 +0000 | [diff] [blame] | 5326 |     CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation); | 
 | 5327 |     if (InstantiationClass->getTemplateSpecializationKind() == | 
 | 5328 |           TSK_ImplicitInstantiation) { | 
 | 5329 |       InstantiationClass->setTemplateSpecializationKind( | 
 | 5330 |                                                    TSK_ExplicitSpecialization); | 
 | 5331 |       InstantiationClass->setLocation(Member->getLocation()); | 
 | 5332 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5333 |  | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5334 |     cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass( | 
| Douglas Gregor | f6b1185 | 2009-10-08 15:14:33 +0000 | [diff] [blame] | 5335 |                                         cast<CXXRecordDecl>(InstantiatedFrom), | 
 | 5336 |                                                    TSK_ExplicitSpecialization); | 
| Douglas Gregor | 251b4ff | 2009-10-08 07:24:58 +0000 | [diff] [blame] | 5337 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5338 |  | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5339 |   // Save the caller the trouble of having to figure out which declaration | 
 | 5340 |   // this specialization matches. | 
| John McCall | 6826314 | 2009-11-18 22:49:29 +0000 | [diff] [blame] | 5341 |   Previous.clear(); | 
 | 5342 |   Previous.addDecl(Instantiation); | 
| Douglas Gregor | 1fef4e6 | 2009-10-07 22:35:40 +0000 | [diff] [blame] | 5343 |   return false; | 
 | 5344 | } | 
 | 5345 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5346 | /// \brief Check the scope of an explicit instantiation. | 
| Douglas Gregor | 669eed8 | 2010-07-13 00:10:04 +0000 | [diff] [blame] | 5347 | /// | 
 | 5348 | /// \returns true if a serious error occurs, false otherwise. | 
 | 5349 | static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D, | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5350 |                                             SourceLocation InstLoc, | 
 | 5351 |                                             bool WasQualifiedName) { | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5352 |   DeclContext *OrigContext= D->getDeclContext()->getEnclosingNamespaceContext(); | 
 | 5353 |   DeclContext *CurContext = S.CurContext->getRedeclContext(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5354 |  | 
| Douglas Gregor | 669eed8 | 2010-07-13 00:10:04 +0000 | [diff] [blame] | 5355 |   if (CurContext->isRecord()) { | 
 | 5356 |     S.Diag(InstLoc, diag::err_explicit_instantiation_in_class) | 
 | 5357 |       << D; | 
 | 5358 |     return true; | 
 | 5359 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5360 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5361 |   // C++0x [temp.explicit]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5362 |   //   An explicit instantiation shall appear in an enclosing namespace of its | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5363 |   //   template. | 
 | 5364 |   // | 
 | 5365 |   // This is DR275, which we do not retroactively apply to C++98/03. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5366 |   if (S.getLangOptions().CPlusPlus0x && | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5367 |       !CurContext->Encloses(OrigContext)) { | 
 | 5368 |     if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext)) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5369 |       S.Diag(InstLoc, | 
 | 5370 |              S.getLangOptions().CPlusPlus0x? | 
| Douglas Gregor | 2166beb | 2010-05-11 17:39:34 +0000 | [diff] [blame] | 5371 |                  diag::err_explicit_instantiation_out_of_scope | 
 | 5372 |                : diag::warn_explicit_instantiation_out_of_scope_0x) | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5373 |         << D << NS; | 
 | 5374 |     else | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5375 |       S.Diag(InstLoc, | 
| Douglas Gregor | 2166beb | 2010-05-11 17:39:34 +0000 | [diff] [blame] | 5376 |              S.getLangOptions().CPlusPlus0x? | 
 | 5377 |                  diag::err_explicit_instantiation_must_be_global | 
 | 5378 |                : diag::warn_explicit_instantiation_out_of_scope_0x) | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5379 |         << D; | 
 | 5380 |     S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); | 
| Douglas Gregor | 669eed8 | 2010-07-13 00:10:04 +0000 | [diff] [blame] | 5381 |     return false; | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5382 |   } | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5383 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5384 |   // C++0x [temp.explicit]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5385 |   //   If the name declared in the explicit instantiation is an unqualified | 
 | 5386 |   //   name, the explicit instantiation shall appear in the namespace where | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5387 |   //   its template is declared or, if that namespace is inline (7.3.1), any | 
 | 5388 |   //   namespace from its enclosing namespace set. | 
 | 5389 |   if (WasQualifiedName) | 
| Douglas Gregor | 669eed8 | 2010-07-13 00:10:04 +0000 | [diff] [blame] | 5390 |     return false; | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5391 |  | 
 | 5392 |   if (CurContext->InEnclosingNamespaceSetOf(OrigContext)) | 
| Douglas Gregor | 669eed8 | 2010-07-13 00:10:04 +0000 | [diff] [blame] | 5393 |     return false; | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5394 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5395 |   S.Diag(InstLoc, | 
| Douglas Gregor | 2166beb | 2010-05-11 17:39:34 +0000 | [diff] [blame] | 5396 |          S.getLangOptions().CPlusPlus0x? | 
 | 5397 |              diag::err_explicit_instantiation_unqualified_wrong_namespace | 
 | 5398 |            : diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x) | 
| Sebastian Redl | 7a126a4 | 2010-08-31 00:36:30 +0000 | [diff] [blame] | 5399 |     << D << OrigContext; | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5400 |   S.Diag(D->getLocation(), diag::note_explicit_instantiation_here); | 
| Douglas Gregor | 669eed8 | 2010-07-13 00:10:04 +0000 | [diff] [blame] | 5401 |   return false; | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5402 | } | 
 | 5403 |  | 
 | 5404 | /// \brief Determine whether the given scope specifier has a template-id in it. | 
 | 5405 | static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) { | 
 | 5406 |   if (!SS.isSet()) | 
 | 5407 |     return false; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5408 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5409 |   // C++0x [temp.explicit]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5410 |   //   If the explicit instantiation is for a member function, a member class | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5411 |   //   or a static data member of a class template specialization, the name of | 
 | 5412 |   //   the class template specialization in the qualified-id for the member | 
 | 5413 |   //   name shall be a simple-template-id. | 
 | 5414 |   // | 
 | 5415 |   // C++98 has the same restriction, just worded differently. | 
 | 5416 |   for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep(); | 
 | 5417 |        NNS; NNS = NNS->getPrefix()) | 
| John McCall | f4c7371 | 2011-01-19 06:33:43 +0000 | [diff] [blame] | 5418 |     if (const Type *T = NNS->getAsType()) | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5419 |       if (isa<TemplateSpecializationType>(T)) | 
 | 5420 |         return true; | 
 | 5421 |  | 
 | 5422 |   return false; | 
 | 5423 | } | 
 | 5424 |  | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5425 | // Explicit instantiation of a class template specialization | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 5426 | DeclResult | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5427 | Sema::ActOnExplicitInstantiation(Scope *S, | 
| Douglas Gregor | 45f9655 | 2009-09-04 06:33:52 +0000 | [diff] [blame] | 5428 |                                  SourceLocation ExternLoc, | 
 | 5429 |                                  SourceLocation TemplateLoc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5430 |                                  unsigned TagSpec, | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5431 |                                  SourceLocation KWLoc, | 
 | 5432 |                                  const CXXScopeSpec &SS, | 
 | 5433 |                                  TemplateTy TemplateD, | 
 | 5434 |                                  SourceLocation TemplateNameLoc, | 
 | 5435 |                                  SourceLocation LAngleLoc, | 
 | 5436 |                                  ASTTemplateArgsPtr TemplateArgsIn, | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5437 |                                  SourceLocation RAngleLoc, | 
 | 5438 |                                  AttributeList *Attr) { | 
 | 5439 |   // Find the class template we're specializing | 
 | 5440 |   TemplateName Name = TemplateD.getAsVal<TemplateName>(); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5441 |   ClassTemplateDecl *ClassTemplate | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5442 |     = cast<ClassTemplateDecl>(Name.getAsTemplateDecl()); | 
 | 5443 |  | 
 | 5444 |   // Check that the specialization uses the same tag kind as the | 
 | 5445 |   // original template. | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 5446 |   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); | 
 | 5447 |   assert(Kind != TTK_Enum && | 
 | 5448 |          "Invalid enum tag in class template explicit instantiation!"); | 
| Douglas Gregor | 501c5ce | 2009-05-14 16:41:31 +0000 | [diff] [blame] | 5449 |   if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(), | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5450 |                                     Kind, KWLoc, | 
| Douglas Gregor | 501c5ce | 2009-05-14 16:41:31 +0000 | [diff] [blame] | 5451 |                                     *ClassTemplate->getIdentifier())) { | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5452 |     Diag(KWLoc, diag::err_use_with_wrong_tag) | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5453 |       << ClassTemplate | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 5454 |       << FixItHint::CreateReplacement(KWLoc, | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5455 |                             ClassTemplate->getTemplatedDecl()->getKindName()); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5456 |     Diag(ClassTemplate->getTemplatedDecl()->getLocation(), | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5457 |          diag::note_previous_use); | 
 | 5458 |     Kind = ClassTemplate->getTemplatedDecl()->getTagKind(); | 
 | 5459 |   } | 
 | 5460 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5461 |   // C++0x [temp.explicit]p2: | 
 | 5462 |   //   There are two forms of explicit instantiation: an explicit instantiation | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5463 |   //   definition and an explicit instantiation declaration. An explicit | 
 | 5464 |   //   instantiation declaration begins with the extern keyword. [...] | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 5465 |   TemplateSpecializationKind TSK | 
 | 5466 |     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition | 
 | 5467 |                            : TSK_ExplicitInstantiationDeclaration; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5468 |  | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5469 |   // Translate the parser's template argument list in our AST format. | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5470 |   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); | 
| Douglas Gregor | 314b97f | 2009-11-10 19:49:08 +0000 | [diff] [blame] | 5471 |   translateTemplateArguments(TemplateArgsIn, TemplateArgs); | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5472 |  | 
 | 5473 |   // Check that the template argument list is well-formed for this | 
 | 5474 |   // template. | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 5475 |   llvm::SmallVector<TemplateArgument, 4> Converted; | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5476 |   if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc, | 
 | 5477 |                                 TemplateArgs, false, Converted)) | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5478 |     return true; | 
 | 5479 |  | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 5480 |   assert((Converted.size() == ClassTemplate->getTemplateParameters()->size()) && | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5481 |          "Converted template argument list is too short!"); | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5482 |  | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5483 |   // Find the class template specialization declaration that | 
 | 5484 |   // corresponds to these arguments. | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5485 |   void *InsertPos = 0; | 
 | 5486 |   ClassTemplateSpecializationDecl *PrevDecl | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 5487 |     = ClassTemplate->findSpecialization(Converted.data(), | 
 | 5488 |                                         Converted.size(), InsertPos); | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5489 |  | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5490 |   TemplateSpecializationKind PrevDecl_TSK | 
 | 5491 |     = PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared; | 
 | 5492 |  | 
| Douglas Gregor | d5cb876 | 2009-10-07 00:13:32 +0000 | [diff] [blame] | 5493 |   // C++0x [temp.explicit]p2: | 
 | 5494 |   //   [...] An explicit instantiation shall appear in an enclosing | 
 | 5495 |   //   namespace of its template. [...] | 
 | 5496 |   // | 
 | 5497 |   // This is C++ DR 275. | 
| Douglas Gregor | 669eed8 | 2010-07-13 00:10:04 +0000 | [diff] [blame] | 5498 |   if (CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc, | 
 | 5499 |                                       SS.isSet())) | 
 | 5500 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5501 |  | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5502 |   ClassTemplateSpecializationDecl *Specialization = 0; | 
 | 5503 |  | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5504 |   bool HasNoEffect = false; | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5505 |   if (PrevDecl) { | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 5506 |     if (CheckSpecializationInstantiationRedecl(TemplateNameLoc, TSK, | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5507 |                                                PrevDecl, PrevDecl_TSK, | 
| Douglas Gregor | 89a5bea | 2009-10-15 22:53:21 +0000 | [diff] [blame] | 5508 |                                             PrevDecl->getPointOfInstantiation(), | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5509 |                                                HasNoEffect)) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5510 |       return PrevDecl; | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5511 |  | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5512 |     // Even though HasNoEffect == true means that this explicit instantiation | 
 | 5513 |     // has no effect on semantics, we go on to put its syntax in the AST. | 
 | 5514 |  | 
 | 5515 |     if (PrevDecl_TSK == TSK_ImplicitInstantiation || | 
 | 5516 |         PrevDecl_TSK == TSK_Undeclared) { | 
| Douglas Gregor | 52604ab | 2009-09-11 21:19:12 +0000 | [diff] [blame] | 5517 |       // Since the only prior class template specialization with these | 
 | 5518 |       // arguments was referenced but not declared, reuse that | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5519 |       // declaration node as our own, updating the source location | 
 | 5520 |       // for the template name to reflect our new declaration. | 
 | 5521 |       // (Other source locations will be updated later.) | 
| Douglas Gregor | 52604ab | 2009-09-11 21:19:12 +0000 | [diff] [blame] | 5522 |       Specialization = PrevDecl; | 
 | 5523 |       Specialization->setLocation(TemplateNameLoc); | 
 | 5524 |       PrevDecl = 0; | 
 | 5525 |     } | 
| Douglas Gregor | 89a5bea | 2009-10-15 22:53:21 +0000 | [diff] [blame] | 5526 |   } | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5527 |  | 
| Douglas Gregor | 52604ab | 2009-09-11 21:19:12 +0000 | [diff] [blame] | 5528 |   if (!Specialization) { | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5529 |     // Create a new class template specialization declaration node for | 
 | 5530 |     // this explicit specialization. | 
 | 5531 |     Specialization | 
| Douglas Gregor | 13c8577 | 2010-05-06 00:28:52 +0000 | [diff] [blame] | 5532 |       = ClassTemplateSpecializationDecl::Create(Context, Kind, | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5533 |                                              ClassTemplate->getDeclContext(), | 
| Abramo Bagnara | ba877ad | 2011-03-09 14:09:51 +0000 | [diff] [blame] | 5534 |                                                 KWLoc, TemplateNameLoc, | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5535 |                                                 ClassTemplate, | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 5536 |                                                 Converted.data(), | 
 | 5537 |                                                 Converted.size(), | 
 | 5538 |                                                 PrevDecl); | 
| John McCall | b621766 | 2010-03-15 10:12:16 +0000 | [diff] [blame] | 5539 |     SetNestedNameSpecifier(Specialization, SS); | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5540 |  | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 5541 |     if (!HasNoEffect && !PrevDecl) { | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5542 |       // Insert the new specialization. | 
| Argyrios Kyrtzidis | cc0b1bc | 2010-07-20 13:59:28 +0000 | [diff] [blame] | 5543 |       ClassTemplate->AddSpecialization(Specialization, InsertPos); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5544 |     } | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5545 |   } | 
 | 5546 |  | 
 | 5547 |   // Build the fully-sugared type for this explicit instantiation as | 
 | 5548 |   // the user wrote in the explicit instantiation itself. This means | 
 | 5549 |   // that we'll pretty-print the type retrieved from the | 
 | 5550 |   // specialization's declaration the way that the user actually wrote | 
 | 5551 |   // the explicit instantiation, rather than formatting the name based | 
 | 5552 |   // on the "canonical" representation used to store the template | 
 | 5553 |   // arguments in the specialization. | 
| John McCall | 3cb0ebd | 2010-03-10 03:28:59 +0000 | [diff] [blame] | 5554 |   TypeSourceInfo *WrittenTy | 
 | 5555 |     = Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc, | 
 | 5556 |                                                 TemplateArgs, | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5557 |                                   Context.getTypeDeclType(Specialization)); | 
 | 5558 |   Specialization->setTypeAsWritten(WrittenTy); | 
 | 5559 |   TemplateArgsIn.release(); | 
 | 5560 |  | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5561 |   // Set source locations for keywords. | 
 | 5562 |   Specialization->setExternLoc(ExternLoc); | 
 | 5563 |   Specialization->setTemplateKeywordLoc(TemplateLoc); | 
 | 5564 |  | 
 | 5565 |   // Add the explicit instantiation into its lexical context. However, | 
 | 5566 |   // since explicit instantiations are never found by name lookup, we | 
 | 5567 |   // just put it into the declaration context directly. | 
 | 5568 |   Specialization->setLexicalDeclContext(CurContext); | 
 | 5569 |   CurContext->addDecl(Specialization); | 
 | 5570 |  | 
 | 5571 |   // Syntax is now OK, so return if it has no other effect on semantics. | 
 | 5572 |   if (HasNoEffect) { | 
 | 5573 |     // Set the template specialization kind. | 
 | 5574 |     Specialization->setTemplateSpecializationKind(TSK); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5575 |     return Specialization; | 
| Douglas Gregor | d78f598 | 2009-11-25 06:01:46 +0000 | [diff] [blame] | 5576 |   } | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5577 |  | 
 | 5578 |   // C++ [temp.explicit]p3: | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5579 |   //   A definition of a class template or class member template | 
 | 5580 |   //   shall be in scope at the point of the explicit instantiation of | 
 | 5581 |   //   the class template or class member template. | 
 | 5582 |   // | 
 | 5583 |   // This check comes when we actually try to perform the | 
 | 5584 |   // instantiation. | 
| Douglas Gregor | 89a5bea | 2009-10-15 22:53:21 +0000 | [diff] [blame] | 5585 |   ClassTemplateSpecializationDecl *Def | 
 | 5586 |     = cast_or_null<ClassTemplateSpecializationDecl>( | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 5587 |                                               Specialization->getDefinition()); | 
| Douglas Gregor | 89a5bea | 2009-10-15 22:53:21 +0000 | [diff] [blame] | 5588 |   if (!Def) | 
| Douglas Gregor | 972e6ce | 2009-10-27 06:26:26 +0000 | [diff] [blame] | 5589 |     InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5590 |   else if (TSK == TSK_ExplicitInstantiationDefinition) { | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 5591 |     MarkVTableUsed(TemplateNameLoc, Specialization, true); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5592 |     Specialization->setPointOfInstantiation(Def->getPointOfInstantiation()); | 
 | 5593 |   } | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 5594 |  | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 5595 |   // Instantiate the members of this class template specialization. | 
 | 5596 |   Def = cast_or_null<ClassTemplateSpecializationDecl>( | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 5597 |                                        Specialization->getDefinition()); | 
| Rafael Espindola | b0f65ca | 2010-03-22 23:12:48 +0000 | [diff] [blame] | 5598 |   if (Def) { | 
| Rafael Espindola | f075b22 | 2010-03-23 19:55:22 +0000 | [diff] [blame] | 5599 |     TemplateSpecializationKind Old_TSK = Def->getTemplateSpecializationKind(); | 
 | 5600 |  | 
 | 5601 |     // Fix a TSK_ExplicitInstantiationDeclaration followed by a | 
 | 5602 |     // TSK_ExplicitInstantiationDefinition | 
 | 5603 |     if (Old_TSK == TSK_ExplicitInstantiationDeclaration && | 
 | 5604 |         TSK == TSK_ExplicitInstantiationDefinition) | 
 | 5605 |       Def->setTemplateSpecializationKind(TSK); | 
| Rafael Espindola | b0f65ca | 2010-03-22 23:12:48 +0000 | [diff] [blame] | 5606 |  | 
| Douglas Gregor | 89a5bea | 2009-10-15 22:53:21 +0000 | [diff] [blame] | 5607 |     InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK); | 
| Rafael Espindola | b0f65ca | 2010-03-22 23:12:48 +0000 | [diff] [blame] | 5608 |   } | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5609 |  | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5610 |   // Set the template specialization kind. | 
 | 5611 |   Specialization->setTemplateSpecializationKind(TSK); | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5612 |   return Specialization; | 
| Douglas Gregor | 93dfdb1 | 2009-05-13 00:25:59 +0000 | [diff] [blame] | 5613 | } | 
 | 5614 |  | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5615 | // Explicit instantiation of a member class of a class template. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5616 | DeclResult | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5617 | Sema::ActOnExplicitInstantiation(Scope *S, | 
| Douglas Gregor | 45f9655 | 2009-09-04 06:33:52 +0000 | [diff] [blame] | 5618 |                                  SourceLocation ExternLoc, | 
 | 5619 |                                  SourceLocation TemplateLoc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 5620 |                                  unsigned TagSpec, | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5621 |                                  SourceLocation KWLoc, | 
| Jeffrey Yasskin | 9ab1454 | 2010-04-08 16:38:48 +0000 | [diff] [blame] | 5622 |                                  CXXScopeSpec &SS, | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5623 |                                  IdentifierInfo *Name, | 
 | 5624 |                                  SourceLocation NameLoc, | 
 | 5625 |                                  AttributeList *Attr) { | 
 | 5626 |  | 
| Douglas Gregor | 402abb5 | 2009-05-28 23:31:59 +0000 | [diff] [blame] | 5627 |   bool Owned = false; | 
| John McCall | c4e7019 | 2009-09-11 04:59:25 +0000 | [diff] [blame] | 5628 |   bool IsDependent = false; | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 5629 |   Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference, | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5630 |                         KWLoc, SS, Name, NameLoc, Attr, AS_none, | 
 | 5631 |                         MultiTemplateParamsArg(*this, 0, 0), | 
| Abramo Bagnara | a88cefd | 2010-12-03 18:54:17 +0000 | [diff] [blame] | 5632 |                         Owned, IsDependent, false, false, | 
| Douglas Gregor | 1274ccd | 2010-10-08 23:50:27 +0000 | [diff] [blame] | 5633 |                         TypeResult()); | 
| John McCall | c4e7019 | 2009-09-11 04:59:25 +0000 | [diff] [blame] | 5634 |   assert(!IsDependent && "explicit instantiation of dependent name not yet handled"); | 
 | 5635 |  | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5636 |   if (!TagD) | 
 | 5637 |     return true; | 
 | 5638 |  | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5639 |   TagDecl *Tag = cast<TagDecl>(TagD); | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5640 |   if (Tag->isEnum()) { | 
 | 5641 |     Diag(TemplateLoc, diag::err_explicit_instantiation_enum) | 
 | 5642 |       << Context.getTypeDeclType(Tag); | 
 | 5643 |     return true; | 
 | 5644 |   } | 
 | 5645 |  | 
| Douglas Gregor | d0c8737 | 2009-05-27 17:30:49 +0000 | [diff] [blame] | 5646 |   if (Tag->isInvalidDecl()) | 
 | 5647 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5648 |  | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5649 |   CXXRecordDecl *Record = cast<CXXRecordDecl>(Tag); | 
 | 5650 |   CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass(); | 
 | 5651 |   if (!Pattern) { | 
 | 5652 |     Diag(TemplateLoc, diag::err_explicit_instantiation_nontemplate_type) | 
 | 5653 |       << Context.getTypeDeclType(Record); | 
 | 5654 |     Diag(Record->getLocation(), diag::note_nontemplate_decl_here); | 
 | 5655 |     return true; | 
 | 5656 |   } | 
 | 5657 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5658 |   // C++0x [temp.explicit]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5659 |   //   If the explicit instantiation is for a class or member class, the | 
 | 5660 |   //   elaborated-type-specifier in the declaration shall include a | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5661 |   //   simple-template-id. | 
 | 5662 |   // | 
 | 5663 |   // C++98 has the same restriction, just worded differently. | 
 | 5664 |   if (!ScopeSpecifierHasTemplateId(SS)) | 
| Douglas Gregor | a2dd828 | 2010-06-16 16:26:47 +0000 | [diff] [blame] | 5665 |     Diag(TemplateLoc, diag::ext_explicit_instantiation_without_qualified_id) | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5666 |       << Record << SS.getRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5667 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5668 |   // C++0x [temp.explicit]p2: | 
 | 5669 |   //   There are two forms of explicit instantiation: an explicit instantiation | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5670 |   //   definition and an explicit instantiation declaration. An explicit | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5671 |   //   instantiation declaration begins with the extern keyword. [...] | 
| Douglas Gregor | a74bbe2 | 2009-10-14 21:46:58 +0000 | [diff] [blame] | 5672 |   TemplateSpecializationKind TSK | 
 | 5673 |     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition | 
 | 5674 |                            : TSK_ExplicitInstantiationDeclaration; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5675 |  | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5676 |   // C++0x [temp.explicit]p2: | 
 | 5677 |   //   [...] An explicit instantiation shall appear in an enclosing | 
 | 5678 |   //   namespace of its template. [...] | 
 | 5679 |   // | 
 | 5680 |   // This is C++ DR 275. | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5681 |   CheckExplicitInstantiationScope(*this, Record, NameLoc, true); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5682 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5683 |   // Verify that it is okay to explicitly instantiate here. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5684 |   CXXRecordDecl *PrevDecl | 
| Douglas Gregor | 583f33b | 2009-10-15 18:07:02 +0000 | [diff] [blame] | 5685 |     = cast_or_null<CXXRecordDecl>(Record->getPreviousDeclaration()); | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 5686 |   if (!PrevDecl && Record->getDefinition()) | 
| Douglas Gregor | 583f33b | 2009-10-15 18:07:02 +0000 | [diff] [blame] | 5687 |     PrevDecl = Record; | 
 | 5688 |   if (PrevDecl) { | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5689 |     MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo(); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5690 |     bool HasNoEffect = false; | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5691 |     assert(MSInfo && "No member specialization information?"); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5692 |     if (CheckSpecializationInstantiationRedecl(TemplateLoc, TSK, | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5693 |                                                PrevDecl, | 
 | 5694 |                                         MSInfo->getTemplateSpecializationKind(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5695 |                                              MSInfo->getPointOfInstantiation(), | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5696 |                                                HasNoEffect)) | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5697 |       return true; | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5698 |     if (HasNoEffect) | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5699 |       return TagD; | 
 | 5700 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5701 |  | 
| Douglas Gregor | 89a5bea | 2009-10-15 22:53:21 +0000 | [diff] [blame] | 5702 |   CXXRecordDecl *RecordDef | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 5703 |     = cast_or_null<CXXRecordDecl>(Record->getDefinition()); | 
| Douglas Gregor | 89a5bea | 2009-10-15 22:53:21 +0000 | [diff] [blame] | 5704 |   if (!RecordDef) { | 
| Douglas Gregor | bf7643e | 2009-10-15 12:53:22 +0000 | [diff] [blame] | 5705 |     // C++ [temp.explicit]p3: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5706 |     //   A definition of a member class of a class template shall be in scope | 
| Douglas Gregor | bf7643e | 2009-10-15 12:53:22 +0000 | [diff] [blame] | 5707 |     //   at the point of an explicit instantiation of the member class. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5708 |     CXXRecordDecl *Def | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 5709 |       = cast_or_null<CXXRecordDecl>(Pattern->getDefinition()); | 
| Douglas Gregor | bf7643e | 2009-10-15 12:53:22 +0000 | [diff] [blame] | 5710 |     if (!Def) { | 
| Douglas Gregor | e2d3a3d | 2009-10-15 14:05:49 +0000 | [diff] [blame] | 5711 |       Diag(TemplateLoc, diag::err_explicit_instantiation_undefined_member) | 
 | 5712 |         << 0 << Record->getDeclName() << Record->getDeclContext(); | 
| Douglas Gregor | bf7643e | 2009-10-15 12:53:22 +0000 | [diff] [blame] | 5713 |       Diag(Pattern->getLocation(), diag::note_forward_declaration) | 
 | 5714 |         << Pattern; | 
 | 5715 |       return true; | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 5716 |     } else { | 
 | 5717 |       if (InstantiateClass(NameLoc, Record, Def, | 
 | 5718 |                            getTemplateInstantiationArgs(Record), | 
 | 5719 |                            TSK)) | 
 | 5720 |         return true; | 
 | 5721 |  | 
| Douglas Gregor | 952b017 | 2010-02-11 01:04:33 +0000 | [diff] [blame] | 5722 |       RecordDef = cast_or_null<CXXRecordDecl>(Record->getDefinition()); | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 5723 |       if (!RecordDef) | 
 | 5724 |         return true; | 
 | 5725 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5726 |   } | 
 | 5727 |  | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 5728 |   // Instantiate all of the members of the class. | 
 | 5729 |   InstantiateClassMembers(NameLoc, RecordDef, | 
 | 5730 |                           getTemplateInstantiationArgs(Record), TSK); | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5731 |  | 
| Douglas Gregor | 6fb745b | 2010-05-13 16:44:06 +0000 | [diff] [blame] | 5732 |   if (TSK == TSK_ExplicitInstantiationDefinition) | 
 | 5733 |     MarkVTableUsed(NameLoc, RecordDef, true); | 
 | 5734 |  | 
| Mike Stump | 390b4cc | 2009-05-16 07:39:55 +0000 | [diff] [blame] | 5735 |   // FIXME: We don't have any representation for explicit instantiations of | 
 | 5736 |   // member classes. Such a representation is not needed for compilation, but it | 
 | 5737 |   // should be available for clients that want to see all of the declarations in | 
 | 5738 |   // the source code. | 
| Douglas Gregor | 3f5b61c | 2009-05-14 00:28:11 +0000 | [diff] [blame] | 5739 |   return TagD; | 
 | 5740 | } | 
 | 5741 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 5742 | DeclResult Sema::ActOnExplicitInstantiation(Scope *S, | 
 | 5743 |                                             SourceLocation ExternLoc, | 
 | 5744 |                                             SourceLocation TemplateLoc, | 
 | 5745 |                                             Declarator &D) { | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5746 |   // Explicit instantiations always require a name. | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 5747 |   // TODO: check if/when DNInfo should replace Name. | 
 | 5748 |   DeclarationNameInfo NameInfo = GetNameForDeclarator(D); | 
 | 5749 |   DeclarationName Name = NameInfo.getName(); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5750 |   if (!Name) { | 
 | 5751 |     if (!D.isInvalidType()) | 
 | 5752 |       Diag(D.getDeclSpec().getSourceRange().getBegin(), | 
 | 5753 |            diag::err_explicit_instantiation_requires_name) | 
 | 5754 |         << D.getDeclSpec().getSourceRange() | 
 | 5755 |         << D.getSourceRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5756 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5757 |     return true; | 
 | 5758 |   } | 
 | 5759 |  | 
 | 5760 |   // The scope passed in may not be a decl scope.  Zip up the scope tree until | 
 | 5761 |   // we find one that is. | 
 | 5762 |   while ((S->getFlags() & Scope::DeclScope) == 0 || | 
 | 5763 |          (S->getFlags() & Scope::TemplateParamScope) != 0) | 
 | 5764 |     S = S->getParent(); | 
 | 5765 |  | 
 | 5766 |   // Determine the type of the declaration. | 
| John McCall | bf1a028 | 2010-06-04 23:28:52 +0000 | [diff] [blame] | 5767 |   TypeSourceInfo *T = GetTypeForDeclarator(D, S); | 
 | 5768 |   QualType R = T->getType(); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5769 |   if (R.isNull()) | 
 | 5770 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5771 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5772 |   if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) { | 
 | 5773 |     // Cannot explicitly instantiate a typedef. | 
 | 5774 |     Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_of_typedef) | 
 | 5775 |       << Name; | 
 | 5776 |     return true; | 
 | 5777 |   } | 
 | 5778 |  | 
| Douglas Gregor | 663b5a0 | 2009-10-14 20:14:33 +0000 | [diff] [blame] | 5779 |   // C++0x [temp.explicit]p1: | 
 | 5780 |   //   [...] An explicit instantiation of a function template shall not use the | 
 | 5781 |   //   inline or constexpr specifiers. | 
 | 5782 |   // Presumably, this also applies to member functions of class templates as | 
 | 5783 |   // well. | 
 | 5784 |   if (D.getDeclSpec().isInlineSpecified() && getLangOptions().CPlusPlus0x) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5785 |     Diag(D.getDeclSpec().getInlineSpecLoc(), | 
| Douglas Gregor | 663b5a0 | 2009-10-14 20:14:33 +0000 | [diff] [blame] | 5786 |          diag::err_explicit_instantiation_inline) | 
| Douglas Gregor | 849b243 | 2010-03-31 17:46:05 +0000 | [diff] [blame] | 5787 |       <<FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5788 |  | 
| Douglas Gregor | 663b5a0 | 2009-10-14 20:14:33 +0000 | [diff] [blame] | 5789 |   // FIXME: check for constexpr specifier. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5790 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5791 |   // C++0x [temp.explicit]p2: | 
 | 5792 |   //   There are two forms of explicit instantiation: an explicit instantiation | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5793 |   //   definition and an explicit instantiation declaration. An explicit | 
 | 5794 |   //   instantiation declaration begins with the extern keyword. [...] | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5795 |   TemplateSpecializationKind TSK | 
 | 5796 |     = ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition | 
 | 5797 |                            : TSK_ExplicitInstantiationDeclaration; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5798 |  | 
| Abramo Bagnara | 2577743 | 2010-08-11 22:01:17 +0000 | [diff] [blame] | 5799 |   LookupResult Previous(*this, NameInfo, LookupOrdinaryName); | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 5800 |   LookupParsedName(Previous, S, &D.getCXXScopeSpec()); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5801 |  | 
 | 5802 |   if (!R->isFunctionType()) { | 
 | 5803 |     // C++ [temp.explicit]p1: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5804 |     //   A [...] static data member of a class template can be explicitly | 
 | 5805 |     //   instantiated from the member definition associated with its class | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5806 |     //   template. | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 5807 |     if (Previous.isAmbiguous()) | 
 | 5808 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5809 |  | 
| John McCall | 1bcee0a | 2009-12-02 08:25:40 +0000 | [diff] [blame] | 5810 |     VarDecl *Prev = Previous.getAsSingle<VarDecl>(); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5811 |     if (!Prev || !Prev->isStaticDataMember()) { | 
 | 5812 |       // We expect to see a data data member here. | 
 | 5813 |       Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_not_known) | 
 | 5814 |         << Name; | 
 | 5815 |       for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end(); | 
 | 5816 |            P != PEnd; ++P) | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 5817 |         Diag((*P)->getLocation(), diag::note_explicit_instantiation_here); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5818 |       return true; | 
 | 5819 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5820 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5821 |     if (!Prev->getInstantiatedFromStaticDataMember()) { | 
 | 5822 |       // FIXME: Check for explicit specialization? | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5823 |       Diag(D.getIdentifierLoc(), | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5824 |            diag::err_explicit_instantiation_data_member_not_instantiated) | 
 | 5825 |         << Prev; | 
 | 5826 |       Diag(Prev->getLocation(), diag::note_explicit_instantiation_here); | 
 | 5827 |       // FIXME: Can we provide a note showing where this was declared? | 
 | 5828 |       return true; | 
 | 5829 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5830 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5831 |     // C++0x [temp.explicit]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5832 |     //   If the explicit instantiation is for a member function, a member class | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5833 |     //   or a static data member of a class template specialization, the name of | 
 | 5834 |     //   the class template specialization in the qualified-id for the member | 
 | 5835 |     //   name shall be a simple-template-id. | 
 | 5836 |     // | 
 | 5837 |     // C++98 has the same restriction, just worded differently. | 
 | 5838 |     if (!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec())) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5839 |       Diag(D.getIdentifierLoc(), | 
| Douglas Gregor | a2dd828 | 2010-06-16 16:26:47 +0000 | [diff] [blame] | 5840 |            diag::ext_explicit_instantiation_without_qualified_id) | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5841 |         << Prev << D.getCXXScopeSpec().getRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5842 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5843 |     // Check the scope of this explicit instantiation. | 
 | 5844 |     CheckExplicitInstantiationScope(*this, Prev, D.getIdentifierLoc(), true); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5845 |  | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5846 |     // Verify that it is okay to explicitly instantiate here. | 
 | 5847 |     MemberSpecializationInfo *MSInfo = Prev->getMemberSpecializationInfo(); | 
 | 5848 |     assert(MSInfo && "Missing static data member specialization info?"); | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5849 |     bool HasNoEffect = false; | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 5850 |     if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK, Prev, | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5851 |                                         MSInfo->getTemplateSpecializationKind(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5852 |                                               MSInfo->getPointOfInstantiation(), | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5853 |                                                HasNoEffect)) | 
| Douglas Gregor | 454885e | 2009-10-15 15:54:05 +0000 | [diff] [blame] | 5854 |       return true; | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5855 |     if (HasNoEffect) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5856 |       return (Decl*) 0; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5857 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5858 |     // Instantiate static data member. | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5859 |     Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5860 |     if (TSK == TSK_ExplicitInstantiationDefinition) | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 5861 |       InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5862 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5863 |     // FIXME: Create an ExplicitInstantiation node? | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5864 |     return (Decl*) 0; | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5865 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5866 |  | 
 | 5867 |   // If the declarator is a template-id, translate the parser's template | 
| Douglas Gregor | 0b60d9e | 2009-09-25 23:53:26 +0000 | [diff] [blame] | 5868 |   // argument list into our AST format. | 
| Douglas Gregor | db422df | 2009-09-25 21:45:23 +0000 | [diff] [blame] | 5869 |   bool HasExplicitTemplateArgs = false; | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5870 |   TemplateArgumentListInfo TemplateArgs; | 
| Douglas Gregor | 3f9a056 | 2009-11-03 01:35:08 +0000 | [diff] [blame] | 5871 |   if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) { | 
 | 5872 |     TemplateIdAnnotation *TemplateId = D.getName().TemplateId; | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5873 |     TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc); | 
 | 5874 |     TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc); | 
| Douglas Gregor | db422df | 2009-09-25 21:45:23 +0000 | [diff] [blame] | 5875 |     ASTTemplateArgsPtr TemplateArgsPtr(*this, | 
 | 5876 |                                        TemplateId->getTemplateArgs(), | 
| Douglas Gregor | db422df | 2009-09-25 21:45:23 +0000 | [diff] [blame] | 5877 |                                        TemplateId->NumArgs); | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5878 |     translateTemplateArguments(TemplateArgsPtr, TemplateArgs); | 
| Douglas Gregor | db422df | 2009-09-25 21:45:23 +0000 | [diff] [blame] | 5879 |     HasExplicitTemplateArgs = true; | 
| Douglas Gregor | b2f81cf | 2009-10-01 23:51:25 +0000 | [diff] [blame] | 5880 |     TemplateArgsPtr.release(); | 
| Douglas Gregor | db422df | 2009-09-25 21:45:23 +0000 | [diff] [blame] | 5881 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5882 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5883 |   // C++ [temp.explicit]p1: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5884 |   //   A [...] function [...] can be explicitly instantiated from its template. | 
 | 5885 |   //   A member function [...] of a class template can be explicitly | 
 | 5886 |   //  instantiated from the member definition associated with its class | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5887 |   //  template. | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5888 |   UnresolvedSet<8> Matches; | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5889 |   for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end(); | 
 | 5890 |        P != PEnd; ++P) { | 
 | 5891 |     NamedDecl *Prev = *P; | 
| Douglas Gregor | db422df | 2009-09-25 21:45:23 +0000 | [diff] [blame] | 5892 |     if (!HasExplicitTemplateArgs) { | 
 | 5893 |       if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) { | 
 | 5894 |         if (Context.hasSameUnqualifiedType(Method->getType(), R)) { | 
 | 5895 |           Matches.clear(); | 
| Douglas Gregor | 48026d2 | 2010-01-11 18:40:55 +0000 | [diff] [blame] | 5896 |  | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5897 |           Matches.addDecl(Method, P.getAccess()); | 
| Douglas Gregor | 48026d2 | 2010-01-11 18:40:55 +0000 | [diff] [blame] | 5898 |           if (Method->getTemplateSpecializationKind() == TSK_Undeclared) | 
 | 5899 |             break; | 
| Douglas Gregor | db422df | 2009-09-25 21:45:23 +0000 | [diff] [blame] | 5900 |         } | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5901 |       } | 
 | 5902 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5903 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5904 |     FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Prev); | 
 | 5905 |     if (!FunTmpl) | 
 | 5906 |       continue; | 
 | 5907 |  | 
| John McCall | 5769d61 | 2010-02-08 23:07:23 +0000 | [diff] [blame] | 5908 |     TemplateDeductionInfo Info(Context, D.getIdentifierLoc()); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5909 |     FunctionDecl *Specialization = 0; | 
 | 5910 |     if (TemplateDeductionResult TDK | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5911 |           = DeduceTemplateArguments(FunTmpl, | 
| John McCall | d5532b6 | 2009-11-23 01:53:49 +0000 | [diff] [blame] | 5912 |                                (HasExplicitTemplateArgs ? &TemplateArgs : 0), | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5913 |                                     R, Specialization, Info)) { | 
 | 5914 |       // FIXME: Keep track of almost-matches? | 
 | 5915 |       (void)TDK; | 
 | 5916 |       continue; | 
 | 5917 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5918 |  | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5919 |     Matches.addDecl(Specialization, P.getAccess()); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5920 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5921 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5922 |   // Find the most specialized function template specialization. | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5923 |   UnresolvedSetIterator Result | 
| Douglas Gregor | 5c7bf42 | 2011-01-11 17:34:58 +0000 | [diff] [blame] | 5924 |     = getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, 0, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5925 |                          D.getIdentifierLoc(), | 
| Douglas Gregor | fe6b2d4 | 2010-03-29 23:34:08 +0000 | [diff] [blame] | 5926 |                      PDiag(diag::err_explicit_instantiation_not_known) << Name, | 
 | 5927 |                      PDiag(diag::err_explicit_instantiation_ambiguous) << Name, | 
 | 5928 |                          PDiag(diag::note_explicit_instantiation_candidate)); | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5929 |  | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5930 |   if (Result == Matches.end()) | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5931 |     return true; | 
| John McCall | c373d48 | 2010-01-27 01:50:18 +0000 | [diff] [blame] | 5932 |  | 
 | 5933 |   // Ignore access control bits, we don't need them for redeclaration checking. | 
 | 5934 |   FunctionDecl *Specialization = cast<FunctionDecl>(*Result); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5935 |  | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5936 |   if (Specialization->getTemplateSpecializationKind() == TSK_Undeclared) { | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5937 |     Diag(D.getIdentifierLoc(), | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5938 |          diag::err_explicit_instantiation_member_function_not_instantiated) | 
 | 5939 |       << Specialization | 
 | 5940 |       << (Specialization->getTemplateSpecializationKind() == | 
 | 5941 |           TSK_ExplicitSpecialization); | 
 | 5942 |     Diag(Specialization->getLocation(), diag::note_explicit_instantiation_here); | 
 | 5943 |     return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5944 |   } | 
 | 5945 |  | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5946 |   FunctionDecl *PrevDecl = Specialization->getPreviousDeclaration(); | 
| Douglas Gregor | 583f33b | 2009-10-15 18:07:02 +0000 | [diff] [blame] | 5947 |   if (!PrevDecl && Specialization->isThisDeclarationADefinition()) | 
 | 5948 |     PrevDecl = Specialization; | 
 | 5949 |  | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5950 |   if (PrevDecl) { | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5951 |     bool HasNoEffect = false; | 
| Douglas Gregor | 0d03514 | 2009-10-27 18:42:08 +0000 | [diff] [blame] | 5952 |     if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5953 |                                                PrevDecl, | 
 | 5954 |                                      PrevDecl->getTemplateSpecializationKind(), | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5955 |                                           PrevDecl->getPointOfInstantiation(), | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5956 |                                                HasNoEffect)) | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5957 |       return true; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5958 |  | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5959 |     // FIXME: We may still want to build some representation of this | 
 | 5960 |     // explicit specialization. | 
| Abramo Bagnara | c98971d | 2010-06-12 07:44:57 +0000 | [diff] [blame] | 5961 |     if (HasNoEffect) | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5962 |       return (Decl*) 0; | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5963 |   } | 
| Anders Carlsson | 26d6e9d | 2009-11-24 05:34:41 +0000 | [diff] [blame] | 5964 |  | 
 | 5965 |   Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5966 |  | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5967 |   if (TSK == TSK_ExplicitInstantiationDefinition) | 
| Chandler Carruth | 58e390e | 2010-08-25 08:27:02 +0000 | [diff] [blame] | 5968 |     InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5969 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5970 |   // C++0x [temp.explicit]p2: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5971 |   //   If the explicit instantiation is for a member function, a member class | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5972 |   //   or a static data member of a class template specialization, the name of | 
 | 5973 |   //   the class template specialization in the qualified-id for the member | 
 | 5974 |   //   name shall be a simple-template-id. | 
 | 5975 |   // | 
 | 5976 |   // C++98 has the same restriction, just worded differently. | 
| Douglas Gregor | 0a897e3 | 2009-10-15 17:21:20 +0000 | [diff] [blame] | 5977 |   FunctionTemplateDecl *FunTmpl = Specialization->getPrimaryTemplate(); | 
| Douglas Gregor | 3f9a056 | 2009-11-03 01:35:08 +0000 | [diff] [blame] | 5978 |   if (D.getName().getKind() != UnqualifiedId::IK_TemplateId && !FunTmpl && | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5979 |       D.getCXXScopeSpec().isSet() && | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5980 |       !ScopeSpecifierHasTemplateId(D.getCXXScopeSpec())) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5981 |     Diag(D.getIdentifierLoc(), | 
| Douglas Gregor | a2dd828 | 2010-06-16 16:26:47 +0000 | [diff] [blame] | 5982 |          diag::ext_explicit_instantiation_without_qualified_id) | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5983 |     << Specialization << D.getCXXScopeSpec().getRange(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5984 |  | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5985 |   CheckExplicitInstantiationScope(*this, | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5986 |                    FunTmpl? (NamedDecl *)FunTmpl | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5987 |                           : Specialization->getInstantiatedFromMemberFunction(), | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5988 |                                   D.getIdentifierLoc(), | 
| Douglas Gregor | 558c032 | 2009-10-14 23:41:34 +0000 | [diff] [blame] | 5989 |                                   D.getCXXScopeSpec().isSet()); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 5990 |  | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5991 |   // FIXME: Create some kind of ExplicitInstantiationDecl here. | 
| John McCall | d226f65 | 2010-08-21 09:40:31 +0000 | [diff] [blame] | 5992 |   return (Decl*) 0; | 
| Douglas Gregor | d5a423b | 2009-09-25 18:43:00 +0000 | [diff] [blame] | 5993 | } | 
 | 5994 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 5995 | TypeResult | 
| John McCall | c4e7019 | 2009-09-11 04:59:25 +0000 | [diff] [blame] | 5996 | Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK, | 
 | 5997 |                         const CXXScopeSpec &SS, IdentifierInfo *Name, | 
 | 5998 |                         SourceLocation TagLoc, SourceLocation NameLoc) { | 
 | 5999 |   // This has to hold, because SS is expected to be defined. | 
 | 6000 |   assert(Name && "Expected a name in a dependent tag"); | 
 | 6001 |  | 
 | 6002 |   NestedNameSpecifier *NNS | 
 | 6003 |     = static_cast<NestedNameSpecifier *>(SS.getScopeRep()); | 
 | 6004 |   if (!NNS) | 
 | 6005 |     return true; | 
 | 6006 |  | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6007 |   TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec); | 
| Daniel Dunbar | 12c0ade | 2010-04-01 16:50:48 +0000 | [diff] [blame] | 6008 |  | 
| Douglas Gregor | 48c89f4 | 2010-04-24 16:38:41 +0000 | [diff] [blame] | 6009 |   if (TUK == TUK_Declaration || TUK == TUK_Definition) { | 
 | 6010 |     Diag(NameLoc, diag::err_dependent_tag_decl) | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6011 |       << (TUK == TUK_Definition) << Kind << SS.getRange(); | 
| Douglas Gregor | 48c89f4 | 2010-04-24 16:38:41 +0000 | [diff] [blame] | 6012 |     return true; | 
 | 6013 |   } | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6014 |  | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 6015 |   // Create the resulting type. | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6016 |   ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind); | 
| Douglas Gregor | 059101f | 2011-03-02 00:47:37 +0000 | [diff] [blame] | 6017 |   QualType Result = Context.getDependentNameType(Kwd, NNS, Name); | 
 | 6018 |    | 
 | 6019 |   // Create type-source location information for this type. | 
 | 6020 |   TypeLocBuilder TLB; | 
 | 6021 |   DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(Result); | 
 | 6022 |   TL.setKeywordLoc(TagLoc); | 
 | 6023 |   TL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
 | 6024 |   TL.setNameLoc(NameLoc); | 
 | 6025 |   return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result)); | 
| John McCall | c4e7019 | 2009-09-11 04:59:25 +0000 | [diff] [blame] | 6026 | } | 
 | 6027 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 6028 | TypeResult | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6029 | Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, | 
 | 6030 |                         const CXXScopeSpec &SS, const IdentifierInfo &II, | 
| Douglas Gregor | 1a15dae | 2010-06-16 22:31:08 +0000 | [diff] [blame] | 6031 |                         SourceLocation IdLoc) { | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6032 |   if (SS.isInvalid()) | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6033 |     return true; | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6034 |    | 
| Douglas Gregor | 1a15dae | 2010-06-16 22:31:08 +0000 | [diff] [blame] | 6035 |   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && | 
 | 6036 |       !getLangOptions().CPlusPlus0x) | 
 | 6037 |     Diag(TypenameLoc, diag::ext_typename_outside_of_template) | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6038 |       << FixItHint::CreateRemoval(TypenameLoc); | 
 | 6039 |  | 
| Douglas Gregor | 2494dd0 | 2011-03-01 01:34:45 +0000 | [diff] [blame] | 6040 |   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); | 
| Douglas Gregor | 9e87687 | 2011-03-01 18:12:44 +0000 | [diff] [blame] | 6041 |   QualType T = CheckTypenameType(TypenameLoc.isValid()? ETK_Typename : ETK_None, | 
 | 6042 |                                  TypenameLoc, QualifierLoc, II, IdLoc); | 
| Douglas Gregor | 31a19b6 | 2009-04-01 21:51:26 +0000 | [diff] [blame] | 6043 |   if (T.isNull()) | 
 | 6044 |     return true; | 
| John McCall | 63b4385 | 2010-04-29 23:50:39 +0000 | [diff] [blame] | 6045 |  | 
 | 6046 |   TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T); | 
 | 6047 |   if (isa<DependentNameType>(T)) { | 
 | 6048 |     DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc()); | 
| John McCall | 4e44983 | 2010-05-28 23:32:21 +0000 | [diff] [blame] | 6049 |     TL.setKeywordLoc(TypenameLoc); | 
| Douglas Gregor | 2494dd0 | 2011-03-01 01:34:45 +0000 | [diff] [blame] | 6050 |     TL.setQualifierLoc(QualifierLoc); | 
| John McCall | 4e44983 | 2010-05-28 23:32:21 +0000 | [diff] [blame] | 6051 |     TL.setNameLoc(IdLoc); | 
| John McCall | 63b4385 | 2010-04-29 23:50:39 +0000 | [diff] [blame] | 6052 |   } else { | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6053 |     ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc()); | 
| John McCall | 4e44983 | 2010-05-28 23:32:21 +0000 | [diff] [blame] | 6054 |     TL.setKeywordLoc(TypenameLoc); | 
| Douglas Gregor | 9e87687 | 2011-03-01 18:12:44 +0000 | [diff] [blame] | 6055 |     TL.setQualifierLoc(QualifierLoc); | 
| John McCall | 4e44983 | 2010-05-28 23:32:21 +0000 | [diff] [blame] | 6056 |     cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc); | 
| John McCall | 63b4385 | 2010-04-29 23:50:39 +0000 | [diff] [blame] | 6057 |   } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6058 |  | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 6059 |   return CreateParsedType(T, TSI); | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6060 | } | 
 | 6061 |  | 
| John McCall | f312b1e | 2010-08-26 23:41:50 +0000 | [diff] [blame] | 6062 | TypeResult | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6063 | Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,  | 
 | 6064 |                         const CXXScopeSpec &SS,  | 
 | 6065 |                         SourceLocation TemplateLoc,  | 
 | 6066 |                         TemplateTy TemplateIn, | 
 | 6067 |                         SourceLocation TemplateNameLoc, | 
 | 6068 |                         SourceLocation LAngleLoc, | 
 | 6069 |                         ASTTemplateArgsPtr TemplateArgsIn, | 
 | 6070 |                         SourceLocation RAngleLoc) { | 
| Douglas Gregor | 1a15dae | 2010-06-16 22:31:08 +0000 | [diff] [blame] | 6071 |   if (TypenameLoc.isValid() && S && !S->getTemplateParamParent() && | 
 | 6072 |       !getLangOptions().CPlusPlus0x) | 
 | 6073 |     Diag(TypenameLoc, diag::ext_typename_outside_of_template) | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6074 |     << FixItHint::CreateRemoval(TypenameLoc); | 
 | 6075 |    | 
 | 6076 |   // Translate the parser's template argument list in our AST format. | 
 | 6077 |   TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc); | 
 | 6078 |   translateTemplateArguments(TemplateArgsIn, TemplateArgs); | 
 | 6079 |    | 
 | 6080 |   TemplateName Template = TemplateIn.get(); | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6081 |   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) { | 
 | 6082 |     // Construct a dependent template specialization type. | 
 | 6083 |     assert(DTN && "dependent template has non-dependent name?"); | 
 | 6084 |     assert(DTN->getQualifier() | 
 | 6085 |            == static_cast<NestedNameSpecifier*>(SS.getScopeRep())); | 
 | 6086 |     QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename, | 
 | 6087 |                                                           DTN->getQualifier(), | 
 | 6088 |                                                           DTN->getIdentifier(), | 
 | 6089 |                                                                 TemplateArgs); | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6090 |      | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6091 |     // Create source-location information for this type. | 
| John McCall | 4e44983 | 2010-05-28 23:32:21 +0000 | [diff] [blame] | 6092 |     TypeLocBuilder Builder; | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6093 |     DependentTemplateSpecializationTypeLoc SpecTL  | 
 | 6094 |     = Builder.push<DependentTemplateSpecializationTypeLoc>(T); | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6095 |     SpecTL.setLAngleLoc(LAngleLoc); | 
 | 6096 |     SpecTL.setRAngleLoc(RAngleLoc); | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6097 |     SpecTL.setKeywordLoc(TypenameLoc); | 
| Douglas Gregor | 94fdffa | 2011-03-01 20:11:18 +0000 | [diff] [blame] | 6098 |     SpecTL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6099 |     SpecTL.setNameLoc(TemplateNameLoc); | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6100 |     for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) | 
 | 6101 |       SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6102 |     return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T)); | 
| Douglas Gregor | 6946baf | 2009-09-02 13:05:45 +0000 | [diff] [blame] | 6103 |   } | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6104 |    | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6105 |   QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs); | 
 | 6106 |   if (T.isNull()) | 
 | 6107 |     return true; | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6108 |    | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6109 |   // Provide source-location information for the template specialization  | 
 | 6110 |   // type. | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6111 |   TypeLocBuilder Builder; | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6112 |   TemplateSpecializationTypeLoc SpecTL  | 
 | 6113 |     = Builder.push<TemplateSpecializationTypeLoc>(T); | 
 | 6114 |    | 
 | 6115 |   // FIXME: No place to set the location of the 'template' keyword! | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6116 |   SpecTL.setLAngleLoc(LAngleLoc); | 
 | 6117 |   SpecTL.setRAngleLoc(RAngleLoc); | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6118 |   SpecTL.setTemplateNameLoc(TemplateNameLoc); | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6119 |   for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I) | 
 | 6120 |     SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo()); | 
 | 6121 |    | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6122 |   T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T); | 
 | 6123 |   ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T); | 
 | 6124 |   TL.setKeywordLoc(TypenameLoc); | 
| Douglas Gregor | 9e87687 | 2011-03-01 18:12:44 +0000 | [diff] [blame] | 6125 |   TL.setQualifierLoc(SS.getWithLocInContext(Context)); | 
 | 6126 |    | 
| Douglas Gregor | ef24c4b | 2011-03-01 16:44:30 +0000 | [diff] [blame] | 6127 |   TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T); | 
 | 6128 |   return CreateParsedType(T, TSI); | 
| Douglas Gregor | 1734317 | 2009-04-01 00:28:59 +0000 | [diff] [blame] | 6129 | } | 
 | 6130 |  | 
| Douglas Gregor | a02411e | 2011-02-27 22:46:49 +0000 | [diff] [blame] | 6131 |  | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6132 | /// \brief Build the type that describes a C++ typename specifier, | 
 | 6133 | /// e.g., "typename T::type". | 
 | 6134 | QualType | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6135 | Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,  | 
 | 6136 |                         SourceLocation KeywordLoc, | 
 | 6137 |                         NestedNameSpecifierLoc QualifierLoc,  | 
 | 6138 |                         const IdentifierInfo &II, | 
| Abramo Bagnara | e4da7a0 | 2010-05-19 21:37:53 +0000 | [diff] [blame] | 6139 |                         SourceLocation IILoc) { | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 6140 |   CXXScopeSpec SS; | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6141 |   SS.Adopt(QualifierLoc); | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6142 |  | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 6143 |   DeclContext *Ctx = computeDeclContext(SS); | 
 | 6144 |   if (!Ctx) { | 
 | 6145 |     // If the nested-name-specifier is dependent and couldn't be | 
 | 6146 |     // resolved to a type, build a typename type. | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6147 |     assert(QualifierLoc.getNestedNameSpecifier()->isDependent()); | 
 | 6148 |     return Context.getDependentNameType(Keyword,  | 
 | 6149 |                                         QualifierLoc.getNestedNameSpecifier(),  | 
 | 6150 |                                         &II); | 
| Douglas Gregor | 42af25f | 2009-05-11 19:58:34 +0000 | [diff] [blame] | 6151 |   } | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6152 |  | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 6153 |   // If the nested-name-specifier refers to the current instantiation, | 
 | 6154 |   // the "typename" keyword itself is superfluous. In C++03, the | 
 | 6155 |   // program is actually ill-formed. However, DR 382 (in C++0x CD1) | 
 | 6156 |   // allows such extraneous "typename" keywords, and we retroactively | 
| Douglas Gregor | 732281d | 2010-06-14 22:07:54 +0000 | [diff] [blame] | 6157 |   // apply this DR to C++03 code with only a warning. In any case we continue. | 
| Douglas Gregor | 42af25f | 2009-05-11 19:58:34 +0000 | [diff] [blame] | 6158 |  | 
| John McCall | 77bb1aa | 2010-05-01 00:40:08 +0000 | [diff] [blame] | 6159 |   if (RequireCompleteDeclContext(SS, Ctx)) | 
 | 6160 |     return QualType(); | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6161 |  | 
 | 6162 |   DeclarationName Name(&II); | 
| Abramo Bagnara | e4da7a0 | 2010-05-19 21:37:53 +0000 | [diff] [blame] | 6163 |   LookupResult Result(*this, Name, IILoc, LookupOrdinaryName); | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 6164 |   LookupQualifiedName(Result, Ctx); | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6165 |   unsigned DiagID = 0; | 
 | 6166 |   Decl *Referenced = 0; | 
| John McCall | a24dc2e | 2009-11-17 02:14:36 +0000 | [diff] [blame] | 6167 |   switch (Result.getResultKind()) { | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6168 |   case LookupResult::NotFound: | 
| Douglas Gregor | 3f09327 | 2009-10-13 21:16:44 +0000 | [diff] [blame] | 6169 |     DiagID = diag::err_typename_nested_not_found; | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6170 |     break; | 
| Douglas Gregor | d954504 | 2010-12-09 00:06:27 +0000 | [diff] [blame] | 6171 |  | 
 | 6172 |   case LookupResult::FoundUnresolvedValue: { | 
 | 6173 |     // We found a using declaration that is a value. Most likely, the using | 
 | 6174 |     // declaration itself is meant to have the 'typename' keyword. | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6175 |     SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(), | 
| Douglas Gregor | d954504 | 2010-12-09 00:06:27 +0000 | [diff] [blame] | 6176 |                           IILoc); | 
 | 6177 |     Diag(IILoc, diag::err_typename_refers_to_using_value_decl) | 
 | 6178 |       << Name << Ctx << FullRange; | 
 | 6179 |     if (UnresolvedUsingValueDecl *Using | 
 | 6180 |           = dyn_cast<UnresolvedUsingValueDecl>(Result.getRepresentativeDecl())){ | 
| Douglas Gregor | dc35571 | 2011-02-25 00:36:19 +0000 | [diff] [blame] | 6181 |       SourceLocation Loc = Using->getQualifierLoc().getBeginLoc(); | 
| Douglas Gregor | d954504 | 2010-12-09 00:06:27 +0000 | [diff] [blame] | 6182 |       Diag(Loc, diag::note_using_value_decl_missing_typename) | 
 | 6183 |         << FixItHint::CreateInsertion(Loc, "typename "); | 
 | 6184 |     } | 
 | 6185 |   } | 
 | 6186 |   // Fall through to create a dependent typename type, from which we can recover | 
 | 6187 |   // better. | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6188 |  | 
| Douglas Gregor | 7d3f576 | 2010-01-15 01:44:47 +0000 | [diff] [blame] | 6189 |   case LookupResult::NotFoundInCurrentInstantiation: | 
 | 6190 |     // Okay, it's a member of an unknown instantiation. | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6191 |     return Context.getDependentNameType(Keyword,  | 
 | 6192 |                                         QualifierLoc.getNestedNameSpecifier(),  | 
 | 6193 |                                         &II); | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6194 |  | 
 | 6195 |   case LookupResult::Found: | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6196 |     if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) { | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6197 |       // We found a type. Build an ElaboratedType, since the | 
 | 6198 |       // typename-specifier was just sugar. | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6199 |       return Context.getElaboratedType(ETK_Typename,  | 
 | 6200 |                                        QualifierLoc.getNestedNameSpecifier(), | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6201 |                                        Context.getTypeDeclType(Type)); | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6202 |     } | 
 | 6203 |  | 
 | 6204 |     DiagID = diag::err_typename_nested_not_type; | 
| John McCall | f36e02d | 2009-10-09 21:13:30 +0000 | [diff] [blame] | 6205 |     Referenced = Result.getFoundDecl(); | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6206 |     break; | 
 | 6207 |  | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6208 |  | 
| Jeffrey Yasskin | 9f61aa9 | 2009-12-12 05:05:38 +0000 | [diff] [blame] | 6209 |     llvm_unreachable("unresolved using decl in non-dependent context"); | 
| John McCall | 7ba107a | 2009-11-18 02:36:19 +0000 | [diff] [blame] | 6210 |     return QualType(); | 
 | 6211 |  | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6212 |   case LookupResult::FoundOverloaded: | 
 | 6213 |     DiagID = diag::err_typename_nested_not_type; | 
 | 6214 |     Referenced = *Result.begin(); | 
 | 6215 |     break; | 
 | 6216 |  | 
| John McCall | 6e24726 | 2009-10-10 05:48:19 +0000 | [diff] [blame] | 6217 |   case LookupResult::Ambiguous: | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6218 |     return QualType(); | 
 | 6219 |   } | 
 | 6220 |  | 
 | 6221 |   // If we get here, it's because name lookup did not find a | 
 | 6222 |   // type. Emit an appropriate diagnostic and return an error. | 
| Douglas Gregor | e29425b | 2011-02-28 22:42:13 +0000 | [diff] [blame] | 6223 |   SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(), | 
| Abramo Bagnara | e4da7a0 | 2010-05-19 21:37:53 +0000 | [diff] [blame] | 6224 |                         IILoc); | 
 | 6225 |   Diag(IILoc, DiagID) << FullRange << Name << Ctx; | 
| Douglas Gregor | d57959a | 2009-03-27 23:10:48 +0000 | [diff] [blame] | 6226 |   if (Referenced) | 
 | 6227 |     Diag(Referenced->getLocation(), diag::note_typename_refers_here) | 
 | 6228 |       << Name; | 
 | 6229 |   return QualType(); | 
 | 6230 | } | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6231 |  | 
 | 6232 | namespace { | 
 | 6233 |   // See Sema::RebuildTypeInCurrentInstantiation | 
| Benjamin Kramer | 85b4521 | 2009-11-28 19:45:26 +0000 | [diff] [blame] | 6234 |   class CurrentInstantiationRebuilder | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6235 |     : public TreeTransform<CurrentInstantiationRebuilder> { | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6236 |     SourceLocation Loc; | 
 | 6237 |     DeclarationName Entity; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6238 |  | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6239 |   public: | 
| Douglas Gregor | 895162d | 2010-04-30 18:55:50 +0000 | [diff] [blame] | 6240 |     typedef TreeTransform<CurrentInstantiationRebuilder> inherited; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6241 |  | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6242 |     CurrentInstantiationRebuilder(Sema &SemaRef, | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6243 |                                   SourceLocation Loc, | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6244 |                                   DeclarationName Entity) | 
 | 6245 |     : TreeTransform<CurrentInstantiationRebuilder>(SemaRef), | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6246 |       Loc(Loc), Entity(Entity) { } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6247 |  | 
 | 6248 |     /// \brief Determine whether the given type \p T has already been | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6249 |     /// transformed. | 
 | 6250 |     /// | 
 | 6251 |     /// For the purposes of type reconstruction, a type has already been | 
 | 6252 |     /// transformed if it is NULL or if it is not dependent. | 
 | 6253 |     bool AlreadyTransformed(QualType T) { | 
 | 6254 |       return T.isNull() || !T->isDependentType(); | 
 | 6255 |     } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6256 |  | 
 | 6257 |     /// \brief Returns the location of the entity whose type is being | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6258 |     /// rebuilt. | 
 | 6259 |     SourceLocation getBaseLocation() { return Loc; } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6260 |  | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6261 |     /// \brief Returns the name of the entity whose type is being rebuilt. | 
 | 6262 |     DeclarationName getBaseEntity() { return Entity; } | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6263 |  | 
| Douglas Gregor | 972e6ce | 2009-10-27 06:26:26 +0000 | [diff] [blame] | 6264 |     /// \brief Sets the "base" location and entity when that | 
 | 6265 |     /// information is known based on another transformation. | 
 | 6266 |     void setBase(SourceLocation Loc, DeclarationName Entity) { | 
 | 6267 |       this->Loc = Loc; | 
 | 6268 |       this->Entity = Entity; | 
 | 6269 |     } | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6270 |   }; | 
 | 6271 | } | 
 | 6272 |  | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6273 | /// \brief Rebuilds a type within the context of the current instantiation. | 
 | 6274 | /// | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6275 | /// The type \p T is part of the type of an out-of-line member definition of | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6276 | /// a class template (or class template partial specialization) that was parsed | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6277 | /// and constructed before we entered the scope of the class template (or | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6278 | /// partial specialization thereof). This routine will rebuild that type now | 
 | 6279 | /// that we have entered the declarator's scope, which may produce different | 
 | 6280 | /// canonical types, e.g., | 
 | 6281 | /// | 
 | 6282 | /// \code | 
 | 6283 | /// template<typename T> | 
 | 6284 | /// struct X { | 
 | 6285 | ///   typedef T* pointer; | 
 | 6286 | ///   pointer data(); | 
 | 6287 | /// }; | 
 | 6288 | /// | 
 | 6289 | /// template<typename T> | 
 | 6290 | /// typename X<T>::pointer X<T>::data() { ... } | 
 | 6291 | /// \endcode | 
 | 6292 | /// | 
| Douglas Gregor | 4714c12 | 2010-03-31 17:34:00 +0000 | [diff] [blame] | 6293 | /// Here, the type "typename X<T>::pointer" will be created as a DependentNameType, | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6294 | /// since we do not know that we can look into X<T> when we parsed the type. | 
 | 6295 | /// This function will rebuild the type, performing the lookup of "pointer" | 
| Abramo Bagnara | 465d41b | 2010-05-11 21:36:43 +0000 | [diff] [blame] | 6296 | /// in X<T> and returning an ElaboratedType whose canonical type is the same | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6297 | /// as the canonical type of T*, allowing the return types of the out-of-line | 
 | 6298 | /// definition and the declaration to match. | 
| John McCall | 63b4385 | 2010-04-29 23:50:39 +0000 | [diff] [blame] | 6299 | TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T, | 
 | 6300 |                                                         SourceLocation Loc, | 
 | 6301 |                                                         DeclarationName Name) { | 
 | 6302 |   if (!T || !T->getType()->isDependentType()) | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6303 |     return T; | 
| Mike Stump | 1eb4433 | 2009-09-09 15:08:12 +0000 | [diff] [blame] | 6304 |  | 
| Douglas Gregor | 4a959d8 | 2009-08-06 16:20:37 +0000 | [diff] [blame] | 6305 |   CurrentInstantiationRebuilder Rebuilder(*this, Loc, Name); | 
 | 6306 |   return Rebuilder.TransformType(T); | 
| Benjamin Kramer | 27ba2f0 | 2009-08-11 22:33:06 +0000 | [diff] [blame] | 6307 | } | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6308 |  | 
| John McCall | 60d7b3a | 2010-08-24 06:29:42 +0000 | [diff] [blame] | 6309 | ExprResult Sema::RebuildExprInCurrentInstantiation(Expr *E) { | 
| John McCall | b3d8748 | 2010-08-24 05:47:05 +0000 | [diff] [blame] | 6310 |   CurrentInstantiationRebuilder Rebuilder(*this, E->getExprLoc(), | 
 | 6311 |                                           DeclarationName()); | 
 | 6312 |   return Rebuilder.TransformExpr(E); | 
 | 6313 | } | 
 | 6314 |  | 
| John McCall | 63b4385 | 2010-04-29 23:50:39 +0000 | [diff] [blame] | 6315 | bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) { | 
| Douglas Gregor | 7e38494 | 2011-02-25 16:07:42 +0000 | [diff] [blame] | 6316 |   if (SS.isInvalid())  | 
 | 6317 |     return true; | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 6318 |  | 
| Douglas Gregor | 7e38494 | 2011-02-25 16:07:42 +0000 | [diff] [blame] | 6319 |   NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context); | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 6320 |   CurrentInstantiationRebuilder Rebuilder(*this, SS.getRange().getBegin(), | 
 | 6321 |                                           DeclarationName()); | 
| Douglas Gregor | 7e38494 | 2011-02-25 16:07:42 +0000 | [diff] [blame] | 6322 |   NestedNameSpecifierLoc Rebuilt  | 
 | 6323 |     = Rebuilder.TransformNestedNameSpecifierLoc(QualifierLoc); | 
 | 6324 |   if (!Rebuilt)  | 
 | 6325 |     return true; | 
| John McCall | 63b4385 | 2010-04-29 23:50:39 +0000 | [diff] [blame] | 6326 |  | 
| Douglas Gregor | 7e38494 | 2011-02-25 16:07:42 +0000 | [diff] [blame] | 6327 |   SS.Adopt(Rebuilt); | 
| John McCall | 63b4385 | 2010-04-29 23:50:39 +0000 | [diff] [blame] | 6328 |   return false; | 
| John McCall | 31f17ec | 2010-04-27 00:57:59 +0000 | [diff] [blame] | 6329 | } | 
 | 6330 |  | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6331 | /// \brief Produces a formatted string that describes the binding of | 
 | 6332 | /// template parameters to template arguments. | 
 | 6333 | std::string | 
 | 6334 | Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params, | 
 | 6335 |                                       const TemplateArgumentList &Args) { | 
| Douglas Gregor | 910f800 | 2010-11-07 23:05:16 +0000 | [diff] [blame] | 6336 |   return getTemplateArgumentBindingsText(Params, Args.data(), Args.size()); | 
| Douglas Gregor | 9148c3f | 2009-11-11 19:13:48 +0000 | [diff] [blame] | 6337 | } | 
 | 6338 |  | 
 | 6339 | std::string | 
 | 6340 | Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params, | 
 | 6341 |                                       const TemplateArgument *Args, | 
 | 6342 |                                       unsigned NumArgs) { | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6343 |   llvm::SmallString<128> Str; | 
 | 6344 |   llvm::raw_svector_ostream Out(Str); | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6345 |  | 
| Douglas Gregor | 9148c3f | 2009-11-11 19:13:48 +0000 | [diff] [blame] | 6346 |   if (!Params || Params->size() == 0 || NumArgs == 0) | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6347 |     return std::string(); | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6348 |  | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6349 |   for (unsigned I = 0, N = Params->size(); I != N; ++I) { | 
| Douglas Gregor | 9148c3f | 2009-11-11 19:13:48 +0000 | [diff] [blame] | 6350 |     if (I >= NumArgs) | 
 | 6351 |       break; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6352 |  | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6353 |     if (I == 0) | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6354 |       Out << "[with "; | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6355 |     else | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6356 |       Out << ", "; | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6357 |  | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6358 |     if (const IdentifierInfo *Id = Params->getParam(I)->getIdentifier()) { | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6359 |       Out << Id->getName(); | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6360 |     } else { | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6361 |       Out << '$' << I; | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6362 |     } | 
| NAKAMURA Takumi | dfbb02a | 2011-01-27 07:10:08 +0000 | [diff] [blame] | 6363 |  | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6364 |     Out << " = "; | 
 | 6365 |     Args[I].print(Context.PrintingPolicy, Out); | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6366 |   } | 
| Douglas Gregor | 87dd697 | 2010-12-20 16:52:59 +0000 | [diff] [blame] | 6367 |  | 
 | 6368 |   Out << ']'; | 
 | 6369 |   return Out.str(); | 
| Douglas Gregor | bf4ea56 | 2009-09-15 16:23:51 +0000 | [diff] [blame] | 6370 | } |