summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp26
-rw-r--r--clang/lib/Sema/SemaLambda.cpp16
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp10
3 files changed, 30 insertions, 22 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8e8abee423b..ff27e2d2159 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -14256,21 +14256,22 @@ void Sema::ActOnPureSpecifier(Decl *D, SourceLocation ZeroLoc) {
Diag(D->getLocation(), diag::err_illegal_initializer);
}
-/// \brief Determine whether the given declaration is a static data member.
-static bool isStaticDataMember(const Decl *D) {
+/// \brief Determine whether the given declaration is a global variable or
+/// static data member.
+static bool isNonlocalVariable(const Decl *D) {
if (const VarDecl *Var = dyn_cast_or_null<VarDecl>(D))
- return Var->isStaticDataMember();
+ return Var->hasGlobalStorage();
return false;
}
-/// ActOnCXXEnterDeclInitializer - Invoked when we are about to parse
-/// an initializer for the out-of-line declaration 'Dcl'. The scope
-/// is a fresh scope pushed for just this purpose.
+/// Invoked when we are about to parse an initializer for the declaration
+/// 'Dcl'.
///
/// After this method is called, according to [C++ 3.4.1p13], if 'Dcl' is a
/// static data member of class X, names should be looked up in the scope of
-/// class X.
+/// class X. If the declaration had a scope specifier, a scope will have
+/// been created and passed in for this purpose. Otherwise, S will be null.
void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
// If there is no declaration, there was an error parsing it.
if (!D || D->isInvalidDecl())
@@ -14280,28 +14281,27 @@ void Sema::ActOnCXXEnterDeclInitializer(Scope *S, Decl *D) {
// might not be out of line if the specifier names the current namespace:
// extern int n;
// int ::n = 0;
- if (D->isOutOfLine())
+ if (S && D->isOutOfLine())
EnterDeclaratorContext(S, D->getDeclContext());
// If we are parsing the initializer for a static data member, push a
// new expression evaluation context that is associated with this static
// data member.
- if (isStaticDataMember(D))
+ if (isNonlocalVariable(D))
PushExpressionEvaluationContext(
ExpressionEvaluationContext::PotentiallyEvaluated, D);
}
-/// ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an
-/// initializer for the out-of-line declaration 'D'.
+/// Invoked after we are finished parsing an initializer for the declaration D.
void Sema::ActOnCXXExitDeclInitializer(Scope *S, Decl *D) {
// If there is no declaration, there was an error parsing it.
if (!D || D->isInvalidDecl())
return;
- if (isStaticDataMember(D))
+ if (isNonlocalVariable(D))
PopExpressionEvaluationContext();
- if (D->isOutOfLine())
+ if (S && D->isOutOfLine())
ExitDeclaratorContext(S);
}
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index bbd7c4a0937..996ed3ea7e4 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -288,7 +288,9 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
Normal,
DefaultArgument,
DataMember,
- StaticDataMember
+ StaticDataMember,
+ InlineVariable,
+ VariableTemplate
} Kind = Normal;
// Default arguments of member function parameters that appear in a class
@@ -303,6 +305,14 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
} else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) {
if (Var->getDeclContext()->isRecord())
Kind = StaticDataMember;
+ else if (Var->getMostRecentDecl()->isInline())
+ Kind = InlineVariable;
+ else if (Var->getDescribedVarTemplate())
+ Kind = VariableTemplate;
+ else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) {
+ if (!VTS->isExplicitSpecialization())
+ Kind = VariableTemplate;
+ }
} else if (isa<FieldDecl>(ManglingContextDecl)) {
Kind = DataMember;
}
@@ -343,6 +353,10 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC,
// -- the in-class initializers of class members
case DefaultArgument:
// -- default arguments appearing in class definitions
+ case InlineVariable:
+ // -- the initializers of inline variables
+ case VariableTemplate:
+ // -- the initializers of templated variables
return &ExprEvalContexts.back().getMangleNumberingContext(Context);
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e702d3c7238..2c51c57bf39 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4140,12 +4140,8 @@ void Sema::InstantiateVariableInitializer(
Var->setImplicitlyInline();
if (OldVar->getInit()) {
- if (Var->isStaticDataMember() && !OldVar->isOutOfLine())
- PushExpressionEvaluationContext(
- Sema::ExpressionEvaluationContext::ConstantEvaluated, OldVar);
- else
- PushExpressionEvaluationContext(
- Sema::ExpressionEvaluationContext::PotentiallyEvaluated, OldVar);
+ EnterExpressionEvaluationContext Evaluated(
+ *this, Sema::ExpressionEvaluationContext::PotentiallyEvaluated, Var);
// Instantiate the initializer.
ExprResult Init;
@@ -4173,8 +4169,6 @@ void Sema::InstantiateVariableInitializer(
// because of a bogus initializer.
Var->setInvalidDecl();
}
-
- PopExpressionEvaluationContext();
} else {
if (Var->isStaticDataMember()) {
if (!Var->isOutOfLine())
OpenPOWER on IntegriCloud