diff options
author | Eli Friedman <eli.friedman@gmail.com> | 2009-12-11 01:34:50 +0000 |
---|---|---|
committer | Eli Friedman <eli.friedman@gmail.com> | 2009-12-11 01:34:50 +0000 |
commit | d0e6097bb03bd02d024eaa552ecd1a7c27bc34a4 (patch) | |
tree | f966612ae571c257cbfa03725213dff749acc138 | |
parent | c988201417a8f422a89da62446e2904e68dd3ad1 (diff) | |
download | bcm5719-llvm-d0e6097bb03bd02d024eaa552ecd1a7c27bc34a4.tar.gz bcm5719-llvm-d0e6097bb03bd02d024eaa552ecd1a7c27bc34a4.zip |
Fix the handling of dependent enums per C++ DR 502.
llvm-svn: 91089
-rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 22 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-enum-2.cpp | 9 |
2 files changed, 27 insertions, 4 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fa0d3cef658..64305b443ec 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/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<EnumConstantDecl>(Elements[i].getAs<Decl>()); + 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/clang/test/SemaTemplate/instantiate-enum-2.cpp b/clang/test/SemaTemplate/instantiate-enum-2.cpp new file mode 100644 index 00000000000..2b56a036e94 --- /dev/null +++ b/clang/test/SemaTemplate/instantiate-enum-2.cpp @@ -0,0 +1,9 @@ +// RUN: clang-cc %s -fsyntax-only -verify + +template<int IntBits> struct X { + enum { + IntShift = (unsigned long long)IntBits, + ShiftedIntMask = (1 << IntShift) + }; +}; +X<1> x; |