diff options
| author | Benjamin Kramer <benny.kra@googlemail.com> | 2012-11-21 17:42:47 +0000 | 
|---|---|---|
| committer | Benjamin Kramer <benny.kra@googlemail.com> | 2012-11-21 17:42:47 +0000 | 
| commit | 3d3ddcec70df5aeee4fc41ba5f55ba1a25716be0 (patch) | |
| tree | 26c1fc4828e1ff72b83fb87544783eccf17482b5 /clang/lib | |
| parent | 568afebcb22b13548fea1b328f2e539b094d4df3 (diff) | |
| download | bcm5719-llvm-3d3ddcec70df5aeee4fc41ba5f55ba1a25716be0.tar.gz bcm5719-llvm-3d3ddcec70df5aeee4fc41ba5f55ba1a25716be0.zip  | |
SemaCXX: an enumeral type can be of character or boolean type in a C++11 enum class. Make sure we create a literal of the right type.
Fixes PR14386.
llvm-svn: 168441
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/SemaTemplate.cpp | 49 | 
1 files changed, 24 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index 1fa554abd03..21be2442e42 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -4606,7 +4606,18 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,                                                    SourceLocation Loc) {    assert(Arg.getKind() == TemplateArgument::Integral &&           "Operation is only valid for integral template arguments"); -  QualType T = Arg.getIntegralType(); +  QualType OrigT = Arg.getIntegralType(); + +  // If this is an enum type that we're instantiating, we need to use an integer +  // type the same size as the enumerator.  We don't want to build an +  // IntegerLiteral with enum type.  The integer type of an enum type can be of +  // any integral type with C++11 enum classes, make sure we create the right +  // type of literal for it. +  QualType T = OrigT; +  if (const EnumType *ET = OrigT->getAs<EnumType>()) +    T = ET->getDecl()->getIntegerType(); + +  Expr *E;    if (T->isAnyCharacterType()) {      CharacterLiteral::CharacterKind Kind;      if (T->isWideCharType()) @@ -4618,34 +4629,22 @@ Sema::BuildExpressionFromIntegralTemplateArgument(const TemplateArgument &Arg,      else        Kind = CharacterLiteral::Ascii; -    return Owned(new (Context) CharacterLiteral( -                                            Arg.getAsIntegral().getZExtValue(), -                                            Kind, T, Loc)); +    E = new (Context) CharacterLiteral(Arg.getAsIntegral().getZExtValue(), +                                       Kind, T, Loc); +  } else if (T->isBooleanType()) { +    E = new (Context) CXXBoolLiteralExpr(Arg.getAsIntegral().getBoolValue(), +                                         T, Loc); +  } else if (T->isNullPtrType()) { +    E = new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc); +  } else { +    E = IntegerLiteral::Create(Context, Arg.getAsIntegral(), T, Loc);    } -  if (T->isBooleanType()) -    return Owned(new (Context) CXXBoolLiteralExpr( -                                            Arg.getAsIntegral().getBoolValue(), -                                            T, Loc)); - -  if (T->isNullPtrType()) -    return Owned(new (Context) CXXNullPtrLiteralExpr(Context.NullPtrTy, Loc)); -   -  // If this is an enum type that we're instantiating, we need to use an integer -  // type the same size as the enumerator.  We don't want to build an -  // IntegerLiteral with enum type. -  QualType BT; -  if (const EnumType *ET = T->getAs<EnumType>()) -    BT = ET->getDecl()->getIntegerType(); -  else -    BT = T; - -  Expr *E = IntegerLiteral::Create(Context, Arg.getAsIntegral(), BT, Loc); -  if (T->isEnumeralType()) { +  if (OrigT->isEnumeralType()) {      // FIXME: This is a hack. We need a better way to handle substituted      // non-type template parameters. -    E = CStyleCastExpr::Create(Context, T, VK_RValue, CK_IntegralCast, E, 0,  -                               Context.getTrivialTypeSourceInfo(T, Loc), +    E = CStyleCastExpr::Create(Context, OrigT, VK_RValue, CK_IntegralCast, E, 0, +                               Context.getTrivialTypeSourceInfo(OrigT, Loc),                                 Loc, Loc);    }  | 

