2008-12-06 02:15:24 +08:00
|
|
|
//===------- SemaTemplate.cpp - Semantic Analysis for C++ Templates -------===/
|
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2009-02-28 03:31:52 +08:00
|
|
|
//===----------------------------------------------------------------------===/
|
2008-12-06 02:15:24 +08:00
|
|
|
//
|
|
|
|
// This file implements semantic analysis for C++ templates.
|
2009-02-28 03:31:52 +08:00
|
|
|
//===----------------------------------------------------------------------===/
|
2008-12-06 02:15:24 +08:00
|
|
|
|
2010-08-26 06:03:47 +08:00
|
|
|
#include "clang/Sema/SemaInternal.h"
|
2010-08-13 04:07:10 +08:00
|
|
|
#include "clang/Sema/Lookup.h"
|
2010-08-24 16:50:51 +08:00
|
|
|
#include "clang/Sema/Scope.h"
|
2010-08-24 15:21:54 +08:00
|
|
|
#include "clang/Sema/Template.h"
|
2010-08-25 13:32:35 +08:00
|
|
|
#include "clang/Sema/TemplateDeduction.h"
|
2009-08-07 00:20:37 +08:00
|
|
|
#include "TreeTransform.h"
|
2009-02-07 06:42:48 +08:00
|
|
|
#include "clang/AST/ASTContext.h"
|
2008-12-06 07:32:09 +08:00
|
|
|
#include "clang/AST/Expr.h"
|
2009-02-12 03:52:55 +08:00
|
|
|
#include "clang/AST/ExprCXX.h"
|
2010-03-11 15:50:04 +08:00
|
|
|
#include "clang/AST/DeclFriend.h"
|
2009-02-05 03:02:06 +08:00
|
|
|
#include "clang/AST/DeclTemplate.h"
|
2010-10-20 13:44:58 +08:00
|
|
|
#include "clang/AST/RecursiveASTVisitor.h"
|
2010-10-13 08:27:52 +08:00
|
|
|
#include "clang/AST/TypeVisitor.h"
|
2010-08-21 02:27:03 +08:00
|
|
|
#include "clang/Sema/DeclSpec.h"
|
|
|
|
#include "clang/Sema/ParsedTemplate.h"
|
2008-12-06 02:15:24 +08:00
|
|
|
#include "clang/Basic/LangOptions.h"
|
2009-09-26 02:43:00 +08:00
|
|
|
#include "clang/Basic/PartialDiagnostic.h"
|
2012-01-31 00:17:39 +08:00
|
|
|
#include "llvm/ADT/SmallBitVector.h"
|
2012-02-04 21:45:25 +08:00
|
|
|
#include "llvm/ADT/SmallString.h"
|
2009-09-16 00:23:51 +08:00
|
|
|
#include "llvm/ADT/StringExtras.h"
|
2008-12-06 02:15:24 +08:00
|
|
|
using namespace clang;
|
2010-08-25 13:32:35 +08:00
|
|
|
using namespace sema;
|
2008-12-06 02:15:24 +08:00
|
|
|
|
2010-11-10 10:40:36 +08:00
|
|
|
// Exported for use by Parser.
|
|
|
|
SourceRange
|
|
|
|
clang::getTemplateParamsRange(TemplateParameterList const * const *Ps,
|
|
|
|
unsigned N) {
|
|
|
|
if (!N) return SourceRange();
|
|
|
|
return SourceRange(Ps[0]->getTemplateLoc(), Ps[N-1]->getRAngleLoc());
|
|
|
|
}
|
|
|
|
|
2009-09-03 06:59:36 +08:00
|
|
|
/// \brief Determine whether the declaration found is acceptable as the name
|
|
|
|
/// of a template and, if so, return that template declaration. Otherwise,
|
|
|
|
/// returns NULL.
|
2010-06-16 16:42:20 +08:00
|
|
|
static NamedDecl *isAcceptableTemplateName(ASTContext &Context,
|
2012-03-11 07:52:41 +08:00
|
|
|
NamedDecl *Orig,
|
|
|
|
bool AllowFunctionTemplates) {
|
2010-06-16 16:42:20 +08:00
|
|
|
NamedDecl *D = Orig->getUnderlyingDecl();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-03-11 07:52:41 +08:00
|
|
|
if (isa<TemplateDecl>(D)) {
|
|
|
|
if (!AllowFunctionTemplates && isa<FunctionTemplateDecl>(D))
|
|
|
|
return 0;
|
|
|
|
|
2010-06-16 16:42:20 +08:00
|
|
|
return Orig;
|
2012-03-11 07:52:41 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-09-03 06:59:36 +08:00
|
|
|
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D)) {
|
|
|
|
// C++ [temp.local]p1:
|
|
|
|
// Like normal (non-template) classes, class templates have an
|
|
|
|
// injected-class-name (Clause 9). The injected-class-name
|
|
|
|
// can be used with or without a template-argument-list. When
|
|
|
|
// it is used without a template-argument-list, it is
|
|
|
|
// equivalent to the injected-class-name followed by the
|
|
|
|
// template-parameters of the class template enclosed in
|
|
|
|
// <>. When it is used with a template-argument-list, it
|
|
|
|
// refers to the specified class template specialization,
|
|
|
|
// which could be the current specialization or another
|
|
|
|
// specialization.
|
|
|
|
if (Record->isInjectedClassName()) {
|
2009-10-15 01:30:58 +08:00
|
|
|
Record = cast<CXXRecordDecl>(Record->getDeclContext());
|
2009-09-03 06:59:36 +08:00
|
|
|
if (Record->getDescribedClassTemplate())
|
|
|
|
return Record->getDescribedClassTemplate();
|
|
|
|
|
|
|
|
if (ClassTemplateSpecializationDecl *Spec
|
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(Record))
|
|
|
|
return Spec->getSpecializedTemplate();
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-09-03 06:59:36 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-09-03 06:59:36 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2009-03-31 06:58:21 +08:00
|
|
|
|
2012-03-11 07:52:41 +08:00
|
|
|
void Sema::FilterAcceptableTemplateNames(LookupResult &R,
|
|
|
|
bool AllowFunctionTemplates) {
|
2010-04-13 04:54:26 +08:00
|
|
|
// The set of class templates we've already seen.
|
|
|
|
llvm::SmallPtrSet<ClassTemplateDecl *, 8> ClassTemplates;
|
2009-11-25 03:00:30 +08:00
|
|
|
LookupResult::Filter filter = R.makeFilter();
|
|
|
|
while (filter.hasNext()) {
|
|
|
|
NamedDecl *Orig = filter.next();
|
2012-03-11 07:52:41 +08:00
|
|
|
NamedDecl *Repl = isAcceptableTemplateName(Context, Orig,
|
|
|
|
AllowFunctionTemplates);
|
2009-11-25 03:00:30 +08:00
|
|
|
if (!Repl)
|
|
|
|
filter.erase();
|
2010-04-13 04:54:26 +08:00
|
|
|
else if (Repl != Orig) {
|
|
|
|
|
|
|
|
// C++ [temp.local]p3:
|
2011-01-27 15:10:08 +08:00
|
|
|
// A lookup that finds an injected-class-name (10.2) can result in an
|
2010-04-13 04:54:26 +08:00
|
|
|
// ambiguity in certain cases (for example, if it is found in more than
|
2011-01-27 15:10:08 +08:00
|
|
|
// one base class). If all of the injected-class-names that are found
|
|
|
|
// refer to specializations of the same class template, and if the name
|
2011-05-06 05:57:07 +08:00
|
|
|
// is used as a template-name, the reference refers to the class
|
|
|
|
// template itself and not a specialization thereof, and is not
|
2010-04-13 04:54:26 +08:00
|
|
|
// ambiguous.
|
|
|
|
if (ClassTemplateDecl *ClassTmpl = dyn_cast<ClassTemplateDecl>(Repl))
|
|
|
|
if (!ClassTemplates.insert(ClassTmpl)) {
|
|
|
|
filter.erase();
|
|
|
|
continue;
|
|
|
|
}
|
2010-08-13 15:02:08 +08:00
|
|
|
|
|
|
|
// FIXME: we promote access to public here as a workaround to
|
|
|
|
// the fact that LookupResult doesn't let us remember that we
|
|
|
|
// found this template through a particular injected class name,
|
|
|
|
// which means we end up doing nasty things to the invariants.
|
|
|
|
// Pretending that access is public is *much* safer.
|
|
|
|
filter.replace(Repl, AS_public);
|
2010-04-13 04:54:26 +08:00
|
|
|
}
|
2009-11-25 03:00:30 +08:00
|
|
|
}
|
|
|
|
filter.done();
|
|
|
|
}
|
|
|
|
|
2012-03-11 07:52:41 +08:00
|
|
|
bool Sema::hasAnyAcceptableTemplateNames(LookupResult &R,
|
|
|
|
bool AllowFunctionTemplates) {
|
2011-04-24 13:37:28 +08:00
|
|
|
for (LookupResult::iterator I = R.begin(), IEnd = R.end(); I != IEnd; ++I)
|
2012-03-11 07:52:41 +08:00
|
|
|
if (isAcceptableTemplateName(Context, *I, AllowFunctionTemplates))
|
2011-04-24 13:37:28 +08:00
|
|
|
return true;
|
|
|
|
|
2011-04-27 12:48:22 +08:00
|
|
|
return false;
|
2011-04-24 13:37:28 +08:00
|
|
|
}
|
|
|
|
|
2009-09-03 06:59:36 +08:00
|
|
|
TemplateNameKind Sema::isTemplateName(Scope *S,
|
2010-04-09 00:38:48 +08:00
|
|
|
CXXScopeSpec &SS,
|
2010-08-06 20:11:11 +08:00
|
|
|
bool hasTemplateKeyword,
|
2009-11-04 07:16:33 +08:00
|
|
|
UnqualifiedId &Name,
|
2010-08-24 13:47:05 +08:00
|
|
|
ParsedType ObjectTypePtr,
|
2009-09-03 06:59:36 +08:00
|
|
|
bool EnteringContext,
|
2010-05-22 07:18:07 +08:00
|
|
|
TemplateTy &TemplateResult,
|
|
|
|
bool &MemberOfUnknownSpecialization) {
|
2012-03-11 15:00:24 +08:00
|
|
|
assert(getLangOpts().CPlusPlus && "No template names in C!");
|
2010-01-12 07:29:10 +08:00
|
|
|
|
2009-11-04 07:16:33 +08:00
|
|
|
DeclarationName TName;
|
2010-05-22 07:18:07 +08:00
|
|
|
MemberOfUnknownSpecialization = false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-04 07:16:33 +08:00
|
|
|
switch (Name.getKind()) {
|
|
|
|
case UnqualifiedId::IK_Identifier:
|
|
|
|
TName = DeclarationName(Name.Identifier);
|
|
|
|
break;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-04 07:16:33 +08:00
|
|
|
case UnqualifiedId::IK_OperatorFunctionId:
|
|
|
|
TName = Context.DeclarationNames.getCXXOperatorName(
|
|
|
|
Name.OperatorFunctionId.Operator);
|
|
|
|
break;
|
|
|
|
|
2009-11-28 16:58:14 +08:00
|
|
|
case UnqualifiedId::IK_LiteralOperatorId:
|
2009-11-29 15:34:05 +08:00
|
|
|
TName = Context.DeclarationNames.getCXXLiteralOperatorName(Name.Identifier);
|
|
|
|
break;
|
2009-11-28 16:58:14 +08:00
|
|
|
|
2009-11-04 07:16:33 +08:00
|
|
|
default:
|
|
|
|
return TNK_Non_template;
|
|
|
|
}
|
2009-11-25 03:00:30 +08:00
|
|
|
|
2010-08-24 13:47:05 +08:00
|
|
|
QualType ObjectType = ObjectTypePtr.get();
|
2009-11-25 03:00:30 +08:00
|
|
|
|
2012-03-10 02:35:03 +08:00
|
|
|
LookupResult R(*this, TName, Name.getLocStart(), LookupOrdinaryName);
|
2010-05-22 07:18:07 +08:00
|
|
|
LookupTemplateName(R, S, SS, ObjectType, EnteringContext,
|
|
|
|
MemberOfUnknownSpecialization);
|
2010-08-29 04:17:00 +08:00
|
|
|
if (R.empty()) return TNK_Non_template;
|
|
|
|
if (R.isAmbiguous()) {
|
|
|
|
// Suppress diagnostics; we'll redo this lookup later.
|
2010-08-13 10:23:42 +08:00
|
|
|
R.suppressDiagnostics();
|
2010-08-29 04:17:00 +08:00
|
|
|
|
|
|
|
// FIXME: we might have ambiguous templates, in which case we
|
|
|
|
// should at least parse them properly!
|
2009-11-25 03:00:30 +08:00
|
|
|
return TNK_Non_template;
|
2010-08-13 10:23:42 +08:00
|
|
|
}
|
2009-11-25 03:00:30 +08:00
|
|
|
|
2009-12-02 16:04:21 +08:00
|
|
|
TemplateName Template;
|
|
|
|
TemplateNameKind TemplateKind;
|
|
|
|
|
|
|
|
unsigned ResultCount = R.end() - R.begin();
|
|
|
|
if (ResultCount > 1) {
|
|
|
|
// We assume that we'll preserve the qualifier from a function
|
|
|
|
// template name in other ways.
|
|
|
|
Template = Context.getOverloadedTemplateName(R.begin(), R.end());
|
|
|
|
TemplateKind = TNK_Function_template;
|
2010-08-13 10:23:42 +08:00
|
|
|
|
|
|
|
// We'll do this lookup again later.
|
|
|
|
R.suppressDiagnostics();
|
2009-11-25 03:00:30 +08:00
|
|
|
} else {
|
2009-12-02 16:04:21 +08:00
|
|
|
TemplateDecl *TD = cast<TemplateDecl>((*R.begin())->getUnderlyingDecl());
|
|
|
|
|
|
|
|
if (SS.isSet() && !SS.isInvalid()) {
|
|
|
|
NestedNameSpecifier *Qualifier
|
|
|
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
2010-08-06 20:11:11 +08:00
|
|
|
Template = Context.getQualifiedTemplateName(Qualifier,
|
|
|
|
hasTemplateKeyword, TD);
|
2009-12-02 16:04:21 +08:00
|
|
|
} else {
|
|
|
|
Template = TemplateName(TD);
|
|
|
|
}
|
2009-11-25 03:00:30 +08:00
|
|
|
|
2010-08-13 10:23:42 +08:00
|
|
|
if (isa<FunctionTemplateDecl>(TD)) {
|
2009-12-02 16:04:21 +08:00
|
|
|
TemplateKind = TNK_Function_template;
|
2010-08-13 10:23:42 +08:00
|
|
|
|
|
|
|
// We'll do this lookup again later.
|
|
|
|
R.suppressDiagnostics();
|
|
|
|
} else {
|
2011-05-06 05:57:07 +08:00
|
|
|
assert(isa<ClassTemplateDecl>(TD) || isa<TemplateTemplateParmDecl>(TD) ||
|
|
|
|
isa<TypeAliasTemplateDecl>(TD));
|
2009-12-02 16:04:21 +08:00
|
|
|
TemplateKind = TNK_Type_template;
|
|
|
|
}
|
|
|
|
}
|
2009-11-25 03:00:30 +08:00
|
|
|
|
2009-12-02 16:04:21 +08:00
|
|
|
TemplateResult = TemplateTy::make(Template);
|
|
|
|
return TemplateKind;
|
2009-11-25 03:00:30 +08:00
|
|
|
}
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II,
|
2010-01-13 05:28:44 +08:00
|
|
|
SourceLocation IILoc,
|
|
|
|
Scope *S,
|
|
|
|
const CXXScopeSpec *SS,
|
|
|
|
TemplateTy &SuggestedTemplate,
|
|
|
|
TemplateNameKind &SuggestedKind) {
|
|
|
|
// We can't recover unless there's a dependent scope specifier preceding the
|
|
|
|
// template name.
|
2010-05-22 07:43:39 +08:00
|
|
|
// FIXME: Typo correction?
|
2010-01-13 05:28:44 +08:00
|
|
|
if (!SS || !SS->isSet() || !isDependentScopeSpecifier(*SS) ||
|
|
|
|
computeDeclContext(*SS))
|
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-01-13 05:28:44 +08:00
|
|
|
// The code is missing a 'template' keyword prior to the dependent template
|
|
|
|
// name.
|
|
|
|
NestedNameSpecifier *Qualifier = (NestedNameSpecifier*)SS->getScopeRep();
|
|
|
|
Diag(IILoc, diag::err_template_kw_missing)
|
|
|
|
<< Qualifier << II.getName()
|
2010-04-01 01:46:05 +08:00
|
|
|
<< FixItHint::CreateInsertion(IILoc, "template ");
|
2011-01-27 15:10:08 +08:00
|
|
|
SuggestedTemplate
|
2010-01-13 05:28:44 +08:00
|
|
|
= TemplateTy::make(Context.getDependentTemplateName(Qualifier, &II));
|
|
|
|
SuggestedKind = TNK_Dependent_template_name;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
void Sema::LookupTemplateName(LookupResult &Found,
|
2010-04-09 00:38:48 +08:00
|
|
|
Scope *S, CXXScopeSpec &SS,
|
2009-11-25 03:00:30 +08:00
|
|
|
QualType ObjectType,
|
2010-05-22 07:18:07 +08:00
|
|
|
bool EnteringContext,
|
|
|
|
bool &MemberOfUnknownSpecialization) {
|
2009-09-03 06:59:36 +08:00
|
|
|
// Determine where to perform name lookup
|
2010-05-22 07:18:07 +08:00
|
|
|
MemberOfUnknownSpecialization = false;
|
2009-09-03 06:59:36 +08:00
|
|
|
DeclContext *LookupCtx = 0;
|
|
|
|
bool isDependent = false;
|
2009-11-25 03:00:30 +08:00
|
|
|
if (!ObjectType.isNull()) {
|
2009-09-03 06:59:36 +08:00
|
|
|
// This nested-name-specifier occurs in a member access expression, e.g.,
|
|
|
|
// x->B::f, and we are looking into the type of the object.
|
2009-11-04 07:16:33 +08:00
|
|
|
assert(!SS.isSet() && "ObjectType and scope specifier cannot coexist");
|
2009-09-03 06:59:36 +08:00
|
|
|
LookupCtx = computeDeclContext(ObjectType);
|
|
|
|
isDependent = ObjectType->isDependentType();
|
2011-01-27 15:10:08 +08:00
|
|
|
assert((isDependent || !ObjectType->isIncompleteType()) &&
|
2009-11-17 13:17:33 +08:00
|
|
|
"Caller should have completed object type");
|
2012-01-13 00:11:24 +08:00
|
|
|
|
|
|
|
// Template names cannot appear inside an Objective-C class or object type.
|
|
|
|
if (ObjectType->isObjCObjectOrInterfaceType()) {
|
|
|
|
Found.clear();
|
|
|
|
return;
|
|
|
|
}
|
2009-11-04 07:16:33 +08:00
|
|
|
} else if (SS.isSet()) {
|
2009-09-03 06:59:36 +08:00
|
|
|
// This nested-name-specifier occurs after another nested-name-specifier,
|
|
|
|
// so long into the context associated with the prior nested-name-specifier.
|
2009-11-04 07:16:33 +08:00
|
|
|
LookupCtx = computeDeclContext(SS, EnteringContext);
|
|
|
|
isDependent = isDependentScopeSpecifier(SS);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-17 13:17:33 +08:00
|
|
|
// The declaration context must be complete.
|
2010-05-01 08:40:08 +08:00
|
|
|
if (LookupCtx && RequireCompleteDeclContext(SS, LookupCtx))
|
2009-11-25 03:00:30 +08:00
|
|
|
return;
|
2009-09-03 06:59:36 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-09-03 06:59:36 +08:00
|
|
|
bool ObjectTypeSearchedInScope = false;
|
2012-03-11 07:52:41 +08:00
|
|
|
bool AllowFunctionTemplatesInLookup = true;
|
2009-09-03 06:59:36 +08:00
|
|
|
if (LookupCtx) {
|
|
|
|
// Perform "qualified" name lookup into the declaration context we
|
|
|
|
// computed, which is either the type of the base of a member access
|
2009-09-09 23:08:12 +08:00
|
|
|
// expression or the declaration context associated with a prior
|
2009-09-03 06:59:36 +08:00
|
|
|
// nested-name-specifier.
|
2009-11-17 10:14:36 +08:00
|
|
|
LookupQualifiedName(Found, LookupCtx);
|
2009-11-25 03:00:30 +08:00
|
|
|
if (!ObjectType.isNull() && Found.empty()) {
|
2009-09-03 06:59:36 +08:00
|
|
|
// C++ [basic.lookup.classref]p1:
|
|
|
|
// In a class member access expression (5.2.5), if the . or -> token is
|
2009-09-09 23:08:12 +08:00
|
|
|
// immediately followed by an identifier followed by a <, the
|
|
|
|
// identifier must be looked up to determine whether the < is the
|
2009-09-03 06:59:36 +08:00
|
|
|
// beginning of a template argument list (14.2) or a less-than operator.
|
2009-09-09 23:08:12 +08:00
|
|
|
// The identifier is first looked up in the class of the object
|
|
|
|
// expression. If the identifier is not found, it is then looked up in
|
2009-09-03 06:59:36 +08:00
|
|
|
// the context of the entire postfix-expression and shall name a class
|
|
|
|
// or function template.
|
2009-11-25 03:00:30 +08:00
|
|
|
if (S) LookupName(Found, S);
|
2009-09-03 06:59:36 +08:00
|
|
|
ObjectTypeSearchedInScope = true;
|
2012-03-11 07:52:41 +08:00
|
|
|
AllowFunctionTemplatesInLookup = false;
|
2009-03-31 06:58:21 +08:00
|
|
|
}
|
2010-07-17 00:54:17 +08:00
|
|
|
} else if (isDependent && (!S || ObjectType.isNull())) {
|
2010-01-13 01:06:20 +08:00
|
|
|
// We cannot look into a dependent object type or nested nme
|
|
|
|
// specifier.
|
2010-05-22 07:18:07 +08:00
|
|
|
MemberOfUnknownSpecialization = true;
|
2009-11-25 03:00:30 +08:00
|
|
|
return;
|
2009-09-03 06:59:36 +08:00
|
|
|
} else {
|
|
|
|
// Perform unqualified name lookup in the current scope.
|
2009-11-17 10:14:36 +08:00
|
|
|
LookupName(Found, S);
|
2012-03-11 07:52:41 +08:00
|
|
|
|
|
|
|
if (!ObjectType.isNull())
|
|
|
|
AllowFunctionTemplatesInLookup = false;
|
2009-09-03 06:59:36 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-01-13 01:06:20 +08:00
|
|
|
if (Found.empty() && !isDependent) {
|
2009-12-31 16:11:17 +08:00
|
|
|
// If we did not find any names, attempt to correct any typos.
|
|
|
|
DeclarationName Name = Found.getLookupName();
|
2011-06-29 00:20:02 +08:00
|
|
|
Found.clear();
|
2012-01-14 07:10:36 +08:00
|
|
|
// Simple filter callback that, for keywords, only accepts the C++ *_cast
|
|
|
|
CorrectionCandidateCallback FilterCCC;
|
|
|
|
FilterCCC.WantTypeSpecifiers = false;
|
|
|
|
FilterCCC.WantExpressionKeywords = false;
|
|
|
|
FilterCCC.WantRemainingKeywords = false;
|
|
|
|
FilterCCC.WantCXXNamedCasts = true;
|
2011-06-29 00:20:02 +08:00
|
|
|
if (TypoCorrection Corrected = CorrectTypo(Found.getLookupNameInfo(),
|
|
|
|
Found.getLookupKind(), S, &SS,
|
2012-02-01 07:49:25 +08:00
|
|
|
FilterCCC, LookupCtx)) {
|
2011-06-29 00:20:02 +08:00
|
|
|
Found.setLookupName(Corrected.getCorrection());
|
|
|
|
if (Corrected.getCorrectionDecl())
|
|
|
|
Found.addDecl(Corrected.getCorrectionDecl());
|
2011-04-24 13:37:28 +08:00
|
|
|
FilterAcceptableTemplateNames(Found);
|
2010-06-16 16:42:20 +08:00
|
|
|
if (!Found.empty()) {
|
2012-03-11 15:00:24 +08:00
|
|
|
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
|
|
|
|
std::string CorrectedQuotedStr(Corrected.getQuoted(getLangOpts()));
|
2009-12-31 16:11:17 +08:00
|
|
|
if (LookupCtx)
|
|
|
|
Diag(Found.getNameLoc(), diag::err_no_member_template_suggest)
|
2011-06-29 00:20:02 +08:00
|
|
|
<< Name << LookupCtx << CorrectedQuotedStr << SS.getRange()
|
|
|
|
<< FixItHint::CreateReplacement(Found.getNameLoc(), CorrectedStr);
|
2009-12-31 16:11:17 +08:00
|
|
|
else
|
|
|
|
Diag(Found.getNameLoc(), diag::err_no_template_suggest)
|
2011-06-29 00:20:02 +08:00
|
|
|
<< Name << CorrectedQuotedStr
|
|
|
|
<< FixItHint::CreateReplacement(Found.getNameLoc(), CorrectedStr);
|
2010-01-07 08:17:44 +08:00
|
|
|
if (TemplateDecl *Template = Found.getAsSingle<TemplateDecl>())
|
|
|
|
Diag(Template->getLocation(), diag::note_previous_decl)
|
2011-06-29 00:20:02 +08:00
|
|
|
<< CorrectedQuotedStr;
|
2010-06-16 16:42:20 +08:00
|
|
|
}
|
2009-12-31 16:11:17 +08:00
|
|
|
} else {
|
2010-06-30 03:27:42 +08:00
|
|
|
Found.setLookupName(Name);
|
2009-12-31 16:11:17 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-03-11 07:52:41 +08:00
|
|
|
FilterAcceptableTemplateNames(Found, AllowFunctionTemplatesInLookup);
|
2010-07-17 00:54:17 +08:00
|
|
|
if (Found.empty()) {
|
|
|
|
if (isDependent)
|
|
|
|
MemberOfUnknownSpecialization = true;
|
2009-11-25 03:00:30 +08:00
|
|
|
return;
|
2010-07-17 00:54:17 +08:00
|
|
|
}
|
2009-09-03 06:59:36 +08:00
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
if (S && !ObjectType.isNull() && !ObjectTypeSearchedInScope) {
|
2009-09-03 06:59:36 +08:00
|
|
|
// C++ [basic.lookup.classref]p1:
|
2009-09-09 23:08:12 +08:00
|
|
|
// [...] If the lookup in the class of the object expression finds a
|
2009-09-03 06:59:36 +08:00
|
|
|
// template, the name is also looked up in the context of the entire
|
|
|
|
// postfix-expression and [...]
|
|
|
|
//
|
2009-11-25 03:00:30 +08:00
|
|
|
LookupResult FoundOuter(*this, Found.getLookupName(), Found.getNameLoc(),
|
|
|
|
LookupOrdinaryName);
|
2009-11-17 10:14:36 +08:00
|
|
|
LookupName(FoundOuter, S);
|
2012-03-11 07:52:41 +08:00
|
|
|
FilterAcceptableTemplateNames(FoundOuter, /*AllowFunctionTemplates=*/false);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
if (FoundOuter.empty()) {
|
2009-09-09 23:08:12 +08:00
|
|
|
// - if the name is not found, the name found in the class of the
|
2009-09-03 06:59:36 +08:00
|
|
|
// object expression is used, otherwise
|
2011-08-11 05:59:45 +08:00
|
|
|
} else if (!FoundOuter.getAsSingle<ClassTemplateDecl>() ||
|
|
|
|
FoundOuter.isAmbiguous()) {
|
2009-09-09 23:08:12 +08:00
|
|
|
// - if the name is found in the context of the entire
|
|
|
|
// postfix-expression and does not name a class template, the name
|
2009-09-03 06:59:36 +08:00
|
|
|
// found in the class of the object expression is used, otherwise
|
2011-08-11 05:59:45 +08:00
|
|
|
FoundOuter.clear();
|
2010-06-16 16:42:20 +08:00
|
|
|
} else if (!Found.isSuppressingDiagnostics()) {
|
2009-09-03 06:59:36 +08:00
|
|
|
// - if the name found is a class template, it must refer to the same
|
2009-09-09 23:08:12 +08:00
|
|
|
// entity as the one found in the class of the object expression,
|
2009-09-03 06:59:36 +08:00
|
|
|
// otherwise the program is ill-formed.
|
2009-11-25 03:00:30 +08:00
|
|
|
if (!Found.isSingleResult() ||
|
|
|
|
Found.getFoundDecl()->getCanonicalDecl()
|
|
|
|
!= FoundOuter.getFoundDecl()->getCanonicalDecl()) {
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(Found.getNameLoc(),
|
2010-06-05 09:39:57 +08:00
|
|
|
diag::ext_nested_name_member_ref_lookup_ambiguous)
|
|
|
|
<< Found.getLookupName()
|
|
|
|
<< ObjectType;
|
2009-11-25 03:00:30 +08:00
|
|
|
Diag(Found.getRepresentativeDecl()->getLocation(),
|
|
|
|
diag::note_ambig_member_ref_object_type)
|
|
|
|
<< ObjectType;
|
|
|
|
Diag(FoundOuter.getFoundDecl()->getLocation(),
|
|
|
|
diag::note_ambig_member_ref_scope);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
|
|
|
// Recover by taking the template that we found in the object
|
2009-09-03 06:59:36 +08:00
|
|
|
// expression's type.
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
}
|
2008-12-19 03:37:40 +08:00
|
|
|
}
|
2009-11-25 03:00:30 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-12-02 11:53:29 +08:00
|
|
|
/// ActOnDependentIdExpression - Handle a dependent id-expression that
|
|
|
|
/// was just parsed. This is only possible with an explicit scope
|
|
|
|
/// specifier naming a dependent type.
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult
|
2009-11-25 03:00:30 +08:00
|
|
|
Sema::ActOnDependentIdExpression(const CXXScopeSpec &SS,
|
2012-01-27 17:46:47 +08:00
|
|
|
SourceLocation TemplateKWLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
const DeclarationNameInfo &NameInfo,
|
2009-12-02 11:53:29 +08:00
|
|
|
bool isAddressOfOperand,
|
2009-11-25 03:00:30 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgs) {
|
2010-05-20 09:18:31 +08:00
|
|
|
DeclContext *DC = getFunctionLevelDeclContext();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-12-02 11:53:29 +08:00
|
|
|
if (!isAddressOfOperand &&
|
2010-05-20 09:18:31 +08:00
|
|
|
isa<CXXMethodDecl>(DC) &&
|
|
|
|
cast<CXXMethodDecl>(DC)->isInstance()) {
|
|
|
|
QualType ThisType = cast<CXXMethodDecl>(DC)->getThisType(Context);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
// Since the 'this' expression is synthesized, we don't need to
|
|
|
|
// perform the double-lookup check.
|
|
|
|
NamedDecl *FirstQualifierInScope = 0;
|
|
|
|
|
2009-12-02 06:10:20 +08:00
|
|
|
return Owned(CXXDependentScopeMemberExpr::Create(Context,
|
|
|
|
/*This*/ 0, ThisType,
|
|
|
|
/*IsArrow*/ true,
|
2009-11-25 03:00:30 +08:00
|
|
|
/*Op*/ SourceLocation(),
|
2011-03-01 02:50:33 +08:00
|
|
|
SS.getWithLocInContext(Context),
|
2012-01-27 17:46:47 +08:00
|
|
|
TemplateKWLoc,
|
2009-11-25 03:00:30 +08:00
|
|
|
FirstQualifierInScope,
|
2010-08-12 06:01:17 +08:00
|
|
|
NameInfo,
|
2009-11-25 03:00:30 +08:00
|
|
|
TemplateArgs));
|
|
|
|
}
|
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs);
|
2009-11-25 03:00:30 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult
|
2009-11-25 03:00:30 +08:00
|
|
|
Sema::BuildDependentDeclRefExpr(const CXXScopeSpec &SS,
|
2012-01-27 17:46:47 +08:00
|
|
|
SourceLocation TemplateKWLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
const DeclarationNameInfo &NameInfo,
|
2009-11-25 03:00:30 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgs) {
|
|
|
|
return Owned(DependentScopeDeclRefExpr::Create(Context,
|
2011-02-26 04:49:16 +08:00
|
|
|
SS.getWithLocInContext(Context),
|
2012-01-27 17:46:47 +08:00
|
|
|
TemplateKWLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
NameInfo,
|
2009-11-25 03:00:30 +08:00
|
|
|
TemplateArgs));
|
2008-12-19 03:37:40 +08:00
|
|
|
}
|
|
|
|
|
2008-12-06 02:15:24 +08:00
|
|
|
/// DiagnoseTemplateParameterShadow - Produce a diagnostic complaining
|
|
|
|
/// that the template parameter 'PrevDecl' is being shadowed by a new
|
|
|
|
/// declaration at location Loc. Returns true to indicate that this is
|
|
|
|
/// an error, and false otherwise.
|
2011-10-21 01:58:49 +08:00
|
|
|
void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl) {
|
2008-12-09 02:40:42 +08:00
|
|
|
assert(PrevDecl->isTemplateParameter() && "Not a template parameter");
|
2008-12-06 02:15:24 +08:00
|
|
|
|
|
|
|
// Microsoft Visual C++ permits template parameters to be shadowed.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (getLangOpts().MicrosoftExt)
|
2011-10-21 01:58:49 +08:00
|
|
|
return;
|
2008-12-06 02:15:24 +08:00
|
|
|
|
|
|
|
// C++ [temp.local]p4:
|
|
|
|
// A template-parameter shall not be redeclared within its
|
|
|
|
// scope (including nested scopes).
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(Loc, diag::err_template_param_shadow)
|
2008-12-06 02:15:24 +08:00
|
|
|
<< cast<NamedDecl>(PrevDecl)->getDeclName();
|
|
|
|
Diag(PrevDecl->getLocation(), diag::note_template_param_here);
|
2011-10-21 01:58:49 +08:00
|
|
|
return;
|
2008-12-06 02:15:24 +08:00
|
|
|
}
|
|
|
|
|
2009-03-03 12:44:36 +08:00
|
|
|
/// AdjustDeclIfTemplate - If the given decl happens to be a template, reset
|
2009-02-05 03:02:06 +08:00
|
|
|
/// the parameter D to reference the templated declaration and return a pointer
|
|
|
|
/// to the template declaration. Otherwise, do nothing to D and return null.
|
2010-08-21 17:40:31 +08:00
|
|
|
TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) {
|
|
|
|
if (TemplateDecl *Temp = dyn_cast_or_null<TemplateDecl>(D)) {
|
|
|
|
D = Temp->getTemplatedDecl();
|
2009-02-05 03:02:06 +08:00
|
|
|
return Temp;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-01-06 01:40:24 +08:00
|
|
|
ParsedTemplateArgument ParsedTemplateArgument::getTemplatePackExpansion(
|
|
|
|
SourceLocation EllipsisLoc) const {
|
2011-01-27 15:10:08 +08:00
|
|
|
assert(Kind == Template &&
|
2011-01-06 01:40:24 +08:00
|
|
|
"Only template template arguments can be pack expansions here");
|
|
|
|
assert(getAsTemplate().get().containsUnexpandedParameterPack() &&
|
|
|
|
"Template template argument pack expansion without packs");
|
|
|
|
ParsedTemplateArgument Result(*this);
|
|
|
|
Result.EllipsisLoc = EllipsisLoc;
|
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
|
|
|
|
const ParsedTemplateArgument &Arg) {
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
switch (Arg.getKind()) {
|
|
|
|
case ParsedTemplateArgument::Type: {
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *DI;
|
2009-11-11 09:00:40 +08:00
|
|
|
QualType T = SemaRef.GetTypeFromParser(Arg.getAsType(), &DI);
|
2011-01-27 15:10:08 +08:00
|
|
|
if (!DI)
|
2009-12-07 10:54:59 +08:00
|
|
|
DI = SemaRef.Context.getTrivialTypeSourceInfo(T, Arg.getLocation());
|
2009-11-11 09:00:40 +08:00
|
|
|
return TemplateArgumentLoc(TemplateArgument(T), DI);
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
case ParsedTemplateArgument::NonType: {
|
|
|
|
Expr *E = static_cast<Expr *>(Arg.getAsExpr());
|
|
|
|
return TemplateArgumentLoc(TemplateArgument(E), E);
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
case ParsedTemplateArgument::Template: {
|
2010-08-23 15:28:44 +08:00
|
|
|
TemplateName Template = Arg.getAsTemplate().get();
|
2011-01-15 07:41:42 +08:00
|
|
|
TemplateArgument TArg;
|
|
|
|
if (Arg.getEllipsisLoc().isValid())
|
|
|
|
TArg = TemplateArgument(Template, llvm::Optional<unsigned int>());
|
|
|
|
else
|
|
|
|
TArg = Template;
|
|
|
|
return TemplateArgumentLoc(TArg,
|
2011-03-03 01:09:35 +08:00
|
|
|
Arg.getScopeSpec().getWithLocInContext(
|
|
|
|
SemaRef.Context),
|
2011-01-06 01:40:24 +08:00
|
|
|
Arg.getLocation(),
|
|
|
|
Arg.getEllipsisLoc());
|
2009-11-11 09:00:40 +08:00
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-12-12 13:05:38 +08:00
|
|
|
llvm_unreachable("Unhandled parsed template argument");
|
2009-11-11 09:00:40 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
/// \brief Translates template arguments as provided by the parser
|
|
|
|
/// into template arguments used by semantic analysis.
|
2009-11-23 09:53:49 +08:00
|
|
|
void Sema::translateTemplateArguments(const ASTTemplateArgsPtr &TemplateArgsIn,
|
|
|
|
TemplateArgumentListInfo &TemplateArgs) {
|
2009-11-11 09:00:40 +08:00
|
|
|
for (unsigned I = 0, Last = TemplateArgsIn.size(); I != Last; ++I)
|
2009-11-23 09:53:49 +08:00
|
|
|
TemplateArgs.addArgument(translateTemplateArgument(*this,
|
|
|
|
TemplateArgsIn[I]));
|
2009-11-11 09:00:40 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2008-12-06 02:15:24 +08:00
|
|
|
/// ActOnTypeParameter - Called when a C++ template type parameter
|
|
|
|
/// (e.g., "typename T") has been parsed. Typename specifies whether
|
|
|
|
/// the keyword "typename" was used to declare the type parameter
|
|
|
|
/// (otherwise, "class" was used), and KeyLoc is the location of the
|
|
|
|
/// "class" or "typename" keyword. ParamName is the name of the
|
|
|
|
/// parameter (NULL indicates an unnamed template parameter) and
|
Re-applies the patch first applied way back in r106099, with
accompanying fixes to make it work today.
The core of this patch is to provide a link from a TemplateTypeParmType
back to the TemplateTypeParmDecl node which declared it. This in turn
provides much more precise information about the type, where it came
from, and how it functions for AST consumers.
To make the patch work almost a year after its first attempt, it needed
serialization support, and it now retains the old getName() interface.
Finally, it requires us to not attempt to instantiate the type in an
unsupported friend decl -- specifically those coming from template
friend decls but which refer to a specific type through a dependent
name.
A cleaner representation of the last item would be to build
FriendTemplateDecl nodes for these, storing their template parameters
etc, and to perform proper instantation of them like any other template
declaration. They can still be flagged as unsupported for the purpose of
access checking, etc.
This passed an asserts-enabled bootstrap for me, and the reduced test
case mentioned in the original review thread no longer causes issues,
likely fixed at somewhere amidst the 24k revisions that have elapsed.
llvm-svn: 130628
2011-05-01 08:51:33 +08:00
|
|
|
/// ParamNameLoc is the location of the parameter name (if any).
|
2008-12-06 02:15:24 +08:00
|
|
|
/// If the type parameter has a default argument, it will be added
|
|
|
|
/// later via ActOnTypeParameterDefault.
|
2010-08-21 17:40:31 +08:00
|
|
|
Decl *Sema::ActOnTypeParameter(Scope *S, bool Typename, bool Ellipsis,
|
|
|
|
SourceLocation EllipsisLoc,
|
|
|
|
SourceLocation KeyLoc,
|
|
|
|
IdentifierInfo *ParamName,
|
|
|
|
SourceLocation ParamNameLoc,
|
|
|
|
unsigned Depth, unsigned Position,
|
|
|
|
SourceLocation EqualLoc,
|
2010-08-24 13:47:05 +08:00
|
|
|
ParsedType DefaultArg) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(S->isTemplateParamScope() &&
|
|
|
|
"Template type parameter not in template parameter scope!");
|
2008-12-06 02:15:24 +08:00
|
|
|
bool Invalid = false;
|
|
|
|
|
|
|
|
if (ParamName) {
|
2010-04-16 06:33:43 +08:00
|
|
|
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, ParamNameLoc,
|
2010-04-16 07:40:53 +08:00
|
|
|
LookupOrdinaryName,
|
|
|
|
ForRedeclaration);
|
2011-10-21 01:58:49 +08:00
|
|
|
if (PrevDecl && PrevDecl->isTemplateParameter()) {
|
|
|
|
DiagnoseTemplateParameterShadow(ParamNameLoc, PrevDecl);
|
|
|
|
PrevDecl = 0;
|
|
|
|
}
|
2008-12-06 02:15:24 +08:00
|
|
|
}
|
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
SourceLocation Loc = ParamNameLoc;
|
|
|
|
if (!ParamName)
|
|
|
|
Loc = KeyLoc;
|
|
|
|
|
2008-12-06 02:15:24 +08:00
|
|
|
TemplateTypeParmDecl *Param
|
2010-01-22 08:28:27 +08:00
|
|
|
= TemplateTypeParmDecl::Create(Context, Context.getTranslationUnitDecl(),
|
2011-03-06 23:48:19 +08:00
|
|
|
KeyLoc, Loc, Depth, Position, ParamName,
|
|
|
|
Typename, Ellipsis);
|
2011-03-05 01:52:15 +08:00
|
|
|
Param->setAccess(AS_public);
|
2008-12-06 02:15:24 +08:00
|
|
|
if (Invalid)
|
|
|
|
Param->setInvalidDecl();
|
|
|
|
|
|
|
|
if (ParamName) {
|
|
|
|
// Add the template parameter into the current scope.
|
2010-08-21 17:40:31 +08:00
|
|
|
S->AddDecl(Param);
|
2008-12-06 02:15:24 +08:00
|
|
|
IdResolver.AddDecl(Param);
|
|
|
|
}
|
|
|
|
|
2011-01-05 23:48:55 +08:00
|
|
|
// C++0x [temp.param]p9:
|
|
|
|
// A default template-argument may be specified for any kind of
|
|
|
|
// template-parameter that is not a template parameter pack.
|
|
|
|
if (DefaultArg && Ellipsis) {
|
|
|
|
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
|
|
|
|
DefaultArg = ParsedType();
|
|
|
|
}
|
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
// Handle the default argument, if provided.
|
|
|
|
if (DefaultArg) {
|
|
|
|
TypeSourceInfo *DefaultTInfo;
|
|
|
|
GetTypeFromParser(DefaultArg, &DefaultTInfo);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
assert(DefaultTInfo && "expected source information for type");
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-16 16:48:57 +08:00
|
|
|
// Check for unexpanded parameter packs.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (DiagnoseUnexpandedParameterPack(Loc, DefaultTInfo,
|
2010-12-16 16:48:57 +08:00
|
|
|
UPPC_DefaultArgument))
|
|
|
|
return Param;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
// Check the template argument itself.
|
|
|
|
if (CheckTemplateArgument(Param, DefaultTInfo)) {
|
|
|
|
Param->setInvalidDecl();
|
2010-08-21 17:40:31 +08:00
|
|
|
return Param;
|
2010-07-01 08:00:45 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
Param->setDefaultArgument(DefaultTInfo, false);
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
return Param;
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
|
|
|
|
2009-03-03 12:44:36 +08:00
|
|
|
/// \brief Check that the type of a non-type template parameter is
|
|
|
|
/// well-formed.
|
|
|
|
///
|
|
|
|
/// \returns the (possibly-promoted) parameter type if valid;
|
|
|
|
/// otherwise, produces a diagnostic and returns a NULL type.
|
2009-09-09 23:08:12 +08:00
|
|
|
QualType
|
2009-03-03 12:44:36 +08:00
|
|
|
Sema::CheckNonTypeTemplateParameterType(QualType T, SourceLocation Loc) {
|
2010-05-24 03:57:01 +08:00
|
|
|
// We don't allow variably-modified types as the type of non-type template
|
|
|
|
// parameters.
|
|
|
|
if (T->isVariablyModifiedType()) {
|
|
|
|
Diag(Loc, diag::err_variably_modified_nontype_template_param)
|
|
|
|
<< T;
|
|
|
|
return QualType();
|
|
|
|
}
|
|
|
|
|
2009-02-11 01:43:50 +08:00
|
|
|
// C++ [temp.param]p4:
|
|
|
|
//
|
|
|
|
// A non-type template-parameter shall have one of the following
|
|
|
|
// (optionally cv-qualified) types:
|
|
|
|
//
|
|
|
|
// -- integral or enumeration type,
|
2010-06-16 08:17:44 +08:00
|
|
|
if (T->isIntegralOrEnumerationType() ||
|
2009-09-09 23:08:12 +08:00
|
|
|
// -- pointer to object or pointer to function,
|
2010-08-05 10:49:48 +08:00
|
|
|
T->isPointerType() ||
|
2009-09-09 23:08:12 +08:00
|
|
|
// -- reference to object or reference to function,
|
2009-02-11 01:43:50 +08:00
|
|
|
T->isReferenceType() ||
|
2011-05-22 07:15:46 +08:00
|
|
|
// -- pointer to member,
|
2009-02-11 01:43:50 +08:00
|
|
|
T->isMemberPointerType() ||
|
2011-05-22 07:15:46 +08:00
|
|
|
// -- std::nullptr_t.
|
|
|
|
T->isNullPtrType() ||
|
2009-02-11 01:43:50 +08:00
|
|
|
// If T is a dependent type, we can't do the check now, so we
|
|
|
|
// assume that it is well-formed.
|
2012-03-13 15:21:50 +08:00
|
|
|
T->isDependentType()) {
|
|
|
|
// C++ [temp.param]p5: The top-level cv-qualifiers on the template-parameter
|
|
|
|
// are ignored when determining its type.
|
|
|
|
return T.getUnqualifiedType();
|
|
|
|
}
|
|
|
|
|
2009-02-11 01:43:50 +08:00
|
|
|
// C++ [temp.param]p8:
|
|
|
|
//
|
|
|
|
// A non-type template-parameter of type "array of T" or
|
|
|
|
// "function returning T" is adjusted to be of type "pointer to
|
|
|
|
// T" or "pointer to function returning T", respectively.
|
|
|
|
else if (T->isArrayType())
|
|
|
|
// FIXME: Keep the type prior to promotion?
|
2009-03-03 12:44:36 +08:00
|
|
|
return Context.getArrayDecayedType(T);
|
2009-02-11 01:43:50 +08:00
|
|
|
else if (T->isFunctionType())
|
|
|
|
// FIXME: Keep the type prior to promotion?
|
2009-03-03 12:44:36 +08:00
|
|
|
return Context.getPointerType(T);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-03-03 12:44:36 +08:00
|
|
|
Diag(Loc, diag::err_template_nontype_parm_bad_type)
|
|
|
|
<< T;
|
|
|
|
|
|
|
|
return QualType();
|
|
|
|
}
|
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
Decl *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
|
|
|
|
unsigned Depth,
|
|
|
|
unsigned Position,
|
|
|
|
SourceLocation EqualLoc,
|
2010-08-24 07:25:46 +08:00
|
|
|
Expr *Default) {
|
2010-06-05 07:28:52 +08:00
|
|
|
TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S);
|
|
|
|
QualType T = TInfo->getType();
|
2009-03-03 12:44:36 +08:00
|
|
|
|
|
|
|
assert(S->isTemplateParamScope() &&
|
|
|
|
"Non-type template parameter not in template parameter scope!");
|
|
|
|
bool Invalid = false;
|
|
|
|
|
|
|
|
IdentifierInfo *ParamName = D.getIdentifier();
|
|
|
|
if (ParamName) {
|
2010-04-16 06:33:43 +08:00
|
|
|
NamedDecl *PrevDecl = LookupSingleName(S, ParamName, D.getIdentifierLoc(),
|
2010-04-16 07:40:53 +08:00
|
|
|
LookupOrdinaryName,
|
|
|
|
ForRedeclaration);
|
2011-10-21 01:58:49 +08:00
|
|
|
if (PrevDecl && PrevDecl->isTemplateParameter()) {
|
|
|
|
DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
|
|
|
|
PrevDecl = 0;
|
|
|
|
}
|
2009-02-11 01:43:50 +08:00
|
|
|
}
|
|
|
|
|
2010-12-16 23:36:43 +08:00
|
|
|
T = CheckNonTypeTemplateParameterType(T, D.getIdentifierLoc());
|
|
|
|
if (T.isNull()) {
|
2009-03-03 12:44:36 +08:00
|
|
|
T = Context.IntTy; // Recover with an 'int' type.
|
2009-03-10 00:46:39 +08:00
|
|
|
Invalid = true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-24 07:51:58 +08:00
|
|
|
bool IsParameterPack = D.hasEllipsis();
|
2008-12-06 02:15:24 +08:00
|
|
|
NonTypeTemplateParmDecl *Param
|
2010-01-22 08:28:27 +08:00
|
|
|
= NonTypeTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
|
2012-03-10 02:35:03 +08:00
|
|
|
D.getLocStart(),
|
2010-01-22 08:28:27 +08:00
|
|
|
D.getIdentifierLoc(),
|
2011-01-27 15:10:08 +08:00
|
|
|
Depth, Position, ParamName, T,
|
2010-12-24 07:51:58 +08:00
|
|
|
IsParameterPack, TInfo);
|
2011-03-05 01:52:15 +08:00
|
|
|
Param->setAccess(AS_public);
|
|
|
|
|
2008-12-06 02:15:24 +08:00
|
|
|
if (Invalid)
|
|
|
|
Param->setInvalidDecl();
|
|
|
|
|
|
|
|
if (D.getIdentifier()) {
|
|
|
|
// Add the template parameter into the current scope.
|
2010-08-21 17:40:31 +08:00
|
|
|
S->AddDecl(Param);
|
2008-12-06 02:15:24 +08:00
|
|
|
IdResolver.AddDecl(Param);
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-05 23:48:55 +08:00
|
|
|
// C++0x [temp.param]p9:
|
|
|
|
// A default template-argument may be specified for any kind of
|
|
|
|
// template-parameter that is not a template parameter pack.
|
|
|
|
if (Default && IsParameterPack) {
|
|
|
|
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
|
|
|
|
Default = 0;
|
|
|
|
}
|
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
// Check the well-formedness of the default template argument, if provided.
|
2010-12-24 07:51:58 +08:00
|
|
|
if (Default) {
|
2010-12-16 16:48:57 +08:00
|
|
|
// Check for unexpanded parameter packs.
|
|
|
|
if (DiagnoseUnexpandedParameterPack(Default, UPPC_DefaultArgument))
|
|
|
|
return Param;
|
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
TemplateArgument Converted;
|
2011-04-09 02:41:53 +08:00
|
|
|
ExprResult DefaultRes = CheckTemplateArgument(Param, Param->getType(), Default, Converted);
|
|
|
|
if (DefaultRes.isInvalid()) {
|
2010-07-01 08:00:45 +08:00
|
|
|
Param->setInvalidDecl();
|
2010-08-21 17:40:31 +08:00
|
|
|
return Param;
|
2010-07-01 08:00:45 +08:00
|
|
|
}
|
2011-04-09 02:41:53 +08:00
|
|
|
Default = DefaultRes.take();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-24 07:25:46 +08:00
|
|
|
Param->setDefaultArgument(Default, false);
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
return Param;
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
|
|
|
|
2009-02-05 03:02:06 +08:00
|
|
|
/// ActOnTemplateTemplateParameter - Called when a C++ template template
|
|
|
|
/// parameter (e.g. T in template <template <typename> class T> class array)
|
|
|
|
/// has been parsed. S is the current scope.
|
2010-08-21 17:40:31 +08:00
|
|
|
Decl *Sema::ActOnTemplateTemplateParameter(Scope* S,
|
|
|
|
SourceLocation TmpLoc,
|
2011-09-09 11:18:59 +08:00
|
|
|
TemplateParameterList *Params,
|
2011-01-05 23:48:55 +08:00
|
|
|
SourceLocation EllipsisLoc,
|
2010-08-21 17:40:31 +08:00
|
|
|
IdentifierInfo *Name,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
unsigned Depth,
|
|
|
|
unsigned Position,
|
|
|
|
SourceLocation EqualLoc,
|
2011-01-05 23:48:55 +08:00
|
|
|
ParsedTemplateArgument Default) {
|
2009-02-05 03:02:06 +08:00
|
|
|
assert(S->isTemplateParamScope() &&
|
|
|
|
"Template template parameter not in template parameter scope!");
|
|
|
|
|
|
|
|
// Construct the parameter object.
|
2011-01-05 23:48:55 +08:00
|
|
|
bool IsParameterPack = EllipsisLoc.isValid();
|
2009-02-05 03:02:06 +08:00
|
|
|
TemplateTemplateParmDecl *Param =
|
2010-01-22 08:28:27 +08:00
|
|
|
TemplateTemplateParmDecl::Create(Context, Context.getTranslationUnitDecl(),
|
2011-01-27 15:10:08 +08:00
|
|
|
NameLoc.isInvalid()? TmpLoc : NameLoc,
|
|
|
|
Depth, Position, IsParameterPack,
|
2011-01-05 23:48:55 +08:00
|
|
|
Name, Params);
|
2011-03-05 01:52:15 +08:00
|
|
|
Param->setAccess(AS_public);
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
// If the template template parameter has a name, then link the identifier
|
2010-07-01 08:00:45 +08:00
|
|
|
// into the scope and lookup mechanisms.
|
2009-02-05 03:02:06 +08:00
|
|
|
if (Name) {
|
2010-08-21 17:40:31 +08:00
|
|
|
S->AddDecl(Param);
|
2009-02-05 03:02:06 +08:00
|
|
|
IdResolver.AddDecl(Param);
|
|
|
|
}
|
|
|
|
|
2010-12-16 16:48:57 +08:00
|
|
|
if (Params->size() == 0) {
|
|
|
|
Diag(Param->getLocation(), diag::err_template_template_parm_no_parms)
|
|
|
|
<< SourceRange(Params->getLAngleLoc(), Params->getRAngleLoc());
|
|
|
|
Param->setInvalidDecl();
|
|
|
|
}
|
|
|
|
|
2011-01-05 23:48:55 +08:00
|
|
|
// C++0x [temp.param]p9:
|
|
|
|
// A default template-argument may be specified for any kind of
|
|
|
|
// template-parameter that is not a template parameter pack.
|
|
|
|
if (IsParameterPack && !Default.isInvalid()) {
|
|
|
|
Diag(EqualLoc, diag::err_template_param_pack_default_arg);
|
|
|
|
Default = ParsedTemplateArgument();
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
if (!Default.isInvalid()) {
|
|
|
|
// Check only that we have a template template argument. We don't want to
|
|
|
|
// try to check well-formedness now, because our template template parameter
|
|
|
|
// might have dependent types in its template parameters, which we wouldn't
|
|
|
|
// be able to match now.
|
|
|
|
//
|
|
|
|
// If none of the template template parameter's template arguments mention
|
|
|
|
// other template parameters, we could actually perform more checking here.
|
|
|
|
// However, it isn't worth doing.
|
|
|
|
TemplateArgumentLoc DefaultArg = translateTemplateArgument(*this, Default);
|
|
|
|
if (DefaultArg.getArgument().getAsTemplate().isNull()) {
|
|
|
|
Diag(DefaultArg.getLocation(), diag::err_template_arg_not_class_template)
|
|
|
|
<< DefaultArg.getSourceRange();
|
2010-08-21 17:40:31 +08:00
|
|
|
return Param;
|
2010-07-01 08:00:45 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-16 16:48:57 +08:00
|
|
|
// Check for unexpanded parameter packs.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (DiagnoseUnexpandedParameterPack(DefaultArg.getLocation(),
|
2010-12-16 16:48:57 +08:00
|
|
|
DefaultArg.getArgument().getAsTemplate(),
|
|
|
|
UPPC_DefaultArgument))
|
|
|
|
return Param;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-07-01 08:00:45 +08:00
|
|
|
Param->setDefaultArgument(DefaultArg, false);
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
return Param;
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
|
|
|
|
2008-12-24 10:52:09 +08:00
|
|
|
/// ActOnTemplateParameterList - Builds a TemplateParameterList that
|
|
|
|
/// contains the template parameters in Params/NumParams.
|
2011-09-09 11:18:59 +08:00
|
|
|
TemplateParameterList *
|
2008-12-24 10:52:09 +08:00
|
|
|
Sema::ActOnTemplateParameterList(unsigned Depth,
|
|
|
|
SourceLocation ExportLoc,
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation TemplateLoc,
|
2008-12-24 10:52:09 +08:00
|
|
|
SourceLocation LAngleLoc,
|
2010-08-21 17:40:31 +08:00
|
|
|
Decl **Params, unsigned NumParams,
|
2008-12-24 10:52:09 +08:00
|
|
|
SourceLocation RAngleLoc) {
|
|
|
|
if (ExportLoc.isValid())
|
2009-11-26 02:55:14 +08:00
|
|
|
Diag(ExportLoc, diag::warn_template_export_unsupported);
|
2008-12-24 10:52:09 +08:00
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
return TemplateParameterList::Create(Context, TemplateLoc, LAngleLoc,
|
2011-01-27 15:10:08 +08:00
|
|
|
(NamedDecl**)Params, NumParams,
|
2009-09-16 00:23:51 +08:00
|
|
|
RAngleLoc);
|
2009-02-07 06:42:48 +08:00
|
|
|
}
|
|
|
|
|
2010-03-15 18:12:16 +08:00
|
|
|
static void SetNestedNameSpecifier(TagDecl *T, const CXXScopeSpec &SS) {
|
|
|
|
if (SS.isSet())
|
2011-02-25 10:25:35 +08:00
|
|
|
T->setQualifierInfo(SS.getWithLocInContext(T->getASTContext()));
|
2010-03-15 18:12:16 +08:00
|
|
|
}
|
|
|
|
|
2010-08-27 07:41:50 +08:00
|
|
|
DeclResult
|
2009-07-31 10:45:11 +08:00
|
|
|
Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
2010-04-09 00:38:48 +08:00
|
|
|
SourceLocation KWLoc, CXXScopeSpec &SS,
|
2009-02-07 06:42:48 +08:00
|
|
|
IdentifierInfo *Name, SourceLocation NameLoc,
|
|
|
|
AttributeList *Attr,
|
2009-08-26 01:23:04 +08:00
|
|
|
TemplateParameterList *TemplateParams,
|
2011-09-10 03:05:14 +08:00
|
|
|
AccessSpecifier AS, SourceLocation ModulePrivateLoc,
|
2011-03-10 21:28:31 +08:00
|
|
|
unsigned NumOuterTemplateParamLists,
|
|
|
|
TemplateParameterList** OuterTemplateParamLists) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(TemplateParams && TemplateParams->size() > 0 &&
|
2009-08-26 01:23:04 +08:00
|
|
|
"No template parameters");
|
2009-07-31 10:45:11 +08:00
|
|
|
assert(TUK != TUK_Reference && "Can only declare or define class templates");
|
2009-02-11 03:49:53 +08:00
|
|
|
bool Invalid = false;
|
2009-02-07 06:42:48 +08:00
|
|
|
|
|
|
|
// Check that we can declare a template here.
|
2009-08-26 01:23:04 +08:00
|
|
|
if (CheckTemplateDeclScope(S, TemplateParams))
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2009-02-07 06:42:48 +08:00
|
|
|
|
2010-05-12 05:36:43 +08:00
|
|
|
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
|
|
|
|
assert(Kind != TTK_Enum && "can't build template of enumerated type");
|
2009-02-07 06:42:48 +08:00
|
|
|
|
|
|
|
// There is no such thing as an unnamed class template.
|
|
|
|
if (!Name) {
|
|
|
|
Diag(KWLoc, diag::err_template_unnamed_class);
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2009-02-07 06:42:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Find any previous declaration with this name.
|
2009-08-26 01:23:04 +08:00
|
|
|
DeclContext *SemanticContext;
|
2012-04-20 15:12:26 +08:00
|
|
|
LookupResult Previous(*this, Name, NameLoc, LookupTagName,
|
2009-11-18 15:57:50 +08:00
|
|
|
ForRedeclaration);
|
2009-08-26 01:23:04 +08:00
|
|
|
if (SS.isNotEmpty() && !SS.isInvalid()) {
|
|
|
|
SemanticContext = computeDeclContext(SS, true);
|
|
|
|
if (!SemanticContext) {
|
2012-03-31 00:20:47 +08:00
|
|
|
// FIXME: Horrible, horrible hack! We can't currently represent this
|
|
|
|
// in the AST, and historically we have just ignored such friend
|
|
|
|
// class templates, so don't complain here.
|
|
|
|
if (TUK != TUK_Friend)
|
|
|
|
Diag(NameLoc, diag::err_template_qualified_declarator_no_match)
|
|
|
|
<< SS.getScopeRep() << SS.getRange();
|
2009-08-26 01:23:04 +08:00
|
|
|
return true;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-05-01 08:40:08 +08:00
|
|
|
if (RequireCompleteDeclContext(SS, SemanticContext))
|
|
|
|
return true;
|
|
|
|
|
2011-10-14 23:31:12 +08:00
|
|
|
// If we're adding a template to a dependent context, we may need to
|
|
|
|
// rebuilding some of the types used within the template parameter list,
|
|
|
|
// now that we know what the current instantiation is.
|
|
|
|
if (SemanticContext->isDependentContext()) {
|
|
|
|
ContextRAII SavedContext(*this, SemanticContext);
|
|
|
|
if (RebuildTemplateParamsInCurrentInstantiation(TemplateParams))
|
|
|
|
Invalid = true;
|
2012-03-29 00:01:27 +08:00
|
|
|
} else if (TUK != TUK_Friend && TUK != TUK_Reference)
|
|
|
|
diagnoseQualifiedDeclaration(SS, SemanticContext, Name, NameLoc);
|
2011-10-14 23:31:12 +08:00
|
|
|
|
2009-11-17 10:14:36 +08:00
|
|
|
LookupQualifiedName(Previous, SemanticContext);
|
2009-08-26 01:23:04 +08:00
|
|
|
} else {
|
|
|
|
SemanticContext = CurContext;
|
2009-11-17 10:14:36 +08:00
|
|
|
LookupName(Previous, S);
|
2009-08-26 01:23:04 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-04-13 00:00:01 +08:00
|
|
|
if (Previous.isAmbiguous())
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
NamedDecl *PrevDecl = 0;
|
|
|
|
if (Previous.begin() != Previous.end())
|
2010-04-13 00:00:01 +08:00
|
|
|
PrevDecl = (*Previous.begin())->getUnderlyingDecl();
|
2009-02-07 06:42:48 +08:00
|
|
|
|
2009-12-18 07:21:11 +08:00
|
|
|
// If there is a previous declaration with the same name, check
|
|
|
|
// whether this is a valid redeclaration.
|
|
|
|
ClassTemplateDecl *PrevClassTemplate
|
|
|
|
= dyn_cast_or_null<ClassTemplateDecl>(PrevDecl);
|
|
|
|
|
|
|
|
// We may have found the injected-class-name of a class template,
|
2011-01-27 15:10:08 +08:00
|
|
|
// class template partial specialization, or class template specialization.
|
2009-12-18 07:21:11 +08:00
|
|
|
// In these cases, grab the template that is being defined or specialized.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (!PrevClassTemplate && PrevDecl && isa<CXXRecordDecl>(PrevDecl) &&
|
2009-12-18 07:21:11 +08:00
|
|
|
cast<CXXRecordDecl>(PrevDecl)->isInjectedClassName()) {
|
|
|
|
PrevDecl = cast<CXXRecordDecl>(PrevDecl->getDeclContext());
|
2011-01-27 15:10:08 +08:00
|
|
|
PrevClassTemplate
|
2009-12-18 07:21:11 +08:00
|
|
|
= cast<CXXRecordDecl>(PrevDecl)->getDescribedClassTemplate();
|
|
|
|
if (!PrevClassTemplate && isa<ClassTemplateSpecializationDecl>(PrevDecl)) {
|
|
|
|
PrevClassTemplate
|
|
|
|
= cast<ClassTemplateSpecializationDecl>(PrevDecl)
|
|
|
|
->getSpecializedTemplate();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-12-18 19:25:59 +08:00
|
|
|
if (TUK == TUK_Friend) {
|
2009-09-26 15:05:09 +08:00
|
|
|
// C++ [namespace.memdef]p3:
|
2011-01-27 15:10:08 +08:00
|
|
|
// [...] When looking for a prior declaration of a class or a function
|
|
|
|
// declared as a friend, and when the name of the friend class or
|
2009-09-26 15:05:09 +08:00
|
|
|
// function is neither a qualified name nor a template-id, scopes outside
|
|
|
|
// the innermost enclosing namespace scope are not considered.
|
2010-04-19 01:37:40 +08:00
|
|
|
if (!SS.isSet()) {
|
|
|
|
DeclContext *OutermostContext = CurContext;
|
|
|
|
while (!OutermostContext->isFileContext())
|
|
|
|
OutermostContext = OutermostContext->getLookupParent();
|
|
|
|
|
2012-04-20 15:12:26 +08:00
|
|
|
if (PrevDecl &&
|
2010-04-19 01:37:40 +08:00
|
|
|
(OutermostContext->Equals(PrevDecl->getDeclContext()) ||
|
|
|
|
OutermostContext->Encloses(PrevDecl->getDeclContext()))) {
|
|
|
|
SemanticContext = PrevDecl->getDeclContext();
|
|
|
|
} else {
|
|
|
|
// Declarations in outer scopes don't matter. However, the outermost
|
2011-01-27 15:10:08 +08:00
|
|
|
// context we computed is the semantic context for our new
|
2010-04-19 01:37:40 +08:00
|
|
|
// declaration.
|
|
|
|
PrevDecl = PrevClassTemplate = 0;
|
|
|
|
SemanticContext = OutermostContext;
|
|
|
|
}
|
2009-09-26 15:05:09 +08:00
|
|
|
}
|
2010-04-19 01:37:40 +08:00
|
|
|
|
2012-04-20 15:12:26 +08:00
|
|
|
if (CurContext->isDependentContext() && PrevClassTemplate) {
|
2009-10-31 06:42:42 +08:00
|
|
|
// If this is a dependent context, we don't want to link the friend
|
|
|
|
// class template to the template in scope, because that would perform
|
|
|
|
// checking of the template parameter lists that can't be performed
|
|
|
|
// until the outer context is instantiated.
|
2009-12-18 07:21:11 +08:00
|
|
|
PrevDecl = PrevClassTemplate = 0;
|
2009-10-31 06:42:42 +08:00
|
|
|
}
|
2009-09-26 15:05:09 +08:00
|
|
|
} else if (PrevDecl && !isDeclInScope(PrevDecl, SemanticContext, S))
|
2009-12-18 07:21:11 +08:00
|
|
|
PrevDecl = PrevClassTemplate = 0;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
if (PrevClassTemplate) {
|
|
|
|
// Ensure that the template parameter lists are compatible.
|
|
|
|
if (!TemplateParameterListsAreEqual(TemplateParams,
|
|
|
|
PrevClassTemplate->getTemplateParameters(),
|
2009-11-13 00:20:59 +08:00
|
|
|
/*Complain=*/true,
|
|
|
|
TPL_TemplateMatch))
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2009-02-07 06:42:48 +08:00
|
|
|
|
|
|
|
// C++ [temp.class]p4:
|
|
|
|
// In a redeclaration, partial specialization, explicit
|
|
|
|
// specialization or explicit instantiation of a class template,
|
|
|
|
// the class-key shall agree in kind with the original class
|
|
|
|
// template declaration (7.1.5.3).
|
|
|
|
RecordDecl *PrevRecordDecl = PrevClassTemplate->getTemplatedDecl();
|
2011-06-10 11:11:26 +08:00
|
|
|
if (!isAcceptableTagRedeclaration(PrevRecordDecl, Kind,
|
|
|
|
TUK == TUK_Definition, KWLoc, *Name)) {
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(KWLoc, diag::err_use_with_wrong_tag)
|
2009-04-02 07:51:29 +08:00
|
|
|
<< Name
|
2010-04-01 01:46:05 +08:00
|
|
|
<< FixItHint::CreateReplacement(KWLoc, PrevRecordDecl->getKindName());
|
2009-02-07 06:42:48 +08:00
|
|
|
Diag(PrevRecordDecl->getLocation(), diag::note_previous_use);
|
2009-04-02 07:51:29 +08:00
|
|
|
Kind = PrevRecordDecl->getTagKind();
|
2009-02-07 06:42:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Check for redefinition of this class template.
|
2009-07-31 10:45:11 +08:00
|
|
|
if (TUK == TUK_Definition) {
|
2010-02-11 09:04:33 +08:00
|
|
|
if (TagDecl *Def = PrevRecordDecl->getDefinition()) {
|
2009-02-07 06:42:48 +08:00
|
|
|
Diag(NameLoc, diag::err_redefinition) << Name;
|
|
|
|
Diag(Def->getLocation(), diag::note_previous_definition);
|
|
|
|
// FIXME: Would it make sense to try to "forget" the previous
|
|
|
|
// definition, as part of error recovery?
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2009-02-07 06:42:48 +08:00
|
|
|
}
|
2011-09-10 02:32:39 +08:00
|
|
|
}
|
2009-02-07 06:42:48 +08:00
|
|
|
} else if (PrevDecl && PrevDecl->isTemplateParameter()) {
|
|
|
|
// Maybe we will complain about the shadowed template parameter.
|
|
|
|
DiagnoseTemplateParameterShadow(NameLoc, PrevDecl);
|
|
|
|
// Just pretend that we didn't see the previous declaration.
|
|
|
|
PrevDecl = 0;
|
|
|
|
} else if (PrevDecl) {
|
|
|
|
// C++ [temp]p5:
|
|
|
|
// A class template shall not have the same name as any other
|
|
|
|
// template, class, function, object, enumeration, enumerator,
|
|
|
|
// namespace, or type in the same scope (3.3), except as specified
|
|
|
|
// in (14.5.4).
|
|
|
|
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
|
|
|
|
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2009-02-07 06:42:48 +08:00
|
|
|
}
|
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
// Check the template parameter list of this declaration, possibly
|
|
|
|
// merging in the template parameter list from the previous class
|
|
|
|
// template declaration.
|
|
|
|
if (CheckTemplateParameterList(TemplateParams,
|
2009-11-26 01:50:39 +08:00
|
|
|
PrevClassTemplate? PrevClassTemplate->getTemplateParameters() : 0,
|
2011-02-04 12:20:44 +08:00
|
|
|
(SS.isSet() && SemanticContext &&
|
2011-02-04 20:22:53 +08:00
|
|
|
SemanticContext->isRecord() &&
|
|
|
|
SemanticContext->isDependentContext())
|
2011-02-04 12:20:44 +08:00
|
|
|
? TPC_ClassTemplateMember
|
|
|
|
: TPC_ClassTemplate))
|
2009-02-11 03:49:53 +08:00
|
|
|
Invalid = true;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-04-13 00:00:01 +08:00
|
|
|
if (SS.isSet()) {
|
2011-01-27 15:10:08 +08:00
|
|
|
// If the name of the template was qualified, we must be defining the
|
2010-04-13 00:00:01 +08:00
|
|
|
// template out-of-line.
|
|
|
|
if (!SS.isInvalid() && !Invalid && !PrevClassTemplate &&
|
2011-11-02 05:35:16 +08:00
|
|
|
!(TUK == TUK_Friend && CurContext->isDependentContext())) {
|
2010-04-13 00:00:01 +08:00
|
|
|
Diag(NameLoc, diag::err_member_def_does_not_match)
|
|
|
|
<< Name << SemanticContext << SS.getRange();
|
2011-11-02 05:35:16 +08:00
|
|
|
Invalid = true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
CXXRecordDecl *NewClass =
|
2011-03-09 22:09:51 +08:00
|
|
|
CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name,
|
2009-09-09 23:08:12 +08:00
|
|
|
PrevClassTemplate?
|
2009-05-16 03:11:46 +08:00
|
|
|
PrevClassTemplate->getTemplatedDecl() : 0,
|
|
|
|
/*DelayTypeCreation=*/true);
|
2010-03-15 18:12:16 +08:00
|
|
|
SetNestedNameSpecifier(NewClass, SS);
|
2011-03-10 21:28:31 +08:00
|
|
|
if (NumOuterTemplateParamLists > 0)
|
|
|
|
NewClass->setTemplateParameterListsInfo(Context,
|
|
|
|
NumOuterTemplateParamLists,
|
|
|
|
OuterTemplateParamLists);
|
2009-02-07 06:42:48 +08:00
|
|
|
|
2012-02-10 10:02:21 +08:00
|
|
|
// Add alignment attributes if necessary; these attributes are checked when
|
|
|
|
// the ASTContext lays out the structure.
|
|
|
|
AddAlignmentAttributesForRecord(NewClass);
|
|
|
|
AddMsStructLayoutForRecord(NewClass);
|
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
ClassTemplateDecl *NewTemplate
|
|
|
|
= ClassTemplateDecl::Create(Context, SemanticContext, NameLoc,
|
|
|
|
DeclarationName(Name), TemplateParams,
|
Introduce a new expression type, UnresolvedDeclRefExpr, that describes
dependent qualified-ids such as
Fibonacci<N - 1>::value
where N is a template parameter. These references are "unresolved"
because the name is dependent and, therefore, cannot be resolved to a
declaration node (as we would do for a DeclRefExpr or
QualifiedDeclRefExpr). UnresolvedDeclRefExprs instantiate to
DeclRefExprs, QualifiedDeclRefExprs, etc.
Also, be a bit more careful about keeping only a single set of
specializations for a class template, and instantiating from the
definition of that template rather than a previous declaration. In
general, we need a better solution for this for all TagDecls, because
it's too easy to accidentally look at a declaration that isn't the
definition.
We can now process a simple Fibonacci computation described as a
template metaprogram.
llvm-svn: 67308
2009-03-20 01:26:29 +08:00
|
|
|
NewClass, PrevClassTemplate);
|
2009-03-26 08:10:35 +08:00
|
|
|
NewClass->setDescribedClassTemplate(NewTemplate);
|
2011-09-10 02:32:39 +08:00
|
|
|
|
2011-12-21 02:11:52 +08:00
|
|
|
if (ModulePrivateLoc.isValid())
|
2011-09-10 02:32:39 +08:00
|
|
|
NewTemplate->setModulePrivate();
|
2011-09-09 10:06:17 +08:00
|
|
|
|
2009-05-16 03:11:46 +08:00
|
|
|
// Build the type for the class template declaration now.
|
2010-07-09 02:37:38 +08:00
|
|
|
QualType T = NewTemplate->getInjectedClassNameSpecialization();
|
2010-03-10 11:28:59 +08:00
|
|
|
T = Context.getInjectedClassNameType(NewClass, T);
|
2009-05-16 03:11:46 +08:00
|
|
|
assert(T->isDependentType() && "Class template type is not dependent?");
|
|
|
|
(void)T;
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
// If we are providing an explicit specialization of a member that is a
|
2009-10-14 00:30:37 +08:00
|
|
|
// class template, make a note of that.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (PrevClassTemplate &&
|
2009-10-14 00:30:37 +08:00
|
|
|
PrevClassTemplate->getInstantiatedFromMemberTemplate())
|
|
|
|
PrevClassTemplate->setMemberSpecialization();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-03-26 09:24:28 +08:00
|
|
|
// Set the access specifier.
|
2012-03-18 07:06:31 +08:00
|
|
|
if (!Invalid && TUK != TUK_Friend && NewTemplate->getDeclContext()->isRecord())
|
2009-09-15 05:59:20 +08:00
|
|
|
SetMemberAccessSpecifier(NewTemplate, PrevClassTemplate, AS);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
// Set the lexical context of these templates
|
|
|
|
NewClass->setLexicalDeclContext(CurContext);
|
|
|
|
NewTemplate->setLexicalDeclContext(CurContext);
|
|
|
|
|
2009-07-31 10:45:11 +08:00
|
|
|
if (TUK == TUK_Definition)
|
2009-02-07 06:42:48 +08:00
|
|
|
NewClass->startDefinition();
|
|
|
|
|
|
|
|
if (Attr)
|
2009-06-18 05:51:59 +08:00
|
|
|
ProcessDeclAttributeList(S, NewClass, Attr);
|
2009-02-07 06:42:48 +08:00
|
|
|
|
2009-09-15 05:59:20 +08:00
|
|
|
if (TUK != TUK_Friend)
|
|
|
|
PushOnScopeChains(NewTemplate, S);
|
|
|
|
else {
|
2009-09-26 14:47:28 +08:00
|
|
|
if (PrevClassTemplate && PrevClassTemplate->getAccess() != AS_none) {
|
2009-09-15 05:59:20 +08:00
|
|
|
NewTemplate->setAccess(PrevClassTemplate->getAccess());
|
2009-09-26 14:47:28 +08:00
|
|
|
NewClass->setAccess(PrevClassTemplate->getAccess());
|
|
|
|
}
|
2009-09-15 05:59:20 +08:00
|
|
|
|
2009-09-26 14:47:28 +08:00
|
|
|
NewTemplate->setObjectOfFriendDecl(/* PreviouslyDeclared = */
|
|
|
|
PrevClassTemplate != NULL);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-15 05:59:20 +08:00
|
|
|
// Friend templates are visible in fairly strange ways.
|
|
|
|
if (!CurContext->isDependentContext()) {
|
2010-08-31 08:36:30 +08:00
|
|
|
DeclContext *DC = SemanticContext->getRedeclContext();
|
2012-03-13 11:12:56 +08:00
|
|
|
DC->makeDeclVisibleInContext(NewTemplate);
|
2009-09-15 05:59:20 +08:00
|
|
|
if (Scope *EnclosingScope = getScopeForDeclContext(S, DC))
|
|
|
|
PushOnScopeChains(NewTemplate, EnclosingScope,
|
2011-01-27 15:10:08 +08:00
|
|
|
/* AddToContext = */ false);
|
2009-09-15 05:59:20 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 14:47:28 +08:00
|
|
|
FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
|
|
|
|
NewClass->getLocation(),
|
|
|
|
NewTemplate,
|
|
|
|
/*FIXME:*/NewClass->getLocation());
|
|
|
|
Friend->setAccess(AS_public);
|
|
|
|
CurContext->addDecl(Friend);
|
2009-09-15 05:59:20 +08:00
|
|
|
}
|
2009-02-07 06:42:48 +08:00
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
if (Invalid) {
|
|
|
|
NewTemplate->setInvalidDecl();
|
|
|
|
NewClass->setInvalidDecl();
|
|
|
|
}
|
2010-08-21 17:40:31 +08:00
|
|
|
return NewTemplate;
|
2008-12-24 10:52:09 +08:00
|
|
|
}
|
2009-02-05 03:02:06 +08:00
|
|
|
|
2009-11-26 01:50:39 +08:00
|
|
|
/// \brief Diagnose the presence of a default template argument on a
|
|
|
|
/// template parameter, which is ill-formed in certain contexts.
|
|
|
|
///
|
|
|
|
/// \returns true if the default template argument should be dropped.
|
2011-01-27 15:10:08 +08:00
|
|
|
static bool DiagnoseDefaultTemplateArgument(Sema &S,
|
2009-11-26 01:50:39 +08:00
|
|
|
Sema::TemplateParamListContext TPC,
|
|
|
|
SourceLocation ParamLoc,
|
|
|
|
SourceRange DefArgRange) {
|
|
|
|
switch (TPC) {
|
|
|
|
case Sema::TPC_ClassTemplate:
|
2011-05-06 05:57:07 +08:00
|
|
|
case Sema::TPC_TypeAliasTemplate:
|
2009-11-26 01:50:39 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
case Sema::TPC_FunctionTemplate:
|
2011-02-04 12:20:44 +08:00
|
|
|
case Sema::TPC_FriendFunctionTemplateDefinition:
|
2011-01-27 15:10:08 +08:00
|
|
|
// C++ [temp.param]p9:
|
2009-11-26 01:50:39 +08:00
|
|
|
// A default template-argument shall not be specified in a
|
|
|
|
// function template declaration or a function template
|
|
|
|
// definition [...]
|
2011-02-04 12:20:44 +08:00
|
|
|
// If a friend function template declaration specifies a default
|
|
|
|
// template-argument, that declaration shall be a definition and shall be
|
|
|
|
// the only declaration of the function template in the translation unit.
|
|
|
|
// (C++98/03 doesn't have this wording; see DR226).
|
2012-03-11 15:00:24 +08:00
|
|
|
S.Diag(ParamLoc, S.getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_template_parameter_default_in_function_template
|
|
|
|
: diag::ext_template_parameter_default_in_function_template)
|
|
|
|
<< DefArgRange;
|
2009-11-26 01:50:39 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
case Sema::TPC_ClassTemplateMember:
|
|
|
|
// C++0x [temp.param]p9:
|
|
|
|
// A default template-argument shall not be specified in the
|
|
|
|
// template-parameter-lists of the definition of a member of a
|
|
|
|
// class template that appears outside of the member's class.
|
|
|
|
S.Diag(ParamLoc, diag::err_template_parameter_default_template_member)
|
|
|
|
<< DefArgRange;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case Sema::TPC_FriendFunctionTemplate:
|
|
|
|
// C++ [temp.param]p9:
|
|
|
|
// A default template-argument shall not be specified in a
|
|
|
|
// friend template declaration.
|
|
|
|
S.Diag(ParamLoc, diag::err_template_parameter_default_friend_template)
|
|
|
|
<< DefArgRange;
|
|
|
|
return true;
|
|
|
|
|
|
|
|
// FIXME: C++0x [temp.param]p9 allows default template-arguments
|
|
|
|
// for friend function templates if there is only a single
|
|
|
|
// declaration (and it is a definition). Strange!
|
|
|
|
}
|
|
|
|
|
2012-01-17 14:56:22 +08:00
|
|
|
llvm_unreachable("Invalid TemplateParamListContext!");
|
2009-11-26 01:50:39 +08:00
|
|
|
}
|
|
|
|
|
2010-12-16 23:36:43 +08:00
|
|
|
/// \brief Check for unexpanded parameter packs within the template parameters
|
|
|
|
/// of a template template parameter, recursively.
|
2011-03-26 20:38:21 +08:00
|
|
|
static bool DiagnoseUnexpandedParameterPacks(Sema &S,
|
|
|
|
TemplateTemplateParmDecl *TTP) {
|
2010-12-16 23:36:43 +08:00
|
|
|
TemplateParameterList *Params = TTP->getTemplateParameters();
|
|
|
|
for (unsigned I = 0, N = Params->size(); I != N; ++I) {
|
|
|
|
NamedDecl *P = Params->getParam(I);
|
|
|
|
if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(P)) {
|
2011-01-27 15:10:08 +08:00
|
|
|
if (S.DiagnoseUnexpandedParameterPack(NTTP->getLocation(),
|
2010-12-16 23:36:43 +08:00
|
|
|
NTTP->getTypeSourceInfo(),
|
|
|
|
Sema::UPPC_NonTypeTemplateParameterType))
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-16 23:36:43 +08:00
|
|
|
continue;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
|
|
|
if (TemplateTemplateParmDecl *InnerTTP
|
2010-12-16 23:36:43 +08:00
|
|
|
= dyn_cast<TemplateTemplateParmDecl>(P))
|
|
|
|
if (DiagnoseUnexpandedParameterPacks(S, InnerTTP))
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-16 23:36:43 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
/// \brief Checks the validity of a template parameter list, possibly
|
|
|
|
/// considering the template parameter list from a previous
|
|
|
|
/// declaration.
|
|
|
|
///
|
|
|
|
/// If an "old" template parameter list is provided, it must be
|
|
|
|
/// equivalent (per TemplateParameterListsAreEqual) to the "new"
|
|
|
|
/// template parameter list.
|
|
|
|
///
|
|
|
|
/// \param NewParams Template parameter list for a new template
|
|
|
|
/// declaration. This template parameter list will be updated with any
|
|
|
|
/// default arguments that are carried through from the previous
|
|
|
|
/// template parameter list.
|
|
|
|
///
|
|
|
|
/// \param OldParams If provided, template parameter list from a
|
|
|
|
/// previous declaration of the same template. Default template
|
|
|
|
/// arguments will be merged from the old template parameter list to
|
|
|
|
/// the new template parameter list.
|
|
|
|
///
|
2009-11-26 01:50:39 +08:00
|
|
|
/// \param TPC Describes the context in which we are checking the given
|
|
|
|
/// template parameter list.
|
|
|
|
///
|
2009-02-11 03:49:53 +08:00
|
|
|
/// \returns true if an error occurred, false otherwise.
|
|
|
|
bool Sema::CheckTemplateParameterList(TemplateParameterList *NewParams,
|
2009-11-26 01:50:39 +08:00
|
|
|
TemplateParameterList *OldParams,
|
|
|
|
TemplateParamListContext TPC) {
|
2009-02-11 03:49:53 +08:00
|
|
|
bool Invalid = false;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
// C++ [temp.param]p10:
|
|
|
|
// The set of default template-arguments available for use with a
|
|
|
|
// template declaration or definition is obtained by merging the
|
|
|
|
// default arguments from the definition (if in scope) and all
|
|
|
|
// declarations in scope in the same way default function
|
|
|
|
// arguments are (8.3.6).
|
|
|
|
bool SawDefaultArgument = false;
|
|
|
|
SourceLocation PreviousDefaultArgLoc;
|
|
|
|
|
2009-02-12 07:03:27 +08:00
|
|
|
// Dummy initialization to avoid warnings.
|
2009-02-12 04:46:19 +08:00
|
|
|
TemplateParameterList::iterator OldParam = NewParams->end();
|
2009-02-11 03:49:53 +08:00
|
|
|
if (OldParams)
|
|
|
|
OldParam = OldParams->begin();
|
|
|
|
|
2011-01-27 09:40:17 +08:00
|
|
|
bool RemoveDefaultArguments = false;
|
2009-02-11 03:49:53 +08:00
|
|
|
for (TemplateParameterList::iterator NewParam = NewParams->begin(),
|
|
|
|
NewParamEnd = NewParams->end();
|
|
|
|
NewParam != NewParamEnd; ++NewParam) {
|
|
|
|
// Variables used to diagnose redundant default arguments
|
|
|
|
bool RedundantDefaultArg = false;
|
|
|
|
SourceLocation OldDefaultLoc;
|
|
|
|
SourceLocation NewDefaultLoc;
|
|
|
|
|
2011-10-19 13:19:50 +08:00
|
|
|
// Variable used to diagnose missing default arguments
|
2009-02-11 03:49:53 +08:00
|
|
|
bool MissingDefaultArg = false;
|
|
|
|
|
2011-10-19 13:19:50 +08:00
|
|
|
// Variable used to diagnose non-final parameter packs
|
|
|
|
bool SawParameterPack = false;
|
2009-06-13 07:20:15 +08:00
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
if (TemplateTypeParmDecl *NewTypeParm
|
|
|
|
= dyn_cast<TemplateTypeParmDecl>(*NewParam)) {
|
2009-11-26 01:50:39 +08:00
|
|
|
// Check the presence of a default argument here.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (NewTypeParm->hasDefaultArgument() &&
|
|
|
|
DiagnoseDefaultTemplateArgument(*this, TPC,
|
|
|
|
NewTypeParm->getLocation(),
|
2009-11-26 01:50:39 +08:00
|
|
|
NewTypeParm->getDefaultArgumentInfo()->getTypeLoc()
|
2010-05-20 18:00:11 +08:00
|
|
|
.getSourceRange()))
|
2009-11-26 01:50:39 +08:00
|
|
|
NewTypeParm->removeDefaultArgument();
|
|
|
|
|
|
|
|
// Merge default arguments for template type parameters.
|
2009-09-09 23:08:12 +08:00
|
|
|
TemplateTypeParmDecl *OldTypeParm
|
2009-02-11 03:49:53 +08:00
|
|
|
= OldParams? cast<TemplateTypeParmDecl>(*OldParam) : 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-13 07:20:15 +08:00
|
|
|
if (NewTypeParm->isParameterPack()) {
|
|
|
|
assert(!NewTypeParm->hasDefaultArgument() &&
|
|
|
|
"Parameter packs can't have a default argument!");
|
|
|
|
SawParameterPack = true;
|
2009-09-09 23:08:12 +08:00
|
|
|
} else if (OldTypeParm && OldTypeParm->hasDefaultArgument() &&
|
2009-10-29 16:12:44 +08:00
|
|
|
NewTypeParm->hasDefaultArgument()) {
|
2009-02-11 03:49:53 +08:00
|
|
|
OldDefaultLoc = OldTypeParm->getDefaultArgumentLoc();
|
|
|
|
NewDefaultLoc = NewTypeParm->getDefaultArgumentLoc();
|
|
|
|
SawDefaultArgument = true;
|
|
|
|
RedundantDefaultArg = true;
|
|
|
|
PreviousDefaultArgLoc = NewDefaultLoc;
|
|
|
|
} else if (OldTypeParm && OldTypeParm->hasDefaultArgument()) {
|
|
|
|
// Merge the default argument from the old declaration to the
|
|
|
|
// new declaration.
|
|
|
|
SawDefaultArgument = true;
|
2009-10-29 16:12:44 +08:00
|
|
|
NewTypeParm->setDefaultArgument(OldTypeParm->getDefaultArgumentInfo(),
|
2009-02-11 03:49:53 +08:00
|
|
|
true);
|
|
|
|
PreviousDefaultArgLoc = OldTypeParm->getDefaultArgumentLoc();
|
|
|
|
} else if (NewTypeParm->hasDefaultArgument()) {
|
|
|
|
SawDefaultArgument = true;
|
|
|
|
PreviousDefaultArgLoc = NewTypeParm->getDefaultArgumentLoc();
|
|
|
|
} else if (SawDefaultArgument)
|
|
|
|
MissingDefaultArg = true;
|
2009-08-05 05:02:39 +08:00
|
|
|
} else if (NonTypeTemplateParmDecl *NewNonTypeParm
|
2009-02-11 03:49:53 +08:00
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(*NewParam)) {
|
2010-12-16 23:36:43 +08:00
|
|
|
// Check for unexpanded parameter packs.
|
|
|
|
if (DiagnoseUnexpandedParameterPack(NewNonTypeParm->getLocation(),
|
2011-01-27 15:10:08 +08:00
|
|
|
NewNonTypeParm->getTypeSourceInfo(),
|
2010-12-16 23:36:43 +08:00
|
|
|
UPPC_NonTypeTemplateParameterType)) {
|
|
|
|
Invalid = true;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2009-11-26 01:50:39 +08:00
|
|
|
// Check the presence of a default argument here.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (NewNonTypeParm->hasDefaultArgument() &&
|
|
|
|
DiagnoseDefaultTemplateArgument(*this, TPC,
|
|
|
|
NewNonTypeParm->getLocation(),
|
2009-11-26 01:50:39 +08:00
|
|
|
NewNonTypeParm->getDefaultArgument()->getSourceRange())) {
|
2010-06-09 17:26:05 +08:00
|
|
|
NewNonTypeParm->removeDefaultArgument();
|
2009-11-26 01:50:39 +08:00
|
|
|
}
|
|
|
|
|
2009-08-05 05:02:39 +08:00
|
|
|
// Merge default arguments for non-type template parameters
|
2009-02-11 03:49:53 +08:00
|
|
|
NonTypeTemplateParmDecl *OldNonTypeParm
|
|
|
|
= OldParams? cast<NonTypeTemplateParmDecl>(*OldParam) : 0;
|
2011-01-06 00:19:19 +08:00
|
|
|
if (NewNonTypeParm->isParameterPack()) {
|
|
|
|
assert(!NewNonTypeParm->hasDefaultArgument() &&
|
|
|
|
"Parameter packs can't have a default argument!");
|
|
|
|
SawParameterPack = true;
|
|
|
|
} else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument() &&
|
2009-02-11 03:49:53 +08:00
|
|
|
NewNonTypeParm->hasDefaultArgument()) {
|
|
|
|
OldDefaultLoc = OldNonTypeParm->getDefaultArgumentLoc();
|
|
|
|
NewDefaultLoc = NewNonTypeParm->getDefaultArgumentLoc();
|
|
|
|
SawDefaultArgument = true;
|
|
|
|
RedundantDefaultArg = true;
|
|
|
|
PreviousDefaultArgLoc = NewDefaultLoc;
|
|
|
|
} else if (OldNonTypeParm && OldNonTypeParm->hasDefaultArgument()) {
|
|
|
|
// Merge the default argument from the old declaration to the
|
|
|
|
// new declaration.
|
|
|
|
SawDefaultArgument = true;
|
|
|
|
// FIXME: We need to create a new kind of "default argument"
|
2011-01-05 23:48:55 +08:00
|
|
|
// expression that points to a previous non-type template
|
2009-02-11 03:49:53 +08:00
|
|
|
// parameter.
|
|
|
|
NewNonTypeParm->setDefaultArgument(
|
2010-06-09 17:26:05 +08:00
|
|
|
OldNonTypeParm->getDefaultArgument(),
|
|
|
|
/*Inherited=*/ true);
|
2009-02-11 03:49:53 +08:00
|
|
|
PreviousDefaultArgLoc = OldNonTypeParm->getDefaultArgumentLoc();
|
|
|
|
} else if (NewNonTypeParm->hasDefaultArgument()) {
|
|
|
|
SawDefaultArgument = true;
|
|
|
|
PreviousDefaultArgLoc = NewNonTypeParm->getDefaultArgumentLoc();
|
|
|
|
} else if (SawDefaultArgument)
|
2009-09-09 23:08:12 +08:00
|
|
|
MissingDefaultArg = true;
|
2009-08-05 05:02:39 +08:00
|
|
|
} else {
|
2009-02-11 03:49:53 +08:00
|
|
|
TemplateTemplateParmDecl *NewTemplateParm
|
|
|
|
= cast<TemplateTemplateParmDecl>(*NewParam);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-16 23:36:43 +08:00
|
|
|
// Check for unexpanded parameter packs, recursively.
|
2011-10-25 11:44:56 +08:00
|
|
|
if (::DiagnoseUnexpandedParameterPacks(*this, NewTemplateParm)) {
|
2010-12-16 23:36:43 +08:00
|
|
|
Invalid = true;
|
|
|
|
continue;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-10-19 13:19:50 +08:00
|
|
|
// Check the presence of a default argument here.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (NewTemplateParm->hasDefaultArgument() &&
|
|
|
|
DiagnoseDefaultTemplateArgument(*this, TPC,
|
|
|
|
NewTemplateParm->getLocation(),
|
2009-11-26 01:50:39 +08:00
|
|
|
NewTemplateParm->getDefaultArgument().getSourceRange()))
|
2010-06-09 17:26:05 +08:00
|
|
|
NewTemplateParm->removeDefaultArgument();
|
2009-11-26 01:50:39 +08:00
|
|
|
|
|
|
|
// Merge default arguments for template template parameters
|
2009-02-11 03:49:53 +08:00
|
|
|
TemplateTemplateParmDecl *OldTemplateParm
|
|
|
|
= OldParams? cast<TemplateTemplateParmDecl>(*OldParam) : 0;
|
2011-01-06 00:19:19 +08:00
|
|
|
if (NewTemplateParm->isParameterPack()) {
|
|
|
|
assert(!NewTemplateParm->hasDefaultArgument() &&
|
|
|
|
"Parameter packs can't have a default argument!");
|
|
|
|
SawParameterPack = true;
|
|
|
|
} else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument() &&
|
2009-02-11 03:49:53 +08:00
|
|
|
NewTemplateParm->hasDefaultArgument()) {
|
2009-11-11 09:00:40 +08:00
|
|
|
OldDefaultLoc = OldTemplateParm->getDefaultArgument().getLocation();
|
|
|
|
NewDefaultLoc = NewTemplateParm->getDefaultArgument().getLocation();
|
2009-02-11 03:49:53 +08:00
|
|
|
SawDefaultArgument = true;
|
|
|
|
RedundantDefaultArg = true;
|
|
|
|
PreviousDefaultArgLoc = NewDefaultLoc;
|
|
|
|
} else if (OldTemplateParm && OldTemplateParm->hasDefaultArgument()) {
|
|
|
|
// Merge the default argument from the old declaration to the
|
|
|
|
// new declaration.
|
|
|
|
SawDefaultArgument = true;
|
2009-05-16 15:39:55 +08:00
|
|
|
// FIXME: We need to create a new kind of "default argument" expression
|
|
|
|
// that points to a previous template template parameter.
|
2009-02-11 03:49:53 +08:00
|
|
|
NewTemplateParm->setDefaultArgument(
|
2010-06-09 17:26:05 +08:00
|
|
|
OldTemplateParm->getDefaultArgument(),
|
|
|
|
/*Inherited=*/ true);
|
2009-11-11 09:00:40 +08:00
|
|
|
PreviousDefaultArgLoc
|
|
|
|
= OldTemplateParm->getDefaultArgument().getLocation();
|
2009-02-11 03:49:53 +08:00
|
|
|
} else if (NewTemplateParm->hasDefaultArgument()) {
|
|
|
|
SawDefaultArgument = true;
|
2009-11-11 09:00:40 +08:00
|
|
|
PreviousDefaultArgLoc
|
|
|
|
= NewTemplateParm->getDefaultArgument().getLocation();
|
2009-02-11 03:49:53 +08:00
|
|
|
} else if (SawDefaultArgument)
|
2009-09-09 23:08:12 +08:00
|
|
|
MissingDefaultArg = true;
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
|
|
|
|
2011-10-19 13:19:50 +08:00
|
|
|
// C++0x [temp.param]p11:
|
|
|
|
// If a template parameter of a primary class template or alias template
|
|
|
|
// is a template parameter pack, it shall be the last template parameter.
|
|
|
|
if (SawParameterPack && (NewParam + 1) != NewParamEnd &&
|
|
|
|
(TPC == TPC_ClassTemplate || TPC == TPC_TypeAliasTemplate)) {
|
|
|
|
Diag((*NewParam)->getLocation(),
|
|
|
|
diag::err_template_param_pack_must_be_last_template_parameter);
|
|
|
|
Invalid = true;
|
|
|
|
}
|
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
if (RedundantDefaultArg) {
|
|
|
|
// C++ [temp.param]p12:
|
|
|
|
// A template-parameter shall not be given default arguments
|
|
|
|
// by two different declarations in the same scope.
|
|
|
|
Diag(NewDefaultLoc, diag::err_template_param_default_arg_redefinition);
|
|
|
|
Diag(OldDefaultLoc, diag::note_template_param_prev_default_arg);
|
|
|
|
Invalid = true;
|
2011-02-04 11:57:22 +08:00
|
|
|
} else if (MissingDefaultArg && TPC != TPC_FunctionTemplate) {
|
2009-02-11 03:49:53 +08:00
|
|
|
// C++ [temp.param]p11:
|
2011-01-27 15:10:08 +08:00
|
|
|
// If a template-parameter of a class template has a default
|
|
|
|
// template-argument, each subsequent template-parameter shall either
|
2011-01-06 00:21:17 +08:00
|
|
|
// have a default template-argument supplied or be a template parameter
|
|
|
|
// pack.
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag((*NewParam)->getLocation(),
|
2009-02-11 03:49:53 +08:00
|
|
|
diag::err_template_param_default_arg_missing);
|
|
|
|
Diag(PreviousDefaultArgLoc, diag::note_template_param_prev_default_arg);
|
|
|
|
Invalid = true;
|
2011-01-27 09:40:17 +08:00
|
|
|
RemoveDefaultArguments = true;
|
2009-02-11 03:49:53 +08:00
|
|
|
}
|
2009-02-10 07:23:08 +08:00
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
// If we have an old template parameter list that we're merging
|
|
|
|
// in, move on to the next parameter.
|
|
|
|
if (OldParams)
|
|
|
|
++OldParam;
|
|
|
|
}
|
|
|
|
|
2011-01-27 09:40:17 +08:00
|
|
|
// We were missing some default arguments at the end of the list, so remove
|
|
|
|
// all of the default arguments.
|
|
|
|
if (RemoveDefaultArguments) {
|
|
|
|
for (TemplateParameterList::iterator NewParam = NewParams->begin(),
|
|
|
|
NewParamEnd = NewParams->end();
|
|
|
|
NewParam != NewParamEnd; ++NewParam) {
|
|
|
|
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*NewParam))
|
|
|
|
TTP->removeDefaultArgument();
|
2011-01-27 15:10:08 +08:00
|
|
|
else if (NonTypeTemplateParmDecl *NTTP
|
2011-01-27 09:40:17 +08:00
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(*NewParam))
|
|
|
|
NTTP->removeDefaultArgument();
|
|
|
|
else
|
|
|
|
cast<TemplateTemplateParmDecl>(*NewParam)->removeDefaultArgument();
|
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-11 03:49:53 +08:00
|
|
|
return Invalid;
|
|
|
|
}
|
2009-02-10 07:23:08 +08:00
|
|
|
|
2010-10-20 13:44:58 +08:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
/// A class which looks for a use of a certain level of template
|
|
|
|
/// parameter.
|
|
|
|
struct DependencyChecker : RecursiveASTVisitor<DependencyChecker> {
|
|
|
|
typedef RecursiveASTVisitor<DependencyChecker> super;
|
|
|
|
|
|
|
|
unsigned Depth;
|
|
|
|
bool Match;
|
|
|
|
|
|
|
|
DependencyChecker(TemplateParameterList *Params) : Match(false) {
|
|
|
|
NamedDecl *ND = Params->getParam(0);
|
|
|
|
if (TemplateTypeParmDecl *PD = dyn_cast<TemplateTypeParmDecl>(ND)) {
|
|
|
|
Depth = PD->getDepth();
|
|
|
|
} else if (NonTypeTemplateParmDecl *PD =
|
|
|
|
dyn_cast<NonTypeTemplateParmDecl>(ND)) {
|
|
|
|
Depth = PD->getDepth();
|
|
|
|
} else {
|
|
|
|
Depth = cast<TemplateTemplateParmDecl>(ND)->getDepth();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Matches(unsigned ParmDepth) {
|
|
|
|
if (ParmDepth >= Depth) {
|
|
|
|
Match = true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
|
|
|
|
return !Matches(T->getDepth());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TraverseTemplateName(TemplateName N) {
|
|
|
|
if (TemplateTemplateParmDecl *PD =
|
|
|
|
dyn_cast_or_null<TemplateTemplateParmDecl>(N.getAsTemplateDecl()))
|
|
|
|
if (Matches(PD->getDepth())) return false;
|
|
|
|
return super::TraverseTemplateName(N);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VisitDeclRefExpr(DeclRefExpr *E) {
|
|
|
|
if (NonTypeTemplateParmDecl *PD =
|
|
|
|
dyn_cast<NonTypeTemplateParmDecl>(E->getDecl())) {
|
|
|
|
if (PD->getDepth() == Depth) {
|
|
|
|
Match = true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return super::VisitDeclRefExpr(E);
|
|
|
|
}
|
2011-05-13 08:34:01 +08:00
|
|
|
|
|
|
|
bool TraverseInjectedClassNameType(const InjectedClassNameType *T) {
|
|
|
|
return TraverseType(T->getInjectedSpecializationType());
|
|
|
|
}
|
2010-10-20 13:44:58 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
/// Determines whether a given type depends on the given parameter
|
2010-10-20 13:44:58 +08:00
|
|
|
/// list.
|
|
|
|
static bool
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
DependsOnTemplateParameters(QualType T, TemplateParameterList *Params) {
|
2010-10-20 13:44:58 +08:00
|
|
|
DependencyChecker Checker(Params);
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
Checker.TraverseType(T);
|
2010-10-20 13:44:58 +08:00
|
|
|
return Checker.Match;
|
|
|
|
}
|
|
|
|
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
// Find the source range corresponding to the named type in the given
|
|
|
|
// nested-name-specifier, if any.
|
|
|
|
static SourceRange getRangeOfTypeInNestedNameSpecifier(ASTContext &Context,
|
|
|
|
QualType T,
|
|
|
|
const CXXScopeSpec &SS) {
|
|
|
|
NestedNameSpecifierLoc NNSLoc(SS.getScopeRep(), SS.location_data());
|
|
|
|
while (NestedNameSpecifier *NNS = NNSLoc.getNestedNameSpecifier()) {
|
|
|
|
if (const Type *CurType = NNS->getAsType()) {
|
|
|
|
if (Context.hasSameUnqualifiedType(T, QualType(CurType, 0)))
|
|
|
|
return NNSLoc.getTypeLoc().getSourceRange();
|
|
|
|
} else
|
|
|
|
break;
|
|
|
|
|
|
|
|
NNSLoc = NNSLoc.getPrefix();
|
|
|
|
}
|
|
|
|
|
|
|
|
return SourceRange();
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
/// \brief Match the given template parameter lists to the given scope
|
2009-07-22 07:53:31 +08:00
|
|
|
/// specifier, returning the template parameter list that applies to the
|
|
|
|
/// name.
|
|
|
|
///
|
|
|
|
/// \param DeclStartLoc the start of the declaration that has a scope
|
|
|
|
/// specifier or a template parameter list.
|
2009-09-09 23:08:12 +08:00
|
|
|
///
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
/// \param DeclLoc The location of the declaration itself.
|
|
|
|
///
|
2009-07-22 07:53:31 +08:00
|
|
|
/// \param SS the scope specifier that will be matched to the given template
|
|
|
|
/// parameter lists. This scope specifier precedes a qualified name that is
|
|
|
|
/// being declared.
|
|
|
|
///
|
|
|
|
/// \param ParamLists the template parameter lists, from the outermost to the
|
|
|
|
/// innermost template parameter lists.
|
|
|
|
///
|
|
|
|
/// \param NumParamLists the number of template parameter lists in ParamLists.
|
|
|
|
///
|
2010-04-14 04:37:33 +08:00
|
|
|
/// \param IsFriend Whether to apply the slightly different rules for
|
|
|
|
/// matching template parameters to scope specifiers in friend
|
|
|
|
/// declarations.
|
|
|
|
///
|
2009-10-08 06:35:40 +08:00
|
|
|
/// \param IsExplicitSpecialization will be set true if the entity being
|
|
|
|
/// declared is an explicit specialization, false otherwise.
|
|
|
|
///
|
2009-09-09 23:08:12 +08:00
|
|
|
/// \returns the template parameter list, if any, that corresponds to the
|
2009-07-22 07:53:31 +08:00
|
|
|
/// name that is preceded by the scope specifier @p SS. This template
|
2011-03-18 23:16:37 +08:00
|
|
|
/// parameter list may have template parameters (if we're declaring a
|
2009-09-09 23:08:12 +08:00
|
|
|
/// template) or may have no template parameters (if we're declaring a
|
2011-03-18 23:16:37 +08:00
|
|
|
/// template specialization), or may be NULL (if what we're declaring isn't
|
2009-07-22 07:53:31 +08:00
|
|
|
/// itself a template).
|
|
|
|
TemplateParameterList *
|
|
|
|
Sema::MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc,
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
SourceLocation DeclLoc,
|
2009-07-22 07:53:31 +08:00
|
|
|
const CXXScopeSpec &SS,
|
|
|
|
TemplateParameterList **ParamLists,
|
2009-10-08 06:35:40 +08:00
|
|
|
unsigned NumParamLists,
|
2010-04-14 04:37:33 +08:00
|
|
|
bool IsFriend,
|
2010-07-15 07:14:12 +08:00
|
|
|
bool &IsExplicitSpecialization,
|
|
|
|
bool &Invalid) {
|
2009-10-08 06:35:40 +08:00
|
|
|
IsExplicitSpecialization = false;
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
Invalid = false;
|
|
|
|
|
|
|
|
// The sequence of nested types to which we will match up the template
|
|
|
|
// parameter lists. We first build this list by starting with the type named
|
|
|
|
// by the nested-name-specifier and walking out until we run out of types.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<QualType, 4> NestedTypes;
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
QualType T;
|
2011-05-16 01:27:27 +08:00
|
|
|
if (SS.getScopeRep()) {
|
|
|
|
if (CXXRecordDecl *Record
|
|
|
|
= dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS, true)))
|
|
|
|
T = Context.getTypeDeclType(Record);
|
|
|
|
else
|
|
|
|
T = QualType(SS.getScopeRep()->getAsType(), 0);
|
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
|
|
|
|
// If we found an explicit specialization that prevents us from needing
|
|
|
|
// 'template<>' headers, this will be set to the location of that
|
|
|
|
// explicit specialization.
|
|
|
|
SourceLocation ExplicitSpecLoc;
|
|
|
|
|
|
|
|
while (!T.isNull()) {
|
|
|
|
NestedTypes.push_back(T);
|
|
|
|
|
|
|
|
// Retrieve the parent of a record type.
|
|
|
|
if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) {
|
|
|
|
// If this type is an explicit specialization, we're done.
|
|
|
|
if (ClassTemplateSpecializationDecl *Spec
|
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
|
|
|
|
if (!isa<ClassTemplatePartialSpecializationDecl>(Spec) &&
|
|
|
|
Spec->getSpecializationKind() == TSK_ExplicitSpecialization) {
|
|
|
|
ExplicitSpecLoc = Spec->getLocation();
|
|
|
|
break;
|
2009-11-23 20:11:45 +08:00
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
} else if (Record->getTemplateSpecializationKind()
|
|
|
|
== TSK_ExplicitSpecialization) {
|
|
|
|
ExplicitSpecLoc = Record->getLocation();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (TypeDecl *Parent = dyn_cast<TypeDecl>(Record->getParent()))
|
|
|
|
T = Context.getTypeDeclType(Parent);
|
|
|
|
else
|
|
|
|
T = QualType();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (const TemplateSpecializationType *TST
|
|
|
|
= T->getAs<TemplateSpecializationType>()) {
|
|
|
|
if (TemplateDecl *Template = TST->getTemplateName().getAsTemplateDecl()) {
|
|
|
|
if (TypeDecl *Parent = dyn_cast<TypeDecl>(Template->getDeclContext()))
|
|
|
|
T = Context.getTypeDeclType(Parent);
|
|
|
|
else
|
|
|
|
T = QualType();
|
|
|
|
continue;
|
2009-07-22 07:53:31 +08:00
|
|
|
}
|
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
|
|
|
|
// Look one step prior in a dependent template specialization type.
|
|
|
|
if (const DependentTemplateSpecializationType *DependentTST
|
|
|
|
= T->getAs<DependentTemplateSpecializationType>()) {
|
|
|
|
if (NestedNameSpecifier *NNS = DependentTST->getQualifier())
|
|
|
|
T = QualType(NNS->getAsType(), 0);
|
|
|
|
else
|
|
|
|
T = QualType();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Look one step prior in a dependent name type.
|
|
|
|
if (const DependentNameType *DependentName = T->getAs<DependentNameType>()){
|
|
|
|
if (NestedNameSpecifier *NNS = DependentName->getQualifier())
|
|
|
|
T = QualType(NNS->getAsType(), 0);
|
|
|
|
else
|
|
|
|
T = QualType();
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Retrieve the parent of an enumeration type.
|
|
|
|
if (const EnumType *EnumT = T->getAs<EnumType>()) {
|
|
|
|
// FIXME: Forward-declared enums require a TSK_ExplicitSpecialization
|
|
|
|
// check here.
|
|
|
|
EnumDecl *Enum = EnumT->getDecl();
|
|
|
|
|
|
|
|
// Get to the parent type.
|
|
|
|
if (TypeDecl *Parent = dyn_cast<TypeDecl>(Enum->getParent()))
|
|
|
|
T = Context.getTypeDeclType(Parent);
|
|
|
|
else
|
|
|
|
T = QualType();
|
|
|
|
continue;
|
2010-10-20 13:44:58 +08:00
|
|
|
}
|
|
|
|
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
T = QualType();
|
|
|
|
}
|
|
|
|
// Reverse the nested types list, since we want to traverse from the outermost
|
|
|
|
// to the innermost while checking template-parameter-lists.
|
|
|
|
std::reverse(NestedTypes.begin(), NestedTypes.end());
|
|
|
|
|
|
|
|
// C++0x [temp.expl.spec]p17:
|
|
|
|
// A member or a member template may be nested within many
|
|
|
|
// enclosing class templates. In an explicit specialization for
|
|
|
|
// such a member, the member declaration shall be preceded by a
|
|
|
|
// template<> for each enclosing class template that is
|
|
|
|
// explicitly specialized.
|
2011-06-06 23:22:55 +08:00
|
|
|
bool SawNonEmptyTemplateParameterList = false;
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
unsigned ParamIdx = 0;
|
|
|
|
for (unsigned TypeIdx = 0, NumTypes = NestedTypes.size(); TypeIdx != NumTypes;
|
|
|
|
++TypeIdx) {
|
|
|
|
T = NestedTypes[TypeIdx];
|
|
|
|
|
|
|
|
// Whether we expect a 'template<>' header.
|
|
|
|
bool NeedEmptyTemplateHeader = false;
|
2010-04-14 04:37:33 +08:00
|
|
|
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
// Whether we expect a template header with parameters.
|
|
|
|
bool NeedNonemptyTemplateHeader = false;
|
|
|
|
|
|
|
|
// For a dependent type, the set of template parameters that we
|
|
|
|
// expect to see.
|
|
|
|
TemplateParameterList *ExpectedTemplateParams = 0;
|
|
|
|
|
2011-05-12 07:26:17 +08:00
|
|
|
// C++0x [temp.expl.spec]p15:
|
|
|
|
// A member or a member template may be nested within many enclosing
|
|
|
|
// class templates. In an explicit specialization for such a member, the
|
|
|
|
// member declaration shall be preceded by a template<> for each
|
|
|
|
// enclosing class template that is explicitly specialized.
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
if (CXXRecordDecl *Record = T->getAsCXXRecordDecl()) {
|
|
|
|
if (ClassTemplatePartialSpecializationDecl *Partial
|
|
|
|
= dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) {
|
|
|
|
ExpectedTemplateParams = Partial->getTemplateParameters();
|
|
|
|
NeedNonemptyTemplateHeader = true;
|
|
|
|
} else if (Record->isDependentType()) {
|
|
|
|
if (Record->getDescribedClassTemplate()) {
|
|
|
|
ExpectedTemplateParams = Record->getDescribedClassTemplate()
|
|
|
|
->getTemplateParameters();
|
|
|
|
NeedNonemptyTemplateHeader = true;
|
|
|
|
}
|
|
|
|
} else if (ClassTemplateSpecializationDecl *Spec
|
|
|
|
= dyn_cast<ClassTemplateSpecializationDecl>(Record)) {
|
|
|
|
// C++0x [temp.expl.spec]p4:
|
|
|
|
// Members of an explicitly specialized class template are defined
|
|
|
|
// in the same manner as members of normal classes, and not using
|
|
|
|
// the template<> syntax.
|
|
|
|
if (Spec->getSpecializationKind() != TSK_ExplicitSpecialization)
|
|
|
|
NeedEmptyTemplateHeader = true;
|
|
|
|
else
|
2011-06-02 06:37:07 +08:00
|
|
|
continue;
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
} else if (Record->getTemplateSpecializationKind()) {
|
|
|
|
if (Record->getTemplateSpecializationKind()
|
2011-05-12 07:26:17 +08:00
|
|
|
!= TSK_ExplicitSpecialization &&
|
|
|
|
TypeIdx == NumTypes - 1)
|
|
|
|
IsExplicitSpecialization = true;
|
|
|
|
|
|
|
|
continue;
|
2010-04-14 04:37:33 +08:00
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
} else if (const TemplateSpecializationType *TST
|
|
|
|
= T->getAs<TemplateSpecializationType>()) {
|
|
|
|
if (TemplateDecl *Template = TST->getTemplateName().getAsTemplateDecl()) {
|
|
|
|
ExpectedTemplateParams = Template->getTemplateParameters();
|
|
|
|
NeedNonemptyTemplateHeader = true;
|
|
|
|
}
|
|
|
|
} else if (T->getAs<DependentTemplateSpecializationType>()) {
|
|
|
|
// FIXME: We actually could/should check the template arguments here
|
|
|
|
// against the corresponding template parameter list.
|
|
|
|
NeedNonemptyTemplateHeader = false;
|
|
|
|
}
|
|
|
|
|
2011-06-06 23:22:55 +08:00
|
|
|
// C++ [temp.expl.spec]p16:
|
|
|
|
// In an explicit specialization declaration for a member of a class
|
|
|
|
// template or a member template that ap- pears in namespace scope, the
|
|
|
|
// member template and some of its enclosing class templates may remain
|
|
|
|
// unspecialized, except that the declaration shall not explicitly
|
|
|
|
// specialize a class member template if its en- closing class templates
|
|
|
|
// are not explicitly specialized as well.
|
|
|
|
if (ParamIdx < NumParamLists) {
|
|
|
|
if (ParamLists[ParamIdx]->size() == 0) {
|
|
|
|
if (SawNonEmptyTemplateParameterList) {
|
|
|
|
Diag(DeclLoc, diag::err_specialize_member_of_template)
|
|
|
|
<< ParamLists[ParamIdx]->getSourceRange();
|
|
|
|
Invalid = true;
|
|
|
|
IsExplicitSpecialization = false;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
SawNonEmptyTemplateParameterList = true;
|
|
|
|
}
|
|
|
|
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
if (NeedEmptyTemplateHeader) {
|
|
|
|
// If we're on the last of the types, and we need a 'template<>' header
|
|
|
|
// here, then it's an explicit specialization.
|
|
|
|
if (TypeIdx == NumTypes - 1)
|
2009-10-08 06:35:40 +08:00
|
|
|
IsExplicitSpecialization = true;
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
|
|
|
|
if (ParamIdx < NumParamLists) {
|
|
|
|
if (ParamLists[ParamIdx]->size() > 0) {
|
|
|
|
// The header has template parameters when it shouldn't. Complain.
|
|
|
|
Diag(ParamLists[ParamIdx]->getTemplateLoc(),
|
|
|
|
diag::err_template_param_list_matches_nontemplate)
|
|
|
|
<< T
|
|
|
|
<< SourceRange(ParamLists[ParamIdx]->getLAngleLoc(),
|
|
|
|
ParamLists[ParamIdx]->getRAngleLoc())
|
|
|
|
<< getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
|
|
|
|
Invalid = true;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Consume this template header.
|
|
|
|
++ParamIdx;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!IsFriend) {
|
|
|
|
// We don't have a template header, but we should.
|
|
|
|
SourceLocation ExpectedTemplateLoc;
|
|
|
|
if (NumParamLists > 0)
|
|
|
|
ExpectedTemplateLoc = ParamLists[0]->getTemplateLoc();
|
|
|
|
else
|
|
|
|
ExpectedTemplateLoc = DeclStartLoc;
|
|
|
|
|
|
|
|
Diag(DeclLoc, diag::err_template_spec_needs_header)
|
|
|
|
<< getRangeOfTypeInNestedNameSpecifier(Context, T, SS)
|
|
|
|
<< FixItHint::CreateInsertion(ExpectedTemplateLoc, "template<> ");
|
2009-07-22 07:53:31 +08:00
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
|
|
|
|
continue;
|
2009-07-22 07:53:31 +08:00
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
|
|
|
|
if (NeedNonemptyTemplateHeader) {
|
|
|
|
// In friend declarations we can have template-ids which don't
|
|
|
|
// depend on the corresponding template parameter lists. But
|
|
|
|
// assume that empty parameter lists are supposed to match this
|
|
|
|
// template-id.
|
|
|
|
if (IsFriend && T->isDependentType()) {
|
|
|
|
if (ParamIdx < NumParamLists &&
|
|
|
|
DependsOnTemplateParameters(T, ParamLists[ParamIdx]))
|
|
|
|
ExpectedTemplateParams = 0;
|
|
|
|
else
|
|
|
|
continue;
|
2009-09-09 23:08:12 +08:00
|
|
|
}
|
2009-11-26 01:50:39 +08:00
|
|
|
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
if (ParamIdx < NumParamLists) {
|
|
|
|
// Check the template parameter list, if we can.
|
|
|
|
if (ExpectedTemplateParams &&
|
|
|
|
!TemplateParameterListsAreEqual(ParamLists[ParamIdx],
|
|
|
|
ExpectedTemplateParams,
|
|
|
|
true, TPL_TemplateMatch))
|
|
|
|
Invalid = true;
|
|
|
|
|
|
|
|
if (!Invalid &&
|
|
|
|
CheckTemplateParameterList(ParamLists[ParamIdx], 0,
|
|
|
|
TPC_ClassTemplateMember))
|
|
|
|
Invalid = true;
|
|
|
|
|
|
|
|
++ParamIdx;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
Diag(DeclLoc, diag::err_template_spec_needs_template_parameters)
|
|
|
|
<< T
|
|
|
|
<< getRangeOfTypeInNestedNameSpecifier(Context, T, SS);
|
|
|
|
Invalid = true;
|
|
|
|
continue;
|
|
|
|
}
|
2009-07-22 07:53:31 +08:00
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
|
2009-07-22 07:53:31 +08:00
|
|
|
// If there were at least as many template-ids as there were template
|
|
|
|
// parameter lists, then there are no template parameter lists remaining for
|
|
|
|
// the declaration itself.
|
2010-10-20 13:44:58 +08:00
|
|
|
if (ParamIdx >= NumParamLists)
|
2009-07-22 07:53:31 +08:00
|
|
|
return 0;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-22 07:53:31 +08:00
|
|
|
// If there were too many template parameter lists, complain about that now.
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
if (ParamIdx < NumParamLists - 1) {
|
|
|
|
bool HasAnyExplicitSpecHeader = false;
|
|
|
|
bool AllExplicitSpecHeaders = true;
|
|
|
|
for (unsigned I = ParamIdx; I != NumParamLists - 1; ++I) {
|
|
|
|
if (ParamLists[I]->size() == 0)
|
|
|
|
HasAnyExplicitSpecHeader = true;
|
|
|
|
else
|
|
|
|
AllExplicitSpecHeaders = false;
|
2009-07-22 07:53:31 +08:00
|
|
|
}
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
|
|
|
|
Diag(ParamLists[ParamIdx]->getTemplateLoc(),
|
|
|
|
AllExplicitSpecHeaders? diag::warn_template_spec_extra_headers
|
|
|
|
: diag::err_template_spec_extra_headers)
|
|
|
|
<< SourceRange(ParamLists[ParamIdx]->getTemplateLoc(),
|
|
|
|
ParamLists[NumParamLists - 2]->getRAngleLoc());
|
|
|
|
|
|
|
|
// If there was a specialization somewhere, such that 'template<>' is
|
|
|
|
// not required, and there were any 'template<>' headers, note where the
|
|
|
|
// specialization occurred.
|
|
|
|
if (ExplicitSpecLoc.isValid() && HasAnyExplicitSpecHeader)
|
|
|
|
Diag(ExplicitSpecLoc,
|
|
|
|
diag::note_explicit_template_spec_does_not_need_header)
|
|
|
|
<< NestedTypes.back();
|
|
|
|
|
|
|
|
// We have a template parameter list with no corresponding scope, which
|
|
|
|
// means that the resulting template declaration can't be instantiated
|
|
|
|
// properly (we'll end up with dependent nodes when we shouldn't).
|
|
|
|
if (!AllExplicitSpecHeaders)
|
|
|
|
Invalid = true;
|
2009-07-22 07:53:31 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-06-06 23:22:55 +08:00
|
|
|
// C++ [temp.expl.spec]p16:
|
|
|
|
// In an explicit specialization declaration for a member of a class
|
|
|
|
// template or a member template that ap- pears in namespace scope, the
|
|
|
|
// member template and some of its enclosing class templates may remain
|
|
|
|
// unspecialized, except that the declaration shall not explicitly
|
|
|
|
// specialize a class member template if its en- closing class templates
|
|
|
|
// are not explicitly specialized as well.
|
|
|
|
if (ParamLists[NumParamLists - 1]->size() == 0 &&
|
|
|
|
SawNonEmptyTemplateParameterList) {
|
|
|
|
Diag(DeclLoc, diag::err_specialize_member_of_template)
|
|
|
|
<< ParamLists[ParamIdx]->getSourceRange();
|
|
|
|
Invalid = true;
|
|
|
|
IsExplicitSpecialization = false;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2009-07-22 07:53:31 +08:00
|
|
|
// Return the last template parameter list, which corresponds to the
|
|
|
|
// entity being declared.
|
|
|
|
return ParamLists[NumParamLists - 1];
|
|
|
|
}
|
|
|
|
|
2011-03-05 05:37:14 +08:00
|
|
|
void Sema::NoteAllFoundTemplates(TemplateName Name) {
|
|
|
|
if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
|
|
|
|
Diag(Template->getLocation(), diag::note_template_declared_here)
|
|
|
|
<< (isa<FunctionTemplateDecl>(Template)? 0
|
|
|
|
: isa<ClassTemplateDecl>(Template)? 1
|
2011-05-06 05:57:07 +08:00
|
|
|
: isa<TypeAliasTemplateDecl>(Template)? 2
|
|
|
|
: 3)
|
2011-03-05 05:37:14 +08:00
|
|
|
<< Template->getDeclName();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (OverloadedTemplateStorage *OST = Name.getAsOverloadedTemplate()) {
|
|
|
|
for (OverloadedTemplateStorage::iterator I = OST->begin(),
|
|
|
|
IEnd = OST->end();
|
|
|
|
I != IEnd; ++I)
|
|
|
|
Diag((*I)->getLocation(), diag::note_template_declared_here)
|
|
|
|
<< 0 << (*I)->getDeclName();
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-31 06:58:21 +08:00
|
|
|
QualType Sema::CheckTemplateIdType(TemplateName Name,
|
|
|
|
SourceLocation TemplateLoc,
|
2011-03-03 10:41:12 +08:00
|
|
|
TemplateArgumentListInfo &TemplateArgs) {
|
2011-06-30 16:33:18 +08:00
|
|
|
DependentTemplateName *DTN
|
|
|
|
= Name.getUnderlying().getAsDependentTemplateName();
|
2011-05-06 05:57:07 +08:00
|
|
|
if (DTN && DTN->isIdentifier())
|
|
|
|
// When building a template-id where the template-name is dependent,
|
|
|
|
// assume the template is a type template. Either our assumption is
|
|
|
|
// correct, or the code is ill-formed and will be diagnosed when the
|
|
|
|
// dependent name is substituted.
|
|
|
|
return Context.getDependentTemplateSpecializationType(ETK_None,
|
|
|
|
DTN->getQualifier(),
|
|
|
|
DTN->getIdentifier(),
|
|
|
|
TemplateArgs);
|
|
|
|
|
2009-03-31 06:58:21 +08:00
|
|
|
TemplateDecl *Template = Name.getAsTemplateDecl();
|
2011-03-05 05:37:14 +08:00
|
|
|
if (!Template || isa<FunctionTemplateDecl>(Template)) {
|
|
|
|
// We might have a substituted template template parameter pack. If so,
|
|
|
|
// build a template specialization type for it.
|
|
|
|
if (Name.getAsSubstTemplateTemplateParmPack())
|
|
|
|
return Context.getTemplateSpecializationType(Name, TemplateArgs);
|
2011-05-06 05:57:07 +08:00
|
|
|
|
2011-03-05 05:37:14 +08:00
|
|
|
Diag(TemplateLoc, diag::err_template_id_not_a_type)
|
|
|
|
<< Name;
|
|
|
|
NoteAllFoundTemplates(Name);
|
|
|
|
return QualType();
|
2009-03-31 08:43:58 +08:00
|
|
|
}
|
2009-03-31 06:58:21 +08:00
|
|
|
|
2009-02-10 07:23:08 +08:00
|
|
|
// Check that the template argument list is well-formed for this
|
|
|
|
// template.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 4> Converted;
|
2012-02-04 01:16:23 +08:00
|
|
|
bool ExpansionIntoFixedList = false;
|
2009-11-23 09:53:49 +08:00
|
|
|
if (CheckTemplateArgumentList(Template, TemplateLoc, TemplateArgs,
|
2012-02-04 01:16:23 +08:00
|
|
|
false, Converted, &ExpansionIntoFixedList))
|
2009-03-10 07:48:35 +08:00
|
|
|
return QualType();
|
2009-02-10 07:23:08 +08:00
|
|
|
|
2009-03-10 07:48:35 +08:00
|
|
|
QualType CanonType;
|
|
|
|
|
2011-07-01 09:22:09 +08:00
|
|
|
bool InstantiationDependent = false;
|
2012-02-04 01:16:23 +08:00
|
|
|
TypeAliasTemplateDecl *AliasTemplate = 0;
|
|
|
|
if (!ExpansionIntoFixedList &&
|
|
|
|
(AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Template))) {
|
2011-05-06 05:57:07 +08:00
|
|
|
// Find the canonical type for this type alias template specialization.
|
|
|
|
TypeAliasDecl *Pattern = AliasTemplate->getTemplatedDecl();
|
|
|
|
if (Pattern->isInvalidDecl())
|
|
|
|
return QualType();
|
|
|
|
|
|
|
|
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
|
|
|
Converted.data(), Converted.size());
|
|
|
|
|
|
|
|
// Only substitute for the innermost template argument list.
|
|
|
|
MultiLevelTemplateArgumentList TemplateArgLists;
|
2011-05-14 23:04:18 +08:00
|
|
|
TemplateArgLists.addOuterTemplateArguments(&TemplateArgs);
|
2011-05-12 08:06:17 +08:00
|
|
|
unsigned Depth = AliasTemplate->getTemplateParameters()->getDepth();
|
|
|
|
for (unsigned I = 0; I < Depth; ++I)
|
|
|
|
TemplateArgLists.addOuterTemplateArguments(0, 0);
|
2011-05-06 05:57:07 +08:00
|
|
|
|
|
|
|
InstantiatingTemplate Inst(*this, TemplateLoc, Template);
|
|
|
|
CanonType = SubstType(Pattern->getUnderlyingType(),
|
|
|
|
TemplateArgLists, AliasTemplate->getLocation(),
|
|
|
|
AliasTemplate->getDeclName());
|
|
|
|
if (CanonType.isNull())
|
|
|
|
return QualType();
|
|
|
|
} else if (Name.isDependent() ||
|
|
|
|
TemplateSpecializationType::anyDependentTemplateArguments(
|
2011-07-01 09:22:09 +08:00
|
|
|
TemplateArgs, InstantiationDependent)) {
|
2009-03-10 07:48:35 +08:00
|
|
|
// This class template specialization is a dependent
|
|
|
|
// type. Therefore, its canonical type is another class template
|
|
|
|
// specialization type that contains all of the converted
|
|
|
|
// arguments in canonical form. This ensures that, e.g., A<T> and
|
|
|
|
// A<T, T> have identical types when A is declared as:
|
|
|
|
//
|
|
|
|
// template<typename T, typename U = T> struct A;
|
2009-05-07 14:41:52 +08:00
|
|
|
TemplateName CanonName = Context.getCanonicalTemplateName(Name);
|
2009-09-09 23:08:12 +08:00
|
|
|
CanonType = Context.getTemplateSpecializationType(CanonName,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(),
|
|
|
|
Converted.size());
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-29 07:00:59 +08:00
|
|
|
// FIXME: CanonType is not actually the canonical type, and unfortunately
|
2009-10-29 16:12:44 +08:00
|
|
|
// it is a TemplateSpecializationType that we will never use again.
|
2009-07-29 07:00:59 +08:00
|
|
|
// In the future, we need to teach getTemplateSpecializationType to only
|
|
|
|
// build the canonical type and return that to us.
|
|
|
|
CanonType = Context.getCanonicalType(CanonType);
|
2010-04-27 08:57:59 +08:00
|
|
|
|
|
|
|
// This might work out to be a current instantiation, in which
|
|
|
|
// case the canonical type needs to be the InjectedClassNameType.
|
|
|
|
//
|
|
|
|
// TODO: in theory this could be a simple hashtable lookup; most
|
|
|
|
// changes to CurContext don't change the set of current
|
|
|
|
// instantiations.
|
|
|
|
if (isa<ClassTemplateDecl>(Template)) {
|
|
|
|
for (DeclContext *Ctx = CurContext; Ctx; Ctx = Ctx->getLookupParent()) {
|
|
|
|
// If we get out to a namespace, we're done.
|
|
|
|
if (Ctx->isFileContext()) break;
|
|
|
|
|
|
|
|
// If this isn't a record, keep looking.
|
|
|
|
CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx);
|
|
|
|
if (!Record) continue;
|
|
|
|
|
|
|
|
// Look for one of the two cases with InjectedClassNameTypes
|
|
|
|
// and check whether it's the same template.
|
|
|
|
if (!isa<ClassTemplatePartialSpecializationDecl>(Record) &&
|
|
|
|
!Record->getDescribedClassTemplate())
|
|
|
|
continue;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-04-27 08:57:59 +08:00
|
|
|
// Fetch the injected class name type and check whether its
|
|
|
|
// injected type is equal to the type we just built.
|
|
|
|
QualType ICNT = Context.getTypeDeclType(Record);
|
|
|
|
QualType Injected = cast<InjectedClassNameType>(ICNT)
|
|
|
|
->getInjectedSpecializationType();
|
|
|
|
|
|
|
|
if (CanonType != Injected->getCanonicalTypeInternal())
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// If so, the canonical type of this TST is the injected
|
|
|
|
// class name type of the record we just found.
|
|
|
|
assert(ICNT.isCanonical());
|
|
|
|
CanonType = ICNT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
} else if (ClassTemplateDecl *ClassTemplate
|
2009-03-31 06:58:21 +08:00
|
|
|
= dyn_cast<ClassTemplateDecl>(Template)) {
|
2009-03-10 07:48:35 +08:00
|
|
|
// Find the class template specialization declaration that
|
|
|
|
// corresponds to these arguments.
|
|
|
|
void *InsertPos = 0;
|
|
|
|
ClassTemplateSpecializationDecl *Decl
|
2011-01-27 15:10:08 +08:00
|
|
|
= ClassTemplate->findSpecialization(Converted.data(), Converted.size(),
|
2010-11-08 07:05:16 +08:00
|
|
|
InsertPos);
|
2009-03-10 07:48:35 +08:00
|
|
|
if (!Decl) {
|
|
|
|
// This is the first time we have referenced this class template
|
|
|
|
// specialization. Create the canonical declaration and add it to
|
|
|
|
// the set of specializations.
|
2009-09-09 23:08:12 +08:00
|
|
|
Decl = ClassTemplateSpecializationDecl::Create(Context,
|
2010-05-06 08:28:52 +08:00
|
|
|
ClassTemplate->getTemplatedDecl()->getTagKind(),
|
|
|
|
ClassTemplate->getDeclContext(),
|
2011-10-04 04:34:03 +08:00
|
|
|
ClassTemplate->getTemplatedDecl()->getLocStart(),
|
2010-05-06 08:28:52 +08:00
|
|
|
ClassTemplate->getLocation(),
|
2010-11-08 07:05:16 +08:00
|
|
|
ClassTemplate,
|
2011-01-27 15:10:08 +08:00
|
|
|
Converted.data(),
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.size(), 0);
|
2010-07-20 21:59:28 +08:00
|
|
|
ClassTemplate->AddSpecialization(Decl, InsertPos);
|
2009-03-10 07:48:35 +08:00
|
|
|
Decl->setLexicalDeclContext(CurContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
CanonType = Context.getTypeDeclType(Decl);
|
2010-03-10 11:28:59 +08:00
|
|
|
assert(isa<RecordType>(CanonType) &&
|
|
|
|
"type of non-dependent specialization is not a RecordType");
|
Added ClassTemplateSpecializationDecl, which is a subclass of
CXXRecordDecl that is used to represent class template
specializations. These are canonical declarations that can refer to
either an actual class template specialization in the code, e.g.,
template<> class vector<bool> { };
or to a template instantiation. However, neither of these features is
actually implemented yet, so really we're just using (and uniqing) the
declarations to make sure that, e.g., A<int> is a different type from
A<float>. Note that we carefully distinguish between what the user
wrote in the source code (e.g., "A<FLOAT>") and the semantic entity it
represents (e.g., "A<float, int>"); the former is in the sugared Type,
the latter is an actual Decl.
llvm-svn: 64716
2009-02-17 09:05:43 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
Added ClassTemplateSpecializationDecl, which is a subclass of
CXXRecordDecl that is used to represent class template
specializations. These are canonical declarations that can refer to
either an actual class template specialization in the code, e.g.,
template<> class vector<bool> { };
or to a template instantiation. However, neither of these features is
actually implemented yet, so really we're just using (and uniqing) the
declarations to make sure that, e.g., A<int> is a different type from
A<float>. Note that we carefully distinguish between what the user
wrote in the source code (e.g., "A<FLOAT>") and the semantic entity it
represents (e.g., "A<float, int>"); the former is in the sugared Type,
the latter is an actual Decl.
llvm-svn: 64716
2009-02-17 09:05:43 +08:00
|
|
|
// Build the fully-sugared type for this class template
|
|
|
|
// specialization, which refers back to the class template
|
|
|
|
// specialization we created or found.
|
2010-06-13 17:25:03 +08:00
|
|
|
return Context.getTemplateSpecializationType(Name, TemplateArgs, CanonType);
|
2009-03-10 07:48:35 +08:00
|
|
|
}
|
|
|
|
|
2010-08-27 07:41:50 +08:00
|
|
|
TypeResult
|
2012-02-06 22:41:24 +08:00
|
|
|
Sema::ActOnTemplateIdType(CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
|
2011-03-02 08:47:37 +08:00
|
|
|
TemplateTy TemplateD, SourceLocation TemplateLoc,
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation LAngleLoc,
|
2009-03-31 06:58:21 +08:00
|
|
|
ASTTemplateArgsPtr TemplateArgsIn,
|
2012-01-27 16:46:19 +08:00
|
|
|
SourceLocation RAngleLoc,
|
|
|
|
bool IsCtorOrDtorName) {
|
2011-03-02 08:47:37 +08:00
|
|
|
if (SS.isInvalid())
|
|
|
|
return true;
|
|
|
|
|
2009-03-31 06:58:21 +08:00
|
|
|
TemplateName Template = TemplateD.getAsVal<TemplateName>();
|
2009-03-10 07:48:35 +08:00
|
|
|
|
|
|
|
// Translate the parser's template argument list in our AST format.
|
2009-11-23 09:53:49 +08:00
|
|
|
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
|
2009-11-11 03:49:08 +08:00
|
|
|
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
2009-03-10 07:48:35 +08:00
|
|
|
|
2011-03-01 01:23:35 +08:00
|
|
|
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
|
2012-01-27 16:46:19 +08:00
|
|
|
QualType T
|
|
|
|
= Context.getDependentTemplateSpecializationType(ETK_None,
|
|
|
|
DTN->getQualifier(),
|
|
|
|
DTN->getIdentifier(),
|
|
|
|
TemplateArgs);
|
|
|
|
// Build type-source information.
|
2011-03-01 01:23:35 +08:00
|
|
|
TypeLocBuilder TLB;
|
|
|
|
DependentTemplateSpecializationTypeLoc SpecTL
|
|
|
|
= TLB.push<DependentTemplateSpecializationTypeLoc>(T);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setElaboratedKeywordLoc(SourceLocation());
|
|
|
|
SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
|
2012-02-07 06:45:07 +08:00
|
|
|
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setTemplateNameLoc(TemplateLoc);
|
2011-03-01 01:23:35 +08:00
|
|
|
SpecTL.setLAngleLoc(LAngleLoc);
|
|
|
|
SpecTL.setRAngleLoc(RAngleLoc);
|
|
|
|
for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I)
|
|
|
|
SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
|
|
|
|
return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
|
|
|
|
}
|
|
|
|
|
2009-11-23 09:53:49 +08:00
|
|
|
QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
|
2009-03-10 07:48:35 +08:00
|
|
|
TemplateArgsIn.release();
|
2009-04-02 05:51:26 +08:00
|
|
|
|
|
|
|
if (Result.isNull())
|
|
|
|
return true;
|
|
|
|
|
2011-03-02 08:47:37 +08:00
|
|
|
// Build type-source information.
|
2012-02-06 22:41:24 +08:00
|
|
|
TypeLocBuilder TLB;
|
2011-03-02 08:47:37 +08:00
|
|
|
TemplateSpecializationTypeLoc SpecTL
|
|
|
|
= TLB.push<TemplateSpecializationTypeLoc>(Result);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
|
2011-03-02 08:47:37 +08:00
|
|
|
SpecTL.setTemplateNameLoc(TemplateLoc);
|
|
|
|
SpecTL.setLAngleLoc(LAngleLoc);
|
|
|
|
SpecTL.setRAngleLoc(RAngleLoc);
|
|
|
|
for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i)
|
|
|
|
SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
|
|
|
|
|
2012-01-27 16:46:19 +08:00
|
|
|
// NOTE: avoid constructing an ElaboratedTypeLoc if this is a
|
|
|
|
// constructor or destructor name (in such a case, the scope specifier
|
|
|
|
// will be attached to the enclosing Decl or Expr node).
|
|
|
|
if (SS.isNotEmpty() && !IsCtorOrDtorName) {
|
2011-03-02 08:47:37 +08:00
|
|
|
// Create an elaborated-type-specifier containing the nested-name-specifier.
|
|
|
|
Result = Context.getElaboratedType(ETK_None, SS.getScopeRep(), Result);
|
|
|
|
ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result);
|
2012-02-07 03:09:27 +08:00
|
|
|
ElabTL.setElaboratedKeywordLoc(SourceLocation());
|
2011-03-02 08:47:37 +08:00
|
|
|
ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
|
|
|
|
}
|
|
|
|
|
|
|
|
return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result));
|
2009-09-09 01:47:29 +08:00
|
|
|
}
|
2009-09-04 09:14:41 +08:00
|
|
|
|
2011-03-02 08:47:37 +08:00
|
|
|
TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK,
|
2010-08-27 07:41:50 +08:00
|
|
|
TypeSpecifierType TagSpec,
|
2011-03-02 08:47:37 +08:00
|
|
|
SourceLocation TagLoc,
|
|
|
|
CXXScopeSpec &SS,
|
2012-02-06 22:41:24 +08:00
|
|
|
SourceLocation TemplateKWLoc,
|
|
|
|
TemplateTy TemplateD,
|
2011-03-02 08:47:37 +08:00
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
SourceLocation LAngleLoc,
|
|
|
|
ASTTemplateArgsPtr TemplateArgsIn,
|
|
|
|
SourceLocation RAngleLoc) {
|
|
|
|
TemplateName Template = TemplateD.getAsVal<TemplateName>();
|
|
|
|
|
|
|
|
// Translate the parser's template argument list in our AST format.
|
|
|
|
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
|
|
|
|
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
|
|
|
|
|
|
|
// Determine the tag kind
|
2010-05-12 05:36:43 +08:00
|
|
|
TagTypeKind TagKind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
|
2011-03-02 08:47:37 +08:00
|
|
|
ElaboratedTypeKeyword Keyword
|
|
|
|
= TypeWithKeyword::getKeywordForTagTypeKind(TagKind);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-03-02 08:47:37 +08:00
|
|
|
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
|
|
|
|
QualType T = Context.getDependentTemplateSpecializationType(Keyword,
|
|
|
|
DTN->getQualifier(),
|
|
|
|
DTN->getIdentifier(),
|
|
|
|
TemplateArgs);
|
|
|
|
|
|
|
|
// Build type-source information.
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
DependentTemplateSpecializationTypeLoc SpecTL
|
2012-02-06 22:41:24 +08:00
|
|
|
= TLB.push<DependentTemplateSpecializationTypeLoc>(T);
|
|
|
|
SpecTL.setElaboratedKeywordLoc(TagLoc);
|
|
|
|
SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
|
2012-02-07 06:45:07 +08:00
|
|
|
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setTemplateNameLoc(TemplateLoc);
|
2011-03-02 08:47:37 +08:00
|
|
|
SpecTL.setLAngleLoc(LAngleLoc);
|
|
|
|
SpecTL.setRAngleLoc(RAngleLoc);
|
|
|
|
for (unsigned I = 0, N = SpecTL.getNumArgs(); I != N; ++I)
|
|
|
|
SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
|
|
|
|
return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
|
|
|
|
}
|
2011-05-06 05:57:07 +08:00
|
|
|
|
|
|
|
if (TypeAliasTemplateDecl *TAT =
|
|
|
|
dyn_cast_or_null<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) {
|
|
|
|
// C++0x [dcl.type.elab]p2:
|
|
|
|
// If the identifier resolves to a typedef-name or the simple-template-id
|
|
|
|
// resolves to an alias template specialization, the
|
|
|
|
// elaborated-type-specifier is ill-formed.
|
|
|
|
Diag(TemplateLoc, diag::err_tag_reference_non_tag) << 4;
|
|
|
|
Diag(TAT->getLocation(), diag::note_declared_at);
|
|
|
|
}
|
2011-03-02 08:47:37 +08:00
|
|
|
|
|
|
|
QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
|
|
|
|
if (Result.isNull())
|
2011-08-26 07:22:24 +08:00
|
|
|
return TypeResult(true);
|
2011-03-02 08:47:37 +08:00
|
|
|
|
|
|
|
// Check the tag kind
|
|
|
|
if (const RecordType *RT = Result->getAs<RecordType>()) {
|
2009-09-09 01:47:29 +08:00
|
|
|
RecordDecl *D = RT->getDecl();
|
2011-03-02 08:47:37 +08:00
|
|
|
|
2009-09-09 01:47:29 +08:00
|
|
|
IdentifierInfo *Id = D->getIdentifier();
|
|
|
|
assert(Id && "templated class must have an identifier");
|
2011-03-02 08:47:37 +08:00
|
|
|
|
2011-06-10 11:11:26 +08:00
|
|
|
if (!isAcceptableTagRedeclaration(D, TagKind, TUK == TUK_Definition,
|
|
|
|
TagLoc, *Id)) {
|
2009-09-09 01:47:29 +08:00
|
|
|
Diag(TagLoc, diag::err_use_with_wrong_tag)
|
2011-03-02 08:47:37 +08:00
|
|
|
<< Result
|
2010-04-01 01:46:05 +08:00
|
|
|
<< FixItHint::CreateReplacement(SourceRange(TagLoc), D->getKindName());
|
2009-09-11 12:59:25 +08:00
|
|
|
Diag(D->getLocation(), diag::note_previous_use);
|
2009-09-04 09:14:41 +08:00
|
|
|
}
|
|
|
|
}
|
2012-02-06 22:41:24 +08:00
|
|
|
|
2011-03-02 08:47:37 +08:00
|
|
|
// Provide source-location information for the template specialization.
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
TemplateSpecializationTypeLoc SpecTL
|
|
|
|
= TLB.push<TemplateSpecializationTypeLoc>(Result);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
|
2011-03-02 08:47:37 +08:00
|
|
|
SpecTL.setTemplateNameLoc(TemplateLoc);
|
|
|
|
SpecTL.setLAngleLoc(LAngleLoc);
|
|
|
|
SpecTL.setRAngleLoc(RAngleLoc);
|
|
|
|
for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i)
|
|
|
|
SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
|
|
|
|
|
|
|
|
// Construct an elaborated type containing the nested-name-specifier (if any)
|
2012-02-06 22:41:24 +08:00
|
|
|
// and tag keyword.
|
2011-03-02 08:47:37 +08:00
|
|
|
Result = Context.getElaboratedType(Keyword, SS.getScopeRep(), Result);
|
|
|
|
ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result);
|
2012-02-07 03:09:27 +08:00
|
|
|
ElabTL.setElaboratedKeywordLoc(TagLoc);
|
2011-03-02 08:47:37 +08:00
|
|
|
ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
|
|
|
|
return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result));
|
2009-02-10 02:46:07 +08:00
|
|
|
}
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
|
2012-01-27 17:46:47 +08:00
|
|
|
SourceLocation TemplateKWLoc,
|
2011-03-01 04:01:57 +08:00
|
|
|
LookupResult &R,
|
|
|
|
bool RequiresADL,
|
2012-02-06 22:31:00 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgs) {
|
2009-07-01 06:34:41 +08:00
|
|
|
// FIXME: Can we do any checking at this point? I guess we could check the
|
|
|
|
// template arguments that we have against the template name, if the template
|
2009-09-09 23:08:12 +08:00
|
|
|
// name refers to a single template. That's not a terribly common case,
|
2009-07-01 06:34:41 +08:00
|
|
|
// though.
|
2011-02-20 05:32:49 +08:00
|
|
|
// foo<int> could identify a single function unambiguously
|
|
|
|
// This approach does NOT work, since f<int>(1);
|
|
|
|
// gets resolved prior to resorting to overload resolution
|
|
|
|
// i.e., template<class T> void f(double);
|
|
|
|
// vs template<class T, class U> void f(U);
|
2009-11-25 03:00:30 +08:00
|
|
|
|
|
|
|
// These should be filtered out by our callers.
|
|
|
|
assert(!R.empty() && "empty lookup results when building templateid");
|
|
|
|
assert(!R.isAmbiguous() && "ambiguous lookup when building templateid");
|
|
|
|
|
2010-01-27 09:50:18 +08:00
|
|
|
// We don't want lookup warnings at this point.
|
|
|
|
R.suppressDiagnostics();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
UnresolvedLookupExpr *ULE
|
2010-12-15 09:34:56 +08:00
|
|
|
= UnresolvedLookupExpr::Create(Context, R.getNamingClass(),
|
2011-03-01 04:01:57 +08:00
|
|
|
SS.getWithLocInContext(Context),
|
2012-01-27 17:46:47 +08:00
|
|
|
TemplateKWLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
R.getLookupNameInfo(),
|
2011-01-27 15:10:08 +08:00
|
|
|
RequiresADL, TemplateArgs,
|
2010-05-24 02:57:34 +08:00
|
|
|
R.begin(), R.end());
|
2009-11-25 03:00:30 +08:00
|
|
|
|
|
|
|
return Owned(ULE);
|
2009-07-01 06:34:41 +08:00
|
|
|
}
|
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
// We actually only call this from template instantiation.
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult
|
2010-04-09 00:38:48 +08:00
|
|
|
Sema::BuildQualifiedTemplateIdExpr(CXXScopeSpec &SS,
|
2012-01-27 17:46:47 +08:00
|
|
|
SourceLocation TemplateKWLoc,
|
2010-08-12 06:01:17 +08:00
|
|
|
const DeclarationNameInfo &NameInfo,
|
2012-02-06 22:31:00 +08:00
|
|
|
const TemplateArgumentListInfo *TemplateArgs) {
|
|
|
|
assert(TemplateArgs || TemplateKWLoc.isValid());
|
2009-11-25 03:00:30 +08:00
|
|
|
DeclContext *DC;
|
|
|
|
if (!(DC = computeDeclContext(SS, false)) ||
|
|
|
|
DC->isDependentContext() ||
|
2010-05-01 08:40:08 +08:00
|
|
|
RequireCompleteDeclContext(SS, DC))
|
2012-02-06 22:31:00 +08:00
|
|
|
return BuildDependentDeclRefExpr(SS, TemplateKWLoc, NameInfo, TemplateArgs);
|
2009-11-25 03:00:30 +08:00
|
|
|
|
2010-05-22 07:18:07 +08:00
|
|
|
bool MemberOfUnknownSpecialization;
|
2010-08-12 06:01:17 +08:00
|
|
|
LookupResult R(*this, NameInfo, LookupOrdinaryName);
|
2010-05-22 07:18:07 +08:00
|
|
|
LookupTemplateName(R, (Scope*) 0, SS, QualType(), /*Entering*/ false,
|
|
|
|
MemberOfUnknownSpecialization);
|
2009-11-25 03:00:30 +08:00
|
|
|
|
|
|
|
if (R.isAmbiguous())
|
|
|
|
return ExprError();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
if (R.empty()) {
|
2010-08-12 06:01:17 +08:00
|
|
|
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_non_template)
|
|
|
|
<< NameInfo.getName() << SS.getRange();
|
2009-11-25 03:00:30 +08:00
|
|
|
return ExprError();
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-11-25 03:00:30 +08:00
|
|
|
if (ClassTemplateDecl *Temp = R.getAsSingle<ClassTemplateDecl>()) {
|
2010-08-12 06:01:17 +08:00
|
|
|
Diag(NameInfo.getLoc(), diag::err_template_kw_refers_to_class_template)
|
|
|
|
<< (NestedNameSpecifier*) SS.getScopeRep()
|
|
|
|
<< NameInfo.getName() << SS.getRange();
|
2009-11-25 03:00:30 +08:00
|
|
|
Diag(Temp->getLocation(), diag::note_referenced_class_template);
|
|
|
|
return ExprError();
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-01-27 17:46:47 +08:00
|
|
|
return BuildTemplateIdExpr(SS, TemplateKWLoc, R, /*ADL*/ false, TemplateArgs);
|
2009-07-01 06:34:41 +08:00
|
|
|
}
|
|
|
|
|
2009-03-31 08:43:58 +08:00
|
|
|
/// \brief Form a dependent template name.
|
|
|
|
///
|
|
|
|
/// This action forms a dependent template name given the template
|
|
|
|
/// name and its (presumably dependent) scope specifier. For
|
|
|
|
/// example, given "MetaFun::template apply", the scope specifier \p
|
|
|
|
/// SS will be "MetaFun::", \p TemplateKWLoc contains the location
|
|
|
|
/// of the "template" keyword, and "apply" is the \p Name.
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateNameKind Sema::ActOnDependentTemplateName(Scope *S,
|
2010-06-17 07:00:59 +08:00
|
|
|
CXXScopeSpec &SS,
|
2012-01-27 17:46:47 +08:00
|
|
|
SourceLocation TemplateKWLoc,
|
2010-06-17 07:00:59 +08:00
|
|
|
UnqualifiedId &Name,
|
2010-08-24 13:47:05 +08:00
|
|
|
ParsedType ObjectType,
|
2010-06-17 07:00:59 +08:00
|
|
|
bool EnteringContext,
|
|
|
|
TemplateTy &Result) {
|
2011-10-19 04:49:44 +08:00
|
|
|
if (TemplateKWLoc.isValid() && S && !S->getTemplateParamParent())
|
|
|
|
Diag(TemplateKWLoc,
|
2012-03-11 15:00:24 +08:00
|
|
|
getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_template_outside_of_template :
|
|
|
|
diag::ext_template_outside_of_template)
|
2011-01-27 15:10:08 +08:00
|
|
|
<< FixItHint::CreateRemoval(TemplateKWLoc);
|
|
|
|
|
2010-01-20 00:01:07 +08:00
|
|
|
DeclContext *LookupCtx = 0;
|
|
|
|
if (SS.isSet())
|
|
|
|
LookupCtx = computeDeclContext(SS, EnteringContext);
|
|
|
|
if (!LookupCtx && ObjectType)
|
2010-08-24 13:47:05 +08:00
|
|
|
LookupCtx = computeDeclContext(ObjectType.get());
|
2010-01-20 00:01:07 +08:00
|
|
|
if (LookupCtx) {
|
2009-03-31 08:43:58 +08:00
|
|
|
// C++0x [temp.names]p5:
|
|
|
|
// If a name prefixed by the keyword template is not the name of
|
|
|
|
// a template, the program is ill-formed. [Note: the keyword
|
|
|
|
// template may not be applied to non-template members of class
|
|
|
|
// templates. -end note ] [ Note: as is the case with the
|
|
|
|
// typename prefix, the template prefix is allowed in cases
|
|
|
|
// where it is not strictly necessary; i.e., when the
|
|
|
|
// nested-name-specifier or the expression on the left of the ->
|
|
|
|
// or . is not dependent on a template-parameter, or the use
|
|
|
|
// does not appear in the scope of a template. -end note]
|
|
|
|
//
|
|
|
|
// Note: C++03 was more strict here, because it banned the use of
|
|
|
|
// the "template" keyword prior to a template-name that was not a
|
|
|
|
// dependent name. C++ DR468 relaxed this requirement (the
|
|
|
|
// "template" keyword is now permitted). We follow the C++0x
|
2010-06-15 06:07:54 +08:00
|
|
|
// rules, even in C++03 mode with a warning, retroactively applying the DR.
|
2010-05-22 07:18:07 +08:00
|
|
|
bool MemberOfUnknownSpecialization;
|
2010-08-06 20:11:11 +08:00
|
|
|
TemplateNameKind TNK = isTemplateName(0, SS, TemplateKWLoc.isValid(), Name,
|
|
|
|
ObjectType, EnteringContext, Result,
|
2010-05-22 07:18:07 +08:00
|
|
|
MemberOfUnknownSpecialization);
|
2010-01-20 00:01:07 +08:00
|
|
|
if (TNK == TNK_Non_template && LookupCtx->isDependentContext() &&
|
|
|
|
isa<CXXRecordDecl>(LookupCtx) &&
|
2011-03-12 07:27:41 +08:00
|
|
|
(!cast<CXXRecordDecl>(LookupCtx)->hasDefinition() ||
|
|
|
|
cast<CXXRecordDecl>(LookupCtx)->hasAnyDependentBases())) {
|
2010-06-17 07:00:59 +08:00
|
|
|
// This is a dependent template. Handle it below.
|
2010-01-15 01:47:39 +08:00
|
|
|
} else if (TNK == TNK_Non_template) {
|
2012-03-10 02:35:03 +08:00
|
|
|
Diag(Name.getLocStart(),
|
2009-11-04 07:16:33 +08:00
|
|
|
diag::err_template_kw_refers_to_non_template)
|
2010-08-12 06:01:17 +08:00
|
|
|
<< GetNameFromUnqualifiedId(Name).getName()
|
2010-05-05 13:58:24 +08:00
|
|
|
<< Name.getSourceRange()
|
|
|
|
<< TemplateKWLoc;
|
2010-06-17 07:00:59 +08:00
|
|
|
return TNK_Non_template;
|
2010-01-15 01:47:39 +08:00
|
|
|
} else {
|
|
|
|
// We found something; return it.
|
2010-06-17 07:00:59 +08:00
|
|
|
return TNK;
|
2009-03-31 08:43:58 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
NestedNameSpecifier *Qualifier
|
2009-09-03 06:59:36 +08:00
|
|
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-04 07:16:33 +08:00
|
|
|
switch (Name.getKind()) {
|
|
|
|
case UnqualifiedId::IK_Identifier:
|
2011-01-27 15:10:08 +08:00
|
|
|
Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
|
2010-06-17 07:00:59 +08:00
|
|
|
Name.Identifier));
|
|
|
|
return TNK_Dependent_template_name;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-04 08:56:37 +08:00
|
|
|
case UnqualifiedId::IK_OperatorFunctionId:
|
2010-06-17 07:00:59 +08:00
|
|
|
Result = TemplateTy::make(Context.getDependentTemplateName(Qualifier,
|
2009-11-04 08:56:37 +08:00
|
|
|
Name.OperatorFunctionId.Operator));
|
2010-06-17 07:00:59 +08:00
|
|
|
return TNK_Dependent_template_name;
|
2009-11-28 16:58:14 +08:00
|
|
|
|
|
|
|
case UnqualifiedId::IK_LiteralOperatorId:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable(
|
|
|
|
"We don't support these; Parse shouldn't have allowed propagation");
|
2009-11-28 16:58:14 +08:00
|
|
|
|
2009-11-04 07:16:33 +08:00
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2012-03-10 02:35:03 +08:00
|
|
|
Diag(Name.getLocStart(),
|
2009-11-04 07:16:33 +08:00
|
|
|
diag::err_template_kw_refers_to_non_template)
|
2010-08-12 06:01:17 +08:00
|
|
|
<< GetNameFromUnqualifiedId(Name).getName()
|
2010-05-05 13:58:24 +08:00
|
|
|
<< Name.getSourceRange()
|
|
|
|
<< TemplateKWLoc;
|
2010-06-17 07:00:59 +08:00
|
|
|
return TNK_Non_template;
|
2009-03-31 08:43:58 +08:00
|
|
|
}
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
bool Sema::CheckTemplateTypeArgument(TemplateTypeParmDecl *Param,
|
2009-10-29 16:12:44 +08:00
|
|
|
const TemplateArgumentLoc &AL,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &Converted) {
|
2009-10-29 16:12:44 +08:00
|
|
|
const TemplateArgument &Arg = AL.getArgument();
|
|
|
|
|
2009-06-13 08:33:33 +08:00
|
|
|
// Check template type parameter.
|
2010-04-08 08:03:06 +08:00
|
|
|
switch(Arg.getKind()) {
|
|
|
|
case TemplateArgument::Type:
|
2009-06-13 08:33:33 +08:00
|
|
|
// C++ [temp.arg.type]p1:
|
|
|
|
// A template-argument for a template-parameter which is a
|
|
|
|
// type shall be a type-id.
|
2010-04-08 08:03:06 +08:00
|
|
|
break;
|
|
|
|
case TemplateArgument::Template: {
|
|
|
|
// We have a template type parameter but the template argument
|
|
|
|
// is a template without any arguments.
|
|
|
|
SourceRange SR = AL.getSourceRange();
|
|
|
|
TemplateName Name = Arg.getAsTemplate();
|
|
|
|
Diag(SR.getBegin(), diag::err_template_missing_args)
|
|
|
|
<< Name << SR;
|
|
|
|
if (TemplateDecl *Decl = Name.getAsTemplateDecl())
|
|
|
|
Diag(Decl->getLocation(), diag::note_template_decl_here);
|
2009-06-13 08:33:33 +08:00
|
|
|
|
2010-04-08 08:03:06 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
default: {
|
2009-06-13 08:33:33 +08:00
|
|
|
// We have a template type parameter but the template argument
|
|
|
|
// is not a type.
|
2009-10-30 02:45:58 +08:00
|
|
|
SourceRange SR = AL.getSourceRange();
|
|
|
|
Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR;
|
2009-06-13 08:33:33 +08:00
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-13 08:33:33 +08:00
|
|
|
return true;
|
2009-09-09 23:08:12 +08:00
|
|
|
}
|
2010-04-08 08:03:06 +08:00
|
|
|
}
|
2009-06-13 08:33:33 +08:00
|
|
|
|
2009-12-07 10:54:59 +08:00
|
|
|
if (CheckTemplateArgument(Param, AL.getTypeSourceInfo()))
|
2009-06-13 08:33:33 +08:00
|
|
|
return true;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-13 08:33:33 +08:00
|
|
|
// Add the converted template type argument.
|
2011-06-18 06:11:49 +08:00
|
|
|
QualType ArgType = Context.getCanonicalType(Arg.getAsType());
|
|
|
|
|
|
|
|
// Objective-C ARC:
|
|
|
|
// If an explicitly-specified template argument type is a lifetime type
|
|
|
|
// with no lifetime qualifier, the __strong lifetime qualifier is inferred.
|
2012-03-11 15:00:24 +08:00
|
|
|
if (getLangOpts().ObjCAutoRefCount &&
|
2011-06-18 06:11:49 +08:00
|
|
|
ArgType->isObjCLifetimeType() &&
|
|
|
|
!ArgType.getObjCLifetime()) {
|
|
|
|
Qualifiers Qs;
|
|
|
|
Qs.setObjCLifetime(Qualifiers::OCL_Strong);
|
|
|
|
ArgType = Context.getQualifiedType(ArgType, Qs);
|
|
|
|
}
|
|
|
|
|
|
|
|
Converted.push_back(TemplateArgument(ArgType));
|
2009-06-13 08:33:33 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-11-10 03:17:50 +08:00
|
|
|
/// \brief Substitute template arguments into the default template argument for
|
|
|
|
/// the given template type parameter.
|
|
|
|
///
|
|
|
|
/// \param SemaRef the semantic analysis object for which we are performing
|
|
|
|
/// the substitution.
|
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \param Template the template that we are synthesizing template arguments
|
2009-11-10 03:17:50 +08:00
|
|
|
/// for.
|
|
|
|
///
|
|
|
|
/// \param TemplateLoc the location of the template name that started the
|
|
|
|
/// template-id we are checking.
|
|
|
|
///
|
|
|
|
/// \param RAngleLoc the location of the right angle bracket ('>') that
|
|
|
|
/// terminates the template-id.
|
|
|
|
///
|
|
|
|
/// \param Param the template template parameter whose default we are
|
|
|
|
/// substituting into.
|
|
|
|
///
|
|
|
|
/// \param Converted the list of template arguments provided for template
|
|
|
|
/// parameters that precede \p Param in the template parameter list.
|
|
|
|
/// \returns the substituted template argument, or NULL if an error occurred.
|
2009-12-07 10:54:59 +08:00
|
|
|
static TypeSourceInfo *
|
2009-11-10 03:17:50 +08:00
|
|
|
SubstDefaultTemplateArgument(Sema &SemaRef,
|
|
|
|
TemplateDecl *Template,
|
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
SourceLocation RAngleLoc,
|
|
|
|
TemplateTypeParmDecl *Param,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &Converted) {
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *ArgType = Param->getDefaultArgumentInfo();
|
2009-11-10 03:17:50 +08:00
|
|
|
|
|
|
|
// If the argument type is dependent, instantiate it now based
|
|
|
|
// on the previously-computed template arguments.
|
|
|
|
if (ArgType->getType()->isDependentType()) {
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(), Converted.size());
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-10 03:17:50 +08:00
|
|
|
MultiLevelTemplateArgumentList AllTemplateArgs
|
|
|
|
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
|
|
|
|
|
|
|
|
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
|
2010-11-08 07:05:16 +08:00
|
|
|
Template, Converted.data(),
|
|
|
|
Converted.size(),
|
2009-11-10 03:17:50 +08:00
|
|
|
SourceRange(TemplateLoc, RAngleLoc));
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-10 03:17:50 +08:00
|
|
|
ArgType = SemaRef.SubstType(ArgType, AllTemplateArgs,
|
|
|
|
Param->getDefaultArgumentLoc(),
|
|
|
|
Param->getDeclName());
|
|
|
|
}
|
|
|
|
|
|
|
|
return ArgType;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Substitute template arguments into the default template argument for
|
|
|
|
/// the given non-type template parameter.
|
|
|
|
///
|
|
|
|
/// \param SemaRef the semantic analysis object for which we are performing
|
|
|
|
/// the substitution.
|
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \param Template the template that we are synthesizing template arguments
|
2009-11-10 03:17:50 +08:00
|
|
|
/// for.
|
|
|
|
///
|
|
|
|
/// \param TemplateLoc the location of the template name that started the
|
|
|
|
/// template-id we are checking.
|
|
|
|
///
|
|
|
|
/// \param RAngleLoc the location of the right angle bracket ('>') that
|
|
|
|
/// terminates the template-id.
|
|
|
|
///
|
2009-11-11 09:00:40 +08:00
|
|
|
/// \param Param the non-type template parameter whose default we are
|
2009-11-10 03:17:50 +08:00
|
|
|
/// substituting into.
|
|
|
|
///
|
|
|
|
/// \param Converted the list of template arguments provided for template
|
|
|
|
/// parameters that precede \p Param in the template parameter list.
|
|
|
|
///
|
|
|
|
/// \returns the substituted template argument, or NULL if an error occurred.
|
2010-08-24 14:29:42 +08:00
|
|
|
static ExprResult
|
2009-11-10 03:17:50 +08:00
|
|
|
SubstDefaultTemplateArgument(Sema &SemaRef,
|
|
|
|
TemplateDecl *Template,
|
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
SourceLocation RAngleLoc,
|
|
|
|
NonTypeTemplateParmDecl *Param,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &Converted) {
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(), Converted.size());
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-10 03:17:50 +08:00
|
|
|
MultiLevelTemplateArgumentList AllTemplateArgs
|
|
|
|
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-10 03:17:50 +08:00
|
|
|
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
|
2010-11-08 07:05:16 +08:00
|
|
|
Template, Converted.data(),
|
|
|
|
Converted.size(),
|
2009-11-10 03:17:50 +08:00
|
|
|
SourceRange(TemplateLoc, RAngleLoc));
|
|
|
|
|
|
|
|
return SemaRef.SubstExpr(Param->getDefaultArgument(), AllTemplateArgs);
|
|
|
|
}
|
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
/// \brief Substitute template arguments into the default template argument for
|
|
|
|
/// the given template template parameter.
|
|
|
|
///
|
|
|
|
/// \param SemaRef the semantic analysis object for which we are performing
|
|
|
|
/// the substitution.
|
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \param Template the template that we are synthesizing template arguments
|
2009-11-11 09:00:40 +08:00
|
|
|
/// for.
|
|
|
|
///
|
|
|
|
/// \param TemplateLoc the location of the template name that started the
|
|
|
|
/// template-id we are checking.
|
|
|
|
///
|
|
|
|
/// \param RAngleLoc the location of the right angle bracket ('>') that
|
|
|
|
/// terminates the template-id.
|
|
|
|
///
|
|
|
|
/// \param Param the template template parameter whose default we are
|
|
|
|
/// substituting into.
|
|
|
|
///
|
|
|
|
/// \param Converted the list of template arguments provided for template
|
|
|
|
/// parameters that precede \p Param in the template parameter list.
|
|
|
|
///
|
2011-03-03 02:46:51 +08:00
|
|
|
/// \param QualifierLoc Will be set to the nested-name-specifier (with
|
|
|
|
/// source-location information) that precedes the template name.
|
2011-03-03 01:09:35 +08:00
|
|
|
///
|
2009-11-11 09:00:40 +08:00
|
|
|
/// \returns the substituted template argument, or NULL if an error occurred.
|
|
|
|
static TemplateName
|
|
|
|
SubstDefaultTemplateArgument(Sema &SemaRef,
|
|
|
|
TemplateDecl *Template,
|
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
SourceLocation RAngleLoc,
|
|
|
|
TemplateTemplateParmDecl *Param,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &Converted,
|
2011-03-03 01:09:35 +08:00
|
|
|
NestedNameSpecifierLoc &QualifierLoc) {
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(), Converted.size());
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
MultiLevelTemplateArgumentList AllTemplateArgs
|
|
|
|
= SemaRef.getTemplateInstantiationArgs(Template, &TemplateArgs);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-11 09:00:40 +08:00
|
|
|
Sema::InstantiatingTemplate Inst(SemaRef, TemplateLoc,
|
2010-11-08 07:05:16 +08:00
|
|
|
Template, Converted.data(),
|
|
|
|
Converted.size(),
|
2009-11-11 09:00:40 +08:00
|
|
|
SourceRange(TemplateLoc, RAngleLoc));
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-03-03 01:09:35 +08:00
|
|
|
// Substitute into the nested-name-specifier first,
|
2011-03-03 02:46:51 +08:00
|
|
|
QualifierLoc = Param->getDefaultArgument().getTemplateQualifierLoc();
|
2011-03-03 01:09:35 +08:00
|
|
|
if (QualifierLoc) {
|
|
|
|
QualifierLoc = SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc,
|
|
|
|
AllTemplateArgs);
|
|
|
|
if (!QualifierLoc)
|
|
|
|
return TemplateName();
|
|
|
|
}
|
|
|
|
|
2011-03-03 02:46:51 +08:00
|
|
|
return SemaRef.SubstTemplateName(QualifierLoc,
|
2009-11-11 09:00:40 +08:00
|
|
|
Param->getDefaultArgument().getArgument().getAsTemplate(),
|
2011-01-27 15:10:08 +08:00
|
|
|
Param->getDefaultArgument().getTemplateNameLoc(),
|
2009-11-11 09:00:40 +08:00
|
|
|
AllTemplateArgs);
|
|
|
|
}
|
|
|
|
|
2009-11-26 02:55:14 +08:00
|
|
|
/// \brief If the given template parameter has a default template
|
|
|
|
/// argument, substitute into that default template argument and
|
|
|
|
/// return the corresponding template argument.
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateArgumentLoc
|
2009-11-26 02:55:14 +08:00
|
|
|
Sema::SubstDefaultTemplateArgumentIfAvailable(TemplateDecl *Template,
|
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
SourceLocation RAngleLoc,
|
|
|
|
Decl *Param,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &Converted) {
|
2010-11-08 07:05:16 +08:00
|
|
|
if (TemplateTypeParmDecl *TypeParm = dyn_cast<TemplateTypeParmDecl>(Param)) {
|
2009-11-26 02:55:14 +08:00
|
|
|
if (!TypeParm->hasDefaultArgument())
|
|
|
|
return TemplateArgumentLoc();
|
|
|
|
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *DI = SubstDefaultTemplateArgument(*this, Template,
|
2009-11-26 02:55:14 +08:00
|
|
|
TemplateLoc,
|
|
|
|
RAngleLoc,
|
|
|
|
TypeParm,
|
|
|
|
Converted);
|
|
|
|
if (DI)
|
|
|
|
return TemplateArgumentLoc(TemplateArgument(DI->getType()), DI);
|
|
|
|
|
|
|
|
return TemplateArgumentLoc();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NonTypeTemplateParmDecl *NonTypeParm
|
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
|
|
|
if (!NonTypeParm->hasDefaultArgument())
|
|
|
|
return TemplateArgumentLoc();
|
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult Arg = SubstDefaultTemplateArgument(*this, Template,
|
2011-03-03 01:09:35 +08:00
|
|
|
TemplateLoc,
|
|
|
|
RAngleLoc,
|
|
|
|
NonTypeParm,
|
|
|
|
Converted);
|
2009-11-26 02:55:14 +08:00
|
|
|
if (Arg.isInvalid())
|
|
|
|
return TemplateArgumentLoc();
|
|
|
|
|
|
|
|
Expr *ArgE = Arg.takeAs<Expr>();
|
|
|
|
return TemplateArgumentLoc(TemplateArgument(ArgE), ArgE);
|
|
|
|
}
|
|
|
|
|
|
|
|
TemplateTemplateParmDecl *TempTempParm
|
|
|
|
= cast<TemplateTemplateParmDecl>(Param);
|
|
|
|
if (!TempTempParm->hasDefaultArgument())
|
|
|
|
return TemplateArgumentLoc();
|
|
|
|
|
2011-03-03 01:09:35 +08:00
|
|
|
|
2011-03-03 02:46:51 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc;
|
2009-11-26 02:55:14 +08:00
|
|
|
TemplateName TName = SubstDefaultTemplateArgument(*this, Template,
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateLoc,
|
2009-11-26 02:55:14 +08:00
|
|
|
RAngleLoc,
|
|
|
|
TempTempParm,
|
2011-03-03 01:09:35 +08:00
|
|
|
Converted,
|
|
|
|
QualifierLoc);
|
2009-11-26 02:55:14 +08:00
|
|
|
if (TName.isNull())
|
|
|
|
return TemplateArgumentLoc();
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
return TemplateArgumentLoc(TemplateArgument(TName),
|
2011-03-03 01:09:35 +08:00
|
|
|
TempTempParm->getDefaultArgument().getTemplateQualifierLoc(),
|
2009-11-26 02:55:14 +08:00
|
|
|
TempTempParm->getDefaultArgument().getTemplateNameLoc());
|
|
|
|
}
|
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
/// \brief Check that the given template argument corresponds to the given
|
|
|
|
/// template parameter.
|
2011-01-20 04:10:05 +08:00
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \param Param The template parameter against which the argument will be
|
2011-01-20 04:10:05 +08:00
|
|
|
/// checked.
|
|
|
|
///
|
|
|
|
/// \param Arg The template argument.
|
|
|
|
///
|
|
|
|
/// \param Template The template in which the template argument resides.
|
|
|
|
///
|
|
|
|
/// \param TemplateLoc The location of the template name for the template
|
|
|
|
/// whose argument list we're matching.
|
|
|
|
///
|
|
|
|
/// \param RAngleLoc The location of the right angle bracket ('>') that closes
|
|
|
|
/// the template argument list.
|
|
|
|
///
|
|
|
|
/// \param ArgumentPackIndex The index into the argument pack where this
|
|
|
|
/// argument will be placed. Only valid if the parameter is a parameter pack.
|
|
|
|
///
|
|
|
|
/// \param Converted The checked, converted argument will be added to the
|
|
|
|
/// end of this small vector.
|
|
|
|
///
|
|
|
|
/// \param CTAK Describes how we arrived at this particular template argument:
|
|
|
|
/// explicitly written, deduced, etc.
|
|
|
|
///
|
|
|
|
/// \returns true on error, false otherwise.
|
2009-11-12 03:31:23 +08:00
|
|
|
bool Sema::CheckTemplateArgument(NamedDecl *Param,
|
|
|
|
const TemplateArgumentLoc &Arg,
|
2011-01-05 07:35:54 +08:00
|
|
|
NamedDecl *Template,
|
2009-11-12 03:31:23 +08:00
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
SourceLocation RAngleLoc,
|
2011-01-20 04:10:05 +08:00
|
|
|
unsigned ArgumentPackIndex,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &Converted,
|
2010-03-28 10:42:43 +08:00
|
|
|
CheckTemplateArgumentKind CTAK) {
|
2009-11-12 03:41:09 +08:00
|
|
|
// Check template type parameters.
|
|
|
|
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
|
2009-11-12 03:31:23 +08:00
|
|
|
return CheckTemplateTypeArgument(TTP, Arg, Converted);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:41:09 +08:00
|
|
|
// Check non-type template parameters.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (NonTypeTemplateParmDecl *NTTP =dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
2009-11-12 03:31:23 +08:00
|
|
|
// Do substitution on the type of the non-type template parameter
|
2010-12-11 01:08:53 +08:00
|
|
|
// with the template arguments we've seen thus far. But if the
|
|
|
|
// template has a dependent context then we cannot substitute yet.
|
2009-11-12 03:31:23 +08:00
|
|
|
QualType NTTPType = NTTP->getType();
|
2011-01-20 04:10:05 +08:00
|
|
|
if (NTTP->isParameterPack() && NTTP->isExpandedParameterPack())
|
|
|
|
NTTPType = NTTP->getExpansionType(ArgumentPackIndex);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-11 01:08:53 +08:00
|
|
|
if (NTTPType->isDependentType() &&
|
|
|
|
!isa<TemplateTemplateParmDecl>(Template) &&
|
|
|
|
!Template->getDeclContext()->isDependentContext()) {
|
2009-11-12 03:31:23 +08:00
|
|
|
// Do substitution on the type of the non-type template parameter.
|
|
|
|
InstantiatingTemplate Inst(*this, TemplateLoc, Template,
|
2010-11-08 07:05:16 +08:00
|
|
|
NTTP, Converted.data(), Converted.size(),
|
2009-11-12 03:31:23 +08:00
|
|
|
SourceRange(TemplateLoc, RAngleLoc));
|
2011-01-27 15:10:08 +08:00
|
|
|
|
|
|
|
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(), Converted.size());
|
2009-11-12 03:31:23 +08:00
|
|
|
NTTPType = SubstType(NTTPType,
|
|
|
|
MultiLevelTemplateArgumentList(TemplateArgs),
|
|
|
|
NTTP->getLocation(),
|
|
|
|
NTTP->getDeclName());
|
|
|
|
// If that worked, check the non-type template parameter type
|
|
|
|
// for validity.
|
|
|
|
if (!NTTPType.isNull())
|
|
|
|
NTTPType = CheckNonTypeTemplateParameterType(NTTPType,
|
|
|
|
NTTP->getLocation());
|
|
|
|
if (NTTPType.isNull())
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
switch (Arg.getArgument().getKind()) {
|
|
|
|
case TemplateArgument::Null:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Should never see a NULL template argument here");
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Expression: {
|
|
|
|
TemplateArgument Result;
|
2011-04-09 02:41:53 +08:00
|
|
|
ExprResult Res =
|
|
|
|
CheckTemplateArgument(NTTP, NTTPType, Arg.getArgument().getAsExpr(),
|
|
|
|
Result, CTAK);
|
|
|
|
if (Res.isInvalid())
|
2009-11-12 03:31:23 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.push_back(Result);
|
2009-11-12 03:31:23 +08:00
|
|
|
break;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Declaration:
|
|
|
|
case TemplateArgument::Integral:
|
|
|
|
// We've already checked this template argument, so just copy
|
|
|
|
// it to the list of converted arguments.
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.push_back(Arg.getArgument());
|
2009-11-12 03:31:23 +08:00
|
|
|
break;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Template:
|
2011-01-06 02:58:31 +08:00
|
|
|
case TemplateArgument::TemplateExpansion:
|
2009-11-12 03:31:23 +08:00
|
|
|
// We were given a template template argument. It may not be ill-formed;
|
|
|
|
// see below.
|
|
|
|
if (DependentTemplateName *DTN
|
2011-01-06 02:58:31 +08:00
|
|
|
= Arg.getArgument().getAsTemplateOrTemplatePattern()
|
|
|
|
.getAsDependentTemplateName()) {
|
2009-11-12 03:31:23 +08:00
|
|
|
// We have a template argument such as \c T::template X, which we
|
|
|
|
// parsed as a template template argument. However, since we now
|
|
|
|
// know that we need a non-type template argument, convert this
|
2010-08-12 06:01:17 +08:00
|
|
|
// template name into an expression.
|
|
|
|
|
|
|
|
DeclarationNameInfo NameInfo(DTN->getIdentifier(),
|
|
|
|
Arg.getTemplateNameLoc());
|
|
|
|
|
2011-02-26 04:49:16 +08:00
|
|
|
CXXScopeSpec SS;
|
2011-03-03 01:09:35 +08:00
|
|
|
SS.Adopt(Arg.getTemplateQualifierLoc());
|
2012-01-27 17:46:47 +08:00
|
|
|
// FIXME: the template-template arg was a DependentTemplateName,
|
|
|
|
// so it was provided with a template keyword. However, its source
|
|
|
|
// location is not stored in the template argument structure.
|
|
|
|
SourceLocation TemplateKWLoc;
|
2011-04-09 02:41:53 +08:00
|
|
|
ExprResult E = Owned(DependentScopeDeclRefExpr::Create(Context,
|
2011-02-26 04:49:16 +08:00
|
|
|
SS.getWithLocInContext(Context),
|
2012-01-27 17:46:47 +08:00
|
|
|
TemplateKWLoc,
|
|
|
|
NameInfo, 0));
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-06 02:58:31 +08:00
|
|
|
// If we parsed the template argument as a pack expansion, create a
|
|
|
|
// pack expansion expression.
|
|
|
|
if (Arg.getArgument().getKind() == TemplateArgument::TemplateExpansion){
|
2011-04-09 02:41:53 +08:00
|
|
|
E = ActOnPackExpansion(E.take(), Arg.getTemplateEllipsisLoc());
|
|
|
|
if (E.isInvalid())
|
2011-01-06 02:58:31 +08:00
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
TemplateArgument Result;
|
2011-04-09 02:41:53 +08:00
|
|
|
E = CheckTemplateArgument(NTTP, NTTPType, E.take(), Result);
|
|
|
|
if (E.isInvalid())
|
2009-11-12 03:31:23 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.push_back(Result);
|
2009-11-12 03:31:23 +08:00
|
|
|
break;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
// We have a template argument that actually does refer to a class
|
2011-05-06 05:57:07 +08:00
|
|
|
// template, alias template, or template template parameter, and
|
2009-11-12 03:31:23 +08:00
|
|
|
// therefore cannot be a non-type template argument.
|
|
|
|
Diag(Arg.getLocation(), diag::err_template_arg_must_be_expr)
|
|
|
|
<< Arg.getSourceRange();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Type: {
|
|
|
|
// We have a non-type template parameter but the template
|
|
|
|
// argument is a type.
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
// C++ [temp.arg]p2:
|
|
|
|
// In a template-argument, an ambiguity between a type-id and
|
|
|
|
// an expression is resolved to a type-id, regardless of the
|
|
|
|
// form of the corresponding template-parameter.
|
|
|
|
//
|
|
|
|
// We warn specifically about this case, since it can be rather
|
|
|
|
// confusing for users.
|
|
|
|
QualType T = Arg.getArgument().getAsType();
|
|
|
|
SourceRange SR = Arg.getSourceRange();
|
|
|
|
if (T->isFunctionType())
|
|
|
|
Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) << SR << T;
|
|
|
|
else
|
|
|
|
Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR;
|
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Pack:
|
2009-12-12 13:05:38 +08:00
|
|
|
llvm_unreachable("Caller must expand template argument packs");
|
2009-11-12 03:31:23 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
// Check template template parameters.
|
|
|
|
TemplateTemplateParmDecl *TempParm = cast<TemplateTemplateParmDecl>(Param);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
// Substitute into the template parameter list of the template
|
|
|
|
// template parameter, since previously-supplied template arguments
|
|
|
|
// may appear within the template template parameter.
|
|
|
|
{
|
|
|
|
// Set up a template instantiation context.
|
|
|
|
LocalInstantiationScope Scope(*this);
|
|
|
|
InstantiatingTemplate Inst(*this, TemplateLoc, Template,
|
2010-11-08 07:05:16 +08:00
|
|
|
TempParm, Converted.data(), Converted.size(),
|
2009-11-12 03:31:23 +08:00
|
|
|
SourceRange(TemplateLoc, RAngleLoc));
|
2011-01-27 15:10:08 +08:00
|
|
|
|
|
|
|
TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(), Converted.size());
|
2009-11-12 03:31:23 +08:00
|
|
|
TempParm = cast_or_null<TemplateTemplateParmDecl>(
|
2011-01-27 15:10:08 +08:00
|
|
|
SubstDecl(TempParm, CurContext,
|
2009-11-12 03:31:23 +08:00
|
|
|
MultiLevelTemplateArgumentList(TemplateArgs)));
|
|
|
|
if (!TempParm)
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
switch (Arg.getArgument().getKind()) {
|
|
|
|
case TemplateArgument::Null:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Should never see a NULL template argument here");
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Template:
|
2011-01-06 02:58:31 +08:00
|
|
|
case TemplateArgument::TemplateExpansion:
|
2009-11-12 03:31:23 +08:00
|
|
|
if (CheckTemplateArgument(TempParm, Arg))
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.push_back(Arg.getArgument());
|
2009-11-12 03:31:23 +08:00
|
|
|
break;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Expression:
|
|
|
|
case TemplateArgument::Type:
|
|
|
|
// We have a template template parameter but the template
|
|
|
|
// argument does not refer to a template.
|
2011-05-06 05:57:07 +08:00
|
|
|
Diag(Arg.getLocation(), diag::err_template_arg_must_be_template)
|
2012-03-11 15:00:24 +08:00
|
|
|
<< getLangOpts().CPlusPlus0x;
|
2009-11-12 03:31:23 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Declaration:
|
2012-01-17 14:56:22 +08:00
|
|
|
llvm_unreachable("Declaration argument with template template parameter");
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Integral:
|
2012-01-17 14:56:22 +08:00
|
|
|
llvm_unreachable("Integral argument with template template parameter");
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
case TemplateArgument::Pack:
|
2009-12-12 13:05:38 +08:00
|
|
|
llvm_unreachable("Caller must expand template argument packs");
|
2009-11-12 03:31:23 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 03:31:23 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-02-03 15:34:46 +08:00
|
|
|
/// \brief Diagnose an arity mismatch in the
|
|
|
|
static bool diagnoseArityMismatch(Sema &S, TemplateDecl *Template,
|
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
TemplateArgumentListInfo &TemplateArgs) {
|
|
|
|
TemplateParameterList *Params = Template->getTemplateParameters();
|
|
|
|
unsigned NumParams = Params->size();
|
|
|
|
unsigned NumArgs = TemplateArgs.size();
|
|
|
|
|
|
|
|
SourceRange Range;
|
|
|
|
if (NumArgs > NumParams)
|
|
|
|
Range = SourceRange(TemplateArgs[NumParams].getLocation(),
|
|
|
|
TemplateArgs.getRAngleLoc());
|
|
|
|
S.Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
|
|
|
|
<< (NumArgs > NumParams)
|
|
|
|
<< (isa<ClassTemplateDecl>(Template)? 0 :
|
|
|
|
isa<FunctionTemplateDecl>(Template)? 1 :
|
|
|
|
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
|
|
|
|
<< Template << Range;
|
|
|
|
S.Diag(Template->getLocation(), diag::note_template_decl_here)
|
|
|
|
<< Params->getSourceRange();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-02-10 07:23:08 +08:00
|
|
|
/// \brief Check that the given template argument list is well-formed
|
|
|
|
/// for specializing the given template.
|
|
|
|
bool Sema::CheckTemplateArgumentList(TemplateDecl *Template,
|
|
|
|
SourceLocation TemplateLoc,
|
2011-03-03 10:41:12 +08:00
|
|
|
TemplateArgumentListInfo &TemplateArgs,
|
2009-07-01 08:28:38 +08:00
|
|
|
bool PartialTemplateArgs,
|
2012-02-04 01:16:23 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &Converted,
|
|
|
|
bool *ExpansionIntoFixedList) {
|
|
|
|
if (ExpansionIntoFixedList)
|
|
|
|
*ExpansionIntoFixedList = false;
|
|
|
|
|
2009-02-10 07:23:08 +08:00
|
|
|
TemplateParameterList *Params = Template->getTemplateParameters();
|
|
|
|
unsigned NumParams = Params->size();
|
2009-11-23 09:53:49 +08:00
|
|
|
unsigned NumArgs = TemplateArgs.size();
|
2009-02-10 07:23:08 +08:00
|
|
|
bool Invalid = false;
|
|
|
|
|
2009-11-23 09:53:49 +08:00
|
|
|
SourceLocation RAngleLoc = TemplateArgs.getRAngleLoc();
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
bool HasParameterPack =
|
2009-06-13 10:08:00 +08:00
|
|
|
NumParams > 0 && Params->getParam(NumParams - 1)->isTemplateParameterPack();
|
2012-02-04 01:16:23 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
// C++ [temp.arg]p1:
|
2009-02-10 07:23:08 +08:00
|
|
|
// [...] The type and form of each template-argument specified in
|
|
|
|
// a template-id shall match the type and form specified for the
|
|
|
|
// corresponding parameter declared by the template in its
|
|
|
|
// template-parameter-list.
|
2011-03-03 10:41:12 +08:00
|
|
|
bool isTemplateTemplateParameter = isa<TemplateTemplateParmDecl>(Template);
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 2> ArgumentPack;
|
2010-12-21 00:57:52 +08:00
|
|
|
TemplateParameterList::iterator Param = Params->begin(),
|
|
|
|
ParamEnd = Params->end();
|
2009-02-10 07:23:08 +08:00
|
|
|
unsigned ArgIdx = 0;
|
2011-01-25 00:14:37 +08:00
|
|
|
LocalInstantiationScope InstScope(*this, true);
|
2012-02-03 15:34:46 +08:00
|
|
|
bool SawPackExpansion = false;
|
2010-12-21 00:57:52 +08:00
|
|
|
while (Param != ParamEnd) {
|
2009-11-12 05:54:23 +08:00
|
|
|
if (ArgIdx < NumArgs) {
|
2011-01-20 04:10:05 +08:00
|
|
|
// If we have an expanded parameter pack, make sure we don't have too
|
|
|
|
// many arguments.
|
2012-02-03 15:34:46 +08:00
|
|
|
// FIXME: This really should fall out from the normal arity checking.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (NonTypeTemplateParmDecl *NTTP
|
2011-01-20 04:10:05 +08:00
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
|
2011-01-27 15:10:08 +08:00
|
|
|
if (NTTP->isExpandedParameterPack() &&
|
2011-01-20 04:10:05 +08:00
|
|
|
ArgumentPack.size() >= NTTP->getNumExpansionTypes()) {
|
|
|
|
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
|
|
|
|
<< true
|
|
|
|
<< (isa<ClassTemplateDecl>(Template)? 0 :
|
|
|
|
isa<FunctionTemplateDecl>(Template)? 1 :
|
|
|
|
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
|
|
|
|
<< Template;
|
|
|
|
Diag(Template->getLocation(), diag::note_template_decl_here)
|
|
|
|
<< Params->getSourceRange();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
// Check the template argument we were given.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (CheckTemplateArgument(*Param, TemplateArgs[ArgIdx], Template,
|
|
|
|
TemplateLoc, RAngleLoc,
|
2011-01-20 04:10:05 +08:00
|
|
|
ArgumentPack.size(), Converted))
|
2009-11-12 05:54:23 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-21 00:57:52 +08:00
|
|
|
if ((*Param)->isTemplateParameterPack()) {
|
|
|
|
// The template parameter was a template parameter pack, so take the
|
|
|
|
// deduced argument and place it on the argument pack. Note that we
|
|
|
|
// stay on the same template parameter so that we can deduce more
|
|
|
|
// arguments.
|
|
|
|
ArgumentPack.push_back(Converted.back());
|
|
|
|
Converted.pop_back();
|
|
|
|
} else {
|
|
|
|
// Move to the next template parameter.
|
|
|
|
++Param;
|
|
|
|
}
|
2012-02-03 15:34:46 +08:00
|
|
|
|
|
|
|
// If this template argument is a pack expansion, record that fact
|
|
|
|
// and break out; we can't actually check any more.
|
|
|
|
if (TemplateArgs[ArgIdx].getArgument().isPackExpansion()) {
|
|
|
|
SawPackExpansion = true;
|
|
|
|
++ArgIdx;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-12-21 00:57:52 +08:00
|
|
|
++ArgIdx;
|
2009-11-12 05:54:23 +08:00
|
|
|
continue;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-06-03 10:59:40 +08:00
|
|
|
// If we're checking a partial template argument list, we're done.
|
|
|
|
if (PartialTemplateArgs) {
|
|
|
|
if ((*Param)->isTemplateParameterPack() && !ArgumentPack.empty())
|
|
|
|
Converted.push_back(TemplateArgument::CreatePackCopy(Context,
|
|
|
|
ArgumentPack.data(),
|
|
|
|
ArgumentPack.size()));
|
|
|
|
|
|
|
|
return Invalid;
|
|
|
|
}
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
// If we have a template parameter pack with no more corresponding
|
2010-12-21 00:57:52 +08:00
|
|
|
// arguments, just break out now and we'll fill in the argument pack below.
|
|
|
|
if ((*Param)->isTemplateParameterPack())
|
|
|
|
break;
|
2011-05-27 09:19:52 +08:00
|
|
|
|
2012-02-03 15:34:46 +08:00
|
|
|
// Check whether we have a default argument.
|
2009-10-29 16:12:44 +08:00
|
|
|
TemplateArgumentLoc Arg;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
// Retrieve the default template argument from the template
|
|
|
|
// parameter. For each kind of template parameter, we substitute the
|
|
|
|
// template arguments provided thus far and any "outer" template arguments
|
2011-01-27 15:10:08 +08:00
|
|
|
// (when the template parameter was part of a nested template) into
|
2009-11-12 05:54:23 +08:00
|
|
|
// the default argument.
|
|
|
|
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param)) {
|
2012-02-03 15:34:46 +08:00
|
|
|
if (!TTP->hasDefaultArgument())
|
|
|
|
return diagnoseArityMismatch(*this, Template, TemplateLoc,
|
|
|
|
TemplateArgs);
|
2009-10-29 16:12:44 +08:00
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
TypeSourceInfo *ArgType = SubstDefaultTemplateArgument(*this,
|
2009-11-12 05:54:23 +08:00
|
|
|
Template,
|
|
|
|
TemplateLoc,
|
|
|
|
RAngleLoc,
|
|
|
|
TTP,
|
|
|
|
Converted);
|
|
|
|
if (!ArgType)
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
Arg = TemplateArgumentLoc(TemplateArgument(ArgType->getType()),
|
|
|
|
ArgType);
|
|
|
|
} else if (NonTypeTemplateParmDecl *NTTP
|
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
|
2012-02-03 15:34:46 +08:00
|
|
|
if (!NTTP->hasDefaultArgument())
|
|
|
|
return diagnoseArityMismatch(*this, Template, TemplateLoc,
|
|
|
|
TemplateArgs);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult E = SubstDefaultTemplateArgument(*this, Template,
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateLoc,
|
|
|
|
RAngleLoc,
|
|
|
|
NTTP,
|
2009-11-12 05:54:23 +08:00
|
|
|
Converted);
|
|
|
|
if (E.isInvalid())
|
|
|
|
return true;
|
Added ClassTemplateSpecializationDecl, which is a subclass of
CXXRecordDecl that is used to represent class template
specializations. These are canonical declarations that can refer to
either an actual class template specialization in the code, e.g.,
template<> class vector<bool> { };
or to a template instantiation. However, neither of these features is
actually implemented yet, so really we're just using (and uniqing) the
declarations to make sure that, e.g., A<int> is a different type from
A<float>. Note that we carefully distinguish between what the user
wrote in the source code (e.g., "A<FLOAT>") and the semantic entity it
represents (e.g., "A<float, int>"); the former is in the sugared Type,
the latter is an actual Decl.
llvm-svn: 64716
2009-02-17 09:05:43 +08:00
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
Expr *Ex = E.takeAs<Expr>();
|
|
|
|
Arg = TemplateArgumentLoc(TemplateArgument(Ex), Ex);
|
|
|
|
} else {
|
|
|
|
TemplateTemplateParmDecl *TempParm
|
|
|
|
= cast<TemplateTemplateParmDecl>(*Param);
|
Added ClassTemplateSpecializationDecl, which is a subclass of
CXXRecordDecl that is used to represent class template
specializations. These are canonical declarations that can refer to
either an actual class template specialization in the code, e.g.,
template<> class vector<bool> { };
or to a template instantiation. However, neither of these features is
actually implemented yet, so really we're just using (and uniqing) the
declarations to make sure that, e.g., A<int> is a different type from
A<float>. Note that we carefully distinguish between what the user
wrote in the source code (e.g., "A<FLOAT>") and the semantic entity it
represents (e.g., "A<float, int>"); the former is in the sugared Type,
the latter is an actual Decl.
llvm-svn: 64716
2009-02-17 09:05:43 +08:00
|
|
|
|
2012-02-03 15:34:46 +08:00
|
|
|
if (!TempParm->hasDefaultArgument())
|
|
|
|
return diagnoseArityMismatch(*this, Template, TemplateLoc,
|
|
|
|
TemplateArgs);
|
2009-11-12 05:54:23 +08:00
|
|
|
|
2011-03-03 02:46:51 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc;
|
2009-11-12 05:54:23 +08:00
|
|
|
TemplateName Name = SubstDefaultTemplateArgument(*this, Template,
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateLoc,
|
|
|
|
RAngleLoc,
|
2009-11-12 05:54:23 +08:00
|
|
|
TempParm,
|
2011-03-03 01:09:35 +08:00
|
|
|
Converted,
|
|
|
|
QualifierLoc);
|
2009-11-12 05:54:23 +08:00
|
|
|
if (Name.isNull())
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-03-03 01:09:35 +08:00
|
|
|
Arg = TemplateArgumentLoc(TemplateArgument(Name), QualifierLoc,
|
|
|
|
TempParm->getDefaultArgument().getTemplateNameLoc());
|
Added ClassTemplateSpecializationDecl, which is a subclass of
CXXRecordDecl that is used to represent class template
specializations. These are canonical declarations that can refer to
either an actual class template specialization in the code, e.g.,
template<> class vector<bool> { };
or to a template instantiation. However, neither of these features is
actually implemented yet, so really we're just using (and uniqing) the
declarations to make sure that, e.g., A<int> is a different type from
A<float>. Note that we carefully distinguish between what the user
wrote in the source code (e.g., "A<FLOAT>") and the semantic entity it
represents (e.g., "A<float, int>"); the former is in the sugared Type,
the latter is an actual Decl.
llvm-svn: 64716
2009-02-17 09:05:43 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
// Introduce an instantiation record that describes where we are using
|
|
|
|
// the default template argument.
|
|
|
|
InstantiatingTemplate Instantiating(*this, RAngleLoc, Template, *Param,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(), Converted.size(),
|
2011-01-27 15:10:08 +08:00
|
|
|
SourceRange(TemplateLoc, RAngleLoc));
|
|
|
|
|
2009-11-12 05:54:23 +08:00
|
|
|
// Check the default template argument.
|
2009-11-12 03:41:09 +08:00
|
|
|
if (CheckTemplateArgument(*Param, Arg, Template, TemplateLoc,
|
2011-01-20 04:10:05 +08:00
|
|
|
RAngleLoc, 0, Converted))
|
2009-11-12 03:31:23 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-03-03 10:41:12 +08:00
|
|
|
// Core issue 150 (assumed resolution): if this is a template template
|
|
|
|
// parameter, keep track of the default template arguments from the
|
|
|
|
// template definition.
|
|
|
|
if (isTemplateTemplateParameter)
|
|
|
|
TemplateArgs.addArgument(Arg);
|
|
|
|
|
2010-12-21 00:57:52 +08:00
|
|
|
// Move to the next template parameter and argument.
|
|
|
|
++Param;
|
|
|
|
++ArgIdx;
|
2009-02-10 07:23:08 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2012-02-03 15:34:46 +08:00
|
|
|
// If we saw a pack expansion, then directly convert the remaining arguments,
|
|
|
|
// because we don't know what parameters they'll match up with.
|
|
|
|
if (SawPackExpansion) {
|
|
|
|
bool AddToArgumentPack
|
|
|
|
= Param != ParamEnd && (*Param)->isTemplateParameterPack();
|
|
|
|
while (ArgIdx < NumArgs) {
|
|
|
|
if (AddToArgumentPack)
|
|
|
|
ArgumentPack.push_back(TemplateArgs[ArgIdx].getArgument());
|
|
|
|
else
|
|
|
|
Converted.push_back(TemplateArgs[ArgIdx].getArgument());
|
|
|
|
++ArgIdx;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Push the argument pack onto the list of converted arguments.
|
|
|
|
if (AddToArgumentPack) {
|
|
|
|
if (ArgumentPack.empty())
|
|
|
|
Converted.push_back(TemplateArgument(0, 0));
|
|
|
|
else {
|
|
|
|
Converted.push_back(
|
|
|
|
TemplateArgument::CreatePackCopy(Context,
|
|
|
|
ArgumentPack.data(),
|
|
|
|
ArgumentPack.size()));
|
|
|
|
ArgumentPack.clear();
|
|
|
|
}
|
2012-02-04 01:16:23 +08:00
|
|
|
} else if (ExpansionIntoFixedList) {
|
|
|
|
// We have expanded a pack into a fixed list.
|
|
|
|
*ExpansionIntoFixedList = true;
|
2012-02-03 15:34:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return Invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have any leftover arguments, then there were too many arguments.
|
|
|
|
// Complain and fail.
|
|
|
|
if (ArgIdx < NumArgs)
|
|
|
|
return diagnoseArityMismatch(*this, Template, TemplateLoc, TemplateArgs);
|
|
|
|
|
|
|
|
// If we have an expanded parameter pack, make sure we don't have too
|
|
|
|
// many arguments.
|
|
|
|
// FIXME: This really should fall out from the normal arity checking.
|
|
|
|
if (Param != ParamEnd) {
|
|
|
|
if (NonTypeTemplateParmDecl *NTTP
|
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(*Param)) {
|
|
|
|
if (NTTP->isExpandedParameterPack() &&
|
|
|
|
ArgumentPack.size() < NTTP->getNumExpansionTypes()) {
|
|
|
|
Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
|
|
|
|
<< false
|
|
|
|
<< (isa<ClassTemplateDecl>(Template)? 0 :
|
|
|
|
isa<FunctionTemplateDecl>(Template)? 1 :
|
|
|
|
isa<TemplateTemplateParmDecl>(Template)? 2 : 3)
|
|
|
|
<< Template;
|
|
|
|
Diag(Template->getLocation(), diag::note_template_decl_here)
|
|
|
|
<< Params->getSourceRange();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-21 00:57:52 +08:00
|
|
|
// Form argument packs for each of the parameter packs remaining.
|
|
|
|
while (Param != ParamEnd) {
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
// If we're checking a partial list of template arguments, don't fill
|
|
|
|
// in arguments for non-template parameter packs.
|
2011-01-27 15:10:08 +08:00
|
|
|
if ((*Param)->isTemplateParameterPack()) {
|
2011-10-19 13:19:50 +08:00
|
|
|
if (!HasParameterPack)
|
|
|
|
return true;
|
2011-06-03 10:59:40 +08:00
|
|
|
if (ArgumentPack.empty())
|
2010-12-21 00:57:52 +08:00
|
|
|
Converted.push_back(TemplateArgument(0, 0));
|
2011-01-12 07:09:57 +08:00
|
|
|
else {
|
2011-01-27 15:10:08 +08:00
|
|
|
Converted.push_back(TemplateArgument::CreatePackCopy(Context,
|
|
|
|
ArgumentPack.data(),
|
2011-01-12 07:09:57 +08:00
|
|
|
ArgumentPack.size()));
|
2010-12-21 00:57:52 +08:00
|
|
|
ArgumentPack.clear();
|
|
|
|
}
|
2012-02-03 15:34:46 +08:00
|
|
|
} else if (!PartialTemplateArgs)
|
|
|
|
return diagnoseArityMismatch(*this, Template, TemplateLoc, TemplateArgs);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-21 00:57:52 +08:00
|
|
|
++Param;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-10 07:23:08 +08:00
|
|
|
return Invalid;
|
|
|
|
}
|
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
namespace {
|
2011-01-27 15:10:08 +08:00
|
|
|
class UnnamedLocalNoLinkageFinder
|
|
|
|
: public TypeVisitor<UnnamedLocalNoLinkageFinder, bool>
|
2010-10-13 08:27:52 +08:00
|
|
|
{
|
|
|
|
Sema &S;
|
|
|
|
SourceRange SR;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
typedef TypeVisitor<UnnamedLocalNoLinkageFinder, bool> inherited;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
public:
|
|
|
|
UnnamedLocalNoLinkageFinder(Sema &S, SourceRange SR) : S(S), SR(SR) { }
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
bool Visit(QualType T) {
|
|
|
|
return inherited::Visit(T.getTypePtr());
|
2010-10-13 08:27:52 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
#define TYPE(Class, Parent) \
|
|
|
|
bool Visit##Class##Type(const Class##Type *);
|
|
|
|
#define ABSTRACT_TYPE(Class, Parent) \
|
|
|
|
bool Visit##Class##Type(const Class##Type *) { return false; }
|
|
|
|
#define NON_CANONICAL_TYPE(Class, Parent) \
|
|
|
|
bool Visit##Class##Type(const Class##Type *) { return false; }
|
|
|
|
#include "clang/AST/TypeNodes.def"
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
bool VisitTagDecl(const TagDecl *Tag);
|
|
|
|
bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitBuiltinType(const BuiltinType*) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitComplexType(const ComplexType* T) {
|
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitPointerType(const PointerType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getPointeeType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitBlockPointerType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const BlockPointerType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getPointeeType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitLValueReferenceType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const LValueReferenceType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getPointeeType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitRValueReferenceType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const RValueReferenceType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getPointeeType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitMemberPointerType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const MemberPointerType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getPointeeType()) || Visit(QualType(T->getClass(), 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitConstantArrayType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const ConstantArrayType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitIncompleteArrayType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const IncompleteArrayType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitVariableArrayType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const VariableArrayType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitDependentSizedArrayType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const DependentSizedArrayType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitDependentSizedExtVectorType(
|
2011-01-27 15:10:08 +08:00
|
|
|
const DependentSizedExtVectorType* T) {
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitVectorType(const VectorType* T) {
|
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitExtVectorType(const ExtVectorType* T) {
|
|
|
|
return Visit(T->getElementType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitFunctionProtoType(
|
|
|
|
const FunctionProtoType* T) {
|
|
|
|
for (FunctionProtoType::arg_type_iterator A = T->arg_type_begin(),
|
2011-01-27 15:10:08 +08:00
|
|
|
AEnd = T->arg_type_end();
|
2010-10-13 08:27:52 +08:00
|
|
|
A != AEnd; ++A) {
|
|
|
|
if (Visit(*A))
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
return Visit(T->getResultType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitFunctionNoProtoType(
|
|
|
|
const FunctionNoProtoType* T) {
|
|
|
|
return Visit(T->getResultType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitUnresolvedUsingType(
|
|
|
|
const UnresolvedUsingType*) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitTypeOfExprType(const TypeOfExprType*) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitTypeOfType(const TypeOfType* T) {
|
|
|
|
return Visit(T->getUnderlyingType());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitDecltypeType(const DecltypeType*) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-05-25 06:41:36 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitUnaryTransformType(
|
|
|
|
const UnaryTransformType*) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-02-20 11:19:35 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitAutoType(const AutoType *T) {
|
|
|
|
return Visit(T->getDeducedType());
|
|
|
|
}
|
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* T) {
|
|
|
|
return VisitTagDecl(T->getDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitEnumType(const EnumType* T) {
|
|
|
|
return VisitTagDecl(T->getDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitTemplateTypeParmType(
|
|
|
|
const TemplateTypeParmType*) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-01-14 10:55:32 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitSubstTemplateTypeParmPackType(
|
|
|
|
const SubstTemplateTypeParmPackType *) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType(
|
|
|
|
const TemplateSpecializationType*) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitInjectedClassNameType(
|
|
|
|
const InjectedClassNameType* T) {
|
|
|
|
return VisitTagDecl(T->getDecl());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitDependentNameType(
|
|
|
|
const DependentNameType* T) {
|
|
|
|
return VisitNestedNameSpecifier(T->getQualifier());
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitDependentTemplateSpecializationType(
|
|
|
|
const DependentTemplateSpecializationType* T) {
|
|
|
|
return VisitNestedNameSpecifier(T->getQualifier());
|
|
|
|
}
|
|
|
|
|
2010-12-20 10:24:11 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitPackExpansionType(
|
|
|
|
const PackExpansionType* T) {
|
|
|
|
return Visit(T->getPattern());
|
|
|
|
}
|
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitObjCObjectType(const ObjCObjectType *) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitObjCInterfaceType(
|
|
|
|
const ObjCInterfaceType *) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitObjCObjectPointerType(
|
|
|
|
const ObjCObjectPointerType *) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-10-07 07:00:33 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitAtomicType(const AtomicType* T) {
|
|
|
|
return Visit(T->getValueType());
|
|
|
|
}
|
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
|
|
|
|
if (Tag->getDeclContext()->isFunctionOrMethod()) {
|
2011-10-19 04:49:44 +08:00
|
|
|
S.Diag(SR.getBegin(),
|
2012-03-11 15:00:24 +08:00
|
|
|
S.getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_template_arg_local_type :
|
|
|
|
diag::ext_template_arg_local_type)
|
2010-10-13 08:27:52 +08:00
|
|
|
<< S.Context.getTypeDeclType(Tag) << SR;
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
}
|
|
|
|
|
2011-04-15 22:24:37 +08:00
|
|
|
if (!Tag->getDeclName() && !Tag->getTypedefNameForAnonDecl()) {
|
2011-10-19 04:49:44 +08:00
|
|
|
S.Diag(SR.getBegin(),
|
2012-03-11 15:00:24 +08:00
|
|
|
S.getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_template_arg_unnamed_type :
|
|
|
|
diag::ext_template_arg_unnamed_type) << SR;
|
2010-10-13 08:27:52 +08:00
|
|
|
S.Diag(Tag->getLocation(), diag::note_template_unnamed_type_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(
|
|
|
|
NestedNameSpecifier *NNS) {
|
|
|
|
if (NNS->getPrefix() && VisitNestedNameSpecifier(NNS->getPrefix()))
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
switch (NNS->getKind()) {
|
|
|
|
case NestedNameSpecifier::Identifier:
|
|
|
|
case NestedNameSpecifier::Namespace:
|
2011-02-24 10:36:08 +08:00
|
|
|
case NestedNameSpecifier::NamespaceAlias:
|
2010-10-13 08:27:52 +08:00
|
|
|
case NestedNameSpecifier::Global:
|
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-10-13 08:27:52 +08:00
|
|
|
case NestedNameSpecifier::TypeSpec:
|
|
|
|
case NestedNameSpecifier::TypeSpecWithTemplate:
|
|
|
|
return Visit(QualType(NNS->getAsType(), 0));
|
|
|
|
}
|
2012-01-17 14:56:22 +08:00
|
|
|
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
|
2010-10-13 08:27:52 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-02-10 07:23:08 +08:00
|
|
|
/// \brief Check a template argument against its corresponding
|
|
|
|
/// template type parameter.
|
|
|
|
///
|
|
|
|
/// This routine implements the semantics of C++ [temp.arg.type]. It
|
|
|
|
/// returns true if an error occurred, and false otherwise.
|
2009-09-09 23:08:12 +08:00
|
|
|
bool Sema::CheckTemplateArgument(TemplateTypeParmDecl *Param,
|
2009-12-07 10:54:59 +08:00
|
|
|
TypeSourceInfo *ArgInfo) {
|
|
|
|
assert(ArgInfo && "invalid TypeSourceInfo");
|
2009-10-29 16:12:44 +08:00
|
|
|
QualType Arg = ArgInfo->getType();
|
2010-10-13 08:27:52 +08:00
|
|
|
SourceRange SR = ArgInfo->getTypeLoc().getSourceRange();
|
|
|
|
|
|
|
|
if (Arg->isVariablyModifiedType()) {
|
|
|
|
return Diag(SR.getBegin(), diag::err_variably_modified_template_arg) << Arg;
|
|
|
|
} else if (Context.hasSameUnqualifiedType(Arg, Context.OverloadTy)) {
|
|
|
|
return Diag(SR.getBegin(), diag::err_template_arg_overload_type) << SR;
|
|
|
|
}
|
2009-10-29 16:12:44 +08:00
|
|
|
|
2010-09-04 05:12:34 +08:00
|
|
|
// C++03 [temp.arg.type]p2:
|
2009-02-10 07:23:08 +08:00
|
|
|
// A local type, a type with no linkage, an unnamed type or a type
|
|
|
|
// compounded from any of these types shall not be used as a
|
|
|
|
// template-argument for a template type-parameter.
|
2010-10-13 08:27:52 +08:00
|
|
|
//
|
2011-10-19 04:49:44 +08:00
|
|
|
// C++11 allows these, and even in C++03 we allow them as an extension with
|
2010-09-04 05:12:34 +08:00
|
|
|
// a warning.
|
2011-10-19 04:49:44 +08:00
|
|
|
if (LangOpts.CPlusPlus0x ?
|
|
|
|
Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_unnamed_type,
|
|
|
|
SR.getBegin()) != DiagnosticsEngine::Ignored ||
|
|
|
|
Diags.getDiagnosticLevel(diag::warn_cxx98_compat_template_arg_local_type,
|
|
|
|
SR.getBegin()) != DiagnosticsEngine::Ignored :
|
|
|
|
Arg->hasUnnamedOrLocalType()) {
|
2010-10-13 08:27:52 +08:00
|
|
|
UnnamedLocalNoLinkageFinder Finder(*this, SR);
|
|
|
|
(void)Finder.Visit(Context.getCanonicalType(Arg));
|
2009-02-10 07:23:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-04-11 01:08:25 +08:00
|
|
|
enum NullPointerValueKind {
|
|
|
|
NPV_NotNullPointer,
|
|
|
|
NPV_NullPointer,
|
|
|
|
NPV_Error
|
|
|
|
};
|
|
|
|
|
|
|
|
/// \brief Determine whether the given template argument is a null pointer
|
|
|
|
/// value of the appropriate type.
|
|
|
|
static NullPointerValueKind
|
|
|
|
isNullPointerValueTemplateArgument(Sema &S, NonTypeTemplateParmDecl *Param,
|
|
|
|
QualType ParamType, Expr *Arg) {
|
|
|
|
if (Arg->isValueDependent() || Arg->isTypeDependent())
|
|
|
|
return NPV_NotNullPointer;
|
|
|
|
|
|
|
|
if (!S.getLangOpts().CPlusPlus0x)
|
|
|
|
return NPV_NotNullPointer;
|
|
|
|
|
|
|
|
// Determine whether we have a constant expression.
|
2012-04-11 03:03:30 +08:00
|
|
|
ExprResult ArgRV = S.DefaultFunctionArrayConversion(Arg);
|
|
|
|
if (ArgRV.isInvalid())
|
|
|
|
return NPV_Error;
|
|
|
|
Arg = ArgRV.take();
|
|
|
|
|
2012-04-11 01:08:25 +08:00
|
|
|
Expr::EvalResult EvalResult;
|
2012-04-11 03:03:30 +08:00
|
|
|
llvm::SmallVector<PartialDiagnosticAt, 8> Notes;
|
|
|
|
EvalResult.Diag = &Notes;
|
2012-04-11 01:08:25 +08:00
|
|
|
if (!Arg->EvaluateAsRValue(EvalResult, S.Context) ||
|
2012-04-11 03:03:30 +08:00
|
|
|
EvalResult.HasSideEffects) {
|
|
|
|
SourceLocation DiagLoc = Arg->getExprLoc();
|
|
|
|
|
|
|
|
// If our only note is the usual "invalid subexpression" note, just point
|
|
|
|
// the caret at its location rather than producing an essentially
|
|
|
|
// redundant note.
|
|
|
|
if (Notes.size() == 1 && Notes[0].second.getDiagID() ==
|
|
|
|
diag::note_invalid_subexpr_in_const_expr) {
|
|
|
|
DiagLoc = Notes[0].first;
|
|
|
|
Notes.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
S.Diag(DiagLoc, diag::err_template_arg_not_address_constant)
|
|
|
|
<< Arg->getType() << Arg->getSourceRange();
|
|
|
|
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
|
|
|
|
S.Diag(Notes[I].first, Notes[I].second);
|
|
|
|
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return NPV_Error;
|
|
|
|
}
|
2012-04-11 01:08:25 +08:00
|
|
|
|
|
|
|
// C++11 [temp.arg.nontype]p1:
|
|
|
|
// - an address constant expression of type std::nullptr_t
|
|
|
|
if (Arg->getType()->isNullPtrType())
|
|
|
|
return NPV_NullPointer;
|
|
|
|
|
|
|
|
// - a constant expression that evaluates to a null pointer value (4.10); or
|
|
|
|
// - a constant expression that evaluates to a null member pointer value
|
|
|
|
// (4.11); or
|
|
|
|
if ((EvalResult.Val.isLValue() && !EvalResult.Val.getLValueBase()) ||
|
|
|
|
(EvalResult.Val.isMemberPointer() &&
|
|
|
|
!EvalResult.Val.getMemberPointerDecl())) {
|
|
|
|
// If our expression has an appropriate type, we've succeeded.
|
|
|
|
bool ObjCLifetimeConversion;
|
|
|
|
if (S.Context.hasSameUnqualifiedType(Arg->getType(), ParamType) ||
|
|
|
|
S.IsQualificationConversion(Arg->getType(), ParamType, false,
|
|
|
|
ObjCLifetimeConversion))
|
|
|
|
return NPV_NullPointer;
|
|
|
|
|
|
|
|
// The types didn't match, but we know we got a null pointer; complain,
|
|
|
|
// then recover as if the types were correct.
|
|
|
|
S.Diag(Arg->getExprLoc(), diag::err_template_arg_wrongtype_null_constant)
|
|
|
|
<< Arg->getType() << ParamType << Arg->getSourceRange();
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return NPV_NullPointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we don't have a null pointer value, but we do have a NULL pointer
|
|
|
|
// constant, suggest a cast to the appropriate type.
|
|
|
|
if (Arg->isNullPointerConstant(S.Context, Expr::NPC_NeverValueDependent)) {
|
|
|
|
std::string Code = "static_cast<" + ParamType.getAsString() + ">(";
|
|
|
|
S.Diag(Arg->getExprLoc(), diag::err_template_arg_untyped_null_constant)
|
|
|
|
<< ParamType
|
|
|
|
<< FixItHint::CreateInsertion(Arg->getLocStart(), Code)
|
|
|
|
<< FixItHint::CreateInsertion(S.PP.getLocForEndOfToken(Arg->getLocEnd()),
|
|
|
|
")");
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return NPV_NullPointer;
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME: If we ever want to support general, address-constant expressions
|
|
|
|
// as non-type template arguments, we should return the ExprResult here to
|
|
|
|
// be interpreted by the caller.
|
|
|
|
return NPV_NotNullPointer;
|
|
|
|
}
|
|
|
|
|
2009-02-12 03:52:55 +08:00
|
|
|
/// \brief Checks whether the given template argument is the address
|
|
|
|
/// of an object or function according to C++ [temp.arg.nontype]p1.
|
2011-01-27 15:10:08 +08:00
|
|
|
static bool
|
2010-04-02 02:32:35 +08:00
|
|
|
CheckTemplateArgumentAddressOfObjectOrFunction(Sema &S,
|
|
|
|
NonTypeTemplateParmDecl *Param,
|
|
|
|
QualType ParamType,
|
|
|
|
Expr *ArgIn,
|
|
|
|
TemplateArgument &Converted) {
|
2009-02-12 03:52:55 +08:00
|
|
|
bool Invalid = false;
|
2010-04-02 02:32:35 +08:00
|
|
|
Expr *Arg = ArgIn;
|
|
|
|
QualType ArgType = Arg->getType();
|
2009-02-12 03:52:55 +08:00
|
|
|
|
2012-04-11 01:08:25 +08:00
|
|
|
// If our parameter has pointer type, check for a null template value.
|
|
|
|
if (ParamType->isPointerType() || ParamType->isNullPtrType()) {
|
|
|
|
switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) {
|
|
|
|
case NPV_NullPointer:
|
|
|
|
Converted = TemplateArgument((Decl *)0);
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case NPV_Error:
|
|
|
|
return true;
|
|
|
|
|
|
|
|
case NPV_NotNullPointer:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-12 03:52:55 +08:00
|
|
|
// See through any implicit casts we added to fix the type.
|
2011-07-15 13:09:51 +08:00
|
|
|
Arg = Arg->IgnoreImpCasts();
|
2009-02-12 03:52:55 +08:00
|
|
|
|
|
|
|
// C++ [temp.arg.nontype]p1:
|
2009-09-09 23:08:12 +08:00
|
|
|
//
|
2009-02-12 03:52:55 +08:00
|
|
|
// A template-argument for a non-type, non-template
|
|
|
|
// template-parameter shall be one of: [...]
|
|
|
|
//
|
|
|
|
// -- the address of an object or function with external
|
|
|
|
// linkage, including function templates and function
|
|
|
|
// template-ids but excluding non-static class members,
|
|
|
|
// expressed as & id-expression where the & is optional if
|
|
|
|
// the name refers to a function or array, or if the
|
|
|
|
// corresponding template-parameter is a reference; or
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-09-13 14:06:58 +08:00
|
|
|
// In C++98/03 mode, give an extension warning on any extra parentheses.
|
|
|
|
// See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
|
|
|
|
bool ExtraParens = false;
|
2009-02-12 03:52:55 +08:00
|
|
|
while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
|
2011-10-19 04:49:44 +08:00
|
|
|
if (!Invalid && !ExtraParens) {
|
2012-03-10 02:35:03 +08:00
|
|
|
S.Diag(Arg->getLocStart(),
|
2012-03-11 15:00:24 +08:00
|
|
|
S.getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_template_arg_extra_parens :
|
|
|
|
diag::ext_template_arg_extra_parens)
|
2009-02-12 03:52:55 +08:00
|
|
|
<< Arg->getSourceRange();
|
2010-09-13 14:06:58 +08:00
|
|
|
ExtraParens = true;
|
2009-02-12 03:52:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Arg = Parens->getSubExpr();
|
|
|
|
}
|
|
|
|
|
2011-07-15 13:09:51 +08:00
|
|
|
while (SubstNonTypeTemplateParmExpr *subst =
|
|
|
|
dyn_cast<SubstNonTypeTemplateParmExpr>(Arg))
|
|
|
|
Arg = subst->getReplacement()->IgnoreImpCasts();
|
|
|
|
|
2010-04-02 02:32:35 +08:00
|
|
|
bool AddressTaken = false;
|
|
|
|
SourceLocation AddrOpLoc;
|
2009-02-12 03:52:55 +08:00
|
|
|
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
|
2010-08-25 19:45:40 +08:00
|
|
|
if (UnOp->getOpcode() == UO_AddrOf) {
|
2011-07-15 13:09:51 +08:00
|
|
|
Arg = UnOp->getSubExpr();
|
2010-04-02 02:32:35 +08:00
|
|
|
AddressTaken = true;
|
|
|
|
AddrOpLoc = UnOp->getOperatorLoc();
|
|
|
|
}
|
2011-04-29 17:08:14 +08:00
|
|
|
}
|
2011-07-15 13:09:51 +08:00
|
|
|
|
2012-03-11 15:00:24 +08:00
|
|
|
if (S.getLangOpts().MicrosoftExt && isa<CXXUuidofExpr>(Arg)) {
|
2011-07-15 13:09:51 +08:00
|
|
|
Converted = TemplateArgument(ArgIn);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (SubstNonTypeTemplateParmExpr *subst =
|
|
|
|
dyn_cast<SubstNonTypeTemplateParmExpr>(Arg))
|
|
|
|
Arg = subst->getReplacement()->IgnoreImpCasts();
|
|
|
|
|
2010-01-31 18:01:20 +08:00
|
|
|
// Stop checking the precise nature of the argument if it is value dependent,
|
|
|
|
// it should be checked when instantiated.
|
2010-04-02 02:32:35 +08:00
|
|
|
if (Arg->isValueDependent()) {
|
2010-10-26 15:05:15 +08:00
|
|
|
Converted = TemplateArgument(ArgIn);
|
2010-01-31 18:01:20 +08:00
|
|
|
return false;
|
2010-04-02 02:32:35 +08:00
|
|
|
}
|
2012-04-07 06:40:38 +08:00
|
|
|
|
|
|
|
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Arg);
|
|
|
|
if (!DRE) {
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_not_decl_ref)
|
|
|
|
<< Arg->getSourceRange();
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
2010-01-31 18:01:20 +08:00
|
|
|
|
2010-04-02 02:32:35 +08:00
|
|
|
if (!isa<ValueDecl>(DRE->getDecl())) {
|
2012-03-10 02:35:03 +08:00
|
|
|
S.Diag(Arg->getLocStart(),
|
2010-04-02 02:32:35 +08:00
|
|
|
diag::err_template_arg_not_object_or_func_form)
|
2009-02-12 03:52:55 +08:00
|
|
|
<< Arg->getSourceRange();
|
2010-04-02 02:32:35 +08:00
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-04-05 05:11:30 +08:00
|
|
|
NamedDecl *Entity = DRE->getDecl();
|
2009-02-12 03:52:55 +08:00
|
|
|
|
|
|
|
// Cannot refer to non-static data members
|
2012-04-05 05:11:30 +08:00
|
|
|
if (FieldDecl *Field = dyn_cast<FieldDecl>(Entity)) {
|
2012-03-10 02:35:03 +08:00
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_field)
|
2009-02-12 03:52:55 +08:00
|
|
|
<< Field << Arg->getSourceRange();
|
2010-04-02 02:32:35 +08:00
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
2009-02-12 03:52:55 +08:00
|
|
|
|
|
|
|
// Cannot refer to non-static member functions
|
2012-04-05 05:11:30 +08:00
|
|
|
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Entity)) {
|
2010-04-02 02:32:35 +08:00
|
|
|
if (!Method->isStatic()) {
|
2012-03-10 02:35:03 +08:00
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_method)
|
2009-02-12 03:52:55 +08:00
|
|
|
<< Method << Arg->getSourceRange();
|
2010-04-02 02:32:35 +08:00
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
2012-04-05 05:11:30 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2012-04-05 05:11:30 +08:00
|
|
|
FunctionDecl *Func = dyn_cast<FunctionDecl>(Entity);
|
|
|
|
VarDecl *Var = dyn_cast<VarDecl>(Entity);
|
|
|
|
|
|
|
|
// A non-type template argument must refer to an object or function.
|
|
|
|
if (!Func && !Var) {
|
|
|
|
// We found something, but we don't know specifically what it is.
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_not_object_or_func)
|
|
|
|
<< Arg->getSourceRange();
|
|
|
|
S.Diag(DRE->getDecl()->getLocation(), diag::note_template_arg_refers_here);
|
|
|
|
return true;
|
|
|
|
}
|
2009-02-12 03:52:55 +08:00
|
|
|
|
2012-04-05 05:11:30 +08:00
|
|
|
// Address / reference template args must have external linkage in C++98.
|
|
|
|
if (Entity->getLinkage() == InternalLinkage) {
|
|
|
|
S.Diag(Arg->getLocStart(), S.getLangOpts().CPlusPlus0x ?
|
|
|
|
diag::warn_cxx98_compat_template_arg_object_internal :
|
|
|
|
diag::ext_template_arg_object_internal)
|
|
|
|
<< !Func << Entity << Arg->getSourceRange();
|
|
|
|
S.Diag(Entity->getLocation(), diag::note_template_arg_internal_object)
|
|
|
|
<< !Func;
|
|
|
|
} else if (Entity->getLinkage() == NoLinkage) {
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_object_no_linkage)
|
|
|
|
<< !Func << Entity << Arg->getSourceRange();
|
|
|
|
S.Diag(Entity->getLocation(), diag::note_template_arg_internal_object)
|
|
|
|
<< !Func;
|
|
|
|
return true;
|
|
|
|
}
|
2009-02-12 03:52:55 +08:00
|
|
|
|
2012-04-05 05:11:30 +08:00
|
|
|
if (Func) {
|
2010-04-02 02:32:35 +08:00
|
|
|
// If the template parameter has pointer type, the function decays.
|
|
|
|
if (ParamType->isPointerType() && !AddressTaken)
|
|
|
|
ArgType = S.Context.getPointerType(Func->getType());
|
|
|
|
else if (AddressTaken && ParamType->isReferenceType()) {
|
|
|
|
// If we originally had an address-of operator, but the
|
|
|
|
// parameter has reference type, complain and (if things look
|
|
|
|
// like they will work) drop the address-of operator.
|
|
|
|
if (!S.Context.hasSameUnqualifiedType(Func->getType(),
|
|
|
|
ParamType.getNonReferenceType())) {
|
|
|
|
S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
|
|
|
|
<< ParamType;
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
|
|
|
|
<< ParamType
|
|
|
|
<< FixItHint::CreateRemoval(AddrOpLoc);
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
|
|
|
|
ArgType = Func->getType();
|
|
|
|
}
|
2012-04-05 05:11:30 +08:00
|
|
|
} else {
|
2010-04-02 02:32:35 +08:00
|
|
|
// A value of reference type is not an object.
|
|
|
|
if (Var->getType()->isReferenceType()) {
|
2012-03-10 02:35:03 +08:00
|
|
|
S.Diag(Arg->getLocStart(),
|
2010-04-02 02:32:35 +08:00
|
|
|
diag::err_template_arg_reference_var)
|
|
|
|
<< Var->getType() << Arg->getSourceRange();
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2012-04-05 05:11:30 +08:00
|
|
|
// A template argument must have static storage duration.
|
|
|
|
// FIXME: Ensure this works for thread_local as well as __thread.
|
|
|
|
if (Var->isThreadSpecified()) {
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_thread_local)
|
|
|
|
<< Arg->getSourceRange();
|
|
|
|
S.Diag(Var->getLocation(), diag::note_template_arg_refers_here);
|
|
|
|
return true;
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-04-02 02:32:35 +08:00
|
|
|
// If the template parameter has pointer type, we must have taken
|
|
|
|
// the address of this object.
|
|
|
|
if (ParamType->isReferenceType()) {
|
|
|
|
if (AddressTaken) {
|
|
|
|
// If we originally had an address-of operator, but the
|
|
|
|
// parameter has reference type, complain and (if things look
|
|
|
|
// like they will work) drop the address-of operator.
|
|
|
|
if (!S.Context.hasSameUnqualifiedType(Var->getType(),
|
|
|
|
ParamType.getNonReferenceType())) {
|
|
|
|
S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
|
|
|
|
<< ParamType;
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
|
|
|
|
<< ParamType
|
|
|
|
<< FixItHint::CreateRemoval(AddrOpLoc);
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
|
|
|
|
ArgType = Var->getType();
|
|
|
|
}
|
|
|
|
} else if (!AddressTaken && ParamType->isPointerType()) {
|
|
|
|
if (Var->getType()->isArrayType()) {
|
|
|
|
// Array-to-pointer decay.
|
|
|
|
ArgType = S.Context.getArrayDecayedType(Var->getType());
|
|
|
|
} else {
|
|
|
|
// If the template parameter has pointer type but the address of
|
|
|
|
// this object was not taken, complain and (possibly) recover by
|
|
|
|
// taking the address of the entity.
|
|
|
|
ArgType = S.Context.getPointerType(Var->getType());
|
|
|
|
if (!S.Context.hasSameUnqualifiedType(ArgType, ParamType)) {
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_not_address_of)
|
|
|
|
<< ParamType;
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_not_address_of)
|
|
|
|
<< ParamType
|
|
|
|
<< FixItHint::CreateInsertion(Arg->getLocStart(), "&");
|
|
|
|
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-06-16 07:02:42 +08:00
|
|
|
bool ObjCLifetimeConversion;
|
2011-01-27 15:10:08 +08:00
|
|
|
if (ParamType->isPointerType() &&
|
2010-04-02 02:32:35 +08:00
|
|
|
!ParamType->getAs<PointerType>()->getPointeeType()->isFunctionType() &&
|
2011-06-16 07:02:42 +08:00
|
|
|
S.IsQualificationConversion(ArgType, ParamType, false,
|
|
|
|
ObjCLifetimeConversion)) {
|
2010-04-02 02:32:35 +08:00
|
|
|
// For pointer-to-object types, qualification conversions are
|
|
|
|
// permitted.
|
|
|
|
} else {
|
|
|
|
if (const ReferenceType *ParamRef = ParamType->getAs<ReferenceType>()) {
|
|
|
|
if (!ParamRef->getPointeeType()->isFunctionType()) {
|
|
|
|
// C++ [temp.arg.nontype]p5b3:
|
|
|
|
// For a non-type template-parameter of type reference to
|
|
|
|
// object, no conversions apply. The type referred to by the
|
|
|
|
// reference may be more cv-qualified than the (otherwise
|
|
|
|
// identical) type of the template- argument. The
|
|
|
|
// template-parameter is bound directly to the
|
|
|
|
// template-argument, which shall be an lvalue.
|
|
|
|
|
|
|
|
// FIXME: Other qualifiers?
|
|
|
|
unsigned ParamQuals = ParamRef->getPointeeType().getCVRQualifiers();
|
|
|
|
unsigned ArgQuals = ArgType.getCVRQualifiers();
|
|
|
|
|
|
|
|
if ((ParamQuals | ArgQuals) != ParamQuals) {
|
2012-03-10 02:35:03 +08:00
|
|
|
S.Diag(Arg->getLocStart(),
|
2010-04-02 02:32:35 +08:00
|
|
|
diag::err_template_arg_ref_bind_ignores_quals)
|
|
|
|
<< ParamType << Arg->getType()
|
|
|
|
<< Arg->getSourceRange();
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
}
|
2010-04-02 02:32:35 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// At this point, the template argument refers to an object or
|
|
|
|
// function with external linkage. We now need to check whether the
|
|
|
|
// argument and parameter types are compatible.
|
|
|
|
if (!S.Context.hasSameUnqualifiedType(ArgType,
|
|
|
|
ParamType.getNonReferenceType())) {
|
|
|
|
// We can't perform this conversion or binding.
|
|
|
|
if (ParamType->isReferenceType())
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_no_ref_bind)
|
2011-07-15 13:09:51 +08:00
|
|
|
<< ParamType << ArgIn->getType() << Arg->getSourceRange();
|
2010-04-02 02:32:35 +08:00
|
|
|
else
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_not_convertible)
|
2011-07-15 13:09:51 +08:00
|
|
|
<< ArgIn->getType() << ParamType << Arg->getSourceRange();
|
2010-04-02 02:32:35 +08:00
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Create the template argument.
|
|
|
|
Converted = TemplateArgument(Entity->getCanonicalDecl());
|
2012-02-02 11:46:19 +08:00
|
|
|
S.MarkAnyDeclReferenced(Arg->getLocStart(), Entity);
|
2010-04-02 02:32:35 +08:00
|
|
|
return false;
|
2009-02-12 03:52:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Checks whether the given template argument is a pointer to
|
|
|
|
/// member constant according to C++ [temp.arg.nontype]p1.
|
2012-04-11 01:08:25 +08:00
|
|
|
static bool CheckTemplateArgumentPointerToMember(Sema &S,
|
|
|
|
NonTypeTemplateParmDecl *Param,
|
|
|
|
QualType ParamType,
|
|
|
|
Expr *&ResultArg,
|
|
|
|
TemplateArgument &Converted) {
|
2009-02-12 03:52:55 +08:00
|
|
|
bool Invalid = false;
|
|
|
|
|
2012-04-11 01:08:25 +08:00
|
|
|
// Check for a null pointer value.
|
|
|
|
Expr *Arg = ResultArg;
|
|
|
|
switch (isNullPointerValueTemplateArgument(S, Param, ParamType, Arg)) {
|
|
|
|
case NPV_Error:
|
|
|
|
return true;
|
|
|
|
case NPV_NullPointer:
|
|
|
|
Converted = TemplateArgument((Decl *)0);
|
|
|
|
return false;
|
|
|
|
case NPV_NotNullPointer:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ObjCLifetimeConversion;
|
|
|
|
if (S.IsQualificationConversion(Arg->getType(),
|
|
|
|
ParamType.getNonReferenceType(),
|
|
|
|
false, ObjCLifetimeConversion)) {
|
|
|
|
Arg = S.ImpCastExprToType(Arg, ParamType, CK_NoOp,
|
|
|
|
Arg->getValueKind()).take();
|
|
|
|
ResultArg = Arg;
|
|
|
|
} else if (!S.Context.hasSameUnqualifiedType(Arg->getType(),
|
|
|
|
ParamType.getNonReferenceType())) {
|
|
|
|
// We can't perform this conversion.
|
|
|
|
S.Diag(Arg->getLocStart(), diag::err_template_arg_not_convertible)
|
|
|
|
<< Arg->getType() << ParamType << Arg->getSourceRange();
|
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-02-12 03:52:55 +08:00
|
|
|
// See through any implicit casts we added to fix the type.
|
2009-10-20 16:27:19 +08:00
|
|
|
while (ImplicitCastExpr *Cast = dyn_cast<ImplicitCastExpr>(Arg))
|
2009-02-12 03:52:55 +08:00
|
|
|
Arg = Cast->getSubExpr();
|
|
|
|
|
|
|
|
// C++ [temp.arg.nontype]p1:
|
2009-09-09 23:08:12 +08:00
|
|
|
//
|
2009-02-12 03:52:55 +08:00
|
|
|
// A template-argument for a non-type, non-template
|
|
|
|
// template-parameter shall be one of: [...]
|
|
|
|
//
|
|
|
|
// -- a pointer to member expressed as described in 5.3.1.
|
2009-10-24 02:54:35 +08:00
|
|
|
DeclRefExpr *DRE = 0;
|
2009-02-12 03:52:55 +08:00
|
|
|
|
2010-09-13 14:06:58 +08:00
|
|
|
// In C++98/03 mode, give an extension warning on any extra parentheses.
|
|
|
|
// See http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#773
|
|
|
|
bool ExtraParens = false;
|
2009-02-12 03:52:55 +08:00
|
|
|
while (ParenExpr *Parens = dyn_cast<ParenExpr>(Arg)) {
|
2011-10-19 04:49:44 +08:00
|
|
|
if (!Invalid && !ExtraParens) {
|
2012-04-11 01:08:25 +08:00
|
|
|
S.Diag(Arg->getLocStart(),
|
|
|
|
S.getLangOpts().CPlusPlus0x ?
|
|
|
|
diag::warn_cxx98_compat_template_arg_extra_parens :
|
|
|
|
diag::ext_template_arg_extra_parens)
|
2009-02-12 03:52:55 +08:00
|
|
|
<< Arg->getSourceRange();
|
2010-09-13 14:06:58 +08:00
|
|
|
ExtraParens = true;
|
2009-02-12 03:52:55 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Arg = Parens->getSubExpr();
|
|
|
|
}
|
|
|
|
|
2011-07-15 13:09:51 +08:00
|
|
|
while (SubstNonTypeTemplateParmExpr *subst =
|
|
|
|
dyn_cast<SubstNonTypeTemplateParmExpr>(Arg))
|
|
|
|
Arg = subst->getReplacement()->IgnoreImpCasts();
|
|
|
|
|
2009-11-13 02:38:13 +08:00
|
|
|
// A pointer-to-member constant written &Class::member.
|
|
|
|
if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(Arg)) {
|
2010-08-25 19:45:40 +08:00
|
|
|
if (UnOp->getOpcode() == UO_AddrOf) {
|
2009-10-24 02:54:35 +08:00
|
|
|
DRE = dyn_cast<DeclRefExpr>(UnOp->getSubExpr());
|
|
|
|
if (DRE && !DRE->getQualifier())
|
|
|
|
DRE = 0;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
}
|
2009-11-13 02:38:13 +08:00
|
|
|
// A constant of pointer-to-member type.
|
|
|
|
else if ((DRE = dyn_cast<DeclRefExpr>(Arg))) {
|
|
|
|
if (ValueDecl *VD = dyn_cast<ValueDecl>(DRE->getDecl())) {
|
|
|
|
if (VD->getType()->isMemberPointerType()) {
|
|
|
|
if (isa<NonTypeTemplateParmDecl>(VD) ||
|
2011-01-27 15:10:08 +08:00
|
|
|
(isa<VarDecl>(VD) &&
|
2012-04-11 01:08:25 +08:00
|
|
|
S.Context.getCanonicalType(VD->getType()).isConstQualified())) {
|
2009-11-13 02:38:13 +08:00
|
|
|
if (Arg->isTypeDependent() || Arg->isValueDependent())
|
2010-10-26 15:05:15 +08:00
|
|
|
Converted = TemplateArgument(Arg);
|
2009-11-13 02:38:13 +08:00
|
|
|
else
|
|
|
|
Converted = TemplateArgument(VD->getCanonicalDecl());
|
|
|
|
return Invalid;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-11-13 02:38:13 +08:00
|
|
|
DRE = 0;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-12 03:52:55 +08:00
|
|
|
if (!DRE)
|
2012-04-11 01:08:25 +08:00
|
|
|
return S.Diag(Arg->getLocStart(),
|
|
|
|
diag::err_template_arg_not_pointer_to_member_form)
|
2009-02-12 03:52:55 +08:00
|
|
|
<< Arg->getSourceRange();
|
|
|
|
|
|
|
|
if (isa<FieldDecl>(DRE->getDecl()) || isa<CXXMethodDecl>(DRE->getDecl())) {
|
|
|
|
assert((isa<FieldDecl>(DRE->getDecl()) ||
|
|
|
|
!cast<CXXMethodDecl>(DRE->getDecl())->isStatic()) &&
|
|
|
|
"Only non-static member pointers can make it here");
|
|
|
|
|
|
|
|
// Okay: this is the address of a non-static member, and therefore
|
|
|
|
// a member pointer constant.
|
2009-11-13 02:38:13 +08:00
|
|
|
if (Arg->isTypeDependent() || Arg->isValueDependent())
|
2010-10-26 15:05:15 +08:00
|
|
|
Converted = TemplateArgument(Arg);
|
2009-11-13 02:38:13 +08:00
|
|
|
else
|
|
|
|
Converted = TemplateArgument(DRE->getDecl()->getCanonicalDecl());
|
2009-02-12 03:52:55 +08:00
|
|
|
return Invalid;
|
|
|
|
}
|
|
|
|
|
|
|
|
// We found something else, but we don't know specifically what it is.
|
2012-04-11 01:08:25 +08:00
|
|
|
S.Diag(Arg->getLocStart(),
|
|
|
|
diag::err_template_arg_not_pointer_to_member_form)
|
|
|
|
<< Arg->getSourceRange();
|
|
|
|
S.Diag(DRE->getDecl()->getLocation(), diag::note_template_arg_refers_here);
|
2009-02-12 03:52:55 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-02-10 07:23:08 +08:00
|
|
|
/// \brief Check a template argument against its corresponding
|
|
|
|
/// non-type template parameter.
|
|
|
|
///
|
2009-03-03 12:44:36 +08:00
|
|
|
/// This routine implements the semantics of C++ [temp.arg.nontype].
|
2011-04-09 02:41:53 +08:00
|
|
|
/// If an error occurred, it returns ExprError(); otherwise, it
|
|
|
|
/// returns the converted template argument. \p
|
2009-03-03 12:44:36 +08:00
|
|
|
/// InstantiatedParamType is the type of the non-type template
|
|
|
|
/// parameter after it has been instantiated.
|
2011-04-09 02:41:53 +08:00
|
|
|
ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
|
|
|
|
QualType InstantiatedParamType, Expr *Arg,
|
|
|
|
TemplateArgument &Converted,
|
|
|
|
CheckTemplateArgumentKind CTAK) {
|
2012-03-10 02:35:03 +08:00
|
|
|
SourceLocation StartLoc = Arg->getLocStart();
|
2009-03-10 07:48:35 +08:00
|
|
|
|
2009-02-11 07:36:10 +08:00
|
|
|
// If either the parameter has a dependent type or the argument is
|
|
|
|
// type-dependent, there's nothing we can check now.
|
2009-03-10 07:48:35 +08:00
|
|
|
if (InstantiatedParamType->isDependentType() || Arg->isTypeDependent()) {
|
|
|
|
// FIXME: Produce a cloned, canonical expression?
|
2009-06-12 02:10:32 +08:00
|
|
|
Converted = TemplateArgument(Arg);
|
2011-04-09 02:41:53 +08:00
|
|
|
return Owned(Arg);
|
2009-03-10 07:48:35 +08:00
|
|
|
}
|
2009-02-11 07:36:10 +08:00
|
|
|
|
|
|
|
// C++ [temp.arg.nontype]p5:
|
|
|
|
// The following conversions are performed on each expression used
|
|
|
|
// as a non-type template-argument. If a non-type
|
|
|
|
// template-argument cannot be converted to the type of the
|
|
|
|
// corresponding template-parameter then the program is
|
|
|
|
// ill-formed.
|
2009-03-03 12:44:36 +08:00
|
|
|
QualType ParamType = InstantiatedParamType;
|
2010-06-16 08:17:44 +08:00
|
|
|
if (ParamType->isIntegralOrEnumerationType()) {
|
2012-01-19 07:55:52 +08:00
|
|
|
// C++11:
|
|
|
|
// -- for a non-type template-parameter of integral or
|
|
|
|
// enumeration type, conversions permitted in a converted
|
|
|
|
// constant expression are applied.
|
|
|
|
//
|
|
|
|
// C++98:
|
|
|
|
// -- for a non-type template-parameter of integral or
|
|
|
|
// enumeration type, integral promotions (4.5) and integral
|
|
|
|
// conversions (4.7) are applied.
|
|
|
|
|
|
|
|
if (CTAK == CTAK_Deduced &&
|
|
|
|
!Context.hasSameUnqualifiedType(ParamType, Arg->getType())) {
|
|
|
|
// C++ [temp.deduct.type]p17:
|
|
|
|
// If, in the declaration of a function template with a non-type
|
|
|
|
// template-parameter, the non-type template-parameter is used
|
|
|
|
// in an expression in the function parameter-list and, if the
|
|
|
|
// corresponding template-argument is deduced, the
|
|
|
|
// template-argument type shall match the type of the
|
|
|
|
// template-parameter exactly, except that a template-argument
|
|
|
|
// deduced from an array bound may be of any integral type.
|
|
|
|
Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
|
|
|
|
<< Arg->getType().getUnqualifiedType()
|
|
|
|
<< ParamType.getUnqualifiedType();
|
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return ExprError();
|
|
|
|
}
|
|
|
|
|
2012-03-11 15:00:24 +08:00
|
|
|
if (getLangOpts().CPlusPlus0x) {
|
2012-01-19 07:55:52 +08:00
|
|
|
// We can't check arbitrary value-dependent arguments.
|
|
|
|
// FIXME: If there's no viable conversion to the template parameter type,
|
|
|
|
// we should be able to diagnose that prior to instantiation.
|
|
|
|
if (Arg->isValueDependent()) {
|
|
|
|
Converted = TemplateArgument(Arg);
|
|
|
|
return Owned(Arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
// C++ [temp.arg.nontype]p1:
|
|
|
|
// A template-argument for a non-type, non-template template-parameter
|
|
|
|
// shall be one of:
|
|
|
|
//
|
|
|
|
// -- for a non-type template-parameter of integral or enumeration
|
|
|
|
// type, a converted constant expression of the type of the
|
|
|
|
// template-parameter; or
|
|
|
|
llvm::APSInt Value;
|
|
|
|
ExprResult ArgResult =
|
|
|
|
CheckConvertedConstantExpression(Arg, ParamType, Value,
|
|
|
|
CCEK_TemplateArg);
|
|
|
|
if (ArgResult.isInvalid())
|
|
|
|
return ExprError();
|
|
|
|
|
|
|
|
// Widen the argument value to sizeof(parameter type). This is almost
|
|
|
|
// always a no-op, except when the parameter type is bool. In
|
|
|
|
// that case, this may extend the argument from 1 bit to 8 bits.
|
|
|
|
QualType IntegerType = ParamType;
|
|
|
|
if (const EnumType *Enum = IntegerType->getAs<EnumType>())
|
|
|
|
IntegerType = Enum->getDecl()->getIntegerType();
|
|
|
|
Value = Value.extOrTrunc(Context.getTypeSize(IntegerType));
|
|
|
|
|
|
|
|
Converted = TemplateArgument(Value, Context.getCanonicalType(ParamType));
|
|
|
|
return ArgResult;
|
|
|
|
}
|
|
|
|
|
2011-10-28 06:11:44 +08:00
|
|
|
ExprResult ArgResult = DefaultLvalueConversion(Arg);
|
|
|
|
if (ArgResult.isInvalid())
|
|
|
|
return ExprError();
|
|
|
|
Arg = ArgResult.take();
|
|
|
|
|
|
|
|
QualType ArgType = Arg->getType();
|
|
|
|
|
2009-02-11 07:36:10 +08:00
|
|
|
// C++ [temp.arg.nontype]p1:
|
|
|
|
// A template-argument for a non-type, non-template
|
|
|
|
// template-parameter shall be one of:
|
|
|
|
//
|
|
|
|
// -- an integral constant-expression of integral or enumeration
|
|
|
|
// type; or
|
|
|
|
// -- the name of a non-type template-parameter; or
|
|
|
|
SourceLocation NonConstantLoc;
|
Added ClassTemplateSpecializationDecl, which is a subclass of
CXXRecordDecl that is used to represent class template
specializations. These are canonical declarations that can refer to
either an actual class template specialization in the code, e.g.,
template<> class vector<bool> { };
or to a template instantiation. However, neither of these features is
actually implemented yet, so really we're just using (and uniqing) the
declarations to make sure that, e.g., A<int> is a different type from
A<float>. Note that we carefully distinguish between what the user
wrote in the source code (e.g., "A<FLOAT>") and the semantic entity it
represents (e.g., "A<float, int>"); the former is in the sugared Type,
the latter is an actual Decl.
llvm-svn: 64716
2009-02-17 09:05:43 +08:00
|
|
|
llvm::APSInt Value;
|
2010-06-16 08:17:44 +08:00
|
|
|
if (!ArgType->isIntegralOrEnumerationType()) {
|
2012-03-10 02:35:03 +08:00
|
|
|
Diag(Arg->getLocStart(),
|
2009-02-11 07:36:10 +08:00
|
|
|
diag::err_template_arg_not_integral_or_enumeral)
|
|
|
|
<< ArgType << Arg->getSourceRange();
|
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
2012-02-04 17:53:13 +08:00
|
|
|
} else if (!Arg->isValueDependent()) {
|
|
|
|
Arg = VerifyIntegerConstantExpression(Arg, &Value,
|
|
|
|
PDiag(diag::err_template_arg_not_ice) << ArgType, false).take();
|
|
|
|
if (!Arg)
|
|
|
|
return ExprError();
|
2009-02-11 07:36:10 +08:00
|
|
|
}
|
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
// From here on out, all we care about are the unqualified forms
|
|
|
|
// of the parameter and argument types.
|
|
|
|
ParamType = ParamType.getUnqualifiedType();
|
|
|
|
ArgType = ArgType.getUnqualifiedType();
|
2009-02-11 07:36:10 +08:00
|
|
|
|
|
|
|
// Try to convert the argument to the parameter's type.
|
2009-11-05 05:50:46 +08:00
|
|
|
if (Context.hasSameType(ParamType, ArgType)) {
|
2009-02-11 07:36:10 +08:00
|
|
|
// Okay: no conversion necessary
|
2010-11-15 17:13:47 +08:00
|
|
|
} else if (ParamType->isBooleanType()) {
|
|
|
|
// This is an integral-to-boolean conversion.
|
2011-04-09 02:41:53 +08:00
|
|
|
Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralToBoolean).take();
|
2009-02-11 07:36:10 +08:00
|
|
|
} else if (IsIntegralPromotion(Arg, ArgType, ParamType) ||
|
|
|
|
!ParamType->isEnumeralType()) {
|
|
|
|
// This is an integral promotion or conversion.
|
2011-04-09 02:41:53 +08:00
|
|
|
Arg = ImpCastExprToType(Arg, ParamType, CK_IntegralCast).take();
|
2009-02-11 07:36:10 +08:00
|
|
|
} else {
|
|
|
|
// We can't perform this conversion.
|
2012-03-10 02:35:03 +08:00
|
|
|
Diag(Arg->getLocStart(),
|
2009-02-11 07:36:10 +08:00
|
|
|
diag::err_template_arg_not_convertible)
|
2009-03-03 12:44:36 +08:00
|
|
|
<< Arg->getType() << InstantiatedParamType << Arg->getSourceRange();
|
2009-02-11 07:36:10 +08:00
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
2009-02-11 07:36:10 +08:00
|
|
|
}
|
|
|
|
|
2011-05-05 05:55:00 +08:00
|
|
|
// Add the value of this argument to the list of converted
|
|
|
|
// arguments. We use the bitwidth and signedness of the template
|
|
|
|
// parameter.
|
|
|
|
if (Arg->isValueDependent()) {
|
|
|
|
// The argument is value-dependent. Create a new
|
|
|
|
// TemplateArgument with the converted expression.
|
|
|
|
Converted = TemplateArgument(Arg);
|
|
|
|
return Owned(Arg);
|
|
|
|
}
|
|
|
|
|
2009-03-14 08:20:21 +08:00
|
|
|
QualType IntegerType = Context.getCanonicalType(ParamType);
|
2009-09-22 07:43:11 +08:00
|
|
|
if (const EnumType *Enum = IntegerType->getAs<EnumType>())
|
2009-06-12 02:10:32 +08:00
|
|
|
IntegerType = Context.getCanonicalType(Enum->getDecl()->getIntegerType());
|
2009-03-14 08:20:21 +08:00
|
|
|
|
2011-05-05 05:55:00 +08:00
|
|
|
if (ParamType->isBooleanType()) {
|
|
|
|
// Value must be zero or one.
|
|
|
|
Value = Value != 0;
|
|
|
|
unsigned AllowedBits = Context.getTypeSize(IntegerType);
|
|
|
|
if (Value.getBitWidth() != AllowedBits)
|
|
|
|
Value = Value.extOrTrunc(AllowedBits);
|
2011-05-21 00:38:50 +08:00
|
|
|
Value.setIsSigned(IntegerType->isSignedIntegerOrEnumerationType());
|
2011-05-05 05:55:00 +08:00
|
|
|
} else {
|
2010-03-26 10:38:37 +08:00
|
|
|
llvm::APSInt OldValue = Value;
|
2011-05-05 05:55:00 +08:00
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
// Coerce the template argument's value to the value it will have
|
2010-03-26 10:38:37 +08:00
|
|
|
// based on the template parameter's type.
|
|
|
|
unsigned AllowedBits = Context.getTypeSize(IntegerType);
|
|
|
|
if (Value.getBitWidth() != AllowedBits)
|
2010-12-07 16:25:34 +08:00
|
|
|
Value = Value.extOrTrunc(AllowedBits);
|
2011-05-21 00:38:50 +08:00
|
|
|
Value.setIsSigned(IntegerType->isSignedIntegerOrEnumerationType());
|
2011-05-05 05:55:00 +08:00
|
|
|
|
2010-03-26 10:38:37 +08:00
|
|
|
// Complain if an unsigned parameter received a negative value.
|
2011-05-21 00:38:50 +08:00
|
|
|
if (IntegerType->isUnsignedIntegerOrEnumerationType()
|
2011-05-05 05:55:00 +08:00
|
|
|
&& (OldValue.isSigned() && OldValue.isNegative())) {
|
2012-03-10 02:35:03 +08:00
|
|
|
Diag(Arg->getLocStart(), diag::warn_template_arg_negative)
|
2010-03-26 10:38:37 +08:00
|
|
|
<< OldValue.toString(10) << Value.toString(10) << Param->getType()
|
2009-03-14 08:20:21 +08:00
|
|
|
<< Arg->getSourceRange();
|
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
}
|
2011-05-05 05:55:00 +08:00
|
|
|
|
2010-03-26 10:38:37 +08:00
|
|
|
// Complain if we overflowed the template parameter's type.
|
2009-12-24 02:44:58 +08:00
|
|
|
unsigned RequiredBits;
|
2011-05-21 00:38:50 +08:00
|
|
|
if (IntegerType->isUnsignedIntegerOrEnumerationType())
|
2010-03-26 10:38:37 +08:00
|
|
|
RequiredBits = OldValue.getActiveBits();
|
|
|
|
else if (OldValue.isUnsigned())
|
|
|
|
RequiredBits = OldValue.getActiveBits() + 1;
|
2009-12-24 02:44:58 +08:00
|
|
|
else
|
2010-03-26 10:38:37 +08:00
|
|
|
RequiredBits = OldValue.getMinSignedBits();
|
2009-12-24 02:44:58 +08:00
|
|
|
if (RequiredBits > AllowedBits) {
|
2012-03-10 02:35:03 +08:00
|
|
|
Diag(Arg->getLocStart(),
|
2010-03-26 10:38:37 +08:00
|
|
|
diag::warn_template_arg_too_large)
|
|
|
|
<< OldValue.toString(10) << Value.toString(10) << Param->getType()
|
2009-03-14 08:20:21 +08:00
|
|
|
<< Arg->getSourceRange();
|
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
}
|
|
|
|
}
|
Added ClassTemplateSpecializationDecl, which is a subclass of
CXXRecordDecl that is used to represent class template
specializations. These are canonical declarations that can refer to
either an actual class template specialization in the code, e.g.,
template<> class vector<bool> { };
or to a template instantiation. However, neither of these features is
actually implemented yet, so really we're just using (and uniqing) the
declarations to make sure that, e.g., A<int> is a different type from
A<float>. Note that we carefully distinguish between what the user
wrote in the source code (e.g., "A<FLOAT>") and the semantic entity it
represents (e.g., "A<float, int>"); the former is in the sugared Type,
the latter is an actual Decl.
llvm-svn: 64716
2009-02-17 09:05:43 +08:00
|
|
|
|
2009-10-29 16:12:44 +08:00
|
|
|
Converted = TemplateArgument(Value,
|
2011-08-09 09:55:14 +08:00
|
|
|
ParamType->isEnumeralType()
|
|
|
|
? Context.getCanonicalType(ParamType)
|
|
|
|
: IntegerType);
|
2011-04-09 02:41:53 +08:00
|
|
|
return Owned(Arg);
|
2009-02-11 07:36:10 +08:00
|
|
|
}
|
2009-02-11 08:19:33 +08:00
|
|
|
|
2011-10-28 06:11:44 +08:00
|
|
|
QualType ArgType = Arg->getType();
|
2010-03-31 05:47:33 +08:00
|
|
|
DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction
|
|
|
|
|
2009-02-11 09:18:59 +08:00
|
|
|
// Handle pointer-to-function, reference-to-function, and
|
|
|
|
// pointer-to-member-function all in (roughly) the same way.
|
|
|
|
if (// -- For a non-type template-parameter of type pointer to
|
|
|
|
// function, only the function-to-pointer conversion (4.3) is
|
|
|
|
// applied. If the template-argument represents a set of
|
|
|
|
// overloaded functions (or a pointer to such), the matching
|
|
|
|
// function is selected from the set (13.4).
|
|
|
|
(ParamType->isPointerType() &&
|
2009-07-30 05:53:49 +08:00
|
|
|
ParamType->getAs<PointerType>()->getPointeeType()->isFunctionType()) ||
|
2009-02-11 09:18:59 +08:00
|
|
|
// -- For a non-type template-parameter of type reference to
|
|
|
|
// function, no conversions apply. If the template-argument
|
|
|
|
// represents a set of overloaded functions, the matching
|
|
|
|
// function is selected from the set (13.4).
|
|
|
|
(ParamType->isReferenceType() &&
|
2009-07-30 05:53:49 +08:00
|
|
|
ParamType->getAs<ReferenceType>()->getPointeeType()->isFunctionType()) ||
|
2009-02-11 09:18:59 +08:00
|
|
|
// -- For a non-type template-parameter of type pointer to
|
|
|
|
// member function, no conversions apply. If the
|
|
|
|
// template-argument represents a set of overloaded member
|
|
|
|
// functions, the matching member function is selected from
|
|
|
|
// the set (13.4).
|
|
|
|
(ParamType->isMemberPointerType() &&
|
2009-07-30 05:53:49 +08:00
|
|
|
ParamType->getAs<MemberPointerType>()->getPointeeType()
|
2009-02-11 09:18:59 +08:00
|
|
|
->isFunctionType())) {
|
2010-04-02 02:32:35 +08:00
|
|
|
|
2010-04-15 07:11:21 +08:00
|
|
|
if (Arg->getType() == Context.OverloadTy) {
|
2011-01-27 15:10:08 +08:00
|
|
|
if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg, ParamType,
|
2010-04-15 07:11:21 +08:00
|
|
|
true,
|
|
|
|
FoundResult)) {
|
2012-03-10 02:35:03 +08:00
|
|
|
if (DiagnoseUseOfDecl(Fn, Arg->getLocStart()))
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
2009-02-19 05:56:37 +08:00
|
|
|
|
2010-04-15 07:11:21 +08:00
|
|
|
Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
|
|
|
|
ArgType = Arg->getType();
|
|
|
|
} else
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
2009-02-11 08:19:33 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-04-09 02:41:53 +08:00
|
|
|
if (!ParamType->isMemberPointerType()) {
|
|
|
|
if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
|
|
|
|
ParamType,
|
|
|
|
Arg, Converted))
|
|
|
|
return ExprError();
|
|
|
|
return Owned(Arg);
|
|
|
|
}
|
2010-04-02 02:32:35 +08:00
|
|
|
|
2012-04-11 01:08:25 +08:00
|
|
|
if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
|
|
|
|
Converted))
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
|
|
|
return Owned(Arg);
|
2009-02-11 08:19:33 +08:00
|
|
|
}
|
|
|
|
|
2009-02-21 05:37:53 +08:00
|
|
|
if (ParamType->isPointerType()) {
|
2009-02-11 09:18:59 +08:00
|
|
|
// -- for a non-type template-parameter of type pointer to
|
|
|
|
// object, qualification conversions (4.4) and the
|
|
|
|
// array-to-pointer conversion (4.2) are applied.
|
2009-05-11 02:38:11 +08:00
|
|
|
// C++0x also allows a value of std::nullptr_t.
|
2010-08-05 10:49:48 +08:00
|
|
|
assert(ParamType->getPointeeType()->isIncompleteOrObjectType() &&
|
2009-02-11 09:18:59 +08:00
|
|
|
"Only object pointers allowed here");
|
|
|
|
|
2011-04-09 02:41:53 +08:00
|
|
|
if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
|
|
|
|
ParamType,
|
|
|
|
Arg, Converted))
|
|
|
|
return ExprError();
|
|
|
|
return Owned(Arg);
|
2009-02-11 09:18:59 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-30 05:53:49 +08:00
|
|
|
if (const ReferenceType *ParamRefType = ParamType->getAs<ReferenceType>()) {
|
2009-02-11 09:18:59 +08:00
|
|
|
// -- For a non-type template-parameter of type reference to
|
|
|
|
// object, no conversions apply. The type referred to by the
|
|
|
|
// reference may be more cv-qualified than the (otherwise
|
|
|
|
// identical) type of the template-argument. The
|
|
|
|
// template-parameter is bound directly to the
|
|
|
|
// template-argument, which must be an lvalue.
|
2010-08-05 10:49:48 +08:00
|
|
|
assert(ParamRefType->getPointeeType()->isIncompleteOrObjectType() &&
|
2009-02-11 09:18:59 +08:00
|
|
|
"Only object references allowed here");
|
|
|
|
|
2010-04-15 07:11:21 +08:00
|
|
|
if (Arg->getType() == Context.OverloadTy) {
|
2011-01-27 15:10:08 +08:00
|
|
|
if (FunctionDecl *Fn = ResolveAddressOfOverloadedFunction(Arg,
|
|
|
|
ParamRefType->getPointeeType(),
|
2010-04-15 07:11:21 +08:00
|
|
|
true,
|
|
|
|
FoundResult)) {
|
2012-03-10 02:35:03 +08:00
|
|
|
if (DiagnoseUseOfDecl(Fn, Arg->getLocStart()))
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2010-04-15 07:11:21 +08:00
|
|
|
Arg = FixOverloadedFunctionReference(Arg, FoundResult, Fn);
|
|
|
|
ArgType = Arg->getType();
|
|
|
|
} else
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
2009-02-11 08:44:29 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-04-09 02:41:53 +08:00
|
|
|
if (CheckTemplateArgumentAddressOfObjectOrFunction(*this, Param,
|
|
|
|
ParamType,
|
|
|
|
Arg, Converted))
|
|
|
|
return ExprError();
|
|
|
|
return Owned(Arg);
|
2009-02-11 08:44:29 +08:00
|
|
|
}
|
2009-02-12 00:16:59 +08:00
|
|
|
|
2012-04-11 01:08:25 +08:00
|
|
|
// Deal with parameters of type std::nullptr_t.
|
|
|
|
if (ParamType->isNullPtrType()) {
|
|
|
|
if (Arg->isTypeDependent() || Arg->isValueDependent()) {
|
|
|
|
Converted = TemplateArgument(Arg);
|
|
|
|
return Owned(Arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (isNullPointerValueTemplateArgument(*this, Param, ParamType, Arg)) {
|
|
|
|
case NPV_NotNullPointer:
|
|
|
|
Diag(Arg->getExprLoc(), diag::err_template_arg_not_convertible)
|
|
|
|
<< Arg->getType() << ParamType;
|
|
|
|
Diag(Param->getLocation(), diag::note_template_param_here);
|
|
|
|
return ExprError();
|
|
|
|
|
|
|
|
case NPV_Error:
|
|
|
|
return ExprError();
|
|
|
|
|
|
|
|
case NPV_NullPointer:
|
|
|
|
Converted = TemplateArgument((Decl *)0);
|
|
|
|
return Owned(Arg);;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-02-12 00:16:59 +08:00
|
|
|
// -- For a non-type template-parameter of type pointer to data
|
|
|
|
// member, qualification conversions (4.4) are applied.
|
|
|
|
assert(ParamType->isMemberPointerType() && "Only pointers to members remain");
|
|
|
|
|
2012-04-11 01:08:25 +08:00
|
|
|
if (CheckTemplateArgumentPointerToMember(*this, Param, ParamType, Arg,
|
|
|
|
Converted))
|
2011-04-09 02:41:53 +08:00
|
|
|
return ExprError();
|
|
|
|
return Owned(Arg);
|
2009-02-10 07:23:08 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Check a template argument against its corresponding
|
|
|
|
/// template template parameter.
|
|
|
|
///
|
|
|
|
/// This routine implements the semantics of C++ [temp.arg.template].
|
|
|
|
/// It returns true if an error occurred, and false otherwise.
|
|
|
|
bool Sema::CheckTemplateArgument(TemplateTemplateParmDecl *Param,
|
2009-11-11 09:00:40 +08:00
|
|
|
const TemplateArgumentLoc &Arg) {
|
|
|
|
TemplateName Name = Arg.getArgument().getAsTemplate();
|
|
|
|
TemplateDecl *Template = Name.getAsTemplateDecl();
|
|
|
|
if (!Template) {
|
|
|
|
// Any dependent template name is fine.
|
|
|
|
assert(Name.isDependent() && "Non-dependent template isn't a declaration?");
|
|
|
|
return false;
|
|
|
|
}
|
2009-02-10 08:24:35 +08:00
|
|
|
|
2011-05-06 05:57:07 +08:00
|
|
|
// C++0x [temp.arg.template]p1:
|
2009-02-10 08:24:35 +08:00
|
|
|
// A template-argument for a template template-parameter shall be
|
2011-05-06 05:57:07 +08:00
|
|
|
// the name of a class template or an alias template, expressed as an
|
|
|
|
// id-expression. When the template-argument names a class template, only
|
2009-02-10 08:24:35 +08:00
|
|
|
// primary class templates are considered when matching the
|
|
|
|
// template template argument with the corresponding parameter;
|
|
|
|
// partial specializations are not considered even if their
|
|
|
|
// parameter lists match that of the template template parameter.
|
2009-06-13 03:43:02 +08:00
|
|
|
//
|
|
|
|
// Note that we also allow template template parameters here, which
|
|
|
|
// will happen when we are dealing with, e.g., class template
|
|
|
|
// partial specializations.
|
2009-09-09 23:08:12 +08:00
|
|
|
if (!isa<ClassTemplateDecl>(Template) &&
|
2011-05-06 05:57:07 +08:00
|
|
|
!isa<TemplateTemplateParmDecl>(Template) &&
|
|
|
|
!isa<TypeAliasTemplateDecl>(Template)) {
|
2009-09-09 23:08:12 +08:00
|
|
|
assert(isa<FunctionTemplateDecl>(Template) &&
|
2009-02-10 08:24:35 +08:00
|
|
|
"Only function templates are possible here");
|
2009-11-11 09:00:40 +08:00
|
|
|
Diag(Arg.getLocation(), diag::err_template_arg_not_class_template);
|
2009-06-26 06:08:12 +08:00
|
|
|
Diag(Template->getLocation(), diag::note_template_arg_refers_here_func)
|
2009-02-10 08:24:35 +08:00
|
|
|
<< Template;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !TemplateParameterListsAreEqual(Template->getTemplateParameters(),
|
|
|
|
Param->getTemplateParameters(),
|
2011-01-27 15:10:08 +08:00
|
|
|
true,
|
2009-11-13 00:20:59 +08:00
|
|
|
TPL_TemplateTemplateArgumentMatch,
|
2009-11-11 09:00:40 +08:00
|
|
|
Arg.getLocation());
|
2009-02-10 07:23:08 +08:00
|
|
|
}
|
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
/// \brief Given a non-type template argument that refers to a
|
|
|
|
/// declaration and the type of its corresponding non-type template
|
|
|
|
/// parameter, produce an expression that properly refers to that
|
|
|
|
/// declaration.
|
2011-01-27 15:10:08 +08:00
|
|
|
ExprResult
|
2010-03-28 10:42:43 +08:00
|
|
|
Sema::BuildExpressionFromDeclTemplateArgument(const TemplateArgument &Arg,
|
|
|
|
QualType ParamType,
|
|
|
|
SourceLocation Loc) {
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Declaration &&
|
|
|
|
"Only declaration template arguments permitted here");
|
2012-04-07 06:40:38 +08:00
|
|
|
|
|
|
|
// For a NULL non-type template argument, return nullptr casted to the
|
|
|
|
// parameter's type.
|
|
|
|
if (!Arg.getAsDecl()) {
|
|
|
|
return ImpCastExprToType(
|
|
|
|
new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc),
|
|
|
|
ParamType,
|
|
|
|
ParamType->getAs<MemberPointerType>()
|
|
|
|
? CK_NullToMemberPointer
|
|
|
|
: CK_NullToPointer);
|
|
|
|
}
|
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
ValueDecl *VD = cast<ValueDecl>(Arg.getAsDecl());
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
if (VD->getDeclContext()->isRecord() &&
|
2010-03-28 10:42:43 +08:00
|
|
|
(isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD))) {
|
|
|
|
// If the value is a class member, we might have a pointer-to-member.
|
|
|
|
// Determine whether the non-type template template parameter is of
|
|
|
|
// pointer-to-member type. If so, we need to build an appropriate
|
|
|
|
// expression for a pointer-to-member, since a "normal" DeclRefExpr
|
|
|
|
// would refer to the member itself.
|
|
|
|
if (ParamType->isMemberPointerType()) {
|
|
|
|
QualType ClassType
|
|
|
|
= Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext()));
|
|
|
|
NestedNameSpecifier *Qualifier
|
2010-08-24 07:25:46 +08:00
|
|
|
= NestedNameSpecifier::Create(Context, 0, false,
|
|
|
|
ClassType.getTypePtr());
|
2010-03-28 10:42:43 +08:00
|
|
|
CXXScopeSpec SS;
|
2011-02-25 01:54:50 +08:00
|
|
|
SS.MakeTrivial(Context, Qualifier, Loc);
|
2010-11-24 04:48:44 +08:00
|
|
|
|
|
|
|
// The actual value-ness of this is unimportant, but for
|
|
|
|
// internal consistency's sake, references to instance methods
|
|
|
|
// are r-values.
|
|
|
|
ExprValueKind VK = VK_LValue;
|
|
|
|
if (isa<CXXMethodDecl>(VD) && cast<CXXMethodDecl>(VD)->isInstance())
|
|
|
|
VK = VK_RValue;
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
ExprResult RefExpr = BuildDeclRefExpr(VD,
|
2010-11-18 14:31:45 +08:00
|
|
|
VD->getType().getNonReferenceType(),
|
2010-11-24 04:48:44 +08:00
|
|
|
VK,
|
2010-11-18 14:31:45 +08:00
|
|
|
Loc,
|
|
|
|
&SS);
|
2010-03-28 10:42:43 +08:00
|
|
|
if (RefExpr.isInvalid())
|
|
|
|
return ExprError();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-25 19:45:40 +08:00
|
|
|
RefExpr = CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-05-01 05:46:38 +08:00
|
|
|
// We might need to perform a trailing qualification conversion, since
|
|
|
|
// the element type on the parameter could be more qualified than the
|
|
|
|
// element type in the expression we constructed.
|
2011-06-16 07:02:42 +08:00
|
|
|
bool ObjCLifetimeConversion;
|
2010-05-01 05:46:38 +08:00
|
|
|
if (IsQualificationConversion(((Expr*) RefExpr.get())->getType(),
|
2011-06-16 07:02:42 +08:00
|
|
|
ParamType.getUnqualifiedType(), false,
|
|
|
|
ObjCLifetimeConversion))
|
2011-04-09 02:41:53 +08:00
|
|
|
RefExpr = ImpCastExprToType(RefExpr.take(), ParamType.getUnqualifiedType(), CK_NoOp);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
assert(!RefExpr.isInvalid() &&
|
|
|
|
Context.hasSameType(((Expr*) RefExpr.get())->getType(),
|
2010-05-01 05:46:38 +08:00
|
|
|
ParamType.getUnqualifiedType()));
|
2010-03-28 10:42:43 +08:00
|
|
|
return move(RefExpr);
|
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
QualType T = VD->getType().getNonReferenceType();
|
|
|
|
if (ParamType->isPointerType()) {
|
2010-04-02 02:32:35 +08:00
|
|
|
// When the non-type template parameter is a pointer, take the
|
|
|
|
// address of the declaration.
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprResult RefExpr = BuildDeclRefExpr(VD, T, VK_LValue, Loc);
|
2010-03-28 10:42:43 +08:00
|
|
|
if (RefExpr.isInvalid())
|
|
|
|
return ExprError();
|
2010-04-02 02:32:35 +08:00
|
|
|
|
|
|
|
if (T->isFunctionType() || T->isArrayType()) {
|
|
|
|
// Decay functions and arrays.
|
2011-04-09 02:41:53 +08:00
|
|
|
RefExpr = DefaultFunctionArrayConversion(RefExpr.take());
|
|
|
|
if (RefExpr.isInvalid())
|
|
|
|
return ExprError();
|
2010-04-02 02:32:35 +08:00
|
|
|
|
|
|
|
return move(RefExpr);
|
2010-03-28 10:42:43 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-04-02 02:32:35 +08:00
|
|
|
// Take the address of everything else
|
2010-08-25 19:45:40 +08:00
|
|
|
return CreateBuiltinUnaryOp(Loc, UO_AddrOf, RefExpr.get());
|
2010-03-28 10:42:43 +08:00
|
|
|
}
|
|
|
|
|
2010-11-18 14:31:45 +08:00
|
|
|
ExprValueKind VK = VK_RValue;
|
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
// If the non-type template parameter has reference type, qualify the
|
|
|
|
// resulting declaration reference with the extra qualifiers on the
|
|
|
|
// type that the reference refers to.
|
2010-11-18 14:31:45 +08:00
|
|
|
if (const ReferenceType *TargetRef = ParamType->getAs<ReferenceType>()) {
|
|
|
|
VK = VK_LValue;
|
|
|
|
T = Context.getQualifiedType(T,
|
|
|
|
TargetRef->getPointeeType().getQualifiers());
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-11-18 14:31:45 +08:00
|
|
|
return BuildDeclRefExpr(VD, T, VK, Loc);
|
2010-03-28 10:42:43 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Construct a new expression that refers to the given
|
|
|
|
/// integral template argument with the given source-location
|
|
|
|
/// information.
|
|
|
|
///
|
|
|
|
/// This routine takes care of the mapping from an integral template
|
|
|
|
/// argument (which may have any integral type) to the appropriate
|
|
|
|
/// literal value.
|
2011-01-27 15:10:08 +08:00
|
|
|
ExprResult
|
2010-03-28 10:42:43 +08:00
|
|
|
Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,
|
|
|
|
SourceLocation Loc) {
|
|
|
|
assert(Arg.getKind() == TemplateArgument::Integral &&
|
Work-in-progress implementation of C++0x [temp.arg.explicit]p9, which
allows an argument pack determines via explicit specification of
function template arguments to be extended by further, deduced
arguments. For example:
template<class ... Types> void f(Types ... values);
void g() {
f<int*, float*>(0, 0, 0); // Types is deduced to the sequence int*, float*, int
}
There are a number of FIXMEs in here that indicate places where we
need to implement + test retained expansions, plus a number of other
places in deduction where we need to correctly cope with the
explicitly-specified arguments when deducing an argument
pack. Furthermore, it appears that the RecursiveASTVisitor needs to be
auditied; it's missing some traversals (especially w.r.t. template
arguments) that cause it not to find unexpanded parameter packs when
it should.
The good news, however, is that the tr1::tuple implementation now
works fully, and the tr1::bind example (both from N2080) is actually
working now.
llvm-svn: 123163
2011-01-10 15:32:04 +08:00
|
|
|
"Operation is only valid for integral template arguments");
|
2010-03-28 10:42:43 +08:00
|
|
|
QualType T = Arg.getIntegralType();
|
2011-07-27 13:40:30 +08:00
|
|
|
if (T->isAnyCharacterType()) {
|
|
|
|
CharacterLiteral::CharacterKind Kind;
|
|
|
|
if (T->isWideCharType())
|
|
|
|
Kind = CharacterLiteral::Wide;
|
|
|
|
else if (T->isChar16Type())
|
|
|
|
Kind = CharacterLiteral::UTF16;
|
|
|
|
else if (T->isChar32Type())
|
|
|
|
Kind = CharacterLiteral::UTF32;
|
|
|
|
else
|
|
|
|
Kind = CharacterLiteral::Ascii;
|
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
return Owned(new (Context) CharacterLiteral(
|
2011-07-27 13:40:30 +08:00
|
|
|
Arg.getAsIntegral()->getZExtValue(),
|
|
|
|
Kind, T, Loc));
|
|
|
|
}
|
|
|
|
|
2010-03-28 10:42:43 +08:00
|
|
|
if (T->isBooleanType())
|
|
|
|
return Owned(new (Context) CXXBoolLiteralExpr(
|
|
|
|
Arg.getAsIntegral()->getBoolValue(),
|
2011-04-26 04:37:58 +08:00
|
|
|
T, Loc));
|
2010-03-28 10:42:43 +08:00
|
|
|
|
2011-05-22 07:15:46 +08:00
|
|
|
if (T->isNullPtrType())
|
|
|
|
return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc));
|
|
|
|
|
2011-04-26 04:37:58 +08:00
|
|
|
// If this is an enum type that we're instantiating, we need to use an integer
|
|
|
|
// type the same size as the enumerator. We don't want to build an
|
|
|
|
// IntegerLiteral with enum type.
|
2010-12-15 23:06:14 +08:00
|
|
|
QualType BT;
|
|
|
|
if (const EnumType *ET = T->getAs<EnumType>())
|
2011-04-26 04:37:58 +08:00
|
|
|
BT = ET->getDecl()->getIntegerType();
|
2010-12-15 23:06:14 +08:00
|
|
|
else
|
|
|
|
BT = T;
|
|
|
|
|
2011-07-15 15:47:58 +08:00
|
|
|
Expr *E = IntegerLiteral::Create(Context, *Arg.getAsIntegral(), BT, Loc);
|
|
|
|
if (T->isEnumeralType()) {
|
|
|
|
// FIXME: This is a hack. We need a better way to handle substituted
|
|
|
|
// non-type template parameters.
|
|
|
|
E = CStyleCastExpr::Create(Context, T, VK_RValue, CK_IntegralCast, E, 0,
|
|
|
|
Context.getTrivialTypeSourceInfo(T, Loc),
|
|
|
|
Loc, Loc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return Owned(E);
|
2010-03-28 10:42:43 +08:00
|
|
|
}
|
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
/// \brief Match two template parameters within template parameter lists.
|
|
|
|
static bool MatchTemplateParameterKind(Sema &S, NamedDecl *New, NamedDecl *Old,
|
|
|
|
bool Complain,
|
|
|
|
Sema::TemplateParameterListEqualKind Kind,
|
|
|
|
SourceLocation TemplateArgLoc) {
|
|
|
|
// Check the actual kind (type, non-type, template).
|
|
|
|
if (Old->getKind() != New->getKind()) {
|
|
|
|
if (Complain) {
|
|
|
|
unsigned NextDiag = diag::err_template_param_different_kind;
|
|
|
|
if (TemplateArgLoc.isValid()) {
|
|
|
|
S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
|
|
|
|
NextDiag = diag::note_template_param_different_kind;
|
|
|
|
}
|
|
|
|
S.Diag(New->getLocation(), NextDiag)
|
|
|
|
<< (Kind != Sema::TPL_TemplateMatch);
|
|
|
|
S.Diag(Old->getLocation(), diag::note_template_prev_declaration)
|
|
|
|
<< (Kind != Sema::TPL_TemplateMatch);
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
// Check that both are parameter packs are neither are parameter packs.
|
|
|
|
// However, if we are matching a template template argument to a
|
2011-01-13 08:08:50 +08:00
|
|
|
// template template parameter, the template template parameter can have
|
|
|
|
// a parameter pack where the template template argument does not.
|
|
|
|
if (Old->isTemplateParameterPack() != New->isTemplateParameterPack() &&
|
|
|
|
!(Kind == Sema::TPL_TemplateTemplateArgumentMatch &&
|
|
|
|
Old->isTemplateParameterPack())) {
|
2011-01-13 07:45:44 +08:00
|
|
|
if (Complain) {
|
|
|
|
unsigned NextDiag = diag::err_template_parameter_pack_non_pack;
|
|
|
|
if (TemplateArgLoc.isValid()) {
|
|
|
|
S.Diag(TemplateArgLoc,
|
|
|
|
diag::err_template_arg_template_params_mismatch);
|
|
|
|
NextDiag = diag::note_template_parameter_pack_non_pack;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
unsigned ParamKind = isa<TemplateTypeParmDecl>(New)? 0
|
|
|
|
: isa<NonTypeTemplateParmDecl>(New)? 1
|
|
|
|
: 2;
|
|
|
|
S.Diag(New->getLocation(), NextDiag)
|
|
|
|
<< ParamKind << New->isParameterPack();
|
|
|
|
S.Diag(Old->getLocation(), diag::note_template_parameter_pack_here)
|
|
|
|
<< ParamKind << Old->isParameterPack();
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
// For non-type template parameters, check the type of the parameter.
|
|
|
|
if (NonTypeTemplateParmDecl *OldNTTP
|
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(Old)) {
|
|
|
|
NonTypeTemplateParmDecl *NewNTTP = cast<NonTypeTemplateParmDecl>(New);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
// If we are matching a template template argument to a template
|
|
|
|
// template parameter and one of the non-type template parameter types
|
|
|
|
// is dependent, then we must wait until template instantiation time
|
|
|
|
// to actually compare the arguments.
|
|
|
|
if (Kind == Sema::TPL_TemplateTemplateArgumentMatch &&
|
|
|
|
(OldNTTP->getType()->isDependentType() ||
|
|
|
|
NewNTTP->getType()->isDependentType()))
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
if (!S.Context.hasSameType(OldNTTP->getType(), NewNTTP->getType())) {
|
|
|
|
if (Complain) {
|
|
|
|
unsigned NextDiag = diag::err_template_nontype_parm_different_type;
|
|
|
|
if (TemplateArgLoc.isValid()) {
|
2011-01-27 15:10:08 +08:00
|
|
|
S.Diag(TemplateArgLoc,
|
2011-01-13 07:45:44 +08:00
|
|
|
diag::err_template_arg_template_params_mismatch);
|
|
|
|
NextDiag = diag::note_template_nontype_parm_different_type;
|
|
|
|
}
|
|
|
|
S.Diag(NewNTTP->getLocation(), NextDiag)
|
|
|
|
<< NewNTTP->getType()
|
|
|
|
<< (Kind != Sema::TPL_TemplateMatch);
|
|
|
|
S.Diag(OldNTTP->getLocation(),
|
|
|
|
diag::note_template_nontype_parm_prev_declaration)
|
|
|
|
<< OldNTTP->getType();
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
// For template template parameters, check the template parameter types.
|
|
|
|
// The template parameter lists of template template
|
|
|
|
// parameters must agree.
|
|
|
|
if (TemplateTemplateParmDecl *OldTTP
|
|
|
|
= dyn_cast<TemplateTemplateParmDecl>(Old)) {
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateTemplateParmDecl *NewTTP = cast<TemplateTemplateParmDecl>(New);
|
2011-01-13 07:45:44 +08:00
|
|
|
return S.TemplateParameterListsAreEqual(NewTTP->getTemplateParameters(),
|
|
|
|
OldTTP->getTemplateParameters(),
|
|
|
|
Complain,
|
|
|
|
(Kind == Sema::TPL_TemplateMatch
|
2011-01-27 15:10:08 +08:00
|
|
|
? Sema::TPL_TemplateTemplateParmMatch
|
2011-01-13 07:45:44 +08:00
|
|
|
: Kind),
|
|
|
|
TemplateArgLoc);
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
return true;
|
|
|
|
}
|
2010-03-28 10:42:43 +08:00
|
|
|
|
2011-01-13 08:08:50 +08:00
|
|
|
/// \brief Diagnose a known arity mismatch when comparing template argument
|
|
|
|
/// lists.
|
|
|
|
static
|
2011-01-27 15:10:08 +08:00
|
|
|
void DiagnoseTemplateParameterListArityMismatch(Sema &S,
|
2011-01-13 08:08:50 +08:00
|
|
|
TemplateParameterList *New,
|
|
|
|
TemplateParameterList *Old,
|
|
|
|
Sema::TemplateParameterListEqualKind Kind,
|
|
|
|
SourceLocation TemplateArgLoc) {
|
|
|
|
unsigned NextDiag = diag::err_template_param_list_different_arity;
|
|
|
|
if (TemplateArgLoc.isValid()) {
|
|
|
|
S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
|
|
|
|
NextDiag = diag::note_template_param_list_different_arity;
|
|
|
|
}
|
|
|
|
S.Diag(New->getTemplateLoc(), NextDiag)
|
|
|
|
<< (New->size() > Old->size())
|
|
|
|
<< (Kind != Sema::TPL_TemplateMatch)
|
|
|
|
<< SourceRange(New->getTemplateLoc(), New->getRAngleLoc());
|
|
|
|
S.Diag(Old->getTemplateLoc(), diag::note_template_prev_declaration)
|
|
|
|
<< (Kind != Sema::TPL_TemplateMatch)
|
|
|
|
<< SourceRange(Old->getTemplateLoc(), Old->getRAngleLoc());
|
|
|
|
}
|
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
/// \brief Determine whether the given template parameter lists are
|
|
|
|
/// equivalent.
|
|
|
|
///
|
2009-09-09 23:08:12 +08:00
|
|
|
/// \param New The new template parameter list, typically written in the
|
2009-02-07 06:42:48 +08:00
|
|
|
/// source code as part of a new template declaration.
|
|
|
|
///
|
|
|
|
/// \param Old The old template parameter list, typically found via
|
|
|
|
/// name lookup of the template declared with this template parameter
|
|
|
|
/// list.
|
|
|
|
///
|
|
|
|
/// \param Complain If true, this routine will produce a diagnostic if
|
|
|
|
/// the template parameter lists are not equivalent.
|
|
|
|
///
|
2009-11-13 00:20:59 +08:00
|
|
|
/// \param Kind describes how we are to match the template parameter lists.
|
2009-02-10 08:24:35 +08:00
|
|
|
///
|
|
|
|
/// \param TemplateArgLoc If this source location is valid, then we
|
|
|
|
/// are actually checking the template parameter list of a template
|
|
|
|
/// argument (New) against the template parameter list of its
|
|
|
|
/// corresponding template template parameter (Old). We produce
|
|
|
|
/// slightly different diagnostics in this scenario.
|
|
|
|
///
|
2009-02-07 06:42:48 +08:00
|
|
|
/// \returns True if the template parameter lists are equal, false
|
|
|
|
/// otherwise.
|
2009-09-09 23:08:12 +08:00
|
|
|
bool
|
2009-02-07 06:42:48 +08:00
|
|
|
Sema::TemplateParameterListsAreEqual(TemplateParameterList *New,
|
|
|
|
TemplateParameterList *Old,
|
|
|
|
bool Complain,
|
2009-11-13 00:20:59 +08:00
|
|
|
TemplateParameterListEqualKind Kind,
|
2009-02-10 08:24:35 +08:00
|
|
|
SourceLocation TemplateArgLoc) {
|
2011-01-13 08:08:50 +08:00
|
|
|
if (Old->size() != New->size() && Kind != TPL_TemplateTemplateArgumentMatch) {
|
|
|
|
if (Complain)
|
|
|
|
DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
|
|
|
|
TemplateArgLoc);
|
2009-02-07 06:42:48 +08:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2011-01-13 07:45:44 +08:00
|
|
|
// C++0x [temp.arg.template]p3:
|
|
|
|
// A template-argument matches a template template-parameter (call it P)
|
2011-01-27 15:09:49 +08:00
|
|
|
// when each of the template parameters in the template-parameter-list of
|
2011-05-06 05:57:07 +08:00
|
|
|
// the template-argument's corresponding class template or alias template
|
2011-01-27 15:09:49 +08:00
|
|
|
// (call it A) matches the corresponding template parameter in the
|
2011-01-13 08:08:50 +08:00
|
|
|
// template-parameter-list of P. [...]
|
|
|
|
TemplateParameterList::iterator NewParm = New->begin();
|
|
|
|
TemplateParameterList::iterator NewParmEnd = New->end();
|
2009-02-07 06:42:48 +08:00
|
|
|
for (TemplateParameterList::iterator OldParm = Old->begin(),
|
2011-01-13 08:08:50 +08:00
|
|
|
OldParmEnd = Old->end();
|
|
|
|
OldParm != OldParmEnd; ++OldParm) {
|
2011-01-14 02:47:47 +08:00
|
|
|
if (Kind != TPL_TemplateTemplateArgumentMatch ||
|
|
|
|
!(*OldParm)->isTemplateParameterPack()) {
|
2011-01-13 08:08:50 +08:00
|
|
|
if (NewParm == NewParmEnd) {
|
|
|
|
if (Complain)
|
|
|
|
DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
|
|
|
|
TemplateArgLoc);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 08:08:50 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 08:08:50 +08:00
|
|
|
if (!MatchTemplateParameterKind(*this, *NewParm, *OldParm, Complain,
|
|
|
|
Kind, TemplateArgLoc))
|
2011-01-27 15:10:08 +08:00
|
|
|
return false;
|
|
|
|
|
2011-01-13 08:08:50 +08:00
|
|
|
++NewParm;
|
|
|
|
continue;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 08:08:50 +08:00
|
|
|
// C++0x [temp.arg.template]p3:
|
2011-01-27 15:09:49 +08:00
|
|
|
// [...] When P's template- parameter-list contains a template parameter
|
|
|
|
// pack (14.5.3), the template parameter pack will match zero or more
|
|
|
|
// template parameters or template parameter packs in the
|
2011-01-13 08:08:50 +08:00
|
|
|
// template-parameter-list of A with the same type and form as the
|
|
|
|
// template parameter pack in P (ignoring whether those template
|
|
|
|
// parameters are template parameter packs).
|
|
|
|
for (; NewParm != NewParmEnd; ++NewParm) {
|
|
|
|
if (!MatchTemplateParameterKind(*this, *NewParm, *OldParm, Complain,
|
|
|
|
Kind, TemplateArgLoc))
|
2011-01-27 15:10:08 +08:00
|
|
|
return false;
|
2011-01-13 08:08:50 +08:00
|
|
|
}
|
2009-02-07 06:42:48 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 08:08:50 +08:00
|
|
|
// Make sure we exhausted all of the arguments.
|
|
|
|
if (NewParm != NewParmEnd) {
|
|
|
|
if (Complain)
|
|
|
|
DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
|
|
|
|
TemplateArgLoc);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-13 08:08:50 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Check whether a template can be declared within this scope.
|
|
|
|
///
|
|
|
|
/// If the template declaration is valid in this scope, returns
|
|
|
|
/// false. Otherwise, issues a diagnostic and returns true.
|
2009-09-09 23:08:12 +08:00
|
|
|
bool
|
2009-08-26 01:23:04 +08:00
|
|
|
Sema::CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams) {
|
2011-11-04 00:37:14 +08:00
|
|
|
if (!S)
|
|
|
|
return false;
|
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
// Find the nearest enclosing declaration scope.
|
|
|
|
while ((S->getFlags() & Scope::DeclScope) == 0 ||
|
|
|
|
(S->getFlags() & Scope::TemplateParamScope) != 0)
|
|
|
|
S = S->getParent();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-02-07 06:42:48 +08:00
|
|
|
// C++ [temp]p2:
|
|
|
|
// A template-declaration can appear only as a namespace scope or
|
|
|
|
// class scope declaration.
|
|
|
|
DeclContext *Ctx = static_cast<DeclContext *>(S->getEntity());
|
2009-07-31 09:43:05 +08:00
|
|
|
if (Ctx && isa<LinkageSpecDecl>(Ctx) &&
|
|
|
|
cast<LinkageSpecDecl>(Ctx)->getLanguage() != LinkageSpecDecl::lang_cxx)
|
2009-09-09 23:08:12 +08:00
|
|
|
return Diag(TemplateParams->getTemplateLoc(), diag::err_template_linkage)
|
2009-08-26 01:23:04 +08:00
|
|
|
<< TemplateParams->getSourceRange();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-07-31 09:43:05 +08:00
|
|
|
while (Ctx && isa<LinkageSpecDecl>(Ctx))
|
2009-02-07 06:42:48 +08:00
|
|
|
Ctx = Ctx->getParent();
|
|
|
|
|
|
|
|
if (Ctx && (Ctx->isFileContext() || Ctx->isRecord()))
|
|
|
|
return false;
|
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
return Diag(TemplateParams->getTemplateLoc(),
|
2009-08-26 01:23:04 +08:00
|
|
|
diag::err_template_outside_namespace_or_class_scope)
|
|
|
|
<< TemplateParams->getSourceRange();
|
2009-02-07 06:42:48 +08:00
|
|
|
}
|
2009-02-18 07:15:12 +08:00
|
|
|
|
2009-10-07 08:13:32 +08:00
|
|
|
/// \brief Determine what kind of template specialization the given declaration
|
|
|
|
/// is.
|
2012-01-14 23:55:47 +08:00
|
|
|
static TemplateSpecializationKind getTemplateSpecializationKind(Decl *D) {
|
2009-10-07 08:13:32 +08:00
|
|
|
if (!D)
|
|
|
|
return TSK_Undeclared;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 23:14:33 +08:00
|
|
|
if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(D))
|
|
|
|
return Record->getTemplateSpecializationKind();
|
2009-10-07 08:13:32 +08:00
|
|
|
if (FunctionDecl *Function = dyn_cast<FunctionDecl>(D))
|
|
|
|
return Function->getTemplateSpecializationKind();
|
2009-10-08 15:24:58 +08:00
|
|
|
if (VarDecl *Var = dyn_cast<VarDecl>(D))
|
|
|
|
return Var->getTemplateSpecializationKind();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-07 08:13:32 +08:00
|
|
|
return TSK_Undeclared;
|
|
|
|
}
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \brief Check whether a specialization is well-formed in the current
|
2009-10-15 07:50:59 +08:00
|
|
|
/// context.
|
2009-02-26 06:02:03 +08:00
|
|
|
///
|
2009-10-15 07:50:59 +08:00
|
|
|
/// This routine determines whether a template specialization can be declared
|
|
|
|
/// in the current context (C++ [temp.expl.spec]p2).
|
2009-10-07 08:13:32 +08:00
|
|
|
///
|
|
|
|
/// \param S the semantic analysis object for which this check is being
|
|
|
|
/// performed.
|
|
|
|
///
|
|
|
|
/// \param Specialized the entity being specialized or instantiated, which
|
|
|
|
/// may be a kind of template (class template, function template, etc.) or
|
2011-01-27 15:10:08 +08:00
|
|
|
/// a member of a class template (member function, static data member,
|
2009-10-07 08:13:32 +08:00
|
|
|
/// member class).
|
|
|
|
///
|
|
|
|
/// \param PrevDecl the previous declaration of this entity, if any.
|
|
|
|
///
|
|
|
|
/// \param Loc the location of the explicit specialization or instantiation of
|
|
|
|
/// this entity.
|
|
|
|
///
|
|
|
|
/// \param IsPartialSpecialization whether this is a partial specialization of
|
|
|
|
/// a class template.
|
|
|
|
///
|
|
|
|
/// \returns true if there was an error that we cannot recover from, false
|
|
|
|
/// otherwise.
|
|
|
|
static bool CheckTemplateSpecializationScope(Sema &S,
|
|
|
|
NamedDecl *Specialized,
|
|
|
|
NamedDecl *PrevDecl,
|
|
|
|
SourceLocation Loc,
|
2009-10-15 07:50:59 +08:00
|
|
|
bool IsPartialSpecialization) {
|
2009-10-07 08:13:32 +08:00
|
|
|
// Keep these "kind" numbers in sync with the %select statements in the
|
|
|
|
// various diagnostics emitted by this routine.
|
|
|
|
int EntityKind = 0;
|
2011-01-15 06:31:36 +08:00
|
|
|
if (isa<ClassTemplateDecl>(Specialized))
|
2009-10-07 08:13:32 +08:00
|
|
|
EntityKind = IsPartialSpecialization? 1 : 0;
|
2011-01-15 06:31:36 +08:00
|
|
|
else if (isa<FunctionTemplateDecl>(Specialized))
|
2009-10-07 08:13:32 +08:00
|
|
|
EntityKind = 2;
|
2011-01-15 06:31:36 +08:00
|
|
|
else if (isa<CXXMethodDecl>(Specialized))
|
2009-10-07 08:13:32 +08:00
|
|
|
EntityKind = 3;
|
|
|
|
else if (isa<VarDecl>(Specialized))
|
|
|
|
EntityKind = 4;
|
|
|
|
else if (isa<RecordDecl>(Specialized))
|
|
|
|
EntityKind = 5;
|
2012-03-23 11:33:32 +08:00
|
|
|
else if (isa<EnumDecl>(Specialized) && S.getLangOpts().CPlusPlus0x)
|
|
|
|
EntityKind = 6;
|
2009-10-07 08:13:32 +08:00
|
|
|
else {
|
2012-03-23 11:33:32 +08:00
|
|
|
S.Diag(Loc, diag::err_template_spec_unknown_kind)
|
|
|
|
<< S.getLangOpts().CPlusPlus0x;
|
2009-10-15 07:50:59 +08:00
|
|
|
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
|
2009-10-07 08:13:32 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-02-26 06:02:03 +08:00
|
|
|
// C++ [temp.expl.spec]p2:
|
|
|
|
// An explicit specialization shall be declared in the namespace
|
|
|
|
// of which the template is a member, or, for member templates, in
|
|
|
|
// the namespace of which the enclosing class or enclosing class
|
|
|
|
// template is a member. An explicit specialization of a member
|
|
|
|
// function, member class or static data member of a class
|
|
|
|
// template shall be declared in the namespace of which the class
|
|
|
|
// template is a member. Such a declaration may also be a
|
|
|
|
// definition. If the declaration is not a definition, the
|
|
|
|
// specialization may be defined later in the name- space in which
|
|
|
|
// the explicit specialization was declared, or in a namespace
|
|
|
|
// that encloses the one in which the explicit specialization was
|
|
|
|
// declared.
|
2010-08-31 08:36:30 +08:00
|
|
|
if (S.CurContext->getRedeclContext()->isFunctionOrMethod()) {
|
2009-10-07 08:13:32 +08:00
|
|
|
S.Diag(Loc, diag::err_template_spec_decl_function_scope)
|
2009-10-15 07:50:59 +08:00
|
|
|
<< Specialized;
|
2009-02-26 06:02:03 +08:00
|
|
|
return true;
|
|
|
|
}
|
2009-10-08 01:21:34 +08:00
|
|
|
|
2009-10-08 01:30:37 +08:00
|
|
|
if (S.CurContext->isRecord() && !IsPartialSpecialization) {
|
2012-03-11 15:00:24 +08:00
|
|
|
if (S.getLangOpts().MicrosoftExt) {
|
2011-08-14 11:52:19 +08:00
|
|
|
// Do not warn for class scope explicit specialization during
|
|
|
|
// instantiation, warning was already emitted during pattern
|
|
|
|
// semantic analysis.
|
|
|
|
if (!S.ActiveTemplateInstantiations.size())
|
|
|
|
S.Diag(Loc, diag::ext_function_specialization_in_class)
|
|
|
|
<< Specialized;
|
|
|
|
} else {
|
|
|
|
S.Diag(Loc, diag::err_template_spec_decl_class_scope)
|
|
|
|
<< Specialized;
|
|
|
|
return true;
|
|
|
|
}
|
2009-10-08 01:30:37 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-10-21 00:41:18 +08:00
|
|
|
if (S.CurContext->isRecord() &&
|
|
|
|
!S.CurContext->Equals(Specialized->getDeclContext())) {
|
|
|
|
// Make sure that we're specializing in the right record context.
|
|
|
|
// Otherwise, things can go horribly wrong.
|
|
|
|
S.Diag(Loc, diag::err_template_spec_decl_class_scope)
|
|
|
|
<< Specialized;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-10-08 01:21:34 +08:00
|
|
|
// C++ [temp.class.spec]p6:
|
|
|
|
// A class template partial specialization may be declared or redeclared
|
2011-01-27 15:10:08 +08:00
|
|
|
// in any namespace scope in which its definition may be defined (14.5.1
|
|
|
|
// and 14.5.2).
|
2009-10-07 08:13:32 +08:00
|
|
|
bool ComplainedAboutScope = false;
|
2011-10-21 00:41:18 +08:00
|
|
|
DeclContext *SpecializedContext
|
2009-10-07 08:13:32 +08:00
|
|
|
= Specialized->getDeclContext()->getEnclosingNamespaceContext();
|
2009-10-08 01:21:34 +08:00
|
|
|
DeclContext *DC = S.CurContext->getEnclosingNamespaceContext();
|
2011-01-27 15:10:08 +08:00
|
|
|
if ((!PrevDecl ||
|
2009-10-15 07:50:59 +08:00
|
|
|
getTemplateSpecializationKind(PrevDecl) == TSK_Undeclared ||
|
|
|
|
getTemplateSpecializationKind(PrevDecl) == TSK_ImplicitInstantiation)){
|
2010-09-12 13:08:28 +08:00
|
|
|
// C++ [temp.exp.spec]p2:
|
|
|
|
// An explicit specialization shall be declared in the namespace of which
|
2011-01-27 15:10:08 +08:00
|
|
|
// the template is a member, or, for member templates, in the namespace
|
2010-09-12 13:08:28 +08:00
|
|
|
// of which the enclosing class or enclosing class template is a member.
|
2011-01-27 15:10:08 +08:00
|
|
|
// An explicit specialization of a member function, member class or
|
|
|
|
// static data member of a class template shall be declared in the
|
2010-09-12 13:08:28 +08:00
|
|
|
// namespace of which the class template is a member.
|
|
|
|
//
|
|
|
|
// C++0x [temp.expl.spec]p2:
|
2011-01-27 15:10:08 +08:00
|
|
|
// An explicit specialization shall be declared in a namespace enclosing
|
2010-09-12 13:08:28 +08:00
|
|
|
// the specialized template.
|
2011-10-19 04:49:44 +08:00
|
|
|
if (!DC->InEnclosingNamespaceSetOf(SpecializedContext)) {
|
|
|
|
bool IsCPlusPlus0xExtension = DC->Encloses(SpecializedContext);
|
|
|
|
if (isa<TranslationUnitDecl>(SpecializedContext)) {
|
|
|
|
assert(!IsCPlusPlus0xExtension &&
|
|
|
|
"DC encloses TU but isn't in enclosing namespace set");
|
|
|
|
S.Diag(Loc, diag::err_template_spec_decl_out_of_scope_global)
|
2010-09-12 13:24:55 +08:00
|
|
|
<< EntityKind << Specialized;
|
2011-10-19 04:49:44 +08:00
|
|
|
} else if (isa<NamespaceDecl>(SpecializedContext)) {
|
|
|
|
int Diag;
|
|
|
|
if (!IsCPlusPlus0xExtension)
|
|
|
|
Diag = diag::err_template_spec_decl_out_of_scope;
|
2012-03-11 15:00:24 +08:00
|
|
|
else if (!S.getLangOpts().CPlusPlus0x)
|
2011-10-19 04:49:44 +08:00
|
|
|
Diag = diag::ext_template_spec_decl_out_of_scope;
|
|
|
|
else
|
|
|
|
Diag = diag::warn_cxx98_compat_template_spec_decl_out_of_scope;
|
|
|
|
S.Diag(Loc, Diag)
|
|
|
|
<< EntityKind << Specialized << cast<NamedDecl>(SpecializedContext);
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:50:59 +08:00
|
|
|
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
|
2011-10-19 04:49:44 +08:00
|
|
|
ComplainedAboutScope =
|
2012-03-11 15:00:24 +08:00
|
|
|
!(IsCPlusPlus0xExtension && S.getLangOpts().CPlusPlus0x);
|
2009-02-26 06:02:03 +08:00
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
|
|
|
// Make sure that this redeclaration (or definition) occurs in an enclosing
|
2009-10-15 07:50:59 +08:00
|
|
|
// namespace.
|
2011-01-27 15:10:08 +08:00
|
|
|
// Note that HandleDeclarator() performs this check for explicit
|
2009-10-07 08:13:32 +08:00
|
|
|
// specializations of function templates, static data members, and member
|
|
|
|
// functions, so we skip the check here for those kinds of entities.
|
|
|
|
// FIXME: HandleDeclarator's diagnostics aren't quite as good, though.
|
2009-10-08 01:21:34 +08:00
|
|
|
// Should we refactor that check, so that it occurs later?
|
|
|
|
if (!ComplainedAboutScope && !DC->Encloses(SpecializedContext) &&
|
2009-10-15 07:50:59 +08:00
|
|
|
!(isa<FunctionTemplateDecl>(Specialized) || isa<VarDecl>(Specialized) ||
|
|
|
|
isa<FunctionDecl>(Specialized))) {
|
2009-10-07 08:13:32 +08:00
|
|
|
if (isa<TranslationUnitDecl>(SpecializedContext))
|
|
|
|
S.Diag(Loc, diag::err_template_spec_redecl_global_scope)
|
|
|
|
<< EntityKind << Specialized;
|
|
|
|
else if (isa<NamespaceDecl>(SpecializedContext))
|
|
|
|
S.Diag(Loc, diag::err_template_spec_redecl_out_of_scope)
|
|
|
|
<< EntityKind << Specialized
|
|
|
|
<< cast<NamedDecl>(SpecializedContext);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:50:59 +08:00
|
|
|
S.Diag(Specialized->getLocation(), diag::note_specialized_entity);
|
2009-02-26 06:02:03 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-07 08:13:32 +08:00
|
|
|
// FIXME: check for specialization-after-instantiation errors and such.
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-26 06:02:03 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-04 05:13:47 +08:00
|
|
|
/// \brief Subroutine of Sema::CheckClassTemplatePartialSpecializationArgs
|
|
|
|
/// that checks non-type template partial specialization arguments.
|
|
|
|
static bool CheckNonTypeClassTemplatePartialSpecializationArgs(Sema &S,
|
|
|
|
NonTypeTemplateParmDecl *Param,
|
|
|
|
const TemplateArgument *Args,
|
|
|
|
unsigned NumArgs) {
|
|
|
|
for (unsigned I = 0; I != NumArgs; ++I) {
|
|
|
|
if (Args[I].getKind() == TemplateArgument::Pack) {
|
|
|
|
if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param,
|
2011-01-27 15:10:08 +08:00
|
|
|
Args[I].pack_begin(),
|
2011-01-04 05:13:47 +08:00
|
|
|
Args[I].pack_size()))
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-06-13 05:21:02 +08:00
|
|
|
continue;
|
2011-01-04 05:13:47 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-04 05:13:47 +08:00
|
|
|
Expr *ArgExpr = Args[I].getAsExpr();
|
2009-06-13 06:08:06 +08:00
|
|
|
if (!ArgExpr) {
|
2009-06-13 05:21:02 +08:00
|
|
|
continue;
|
2009-06-13 06:08:06 +08:00
|
|
|
}
|
2009-06-13 05:21:02 +08:00
|
|
|
|
2011-01-04 05:37:45 +08:00
|
|
|
// We can have a pack expansion of any of the bullets below.
|
2011-01-04 05:13:47 +08:00
|
|
|
if (PackExpansionExpr *Expansion = dyn_cast<PackExpansionExpr>(ArgExpr))
|
|
|
|
ArgExpr = Expansion->getPattern();
|
2011-01-05 07:35:54 +08:00
|
|
|
|
|
|
|
// Strip off any implicit casts we added as part of type checking.
|
|
|
|
while (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr))
|
|
|
|
ArgExpr = ICE->getSubExpr();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-06-13 05:21:02 +08:00
|
|
|
// C++ [temp.class.spec]p8:
|
|
|
|
// A non-type argument is non-specialized if it is the name of a
|
|
|
|
// non-type parameter. All other non-type arguments are
|
|
|
|
// specialized.
|
|
|
|
//
|
|
|
|
// Below, we check the two conditions that only apply to
|
|
|
|
// specialized non-type arguments, so skip any non-specialized
|
|
|
|
// arguments.
|
|
|
|
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(ArgExpr))
|
2011-01-05 07:35:54 +08:00
|
|
|
if (isa<NonTypeTemplateParmDecl>(DRE->getDecl()))
|
2009-06-13 05:21:02 +08:00
|
|
|
continue;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-06-13 05:21:02 +08:00
|
|
|
// C++ [temp.class.spec]p9:
|
|
|
|
// Within the argument list of a class template partial
|
|
|
|
// specialization, the following restrictions apply:
|
|
|
|
// -- A partially specialized non-type argument expression
|
|
|
|
// shall not involve a template parameter of the partial
|
|
|
|
// specialization except when the argument expression is a
|
|
|
|
// simple identifier.
|
|
|
|
if (ArgExpr->isTypeDependent() || ArgExpr->isValueDependent()) {
|
2011-01-04 05:13:47 +08:00
|
|
|
S.Diag(ArgExpr->getLocStart(),
|
2009-06-13 05:21:02 +08:00
|
|
|
diag::err_dependent_non_type_arg_in_partial_spec)
|
|
|
|
<< ArgExpr->getSourceRange();
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-06-13 05:21:02 +08:00
|
|
|
// -- The type of a template parameter corresponding to a
|
|
|
|
// specialized non-type argument shall not be dependent on a
|
|
|
|
// parameter of the specialization.
|
|
|
|
if (Param->getType()->isDependentType()) {
|
2011-01-04 05:13:47 +08:00
|
|
|
S.Diag(ArgExpr->getLocStart(),
|
2009-06-13 05:21:02 +08:00
|
|
|
diag::err_dependent_typed_non_type_arg_in_partial_spec)
|
|
|
|
<< Param->getType()
|
|
|
|
<< ArgExpr->getSourceRange();
|
2011-01-04 05:13:47 +08:00
|
|
|
S.Diag(Param->getLocation(), diag::note_template_param_here);
|
2009-06-13 05:21:02 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-04 05:13:47 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-01-04 05:13:47 +08:00
|
|
|
/// \brief Check the non-type template arguments of a class template
|
|
|
|
/// partial specialization according to C++ [temp.class.spec]p9.
|
|
|
|
///
|
|
|
|
/// \param TemplateParams the template parameters of the primary class
|
|
|
|
/// template.
|
|
|
|
///
|
|
|
|
/// \param TemplateArg the template arguments of the class template
|
|
|
|
/// partial specialization.
|
|
|
|
///
|
|
|
|
/// \returns true if there was an error, false otherwise.
|
|
|
|
static bool CheckClassTemplatePartialSpecializationArgs(Sema &S,
|
|
|
|
TemplateParameterList *TemplateParams,
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVectorImpl<TemplateArgument> &TemplateArgs) {
|
2011-01-04 05:13:47 +08:00
|
|
|
const TemplateArgument *ArgList = TemplateArgs.data();
|
|
|
|
|
|
|
|
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
|
|
|
|
NonTypeTemplateParmDecl *Param
|
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I));
|
|
|
|
if (!Param)
|
|
|
|
continue;
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
if (CheckNonTypeClassTemplatePartialSpecializationArgs(S, Param,
|
2011-01-04 05:13:47 +08:00
|
|
|
&ArgList[I], 1))
|
|
|
|
return true;
|
|
|
|
}
|
2009-06-13 05:21:02 +08:00
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
DeclResult
|
2009-07-31 10:45:11 +08:00
|
|
|
Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
|
|
|
|
TagUseKind TUK,
|
2009-09-09 23:08:12 +08:00
|
|
|
SourceLocation KWLoc,
|
2011-09-10 04:53:38 +08:00
|
|
|
SourceLocation ModulePrivateLoc,
|
2010-04-09 00:38:48 +08:00
|
|
|
CXXScopeSpec &SS,
|
2009-03-31 06:58:21 +08:00
|
|
|
TemplateTy TemplateD,
|
2009-02-18 07:15:12 +08:00
|
|
|
SourceLocation TemplateNameLoc,
|
|
|
|
SourceLocation LAngleLoc,
|
2009-03-10 07:48:35 +08:00
|
|
|
ASTTemplateArgsPtr TemplateArgsIn,
|
2009-02-18 07:15:12 +08:00
|
|
|
SourceLocation RAngleLoc,
|
|
|
|
AttributeList *Attr,
|
|
|
|
MultiTemplateParamsArg TemplateParameterLists) {
|
2009-09-27 04:57:03 +08:00
|
|
|
assert(TUK != TUK_Reference && "References are not specializations");
|
2009-09-04 09:14:41 +08:00
|
|
|
|
2011-03-18 23:16:37 +08:00
|
|
|
// NOTE: KWLoc is the location of the tag keyword. This will instead
|
|
|
|
// store the location of the outermost template keyword in the declaration.
|
|
|
|
SourceLocation TemplateKWLoc = TemplateParameterLists.size() > 0
|
|
|
|
? TemplateParameterLists.get()[0]->getTemplateLoc() : SourceLocation();
|
|
|
|
|
2009-02-18 07:15:12 +08:00
|
|
|
// Find the class template we're specializing
|
2009-03-31 06:58:21 +08:00
|
|
|
TemplateName Name = TemplateD.getAsVal<TemplateName>();
|
2009-09-09 23:08:12 +08:00
|
|
|
ClassTemplateDecl *ClassTemplate
|
2009-11-12 08:46:20 +08:00
|
|
|
= dyn_cast_or_null<ClassTemplateDecl>(Name.getAsTemplateDecl());
|
|
|
|
|
|
|
|
if (!ClassTemplate) {
|
|
|
|
Diag(TemplateNameLoc, diag::err_not_class_template_specialization)
|
2011-01-27 15:10:08 +08:00
|
|
|
<< (Name.getAsTemplateDecl() &&
|
2009-11-12 08:46:20 +08:00
|
|
|
isa<TemplateTemplateParmDecl>(Name.getAsTemplateDecl()));
|
|
|
|
return true;
|
|
|
|
}
|
2009-02-18 07:15:12 +08:00
|
|
|
|
2009-10-08 06:35:40 +08:00
|
|
|
bool isExplicitSpecialization = false;
|
2009-05-31 17:31:02 +08:00
|
|
|
bool isPartialSpecialization = false;
|
|
|
|
|
2009-02-26 06:02:03 +08:00
|
|
|
// Check the validity of the template headers that introduce this
|
|
|
|
// template.
|
2009-09-27 04:57:03 +08:00
|
|
|
// FIXME: We probably shouldn't complain about these headers for
|
|
|
|
// friend declarations.
|
2010-07-15 07:14:12 +08:00
|
|
|
bool Invalid = false;
|
2009-08-26 01:23:04 +08:00
|
|
|
TemplateParameterList *TemplateParams
|
Reimplement Sema::MatchTemplateParametersToScopeSpecifier() based on
the semantic context referenced by the nested-name-specifier rather
than the syntactic form of the nested-name-specifier. The previous
incarnation was based on my complete misunderstanding of C++
[temp.expl.spec]. The latest C++0x working draft clarifies the
requirements here, and this rewrite is intended to follow that.
Along the way, improve source location information in the
diagnostics. For example, if we report that a specific type needs or
doesn't need a 'template<>' header, we dig out that type in the
nested-name-specifier and highlight its range.
Fixes: PR5907, PR9421, PR8277, PR8708, PR9482, PR9668, PR9877, and
<rdar://problem/9135379>.
llvm-svn: 131138
2011-05-11 02:27:06 +08:00
|
|
|
= MatchTemplateParametersToScopeSpecifier(TemplateNameLoc,
|
|
|
|
TemplateNameLoc,
|
|
|
|
SS,
|
2009-09-09 23:08:12 +08:00
|
|
|
(TemplateParameterList**)TemplateParameterLists.get(),
|
2009-10-08 06:35:40 +08:00
|
|
|
TemplateParameterLists.size(),
|
2010-04-14 04:37:33 +08:00
|
|
|
TUK == TUK_Friend,
|
2010-07-15 07:14:12 +08:00
|
|
|
isExplicitSpecialization,
|
|
|
|
Invalid);
|
|
|
|
if (Invalid)
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-08-26 01:23:04 +08:00
|
|
|
if (TemplateParams && TemplateParams->size() > 0) {
|
|
|
|
isPartialSpecialization = true;
|
|
|
|
|
2010-12-21 16:14:57 +08:00
|
|
|
if (TUK == TUK_Friend) {
|
|
|
|
Diag(KWLoc, diag::err_partial_specialization_friend)
|
|
|
|
<< SourceRange(LAngleLoc, RAngleLoc);
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-08-26 01:23:04 +08:00
|
|
|
// C++ [temp.class.spec]p10:
|
|
|
|
// The template parameter list of a specialization shall not
|
|
|
|
// contain default template argument values.
|
|
|
|
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
|
|
|
|
Decl *Param = TemplateParams->getParam(I);
|
|
|
|
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
|
|
|
|
if (TTP->hasDefaultArgument()) {
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(TTP->getDefaultArgumentLoc(),
|
2009-08-26 01:23:04 +08:00
|
|
|
diag::err_default_arg_in_partial_spec);
|
2009-10-29 16:12:44 +08:00
|
|
|
TTP->removeDefaultArgument();
|
2009-08-26 01:23:04 +08:00
|
|
|
}
|
|
|
|
} else if (NonTypeTemplateParmDecl *NTTP
|
|
|
|
= dyn_cast<NonTypeTemplateParmDecl>(Param)) {
|
|
|
|
if (Expr *DefArg = NTTP->getDefaultArgument()) {
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(NTTP->getDefaultArgumentLoc(),
|
2009-08-26 01:23:04 +08:00
|
|
|
diag::err_default_arg_in_partial_spec)
|
|
|
|
<< DefArg->getSourceRange();
|
2010-06-09 17:26:05 +08:00
|
|
|
NTTP->removeDefaultArgument();
|
2009-08-26 01:23:04 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(Param);
|
2009-11-11 09:00:40 +08:00
|
|
|
if (TTP->hasDefaultArgument()) {
|
|
|
|
Diag(TTP->getDefaultArgument().getLocation(),
|
2009-08-26 01:23:04 +08:00
|
|
|
diag::err_default_arg_in_partial_spec)
|
2009-11-11 09:00:40 +08:00
|
|
|
<< TTP->getDefaultArgument().getSourceRange();
|
2010-06-09 17:26:05 +08:00
|
|
|
TTP->removeDefaultArgument();
|
2009-06-13 03:43:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-10-13 22:39:41 +08:00
|
|
|
} else if (TemplateParams) {
|
|
|
|
if (TUK == TUK_Friend)
|
|
|
|
Diag(KWLoc, diag::err_template_spec_friend)
|
2010-04-01 01:46:05 +08:00
|
|
|
<< FixItHint::CreateRemoval(
|
2009-10-13 22:39:41 +08:00
|
|
|
SourceRange(TemplateParams->getTemplateLoc(),
|
|
|
|
TemplateParams->getRAngleLoc()))
|
|
|
|
<< SourceRange(LAngleLoc, RAngleLoc);
|
|
|
|
else
|
|
|
|
isExplicitSpecialization = true;
|
|
|
|
} else if (TUK != TUK_Friend) {
|
2009-08-26 01:23:04 +08:00
|
|
|
Diag(KWLoc, diag::err_template_spec_needs_header)
|
2010-04-01 01:46:05 +08:00
|
|
|
<< FixItHint::CreateInsertion(KWLoc, "template<> ");
|
2009-10-08 06:35:40 +08:00
|
|
|
isExplicitSpecialization = true;
|
|
|
|
}
|
2009-02-26 06:02:03 +08:00
|
|
|
|
2009-02-18 07:15:12 +08:00
|
|
|
// Check that the specialization uses the same tag kind as the
|
|
|
|
// original template.
|
2010-05-12 05:36:43 +08:00
|
|
|
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
|
|
|
|
assert(Kind != TTK_Enum && "Invalid enum tag in class template spec!");
|
2009-05-15 00:41:31 +08:00
|
|
|
if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
|
2011-06-10 11:11:26 +08:00
|
|
|
Kind, TUK == TUK_Definition, KWLoc,
|
2009-05-15 00:41:31 +08:00
|
|
|
*ClassTemplate->getIdentifier())) {
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(KWLoc, diag::err_use_with_wrong_tag)
|
2009-04-02 07:51:29 +08:00
|
|
|
<< ClassTemplate
|
2010-04-01 01:46:05 +08:00
|
|
|
<< FixItHint::CreateReplacement(KWLoc,
|
2009-04-02 07:51:29 +08:00
|
|
|
ClassTemplate->getTemplatedDecl()->getKindName());
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(ClassTemplate->getTemplatedDecl()->getLocation(),
|
2009-02-18 07:15:12 +08:00
|
|
|
diag::note_previous_use);
|
|
|
|
Kind = ClassTemplate->getTemplatedDecl()->getTagKind();
|
|
|
|
}
|
|
|
|
|
2009-03-10 07:48:35 +08:00
|
|
|
// Translate the parser's template argument list in our AST format.
|
2009-11-23 09:53:49 +08:00
|
|
|
TemplateArgumentListInfo TemplateArgs;
|
|
|
|
TemplateArgs.setLAngleLoc(LAngleLoc);
|
|
|
|
TemplateArgs.setRAngleLoc(RAngleLoc);
|
2009-11-11 03:49:08 +08:00
|
|
|
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
2009-03-10 07:48:35 +08:00
|
|
|
|
2011-01-04 04:35:03 +08:00
|
|
|
// Check for unexpanded parameter packs in any of the template arguments.
|
|
|
|
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
|
2011-01-27 15:10:08 +08:00
|
|
|
if (DiagnoseUnexpandedParameterPack(TemplateArgs[I],
|
2011-01-04 04:35:03 +08:00
|
|
|
UPPC_PartialSpecialization))
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-02-18 07:15:12 +08:00
|
|
|
// Check that the template argument list is well-formed for this
|
|
|
|
// template.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 4> Converted;
|
2009-11-23 09:53:49 +08:00
|
|
|
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
|
|
|
|
TemplateArgs, false, Converted))
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2009-02-18 07:15:12 +08:00
|
|
|
|
2009-05-31 17:31:02 +08:00
|
|
|
// Find the class template (partial) specialization declaration that
|
2009-02-18 07:15:12 +08:00
|
|
|
// corresponds to these arguments.
|
2009-06-13 03:43:02 +08:00
|
|
|
if (isPartialSpecialization) {
|
2011-01-04 05:13:47 +08:00
|
|
|
if (CheckClassTemplatePartialSpecializationArgs(*this,
|
2009-06-13 05:21:02 +08:00
|
|
|
ClassTemplate->getTemplateParameters(),
|
2010-12-24 01:13:55 +08:00
|
|
|
Converted))
|
2009-06-13 05:21:02 +08:00
|
|
|
return true;
|
|
|
|
|
2011-07-01 09:22:09 +08:00
|
|
|
bool InstantiationDependent;
|
2011-01-27 15:10:08 +08:00
|
|
|
if (!Name.isDependent() &&
|
2010-02-09 08:37:32 +08:00
|
|
|
!TemplateSpecializationType::anyDependentTemplateArguments(
|
2011-01-27 15:10:08 +08:00
|
|
|
TemplateArgs.getArgumentArray(),
|
2011-07-01 09:22:09 +08:00
|
|
|
TemplateArgs.size(),
|
|
|
|
InstantiationDependent)) {
|
2010-02-09 08:37:32 +08:00
|
|
|
Diag(TemplateNameLoc, diag::err_partial_spec_fully_specialized)
|
|
|
|
<< ClassTemplate->getDeclName();
|
|
|
|
isPartialSpecialization = false;
|
|
|
|
}
|
|
|
|
}
|
2010-07-20 21:59:28 +08:00
|
|
|
|
2009-02-18 07:15:12 +08:00
|
|
|
void *InsertPos = 0;
|
2009-05-31 17:31:02 +08:00
|
|
|
ClassTemplateSpecializationDecl *PrevDecl = 0;
|
|
|
|
|
|
|
|
if (isPartialSpecialization)
|
2010-07-20 21:59:28 +08:00
|
|
|
// FIXME: Template parameter list matters, too
|
2009-05-31 17:31:02 +08:00
|
|
|
PrevDecl
|
2010-11-08 07:05:16 +08:00
|
|
|
= ClassTemplate->findPartialSpecialization(Converted.data(),
|
|
|
|
Converted.size(),
|
2010-07-20 21:59:28 +08:00
|
|
|
InsertPos);
|
2009-05-31 17:31:02 +08:00
|
|
|
else
|
|
|
|
PrevDecl
|
2010-11-08 07:05:16 +08:00
|
|
|
= ClassTemplate->findSpecialization(Converted.data(),
|
|
|
|
Converted.size(), InsertPos);
|
2009-02-18 07:15:12 +08:00
|
|
|
|
|
|
|
ClassTemplateSpecializationDecl *Specialization = 0;
|
|
|
|
|
2009-02-26 06:02:03 +08:00
|
|
|
// Check whether we can declare a class template specialization in
|
|
|
|
// the current scope.
|
2009-09-27 04:57:03 +08:00
|
|
|
if (TUK != TUK_Friend &&
|
2011-01-27 15:10:08 +08:00
|
|
|
CheckTemplateSpecializationScope(*this, ClassTemplate, PrevDecl,
|
|
|
|
TemplateNameLoc,
|
2009-10-15 07:50:59 +08:00
|
|
|
isPartialSpecialization))
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-07-31 01:40:51 +08:00
|
|
|
// The canonical type
|
|
|
|
QualType CanonType;
|
2011-01-27 15:10:08 +08:00
|
|
|
if (PrevDecl &&
|
2009-09-27 04:57:03 +08:00
|
|
|
(PrevDecl->getSpecializationKind() == TSK_Undeclared ||
|
2010-02-09 08:37:32 +08:00
|
|
|
TUK == TUK_Friend)) {
|
2009-02-18 07:15:12 +08:00
|
|
|
// Since the only prior class template specialization with these
|
2009-09-27 04:57:03 +08:00
|
|
|
// arguments was referenced but not declared, or we're only
|
|
|
|
// referencing this specialization as a friend, reuse that
|
2011-03-18 23:16:37 +08:00
|
|
|
// declaration node as our own, updating its source location and
|
|
|
|
// the list of outer template parameters to reflect our new declaration.
|
2009-02-18 07:15:12 +08:00
|
|
|
Specialization = PrevDecl;
|
2009-02-26 06:18:32 +08:00
|
|
|
Specialization->setLocation(TemplateNameLoc);
|
2011-03-18 23:16:37 +08:00
|
|
|
if (TemplateParameterLists.size() > 0) {
|
|
|
|
Specialization->setTemplateParameterListsInfo(Context,
|
|
|
|
TemplateParameterLists.size(),
|
|
|
|
(TemplateParameterList**) TemplateParameterLists.release());
|
|
|
|
}
|
2009-02-18 07:15:12 +08:00
|
|
|
PrevDecl = 0;
|
2009-07-31 01:40:51 +08:00
|
|
|
CanonType = Context.getTypeDeclType(Specialization);
|
2009-05-31 17:31:02 +08:00
|
|
|
} else if (isPartialSpecialization) {
|
2009-07-31 01:40:51 +08:00
|
|
|
// Build the canonical type that describes the converted template
|
|
|
|
// arguments of the class template partial specialization.
|
2010-02-09 08:37:32 +08:00
|
|
|
TemplateName CanonTemplate = Context.getCanonicalTemplateName(Name);
|
|
|
|
CanonType = Context.getTemplateSpecializationType(CanonTemplate,
|
2010-12-24 01:13:55 +08:00
|
|
|
Converted.data(),
|
|
|
|
Converted.size());
|
2011-01-27 15:10:08 +08:00
|
|
|
|
|
|
|
if (Context.hasSameType(CanonType,
|
2010-12-24 01:13:55 +08:00
|
|
|
ClassTemplate->getInjectedClassNameSpecialization())) {
|
|
|
|
// C++ [temp.class.spec]p9b3:
|
|
|
|
//
|
|
|
|
// -- The argument list of the specialization shall not be identical
|
|
|
|
// to the implicit argument list of the primary template.
|
|
|
|
Diag(TemplateNameLoc, diag::err_partial_spec_args_match_primary_template)
|
2011-09-09 10:06:17 +08:00
|
|
|
<< (TUK == TUK_Definition)
|
|
|
|
<< FixItHint::CreateRemoval(SourceRange(LAngleLoc, RAngleLoc));
|
2010-12-24 01:13:55 +08:00
|
|
|
return CheckClassTemplate(S, TagSpec, TUK, KWLoc, SS,
|
|
|
|
ClassTemplate->getIdentifier(),
|
|
|
|
TemplateNameLoc,
|
|
|
|
Attr,
|
|
|
|
TemplateParams,
|
2011-09-10 03:05:14 +08:00
|
|
|
AS_none, /*ModulePrivateLoc=*/SourceLocation(),
|
2011-03-18 23:16:37 +08:00
|
|
|
TemplateParameterLists.size() - 1,
|
2011-03-10 21:28:31 +08:00
|
|
|
(TemplateParameterList**) TemplateParameterLists.release());
|
2010-12-24 01:13:55 +08:00
|
|
|
}
|
2009-07-31 01:40:51 +08:00
|
|
|
|
2009-05-31 17:31:02 +08:00
|
|
|
// Create a new class template partial specialization declaration node.
|
|
|
|
ClassTemplatePartialSpecializationDecl *PrevPartial
|
|
|
|
= cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
|
2010-04-30 13:56:50 +08:00
|
|
|
unsigned SequenceNumber = PrevPartial? PrevPartial->getSequenceNumber()
|
2010-07-20 21:59:28 +08:00
|
|
|
: ClassTemplate->getNextPartialSpecSequenceNumber();
|
2009-09-09 23:08:12 +08:00
|
|
|
ClassTemplatePartialSpecializationDecl *Partial
|
2010-05-06 08:28:52 +08:00
|
|
|
= ClassTemplatePartialSpecializationDecl::Create(Context, Kind,
|
2009-05-31 17:31:02 +08:00
|
|
|
ClassTemplate->getDeclContext(),
|
2011-03-09 22:09:51 +08:00
|
|
|
KWLoc, TemplateNameLoc,
|
2009-06-05 12:06:48 +08:00
|
|
|
TemplateParams,
|
|
|
|
ClassTemplate,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(),
|
|
|
|
Converted.size(),
|
2009-11-23 09:53:49 +08:00
|
|
|
TemplateArgs,
|
2010-03-10 11:28:59 +08:00
|
|
|
CanonType,
|
2010-04-30 13:56:50 +08:00
|
|
|
PrevPartial,
|
|
|
|
SequenceNumber);
|
2010-03-15 18:12:16 +08:00
|
|
|
SetNestedNameSpecifier(Partial, SS);
|
2011-03-18 23:16:37 +08:00
|
|
|
if (TemplateParameterLists.size() > 1 && SS.isSet()) {
|
2010-06-16 01:44:38 +08:00
|
|
|
Partial->setTemplateParameterListsInfo(Context,
|
2011-03-18 23:16:37 +08:00
|
|
|
TemplateParameterLists.size() - 1,
|
2010-06-12 16:15:14 +08:00
|
|
|
(TemplateParameterList**) TemplateParameterLists.release());
|
|
|
|
}
|
2009-05-31 17:31:02 +08:00
|
|
|
|
2010-07-20 21:59:28 +08:00
|
|
|
if (!PrevPartial)
|
|
|
|
ClassTemplate->AddPartialSpecialization(Partial, InsertPos);
|
2009-05-31 17:31:02 +08:00
|
|
|
Specialization = Partial;
|
2009-06-13 08:26:55 +08:00
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
// If we are providing an explicit specialization of a member class
|
2009-10-29 08:04:11 +08:00
|
|
|
// template specialization, make a note of that.
|
|
|
|
if (PrevPartial && PrevPartial->getInstantiatedFromMember())
|
|
|
|
PrevPartial->setMemberSpecialization();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-06-13 08:26:55 +08:00
|
|
|
// Check that all of the template parameters of the class template
|
|
|
|
// partial specialization are deducible from the template
|
|
|
|
// arguments. If not, this class template partial specialization
|
|
|
|
// will never be used.
|
2012-01-31 00:17:39 +08:00
|
|
|
llvm::SmallBitVector DeducibleParams(TemplateParams->size());
|
2011-01-27 15:10:08 +08:00
|
|
|
MarkUsedTemplateParameters(Partial->getTemplateArgs(), true,
|
2009-10-29 08:04:11 +08:00
|
|
|
TemplateParams->getDepth(),
|
2009-09-15 05:25:05 +08:00
|
|
|
DeducibleParams);
|
2009-06-13 08:26:55 +08:00
|
|
|
|
2012-01-31 00:17:39 +08:00
|
|
|
if (!DeducibleParams.all()) {
|
|
|
|
unsigned NumNonDeducible = DeducibleParams.size()-DeducibleParams.count();
|
2009-06-13 08:26:55 +08:00
|
|
|
Diag(TemplateNameLoc, diag::warn_partial_specs_not_deducible)
|
|
|
|
<< (NumNonDeducible > 1)
|
|
|
|
<< SourceRange(TemplateNameLoc, RAngleLoc);
|
|
|
|
for (unsigned I = 0, N = DeducibleParams.size(); I != N; ++I) {
|
|
|
|
if (!DeducibleParams[I]) {
|
|
|
|
NamedDecl *Param = cast<NamedDecl>(TemplateParams->getParam(I));
|
|
|
|
if (Param->getDeclName())
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(Param->getLocation(),
|
2009-06-13 08:26:55 +08:00
|
|
|
diag::note_partial_spec_unused_parameter)
|
|
|
|
<< Param->getDeclName();
|
|
|
|
else
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(Param->getLocation(),
|
2009-06-13 08:26:55 +08:00
|
|
|
diag::note_partial_spec_unused_parameter)
|
2010-08-11 22:47:12 +08:00
|
|
|
<< "<anonymous>";
|
2009-06-13 08:26:55 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-02-18 07:15:12 +08:00
|
|
|
} else {
|
|
|
|
// Create a new class template specialization declaration node for
|
2009-09-27 04:57:03 +08:00
|
|
|
// this explicit specialization or friend declaration.
|
2009-02-18 07:15:12 +08:00
|
|
|
Specialization
|
2010-05-06 08:28:52 +08:00
|
|
|
= ClassTemplateSpecializationDecl::Create(Context, Kind,
|
2009-02-18 07:15:12 +08:00
|
|
|
ClassTemplate->getDeclContext(),
|
2011-03-09 22:09:51 +08:00
|
|
|
KWLoc, TemplateNameLoc,
|
2009-09-09 23:08:12 +08:00
|
|
|
ClassTemplate,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(),
|
|
|
|
Converted.size(),
|
2009-02-18 07:15:12 +08:00
|
|
|
PrevDecl);
|
2010-03-15 18:12:16 +08:00
|
|
|
SetNestedNameSpecifier(Specialization, SS);
|
2011-03-18 23:16:37 +08:00
|
|
|
if (TemplateParameterLists.size() > 0) {
|
2010-06-16 01:44:38 +08:00
|
|
|
Specialization->setTemplateParameterListsInfo(Context,
|
2011-03-18 23:16:37 +08:00
|
|
|
TemplateParameterLists.size(),
|
2010-06-12 16:15:14 +08:00
|
|
|
(TemplateParameterList**) TemplateParameterLists.release());
|
|
|
|
}
|
2009-02-18 07:15:12 +08:00
|
|
|
|
2010-07-20 21:59:28 +08:00
|
|
|
if (!PrevDecl)
|
|
|
|
ClassTemplate->AddSpecialization(Specialization, InsertPos);
|
2009-07-31 01:40:51 +08:00
|
|
|
|
|
|
|
CanonType = Context.getTypeDeclType(Specialization);
|
2009-02-18 07:15:12 +08:00
|
|
|
}
|
|
|
|
|
2009-10-13 04:18:28 +08:00
|
|
|
// C++ [temp.expl.spec]p6:
|
|
|
|
// If a template, a member template or the member of a class template is
|
2011-01-27 15:10:08 +08:00
|
|
|
// explicitly specialized then that specialization shall be declared
|
2009-10-13 04:18:28 +08:00
|
|
|
// before the first use of that specialization that would cause an implicit
|
2011-01-27 15:10:08 +08:00
|
|
|
// instantiation to take place, in every translation unit in which such a
|
2009-10-13 04:18:28 +08:00
|
|
|
// use occurs; no diagnostic is required.
|
|
|
|
if (PrevDecl && PrevDecl->getPointOfInstantiation().isValid()) {
|
2010-02-26 14:03:23 +08:00
|
|
|
bool Okay = false;
|
2012-01-14 23:55:47 +08:00
|
|
|
for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) {
|
2010-02-26 14:03:23 +08:00
|
|
|
// Is there any previous explicit specialization declaration?
|
|
|
|
if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) {
|
|
|
|
Okay = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!Okay) {
|
|
|
|
SourceRange Range(TemplateNameLoc, RAngleLoc);
|
|
|
|
Diag(TemplateNameLoc, diag::err_specialization_after_instantiation)
|
|
|
|
<< Context.getTypeDeclType(Specialization) << Range;
|
2009-10-13 04:18:28 +08:00
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(PrevDecl->getPointOfInstantiation(),
|
2010-02-26 14:03:23 +08:00
|
|
|
diag::note_instantiation_required_here)
|
2011-01-27 15:10:08 +08:00
|
|
|
<< (PrevDecl->getTemplateSpecializationKind()
|
2009-10-13 04:18:28 +08:00
|
|
|
!= TSK_ImplicitInstantiation);
|
2010-02-26 14:03:23 +08:00
|
|
|
return true;
|
|
|
|
}
|
2009-10-13 04:18:28 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-27 04:57:03 +08:00
|
|
|
// If this is not a friend, note that this is an explicit specialization.
|
|
|
|
if (TUK != TUK_Friend)
|
|
|
|
Specialization->setSpecializationKind(TSK_ExplicitSpecialization);
|
2009-02-18 07:15:12 +08:00
|
|
|
|
|
|
|
// Check that this isn't a redefinition of this specialization.
|
2009-07-31 10:45:11 +08:00
|
|
|
if (TUK == TUK_Definition) {
|
2010-02-11 09:04:33 +08:00
|
|
|
if (RecordDecl *Def = Specialization->getDefinition()) {
|
2009-02-18 07:15:12 +08:00
|
|
|
SourceRange Range(TemplateNameLoc, RAngleLoc);
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(TemplateNameLoc, diag::err_redefinition)
|
2009-05-31 17:31:02 +08:00
|
|
|
<< Context.getTypeDeclType(Specialization) << Range;
|
2009-02-18 07:15:12 +08:00
|
|
|
Diag(Def->getLocation(), diag::note_previous_definition);
|
|
|
|
Specialization->setInvalidDecl();
|
2009-03-25 08:13:59 +08:00
|
|
|
return true;
|
2009-02-18 07:15:12 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-12-18 11:30:47 +08:00
|
|
|
if (Attr)
|
|
|
|
ProcessDeclAttributeList(S, Specialization, Attr);
|
|
|
|
|
2011-09-10 04:53:38 +08:00
|
|
|
if (ModulePrivateLoc.isValid())
|
|
|
|
Diag(Specialization->getLocation(), diag::err_module_private_specialization)
|
|
|
|
<< (isPartialSpecialization? 1 : 0)
|
|
|
|
<< FixItHint::CreateRemoval(ModulePrivateLoc);
|
|
|
|
|
2009-02-27 06:19:44 +08:00
|
|
|
// Build the fully-sugared type for this class template
|
|
|
|
// specialization as the user wrote in the specialization
|
|
|
|
// itself. This means that we'll pretty-print the type retrieved
|
|
|
|
// from the specialization's declaration the way that the user
|
|
|
|
// actually wrote the specialization, rather than formatting the
|
|
|
|
// name based on the "canonical" representation used to store the
|
|
|
|
// template arguments in the specialization.
|
2010-03-10 11:28:59 +08:00
|
|
|
TypeSourceInfo *WrittenTy
|
|
|
|
= Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
|
|
|
|
TemplateArgs, CanonType);
|
2010-06-12 15:44:57 +08:00
|
|
|
if (TUK != TUK_Friend) {
|
2009-09-27 04:57:03 +08:00
|
|
|
Specialization->setTypeAsWritten(WrittenTy);
|
2011-03-18 23:16:37 +08:00
|
|
|
Specialization->setTemplateKeywordLoc(TemplateKWLoc);
|
2010-06-12 15:44:57 +08:00
|
|
|
}
|
2009-03-10 07:48:35 +08:00
|
|
|
TemplateArgsIn.release();
|
2009-02-18 07:15:12 +08:00
|
|
|
|
2009-02-26 06:18:32 +08:00
|
|
|
// C++ [temp.expl.spec]p9:
|
|
|
|
// A template explicit specialization is in the scope of the
|
|
|
|
// namespace in which the template was defined.
|
|
|
|
//
|
|
|
|
// We actually implement this paragraph where we set the semantic
|
|
|
|
// context (in the creation of the ClassTemplateSpecializationDecl),
|
|
|
|
// but we also maintain the lexical context where the actual
|
|
|
|
// definition occurs.
|
2009-02-18 07:15:12 +08:00
|
|
|
Specialization->setLexicalDeclContext(CurContext);
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-02-18 07:15:12 +08:00
|
|
|
// We may be starting the definition of this specialization.
|
2009-07-31 10:45:11 +08:00
|
|
|
if (TUK == TUK_Definition)
|
2009-02-18 07:15:12 +08:00
|
|
|
Specialization->startDefinition();
|
|
|
|
|
2009-09-27 04:57:03 +08:00
|
|
|
if (TUK == TUK_Friend) {
|
|
|
|
FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
|
|
|
|
TemplateNameLoc,
|
2010-03-26 02:04:51 +08:00
|
|
|
WrittenTy,
|
2009-09-27 04:57:03 +08:00
|
|
|
/*FIXME:*/KWLoc);
|
|
|
|
Friend->setAccess(AS_public);
|
|
|
|
CurContext->addDecl(Friend);
|
|
|
|
} else {
|
|
|
|
// Add the specialization into its lexical context, so that it can
|
|
|
|
// be seen when iterating through the list of declarations in that
|
|
|
|
// context. However, specializations are not found by name lookup.
|
|
|
|
CurContext->addDecl(Specialization);
|
|
|
|
}
|
2010-08-21 17:40:31 +08:00
|
|
|
return Specialization;
|
2009-02-18 07:15:12 +08:00
|
|
|
}
|
2009-03-28 07:10:48 +08:00
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
Decl *Sema::ActOnTemplateDeclarator(Scope *S,
|
2009-06-24 07:11:28 +08:00
|
|
|
MultiTemplateParamsArg TemplateParameterLists,
|
2010-08-21 17:40:31 +08:00
|
|
|
Declarator &D) {
|
2011-10-11 08:28:45 +08:00
|
|
|
return HandleDeclarator(S, D, move(TemplateParameterLists));
|
2009-06-24 07:11:28 +08:00
|
|
|
}
|
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
Decl *Sema::ActOnStartOfFunctionTemplateDef(Scope *FnBodyScope,
|
2009-06-24 08:54:41 +08:00
|
|
|
MultiTemplateParamsArg TemplateParameterLists,
|
2010-08-21 17:40:31 +08:00
|
|
|
Declarator &D) {
|
2009-06-24 08:54:41 +08:00
|
|
|
assert(getCurFunctionDecl() == 0 && "Function parsing confused");
|
2010-12-11 00:29:40 +08:00
|
|
|
DeclaratorChunk::FunctionTypeInfo &FTI = D.getFunctionTypeInfo();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-24 08:54:41 +08:00
|
|
|
if (FTI.hasPrototype) {
|
2009-09-09 23:08:12 +08:00
|
|
|
// FIXME: Diagnose arguments without names in C.
|
2009-06-24 08:54:41 +08:00
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-06-24 08:54:41 +08:00
|
|
|
Scope *ParentScope = FnBodyScope->getParent();
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2011-11-08 04:56:01 +08:00
|
|
|
D.setFunctionDefinitionKind(FDK_Definition);
|
2010-08-21 17:40:31 +08:00
|
|
|
Decl *DP = HandleDeclarator(ParentScope, D,
|
2011-10-11 08:28:45 +08:00
|
|
|
move(TemplateParameterLists));
|
2009-09-09 23:08:12 +08:00
|
|
|
if (FunctionTemplateDecl *FunctionTemplate
|
2010-08-21 17:40:31 +08:00
|
|
|
= dyn_cast_or_null<FunctionTemplateDecl>(DP))
|
2009-09-09 23:08:12 +08:00
|
|
|
return ActOnStartOfFunctionDef(FnBodyScope,
|
2010-08-21 17:40:31 +08:00
|
|
|
FunctionTemplate->getTemplatedDecl());
|
|
|
|
if (FunctionDecl *Function = dyn_cast_or_null<FunctionDecl>(DP))
|
|
|
|
return ActOnStartOfFunctionDef(FnBodyScope, Function);
|
|
|
|
return 0;
|
2009-06-24 08:54:41 +08:00
|
|
|
}
|
|
|
|
|
2010-02-11 09:33:53 +08:00
|
|
|
/// \brief Strips various properties off an implicit instantiation
|
|
|
|
/// that has just been explicitly specialized.
|
|
|
|
static void StripImplicitInstantiation(NamedDecl *D) {
|
2012-02-23 12:17:32 +08:00
|
|
|
// FIXME: "make check" is clean if the call to dropAttrs() is commented out.
|
2010-08-19 07:23:40 +08:00
|
|
|
D->dropAttrs();
|
2010-02-11 09:33:53 +08:00
|
|
|
|
|
|
|
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
|
|
|
FD->setInlineSpecified(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-01-10 03:52:25 +08:00
|
|
|
/// \brief Compute the diagnostic location for an explicit instantiation
|
|
|
|
// declaration or definition.
|
|
|
|
static SourceLocation DiagLocForExplicitInstantiation(
|
2012-01-14 23:55:47 +08:00
|
|
|
NamedDecl* D, SourceLocation PointOfInstantiation) {
|
2012-01-10 03:52:25 +08:00
|
|
|
// Explicit instantiations following a specialization have no effect and
|
|
|
|
// hence no PointOfInstantiation. In that case, walk decl backwards
|
|
|
|
// until a valid name loc is found.
|
|
|
|
SourceLocation PrevDiagLoc = PointOfInstantiation;
|
2012-01-14 23:55:47 +08:00
|
|
|
for (Decl *Prev = D; Prev && !PrevDiagLoc.isValid();
|
|
|
|
Prev = Prev->getPreviousDecl()) {
|
2012-01-10 03:52:25 +08:00
|
|
|
PrevDiagLoc = Prev->getLocation();
|
|
|
|
}
|
|
|
|
assert(PrevDiagLoc.isValid() &&
|
|
|
|
"Explicit instantiation without point of instantiation?");
|
|
|
|
return PrevDiagLoc;
|
|
|
|
}
|
|
|
|
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \brief Diagnose cases where we have an explicit template specialization
|
2009-10-15 23:54:05 +08:00
|
|
|
/// before/after an explicit template instantiation, producing diagnostics
|
2011-01-27 15:10:08 +08:00
|
|
|
/// for those cases where they are required and determining whether the
|
2009-10-15 23:54:05 +08:00
|
|
|
/// new specialization/instantiation will have any effect.
|
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \param NewLoc the location of the new explicit specialization or
|
2009-10-15 23:54:05 +08:00
|
|
|
/// instantiation.
|
|
|
|
///
|
|
|
|
/// \param NewTSK the kind of the new explicit specialization or instantiation.
|
|
|
|
///
|
|
|
|
/// \param PrevDecl the previous declaration of the entity.
|
|
|
|
///
|
|
|
|
/// \param PrevTSK the kind of the old explicit specialization or instantiatin.
|
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \param PrevPointOfInstantiation if valid, indicates where the previus
|
2009-10-15 23:54:05 +08:00
|
|
|
/// declaration was instantiated (either implicitly or explicitly).
|
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// \param HasNoEffect will be set to true to indicate that the new
|
2009-10-15 23:54:05 +08:00
|
|
|
/// specialization or instantiation has no effect and should be ignored.
|
|
|
|
///
|
|
|
|
/// \returns true if there was an error that should prevent the introduction of
|
|
|
|
/// the new declaration into the AST, false otherwise.
|
2009-10-28 02:42:08 +08:00
|
|
|
bool
|
|
|
|
Sema::CheckSpecializationInstantiationRedecl(SourceLocation NewLoc,
|
|
|
|
TemplateSpecializationKind NewTSK,
|
|
|
|
NamedDecl *PrevDecl,
|
|
|
|
TemplateSpecializationKind PrevTSK,
|
|
|
|
SourceLocation PrevPointOfInstantiation,
|
2010-06-12 15:44:57 +08:00
|
|
|
bool &HasNoEffect) {
|
|
|
|
HasNoEffect = false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
switch (NewTSK) {
|
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ImplicitInstantiation:
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Don't check implicit instantiations here");
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitSpecialization:
|
|
|
|
switch (PrevTSK) {
|
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ExplicitSpecialization:
|
2011-01-27 15:10:08 +08:00
|
|
|
// Okay, we're just specializing something that is either already
|
2009-10-15 23:54:05 +08:00
|
|
|
// explicitly specialized or has merely been mentioned without any
|
|
|
|
// instantiation.
|
|
|
|
return false;
|
|
|
|
|
|
|
|
case TSK_ImplicitInstantiation:
|
|
|
|
if (PrevPointOfInstantiation.isInvalid()) {
|
|
|
|
// The declaration itself has not actually been instantiated, so it is
|
|
|
|
// still okay to specialize it.
|
2010-02-11 09:33:53 +08:00
|
|
|
StripImplicitInstantiation(PrevDecl);
|
2009-10-15 23:54:05 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// Fall through
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
2011-01-27 15:10:08 +08:00
|
|
|
assert((PrevTSK == TSK_ImplicitInstantiation ||
|
|
|
|
PrevPointOfInstantiation.isValid()) &&
|
2009-10-15 23:54:05 +08:00
|
|
|
"Explicit instantiation without point of instantiation?");
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
// C++ [temp.expl.spec]p6:
|
2011-01-27 15:10:08 +08:00
|
|
|
// If a template, a member template or the member of a class template
|
2009-10-15 23:54:05 +08:00
|
|
|
// is explicitly specialized then that specialization shall be declared
|
2011-01-27 15:10:08 +08:00
|
|
|
// before the first use of that specialization that would cause an
|
2009-10-15 23:54:05 +08:00
|
|
|
// implicit instantiation to take place, in every translation unit in
|
|
|
|
// which such a use occurs; no diagnostic is required.
|
2012-01-14 23:55:47 +08:00
|
|
|
for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) {
|
2010-02-26 14:03:23 +08:00
|
|
|
// Is there any previous explicit specialization declaration?
|
|
|
|
if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
Diag(NewLoc, diag::err_specialization_after_instantiation)
|
2009-10-15 23:54:05 +08:00
|
|
|
<< PrevDecl;
|
2009-10-28 02:42:08 +08:00
|
|
|
Diag(PrevPointOfInstantiation, diag::note_instantiation_required_here)
|
2009-10-15 23:54:05 +08:00
|
|
|
<< (PrevTSK != TSK_ImplicitInstantiation);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
switch (PrevTSK) {
|
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
// This explicit instantiation declaration is redundant (that's okay).
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect = true;
|
2009-10-15 23:54:05 +08:00
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ImplicitInstantiation:
|
|
|
|
// We're explicitly instantiating something that may have already been
|
|
|
|
// implicitly instantiated; that's fine.
|
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitSpecialization:
|
|
|
|
// C++0x [temp.explicit]p4:
|
|
|
|
// For a given set of template parameters, if an explicit instantiation
|
2011-01-27 15:10:08 +08:00
|
|
|
// of a template appears after a declaration of an explicit
|
2009-10-15 23:54:05 +08:00
|
|
|
// specialization for that template, the explicit instantiation has no
|
|
|
|
// effect.
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect = true;
|
2009-10-15 23:54:05 +08:00
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
// C++0x [temp.explicit]p10:
|
2011-01-27 15:10:08 +08:00
|
|
|
// If an entity is the subject of both an explicit instantiation
|
|
|
|
// declaration and an explicit instantiation definition in the same
|
2009-10-15 23:54:05 +08:00
|
|
|
// translation unit, the definition shall follow the declaration.
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(NewLoc,
|
2009-10-28 02:42:08 +08:00
|
|
|
diag::err_explicit_instantiation_declaration_after_definition);
|
2011-12-24 04:58:04 +08:00
|
|
|
|
|
|
|
// Explicit instantiations following a specialization have no effect and
|
|
|
|
// hence no PrevPointOfInstantiation. In that case, walk decl backwards
|
|
|
|
// until a valid name loc is found.
|
2012-01-10 03:52:25 +08:00
|
|
|
Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation),
|
|
|
|
diag::note_explicit_instantiation_definition_here);
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect = true;
|
2009-10-15 23:54:05 +08:00
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
switch (PrevTSK) {
|
|
|
|
case TSK_Undeclared:
|
|
|
|
case TSK_ImplicitInstantiation:
|
|
|
|
// We're explicitly instantiating something that may have already been
|
|
|
|
// implicitly instantiated; that's fine.
|
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitSpecialization:
|
|
|
|
// C++ DR 259, C++0x [temp.explicit]p4:
|
|
|
|
// For a given set of template parameters, if an explicit
|
|
|
|
// instantiation of a template appears after a declaration of
|
|
|
|
// an explicit specialization for that template, the explicit
|
|
|
|
// instantiation has no effect.
|
|
|
|
//
|
2011-01-27 15:10:08 +08:00
|
|
|
// In C++98/03 mode, we only give an extension warning here, because it
|
2010-04-10 05:02:29 +08:00
|
|
|
// is not harmful to try to explicitly instantiate something that
|
2009-10-15 23:54:05 +08:00
|
|
|
// has been explicitly specialized.
|
2012-03-11 15:00:24 +08:00
|
|
|
Diag(NewLoc, getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_explicit_instantiation_after_specialization :
|
|
|
|
diag::ext_explicit_instantiation_after_specialization)
|
|
|
|
<< PrevDecl;
|
|
|
|
Diag(PrevDecl->getLocation(),
|
|
|
|
diag::note_previous_template_specialization);
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect = true;
|
2009-10-15 23:54:05 +08:00
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitInstantiationDeclaration:
|
|
|
|
// We're explicity instantiating a definition for something for which we
|
2011-01-27 15:10:08 +08:00
|
|
|
// were previously asked to suppress instantiations. That's fine.
|
2011-12-24 04:58:04 +08:00
|
|
|
|
|
|
|
// C++0x [temp.explicit]p4:
|
|
|
|
// For a given set of template parameters, if an explicit instantiation
|
|
|
|
// of a template appears after a declaration of an explicit
|
|
|
|
// specialization for that template, the explicit instantiation has no
|
|
|
|
// effect.
|
2012-01-14 23:55:47 +08:00
|
|
|
for (Decl *Prev = PrevDecl; Prev; Prev = Prev->getPreviousDecl()) {
|
2011-12-24 04:58:04 +08:00
|
|
|
// Is there any previous explicit specialization declaration?
|
|
|
|
if (getTemplateSpecializationKind(Prev) == TSK_ExplicitSpecialization) {
|
|
|
|
HasNoEffect = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
case TSK_ExplicitInstantiationDefinition:
|
|
|
|
// C++0x [temp.spec]p5:
|
|
|
|
// For a given template and a given set of template-arguments,
|
|
|
|
// - an explicit instantiation definition shall appear at most once
|
|
|
|
// in a program,
|
2009-10-28 02:42:08 +08:00
|
|
|
Diag(NewLoc, diag::err_explicit_instantiation_duplicate)
|
2009-10-15 23:54:05 +08:00
|
|
|
<< PrevDecl;
|
2012-01-10 03:52:25 +08:00
|
|
|
Diag(DiagLocForExplicitInstantiation(PrevDecl, PrevPointOfInstantiation),
|
2009-10-28 02:42:08 +08:00
|
|
|
diag::note_previous_explicit_instantiation);
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect = true;
|
2011-01-27 15:10:08 +08:00
|
|
|
return false;
|
2009-10-15 23:54:05 +08:00
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-09-23 13:06:16 +08:00
|
|
|
llvm_unreachable("Missing specialization/instantiation case?");
|
2010-04-08 17:05:18 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Perform semantic analysis for the given dependent function
|
|
|
|
/// template specialization. The only possible way to get a dependent
|
|
|
|
/// function template specialization is with a friend declaration,
|
|
|
|
/// like so:
|
|
|
|
///
|
|
|
|
/// template <class T> void foo(T);
|
|
|
|
/// template <class T> class A {
|
|
|
|
/// friend void foo<>(T);
|
|
|
|
/// };
|
|
|
|
///
|
|
|
|
/// There really isn't any useful analysis we can do here, so we
|
|
|
|
/// just store the information.
|
|
|
|
bool
|
|
|
|
Sema::CheckDependentFunctionTemplateSpecialization(FunctionDecl *FD,
|
|
|
|
const TemplateArgumentListInfo &ExplicitTemplateArgs,
|
|
|
|
LookupResult &Previous) {
|
|
|
|
// Remove anything from Previous that isn't a function template in
|
|
|
|
// the correct context.
|
2010-08-31 08:36:30 +08:00
|
|
|
DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
|
2010-04-08 17:05:18 +08:00
|
|
|
LookupResult::Filter F = Previous.makeFilter();
|
|
|
|
while (F.hasNext()) {
|
|
|
|
NamedDecl *D = F.next()->getUnderlyingDecl();
|
|
|
|
if (!isa<FunctionTemplateDecl>(D) ||
|
2010-08-31 08:36:30 +08:00
|
|
|
!FDLookupContext->InEnclosingNamespaceSetOf(
|
|
|
|
D->getDeclContext()->getRedeclContext()))
|
2010-04-08 17:05:18 +08:00
|
|
|
F.erase();
|
|
|
|
}
|
|
|
|
F.done();
|
|
|
|
|
|
|
|
// Should this be diagnosed here?
|
|
|
|
if (Previous.empty()) return true;
|
|
|
|
|
|
|
|
FD->setDependentTemplateSpecialization(Context, Previous.asUnresolvedSet(),
|
|
|
|
ExplicitTemplateArgs);
|
|
|
|
return false;
|
2009-10-15 23:54:05 +08:00
|
|
|
}
|
|
|
|
|
2010-05-20 23:32:11 +08:00
|
|
|
/// \brief Perform semantic analysis for the given function template
|
2009-09-25 07:14:47 +08:00
|
|
|
/// specialization.
|
|
|
|
///
|
2010-05-20 23:32:11 +08:00
|
|
|
/// This routine performs all of the semantic analysis required for an
|
2009-09-25 07:14:47 +08:00
|
|
|
/// explicit function template specialization. On successful completion,
|
|
|
|
/// the function declaration \p FD will become a function template
|
|
|
|
/// specialization.
|
|
|
|
///
|
|
|
|
/// \param FD the function declaration, which will be updated to become a
|
|
|
|
/// function template specialization.
|
|
|
|
///
|
2010-05-20 23:32:11 +08:00
|
|
|
/// \param ExplicitTemplateArgs the explicitly-provided template arguments,
|
|
|
|
/// if any. Note that this may be valid info even when 0 arguments are
|
|
|
|
/// explicitly provided as in, e.g., \c void sort<>(char*, char*);
|
|
|
|
/// as it anyway contains info on the angle brackets locations.
|
2009-09-25 07:14:47 +08:00
|
|
|
///
|
2011-07-08 14:21:47 +08:00
|
|
|
/// \param Previous the set of declarations that may be specialized by
|
2010-05-20 23:32:11 +08:00
|
|
|
/// this function specialization.
|
|
|
|
bool
|
2009-09-25 07:14:47 +08:00
|
|
|
Sema::CheckFunctionTemplateSpecialization(FunctionDecl *FD,
|
2011-03-03 10:41:12 +08:00
|
|
|
TemplateArgumentListInfo *ExplicitTemplateArgs,
|
2009-11-19 06:49:29 +08:00
|
|
|
LookupResult &Previous) {
|
2009-09-25 07:14:47 +08:00
|
|
|
// The set of function template specializations that could match this
|
|
|
|
// explicit function template specialization.
|
2010-01-27 09:50:18 +08:00
|
|
|
UnresolvedSet<8> Candidates;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-31 08:36:30 +08:00
|
|
|
DeclContext *FDLookupContext = FD->getDeclContext()->getRedeclContext();
|
2009-11-19 06:49:29 +08:00
|
|
|
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
NamedDecl *Ovl = (*I)->getUnderlyingDecl();
|
|
|
|
if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Ovl)) {
|
2011-01-27 15:10:08 +08:00
|
|
|
// Only consider templates found within the same semantic lookup scope as
|
2009-09-25 07:14:47 +08:00
|
|
|
// FD.
|
2010-08-31 08:36:30 +08:00
|
|
|
if (!FDLookupContext->InEnclosingNamespaceSetOf(
|
|
|
|
Ovl->getDeclContext()->getRedeclContext()))
|
2009-09-25 07:14:47 +08:00
|
|
|
continue;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-25 07:14:47 +08:00
|
|
|
// C++ [temp.expl.spec]p11:
|
2011-01-27 15:10:08 +08:00
|
|
|
// A trailing template-argument can be left unspecified in the
|
|
|
|
// template-id naming an explicit function template specialization
|
2009-09-25 07:14:47 +08:00
|
|
|
// provided it can be deduced from the function argument type.
|
|
|
|
// Perform template argument deduction to determine whether we may be
|
|
|
|
// specializing this template.
|
|
|
|
// FIXME: It is somewhat wasteful to build
|
2010-02-09 07:07:23 +08:00
|
|
|
TemplateDeductionInfo Info(Context, FD->getLocation());
|
2009-09-25 07:14:47 +08:00
|
|
|
FunctionDecl *Specialization = 0;
|
|
|
|
if (TemplateDeductionResult TDK
|
2009-11-23 09:53:49 +08:00
|
|
|
= DeduceTemplateArguments(FunTmpl, ExplicitTemplateArgs,
|
2009-09-25 07:14:47 +08:00
|
|
|
FD->getType(),
|
|
|
|
Specialization,
|
|
|
|
Info)) {
|
|
|
|
// FIXME: Template argument deduction failed; record why it failed, so
|
|
|
|
// that we can provide nifty diagnostics.
|
|
|
|
(void)TDK;
|
|
|
|
continue;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-25 07:14:47 +08:00
|
|
|
// Record this candidate.
|
2010-01-27 09:50:18 +08:00
|
|
|
Candidates.addDecl(Specialization, I.getAccess());
|
2009-09-25 07:14:47 +08:00
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 11:41:46 +08:00
|
|
|
// Find the most specialized function template.
|
2010-01-27 09:50:18 +08:00
|
|
|
UnresolvedSetIterator Result
|
|
|
|
= getMostSpecialized(Candidates.begin(), Candidates.end(),
|
2011-01-12 01:34:58 +08:00
|
|
|
TPOC_Other, 0, FD->getLocation(),
|
2011-01-27 15:10:08 +08:00
|
|
|
PDiag(diag::err_function_template_spec_no_match)
|
2009-09-26 11:41:46 +08:00
|
|
|
<< FD->getDeclName(),
|
2010-03-30 07:34:08 +08:00
|
|
|
PDiag(diag::err_function_template_spec_ambiguous)
|
2009-11-23 09:53:49 +08:00
|
|
|
<< FD->getDeclName() << (ExplicitTemplateArgs != 0),
|
2010-03-30 07:34:08 +08:00
|
|
|
PDiag(diag::note_function_template_spec_matched));
|
2010-01-27 09:50:18 +08:00
|
|
|
if (Result == Candidates.end())
|
2009-09-25 07:14:47 +08:00
|
|
|
return true;
|
2010-01-27 09:50:18 +08:00
|
|
|
|
|
|
|
// Ignore access information; it doesn't figure into redeclaration checking.
|
|
|
|
FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
|
2011-03-05 01:20:30 +08:00
|
|
|
|
|
|
|
FunctionTemplateSpecializationInfo *SpecInfo
|
|
|
|
= Specialization->getTemplateSpecializationInfo();
|
|
|
|
assert(SpecInfo && "Function template specialization info missing?");
|
2011-07-08 14:21:47 +08:00
|
|
|
|
|
|
|
// Note: do not overwrite location info if previous template
|
|
|
|
// specialization kind was explicit.
|
|
|
|
TemplateSpecializationKind TSK = SpecInfo->getTemplateSpecializationKind();
|
2012-02-21 07:28:05 +08:00
|
|
|
if (TSK == TSK_Undeclared || TSK == TSK_ImplicitInstantiation) {
|
2011-07-08 14:21:47 +08:00
|
|
|
Specialization->setLocation(FD->getLocation());
|
2012-02-21 07:28:05 +08:00
|
|
|
// C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr
|
|
|
|
// function can differ from the template declaration with respect to
|
|
|
|
// the constexpr specifier.
|
|
|
|
Specialization->setConstexpr(FD->isConstexpr());
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-25 07:14:47 +08:00
|
|
|
// FIXME: Check if the prior specialization has a point of instantiation.
|
2009-10-13 04:18:28 +08:00
|
|
|
// If so, we have run afoul of .
|
2010-03-24 15:46:06 +08:00
|
|
|
|
|
|
|
// If this is a friend declaration, then we're not really declaring
|
|
|
|
// an explicit specialization.
|
|
|
|
bool isFriend = (FD->getFriendObjectKind() != Decl::FOK_None);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-07 08:13:32 +08:00
|
|
|
// Check the scope of this explicit specialization.
|
2010-03-24 15:46:06 +08:00
|
|
|
if (!isFriend &&
|
2011-01-27 15:10:08 +08:00
|
|
|
CheckTemplateSpecializationScope(*this,
|
2009-10-07 08:13:32 +08:00
|
|
|
Specialization->getPrimaryTemplate(),
|
2011-01-27 15:10:08 +08:00
|
|
|
Specialization, FD->getLocation(),
|
2009-10-15 07:50:59 +08:00
|
|
|
false))
|
2009-10-07 08:13:32 +08:00
|
|
|
return true;
|
2009-10-13 04:18:28 +08:00
|
|
|
|
|
|
|
// C++ [temp.expl.spec]p6:
|
|
|
|
// If a template, a member template or the member of a class template is
|
2011-01-27 15:10:08 +08:00
|
|
|
// explicitly specialized then that specialization shall be declared
|
2009-10-13 04:18:28 +08:00
|
|
|
// before the first use of that specialization that would cause an implicit
|
2011-01-27 15:10:08 +08:00
|
|
|
// instantiation to take place, in every translation unit in which such a
|
2009-10-13 04:18:28 +08:00
|
|
|
// use occurs; no diagnostic is required.
|
2010-06-12 15:44:57 +08:00
|
|
|
bool HasNoEffect = false;
|
2010-03-24 15:46:06 +08:00
|
|
|
if (!isFriend &&
|
|
|
|
CheckSpecializationInstantiationRedecl(FD->getLocation(),
|
2010-02-11 09:33:53 +08:00
|
|
|
TSK_ExplicitSpecialization,
|
|
|
|
Specialization,
|
|
|
|
SpecInfo->getTemplateSpecializationKind(),
|
|
|
|
SpecInfo->getPointOfInstantiation(),
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect))
|
2009-10-13 04:18:28 +08:00
|
|
|
return true;
|
2011-05-22 02:53:30 +08:00
|
|
|
|
2009-09-25 07:14:47 +08:00
|
|
|
// Mark the prior declaration as an explicit specialization, so that later
|
|
|
|
// clients know that this is an explicit specialization.
|
2010-08-15 09:15:20 +08:00
|
|
|
if (!isFriend) {
|
2010-03-24 15:46:06 +08:00
|
|
|
SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
|
2010-08-15 09:15:20 +08:00
|
|
|
MarkUnusedFileScopedDecl(Specialization);
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-25 07:14:47 +08:00
|
|
|
// Turn the given function declaration into a function template
|
|
|
|
// specialization, with the template arguments from the previous
|
|
|
|
// specialization.
|
2010-05-20 23:32:11 +08:00
|
|
|
// Take copies of (semantic and syntactic) template argument lists.
|
|
|
|
const TemplateArgumentList* TemplArgs = new (Context)
|
|
|
|
TemplateArgumentList(Specialization->getTemplateSpecializationArgs());
|
2010-02-11 09:19:42 +08:00
|
|
|
FD->setFunctionTemplateSpecialization(Specialization->getPrimaryTemplate(),
|
2010-05-20 23:32:11 +08:00
|
|
|
TemplArgs, /*InsertPos=*/0,
|
|
|
|
SpecInfo->getTemplateSpecializationKind(),
|
2011-09-23 04:07:09 +08:00
|
|
|
ExplicitTemplateArgs);
|
2011-05-22 02:53:30 +08:00
|
|
|
FD->setStorageClass(Specialization->getStorageClass());
|
|
|
|
|
2009-09-25 07:14:47 +08:00
|
|
|
// The "previous declaration" for this function template specialization is
|
|
|
|
// the prior function template specialization.
|
2009-11-19 06:49:29 +08:00
|
|
|
Previous.clear();
|
|
|
|
Previous.addDecl(Specialization);
|
2009-09-25 07:14:47 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
/// \brief Perform semantic analysis for the given non-template member
|
2009-10-08 06:35:40 +08:00
|
|
|
/// specialization.
|
|
|
|
///
|
2011-01-27 15:10:08 +08:00
|
|
|
/// This routine performs all of the semantic analysis required for an
|
2009-10-08 06:35:40 +08:00
|
|
|
/// explicit member function specialization. On successful completion,
|
|
|
|
/// the function declaration \p FD will become a member function
|
|
|
|
/// specialization.
|
|
|
|
///
|
2009-10-08 15:24:58 +08:00
|
|
|
/// \param Member the member declaration, which will be updated to become a
|
|
|
|
/// specialization.
|
2009-10-08 06:35:40 +08:00
|
|
|
///
|
2009-11-19 06:49:29 +08:00
|
|
|
/// \param Previous the set of declarations, one of which may be specialized
|
|
|
|
/// by this function specialization; the set will be modified to contain the
|
|
|
|
/// redeclared member.
|
2011-01-27 15:10:08 +08:00
|
|
|
bool
|
2009-11-19 06:49:29 +08:00
|
|
|
Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
|
2009-10-08 15:24:58 +08:00
|
|
|
assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
|
2010-04-14 04:37:33 +08:00
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
// Try to find the member we are instantiating.
|
|
|
|
NamedDecl *Instantiation = 0;
|
|
|
|
NamedDecl *InstantiatedFrom = 0;
|
2009-10-13 04:18:28 +08:00
|
|
|
MemberSpecializationInfo *MSInfo = 0;
|
|
|
|
|
2009-11-19 06:49:29 +08:00
|
|
|
if (Previous.empty()) {
|
2009-10-08 15:24:58 +08:00
|
|
|
// Nowhere to look anyway.
|
|
|
|
} else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Member)) {
|
2009-11-19 06:49:29 +08:00
|
|
|
for (LookupResult::iterator I = Previous.begin(), E = Previous.end();
|
|
|
|
I != E; ++I) {
|
|
|
|
NamedDecl *D = (*I)->getUnderlyingDecl();
|
|
|
|
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(D)) {
|
2009-10-08 15:24:58 +08:00
|
|
|
if (Context.hasSameType(Function->getType(), Method->getType())) {
|
|
|
|
Instantiation = Method;
|
|
|
|
InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
|
2009-10-13 04:18:28 +08:00
|
|
|
MSInfo = Method->getMemberSpecializationInfo();
|
2009-10-08 15:24:58 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (isa<VarDecl>(Member)) {
|
2009-11-19 06:49:29 +08:00
|
|
|
VarDecl *PrevVar;
|
|
|
|
if (Previous.isSingleResult() &&
|
|
|
|
(PrevVar = dyn_cast<VarDecl>(Previous.getFoundDecl())))
|
2009-10-08 15:24:58 +08:00
|
|
|
if (PrevVar->isStaticDataMember()) {
|
2009-11-19 06:49:29 +08:00
|
|
|
Instantiation = PrevVar;
|
2009-10-08 15:24:58 +08:00
|
|
|
InstantiatedFrom = PrevVar->getInstantiatedFromStaticDataMember();
|
2009-10-13 04:18:28 +08:00
|
|
|
MSInfo = PrevVar->getMemberSpecializationInfo();
|
2009-10-08 06:35:40 +08:00
|
|
|
}
|
2009-10-08 15:24:58 +08:00
|
|
|
} else if (isa<RecordDecl>(Member)) {
|
2009-11-19 06:49:29 +08:00
|
|
|
CXXRecordDecl *PrevRecord;
|
|
|
|
if (Previous.isSingleResult() &&
|
|
|
|
(PrevRecord = dyn_cast<CXXRecordDecl>(Previous.getFoundDecl()))) {
|
|
|
|
Instantiation = PrevRecord;
|
2009-10-08 15:24:58 +08:00
|
|
|
InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass();
|
2009-10-13 04:18:28 +08:00
|
|
|
MSInfo = PrevRecord->getMemberSpecializationInfo();
|
2009-10-08 06:35:40 +08:00
|
|
|
}
|
2012-03-23 11:33:32 +08:00
|
|
|
} else if (isa<EnumDecl>(Member)) {
|
|
|
|
EnumDecl *PrevEnum;
|
|
|
|
if (Previous.isSingleResult() &&
|
|
|
|
(PrevEnum = dyn_cast<EnumDecl>(Previous.getFoundDecl()))) {
|
|
|
|
Instantiation = PrevEnum;
|
|
|
|
InstantiatedFrom = PrevEnum->getInstantiatedFromMemberEnum();
|
|
|
|
MSInfo = PrevEnum->getMemberSpecializationInfo();
|
|
|
|
}
|
2009-10-08 06:35:40 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 06:35:40 +08:00
|
|
|
if (!Instantiation) {
|
2009-10-08 15:24:58 +08:00
|
|
|
// There is no previous declaration that matches. Since member
|
2009-10-08 06:35:40 +08:00
|
|
|
// specializations are always out-of-line, the caller will complain about
|
|
|
|
// this mismatch later.
|
|
|
|
return false;
|
|
|
|
}
|
2010-04-14 04:37:33 +08:00
|
|
|
|
|
|
|
// If this is a friend, just bail out here before we start turning
|
|
|
|
// things into explicit specializations.
|
|
|
|
if (Member->getFriendObjectKind() != Decl::FOK_None) {
|
|
|
|
// Preserve instantiation information.
|
|
|
|
if (InstantiatedFrom && isa<CXXMethodDecl>(Member)) {
|
|
|
|
cast<CXXMethodDecl>(Member)->setInstantiationOfMemberFunction(
|
|
|
|
cast<CXXMethodDecl>(InstantiatedFrom),
|
|
|
|
cast<CXXMethodDecl>(Instantiation)->getTemplateSpecializationKind());
|
|
|
|
} else if (InstantiatedFrom && isa<CXXRecordDecl>(Member)) {
|
|
|
|
cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass(
|
|
|
|
cast<CXXRecordDecl>(InstantiatedFrom),
|
|
|
|
cast<CXXRecordDecl>(Instantiation)->getTemplateSpecializationKind());
|
|
|
|
}
|
|
|
|
|
|
|
|
Previous.clear();
|
|
|
|
Previous.addDecl(Instantiation);
|
|
|
|
return false;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
// Make sure that this is a specialization of a member.
|
|
|
|
if (!InstantiatedFrom) {
|
|
|
|
Diag(Member->getLocation(), diag::err_spec_member_not_instantiated)
|
|
|
|
<< Member;
|
2009-10-08 06:35:40 +08:00
|
|
|
Diag(Instantiation->getLocation(), diag::note_specialized_decl);
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-13 04:18:28 +08:00
|
|
|
// C++ [temp.expl.spec]p6:
|
|
|
|
// If a template, a member template or the member of a class template is
|
2011-12-24 04:58:04 +08:00
|
|
|
// explicitly specialized then that specialization shall be declared
|
2009-10-13 04:18:28 +08:00
|
|
|
// before the first use of that specialization that would cause an implicit
|
2011-01-27 15:10:08 +08:00
|
|
|
// instantiation to take place, in every translation unit in which such a
|
2009-10-13 04:18:28 +08:00
|
|
|
// use occurs; no diagnostic is required.
|
|
|
|
assert(MSInfo && "Member specialization info missing?");
|
2010-02-11 09:33:53 +08:00
|
|
|
|
2010-06-12 15:44:57 +08:00
|
|
|
bool HasNoEffect = false;
|
2010-02-11 09:33:53 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(Member->getLocation(),
|
|
|
|
TSK_ExplicitSpecialization,
|
|
|
|
Instantiation,
|
|
|
|
MSInfo->getTemplateSpecializationKind(),
|
|
|
|
MSInfo->getPointOfInstantiation(),
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect))
|
2009-10-13 04:18:28 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 06:35:40 +08:00
|
|
|
// Check the scope of this explicit specialization.
|
2011-01-27 15:10:08 +08:00
|
|
|
if (CheckTemplateSpecializationScope(*this,
|
2009-10-08 15:24:58 +08:00
|
|
|
InstantiatedFrom,
|
2011-01-27 15:10:08 +08:00
|
|
|
Instantiation, Member->getLocation(),
|
2009-10-15 07:50:59 +08:00
|
|
|
false))
|
2009-10-08 06:35:40 +08:00
|
|
|
return true;
|
2009-10-08 07:56:10 +08:00
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
// Note that this is an explicit instantiation of a member.
|
2009-10-08 23:14:33 +08:00
|
|
|
// the original declaration to note that it is an explicit specialization
|
|
|
|
// (if it was previously an implicit instantiation). This latter step
|
|
|
|
// makes bookkeeping easier.
|
2009-10-08 15:24:58 +08:00
|
|
|
if (isa<FunctionDecl>(Member)) {
|
2009-10-08 23:14:33 +08:00
|
|
|
FunctionDecl *InstantiationFunction = cast<FunctionDecl>(Instantiation);
|
|
|
|
if (InstantiationFunction->getTemplateSpecializationKind() ==
|
|
|
|
TSK_ImplicitInstantiation) {
|
|
|
|
InstantiationFunction->setTemplateSpecializationKind(
|
|
|
|
TSK_ExplicitSpecialization);
|
|
|
|
InstantiationFunction->setLocation(Member->getLocation());
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
|
|
|
|
cast<CXXMethodDecl>(InstantiatedFrom),
|
|
|
|
TSK_ExplicitSpecialization);
|
2010-08-15 09:15:20 +08:00
|
|
|
MarkUnusedFileScopedDecl(InstantiationFunction);
|
2009-10-08 15:24:58 +08:00
|
|
|
} else if (isa<VarDecl>(Member)) {
|
2009-10-08 23:14:33 +08:00
|
|
|
VarDecl *InstantiationVar = cast<VarDecl>(Instantiation);
|
|
|
|
if (InstantiationVar->getTemplateSpecializationKind() ==
|
|
|
|
TSK_ImplicitInstantiation) {
|
|
|
|
InstantiationVar->setTemplateSpecializationKind(
|
|
|
|
TSK_ExplicitSpecialization);
|
|
|
|
InstantiationVar->setLocation(Member->getLocation());
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
Context.setInstantiatedFromStaticDataMember(cast<VarDecl>(Member),
|
|
|
|
cast<VarDecl>(InstantiatedFrom),
|
|
|
|
TSK_ExplicitSpecialization);
|
2010-08-15 09:15:20 +08:00
|
|
|
MarkUnusedFileScopedDecl(InstantiationVar);
|
2012-03-23 11:33:32 +08:00
|
|
|
} else if (isa<CXXRecordDecl>(Member)) {
|
2009-10-08 23:14:33 +08:00
|
|
|
CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation);
|
|
|
|
if (InstantiationClass->getTemplateSpecializationKind() ==
|
|
|
|
TSK_ImplicitInstantiation) {
|
|
|
|
InstantiationClass->setTemplateSpecializationKind(
|
|
|
|
TSK_ExplicitSpecialization);
|
|
|
|
InstantiationClass->setLocation(Member->getLocation());
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 15:24:58 +08:00
|
|
|
cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass(
|
2009-10-08 23:14:33 +08:00
|
|
|
cast<CXXRecordDecl>(InstantiatedFrom),
|
|
|
|
TSK_ExplicitSpecialization);
|
2012-03-23 11:33:32 +08:00
|
|
|
} else {
|
|
|
|
assert(isa<EnumDecl>(Member) && "Only member enums remain");
|
|
|
|
EnumDecl *InstantiationEnum = cast<EnumDecl>(Instantiation);
|
|
|
|
if (InstantiationEnum->getTemplateSpecializationKind() ==
|
|
|
|
TSK_ImplicitInstantiation) {
|
|
|
|
InstantiationEnum->setTemplateSpecializationKind(
|
|
|
|
TSK_ExplicitSpecialization);
|
|
|
|
InstantiationEnum->setLocation(Member->getLocation());
|
|
|
|
}
|
|
|
|
|
|
|
|
cast<EnumDecl>(Member)->setInstantiationOfMemberEnum(
|
|
|
|
cast<EnumDecl>(InstantiatedFrom), TSK_ExplicitSpecialization);
|
2009-10-08 15:24:58 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-08 06:35:40 +08:00
|
|
|
// Save the caller the trouble of having to figure out which declaration
|
|
|
|
// this specialization matches.
|
2009-11-19 06:49:29 +08:00
|
|
|
Previous.clear();
|
|
|
|
Previous.addDecl(Instantiation);
|
2009-10-08 06:35:40 +08:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
/// \brief Check the scope of an explicit instantiation.
|
2010-07-13 08:10:04 +08:00
|
|
|
///
|
|
|
|
/// \returns true if a serious error occurs, false otherwise.
|
|
|
|
static bool CheckExplicitInstantiationScope(Sema &S, NamedDecl *D,
|
2009-10-15 07:41:34 +08:00
|
|
|
SourceLocation InstLoc,
|
|
|
|
bool WasQualifiedName) {
|
2010-08-31 08:36:30 +08:00
|
|
|
DeclContext *OrigContext= D->getDeclContext()->getEnclosingNamespaceContext();
|
|
|
|
DeclContext *CurContext = S.CurContext->getRedeclContext();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-07-13 08:10:04 +08:00
|
|
|
if (CurContext->isRecord()) {
|
|
|
|
S.Diag(InstLoc, diag::err_explicit_instantiation_in_class)
|
|
|
|
<< D;
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-10-18 10:28:33 +08:00
|
|
|
// C++11 [temp.explicit]p3:
|
2011-01-27 15:10:08 +08:00
|
|
|
// An explicit instantiation shall appear in an enclosing namespace of its
|
2011-10-18 10:28:33 +08:00
|
|
|
// template. If the name declared in the explicit instantiation is an
|
|
|
|
// unqualified name, the explicit instantiation shall appear in the
|
|
|
|
// namespace where its template is declared or, if that namespace is inline
|
|
|
|
// (7.3.1), any namespace from its enclosing namespace set.
|
2009-10-15 07:41:34 +08:00
|
|
|
//
|
|
|
|
// This is DR275, which we do not retroactively apply to C++98/03.
|
2011-10-18 10:28:33 +08:00
|
|
|
if (WasQualifiedName) {
|
|
|
|
if (CurContext->Encloses(OrigContext))
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
if (CurContext->InEnclosingNamespaceSetOf(OrigContext))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (NamespaceDecl *NS = dyn_cast<NamespaceDecl>(OrigContext)) {
|
|
|
|
if (WasQualifiedName)
|
2011-01-27 15:10:08 +08:00
|
|
|
S.Diag(InstLoc,
|
2012-03-11 15:00:24 +08:00
|
|
|
S.getLangOpts().CPlusPlus0x?
|
2011-10-18 10:28:33 +08:00
|
|
|
diag::err_explicit_instantiation_out_of_scope :
|
|
|
|
diag::warn_explicit_instantiation_out_of_scope_0x)
|
2009-10-15 07:41:34 +08:00
|
|
|
<< D << NS;
|
|
|
|
else
|
2011-01-27 15:10:08 +08:00
|
|
|
S.Diag(InstLoc,
|
2012-03-11 15:00:24 +08:00
|
|
|
S.getLangOpts().CPlusPlus0x?
|
2011-10-18 10:28:33 +08:00
|
|
|
diag::err_explicit_instantiation_unqualified_wrong_namespace :
|
|
|
|
diag::warn_explicit_instantiation_unqualified_wrong_namespace_0x)
|
|
|
|
<< D << NS;
|
|
|
|
} else
|
|
|
|
S.Diag(InstLoc,
|
2012-03-11 15:00:24 +08:00
|
|
|
S.getLangOpts().CPlusPlus0x?
|
2011-10-18 10:28:33 +08:00
|
|
|
diag::err_explicit_instantiation_must_be_global :
|
|
|
|
diag::warn_explicit_instantiation_must_be_global_0x)
|
|
|
|
<< D;
|
2009-10-15 07:41:34 +08:00
|
|
|
S.Diag(D->getLocation(), diag::note_explicit_instantiation_here);
|
2010-07-13 08:10:04 +08:00
|
|
|
return false;
|
2009-10-15 07:41:34 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Determine whether the given scope specifier has a template-id in it.
|
|
|
|
static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
|
|
|
|
if (!SS.isSet())
|
|
|
|
return false;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-10-18 10:28:33 +08:00
|
|
|
// C++11 [temp.explicit]p3:
|
2011-01-27 15:10:08 +08:00
|
|
|
// If the explicit instantiation is for a member function, a member class
|
2009-10-15 07:41:34 +08:00
|
|
|
// or a static data member of a class template specialization, the name of
|
|
|
|
// the class template specialization in the qualified-id for the member
|
|
|
|
// name shall be a simple-template-id.
|
|
|
|
//
|
|
|
|
// C++98 has the same restriction, just worded differently.
|
|
|
|
for (NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
|
|
|
|
NNS; NNS = NNS->getPrefix())
|
2011-01-19 14:33:43 +08:00
|
|
|
if (const Type *T = NNS->getAsType())
|
2009-10-15 07:41:34 +08:00
|
|
|
if (isa<TemplateSpecializationType>(T))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-05-14 08:28:11 +08:00
|
|
|
// Explicit instantiation of a class template specialization
|
2010-08-27 07:41:50 +08:00
|
|
|
DeclResult
|
2009-09-09 23:08:12 +08:00
|
|
|
Sema::ActOnExplicitInstantiation(Scope *S,
|
2009-09-04 14:33:52 +08:00
|
|
|
SourceLocation ExternLoc,
|
|
|
|
SourceLocation TemplateLoc,
|
2009-09-09 23:08:12 +08:00
|
|
|
unsigned TagSpec,
|
2009-05-13 08:25:59 +08:00
|
|
|
SourceLocation KWLoc,
|
|
|
|
const CXXScopeSpec &SS,
|
|
|
|
TemplateTy TemplateD,
|
|
|
|
SourceLocation TemplateNameLoc,
|
|
|
|
SourceLocation LAngleLoc,
|
|
|
|
ASTTemplateArgsPtr TemplateArgsIn,
|
|
|
|
SourceLocation RAngleLoc,
|
|
|
|
AttributeList *Attr) {
|
|
|
|
// Find the class template we're specializing
|
|
|
|
TemplateName Name = TemplateD.getAsVal<TemplateName>();
|
2009-09-09 23:08:12 +08:00
|
|
|
ClassTemplateDecl *ClassTemplate
|
2009-05-13 08:25:59 +08:00
|
|
|
= cast<ClassTemplateDecl>(Name.getAsTemplateDecl());
|
|
|
|
|
|
|
|
// Check that the specialization uses the same tag kind as the
|
|
|
|
// original template.
|
2010-05-12 05:36:43 +08:00
|
|
|
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
|
|
|
|
assert(Kind != TTK_Enum &&
|
|
|
|
"Invalid enum tag in class template explicit instantiation!");
|
2009-05-15 00:41:31 +08:00
|
|
|
if (!isAcceptableTagRedeclaration(ClassTemplate->getTemplatedDecl(),
|
2011-06-10 11:11:26 +08:00
|
|
|
Kind, /*isDefinition*/false, KWLoc,
|
2009-05-15 00:41:31 +08:00
|
|
|
*ClassTemplate->getIdentifier())) {
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(KWLoc, diag::err_use_with_wrong_tag)
|
2009-05-13 08:25:59 +08:00
|
|
|
<< ClassTemplate
|
2010-04-01 01:46:05 +08:00
|
|
|
<< FixItHint::CreateReplacement(KWLoc,
|
2009-05-13 08:25:59 +08:00
|
|
|
ClassTemplate->getTemplatedDecl()->getKindName());
|
2009-09-09 23:08:12 +08:00
|
|
|
Diag(ClassTemplate->getTemplatedDecl()->getLocation(),
|
2009-05-13 08:25:59 +08:00
|
|
|
diag::note_previous_use);
|
|
|
|
Kind = ClassTemplate->getTemplatedDecl()->getTagKind();
|
|
|
|
}
|
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
|
|
|
// There are two forms of explicit instantiation: an explicit instantiation
|
2011-01-27 15:10:08 +08:00
|
|
|
// definition and an explicit instantiation declaration. An explicit
|
|
|
|
// instantiation declaration begins with the extern keyword. [...]
|
2009-10-07 08:13:32 +08:00
|
|
|
TemplateSpecializationKind TSK
|
|
|
|
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
|
|
|
|
: TSK_ExplicitInstantiationDeclaration;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-05-13 08:25:59 +08:00
|
|
|
// Translate the parser's template argument list in our AST format.
|
2009-11-23 09:53:49 +08:00
|
|
|
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
|
2009-11-11 03:49:08 +08:00
|
|
|
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
2009-05-13 08:25:59 +08:00
|
|
|
|
|
|
|
// Check that the template argument list is well-formed for this
|
|
|
|
// template.
|
2011-07-23 18:55:15 +08:00
|
|
|
SmallVector<TemplateArgument, 4> Converted;
|
2009-11-23 09:53:49 +08:00
|
|
|
if (CheckTemplateArgumentList(ClassTemplate, TemplateNameLoc,
|
|
|
|
TemplateArgs, false, Converted))
|
2009-05-13 08:25:59 +08:00
|
|
|
return true;
|
|
|
|
|
|
|
|
// Find the class template specialization declaration that
|
|
|
|
// corresponds to these arguments.
|
|
|
|
void *InsertPos = 0;
|
|
|
|
ClassTemplateSpecializationDecl *PrevDecl
|
2010-11-08 07:05:16 +08:00
|
|
|
= ClassTemplate->findSpecialization(Converted.data(),
|
|
|
|
Converted.size(), InsertPos);
|
2009-05-13 08:25:59 +08:00
|
|
|
|
2010-06-12 15:44:57 +08:00
|
|
|
TemplateSpecializationKind PrevDecl_TSK
|
|
|
|
= PrevDecl ? PrevDecl->getTemplateSpecializationKind() : TSK_Undeclared;
|
|
|
|
|
2009-10-07 08:13:32 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
|
|
|
// [...] An explicit instantiation shall appear in an enclosing
|
|
|
|
// namespace of its template. [...]
|
|
|
|
//
|
|
|
|
// This is C++ DR 275.
|
2010-07-13 08:10:04 +08:00
|
|
|
if (CheckExplicitInstantiationScope(*this, ClassTemplate, TemplateNameLoc,
|
|
|
|
SS.isSet()))
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-05-13 08:25:59 +08:00
|
|
|
ClassTemplateSpecializationDecl *Specialization = 0;
|
|
|
|
|
2010-06-12 15:44:57 +08:00
|
|
|
bool HasNoEffect = false;
|
2009-05-13 08:25:59 +08:00
|
|
|
if (PrevDecl) {
|
2009-10-28 02:42:08 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(TemplateNameLoc, TSK,
|
2010-06-12 15:44:57 +08:00
|
|
|
PrevDecl, PrevDecl_TSK,
|
2009-10-16 06:53:21 +08:00
|
|
|
PrevDecl->getPointOfInstantiation(),
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect))
|
2010-08-21 17:40:31 +08:00
|
|
|
return PrevDecl;
|
2009-05-14 02:28:20 +08:00
|
|
|
|
2010-06-12 15:44:57 +08:00
|
|
|
// Even though HasNoEffect == true means that this explicit instantiation
|
|
|
|
// has no effect on semantics, we go on to put its syntax in the AST.
|
|
|
|
|
|
|
|
if (PrevDecl_TSK == TSK_ImplicitInstantiation ||
|
|
|
|
PrevDecl_TSK == TSK_Undeclared) {
|
2009-09-12 05:19:12 +08:00
|
|
|
// Since the only prior class template specialization with these
|
|
|
|
// arguments was referenced but not declared, reuse that
|
2010-06-12 15:44:57 +08:00
|
|
|
// declaration node as our own, updating the source location
|
|
|
|
// for the template name to reflect our new declaration.
|
|
|
|
// (Other source locations will be updated later.)
|
2009-09-12 05:19:12 +08:00
|
|
|
Specialization = PrevDecl;
|
|
|
|
Specialization->setLocation(TemplateNameLoc);
|
|
|
|
PrevDecl = 0;
|
|
|
|
}
|
2009-10-16 06:53:21 +08:00
|
|
|
}
|
2010-06-12 15:44:57 +08:00
|
|
|
|
2009-09-12 05:19:12 +08:00
|
|
|
if (!Specialization) {
|
2009-05-13 08:25:59 +08:00
|
|
|
// Create a new class template specialization declaration node for
|
|
|
|
// this explicit specialization.
|
|
|
|
Specialization
|
2010-05-06 08:28:52 +08:00
|
|
|
= ClassTemplateSpecializationDecl::Create(Context, Kind,
|
2009-05-13 08:25:59 +08:00
|
|
|
ClassTemplate->getDeclContext(),
|
2011-03-09 22:09:51 +08:00
|
|
|
KWLoc, TemplateNameLoc,
|
2009-05-13 08:25:59 +08:00
|
|
|
ClassTemplate,
|
2010-11-08 07:05:16 +08:00
|
|
|
Converted.data(),
|
|
|
|
Converted.size(),
|
|
|
|
PrevDecl);
|
2010-03-15 18:12:16 +08:00
|
|
|
SetNestedNameSpecifier(Specialization, SS);
|
2009-05-13 08:25:59 +08:00
|
|
|
|
2010-07-20 21:59:28 +08:00
|
|
|
if (!HasNoEffect && !PrevDecl) {
|
2010-06-12 15:44:57 +08:00
|
|
|
// Insert the new specialization.
|
2010-07-20 21:59:28 +08:00
|
|
|
ClassTemplate->AddSpecialization(Specialization, InsertPos);
|
2010-06-12 15:44:57 +08:00
|
|
|
}
|
2009-05-13 08:25:59 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Build the fully-sugared type for this explicit instantiation as
|
|
|
|
// the user wrote in the explicit instantiation itself. This means
|
|
|
|
// that we'll pretty-print the type retrieved from the
|
|
|
|
// specialization's declaration the way that the user actually wrote
|
|
|
|
// the explicit instantiation, rather than formatting the name based
|
|
|
|
// on the "canonical" representation used to store the template
|
|
|
|
// arguments in the specialization.
|
2010-03-10 11:28:59 +08:00
|
|
|
TypeSourceInfo *WrittenTy
|
|
|
|
= Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
|
|
|
|
TemplateArgs,
|
2009-05-13 08:25:59 +08:00
|
|
|
Context.getTypeDeclType(Specialization));
|
|
|
|
Specialization->setTypeAsWritten(WrittenTy);
|
|
|
|
TemplateArgsIn.release();
|
|
|
|
|
2010-06-12 15:44:57 +08:00
|
|
|
// Set source locations for keywords.
|
|
|
|
Specialization->setExternLoc(ExternLoc);
|
|
|
|
Specialization->setTemplateKeywordLoc(TemplateLoc);
|
|
|
|
|
2012-01-03 14:04:21 +08:00
|
|
|
if (Attr)
|
|
|
|
ProcessDeclAttributeList(S, Specialization, Attr);
|
|
|
|
|
2010-06-12 15:44:57 +08:00
|
|
|
// Add the explicit instantiation into its lexical context. However,
|
|
|
|
// since explicit instantiations are never found by name lookup, we
|
|
|
|
// just put it into the declaration context directly.
|
|
|
|
Specialization->setLexicalDeclContext(CurContext);
|
|
|
|
CurContext->addDecl(Specialization);
|
|
|
|
|
|
|
|
// Syntax is now OK, so return if it has no other effect on semantics.
|
|
|
|
if (HasNoEffect) {
|
|
|
|
// Set the template specialization kind.
|
|
|
|
Specialization->setTemplateSpecializationKind(TSK);
|
2010-08-21 17:40:31 +08:00
|
|
|
return Specialization;
|
2009-11-25 14:01:46 +08:00
|
|
|
}
|
2009-05-13 08:25:59 +08:00
|
|
|
|
|
|
|
// C++ [temp.explicit]p3:
|
|
|
|
// A definition of a class template or class member template
|
|
|
|
// shall be in scope at the point of the explicit instantiation of
|
|
|
|
// the class template or class member template.
|
|
|
|
//
|
|
|
|
// This check comes when we actually try to perform the
|
|
|
|
// instantiation.
|
2009-10-16 06:53:21 +08:00
|
|
|
ClassTemplateSpecializationDecl *Def
|
|
|
|
= cast_or_null<ClassTemplateSpecializationDecl>(
|
2010-02-11 09:04:33 +08:00
|
|
|
Specialization->getDefinition());
|
2009-10-16 06:53:21 +08:00
|
|
|
if (!Def)
|
2009-10-27 14:26:26 +08:00
|
|
|
InstantiateClassTemplateSpecialization(TemplateNameLoc, Specialization, TSK);
|
2010-06-12 15:44:57 +08:00
|
|
|
else if (TSK == TSK_ExplicitInstantiationDefinition) {
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
MarkVTableUsed(TemplateNameLoc, Specialization, true);
|
2010-06-12 15:44:57 +08:00
|
|
|
Specialization->setPointOfInstantiation(Def->getPointOfInstantiation());
|
|
|
|
}
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
// Instantiate the members of this class template specialization.
|
|
|
|
Def = cast_or_null<ClassTemplateSpecializationDecl>(
|
2010-02-11 09:04:33 +08:00
|
|
|
Specialization->getDefinition());
|
2010-03-23 07:12:48 +08:00
|
|
|
if (Def) {
|
2010-03-24 03:55:22 +08:00
|
|
|
TemplateSpecializationKind Old_TSK = Def->getTemplateSpecializationKind();
|
|
|
|
|
|
|
|
// Fix a TSK_ExplicitInstantiationDeclaration followed by a
|
|
|
|
// TSK_ExplicitInstantiationDefinition
|
|
|
|
if (Old_TSK == TSK_ExplicitInstantiationDeclaration &&
|
|
|
|
TSK == TSK_ExplicitInstantiationDefinition)
|
|
|
|
Def->setTemplateSpecializationKind(TSK);
|
2010-03-23 07:12:48 +08:00
|
|
|
|
2009-10-16 06:53:21 +08:00
|
|
|
InstantiateClassTemplateSpecializationMembers(TemplateNameLoc, Def, TSK);
|
2010-03-23 07:12:48 +08:00
|
|
|
}
|
2009-05-13 08:25:59 +08:00
|
|
|
|
2010-06-12 15:44:57 +08:00
|
|
|
// Set the template specialization kind.
|
|
|
|
Specialization->setTemplateSpecializationKind(TSK);
|
2010-08-21 17:40:31 +08:00
|
|
|
return Specialization;
|
2009-05-13 08:25:59 +08:00
|
|
|
}
|
|
|
|
|
2009-05-14 08:28:11 +08:00
|
|
|
// Explicit instantiation of a member class of a class template.
|
2010-08-21 17:40:31 +08:00
|
|
|
DeclResult
|
2009-09-09 23:08:12 +08:00
|
|
|
Sema::ActOnExplicitInstantiation(Scope *S,
|
2009-09-04 14:33:52 +08:00
|
|
|
SourceLocation ExternLoc,
|
|
|
|
SourceLocation TemplateLoc,
|
2009-09-09 23:08:12 +08:00
|
|
|
unsigned TagSpec,
|
2009-05-14 08:28:11 +08:00
|
|
|
SourceLocation KWLoc,
|
2010-04-09 00:38:48 +08:00
|
|
|
CXXScopeSpec &SS,
|
2009-05-14 08:28:11 +08:00
|
|
|
IdentifierInfo *Name,
|
|
|
|
SourceLocation NameLoc,
|
|
|
|
AttributeList *Attr) {
|
|
|
|
|
When we parse a tag specifier, keep track of whether that tag
specifier resulted in the creation of a new TagDecl node, which
happens either when the tag specifier was a definition or when the tag
specifier was the first declaration of that tag type. This information
has several uses, the first of which is implemented in this commit:
1) In C++, one is not allowed to define tag types within a type
specifier (e.g., static_cast<struct S { int x; } *>(0) is
ill-formed) or within the result or parameter types of a
function. We now diagnose this.
2) We can extend DeclGroups to contain information about any tags
that are declared/defined within the declaration specifiers of a
variable, e.g.,
struct Point { int x, y, z; } p;
This will help improve AST printing and template instantiation,
among other things.
3) For C99, we can keep track of whether a tag type is defined
within the type of a parameter, to properly cope with cases like,
e.g.,
int bar(struct T2 { int x; } y) {
struct T2 z;
}
We can also do similar things wherever there is a type specifier,
e.g., to keep track of where the definition of S occurs in this
legal C99 code:
(struct S { int x, y; } *)0
llvm-svn: 72555
2009-05-29 07:31:59 +08:00
|
|
|
bool Owned = false;
|
2009-09-11 12:59:25 +08:00
|
|
|
bool IsDependent = false;
|
2010-08-27 07:41:50 +08:00
|
|
|
Decl *TagD = ActOnTag(S, TagSpec, Sema::TUK_Reference,
|
2010-08-21 17:40:31 +08:00
|
|
|
KWLoc, SS, Name, NameLoc, Attr, AS_none,
|
2011-09-10 03:05:14 +08:00
|
|
|
/*ModulePrivateLoc=*/SourceLocation(),
|
2010-08-21 17:40:31 +08:00
|
|
|
MultiTemplateParamsArg(*this, 0, 0),
|
2012-01-10 09:33:14 +08:00
|
|
|
Owned, IsDependent, SourceLocation(), false,
|
2010-10-09 07:50:27 +08:00
|
|
|
TypeResult());
|
2009-09-11 12:59:25 +08:00
|
|
|
assert(!IsDependent && "explicit instantiation of dependent name not yet handled");
|
|
|
|
|
2009-05-14 08:28:11 +08:00
|
|
|
if (!TagD)
|
|
|
|
return true;
|
|
|
|
|
2010-08-21 17:40:31 +08:00
|
|
|
TagDecl *Tag = cast<TagDecl>(TagD);
|
2012-03-23 11:33:32 +08:00
|
|
|
assert(!Tag->isEnum() && "shouldn't see enumerations here");
|
2009-05-14 08:28:11 +08:00
|
|
|
|
2009-05-28 01:30:49 +08:00
|
|
|
if (Tag->isInvalidDecl())
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-05-14 08:28:11 +08:00
|
|
|
CXXRecordDecl *Record = cast<CXXRecordDecl>(Tag);
|
|
|
|
CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
|
|
|
|
if (!Pattern) {
|
|
|
|
Diag(TemplateLoc, diag::err_explicit_instantiation_nontemplate_type)
|
|
|
|
<< Context.getTypeDeclType(Record);
|
|
|
|
Diag(Record->getLocation(), diag::note_nontemplate_decl_here);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
2011-01-27 15:10:08 +08:00
|
|
|
// If the explicit instantiation is for a class or member class, the
|
|
|
|
// elaborated-type-specifier in the declaration shall include a
|
2009-10-15 07:41:34 +08:00
|
|
|
// simple-template-id.
|
|
|
|
//
|
|
|
|
// C++98 has the same restriction, just worded differently.
|
|
|
|
if (!ScopeSpecifierHasTemplateId(SS))
|
2010-06-17 00:26:47 +08:00
|
|
|
Diag(TemplateLoc, diag::ext_explicit_instantiation_without_qualified_id)
|
2009-10-15 07:41:34 +08:00
|
|
|
<< Record << SS.getRange();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
|
|
|
// There are two forms of explicit instantiation: an explicit instantiation
|
2011-01-27 15:10:08 +08:00
|
|
|
// definition and an explicit instantiation declaration. An explicit
|
2009-10-15 07:41:34 +08:00
|
|
|
// instantiation declaration begins with the extern keyword. [...]
|
2009-10-15 05:46:58 +08:00
|
|
|
TemplateSpecializationKind TSK
|
|
|
|
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
|
|
|
|
: TSK_ExplicitInstantiationDeclaration;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-05-14 08:28:11 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
|
|
|
// [...] An explicit instantiation shall appear in an enclosing
|
|
|
|
// namespace of its template. [...]
|
|
|
|
//
|
|
|
|
// This is C++ DR 275.
|
2009-10-15 07:41:34 +08:00
|
|
|
CheckExplicitInstantiationScope(*this, Record, NameLoc, true);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
// Verify that it is okay to explicitly instantiate here.
|
2011-01-27 15:10:08 +08:00
|
|
|
CXXRecordDecl *PrevDecl
|
2012-01-15 00:38:05 +08:00
|
|
|
= cast_or_null<CXXRecordDecl>(Record->getPreviousDecl());
|
2010-02-11 09:04:33 +08:00
|
|
|
if (!PrevDecl && Record->getDefinition())
|
2009-10-16 02:07:02 +08:00
|
|
|
PrevDecl = Record;
|
|
|
|
if (PrevDecl) {
|
2009-10-15 23:54:05 +08:00
|
|
|
MemberSpecializationInfo *MSInfo = PrevDecl->getMemberSpecializationInfo();
|
2010-06-12 15:44:57 +08:00
|
|
|
bool HasNoEffect = false;
|
2009-10-15 23:54:05 +08:00
|
|
|
assert(MSInfo && "No member specialization information?");
|
2011-01-27 15:10:08 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(TemplateLoc, TSK,
|
2009-10-15 23:54:05 +08:00
|
|
|
PrevDecl,
|
|
|
|
MSInfo->getTemplateSpecializationKind(),
|
2011-01-27 15:10:08 +08:00
|
|
|
MSInfo->getPointOfInstantiation(),
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect))
|
2009-10-15 23:54:05 +08:00
|
|
|
return true;
|
2010-06-12 15:44:57 +08:00
|
|
|
if (HasNoEffect)
|
2009-10-15 23:54:05 +08:00
|
|
|
return TagD;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-16 06:53:21 +08:00
|
|
|
CXXRecordDecl *RecordDef
|
2010-02-11 09:04:33 +08:00
|
|
|
= cast_or_null<CXXRecordDecl>(Record->getDefinition());
|
2009-10-16 06:53:21 +08:00
|
|
|
if (!RecordDef) {
|
2009-10-15 20:53:22 +08:00
|
|
|
// C++ [temp.explicit]p3:
|
2011-01-27 15:10:08 +08:00
|
|
|
// A definition of a member class of a class template shall be in scope
|
2009-10-15 20:53:22 +08:00
|
|
|
// at the point of an explicit instantiation of the member class.
|
2011-01-27 15:10:08 +08:00
|
|
|
CXXRecordDecl *Def
|
2010-02-11 09:04:33 +08:00
|
|
|
= cast_or_null<CXXRecordDecl>(Pattern->getDefinition());
|
2009-10-15 20:53:22 +08:00
|
|
|
if (!Def) {
|
2009-10-15 22:05:49 +08:00
|
|
|
Diag(TemplateLoc, diag::err_explicit_instantiation_undefined_member)
|
|
|
|
<< 0 << Record->getDeclName() << Record->getDeclContext();
|
2009-10-15 20:53:22 +08:00
|
|
|
Diag(Pattern->getLocation(), diag::note_forward_declaration)
|
|
|
|
<< Pattern;
|
|
|
|
return true;
|
2009-10-28 02:42:08 +08:00
|
|
|
} else {
|
|
|
|
if (InstantiateClass(NameLoc, Record, Def,
|
|
|
|
getTemplateInstantiationArgs(Record),
|
|
|
|
TSK))
|
|
|
|
return true;
|
|
|
|
|
2010-02-11 09:04:33 +08:00
|
|
|
RecordDef = cast_or_null<CXXRecordDecl>(Record->getDefinition());
|
2009-10-28 02:42:08 +08:00
|
|
|
if (!RecordDef)
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
}
|
|
|
|
|
2009-10-28 02:42:08 +08:00
|
|
|
// Instantiate all of the members of the class.
|
|
|
|
InstantiateClassMembers(NameLoc, RecordDef,
|
|
|
|
getTemplateInstantiationArgs(Record), TSK);
|
2009-05-14 08:28:11 +08:00
|
|
|
|
Rework when and how vtables are emitted, by tracking where vtables are
"used" (e.g., we will refer to the vtable in the generated code) and
when they are defined (i.e., because we've seen the key function
definition). Previously, we were effectively tracking "potential
definitions" rather than uses, so we were a bit too eager about emitting
vtables for classes without key functions.
The new scheme:
- For every use of a vtable, Sema calls MarkVTableUsed() to indicate
the use. For example, this occurs when calling a virtual member
function of the class, defining a constructor of that class type,
dynamic_cast'ing from that type to a derived class, casting
to/through a virtual base class, etc.
- For every definition of a vtable, Sema calls MarkVTableUsed() to
indicate the definition. This happens at the end of the translation
unit for classes whose key function has been defined (so we can
delay computation of the key function; see PR6564), and will also
occur with explicit template instantiation definitions.
- For every vtable defined/used, we mark all of the virtual member
functions of that vtable as defined/used, unless we know that the key
function is in another translation unit. This instantiates virtual
member functions when needed.
- At the end of the translation unit, Sema tells CodeGen (via the
ASTConsumer) which vtables must be defined (CodeGen will define
them) and which may be used (for which CodeGen will define the
vtables lazily).
From a language perspective, both the old and the new schemes are
permissible: we're allowed to instantiate virtual member functions
whenever we want per the standard. However, all other C++ compilers
were more lazy than we were, and our eagerness was both a performance
issue (we instantiated too much) and a portability problem (we broke
Boost test cases, which now pass).
Notes:
(1) There's a ton of churn in the tests, because the order in which
vtables get emitted to IR has changed. I've tried to isolate some of
the larger tests from these issues.
(2) Some diagnostics related to
implicitly-instantiated/implicitly-defined virtual member functions
have moved to the point of first use/definition. It's better this
way.
(3) I could use a review of the places where we MarkVTableUsed, to
see if I missed any place where the language effectively requires a
vtable.
Fixes PR7114 and PR6564.
llvm-svn: 103718
2010-05-14 00:44:06 +08:00
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition)
|
|
|
|
MarkVTableUsed(NameLoc, RecordDef, true);
|
|
|
|
|
2009-05-16 15:39:55 +08:00
|
|
|
// FIXME: We don't have any representation for explicit instantiations of
|
|
|
|
// member classes. Such a representation is not needed for compilation, but it
|
|
|
|
// should be available for clients that want to see all of the declarations in
|
|
|
|
// the source code.
|
2009-05-14 08:28:11 +08:00
|
|
|
return TagD;
|
2009-09-26 02:43:00 +08:00
|
|
|
}
|
|
|
|
|
2010-08-27 07:41:50 +08:00
|
|
|
DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
|
|
|
|
SourceLocation ExternLoc,
|
|
|
|
SourceLocation TemplateLoc,
|
|
|
|
Declarator &D) {
|
2009-09-26 02:43:00 +08:00
|
|
|
// Explicit instantiations always require a name.
|
2010-08-12 06:01:17 +08:00
|
|
|
// TODO: check if/when DNInfo should replace Name.
|
|
|
|
DeclarationNameInfo NameInfo = GetNameForDeclarator(D);
|
|
|
|
DeclarationName Name = NameInfo.getName();
|
2009-09-26 02:43:00 +08:00
|
|
|
if (!Name) {
|
|
|
|
if (!D.isInvalidType())
|
2012-03-10 02:35:03 +08:00
|
|
|
Diag(D.getDeclSpec().getLocStart(),
|
2009-09-26 02:43:00 +08:00
|
|
|
diag::err_explicit_instantiation_requires_name)
|
|
|
|
<< D.getDeclSpec().getSourceRange()
|
|
|
|
<< D.getSourceRange();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// The scope passed in may not be a decl scope. Zip up the scope tree until
|
|
|
|
// we find one that is.
|
|
|
|
while ((S->getFlags() & Scope::DeclScope) == 0 ||
|
|
|
|
(S->getFlags() & Scope::TemplateParamScope) != 0)
|
|
|
|
S = S->getParent();
|
|
|
|
|
|
|
|
// Determine the type of the declaration.
|
2010-06-05 07:28:52 +08:00
|
|
|
TypeSourceInfo *T = GetTypeForDeclarator(D, S);
|
|
|
|
QualType R = T->getType();
|
2009-09-26 02:43:00 +08:00
|
|
|
if (R.isNull())
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2011-05-22 02:53:30 +08:00
|
|
|
// C++ [dcl.stc]p1:
|
|
|
|
// A storage-class-specifier shall not be specified in [...] an explicit
|
|
|
|
// instantiation (14.7.2) directive.
|
2009-09-26 02:43:00 +08:00
|
|
|
if (D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_typedef) {
|
|
|
|
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_of_typedef)
|
|
|
|
<< Name;
|
|
|
|
return true;
|
2011-05-22 02:53:30 +08:00
|
|
|
} else if (D.getDeclSpec().getStorageClassSpec()
|
|
|
|
!= DeclSpec::SCS_unspecified) {
|
|
|
|
// Complain about then remove the storage class specifier.
|
|
|
|
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_storage_class)
|
|
|
|
<< FixItHint::CreateRemoval(D.getDeclSpec().getStorageClassSpecLoc());
|
|
|
|
|
|
|
|
D.getMutableDeclSpec().ClearStorageClassSpecs();
|
2009-09-26 02:43:00 +08:00
|
|
|
}
|
|
|
|
|
2009-10-15 04:14:33 +08:00
|
|
|
// C++0x [temp.explicit]p1:
|
|
|
|
// [...] An explicit instantiation of a function template shall not use the
|
|
|
|
// inline or constexpr specifiers.
|
|
|
|
// Presumably, this also applies to member functions of class templates as
|
|
|
|
// well.
|
2011-10-18 11:44:03 +08:00
|
|
|
if (D.getDeclSpec().isInlineSpecified())
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(D.getDeclSpec().getInlineSpecLoc(),
|
2012-03-11 15:00:24 +08:00
|
|
|
getLangOpts().CPlusPlus0x ?
|
2011-10-18 11:44:03 +08:00
|
|
|
diag::err_explicit_instantiation_inline :
|
|
|
|
diag::warn_explicit_instantiation_inline_0x)
|
2011-10-15 03:58:02 +08:00
|
|
|
<< FixItHint::CreateRemoval(D.getDeclSpec().getInlineSpecLoc());
|
|
|
|
if (D.getDeclSpec().isConstexprSpecified())
|
|
|
|
// FIXME: Add a fix-it to remove the 'constexpr' and add a 'const' if one is
|
|
|
|
// not already specified.
|
|
|
|
Diag(D.getDeclSpec().getConstexprSpecLoc(),
|
|
|
|
diag::err_explicit_instantiation_constexpr);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
|
|
|
// There are two forms of explicit instantiation: an explicit instantiation
|
2011-01-27 15:10:08 +08:00
|
|
|
// definition and an explicit instantiation declaration. An explicit
|
|
|
|
// instantiation declaration begins with the extern keyword. [...]
|
2009-09-26 02:43:00 +08:00
|
|
|
TemplateSpecializationKind TSK
|
|
|
|
= ExternLoc.isInvalid()? TSK_ExplicitInstantiationDefinition
|
|
|
|
: TSK_ExplicitInstantiationDeclaration;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-12 06:01:17 +08:00
|
|
|
LookupResult Previous(*this, NameInfo, LookupOrdinaryName);
|
2009-11-17 10:14:36 +08:00
|
|
|
LookupParsedName(Previous, S, &D.getCXXScopeSpec());
|
2009-09-26 02:43:00 +08:00
|
|
|
|
|
|
|
if (!R->isFunctionType()) {
|
|
|
|
// C++ [temp.explicit]p1:
|
2011-01-27 15:10:08 +08:00
|
|
|
// A [...] static data member of a class template can be explicitly
|
|
|
|
// instantiated from the member definition associated with its class
|
2009-09-26 02:43:00 +08:00
|
|
|
// template.
|
2009-11-17 10:14:36 +08:00
|
|
|
if (Previous.isAmbiguous())
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-12-02 16:25:40 +08:00
|
|
|
VarDecl *Prev = Previous.getAsSingle<VarDecl>();
|
2009-09-26 02:43:00 +08:00
|
|
|
if (!Prev || !Prev->isStaticDataMember()) {
|
|
|
|
// We expect to see a data data member here.
|
|
|
|
Diag(D.getIdentifierLoc(), diag::err_explicit_instantiation_not_known)
|
|
|
|
<< Name;
|
|
|
|
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
|
|
|
|
P != PEnd; ++P)
|
2009-10-10 05:13:30 +08:00
|
|
|
Diag((*P)->getLocation(), diag::note_explicit_instantiation_here);
|
2009-09-26 02:43:00 +08:00
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
if (!Prev->getInstantiatedFromStaticDataMember()) {
|
|
|
|
// FIXME: Check for explicit specialization?
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(D.getIdentifierLoc(),
|
2009-09-26 02:43:00 +08:00
|
|
|
diag::err_explicit_instantiation_data_member_not_instantiated)
|
|
|
|
<< Prev;
|
|
|
|
Diag(Prev->getLocation(), diag::note_explicit_instantiation_here);
|
|
|
|
// FIXME: Can we provide a note showing where this was declared?
|
|
|
|
return true;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
2011-01-27 15:10:08 +08:00
|
|
|
// If the explicit instantiation is for a member function, a member class
|
2009-10-15 07:41:34 +08:00
|
|
|
// or a static data member of a class template specialization, the name of
|
|
|
|
// the class template specialization in the qualified-id for the member
|
|
|
|
// name shall be a simple-template-id.
|
|
|
|
//
|
|
|
|
// C++98 has the same restriction, just worded differently.
|
|
|
|
if (!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(D.getIdentifierLoc(),
|
2010-06-17 00:26:47 +08:00
|
|
|
diag::ext_explicit_instantiation_without_qualified_id)
|
2009-10-15 07:41:34 +08:00
|
|
|
<< Prev << D.getCXXScopeSpec().getRange();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
// Check the scope of this explicit instantiation.
|
|
|
|
CheckExplicitInstantiationScope(*this, Prev, D.getIdentifierLoc(), true);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 23:54:05 +08:00
|
|
|
// Verify that it is okay to explicitly instantiate here.
|
|
|
|
MemberSpecializationInfo *MSInfo = Prev->getMemberSpecializationInfo();
|
|
|
|
assert(MSInfo && "Missing static data member specialization info?");
|
2010-06-12 15:44:57 +08:00
|
|
|
bool HasNoEffect = false;
|
2009-10-28 02:42:08 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK, Prev,
|
2009-10-15 23:54:05 +08:00
|
|
|
MSInfo->getTemplateSpecializationKind(),
|
2011-01-27 15:10:08 +08:00
|
|
|
MSInfo->getPointOfInstantiation(),
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect))
|
2009-10-15 23:54:05 +08:00
|
|
|
return true;
|
2010-06-12 15:44:57 +08:00
|
|
|
if (HasNoEffect)
|
2010-08-21 17:40:31 +08:00
|
|
|
return (Decl*) 0;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
// Instantiate static data member.
|
2009-10-16 01:21:20 +08:00
|
|
|
Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
|
2009-09-26 02:43:00 +08:00
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition)
|
2010-08-25 16:27:02 +08:00
|
|
|
InstantiateStaticDataMemberDefinition(D.getIdentifierLoc(), Prev);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
// FIXME: Create an ExplicitInstantiation node?
|
2010-08-21 17:40:31 +08:00
|
|
|
return (Decl*) 0;
|
2009-09-26 02:43:00 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
|
|
|
// If the declarator is a template-id, translate the parser's template
|
2009-09-26 07:53:26 +08:00
|
|
|
// argument list into our AST format.
|
2009-09-26 05:45:23 +08:00
|
|
|
bool HasExplicitTemplateArgs = false;
|
2009-11-23 09:53:49 +08:00
|
|
|
TemplateArgumentListInfo TemplateArgs;
|
2009-11-03 09:35:08 +08:00
|
|
|
if (D.getName().getKind() == UnqualifiedId::IK_TemplateId) {
|
|
|
|
TemplateIdAnnotation *TemplateId = D.getName().TemplateId;
|
2009-11-23 09:53:49 +08:00
|
|
|
TemplateArgs.setLAngleLoc(TemplateId->LAngleLoc);
|
|
|
|
TemplateArgs.setRAngleLoc(TemplateId->RAngleLoc);
|
2009-09-26 05:45:23 +08:00
|
|
|
ASTTemplateArgsPtr TemplateArgsPtr(*this,
|
|
|
|
TemplateId->getTemplateArgs(),
|
|
|
|
TemplateId->NumArgs);
|
2009-11-23 09:53:49 +08:00
|
|
|
translateTemplateArguments(TemplateArgsPtr, TemplateArgs);
|
2009-09-26 05:45:23 +08:00
|
|
|
HasExplicitTemplateArgs = true;
|
2009-10-02 07:51:25 +08:00
|
|
|
TemplateArgsPtr.release();
|
2009-09-26 05:45:23 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
// C++ [temp.explicit]p1:
|
2011-01-27 15:10:08 +08:00
|
|
|
// A [...] function [...] can be explicitly instantiated from its template.
|
|
|
|
// A member function [...] of a class template can be explicitly
|
|
|
|
// instantiated from the member definition associated with its class
|
2009-09-26 02:43:00 +08:00
|
|
|
// template.
|
2010-01-27 09:50:18 +08:00
|
|
|
UnresolvedSet<8> Matches;
|
2009-09-26 02:43:00 +08:00
|
|
|
for (LookupResult::iterator P = Previous.begin(), PEnd = Previous.end();
|
|
|
|
P != PEnd; ++P) {
|
|
|
|
NamedDecl *Prev = *P;
|
2009-09-26 05:45:23 +08:00
|
|
|
if (!HasExplicitTemplateArgs) {
|
|
|
|
if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(Prev)) {
|
|
|
|
if (Context.hasSameUnqualifiedType(Method->getType(), R)) {
|
|
|
|
Matches.clear();
|
2010-01-12 02:40:55 +08:00
|
|
|
|
2010-01-27 09:50:18 +08:00
|
|
|
Matches.addDecl(Method, P.getAccess());
|
2010-01-12 02:40:55 +08:00
|
|
|
if (Method->getTemplateSpecializationKind() == TSK_Undeclared)
|
|
|
|
break;
|
2009-09-26 05:45:23 +08:00
|
|
|
}
|
2009-09-26 02:43:00 +08:00
|
|
|
}
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(Prev);
|
|
|
|
if (!FunTmpl)
|
|
|
|
continue;
|
|
|
|
|
2010-02-09 07:07:23 +08:00
|
|
|
TemplateDeductionInfo Info(Context, D.getIdentifierLoc());
|
2009-09-26 02:43:00 +08:00
|
|
|
FunctionDecl *Specialization = 0;
|
|
|
|
if (TemplateDeductionResult TDK
|
2011-01-27 15:10:08 +08:00
|
|
|
= DeduceTemplateArguments(FunTmpl,
|
2009-11-23 09:53:49 +08:00
|
|
|
(HasExplicitTemplateArgs ? &TemplateArgs : 0),
|
2009-09-26 02:43:00 +08:00
|
|
|
R, Specialization, Info)) {
|
|
|
|
// FIXME: Keep track of almost-matches?
|
|
|
|
(void)TDK;
|
|
|
|
continue;
|
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-01-27 09:50:18 +08:00
|
|
|
Matches.addDecl(Specialization, P.getAccess());
|
2009-09-26 02:43:00 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
// Find the most specialized function template specialization.
|
2010-01-27 09:50:18 +08:00
|
|
|
UnresolvedSetIterator Result
|
2011-01-12 01:34:58 +08:00
|
|
|
= getMostSpecialized(Matches.begin(), Matches.end(), TPOC_Other, 0,
|
2011-01-27 15:10:08 +08:00
|
|
|
D.getIdentifierLoc(),
|
2010-03-30 07:34:08 +08:00
|
|
|
PDiag(diag::err_explicit_instantiation_not_known) << Name,
|
|
|
|
PDiag(diag::err_explicit_instantiation_ambiguous) << Name,
|
|
|
|
PDiag(diag::note_explicit_instantiation_candidate));
|
2009-09-26 02:43:00 +08:00
|
|
|
|
2010-01-27 09:50:18 +08:00
|
|
|
if (Result == Matches.end())
|
2009-09-26 02:43:00 +08:00
|
|
|
return true;
|
2010-01-27 09:50:18 +08:00
|
|
|
|
|
|
|
// Ignore access control bits, we don't need them for redeclaration checking.
|
|
|
|
FunctionDecl *Specialization = cast<FunctionDecl>(*Result);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-16 01:21:20 +08:00
|
|
|
if (Specialization->getTemplateSpecializationKind() == TSK_Undeclared) {
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(D.getIdentifierLoc(),
|
2009-09-26 02:43:00 +08:00
|
|
|
diag::err_explicit_instantiation_member_function_not_instantiated)
|
|
|
|
<< Specialization
|
|
|
|
<< (Specialization->getTemplateSpecializationKind() ==
|
|
|
|
TSK_ExplicitSpecialization);
|
|
|
|
Diag(Specialization->getLocation(), diag::note_explicit_instantiation_here);
|
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
}
|
|
|
|
|
2012-01-15 00:38:05 +08:00
|
|
|
FunctionDecl *PrevDecl = Specialization->getPreviousDecl();
|
2009-10-16 02:07:02 +08:00
|
|
|
if (!PrevDecl && Specialization->isThisDeclarationADefinition())
|
|
|
|
PrevDecl = Specialization;
|
|
|
|
|
2009-10-16 01:21:20 +08:00
|
|
|
if (PrevDecl) {
|
2010-06-12 15:44:57 +08:00
|
|
|
bool HasNoEffect = false;
|
2009-10-28 02:42:08 +08:00
|
|
|
if (CheckSpecializationInstantiationRedecl(D.getIdentifierLoc(), TSK,
|
2011-01-27 15:10:08 +08:00
|
|
|
PrevDecl,
|
|
|
|
PrevDecl->getTemplateSpecializationKind(),
|
2009-10-16 01:21:20 +08:00
|
|
|
PrevDecl->getPointOfInstantiation(),
|
2010-06-12 15:44:57 +08:00
|
|
|
HasNoEffect))
|
2009-10-16 01:21:20 +08:00
|
|
|
return true;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-16 01:21:20 +08:00
|
|
|
// FIXME: We may still want to build some representation of this
|
|
|
|
// explicit specialization.
|
2010-06-12 15:44:57 +08:00
|
|
|
if (HasNoEffect)
|
2010-08-21 17:40:31 +08:00
|
|
|
return (Decl*) 0;
|
2009-09-26 02:43:00 +08:00
|
|
|
}
|
2009-11-24 13:34:41 +08:00
|
|
|
|
|
|
|
Specialization->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
|
2012-01-04 13:40:59 +08:00
|
|
|
AttributeList *Attr = D.getDeclSpec().getAttributes().getList();
|
|
|
|
if (Attr)
|
|
|
|
ProcessDeclAttributeList(S, Specialization, Attr);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-16 01:21:20 +08:00
|
|
|
if (TSK == TSK_ExplicitInstantiationDefinition)
|
2010-08-25 16:27:02 +08:00
|
|
|
InstantiateFunctionDefinition(D.getIdentifierLoc(), Specialization);
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
// C++0x [temp.explicit]p2:
|
2011-01-27 15:10:08 +08:00
|
|
|
// If the explicit instantiation is for a member function, a member class
|
2009-10-15 07:41:34 +08:00
|
|
|
// or a static data member of a class template specialization, the name of
|
|
|
|
// the class template specialization in the qualified-id for the member
|
|
|
|
// name shall be a simple-template-id.
|
|
|
|
//
|
|
|
|
// C++98 has the same restriction, just worded differently.
|
2009-10-16 01:21:20 +08:00
|
|
|
FunctionTemplateDecl *FunTmpl = Specialization->getPrimaryTemplate();
|
2009-11-03 09:35:08 +08:00
|
|
|
if (D.getName().getKind() != UnqualifiedId::IK_TemplateId && !FunTmpl &&
|
2011-01-27 15:10:08 +08:00
|
|
|
D.getCXXScopeSpec().isSet() &&
|
2009-10-15 07:41:34 +08:00
|
|
|
!ScopeSpecifierHasTemplateId(D.getCXXScopeSpec()))
|
2011-01-27 15:10:08 +08:00
|
|
|
Diag(D.getIdentifierLoc(),
|
2010-06-17 00:26:47 +08:00
|
|
|
diag::ext_explicit_instantiation_without_qualified_id)
|
2009-10-15 07:41:34 +08:00
|
|
|
<< Specialization << D.getCXXScopeSpec().getRange();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-10-15 07:41:34 +08:00
|
|
|
CheckExplicitInstantiationScope(*this,
|
2011-01-27 15:10:08 +08:00
|
|
|
FunTmpl? (NamedDecl *)FunTmpl
|
2009-10-15 07:41:34 +08:00
|
|
|
: Specialization->getInstantiatedFromMemberFunction(),
|
2011-01-27 15:10:08 +08:00
|
|
|
D.getIdentifierLoc(),
|
2009-10-15 07:41:34 +08:00
|
|
|
D.getCXXScopeSpec().isSet());
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-26 02:43:00 +08:00
|
|
|
// FIXME: Create some kind of ExplicitInstantiationDecl here.
|
2010-08-21 17:40:31 +08:00
|
|
|
return (Decl*) 0;
|
2009-05-14 08:28:11 +08:00
|
|
|
}
|
|
|
|
|
2010-08-27 07:41:50 +08:00
|
|
|
TypeResult
|
2009-09-11 12:59:25 +08:00
|
|
|
Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
|
|
|
const CXXScopeSpec &SS, IdentifierInfo *Name,
|
|
|
|
SourceLocation TagLoc, SourceLocation NameLoc) {
|
|
|
|
// This has to hold, because SS is expected to be defined.
|
|
|
|
assert(Name && "Expected a name in a dependent tag");
|
|
|
|
|
|
|
|
NestedNameSpecifier *NNS
|
|
|
|
= static_cast<NestedNameSpecifier *>(SS.getScopeRep());
|
|
|
|
if (!NNS)
|
|
|
|
return true;
|
|
|
|
|
2010-05-12 05:36:43 +08:00
|
|
|
TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForTypeSpec(TagSpec);
|
2010-04-02 00:50:48 +08:00
|
|
|
|
2010-04-25 00:38:41 +08:00
|
|
|
if (TUK == TUK_Declaration || TUK == TUK_Definition) {
|
|
|
|
Diag(NameLoc, diag::err_dependent_tag_decl)
|
2010-05-12 05:36:43 +08:00
|
|
|
<< (TUK == TUK_Definition) << Kind << SS.getRange();
|
2010-04-25 00:38:41 +08:00
|
|
|
return true;
|
|
|
|
}
|
2010-05-12 05:36:43 +08:00
|
|
|
|
2011-03-02 08:47:37 +08:00
|
|
|
// Create the resulting type.
|
2010-05-12 05:36:43 +08:00
|
|
|
ElaboratedTypeKeyword Kwd = TypeWithKeyword::getKeywordForTagTypeKind(Kind);
|
2011-03-02 08:47:37 +08:00
|
|
|
QualType Result = Context.getDependentNameType(Kwd, NNS, Name);
|
|
|
|
|
|
|
|
// Create type-source location information for this type.
|
|
|
|
TypeLocBuilder TLB;
|
|
|
|
DependentNameTypeLoc TL = TLB.push<DependentNameTypeLoc>(Result);
|
2012-02-07 03:09:27 +08:00
|
|
|
TL.setElaboratedKeywordLoc(TagLoc);
|
2011-03-02 08:47:37 +08:00
|
|
|
TL.setQualifierLoc(SS.getWithLocInContext(Context));
|
|
|
|
TL.setNameLoc(NameLoc);
|
|
|
|
return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result));
|
2009-09-11 12:59:25 +08:00
|
|
|
}
|
|
|
|
|
2010-08-27 07:41:50 +08:00
|
|
|
TypeResult
|
2011-01-27 15:10:08 +08:00
|
|
|
Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
|
|
|
|
const CXXScopeSpec &SS, const IdentifierInfo &II,
|
2010-06-17 06:31:08 +08:00
|
|
|
SourceLocation IdLoc) {
|
2011-03-01 06:42:13 +08:00
|
|
|
if (SS.isInvalid())
|
2009-03-28 07:10:48 +08:00
|
|
|
return true;
|
2011-03-01 06:42:13 +08:00
|
|
|
|
2011-10-19 04:49:44 +08:00
|
|
|
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
|
|
|
|
Diag(TypenameLoc,
|
2012-03-11 15:00:24 +08:00
|
|
|
getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_typename_outside_of_template :
|
|
|
|
diag::ext_typename_outside_of_template)
|
2011-01-27 15:10:08 +08:00
|
|
|
<< FixItHint::CreateRemoval(TypenameLoc);
|
|
|
|
|
2011-03-01 09:34:45 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
|
2011-03-02 02:12:44 +08:00
|
|
|
QualType T = CheckTypenameType(TypenameLoc.isValid()? ETK_Typename : ETK_None,
|
|
|
|
TypenameLoc, QualifierLoc, II, IdLoc);
|
2009-04-02 05:51:26 +08:00
|
|
|
if (T.isNull())
|
|
|
|
return true;
|
2010-04-30 07:50:39 +08:00
|
|
|
|
|
|
|
TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
|
|
|
|
if (isa<DependentNameType>(T)) {
|
|
|
|
DependentNameTypeLoc TL = cast<DependentNameTypeLoc>(TSI->getTypeLoc());
|
2012-02-07 03:09:27 +08:00
|
|
|
TL.setElaboratedKeywordLoc(TypenameLoc);
|
2011-03-01 09:34:45 +08:00
|
|
|
TL.setQualifierLoc(QualifierLoc);
|
2010-05-29 07:32:21 +08:00
|
|
|
TL.setNameLoc(IdLoc);
|
2010-04-30 07:50:39 +08:00
|
|
|
} else {
|
2010-05-12 05:36:43 +08:00
|
|
|
ElaboratedTypeLoc TL = cast<ElaboratedTypeLoc>(TSI->getTypeLoc());
|
2012-02-07 03:09:27 +08:00
|
|
|
TL.setElaboratedKeywordLoc(TypenameLoc);
|
2011-03-02 02:12:44 +08:00
|
|
|
TL.setQualifierLoc(QualifierLoc);
|
2010-05-29 07:32:21 +08:00
|
|
|
cast<TypeSpecTypeLoc>(TL.getNamedTypeLoc()).setNameLoc(IdLoc);
|
2010-04-30 07:50:39 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-08-24 13:47:05 +08:00
|
|
|
return CreateParsedType(T, TSI);
|
2009-03-28 07:10:48 +08:00
|
|
|
}
|
|
|
|
|
2010-08-27 07:41:50 +08:00
|
|
|
TypeResult
|
2012-02-06 22:41:24 +08:00
|
|
|
Sema::ActOnTypenameType(Scope *S,
|
|
|
|
SourceLocation TypenameLoc,
|
|
|
|
const CXXScopeSpec &SS,
|
|
|
|
SourceLocation TemplateKWLoc,
|
2011-02-28 06:46:49 +08:00
|
|
|
TemplateTy TemplateIn,
|
|
|
|
SourceLocation TemplateNameLoc,
|
|
|
|
SourceLocation LAngleLoc,
|
|
|
|
ASTTemplateArgsPtr TemplateArgsIn,
|
|
|
|
SourceLocation RAngleLoc) {
|
2011-10-19 04:49:44 +08:00
|
|
|
if (TypenameLoc.isValid() && S && !S->getTemplateParamParent())
|
|
|
|
Diag(TypenameLoc,
|
2012-03-11 15:00:24 +08:00
|
|
|
getLangOpts().CPlusPlus0x ?
|
2011-10-19 04:49:44 +08:00
|
|
|
diag::warn_cxx98_compat_typename_outside_of_template :
|
|
|
|
diag::ext_typename_outside_of_template)
|
|
|
|
<< FixItHint::CreateRemoval(TypenameLoc);
|
2011-02-28 06:46:49 +08:00
|
|
|
|
|
|
|
// Translate the parser's template argument list in our AST format.
|
|
|
|
TemplateArgumentListInfo TemplateArgs(LAngleLoc, RAngleLoc);
|
|
|
|
translateTemplateArguments(TemplateArgsIn, TemplateArgs);
|
|
|
|
|
|
|
|
TemplateName Template = TemplateIn.get();
|
2011-03-02 00:44:30 +08:00
|
|
|
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
|
|
|
|
// Construct a dependent template specialization type.
|
|
|
|
assert(DTN && "dependent template has non-dependent name?");
|
|
|
|
assert(DTN->getQualifier()
|
|
|
|
== static_cast<NestedNameSpecifier*>(SS.getScopeRep()));
|
|
|
|
QualType T = Context.getDependentTemplateSpecializationType(ETK_Typename,
|
|
|
|
DTN->getQualifier(),
|
|
|
|
DTN->getIdentifier(),
|
|
|
|
TemplateArgs);
|
2011-02-28 06:46:49 +08:00
|
|
|
|
2011-03-02 00:44:30 +08:00
|
|
|
// Create source-location information for this type.
|
2010-05-29 07:32:21 +08:00
|
|
|
TypeLocBuilder Builder;
|
2011-03-02 00:44:30 +08:00
|
|
|
DependentTemplateSpecializationTypeLoc SpecTL
|
|
|
|
= Builder.push<DependentTemplateSpecializationTypeLoc>(T);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setElaboratedKeywordLoc(TypenameLoc);
|
|
|
|
SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
|
2012-02-07 06:45:07 +08:00
|
|
|
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setTemplateNameLoc(TemplateNameLoc);
|
2011-02-28 06:46:49 +08:00
|
|
|
SpecTL.setLAngleLoc(LAngleLoc);
|
|
|
|
SpecTL.setRAngleLoc(RAngleLoc);
|
|
|
|
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
|
|
|
|
SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
|
2011-03-02 00:44:30 +08:00
|
|
|
return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
|
2009-09-02 21:05:45 +08:00
|
|
|
}
|
2011-02-28 06:46:49 +08:00
|
|
|
|
2011-03-02 00:44:30 +08:00
|
|
|
QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
|
|
|
|
if (T.isNull())
|
|
|
|
return true;
|
2011-02-28 06:46:49 +08:00
|
|
|
|
2012-02-06 22:41:24 +08:00
|
|
|
// Provide source-location information for the template specialization type.
|
2011-02-28 06:46:49 +08:00
|
|
|
TypeLocBuilder Builder;
|
2012-02-06 22:41:24 +08:00
|
|
|
TemplateSpecializationTypeLoc SpecTL
|
2011-03-02 00:44:30 +08:00
|
|
|
= Builder.push<TemplateSpecializationTypeLoc>(T);
|
2012-02-06 22:41:24 +08:00
|
|
|
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
|
|
|
|
SpecTL.setTemplateNameLoc(TemplateNameLoc);
|
2011-02-28 06:46:49 +08:00
|
|
|
SpecTL.setLAngleLoc(LAngleLoc);
|
|
|
|
SpecTL.setRAngleLoc(RAngleLoc);
|
|
|
|
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
|
|
|
|
SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
|
|
|
|
|
2011-03-02 00:44:30 +08:00
|
|
|
T = Context.getElaboratedType(ETK_Typename, SS.getScopeRep(), T);
|
|
|
|
ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
|
2012-02-07 03:09:27 +08:00
|
|
|
TL.setElaboratedKeywordLoc(TypenameLoc);
|
2011-03-02 02:12:44 +08:00
|
|
|
TL.setQualifierLoc(SS.getWithLocInContext(Context));
|
|
|
|
|
2011-03-02 00:44:30 +08:00
|
|
|
TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
|
|
|
|
return CreateParsedType(T, TSI);
|
2009-04-01 08:28:59 +08:00
|
|
|
}
|
|
|
|
|
2011-02-28 06:46:49 +08:00
|
|
|
|
2009-03-28 07:10:48 +08:00
|
|
|
/// \brief Build the type that describes a C++ typename specifier,
|
|
|
|
/// e.g., "typename T::type".
|
|
|
|
QualType
|
2011-03-01 06:42:13 +08:00
|
|
|
Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
|
|
|
|
SourceLocation KeywordLoc,
|
|
|
|
NestedNameSpecifierLoc QualifierLoc,
|
|
|
|
const IdentifierInfo &II,
|
2010-05-20 05:37:53 +08:00
|
|
|
SourceLocation IILoc) {
|
2010-05-01 08:40:08 +08:00
|
|
|
CXXScopeSpec SS;
|
2011-03-01 06:42:13 +08:00
|
|
|
SS.Adopt(QualifierLoc);
|
2010-05-01 08:40:08 +08:00
|
|
|
|
|
|
|
DeclContext *Ctx = computeDeclContext(SS);
|
|
|
|
if (!Ctx) {
|
|
|
|
// If the nested-name-specifier is dependent and couldn't be
|
|
|
|
// resolved to a type, build a typename type.
|
2011-03-01 06:42:13 +08:00
|
|
|
assert(QualifierLoc.getNestedNameSpecifier()->isDependent());
|
|
|
|
return Context.getDependentNameType(Keyword,
|
|
|
|
QualifierLoc.getNestedNameSpecifier(),
|
|
|
|
&II);
|
2009-05-12 03:58:34 +08:00
|
|
|
}
|
2009-03-28 07:10:48 +08:00
|
|
|
|
2010-05-01 08:40:08 +08:00
|
|
|
// If the nested-name-specifier refers to the current instantiation,
|
|
|
|
// the "typename" keyword itself is superfluous. In C++03, the
|
|
|
|
// program is actually ill-formed. However, DR 382 (in C++0x CD1)
|
|
|
|
// allows such extraneous "typename" keywords, and we retroactively
|
2010-06-15 06:07:54 +08:00
|
|
|
// apply this DR to C++03 code with only a warning. In any case we continue.
|
2009-03-28 07:10:48 +08:00
|
|
|
|
2010-05-01 08:40:08 +08:00
|
|
|
if (RequireCompleteDeclContext(SS, Ctx))
|
|
|
|
return QualType();
|
2009-03-28 07:10:48 +08:00
|
|
|
|
|
|
|
DeclarationName Name(&II);
|
2010-05-20 05:37:53 +08:00
|
|
|
LookupResult Result(*this, Name, IILoc, LookupOrdinaryName);
|
2009-11-17 10:14:36 +08:00
|
|
|
LookupQualifiedName(Result, Ctx);
|
2009-03-28 07:10:48 +08:00
|
|
|
unsigned DiagID = 0;
|
|
|
|
Decl *Referenced = 0;
|
2009-11-17 10:14:36 +08:00
|
|
|
switch (Result.getResultKind()) {
|
2009-03-28 07:10:48 +08:00
|
|
|
case LookupResult::NotFound:
|
2009-10-14 05:16:44 +08:00
|
|
|
DiagID = diag::err_typename_nested_not_found;
|
2009-03-28 07:10:48 +08:00
|
|
|
break;
|
2010-12-09 08:06:27 +08:00
|
|
|
|
|
|
|
case LookupResult::FoundUnresolvedValue: {
|
|
|
|
// We found a using declaration that is a value. Most likely, the using
|
|
|
|
// declaration itself is meant to have the 'typename' keyword.
|
2011-03-01 06:42:13 +08:00
|
|
|
SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(),
|
2010-12-09 08:06:27 +08:00
|
|
|
IILoc);
|
|
|
|
Diag(IILoc, diag::err_typename_refers_to_using_value_decl)
|
|
|
|
<< Name << Ctx << FullRange;
|
|
|
|
if (UnresolvedUsingValueDecl *Using
|
|
|
|
= dyn_cast<UnresolvedUsingValueDecl>(Result.getRepresentativeDecl())){
|
2011-02-25 08:36:19 +08:00
|
|
|
SourceLocation Loc = Using->getQualifierLoc().getBeginLoc();
|
2010-12-09 08:06:27 +08:00
|
|
|
Diag(Loc, diag::note_using_value_decl_missing_typename)
|
|
|
|
<< FixItHint::CreateInsertion(Loc, "typename ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Fall through to create a dependent typename type, from which we can recover
|
|
|
|
// better.
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-01-15 09:44:47 +08:00
|
|
|
case LookupResult::NotFoundInCurrentInstantiation:
|
|
|
|
// Okay, it's a member of an unknown instantiation.
|
2011-03-01 06:42:13 +08:00
|
|
|
return Context.getDependentNameType(Keyword,
|
|
|
|
QualifierLoc.getNestedNameSpecifier(),
|
|
|
|
&II);
|
2009-03-28 07:10:48 +08:00
|
|
|
|
|
|
|
case LookupResult::Found:
|
2011-01-27 15:10:08 +08:00
|
|
|
if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
|
2010-05-12 05:36:43 +08:00
|
|
|
// We found a type. Build an ElaboratedType, since the
|
|
|
|
// typename-specifier was just sugar.
|
2011-03-01 06:42:13 +08:00
|
|
|
return Context.getElaboratedType(ETK_Typename,
|
|
|
|
QualifierLoc.getNestedNameSpecifier(),
|
2010-05-12 05:36:43 +08:00
|
|
|
Context.getTypeDeclType(Type));
|
2009-03-28 07:10:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
DiagID = diag::err_typename_nested_not_type;
|
2009-10-10 05:13:30 +08:00
|
|
|
Referenced = Result.getFoundDecl();
|
2009-03-28 07:10:48 +08:00
|
|
|
break;
|
|
|
|
|
|
|
|
case LookupResult::FoundOverloaded:
|
|
|
|
DiagID = diag::err_typename_nested_not_type;
|
|
|
|
Referenced = *Result.begin();
|
|
|
|
break;
|
|
|
|
|
2009-10-10 13:48:19 +08:00
|
|
|
case LookupResult::Ambiguous:
|
2009-03-28 07:10:48 +08:00
|
|
|
return QualType();
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we get here, it's because name lookup did not find a
|
|
|
|
// type. Emit an appropriate diagnostic and return an error.
|
2011-03-01 06:42:13 +08:00
|
|
|
SourceRange FullRange(KeywordLoc.isValid() ? KeywordLoc : SS.getBeginLoc(),
|
2010-05-20 05:37:53 +08:00
|
|
|
IILoc);
|
|
|
|
Diag(IILoc, DiagID) << FullRange << Name << Ctx;
|
2009-03-28 07:10:48 +08:00
|
|
|
if (Referenced)
|
|
|
|
Diag(Referenced->getLocation(), diag::note_typename_refers_here)
|
|
|
|
<< Name;
|
|
|
|
return QualType();
|
|
|
|
}
|
2009-08-07 00:20:37 +08:00
|
|
|
|
|
|
|
namespace {
|
|
|
|
// See Sema::RebuildTypeInCurrentInstantiation
|
2009-11-29 03:45:26 +08:00
|
|
|
class CurrentInstantiationRebuilder
|
2009-09-09 23:08:12 +08:00
|
|
|
: public TreeTransform<CurrentInstantiationRebuilder> {
|
2009-08-07 00:20:37 +08:00
|
|
|
SourceLocation Loc;
|
|
|
|
DeclarationName Entity;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-07 00:20:37 +08:00
|
|
|
public:
|
2010-05-01 02:55:50 +08:00
|
|
|
typedef TreeTransform<CurrentInstantiationRebuilder> inherited;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-09 23:08:12 +08:00
|
|
|
CurrentInstantiationRebuilder(Sema &SemaRef,
|
2009-08-07 00:20:37 +08:00
|
|
|
SourceLocation Loc,
|
2009-09-09 23:08:12 +08:00
|
|
|
DeclarationName Entity)
|
|
|
|
: TreeTransform<CurrentInstantiationRebuilder>(SemaRef),
|
2009-08-07 00:20:37 +08:00
|
|
|
Loc(Loc), Entity(Entity) { }
|
2009-09-09 23:08:12 +08:00
|
|
|
|
|
|
|
/// \brief Determine whether the given type \p T has already been
|
2009-08-07 00:20:37 +08:00
|
|
|
/// transformed.
|
|
|
|
///
|
|
|
|
/// For the purposes of type reconstruction, a type has already been
|
|
|
|
/// transformed if it is NULL or if it is not dependent.
|
|
|
|
bool AlreadyTransformed(QualType T) {
|
|
|
|
return T.isNull() || !T->isDependentType();
|
|
|
|
}
|
2009-09-09 23:08:12 +08:00
|
|
|
|
|
|
|
/// \brief Returns the location of the entity whose type is being
|
2009-08-07 00:20:37 +08:00
|
|
|
/// rebuilt.
|
|
|
|
SourceLocation getBaseLocation() { return Loc; }
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-07 00:20:37 +08:00
|
|
|
/// \brief Returns the name of the entity whose type is being rebuilt.
|
|
|
|
DeclarationName getBaseEntity() { return Entity; }
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-10-27 14:26:26 +08:00
|
|
|
/// \brief Sets the "base" location and entity when that
|
|
|
|
/// information is known based on another transformation.
|
|
|
|
void setBase(SourceLocation Loc, DeclarationName Entity) {
|
|
|
|
this->Loc = Loc;
|
|
|
|
this->Entity = Entity;
|
|
|
|
}
|
2012-02-14 06:00:16 +08:00
|
|
|
|
|
|
|
ExprResult TransformLambdaExpr(LambdaExpr *E) {
|
|
|
|
// Lambdas never need to be transformed.
|
|
|
|
return E;
|
|
|
|
}
|
2009-08-07 00:20:37 +08:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
/// \brief Rebuilds a type within the context of the current instantiation.
|
|
|
|
///
|
2009-09-09 23:08:12 +08:00
|
|
|
/// The type \p T is part of the type of an out-of-line member definition of
|
2009-08-07 00:20:37 +08:00
|
|
|
/// a class template (or class template partial specialization) that was parsed
|
2009-09-09 23:08:12 +08:00
|
|
|
/// and constructed before we entered the scope of the class template (or
|
2009-08-07 00:20:37 +08:00
|
|
|
/// partial specialization thereof). This routine will rebuild that type now
|
|
|
|
/// that we have entered the declarator's scope, which may produce different
|
|
|
|
/// canonical types, e.g.,
|
|
|
|
///
|
|
|
|
/// \code
|
|
|
|
/// template<typename T>
|
|
|
|
/// struct X {
|
|
|
|
/// typedef T* pointer;
|
|
|
|
/// pointer data();
|
|
|
|
/// };
|
|
|
|
///
|
|
|
|
/// template<typename T>
|
|
|
|
/// typename X<T>::pointer X<T>::data() { ... }
|
|
|
|
/// \endcode
|
|
|
|
///
|
2010-04-01 01:34:00 +08:00
|
|
|
/// Here, the type "typename X<T>::pointer" will be created as a DependentNameType,
|
2009-08-07 00:20:37 +08:00
|
|
|
/// since we do not know that we can look into X<T> when we parsed the type.
|
|
|
|
/// This function will rebuild the type, performing the lookup of "pointer"
|
2010-05-12 05:36:43 +08:00
|
|
|
/// in X<T> and returning an ElaboratedType whose canonical type is the same
|
2009-08-07 00:20:37 +08:00
|
|
|
/// as the canonical type of T*, allowing the return types of the out-of-line
|
|
|
|
/// definition and the declaration to match.
|
2010-04-30 07:50:39 +08:00
|
|
|
TypeSourceInfo *Sema::RebuildTypeInCurrentInstantiation(TypeSourceInfo *T,
|
|
|
|
SourceLocation Loc,
|
|
|
|
DeclarationName Name) {
|
|
|
|
if (!T || !T->getType()->isDependentType())
|
2009-08-07 00:20:37 +08:00
|
|
|
return T;
|
2009-09-09 23:08:12 +08:00
|
|
|
|
2009-08-07 00:20:37 +08:00
|
|
|
CurrentInstantiationRebuilder Rebuilder(*this, Loc, Name);
|
|
|
|
return Rebuilder.TransformType(T);
|
2009-08-12 06:33:06 +08:00
|
|
|
}
|
2009-09-16 00:23:51 +08:00
|
|
|
|
2010-08-24 14:29:42 +08:00
|
|
|
ExprResult Sema::RebuildExprInCurrentInstantiation(Expr *E) {
|
2010-08-24 13:47:05 +08:00
|
|
|
CurrentInstantiationRebuilder Rebuilder(*this, E->getExprLoc(),
|
|
|
|
DeclarationName());
|
|
|
|
return Rebuilder.TransformExpr(E);
|
|
|
|
}
|
|
|
|
|
2010-04-30 07:50:39 +08:00
|
|
|
bool Sema::RebuildNestedNameSpecifierInCurrentInstantiation(CXXScopeSpec &SS) {
|
2011-02-26 00:07:42 +08:00
|
|
|
if (SS.isInvalid())
|
|
|
|
return true;
|
2010-04-27 08:57:59 +08:00
|
|
|
|
2011-02-26 00:07:42 +08:00
|
|
|
NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(Context);
|
2010-04-27 08:57:59 +08:00
|
|
|
CurrentInstantiationRebuilder Rebuilder(*this, SS.getRange().getBegin(),
|
|
|
|
DeclarationName());
|
2011-02-26 00:07:42 +08:00
|
|
|
NestedNameSpecifierLoc Rebuilt
|
|
|
|
= Rebuilder.TransformNestedNameSpecifierLoc(QualifierLoc);
|
|
|
|
if (!Rebuilt)
|
|
|
|
return true;
|
2010-04-30 07:50:39 +08:00
|
|
|
|
2011-02-26 00:07:42 +08:00
|
|
|
SS.Adopt(Rebuilt);
|
2010-04-30 07:50:39 +08:00
|
|
|
return false;
|
2010-04-27 08:57:59 +08:00
|
|
|
}
|
|
|
|
|
2011-10-14 23:31:12 +08:00
|
|
|
/// \brief Rebuild the template parameters now that we know we're in a current
|
|
|
|
/// instantiation.
|
|
|
|
bool Sema::RebuildTemplateParamsInCurrentInstantiation(
|
|
|
|
TemplateParameterList *Params) {
|
|
|
|
for (unsigned I = 0, N = Params->size(); I != N; ++I) {
|
|
|
|
Decl *Param = Params->getParam(I);
|
|
|
|
|
|
|
|
// There is nothing to rebuild in a type parameter.
|
|
|
|
if (isa<TemplateTypeParmDecl>(Param))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
// Rebuild the template parameter list of a template template parameter.
|
|
|
|
if (TemplateTemplateParmDecl *TTP
|
|
|
|
= dyn_cast<TemplateTemplateParmDecl>(Param)) {
|
|
|
|
if (RebuildTemplateParamsInCurrentInstantiation(
|
|
|
|
TTP->getTemplateParameters()))
|
|
|
|
return true;
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Rebuild the type of a non-type template parameter.
|
|
|
|
NonTypeTemplateParmDecl *NTTP = cast<NonTypeTemplateParmDecl>(Param);
|
|
|
|
TypeSourceInfo *NewTSI
|
|
|
|
= RebuildTypeInCurrentInstantiation(NTTP->getTypeSourceInfo(),
|
|
|
|
NTTP->getLocation(),
|
|
|
|
NTTP->getDeclName());
|
|
|
|
if (!NewTSI)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
if (NewTSI != NTTP->getTypeSourceInfo()) {
|
|
|
|
NTTP->setTypeSourceInfo(NewTSI);
|
|
|
|
NTTP->setType(NewTSI->getType());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2009-09-16 00:23:51 +08:00
|
|
|
/// \brief Produces a formatted string that describes the binding of
|
|
|
|
/// template parameters to template arguments.
|
|
|
|
std::string
|
|
|
|
Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params,
|
|
|
|
const TemplateArgumentList &Args) {
|
2010-11-08 07:05:16 +08:00
|
|
|
return getTemplateArgumentBindingsText(Params, Args.data(), Args.size());
|
2009-11-12 03:13:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
|
|
|
Sema::getTemplateArgumentBindingsText(const TemplateParameterList *Params,
|
|
|
|
const TemplateArgument *Args,
|
|
|
|
unsigned NumArgs) {
|
2012-02-05 10:13:05 +08:00
|
|
|
SmallString<128> Str;
|
2010-12-21 00:52:59 +08:00
|
|
|
llvm::raw_svector_ostream Out(Str);
|
2009-09-16 00:23:51 +08:00
|
|
|
|
2009-11-12 03:13:48 +08:00
|
|
|
if (!Params || Params->size() == 0 || NumArgs == 0)
|
2010-12-21 00:52:59 +08:00
|
|
|
return std::string();
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-16 00:23:51 +08:00
|
|
|
for (unsigned I = 0, N = Params->size(); I != N; ++I) {
|
2009-11-12 03:13:48 +08:00
|
|
|
if (I >= NumArgs)
|
|
|
|
break;
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-16 00:23:51 +08:00
|
|
|
if (I == 0)
|
2010-12-21 00:52:59 +08:00
|
|
|
Out << "[with ";
|
2009-09-16 00:23:51 +08:00
|
|
|
else
|
2010-12-21 00:52:59 +08:00
|
|
|
Out << ", ";
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2009-09-16 00:23:51 +08:00
|
|
|
if (const IdentifierInfo *Id = Params->getParam(I)->getIdentifier()) {
|
2010-12-21 00:52:59 +08:00
|
|
|
Out << Id->getName();
|
2009-09-16 00:23:51 +08:00
|
|
|
} else {
|
2010-12-21 00:52:59 +08:00
|
|
|
Out << '$' << I;
|
2009-09-16 00:23:51 +08:00
|
|
|
}
|
2011-01-27 15:10:08 +08:00
|
|
|
|
2010-12-21 00:52:59 +08:00
|
|
|
Out << " = ";
|
2011-09-28 07:30:47 +08:00
|
|
|
Args[I].print(getPrintingPolicy(), Out);
|
2009-09-16 00:23:51 +08:00
|
|
|
}
|
2010-12-21 00:52:59 +08:00
|
|
|
|
|
|
|
Out << ']';
|
|
|
|
return Out.str();
|
2009-09-16 00:23:51 +08:00
|
|
|
}
|
2011-04-23 06:18:13 +08:00
|
|
|
|
|
|
|
void Sema::MarkAsLateParsedTemplate(FunctionDecl *FD, bool Flag) {
|
|
|
|
if (!FD)
|
|
|
|
return;
|
|
|
|
FD->setLateTemplateParsed(Flag);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Sema::IsInsideALocalClassWithinATemplateFunction() {
|
|
|
|
DeclContext *DC = CurContext;
|
|
|
|
|
|
|
|
while (DC) {
|
|
|
|
if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(CurContext)) {
|
|
|
|
const FunctionDecl *FD = RD->isLocalClass();
|
|
|
|
return (FD && FD->getTemplatedKind() != FunctionDecl::TK_NonTemplate);
|
|
|
|
} else if (DC->isTranslationUnit() || DC->isNamespace())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
DC = DC->getParent();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|