summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2011-12-21 00:25:33 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2011-12-21 00:25:33 +0000
commited2974f3cf2b9af28d62a1959f7b7bced32fca9f (patch)
tree2046dfb6b27f81a7f213bc2ba523fea77d9013df
parent1d8efaba7e9517c95a67f5ec589a8a1329b90a00 (diff)
downloadbcm5719-llvm-ed2974f3cf2b9af28d62a1959f7b7bced32fca9f.tar.gz
bcm5719-llvm-ed2974f3cf2b9af28d62a1959f7b7bced32fca9f.zip
C++ constant expression handling: eagerly instantiate static const integral data
members of class templates so that their values can be used in ICEs. This required reverting r105465, to get such instantiated members to be included in serialized ASTs. llvm-svn: 147023
-rw-r--r--clang/lib/Sema/SemaExpr.cpp7
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp3
-rw-r--r--clang/test/PCH/chain-cxx.cpp7
-rw-r--r--clang/test/SemaTemplate/instantiate-declref-ice.cpp2
4 files changed, 14 insertions, 5 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 65439032f2c..3a61fe50666 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -9526,7 +9526,12 @@ 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);
- PendingInstantiations.push_back(std::make_pair(Var, Loc));
+ QualType T = Var->getType();
+ if (T.isConstQualified() && !T.isVolatileQualified() &&
+ T->isIntegralOrEnumerationType())
+ InstantiateStaticDataMemberDefinition(Loc, Var);
+ else
+ PendingInstantiations.push_back(std::make_pair(Var, Loc));
}
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b2208b63c87..53adf68cd97 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -359,8 +359,7 @@ Decl *TemplateDeclInstantiator::VisitVarDecl(VarDecl *D) {
SemaRef.CheckVariableDeclaration(Var, Previous);
if (D->isOutOfLine()) {
- if (!D->isStaticDataMember())
- D->getLexicalDeclContext()->addDecl(Var);
+ D->getLexicalDeclContext()->addDecl(Var);
Owner->makeDeclVisibleInContext(Var);
} else {
Owner->addDecl(Var);
diff --git a/clang/test/PCH/chain-cxx.cpp b/clang/test/PCH/chain-cxx.cpp
index c42ee7d39ee..0d50e61c5a9 100644
--- a/clang/test/PCH/chain-cxx.cpp
+++ b/clang/test/PCH/chain-cxx.cpp
@@ -38,9 +38,12 @@ template<typename T> struct TestBaseSpecifiers2 : TestBaseSpecifiers<T> { };
template <typename T>
struct TS3 {
static const int value = 0;
+ static const int value2;
};
template <typename T>
const int TS3<T>::value;
+template <typename T>
+const int TS3<T>::value2 = 1;
// Instantiate struct, but not value.
struct instantiate : TS3<int> {};
@@ -96,8 +99,9 @@ struct TestBaseSpecifiers4 : TestBaseSpecifiers3 { };
struct A { };
struct B : A { };
-// Instantiate TS3's member.
+// Instantiate TS3's members.
static const int ts3m1 = TS3<int>::value;
+extern int arr[TS3<int>::value2];
// Redefinition of typedef
typedef int Integer;
@@ -132,6 +136,7 @@ void test() {
// Should have remembered that there is a definition.
static const int ts3m2 = TS3<int>::value;
+int arr[TS3<int>::value2];
//===----------------------------------------------------------------------===//
#endif
diff --git a/clang/test/SemaTemplate/instantiate-declref-ice.cpp b/clang/test/SemaTemplate/instantiate-declref-ice.cpp
index 0f3c08b0562..49b1b63f515 100644
--- a/clang/test/SemaTemplate/instantiate-declref-ice.cpp
+++ b/clang/test/SemaTemplate/instantiate-declref-ice.cpp
@@ -31,4 +31,4 @@ struct X1 {
template<typename T>
const unsigned X1<T>::value = sizeof(T);
-int array3[X1<int>::value == sizeof(int)? 1 : -1]; // expected-error{{variable length array declaration not allowed at file scope}}
+int array3[X1<int>::value == sizeof(int)? 1 : -1];
OpenPOWER on IntegriCloud