diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-25 00:15:56 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2016-06-25 00:15:56 +0000 |
commit | 62f19e700d3126415bb443162501eefe22cf1811 (patch) | |
tree | f099beb58ddd384abd71e64128ae992e87362263 /clang/lib/AST/Decl.cpp | |
parent | b8da3a2bb2b840db6ab7c473190ee6d65dcf3a1e (diff) | |
download | bcm5719-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.cpp | 30 |
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(); |