From ed0716b7b79d8cdef34f3bd35776a91aa3c943e5 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Fri, 11 Dec 2009 01:34:50 +0000 Subject: [PATCH] Fix the handling of dependent enums per C++ DR 502. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91089 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 22 ++++++++++++++++++---- test/SemaTemplate/instantiate-enum-2.cpp | 9 +++++++++ 2 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 test/SemaTemplate/instantiate-enum-2.cpp diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index fa0d3cef65..64305b443e 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -5663,7 +5663,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, llvm::APSInt EnumVal(32); QualType EltTy; if (Val) { - if (Val->isTypeDependent()) + if (Enum->isDependentType()) EltTy = Context.DependentTy; else { // Make sure to promote the operand type to int. @@ -5675,8 +5675,7 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, // C99 6.7.2.2p2: Make sure we have an integer constant expression. SourceLocation ExpLoc; - if (!Val->isValueDependent() && - VerifyIntegerConstantExpression(Val, &EnumVal)) { + if (VerifyIntegerConstantExpression(Val, &EnumVal)) { Val = 0; } else { EltTy = Val->getType(); @@ -5685,7 +5684,9 @@ EnumConstantDecl *Sema::CheckEnumConstant(EnumDecl *Enum, } if (!Val) { - if (LastEnumConst) { + if (Enum->isDependentType()) + EltTy = Context.DependentTy; + else if (LastEnumConst) { // Assign the last value + 1. EnumVal = LastEnumConst->getInitVal(); ++EnumVal; @@ -5771,6 +5772,19 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceLocation LBraceLoc, if (Attr) ProcessDeclAttributeList(S, Enum, Attr); + if (Enum->isDependentType()) { + for (unsigned i = 0; i != NumElements; ++i) { + EnumConstantDecl *ECD = + cast_or_null(Elements[i].getAs()); + if (!ECD) continue; + + ECD->setType(EnumType); + } + + Enum->completeDefinition(Context, Context.DependentTy, Context.DependentTy); + return; + } + // TODO: If the result value doesn't fit in an int, it must be a long or long // long value. ISO C does not support this, but GCC does as an extension, // emit a warning. diff --git a/test/SemaTemplate/instantiate-enum-2.cpp b/test/SemaTemplate/instantiate-enum-2.cpp new file mode 100644 index 0000000000..2b56a036e9 --- /dev/null +++ b/test/SemaTemplate/instantiate-enum-2.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +template struct X { + enum { + IntShift = (unsigned long long)IntBits, + ShiftedIntMask = (1 << IntShift) + }; +}; +X<1> x; -- 2.50.1