From c9467cf4cff1bb09f38667b871268c47ed823f97 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 12 Dec 2008 02:00:36 +0000 Subject: [PATCH] In C++, set the type of each of the enumerators in an enumeration to the type of the enumeration once the enumeration has been defined. Fix the overloading test-case to properly create enums that promote the way we want them to. Implement C++0x promotions from enumeration types to long long/unsigned long long. We're using these promotions in Carbon.h (since long long is a common extension). Fixes PR clang/2954: http://llvm.org/bugs/show_bug.cgi?id=2954 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@60917 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaDecl.cpp | 20 +++++++++++++++++++- lib/Sema/SemaOverload.cpp | 8 +++++--- test/SemaCXX/overload-call.cpp | 6 +++--- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index fe53585aae..43964f7cca 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -3176,6 +3176,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, // Keep track of whether all elements have type int. bool AllElementsInt = true; + QualType EnumType = Context.getTypeDeclType(Enum); EnumConstantDecl *EltList = 0; for (unsigned i = 0; i != NumElements; ++i) { EnumConstantDecl *ECD = @@ -3269,6 +3270,12 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, llvm::APSInt IV = ECD->getInitVal(); IV.setIsSigned(true); ECD->setInitVal(IV); + + if (getLangOptions().CPlusPlus) + // C++ [dcl.enum]p4: Following the closing brace of an + // enum-specifier, each enumerator has the type of its + // enumeration. + ECD->setType(EnumType); continue; // Already int type. } @@ -3291,6 +3298,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, NewSign = true; } else if (ECD->getType() == BestType) { // Already the right type! + if (getLangOptions().CPlusPlus) + // C++ [dcl.enum]p4: Following the closing brace of an + // enum-specifier, each enumerator has the type of its + // enumeration. + ECD->setType(EnumType); continue; } else { NewTy = BestType; @@ -3306,7 +3318,13 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, DeclTy *EnumDeclX, // Adjust the Expr initializer and type. ECD->setInitExpr(new ImplicitCastExpr(NewTy, ECD->getInitExpr(), /*isLvalue=*/false)); - ECD->setType(NewTy); + if (getLangOptions().CPlusPlus) + // C++ [dcl.enum]p4: Following the closing brace of an + // enum-specifier, each enumerator has the type of its + // enumeration. + ECD->setType(EnumType); + else + ECD->setType(NewTy); } Enum->completeDefinition(Context, BestType); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index def85ca9e9..4bfe0c4dab 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -634,11 +634,12 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) // The types we'll try to promote to, in the appropriate // order. Try each of these types. - QualType PromoteTypes[4] = { + QualType PromoteTypes[6] = { Context.IntTy, Context.UnsignedIntTy, - Context.LongTy, Context.UnsignedLongTy + Context.LongTy, Context.UnsignedLongTy , + Context.LongLongTy, Context.UnsignedLongLongTy }; - for (int Idx = 0; Idx < 4; ++Idx) { + for (int Idx = 0; Idx < 6; ++Idx) { uint64_t ToSize = Context.getTypeSize(PromoteTypes[Idx]); if (FromSize < ToSize || (FromSize == ToSize && @@ -2034,6 +2035,7 @@ void Sema::AddBuiltinCandidate(QualType ResultTy, QualType *ParamTys, CandidateSet.push_back(OverloadCandidate()); OverloadCandidate& Candidate = CandidateSet.back(); Candidate.Function = 0; + Candidate.IsSurrogate = false; Candidate.BuiltinTypes.ResultTy = ResultTy; for (unsigned ArgIdx = 0; ArgIdx < NumArgs; ++ArgIdx) Candidate.BuiltinTypes.ParamTypes[ArgIdx] = ParamTys[ArgIdx]; diff --git a/test/SemaCXX/overload-call.cpp b/test/SemaCXX/overload-call.cpp index 5460521e11..eed8223862 100644 --- a/test/SemaCXX/overload-call.cpp +++ b/test/SemaCXX/overload-call.cpp @@ -1,4 +1,4 @@ -// RUN: clang -fsyntax-only -pedantic -verify %s +// RUN: clang -fsyntax-only -pedantic -verify %s int* f(int) { return 0; } float* f(float) { return 0; } void f(); @@ -88,11 +88,11 @@ void test_n(E* e) { } enum PromotesToInt { - PromotesToIntValue = 1 + PromotesToIntValue = -1 }; enum PromotesToUnsignedInt { - PromotesToUnsignedIntValue = (unsigned int)-1 + PromotesToUnsignedIntValue = 1u }; int* o(int); -- 2.40.0