r259734 - Fix predefine for __NSConstantString struct type

Douglas Gregor via cfe-commits cfe-commits at lists.llvm.org
Wed Feb 3 20:18:34 PST 2016


> On Feb 3, 2016, at 4:55 PM, Ben Langmuir via cfe-commits <cfe-commits at lists.llvm.org> wrote:
> 
> 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.

Looks great, thanks Ben!

	- Doug

> 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);
> 
> 
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list