]> granicus.if.org Git - clang/commitdiff
Reapply r259624, it is likely not the commit causing the bot failures.
authorQuentin Colombet <qcolombet@apple.com>
Wed, 3 Feb 2016 22:41:00 +0000 (22:41 +0000)
committerQuentin Colombet <qcolombet@apple.com>
Wed, 3 Feb 2016 22:41:00 +0000 (22:41 +0000)
Original message:
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@259721 91177308-0d34-0410-b5e6-96231b3b80d8

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

index abf92948bb42ed7ae4731725755136dc7d4f8f17..1d053411ebc24502555d9f667fb70eb1171cc316 100644 (file)
@@ -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);
index c50b9b1a276f116e240952f4ca0768fe163bb8b7..6ca9f54bc883fcd8d45f76365cfcf45e622e5911 100644 (file)
@@ -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;
index 02b3e51d1de50d61b33588485310745e198f1910..fc5ff8668e9539cd43681ab3670fe2ce89f65e7c 100644 (file)
@@ -4868,10 +4868,11 @@ int ASTContext::getIntegerTypeOrder(QualType LHS, QualType RHS) const {
   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::getCFConstantStringType() const {
     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 {
index 39b8cc9f0c632c6dc5a59bbe22390183add348ff..3745cdd9a5920564dfeb48b18a53c90fbea7a775 100644 (file)
@@ -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".
index 72fbea6e9a82164da07b9679d49d3a1b5ecdc5a1..1fbff107ea5bab240f08dd7483a19c7051c1922a 100644 (file)
@@ -6444,6 +6444,9 @@ static Decl *getPredefinedDecl(ASTContext &Context, PredefinedDeclIDs ID) {
 
   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");
 }
index ec04cd6c1fa912985f052fcf576ef5c42a5d5d0b..a590e188eca9e18bf77f311c9aecefaab9212123 100644 (file)
@@ -4152,6 +4152,8 @@ uint64_t ASTWriter::WriteASTCore(Sema &SemaRef, StringRef isysroot,
   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
index 46ce3b289fc1af8510edd4c016fd9c58fa42598c..856ac9ac97bde9e7ff1d087745dc210c71f00005 100644 (file)
@@ -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";
index 82977b0a17513a5ecf2fe5c0e156a093342f449c..30424e7fb361f2512f54a2ddfe05b5672e41df7a 100644 (file)
@@ -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
index 5b3c3bd924942ff8b6067ae2b536ba01af0b76bc..0c692c37c955e780d65b9203b6aeba287754cb58 100644 (file)
@@ -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
 
index 7be90177d1948d15a82a23d53ecb92baa7306d83..d87794523420d8954eb21b08419e7c481c5addbf 100644 (file)
@@ -1,3 +1,10 @@
 int i;
 int *p = &i;
 
+#ifdef __OBJC__
+void use_constant_string_builtins(void) {
+  (void)__builtin___CFStringMakeConstantString("");
+  (void)__builtin___NSStringMakeConstantString("");
+}
+#endif
+
index 33d23979ce79e3203816ed2682d32d95be0913dd..a835039cc60ba9f55bd12e882998b0bb7869774d 100644 (file)
@@ -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("");
+}