r259624 - Make CF constant string decl visible to name lookup to fix module errors

Ben Langmuir via cfe-commits cfe-commits at lists.llvm.org
Tue Feb 2 19:26:19 PST 2016


Author: benlangmuir
Date: Tue Feb  2 21:26:19 2016
New Revision: 259624

URL: http://llvm.org/viewvc/llvm-project?rev=259624&view=rev
Log:
Make CF constant string decl visible to name lookup to fix module errors

The return type of the __builtin___*StringMakeConstantString functions
is a pointer to a struct, so we need that struct to be visible to name
lookup so that we will correctly merge multiple declarations of that
type if they come from different modules.

Incidentally, to make this visible to name lookup we need to rename the
type to __NSConstantString, since the real NSConstantString is an
Objective-C interface type.  This shouldn't affect anyone outside the
compiler since users of the constant string builtins cast the result
immediately to CFStringRef.

Since this struct type is otherwise implicitly created by the AST
context and cannot access namelookup, we make this a predefined type
and initialize it in Sema.

Note: this issue of builtins that refer to types not visible to name
lookup technically also affects other builtins (e.g. objc_msgSendSuper),
but in all other cases the builtin is a library builtin and the issue
goes away if you include the library that defines the types it uses,
unlike for these constant string builtins.

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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Feb  2 21:26:19 2016
@@ -1385,6 +1385,7 @@ public:
     return QualType();
   }
   void setCFConstantStringType(QualType T);
+  TagDecl *getCFConstantStringDecl() 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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Feb  2 21:26:19 2016
@@ -987,13 +987,16 @@ namespace clang {
 
       /// \brief The internal '__make_integer_seq' template.
       PREDEF_DECL_MAKE_INTEGER_SEQ_ID = 13,
+
+      /// \brief The internal '__NSConstantString' type.
+      PREDEF_DECL_CF_CONSTANT_STRING_ID = 14,
     };
 
     /// \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 = 14;
+    const unsigned int NUM_PREDEF_DECL_IDS = 15;
 
     /// \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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Feb  2 21:26:19 2016
@@ -4868,10 +4868,11 @@ int ASTContext::getIntegerTypeOrder(Qual
   return 1;
 }
 
-// getCFConstantStringType - Return the type used for constant CFStrings.
-QualType ASTContext::getCFConstantStringType() const {
+TagDecl *ASTContext::getCFConstantStringDecl() const {
   if (!CFConstantStringTypeDecl) {
-    CFConstantStringTypeDecl = buildImplicitRecord("NSConstantString");
+    // 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();
 
     QualType FieldTypes[4];
@@ -4901,7 +4902,12 @@ QualType ASTContext::getCFConstantString
     CFConstantStringTypeDecl->completeDefinition();
   }
 
-  return getTagDeclType(CFConstantStringTypeDecl);
+  return CFConstantStringTypeDecl;
+}
+
+// getCFConstantStringType - Return the type used for constant CFStrings.
+QualType ASTContext::getCFConstantStringType() const {
+  return getTagDeclType(getCFConstantStringDecl());
 }
 
 QualType ASTContext::getObjCSuperType() const {

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Tue Feb  2 21:26:19 2016
@@ -189,6 +189,10 @@ 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);
   }
 
   // Initialize Microsoft "predefined C++ types".

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Tue Feb  2 21:26:19 2016
@@ -6444,6 +6444,9 @@ static Decl *getPredefinedDecl(ASTContex
 
   case PREDEF_DECL_MAKE_INTEGER_SEQ_ID:
     return Context.getMakeIntegerSeqDecl();
+
+  case PREDEF_DECL_CF_CONSTANT_STRING_ID:
+    return Context.getCFConstantStringDecl();
   }
   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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Feb  2 21:26:19 2016
@@ -4152,6 +4152,8 @@ uint64_t ASTWriter::WriteASTCore(Sema &S
   RegisterPredefDecl(Context.ExternCContext, PREDEF_DECL_EXTERN_C_CONTEXT_ID);
   RegisterPredefDecl(Context.MakeIntegerSeqDecl,
                      PREDEF_DECL_MAKE_INTEGER_SEQ_ID);
+  RegisterPredefDecl(Context.CFConstantStringTypeDecl,
+                     PREDEF_DECL_CF_CONSTANT_STRING_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=259624&r1=259623&r2=259624&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 Tue Feb  2 21:26:19 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 { 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
 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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m (original)
+++ cfe/trunk/test/CodeGenObjC/arc-no-arc-exceptions.m Tue Feb  2 21:26:19 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* @_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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/tentative-cfconstantstring.m (original)
+++ cfe/trunk/test/CodeGenObjC/tentative-cfconstantstring.m Tue Feb  2 21:26:19 2016
@@ -32,12 +32,12 @@ 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 { 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* @_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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/builtin.h (original)
+++ cfe/trunk/test/Modules/Inputs/builtin.h Tue Feb  2 21:26:19 2016
@@ -1,3 +1,10 @@
 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=259624&r1=259623&r2=259624&view=diff
==============================================================================
--- cfe/trunk/test/Modules/builtins.m (original)
+++ cfe/trunk/test/Modules/builtins.m Tue Feb  2 21:26:19 2016
@@ -1,3 +1,17 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %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
+// RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs %s -include-pch %t.pch %s -verify
+
+// expected-no-diagnostics
+
+void use_constant_string_builtins1(void) {
+  (void)__builtin___CFStringMakeConstantString("");
+  (void)__builtin___NSStringMakeConstantString("");
+}
+
 @import builtin;
 
 int foo() {
@@ -14,11 +28,7 @@ int baz() {
   return IS_CONST(0);
 }
 
-// RUN: rm -rf %t
-// RUN: %clang_cc1 -fmodules-cache-path=%t -fmodules -fimplicit-module-maps -I %S/Inputs %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
-// RUN: %clang_cc1 -fmodules-cache-path=%t.pch.cache -fmodules -fimplicit-module-maps -I %S/Inputs %s -include-pch %t.pch %s -verify
-
-// expected-no-diagnostics
+void use_constant_string_builtins2(void) {
+  (void)__builtin___CFStringMakeConstantString("");
+  (void)__builtin___NSStringMakeConstantString("");
+}




More information about the cfe-commits mailing list