diff options
| author | John McCall <rjmccall@apple.com> | 2009-12-09 09:09:27 +0000 |
|---|---|---|
| committer | John McCall <rjmccall@apple.com> | 2009-12-09 09:09:27 +0000 |
| commit | 5677499fbffe3441543f2e0c2f7e4016270560a5 (patch) | |
| tree | a2f87a1b1b6eb37c6fbf50caba31774a94c123a2 /clang/lib/AST/ASTContext.cpp | |
| parent | 1d153328be1c52cf8d595bbd24ca829c2f8334d2 (diff) | |
| download | bcm5719-llvm-5677499fbffe3441543f2e0c2f7e4016270560a5.tar.gz bcm5719-llvm-5677499fbffe3441543f2e0c2f7e4016270560a5.zip | |
First pass at implementing C++ enum semantics: calculate (and store) an
"integer promotion" type associated with an enum decl, and use this type to
determine which type to promote to. This type obeys C++ [conv.prom]p2 and
is therefore generally signed unless the range of the enumerators forces
it to be unsigned.
Kills off a lot of false positives from -Wsign-compare in C++, addressing
rdar://7455616
llvm-svn: 90965
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
| -rw-r--r-- | clang/lib/AST/ASTContext.cpp | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index fcdd48716e8..91fd1661338 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2671,7 +2671,7 @@ int ASTContext::getFloatingTypeOrder(QualType LHS, QualType RHS) { unsigned ASTContext::getIntegerRank(Type *T) { assert(T->isCanonicalUnqualified() && "T should be canonicalized"); if (EnumType* ET = dyn_cast<EnumType>(T)) - T = ET->getDecl()->getIntegerType().getTypePtr(); + T = ET->getDecl()->getPromotionType().getTypePtr(); if (T->isSpecificBuiltinType(BuiltinType::WChar)) T = getFromTargetType(Target.getWCharType()).getTypePtr(); @@ -2752,6 +2752,8 @@ QualType ASTContext::isPromotableBitField(Expr *E) { QualType ASTContext::getPromotedIntegerType(QualType Promotable) { assert(!Promotable.isNull()); assert(Promotable->isPromotableIntegerType()); + if (const EnumType *ET = Promotable->getAs<EnumType>()) + return ET->getDecl()->getPromotionType(); if (Promotable->isSignedIntegerType()) return IntTy; uint64_t PromotableSize = getTypeSize(Promotable); @@ -4358,6 +4360,8 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { if (LHSClass != RHSClass) { // C99 6.7.2.2p4: Each enumerated type shall be compatible with char, // a signed integer type, or an unsigned integer type. + // Compatibility is based on the underlying type, not the promotion + // type. if (const EnumType* ETy = LHS->getAs<EnumType>()) { if (ETy->getDecl()->getIntegerType() == RHSCan.getUnqualifiedType()) return RHS; @@ -4517,6 +4521,8 @@ unsigned ASTContext::getIntWidth(QualType T) { if (FixedWidthIntType *FWIT = dyn_cast<FixedWidthIntType>(T)) { return FWIT->getWidth(); } + if (EnumType *ET = dyn_cast<EnumType>(T)) + T = ET->getDecl()->getPromotionType(); // For builtin types, just use the standard type sizing method return (unsigned)getTypeSize(T); } |

