summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2009-12-09 09:09:27 +0000
committerJohn McCall <rjmccall@apple.com>2009-12-09 09:09:27 +0000
commit5677499fbffe3441543f2e0c2f7e4016270560a5 (patch)
treea2f87a1b1b6eb37c6fbf50caba31774a94c123a2 /clang/lib/AST/ASTContext.cpp
parent1d153328be1c52cf8d595bbd24ca829c2f8334d2 (diff)
downloadbcm5719-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.cpp8
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);
}
OpenPOWER on IntegriCloud