summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDecl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaDecl.cpp')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp90
1 files changed, 42 insertions, 48 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;
OpenPOWER on IntegriCloud