[cfe-commits] r139297 - in /cfe/trunk: docs/LanguageExtensions.html lib/AST/ASTContext.cpp lib/Lex/PPMacroExpansion.cpp lib/Parse/ParseDecl.cpp test/CodeGenObjC/encode-test-4.m test/SemaObjC/enum-fixed-type.m

Douglas Gregor dgregor at apple.com
Thu Sep 8 10:18:36 PDT 2011


Author: dgregor
Date: Thu Sep  8 12:18:35 2011
New Revision: 139297

URL: http://llvm.org/viewvc/llvm-project?rev=139297&view=rev
Log:
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>.


Added:
    cfe/trunk/test/SemaObjC/enum-fixed-type.m
Modified:
    cfe/trunk/docs/LanguageExtensions.html
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Lex/PPMacroExpansion.cpp
    cfe/trunk/lib/Parse/ParseDecl.cpp
    cfe/trunk/test/CodeGenObjC/encode-test-4.m

Modified: cfe/trunk/docs/LanguageExtensions.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LanguageExtensions.html?rev=139297&r1=139296&r2=139297&view=diff
==============================================================================
--- cfe/trunk/docs/LanguageExtensions.html (original)
+++ cfe/trunk/docs/LanguageExtensions.html Thu Sep  8 12:18:35 2011
@@ -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>
@@ -774,6 +775,24 @@
 <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>
 <!-- ======================================================================= -->
 

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=139297&r1=139296&r2=139297&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Sep  8 12:18:35 2011
@@ -4204,6 +4204,17 @@
     }
 }
 
+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 @@
     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 @@
     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;
   }
 

Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=139297&r1=139296&r2=139297&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)
+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Thu Sep  8 12:18:35 2011
@@ -599,6 +599,7 @@
            .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)

Modified: cfe/trunk/lib/Parse/ParseDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseDecl.cpp?rev=139297&r1=139296&r2=139297&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseDecl.cpp (original)
+++ cfe/trunk/lib/Parse/ParseDecl.cpp Thu Sep  8 12:18:35 2011
@@ -2555,7 +2555,8 @@
   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 @@
       SourceRange Range;
       BaseType = ParseTypeName(&Range);
       
-      if (!getLang().CPlusPlus0x)
+      if (!getLang().CPlusPlus0x && !getLang().ObjC2)
         Diag(StartLoc, diag::ext_ms_enum_fixed_underlying_type)
           << Range;
     }

Modified: cfe/trunk/test/CodeGenObjC/encode-test-4.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/encode-test-4.m?rev=139297&r1=139296&r2=139297&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/encode-test-4.m (original)
+++ cfe/trunk/test/CodeGenObjC/encode-test-4.m Thu Sep  8 12:18:35 2011
@@ -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);
 }

Added: cfe/trunk/test/SemaObjC/enum-fixed-type.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/enum-fixed-type.m?rev=139297&view=auto
==============================================================================
--- cfe/trunk/test/SemaObjC/enum-fixed-type.m (added)
+++ cfe/trunk/test/SemaObjC/enum-fixed-type.m Thu Sep  8 12:18:35 2011
@@ -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;
+};





More information about the cfe-commits mailing list