mirror of https://github.com/microsoft/clang.git
Allow C++0x enumerations with a fixed underlying type in
Objective-C. The @encode'ing of such an enumeration type is the same as its underlying type. <rdar://problem/5276348>. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@139297 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
6aff47db98
commit
5471bc85b6
|
@ -81,6 +81,7 @@
|
|||
<ul>
|
||||
<li><a href="#objc_instancetype">Related result types</a></li>
|
||||
<li><a href="#objc_arc">Automatic reference counting</a></li>
|
||||
<li><a href="#objc_fixed_enum">Enumerations with a fixed underlying type</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#overloading-in-c">Function Overloading in C</a></li>
|
||||
|
@ -773,6 +774,24 @@ returns <tt>id</tt>.</p>
|
|||
|
||||
<p>Clang provides support for <a href="AutomaticReferenceCounting.html">automated reference counting</a> in Objective-C, which eliminates the need for manual retain/release/autorelease message sends. There are two feature macros associated with automatic reference counting: <code>__has_feature(objc_arc)</code> indicates the availability of automated reference counting in general, while <code>__has_feature(objc_arc_weak)</code> indicates that automated reference counting also includes support for <code>__weak</code> pointers to Objective-C objects.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h2 id="objc_fixed_enum">Enumerations with a fixed underlying type</h2>
|
||||
<!-- ======================================================================= -->
|
||||
|
||||
<p>Clang provides support for C++0x enumerations with a fixed
|
||||
underlying type within Objective-C. For example, one can write an
|
||||
enumeration type as:</p>
|
||||
|
||||
<pre>
|
||||
typedef enum : unsigned char { Red, Green, Blue } Color;
|
||||
</pre>
|
||||
|
||||
<p>This specifies that the underlying type, which is used to store the
|
||||
enumeration value, is <tt>unsigned char</tt>.</p>
|
||||
|
||||
<p>Use <tt>__has_feature(objc_fixed_enum)</tt> to determine whether
|
||||
support for fixed underlying types is available in Objective-C.</p>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<h2 id="overloading-in-c">Function Overloading in C</h2>
|
||||
<!-- ======================================================================= -->
|
||||
|
|
|
@ -4204,6 +4204,17 @@ static char ObjCEncodingForPrimitiveKind(const ASTContext *C, QualType T) {
|
|||
}
|
||||
}
|
||||
|
||||
static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) {
|
||||
EnumDecl *Enum = ET->getDecl();
|
||||
|
||||
// The encoding of an non-fixed enum type is always 'i', regardless of size.
|
||||
if (!Enum->isFixed())
|
||||
return 'i';
|
||||
|
||||
// The encoding of a fixed enum type matches its fixed underlying type.
|
||||
return ObjCEncodingForPrimitiveKind(C, Enum->getIntegerType());
|
||||
}
|
||||
|
||||
static void EncodeBitField(const ASTContext *Ctx, std::string& S,
|
||||
QualType T, const FieldDecl *FD) {
|
||||
const Expr *E = FD->getBitWidth();
|
||||
|
@ -4228,8 +4239,8 @@ static void EncodeBitField(const ASTContext *Ctx, std::string& S,
|
|||
const RecordDecl *RD = FD->getParent();
|
||||
const ASTRecordLayout &RL = Ctx->getASTRecordLayout(RD);
|
||||
S += llvm::utostr(RL.getFieldOffset(FD->getFieldIndex()));
|
||||
if (T->isEnumeralType())
|
||||
S += 'i';
|
||||
if (const EnumType *ET = T->getAs<EnumType>())
|
||||
S += ObjCEncodingForEnumType(Ctx, ET);
|
||||
else
|
||||
S += ObjCEncodingForPrimitiveKind(Ctx, T);
|
||||
}
|
||||
|
@ -4415,11 +4426,11 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
|
|||
return;
|
||||
}
|
||||
|
||||
if (T->isEnumeralType()) {
|
||||
if (const EnumType *ET = T->getAs<EnumType>()) {
|
||||
if (FD && FD->isBitField())
|
||||
EncodeBitField(this, S, T, FD);
|
||||
else
|
||||
S += 'i';
|
||||
S += ObjCEncodingForEnumType(this, ET);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -599,6 +599,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
|
|||
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
|
||||
.Case("objc_arc_weak", LangOpts.ObjCAutoRefCount &&
|
||||
LangOpts.ObjCRuntimeHasWeak)
|
||||
.Case("objc_fixed_enum", LangOpts.ObjC2)
|
||||
.Case("objc_instancetype", LangOpts.ObjC2)
|
||||
.Case("objc_nonfragile_abi", LangOpts.ObjCNonFragileABI)
|
||||
.Case("objc_weak_class", LangOpts.ObjCNonFragileABI)
|
||||
|
|
|
@ -2555,7 +2555,8 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
|||
ParsedAttributes attrs(AttrFactory);
|
||||
MaybeParseGNUAttributes(attrs);
|
||||
|
||||
bool AllowFixedUnderlyingType = getLang().CPlusPlus0x || getLang().Microsoft;
|
||||
bool AllowFixedUnderlyingType
|
||||
= getLang().CPlusPlus0x || getLang().Microsoft || getLang().ObjC2;
|
||||
|
||||
CXXScopeSpec &SS = DS.getTypeSpecScope();
|
||||
if (getLang().CPlusPlus) {
|
||||
|
@ -2658,7 +2659,7 @@ void Parser::ParseEnumSpecifier(SourceLocation StartLoc, DeclSpec &DS,
|
|||
SourceRange Range;
|
||||
BaseType = ParseTypeName(&Range);
|
||||
|
||||
if (!getLang().CPlusPlus0x)
|
||||
if (!getLang().CPlusPlus0x && !getLang().ObjC2)
|
||||
Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
|
||||
<< Range;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
// RUN: %clang_cc1 -emit-llvm -o - %s -O2 | grep "ret i32 1"
|
||||
typedef long Integer;
|
||||
typedef enum : Integer { Red, Green, Blue} Color;
|
||||
typedef enum { Cyan, Magenta, Yellow, Key } PrintColor;
|
||||
|
||||
int a() {
|
||||
return @encode(int) == @encode(int);
|
||||
return @encode(int) == @encode(int) &&
|
||||
@encode(Color) == @encode(long) &&
|
||||
@encode(PrintColor) == @encode(int);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
||||
|
||||
#if !__has_feature(objc_fixed_enum)
|
||||
# error Enumerations with a fixed underlying type are not supported
|
||||
#endif
|
||||
|
||||
typedef long Integer;
|
||||
|
||||
typedef enum : Integer { Enumerator1, Enumerator2 } Enumeration;
|
||||
|
||||
int array[sizeof(Enumeration) == sizeof(long)? 1 : -1];
|
||||
|
||||
|
||||
enum Color { Red, Green, Blue };
|
||||
|
||||
struct X {
|
||||
enum Color : 4;
|
||||
enum Color field1: 4;
|
||||
enum Other : Integer field2;
|
||||
enum Other : Integer field3 : 4;
|
||||
enum : Integer { Blah, Blarg } field4 : 4;
|
||||
};
|
Loading…
Reference in New Issue