summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp90
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp10
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp28
3 files changed, 59 insertions, 69 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 9f2e757dc2f..80863e35e29 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -2887,7 +2887,7 @@ void Sema::MergeVarDeclTypes(VarDecl *New, VarDecl *Old,
/// definitions here, since the initializer hasn't been attached.
///
void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
- bool IsVariableTemplate, bool MergeTypeWithPrevious) {
+ bool MergeTypeWithPrevious) {
// If the new decl is already invalid, don't do any other checking.
if (New->isInvalidDecl())
return;
@@ -2896,7 +2896,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
VarDecl *Old = 0;
if (Previous.isSingleResult() &&
(Old = dyn_cast<VarDecl>(Previous.getFoundDecl()))) {
- if (IsVariableTemplate)
+ if (New->getDescribedVarTemplate())
Old = Old->getDescribedVarTemplate() ? Old : 0;
else
Old = Old->getDescribedVarTemplate() ? 0 : Old;
@@ -3039,6 +3039,11 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
// Inherit access appropriately.
New->setAccess(Old->getAccess());
+
+ if (VarTemplateDecl *VTD = New->getDescribedVarTemplate()) {
+ if (New->isStaticDataMember() && New->isOutOfLine())
+ VTD->setAccess(New->getAccess());
+ }
}
/// ParsedFreeStandingDeclSpec - This method is invoked when a declspec with
@@ -4893,10 +4898,9 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
bool IsVariableTemplateSpecialization = false;
bool IsPartialSpecialization = false;
bool IsVariableTemplate = false;
- bool Invalid = false; // TODO: Can we remove this (error-prone)?
- TemplateParameterList *TemplateParams = 0;
VarTemplateDecl *PrevVarTemplate = 0;
- VarDecl *NewVD;
+ VarDecl *NewVD = 0;
+ VarTemplateDecl *NewTemplate = 0;
if (!getLangOpts().CPlusPlus) {
NewVD = VarDecl::Create(Context, DC, D.getLocStart(),
D.getIdentifierLoc(), II,
@@ -4905,6 +4909,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
if (D.isInvalidType())
NewVD->setInvalidDecl();
} else {
+ bool Invalid = false;
+
if (DC->isRecord() && !CurContext->isRecord()) {
// This is an out-of-line definition of a static data member.
switch (SC) {
@@ -4963,10 +4969,11 @@ 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.
- TemplateParams = MatchTemplateParametersToScopeSpecifier(
- D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
- D.getCXXScopeSpec(), TemplateParamLists,
- /*never a friend*/ false, IsExplicitSpecialization, Invalid);
+ TemplateParameterList *TemplateParams =
+ MatchTemplateParametersToScopeSpecifier(
+ D.getDeclSpec().getLocStart(), D.getIdentifierLoc(),
+ D.getCXXScopeSpec(), TemplateParamLists,
+ /*never a friend*/ false, IsExplicitSpecialization, Invalid);
if (TemplateParams) {
if (!TemplateParams->size() &&
D.getName().getKind() != UnqualifiedId::IK_TemplateId) {
@@ -5090,13 +5097,24 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
NewVD = VarDecl::Create(Context, DC, D.getLocStart(),
D.getIdentifierLoc(), II, R, TInfo, SC);
+ // If this is supposed to be a variable template, create it as such.
+ if (IsVariableTemplate) {
+ NewTemplate =
+ VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name,
+ TemplateParams, NewVD, PrevVarTemplate);
+ NewVD->setDescribedVarTemplate(NewTemplate);
+ }
+
// If this decl has an auto type in need of deduction, make a note of the
// Decl so we can diagnose uses of it in its own initializer.
if (D.getDeclSpec().containsPlaceholderType() && R->getContainedAutoType())
ParsingInitForAutoVars.insert(NewVD);
- if (D.isInvalidType() || Invalid)
+ if (D.isInvalidType() || Invalid) {
NewVD->setInvalidDecl();
+ if (NewTemplate)
+ NewTemplate->setInvalidDecl();
+ }
SetNestedNameSpecifier(NewVD, D);
@@ -5120,6 +5138,8 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// Set the lexical context. If the declarator has a C++ scope specifier, the
// lexical context will be different from the semantic context.
NewVD->setLexicalDeclContext(CurContext);
+ if (NewTemplate)
+ NewTemplate->setLexicalDeclContext(CurContext);
if (DeclSpec::TSCS TSCS = D.getDeclSpec().getThreadStorageClassSpec()) {
if (NewVD->hasLocalStorage()) {
@@ -5178,8 +5198,11 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
<< 0 << NewVD->getDeclName()
<< SourceRange(D.getDeclSpec().getModulePrivateSpecLoc())
<< FixItHint::CreateRemoval(D.getDeclSpec().getModulePrivateSpecLoc());
- else
+ else {
NewVD->setModulePrivate();
+ if (NewTemplate)
+ NewTemplate->setModulePrivate();
+ }
}
// Handle attributes prior to checking for duplicates in MergeVarDecl
@@ -5238,7 +5261,6 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
// Diagnose shadowed variables before filtering for scope.
- // FIXME: Special treatment for static variable template members (?).
if (!D.getCXXScopeSpec().isSet())
CheckShadow(S, NewVD, Previous);
@@ -5285,15 +5307,12 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
LookupResult PrevDecl(*this, GetNameForDeclarator(D),
LookupOrdinaryName, ForRedeclaration);
PrevDecl.addDecl(PrevVarTemplate->getTemplatedDecl());
- D.setRedeclaration(
- CheckVariableDeclaration(NewVD, PrevDecl, IsVariableTemplate));
+ D.setRedeclaration(CheckVariableDeclaration(NewVD, PrevDecl));
} else
- D.setRedeclaration(
- CheckVariableDeclaration(NewVD, Previous, IsVariableTemplate));
+ D.setRedeclaration(CheckVariableDeclaration(NewVD, Previous));
}
// This is an explicit specialization of a static data member. Check it.
- // FIXME: Special treatment for static variable template members (?).
if (IsExplicitSpecialization && !NewVD->isInvalidDecl() &&
CheckMemberSpecialization(NewVD, Previous))
NewVD->setInvalidDecl();
@@ -5317,40 +5336,17 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
}
- // If this is not a variable template, return it now.
- if (!IsVariableTemplate)
- return NewVD;
-
- // If this is supposed to be a variable template, create it as such.
- VarTemplateDecl *NewTemplate =
- VarTemplateDecl::Create(Context, DC, D.getIdentifierLoc(), Name,
- TemplateParams, NewVD, PrevVarTemplate);
- NewVD->setDescribedVarTemplate(NewTemplate);
-
- if (D.getDeclSpec().isModulePrivateSpecified())
- NewTemplate->setModulePrivate();
-
// If we are providing an explicit specialization of a static variable
// template, make a note of that.
if (PrevVarTemplate && PrevVarTemplate->getInstantiatedFromMemberTemplate())
PrevVarTemplate->setMemberSpecialization();
- // Set the lexical context of this template
- NewTemplate->setLexicalDeclContext(CurContext);
- if (NewVD->isStaticDataMember() && NewVD->isOutOfLine())
- NewTemplate->setAccess(NewVD->getAccess());
-
- PushOnScopeChains(NewTemplate, S);
- AddToScope = false;
-
- if (Invalid) {
- NewTemplate->setInvalidDecl();
- NewVD->setInvalidDecl();
+ if (NewTemplate) {
+ ActOnDocumentableDecl(NewTemplate);
+ return NewTemplate;
}
- ActOnDocumentableDecl(NewTemplate);
-
- return NewTemplate;
+ return NewVD;
}
/// \brief Diagnose variable or built-in function shadowing. Implements
@@ -5716,9 +5712,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
/// Sets NewVD->isInvalidDecl() if an error was encountered.
///
/// Returns true if the variable declaration is a redeclaration.
-bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
- LookupResult &Previous,
- bool IsVariableTemplate) {
+bool Sema::CheckVariableDeclaration(VarDecl *NewVD, LookupResult &Previous) {
CheckVariableDeclarationType(NewVD);
// If the decl is already known invalid, don't check it.
@@ -5768,7 +5762,7 @@ bool Sema::CheckVariableDeclaration(VarDecl *NewVD,
filterNonConflictingPreviousDecls(Context, NewVD, Previous);
if (!Previous.empty()) {
- MergeVarDecl(NewVD, Previous, IsVariableTemplate, MergeTypeWithPrevious);
+ MergeVarDecl(NewVD, Previous, MergeTypeWithPrevious);
return true;
}
return false;
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 9f84fc665b1..9b7b4a85966 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2254,12 +2254,10 @@ namespace {
};
}
-bool
-Sema::InstantiateClassTemplateSpecialization(
- SourceLocation PointOfInstantiation,
- ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK,
- bool Complain) {
+bool Sema::InstantiateClassTemplateSpecialization(
+ SourceLocation PointOfInstantiation,
+ ClassTemplateSpecializationDecl *ClassTemplateSpec,
+ TemplateSpecializationKind TSK, bool Complain) {
// Perform the actual instantiation on the canonical declaration.
ClassTemplateSpec = cast<ClassTemplateSpecializationDecl>(
ClassTemplateSpec->getCanonicalDecl());
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 8d066a0ac2b..37511d0b36e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -320,10 +320,11 @@ TemplateDeclInstantiator::VisitTypeAliasTemplateDecl(TypeAliasTemplateDecl *D) {
// FIXME: Revise for static member templates.
Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
- return VisitVarDecl(D, /*ForVarTemplate=*/false);
+ return VisitVarDecl(D, /*InstantiatingVarTemplate=*/false);
}
-Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, bool ForVarTemplate) {
+Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D,
+ bool InstantiatingVarTemplate) {
// If this is the variable for an anonymous struct or union,
// instantiate the anonymous struct/union type first.
@@ -361,7 +362,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D, bool ForVarTemplate) {
return 0;
SemaRef.BuildVariableInstantiation(Var, D, TemplateArgs, LateAttrs,
- StartingScope, ForVarTemplate);
+ StartingScope, InstantiatingVarTemplate);
return Var;
}
@@ -971,7 +972,8 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateDecl(VarTemplateDecl *D) {
}
VarDecl *VarInst =
- cast_or_null<VarDecl>(VisitVarDecl(Pattern, /*ForVarTemplate=*/ true));
+ cast_or_null<VarDecl>(VisitVarDecl(Pattern,
+ /*InstantiatingVarTemplate=*/true));
DeclContext *DC = Owner;
@@ -2649,8 +2651,6 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
InstPartialSpec->setTypeAsWritten(WrittenTy);
- InstPartialSpec->setAccess(PartialSpec->getAccess());
-
// Add this partial specialization to the set of variable template partial
// specializations. The instantiation of the initializer is not necessary.
VarTemplate->AddPartialSpecialization(InstPartialSpec, /*InsertPos=*/0);
@@ -3314,9 +3314,8 @@ VarTemplateSpecializationDecl *Sema::CompleteVarTemplateSpecializationDecl(
void Sema::BuildVariableInstantiation(
VarDecl *NewVar, VarDecl *OldVar,
const MultiLevelTemplateArgumentList &TemplateArgs,
- LateInstantiatedAttrVec *LateAttrs,
- LocalInstantiationScope *StartingScope,
- bool ForVarTemplate) {
+ LateInstantiatedAttrVec *LateAttrs, LocalInstantiationScope *StartingScope,
+ bool InstantiatingVarTemplate) {
// If we are instantiating a static data member defined
// out-of-line, the instantiation will have the same lexical
@@ -3354,15 +3353,14 @@ void Sema::BuildVariableInstantiation(
} else if (!isa<VarTemplateSpecializationDecl>(NewVar) &&
OldVar->hasLinkage())
LookupQualifiedName(Previous, NewVar->getDeclContext(), false);
-
- CheckVariableDeclaration(NewVar, Previous, ForVarTemplate);
+ CheckVariableDeclaration(NewVar, Previous);
if (OldVar->isOutOfLine()) {
OldVar->getLexicalDeclContext()->addDecl(NewVar);
- if (!ForVarTemplate)
+ if (!InstantiatingVarTemplate)
NewVar->getDeclContext()->makeDeclVisibleInContext(NewVar);
} else {
- if (!ForVarTemplate)
+ if (!InstantiatingVarTemplate)
NewVar->getDeclContext()->addDecl(NewVar);
if (NewVar->getDeclContext()->isFunctionOrMethod())
CurrentInstantiationScope->InstantiatedLocal(OldVar, NewVar);
@@ -3370,13 +3368,13 @@ void Sema::BuildVariableInstantiation(
// Link instantiations of static data members back to the template from
// which they were instantiated.
- if (NewVar->isStaticDataMember() && !ForVarTemplate)
+ if (NewVar->isStaticDataMember() && !InstantiatingVarTemplate)
NewVar->setInstantiationOfStaticDataMember(OldVar,
TSK_ImplicitInstantiation);
if (isa<VarTemplateSpecializationDecl>(NewVar)) {
// Do not instantiate the variable just yet.
- } else if (ForVarTemplate) {
+ } else if (InstantiatingVarTemplate) {
assert(!NewVar->getInit() &&
"A variable should not have an initializer if it is templated"
" and we are instantiating its template");
OpenPOWER on IntegriCloud