[cfe-commits] r69932 - in /cfe/trunk: include/clang/AST/ASTContext.h include/clang/Frontend/PCHBitCodes.h lib/AST/ASTContext.cpp lib/AST/DeclarationName.cpp lib/Frontend/PCHReader.cpp lib/Frontend/PCHWriter.cpp lib/Sema/Sema.cpp lib/Sema/SemaDecl.cpp test/PCH/objc_methods.m test/PCH/objc_property.m

Douglas Gregor dgregor at apple.com
Thu Apr 23 15:29:12 PDT 2009


Author: dgregor
Date: Thu Apr 23 17:29:11 2009
New Revision: 69932

URL: http://llvm.org/viewvc/llvm-project?rev=69932&view=rev
Log:
PCH support for all of the predefined Objective-C types, such as id,
SEL, Class, Protocol, CFConstantString, and
__objcFastEnumerationState. With this, we can now run the Objective-C
methods and properties PCH tests.


Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/Frontend/PCHBitCodes.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/AST/DeclarationName.cpp
    cfe/trunk/lib/Frontend/PCHReader.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/test/PCH/objc_methods.m
    cfe/trunk/test/PCH/objc_property.m

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Thu Apr 23 17:29:11 2009
@@ -370,6 +370,15 @@
   // constant CFStrings.
   QualType getCFConstantStringType(); 
   
+  /// Get the structure type used to representation CFStrings, or NULL
+  /// if it hasn't yet been built.
+  QualType getRawCFConstantStringType() {
+    if (CFConstantStringTypeDecl)
+      return getTagDeclType(CFConstantStringTypeDecl);
+    return QualType();
+  }
+  void setCFConstantStringType(QualType T);
+
   // This setter/getter represents the ObjC type for an NSConstantString.
   void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);
   QualType getObjCConstantStringInterface() const { 
@@ -379,6 +388,16 @@
   //// This gets the struct used to keep track of fast enumerations.
   QualType getObjCFastEnumerationStateType();
   
+  /// Get the ObjCFastEnumerationState type, or NULL if it hasn't yet
+  /// been built.
+  QualType getRawObjCFastEnumerationStateType() {
+    if (ObjCFastEnumerationStateTypeDecl)
+      return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
+    return QualType();
+  }
+
+  void setObjCFastEnumerationStateType(QualType T);
+
   /// getObjCEncodingForType - Emit the ObjC type encoding for the
   /// given type into \arg S. If \arg NameFields is specified then
   /// record field names are also encoded.
@@ -410,9 +429,9 @@
   /// This setter/getter represents the ObjC 'id' type. It is setup lazily, by
   /// Sema.  id is always a (typedef for a) pointer type, a pointer to a struct.
   QualType getObjCIdType() const { return ObjCIdType; }
-  void setObjCIdType(TypedefDecl *Decl);
+  void setObjCIdType(QualType T);
   
-  void setObjCSelType(TypedefDecl *Decl);
+  void setObjCSelType(QualType T);
   QualType getObjCSelType() const { return ObjCSelType; }
   
   void setObjCProtoType(QualType QT);
@@ -422,7 +441,7 @@
   /// Sema.  'Class' is always a (typedef for a) pointer type, a pointer to a
   /// struct.
   QualType getObjCClassType() const { return ObjCClassType; }
-  void setObjCClassType(TypedefDecl *Decl);
+  void setObjCClassType(QualType T);
   
   void setBuiltinVaListType(QualType T);
   QualType getBuiltinVaListType() const { return BuiltinVaListType; }

Modified: cfe/trunk/include/clang/Frontend/PCHBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHBitCodes.h?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHBitCodes.h (original)
+++ cfe/trunk/include/clang/Frontend/PCHBitCodes.h Thu Apr 23 17:29:11 2009
@@ -342,7 +342,19 @@
     /// SPECIAL_TYPES record.
     enum SpecialTypeIDs {
       /// \brief __builtin_va_list
-      SPECIAL_TYPE_BUILTIN_VA_LIST = 0
+      SPECIAL_TYPE_BUILTIN_VA_LIST             = 0,
+      /// \brief Objective-C "id" type
+      SPECIAL_TYPE_OBJC_ID                     = 1,
+      /// \brief Objective-C selector type
+      SPECIAL_TYPE_OBJC_SELECTOR               = 2,
+      /// \brief Objective-C Protocol type
+      SPECIAL_TYPE_OBJC_PROTOCOL               = 3,
+      /// \brief Objective-C Class type
+      SPECIAL_TYPE_OBJC_CLASS                  = 4,
+      /// \brief CFConstantString type
+      SPECIAL_TYPE_CF_CONSTANT_STRING          = 5,
+      /// \brief Objective-C fast enumeration state type
+      SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE = 6
     };
 
     /// \brief Record codes for each kind of declaration.

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Thu Apr 23 17:29:11 2009
@@ -2000,6 +2000,12 @@
   return getTagDeclType(CFConstantStringTypeDecl);
 }
 
+void ASTContext::setCFConstantStringType(QualType T) {
+  const RecordType *Rec = T->getAsRecordType();
+  assert(Rec && "Invalid CFConstantStringType");
+  CFConstantStringTypeDecl = Rec->getDecl();
+}
+
 QualType ASTContext::getObjCFastEnumerationStateType()
 {
   if (!ObjCFastEnumerationStateTypeDecl) {
@@ -2030,6 +2036,12 @@
   return getTagDeclType(ObjCFastEnumerationStateTypeDecl);
 }
 
+void ASTContext::setObjCFastEnumerationStateType(QualType T) {
+  const RecordType *Rec = T->getAsRecordType();
+  assert(Rec && "Invalid ObjCFAstEnumerationStateType");
+  ObjCFastEnumerationStateTypeDecl = Rec->getDecl();
+}
+
 // This returns true if a type has been typedefed to BOOL:
 // typedef <type> BOOL;
 static bool isTypeTypedefedAsBOOL(QualType T) {
@@ -2520,9 +2532,15 @@
   BuiltinVaListType = T;
 }
 
-void ASTContext::setObjCIdType(TypedefDecl *TD)
+void ASTContext::setObjCIdType(QualType T)
 {
-  ObjCIdType = getTypedefType(TD);
+  ObjCIdType = T;
+
+  const TypedefType *TT = T->getAsTypedefType();
+  if (!TT)
+    return;
+
+  TypedefDecl *TD = TT->getDecl();
 
   // typedef struct objc_object *id;
   const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
@@ -2536,9 +2554,14 @@
   IdStructType = rec;
 }
 
-void ASTContext::setObjCSelType(TypedefDecl *TD)
+void ASTContext::setObjCSelType(QualType T)
 {
-  ObjCSelType = getTypedefType(TD);
+  ObjCSelType = T;
+
+  const TypedefType *TT = T->getAsTypedefType();
+  if (!TT)
+    return;
+  TypedefDecl *TD = TT->getDecl();
 
   // typedef struct objc_selector *SEL;
   const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();
@@ -2555,9 +2578,14 @@
   ObjCProtoType = QT;
 }
 
-void ASTContext::setObjCClassType(TypedefDecl *TD)
+void ASTContext::setObjCClassType(QualType T)
 {
-  ObjCClassType = getTypedefType(TD);
+  ObjCClassType = T;
+
+  const TypedefType *TT = T->getAsTypedefType();
+  if (!TT)
+    return;
+  TypedefDecl *TD = TT->getDecl();
 
   // typedef struct objc_class *Class;
   const PointerType *ptr = TD->getUnderlyingType()->getAsPointerType();

Modified: cfe/trunk/lib/AST/DeclarationName.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclarationName.cpp?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/lib/AST/DeclarationName.cpp (original)
+++ cfe/trunk/lib/AST/DeclarationName.cpp Thu Apr 23 17:29:11 2009
@@ -59,6 +59,11 @@
 } // end namespace clang
 
 DeclarationName::DeclarationName(Selector Sel) {
+  if (!Sel.getAsOpaquePtr()) {
+    Ptr = StoredObjCZeroArgSelector;
+    return;
+  }
+
   switch (Sel.getNumArgs()) {
   case 0:
     Ptr = reinterpret_cast<uintptr_t>(Sel.getAsIdentifierInfo());

Modified: cfe/trunk/lib/Frontend/PCHReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReader.cpp?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHReader.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReader.cpp Thu Apr 23 17:29:11 2009
@@ -1948,7 +1948,19 @@
   // Load the special types.
   Context.setBuiltinVaListType(
     GetType(SpecialTypes[pch::SPECIAL_TYPE_BUILTIN_VA_LIST]));
-
+  if (unsigned Id = SpecialTypes[pch::SPECIAL_TYPE_OBJC_ID])
+    Context.setObjCIdType(GetType(Id));
+  if (unsigned Sel = SpecialTypes[pch::SPECIAL_TYPE_OBJC_SELECTOR])
+    Context.setObjCSelType(GetType(Sel));
+  if (unsigned Proto = SpecialTypes[pch::SPECIAL_TYPE_OBJC_PROTOCOL])
+    Context.setObjCProtoType(GetType(Proto));
+  if (unsigned Class = SpecialTypes[pch::SPECIAL_TYPE_OBJC_CLASS])
+    Context.setObjCClassType(GetType(Class));
+  if (unsigned String = SpecialTypes[pch::SPECIAL_TYPE_CF_CONSTANT_STRING])
+    Context.setCFConstantStringType(GetType(String));
+  if (unsigned FastEnum 
+        = SpecialTypes[pch::SPECIAL_TYPE_OBJC_FAST_ENUMERATION_STATE])
+    Context.setObjCFastEnumerationStateType(GetType(FastEnum));
   // If we saw the preprocessor block, read it now.
   if (PreprocessorBlockOffset) {
     SavedStreamPosition SavedPos(Stream);

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Apr 23 17:29:11 2009
@@ -2105,6 +2105,12 @@
   // Write the record of special types.
   Record.clear();
   AddTypeRef(Context.getBuiltinVaListType(), Record);
+  AddTypeRef(Context.getObjCIdType(), Record);
+  AddTypeRef(Context.getObjCSelType(), Record);
+  AddTypeRef(Context.getObjCProtoType(), Record);
+  AddTypeRef(Context.getObjCClassType(), Record);
+  AddTypeRef(Context.getRawCFConstantStringType(), Record);
+  AddTypeRef(Context.getRawObjCFastEnumerationStateType(), Record);
   Stream.EmitRecord(pch::SPECIAL_TYPES, Record);
 
   // Write the record containing external, unnamed definitions.

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Apr 23 17:29:11 2009
@@ -110,46 +110,54 @@
   PushDeclContext(S, Context.getTranslationUnitDecl());
   if (!PP.getLangOptions().ObjC1) return;
   
-  // Synthesize "typedef struct objc_selector *SEL;"
-  RecordDecl *SelTag = CreateStructDecl(Context, "objc_selector");
-  PushOnScopeChains(SelTag, TUScope);
-  
-  QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
-  TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
-                                                SourceLocation(),
-                                                &Context.Idents.get("SEL"),
-                                                SelT);
-  PushOnScopeChains(SelTypedef, TUScope);
-  Context.setObjCSelType(SelTypedef);
-
-  // FIXME: Make sure these don't leak!
-  RecordDecl *ClassTag = CreateStructDecl(Context, "objc_class");
-  QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
-  TypedefDecl *ClassTypedef = 
-    TypedefDecl::Create(Context, CurContext, SourceLocation(),
-                        &Context.Idents.get("Class"), ClassT);
-  PushOnScopeChains(ClassTag, TUScope);
-  PushOnScopeChains(ClassTypedef, TUScope);
-  Context.setObjCClassType(ClassTypedef);
+  if (Context.getObjCSelType().isNull()) {
+    // Synthesize "typedef struct objc_selector *SEL;"
+    RecordDecl *SelTag = CreateStructDecl(Context, "objc_selector");
+    PushOnScopeChains(SelTag, TUScope);
+  
+    QualType SelT = Context.getPointerType(Context.getTagDeclType(SelTag));
+    TypedefDecl *SelTypedef = TypedefDecl::Create(Context, CurContext,
+                                                  SourceLocation(),
+                                                  &Context.Idents.get("SEL"),
+                                                  SelT);
+    PushOnScopeChains(SelTypedef, TUScope);
+    Context.setObjCSelType(Context.getTypeDeclType(SelTypedef));
+  }
+
+  if (Context.getObjCClassType().isNull()) {
+    RecordDecl *ClassTag = CreateStructDecl(Context, "objc_class");
+    QualType ClassT = Context.getPointerType(Context.getTagDeclType(ClassTag));
+    TypedefDecl *ClassTypedef = 
+      TypedefDecl::Create(Context, CurContext, SourceLocation(),
+                          &Context.Idents.get("Class"), ClassT);
+    PushOnScopeChains(ClassTag, TUScope);
+    PushOnScopeChains(ClassTypedef, TUScope);
+    Context.setObjCClassType(Context.getTypeDeclType(ClassTypedef));
+  }
+
   // Synthesize "@class Protocol;
-  ObjCInterfaceDecl *ProtocolDecl =
-    ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
-                              &Context.Idents.get("Protocol"), 
-                              SourceLocation(), true);
-  Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
-  PushOnScopeChains(ProtocolDecl, TUScope);
-  
-  // Synthesize "typedef struct objc_object { Class isa; } *id;"
-  RecordDecl *ObjectTag = CreateStructDecl(Context, "objc_object");
+  if (Context.getObjCProtoType().isNull()) {
+    ObjCInterfaceDecl *ProtocolDecl =
+      ObjCInterfaceDecl::Create(Context, CurContext, SourceLocation(),
+                                &Context.Idents.get("Protocol"), 
+                                SourceLocation(), true);
+    Context.setObjCProtoType(Context.getObjCInterfaceType(ProtocolDecl));
+    PushOnScopeChains(ProtocolDecl, TUScope);
+  }
 
-  QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
-  PushOnScopeChains(ObjectTag, TUScope);
-  TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
-                                               SourceLocation(),
-                                               &Context.Idents.get("id"),
-                                               ObjT);
-  PushOnScopeChains(IdTypedef, TUScope);
-  Context.setObjCIdType(IdTypedef);
+  // Synthesize "typedef struct objc_object { Class isa; } *id;"
+  if (Context.getObjCIdType().isNull()) {
+    RecordDecl *ObjectTag = CreateStructDecl(Context, "objc_object");
+    
+    QualType ObjT = Context.getPointerType(Context.getTagDeclType(ObjectTag));
+    PushOnScopeChains(ObjectTag, TUScope);
+    TypedefDecl *IdTypedef = TypedefDecl::Create(Context, CurContext,
+                                                 SourceLocation(),
+                                                 &Context.Idents.get("id"),
+                                                 ObjT);
+    PushOnScopeChains(IdTypedef, TUScope);
+    Context.setObjCIdType(Context.getTypeDeclType(IdTypedef));
+  }
 }
 
 Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Apr 23 17:29:11 2009
@@ -473,19 +473,19 @@
     case 2: 
       if (!TypeID->isStr("id"))
         break;
-      Context.setObjCIdType(New);
+      Context.setObjCIdType(Context.getTypeDeclType(New));
       objc_types = true;
       break;
     case 5:
       if (!TypeID->isStr("Class"))
         break;
-      Context.setObjCClassType(New);
+      Context.setObjCClassType(Context.getTypeDeclType(New));
       objc_types = true;
       return false;
     case 3:
       if (!TypeID->isStr("SEL"))
         break;
-      Context.setObjCSelType(New);
+      Context.setObjCSelType(Context.getTypeDeclType(New));
       objc_types = true;
       return false;
     case 8:

Modified: cfe/trunk/test/PCH/objc_methods.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/objc_methods.m?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/test/PCH/objc_methods.m (original)
+++ cfe/trunk/test/PCH/objc_methods.m Thu Apr 23 17:29:11 2009
@@ -11,8 +11,6 @@
 // FIXME:
 // AliasForTestPCH *zz;
  
-#if 0
  xx = [TestPCH alloc];
  [xx instMethod];
-#endif
 }

Modified: cfe/trunk/test/PCH/objc_property.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/objc_property.m?rev=69932&r1=69931&r2=69932&view=diff

==============================================================================
--- cfe/trunk/test/PCH/objc_property.m (original)
+++ cfe/trunk/test/PCH/objc_property.m Thu Apr 23 17:29:11 2009
@@ -1,9 +1,9 @@
 // Test this without pch.
-// FIXME: clang-cc -include %S/objc_property.h -fsyntax-only -verify %s &&
+// RUN: clang-cc -include %S/objc_property.h -fsyntax-only -verify %s &&
 
 // Test with pch.
-// FIXME: clang-cc -x=objective-c -emit-pch -o %t %S/objc_property.h &&
-// FIXME: clang-cc -include-pch %t -fsyntax-only -verify %s 
+// RUN: clang-cc -x=objective-c -emit-pch -o %t %S/objc_property.h &&
+// RUN: clang-cc -include-pch %t -fsyntax-only -verify %s 
 
 void func() {
  TestProperties *xx = [TestProperties alloc];





More information about the cfe-commits mailing list