r259734 - Fix predefine for __NSConstantString struct type

Ben Langmuir via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 3 16:55:24 PST 2016


Author: benlangmuir
Date: Wed Feb  3 18:55:24 2016
New Revision: 259734

URL: http://llvm.org/viewvc/llvm-project?rev=259734&view=rev
Log:
Fix predefine for __NSConstantString struct type

Per review feedback the name was wrong and it can be used outside
Objective-C.

Unfortunately, making the internal struct visible broke some ASTMatchers
tests that assumed that the first record decl would be from user code,
rather than a builtin type.  I'm worried that this will also affect
users' code.  So this patch adds a typedef to wrap the internal struct
and only makes the typedef visible to namelookup.  This is sufficient to
allow the ASTReader to merge the decls we need without making the struct
itself visible.

rdar://problem/24425801

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/ASTWriter.cpp
    cfe/trunk/test/CodeGenObjC/2010-02-01-utf16-with-null.m
    cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m
    cfe/trunk/test/CodeGenObjC/tentative-cfconstantstring.m
    cfe/trunk/test/Modules/Inputs/builtin.h
    cfe/trunk/test/Modules/builtins.m

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Feb  3 18:55:24 2016
@@ -253,8 +253,9 @@ class ASTContext : public RefCountedBase
   mutable IdentifierInfo *MakeIntegerSeqName = nullptr;
 
   QualType ObjCConstantStringType;
-  mutable RecordDecl *CFConstantStringTypeDecl;
-  
+  mutable RecordDecl *CFConstantStringTagDecl;
+  mutable TypedefDecl *CFConstantStringTypeDecl;
+
   mutable QualType ObjCSuperType;
   
   QualType ObjCNSStringType;
@@ -1381,11 +1382,12 @@ public:
   /// if it hasn't yet been built.
   QualType getRawCFConstantStringType() const {
     if (CFConstantStringTypeDecl)
-      return getTagDeclType(CFConstantStringTypeDecl);
+      return getTypedefType(CFConstantStringTypeDecl);
     return QualType();
   }
   void setCFConstantStringType(QualType T);
-  TagDecl *getCFConstantStringDecl() const;
+  TypedefDecl *getCFConstantStringDecl() const;
+  RecordDecl *getCFConstantStringTagDecl() const;
 
   // This setter/getter represents the ObjC type for an NSConstantString.
   void setObjCConstantStringInterface(ObjCInterfaceDecl *Decl);

Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Wed Feb  3 18:55:24 2016
@@ -988,15 +988,18 @@ namespace clang {
       /// \brief The internal '__make_integer_seq' template.
       PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13,
 
-      /// \brief The internal '__NSConstantString' type.
+      /// \brief The internal '__NSConstantString' typedef.
       PREDEF_DECL_CF_CONSTANT_STRING_ID = 14,
+
+      /// \brief The internal '__NSConstantString' tag type.
+      PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID = 15,
     };
 
     /// \brief The number of declaration IDs that are predefined.
     ///
     /// For more information about predefined declarations, see the
     /// \c PredefinedDeclIDs type and the PREDEF_DECL_*_ID constants.
-    const unsigned int NUM_PREDEF_DECL_IDS = 15;
+    const unsigned int NUM_PREDEF_DECL_IDS = 16;
 
     /// \brief Record code for a list of local redeclarations of a declaration.
     const unsigned int LOCAL_REDECLARATIONS = 50;

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Wed Feb  3 18:55:24 2016
@@ -738,12 +738,13 @@ ASTContext::ASTContext(LangOptions &LOpt
       BuiltinVaListDecl(nullptr), BuiltinMSVaListDecl(nullptr),
       ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr),
       ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
-      CFConstantStringTypeDecl(nullptr), ObjCInstanceTypeDecl(nullptr),
-      FILEDecl(nullptr), jmp_bufDecl(nullptr), sigjmp_bufDecl(nullptr),
-      ucontext_tDecl(nullptr), BlockDescriptorType(nullptr),
-      BlockDescriptorExtendedType(nullptr), cudaConfigureCallDecl(nullptr),
-      FirstLocalImport(), LastLocalImport(), ExternCContext(nullptr),
-      MakeIntegerSeqDecl(nullptr), SourceMgr(SM), LangOpts(LOpts),
+      CFConstantStringTagDecl(nullptr), CFConstantStringTypeDecl(nullptr),
+      ObjCInstanceTypeDecl(nullptr), FILEDecl(nullptr), jmp_bufDecl(nullptr),
+      sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr),
+      BlockDescriptorType(nullptr), BlockDescriptorExtendedType(nullptr),
+      cudaConfigureCallDecl(nullptr), FirstLocalImport(), LastLocalImport(),
+      ExternCContext(nullptr), MakeIntegerSeqDecl(nullptr), SourceMgr(SM),
+      LangOpts(LOpts),
       SanitizerBL(new SanitizerBlacklist(LangOpts.SanitizerBlacklistFiles, SM)),
       AddrSpaceMap(nullptr), Target(nullptr), AuxTarget(nullptr),
       PrintingPolicy(LOpts), Idents(idents), Selectors(sels),
@@ -4868,12 +4869,12 @@ int ASTContext::getIntegerTypeOrder(Qual
   return 1;
 }
 
-TagDecl *ASTContext::getCFConstantStringDecl() const {
+TypedefDecl *ASTContext::getCFConstantStringDecl() const {
   if (!CFConstantStringTypeDecl) {
-    // This type is designed to be compatible with NSConstantString, but cannot
-    // use the same name, since NSConstantString is an interface.
-    CFConstantStringTypeDecl = buildImplicitRecord("__NSConstantString");
-    CFConstantStringTypeDecl->startDefinition();
+    assert(!CFConstantStringTagDecl &&
+           "tag and typedef should be initialized together");
+    CFConstantStringTagDecl = buildImplicitRecord("__NSConstantString_tag");
+    CFConstantStringTagDecl->startDefinition();
 
     QualType FieldTypes[4];
 
@@ -4888,7 +4889,7 @@ TagDecl *ASTContext::getCFConstantString
 
     // Create fields
     for (unsigned i = 0; i < 4; ++i) {
-      FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTypeDecl,
+      FieldDecl *Field = FieldDecl::Create(*this, CFConstantStringTagDecl,
                                            SourceLocation(),
                                            SourceLocation(), nullptr,
                                            FieldTypes[i], /*TInfo=*/nullptr,
@@ -4896,18 +4897,29 @@ TagDecl *ASTContext::getCFConstantString
                                            /*Mutable=*/false,
                                            ICIS_NoInit);
       Field->setAccess(AS_public);
-      CFConstantStringTypeDecl->addDecl(Field);
+      CFConstantStringTagDecl->addDecl(Field);
     }
 
-    CFConstantStringTypeDecl->completeDefinition();
+    CFConstantStringTagDecl->completeDefinition();
+    // This type is designed to be compatible with NSConstantString, but cannot
+    // use the same name, since NSConstantString is an interface.
+    auto tagType = getTagDeclType(CFConstantStringTagDecl);
+    CFConstantStringTypeDecl =
+        buildImplicitTypedef(tagType, "__NSConstantString");
   }
 
   return CFConstantStringTypeDecl;
 }
 
+RecordDecl *ASTContext::getCFConstantStringTagDecl() const {
+  if (!CFConstantStringTagDecl)
+    getCFConstantStringDecl(); // Build the tag and the typedef.
+  return CFConstantStringTagDecl;
+}
+
 // getCFConstantStringType - Return the type used for constant CFStrings.
 QualType ASTContext::getCFConstantStringType() const {
-  return getTagDeclType(getCFConstantStringDecl());
+  return getTypedefType(getCFConstantStringDecl());
 }
 
 QualType ASTContext::getObjCSuperType() const {
@@ -4920,9 +4932,13 @@ QualType ASTContext::getObjCSuperType()
 }
 
 void ASTContext::setCFConstantStringType(QualType T) {
-  const RecordType *Rec = T->getAs<RecordType>();
-  assert(Rec && "Invalid CFConstantStringType");
-  CFConstantStringTypeDecl = Rec->getDecl();
+  const TypedefType *TD = T->getAs<TypedefType>();
+  assert(TD && "Invalid CFConstantStringType");
+  CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl());
+  auto TagType =
+      CFConstantStringTypeDecl->getUnderlyingType()->getAs<RecordType>();
+  assert(TagType && "Invalid CFConstantStringType");
+  CFConstantStringTagDecl = TagType->getDecl();
 }
 
 QualType ASTContext::getBlockDescriptorType() const {

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Wed Feb  3 18:55:24 2016
@@ -189,12 +189,13 @@ void Sema::Initialize() {
     DeclarationName Protocol = &Context.Idents.get("Protocol");
     if (IdResolver.begin(Protocol) == IdResolver.end())
       PushOnScopeChains(Context.getObjCProtocolDecl(), TUScope);
-
-    DeclarationName ConstantString = &Context.Idents.get("NSConstantString");
-    if (IdResolver.begin(ConstantString) == IdResolver.end())
-      PushOnScopeChains(Context.getCFConstantStringDecl(), TUScope);
   }
 
+  // Create the internal type for the *StringMakeConstantString builtins.
+  DeclarationName ConstantString = &Context.Idents.get("__NSConstantString");
+  if (IdResolver.begin(ConstantString) == IdResolver.end())
+    PushOnScopeChains(Context.getCFConstantStringDecl(), TUScope);
+
   // Initialize Microsoft "predefined C++ types".
   if (getLangOpts().MSVCCompat) {
     if (getLangOpts().CPlusPlus &&

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Wed Feb  3 18:55:24 2016
@@ -6447,6 +6447,9 @@ static Decl *getPredefinedDecl(ASTContex
 
   case PREDEF_DECL_CF_CONSTANT_STRING_ID:
     return Context.getCFConstantStringDecl();
+
+  case PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID:
+    return Context.getCFConstantStringTagDecl();
   }
   llvm_unreachable("PredefinedDeclIDs unknown enum value");
 }

Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Feb  3 18:55:24 2016
@@ -4154,6 +4154,8 @@ uint64_t ASTWriter::WriteASTCore(Sema &S
                      PREDEF_DECL_MAKE_INTEGER_SEQ_ID);
   RegisterPredefDecl(Context.CFConstantStringTypeDecl,
                      PREDEF_DECL_CF_CONSTANT_STRING_ID);
+  RegisterPredefDecl(Context.CFConstantStringTagDecl,
+                     PREDEF_DECL_CF_CONSTANT_STRING_TAG_ID);
 
   // Build a record containing all of the tentative definitions in this file, in
   // TentativeDefinitions order.  Generally, this record will be empty for

Modified: cfe/trunk/test/CodeGenObjC/2010-02-01-utf16-with-null.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/2010-02-01-utf16-with-null.m?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/2010-02-01-utf16-with-null.m (original)
+++ cfe/trunk/test/CodeGenObjC/2010-02-01-utf16-with-null.m Wed Feb  3 18:55:24 2016
@@ -2,6 +2,6 @@
 // rdar://7589850
 
 // CHECK: @.str = private unnamed_addr constant [9 x i16] [i16 103, i16 111, i16 111, i16 100, i16 0, i16 98, i16 121, i16 101, i16 0], section "__TEXT,__ustring", align 2
-// CHECK: @_unnamed_cfstring_ = private constant %struct.__NSConstantString { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast ([9 x i16]* @.str to i8*), i32 8 }, section "__DATA,__cfstring"
-// CHECK: @P = global i8* bitcast (%struct.__NSConstantString* @_unnamed_cfstring_ to i8*), align 4
+// CHECK: @_unnamed_cfstring_ = private constant %struct.__NSConstantString_tag { i32* getelementptr inbounds ([0 x i32], [0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 2000, i8* bitcast ([9 x i16]* @.str to i8*), i32 8 }, section "__DATA,__cfstring"
+// CHECK: @P = global i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to i8*), align 4
 void *P = @"good\0bye";

Modified: cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m Wed Feb  3 18:55:24 2016
@@ -34,7 +34,7 @@ void test1(id x) {
 void NSLog(id, ...);
 
 // CHECK-LABEL: define void @test2(
-// CHECK: invoke void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString* @_unnamed_cfstring_ to i8*), i32* %{{.*}})
+// CHECK: invoke void (i8*, ...) @NSLog(i8* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_ to i8*), i32* %{{.*}})
 // CHECK:   to label %{{.*}} unwind label %{{.*}}, !clang.arc.no_objc_arc_exceptions !
 // NO-METADATA-LABEL: define void @test2(
 // NO-METADATA-NOT: !clang.arc.no_objc_arc_exceptions

Modified: cfe/trunk/test/CodeGenObjC/tentative-cfconstantstring.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/tentative-cfconstantstring.m?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/tentative-cfconstantstring.m (original)
+++ cfe/trunk/test/CodeGenObjC/tentative-cfconstantstring.m Wed Feb  3 18:55:24 2016
@@ -32,12 +32,11 @@ static inline void _inlineFunction() {
 @end
 
 // CHECK: @__CFConstantStringClassReference = common global [24 x i32] zeroinitializer, align 16
-// CHECK: @_unnamed_cfstring_{{.*}} = private constant %struct.__NSConstantString { i32* getelementptr inbounds ([24 x i32], [24 x i32]* @__CFConstantStringClassReference, i32 0, i32 0)
+// CHECK: @_unnamed_cfstring_{{.*}} = private constant %struct.__NSConstantString_tag { i32* getelementptr inbounds ([24 x i32], [24 x i32]* @__CFConstantStringClassReference, i32 0, i32 0)
 
 // CHECK-LABEL: define internal void @_inlineFunction()
 // CHECK:  [[ZERO:%.*]] = load %struct._class_t*, %struct._class_t** @"OBJC_CLASSLIST_REFERENCES_
 // CHECK-NEXT:   [[ONE:%.*]] = load i8*, i8** @OBJC_SELECTOR_REFERENCES_
 // CHECK-NEXT:   [[TWO:%.*]] = bitcast %struct._class_t* [[ZERO]] to i8*
-// CHECK-NEXT:   call void (i8*, i8*, [[T:%.*]]*, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, [[T:%.*]]*, ...)*)(i8* [[TWO]], i8* [[ONE]], [[T:%.*]]* bitcast (%struct.__NSConstantString* @_unnamed_cfstring_{{.*}} to [[T:%.*]]*))
+// CHECK-NEXT:   call void (i8*, i8*, [[T:%.*]]*, ...) bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, [[T:%.*]]*, ...)*)(i8* [[TWO]], i8* [[ONE]], [[T:%.*]]* bitcast (%struct.__NSConstantString_tag* @_unnamed_cfstring_{{.*}} to [[T:%.*]]*))
 // CHECK-NEXT:   ret void
-

Modified: cfe/trunk/test/Modules/Inputs/builtin.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/builtin.h?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/builtin.h (original)
+++ cfe/trunk/test/Modules/Inputs/builtin.h Wed Feb  3 18:55:24 2016
@@ -1,10 +1,7 @@
 int i;
 int *p = &i;
 
-#ifdef __OBJC__
 void use_constant_string_builtins(void) {
   (void)__builtin___CFStringMakeConstantString("");
   (void)__builtin___NSStringMakeConstantString("");
 }
-#endif
-

Modified: cfe/trunk/test/Modules/builtins.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/builtins.m?rev=259734&r1=259733&r2=259734&view=diff
==============================================================================
--- cfe/trunk/test/Modules/builtins.m (original)
+++ cfe/trunk/test/Modules/builtins.m Wed Feb  3 18:55:24 2016
@@ -1,5 +1,7 @@
 // RUN: rm -rf %t
 // RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %s -verify
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs -x c %s -verify
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs -x objective-c++ %s -verify
 
 // RUN: rm -rf %t.pch.cache
 // RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs -emit-pch -o %t.pch -x objective-c-header %S/Inputs/use-builtin.h
@@ -12,13 +14,13 @@ void use_constant_string_builtins1(void)
   (void)__builtin___NSStringMakeConstantString("");
 }
 
- at import builtin;
+#include "builtin.h"
 
 int foo() {
   return __builtin_object_size(p, 0);
 }
 
- at import builtin.sub;
+#include "builtin_sub.h"
 
 int bar() {
   return __builtin_object_size(p, 0);




More information about the cfe-commits mailing list