aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/AST/Decl.cpp23
-rw-r--r--lib/Sema/SemaDecl.cpp31
-rw-r--r--lib/Sema/SemaTemplate.cpp13
3 files changed, 62 insertions, 5 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 4d13f7f3ab..cad7f1f88a 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -566,6 +566,29 @@ void DeclaratorDecl::setQualifierInfo(NestedNameSpecifier *Qualifier,
}
}
+void
+QualifierInfo::setTemplateParameterListsInfo(unsigned NumTPLists,
+ TemplateParameterList **TPLists) {
+ assert((NumTPLists == 0 || TPLists != 0) &&
+ "Empty array of template parameters with positive size!");
+ assert((NumTPLists == 0 || NNS) &&
+ "Nonempty array of template parameters with no qualifier!");
+
+ // Free previous template parameters (if any).
+ if (NumTemplParamLists > 0) {
+ delete[] TemplParamLists;
+ TemplParamLists = 0;
+ NumTemplParamLists = 0;
+ }
+ // Set info on matched template parameter lists (if any).
+ if (NumTPLists > 0) {
+ TemplParamLists = new TemplateParameterList*[NumTPLists];
+ NumTemplParamLists = NumTPLists;
+ for (unsigned i = NumTPLists; i-- > 0; )
+ TemplParamLists[i] = TPLists[i];
+ }
+}
+
//===----------------------------------------------------------------------===//
// VarDecl Implementation
//===----------------------------------------------------------------------===//
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 6bad5da9c4..9ba3ee6ca4 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -2532,6 +2532,7 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
// Match up the template parameter lists with the scope specifier, then
// determine whether we have a template or a template specialization.
bool isExplicitSpecialization = false;
+ unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(
D.getDeclSpec().getSourceRange().getBegin(),
@@ -2540,6 +2541,9 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
TemplateParamLists.size(),
/*never a friend*/ false,
isExplicitSpecialization)) {
+ // All but one template parameter lists have been matching.
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams->size() > 0) {
// There is no such thing as a variable template.
Diag(D.getIdentifierLoc(), diag::err_template_variable)
@@ -2568,6 +2572,11 @@ Sema::ActOnVariableDeclarator(Scope* S, Declarator& D, DeclContext* DC,
SetNestedNameSpecifier(NewVD, D);
+ if (NumMatchedTemplateParamLists > 0) {
+ NewVD->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**)TemplateParamLists.release());
+ }
+
if (D.getDeclSpec().isThreadSpecified()) {
if (NewVD->hasLocalStorage())
Diag(D.getDeclSpec().getThreadSpecLoc(), diag::err_thread_non_global);
@@ -3088,6 +3097,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
FunctionTemplateDecl *FunctionTemplate = 0;
bool isExplicitSpecialization = false;
bool isFunctionTemplateSpecialization = false;
+ unsigned NumMatchedTemplateParamLists = TemplateParamLists.size();
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(
D.getDeclSpec().getSourceRange().getBegin(),
@@ -3096,6 +3106,9 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
TemplateParamLists.size(),
isFriend,
isExplicitSpecialization)) {
+ // All but one template parameter lists have been matching.
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams->size() > 0) {
// This is a function template
@@ -3135,11 +3148,13 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
<< FixItHint::CreateInsertion(InsertLoc, "<>");
}
}
+ }
- // FIXME: Free this memory properly.
- TemplateParamLists.release();
+ if (NumMatchedTemplateParamLists > 0) {
+ NewFD->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**)TemplateParamLists.release());
}
-
+
// C++ [dcl.fct.spec]p5:
// The virtual specifier shall only be used in declarations of
// nonstatic class member functions that appear within a
@@ -4965,6 +4980,7 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// FIXME: Check explicit specializations more carefully.
bool isExplicitSpecialization = false;
+ unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
if (TUK != TUK_Reference) {
if (TemplateParameterList *TemplateParams
= MatchTemplateParametersToScopeSpecifier(KWLoc, SS,
@@ -4972,6 +4988,9 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
TemplateParameterLists.size(),
TUK == TUK_Friend,
isExplicitSpecialization)) {
+ // All but one template parameter lists have been matching.
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams->size() > 0) {
// This is a declaration or definition of a class template (which may
// be a member of another template).
@@ -4989,8 +5008,6 @@ Sema::DeclPtrTy Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
isExplicitSpecialization = true;
}
}
-
- TemplateParameterLists.release();
}
DeclContext *SearchDC = CurContext;
@@ -5394,6 +5411,10 @@ CreateNewDecl:
NestedNameSpecifier *NNS
= static_cast<NestedNameSpecifier*>(SS.getScopeRep());
New->setQualifierInfo(NNS, SS.getRange());
+ if (NumMatchedTemplateParamLists > 0) {
+ New->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**) TemplateParameterLists.release());
+ }
}
else
Invalid = true;
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 44e3a40245..6be74a0897 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -3666,6 +3666,10 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
TemplateParameterLists.size(),
TUK == TUK_Friend,
isExplicitSpecialization);
+ unsigned NumMatchedTemplateParamLists = TemplateParameterLists.size();
+ if (TemplateParams)
+ --NumMatchedTemplateParamLists;
+
if (TemplateParams && TemplateParams->size() > 0) {
isPartialSpecialization = true;
@@ -3857,6 +3861,10 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
PrevPartial,
SequenceNumber);
SetNestedNameSpecifier(Partial, SS);
+ if (NumMatchedTemplateParamLists > 0) {
+ Partial->setTemplateParameterListsInfo(NumMatchedTemplateParamLists,
+ (TemplateParameterList**) TemplateParameterLists.release());
+ }
if (PrevPartial) {
ClassTemplate->getPartialSpecializations().RemoveNode(PrevPartial);
@@ -3914,6 +3922,11 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
Converted,
PrevDecl);
SetNestedNameSpecifier(Specialization, SS);
+ if (NumMatchedTemplateParamLists > 0) {
+ Specialization->setTemplateParameterListsInfo(
+ NumMatchedTemplateParamLists,
+ (TemplateParameterList**) TemplateParameterLists.release());
+ }
if (PrevDecl) {
ClassTemplate->getSpecializations().RemoveNode(PrevDecl);