summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-06-25 00:15:56 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-06-25 00:15:56 +0000
commit62f19e700d3126415bb443162501eefe22cf1811 (patch)
treef099beb58ddd384abd71e64128ae992e87362263 /clang/lib/AST/Decl.cpp
parentb8da3a2bb2b840db6ab7c473190ee6d65dcf3a1e (diff)
downloadbcm5719-llvm-62f19e700d3126415bb443162501eefe22cf1811.tar.gz
bcm5719-llvm-62f19e700d3126415bb443162501eefe22cf1811.zip
Implement C++17 P0386R2, inline variables. (The 'inline' specifier gives a
variable weak discardable linkage and partially-ordered initialization, and is implied for constexpr static data members.) llvm-svn: 273754
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r--clang/lib/AST/Decl.cpp30
1 files changed, 13 insertions, 17 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index d59c4b422b3..e94d7b93f71 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -592,12 +592,14 @@ static LinkageInfo getLVForNamespaceScopeDecl(const NamedDecl *D,
if (Var->getStorageClass() == SC_Static)
return LinkageInfo::internal();
- // - a non-volatile object or reference that is explicitly declared const
- // or constexpr and neither explicitly declared extern nor previously
- // declared to have external linkage; or (there is no equivalent in C99)
+ // - a non-inline, non-volatile object or reference that is explicitly
+ // declared const or constexpr and neither explicitly declared extern
+ // nor previously declared to have external linkage; or (there is no
+ // equivalent in C99)
if (Context.getLangOpts().CPlusPlus &&
Var->getType().isConstQualified() &&
- !Var->getType().isVolatileQualified()) {
+ !Var->getType().isVolatileQualified() &&
+ !Var->isInline()) {
const VarDecl *PrevVar = Var->getPreviousDecl();
if (PrevVar)
return getLVForDecl(PrevVar, computation);
@@ -1912,7 +1914,9 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
// C++ [basic.def]p2:
// A declaration is a definition unless [...] it contains the 'extern'
// specifier or a linkage-specification and neither an initializer [...],
- // it declares a static data member in a class declaration [...].
+ // it declares a non-inline static data member in a class declaration [...],
+ // it declares a static data member outside a class definition and the variable
+ // was defined within the class with the constexpr specifier [...],
// C++1y [temp.expl.spec]p15:
// An explicit specialization of a static data member or an explicit
// specialization of a static data member template is a definition if the
@@ -1922,6 +1926,8 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
// a static data member template outside the containing class?
if (isStaticDataMember()) {
if (isOutOfLine() &&
+ !(getCanonicalDecl()->isInline() &&
+ getCanonicalDecl()->isConstexpr()) &&
(hasInit() ||
// If the first declaration is out-of-line, this may be an
// instantiation of an out-of-line partial specialization of a variable
@@ -1932,6 +1938,8 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
TSK_ExplicitSpecialization) ||
isa<VarTemplatePartialSpecializationDecl>(this)))
return Definition;
+ else if (!isOutOfLine() && isInline())
+ return Definition;
else
return DeclarationOnly;
}
@@ -2072,18 +2080,6 @@ bool VarDecl::isOutOfLine() const {
return false;
}
-VarDecl *VarDecl::getOutOfLineDefinition() {
- if (!isStaticDataMember())
- return nullptr;
-
- for (auto RD : redecls()) {
- if (RD->getLexicalDeclContext()->isFileContext())
- return RD;
- }
-
- return nullptr;
-}
-
void VarDecl::setInit(Expr *I) {
if (auto *Eval = Init.dyn_cast<EvaluatedStmt *>()) {
Eval->~EvaluatedStmt();
OpenPOWER on IntegriCloud