diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-21 02:55:12 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2011-12-21 02:55:12 +0000 |
commit | 1d238ea926bbdd04356ce475934fcd4cac654c4b (patch) | |
tree | 06e68608a02ef5c6e4bf42648bd8323e50bd8b5e /lib | |
parent | 14b94366a829d2ed1b1b6d5cec1bb83aad9aeca2 (diff) |
C++11 half of r147023: In C++11, additionally eagerly instantiate:
- constexpr function template instantiations
- variables of reference type
- constexpr variables
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147031 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Decl.cpp | 20 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 11 |
3 files changed, 29 insertions, 5 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 9028a09bc3..84a2a59ee2 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -1339,6 +1339,26 @@ void VarDecl::setInit(Expr *I) { Init = I; } +bool VarDecl::isUsableInConstantExpressions() const { + const LangOptions &Lang = getASTContext().getLangOptions(); + + // Only const variables can be used in constant expressions in C++. C++98 does + // not require the variable to be non-volatile, but we consider this to be a + // defect. + if (!Lang.CPlusPlus || + !getType().isConstQualified() || getType().isVolatileQualified()) + return false; + + // In C++, const, non-volatile variables of integral or enumeration types + // can be used in constant expressions. + if (getType()->isIntegralOrEnumerationType()) + return true; + + // Additionally, in C++11, non-volatile constexpr variables and references can + // be used in constant expressions. + return Lang.CPlusPlus0x && (isConstexpr() || getType()->isReferenceType()); +} + /// Convert the initializer for this declaration to the elaborated EvaluatedStmt /// form, which contains extra information on the evaluated value of the /// initializer. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ebcdcf58d0..9ae39f1af3 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6544,8 +6544,7 @@ void Sema::CheckCompleteVariableDeclaration(VarDecl *var) { for (unsigned I = 0, N = Notes.size(); I != N; ++I) Diag(Notes[I].first, Notes[I].second); } - } else if (getLangOptions().CPlusPlus && !Type.isVolatileQualified() && - Type.isConstQualified() && Type->isIntegralOrEnumerationType()) { + } else if (var->isUsableInConstantExpressions()) { // Check whether the initializer of a const variable of integral or // enumeration type is an ICE now, since we can't tell whether it was // initialized by a constant expression if we check later. diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3a61fe5066..9d2298a704 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9491,6 +9491,11 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { cast<CXXRecordDecl>(Function->getDeclContext())->isLocalClass()) PendingLocalImplicitInstantiations.push_back(std::make_pair(Function, Loc)); + else if (Function->getTemplateInstantiationPattern()->isConstexpr()) + // Do not defer instantiations of constexpr functions, to avoid the + // expression evaluator needing to call back into Sema if it sees a + // call to such a function. + InstantiateFunctionDefinition(Loc, Function); else PendingInstantiations.push_back(std::make_pair(Function, Loc)); } @@ -9526,9 +9531,9 @@ void Sema::MarkDeclarationReferenced(SourceLocation Loc, Decl *D) { // This is a modification of an existing AST node. Notify listeners. if (ASTMutationListener *L = getASTMutationListener()) L->StaticDataMemberInstantiated(Var); - QualType T = Var->getType(); - if (T.isConstQualified() && !T.isVolatileQualified() && - T->isIntegralOrEnumerationType()) + if (Var->isUsableInConstantExpressions()) + // Do not defer instantiations of variables which could be used in a + // constant expression. InstantiateStaticDataMemberDefinition(Loc, Var); else PendingInstantiations.push_back(std::make_pair(Var, Loc)); |