From 45c4ea75b235de94f44bf96843624e6a559e4c00 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 9 Aug 2011 15:54:21 +0000 Subject: [PATCH] Move the construction of the RecordDecl representing the runtime layout of a constant NSString from the ASTContext over to CodeGen, since this is solely CodeGen's responsibility. Eliminates one of the unnecessary "special" types that we serialize. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137121 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ASTContext.h | 15 ------- include/clang/Serialization/ASTBitCodes.h | 4 +- lib/AST/ASTContext.cpp | 44 +------------------ lib/CodeGen/CodeGenModule.cpp | 52 ++++++++++++++++++++--- lib/CodeGen/CodeGenModule.h | 8 ++++ lib/Serialization/ASTReader.cpp | 2 - lib/Serialization/ASTWriter.cpp | 1 - 7 files changed, 56 insertions(+), 70 deletions(-) diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 0c6bc954a7..025bb41242 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -198,8 +198,6 @@ class ASTContext : public llvm::RefCountedBase { QualType ObjCConstantStringType; mutable RecordDecl *CFConstantStringTypeDecl; - mutable RecordDecl *NSConstantStringTypeDecl; - mutable RecordDecl *ObjCFastEnumerationStateTypeDecl; /// \brief The type for the C FILE type. @@ -823,19 +821,6 @@ public: // constant CFStrings. QualType getCFConstantStringType() const; - // getNSConstantStringType - Return the C structure type used to represent - // constant NSStrings. - QualType getNSConstantStringType() const; - /// Get the structure type used to representation NSStrings, or NULL - /// if it hasn't yet been built. - QualType getRawNSConstantStringType() const { - if (NSConstantStringTypeDecl) - return getTagDeclType(NSConstantStringTypeDecl); - return QualType(); - } - void setNSConstantStringType(QualType T); - - /// Get the structure type used to representation CFStrings, or NULL /// if it hasn't yet been built. QualType getRawCFConstantStringType() const { diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index d9b845c88b..aa1d9b99bf 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -668,10 +668,8 @@ namespace clang { SPECIAL_TYPE_BLOCK_EXTENDED_DESCRIPTOR = 13, /// \brief Objective-C "SEL" redefinition type SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 14, - /// \brief NSConstantString type - SPECIAL_TYPE_NS_CONSTANT_STRING = 15, /// \brief Whether __[u]int128_t identifier is installed. - SPECIAL_TYPE_INT128_INSTALLED = 16 + SPECIAL_TYPE_INT128_INSTALLED = 15 }; /// \brief Predefined declaration IDs. diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 92695f2398..3f8cf37a68 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -222,7 +222,7 @@ ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, DependentTemplateSpecializationTypes(this_()), SubstTemplateTemplateParmPacks(this_()), GlobalNestedNameSpecifier(0), IsInt128Installed(false), - CFConstantStringTypeDecl(0), NSConstantStringTypeDecl(0), + CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0), FILEDecl(0), jmp_bufDecl(0), sigjmp_bufDecl(0), BlockDescriptorType(0), BlockDescriptorExtendedType(0), cudaConfigureCallDecl(0), @@ -3639,48 +3639,6 @@ void ASTContext::setCFConstantStringType(QualType T) { CFConstantStringTypeDecl = Rec->getDecl(); } -// getNSConstantStringType - Return the type used for constant NSStrings. -QualType ASTContext::getNSConstantStringType() const { - if (!NSConstantStringTypeDecl) { - NSConstantStringTypeDecl = - CreateRecordDecl(*this, TTK_Struct, TUDecl, - &Idents.get("__builtin_NSString")); - NSConstantStringTypeDecl->startDefinition(); - - QualType FieldTypes[3]; - - // const int *isa; - FieldTypes[0] = getPointerType(IntTy.withConst()); - // const char *str; - FieldTypes[1] = getPointerType(CharTy.withConst()); - // unsigned int length; - FieldTypes[2] = UnsignedIntTy; - - // Create fields - for (unsigned i = 0; i < 3; ++i) { - FieldDecl *Field = FieldDecl::Create(*this, NSConstantStringTypeDecl, - SourceLocation(), - SourceLocation(), 0, - FieldTypes[i], /*TInfo=*/0, - /*BitWidth=*/0, - /*Mutable=*/false, - /*HasInit=*/false); - Field->setAccess(AS_public); - NSConstantStringTypeDecl->addDecl(Field); - } - - NSConstantStringTypeDecl->completeDefinition(); - } - - return getTagDeclType(NSConstantStringTypeDecl); -} - -void ASTContext::setNSConstantStringType(QualType T) { - const RecordType *Rec = T->getAs(); - assert(Rec && "Invalid NSConstantStringType"); - NSConstantStringTypeDecl = Rec->getDecl(); -} - QualType ASTContext::getObjCFastEnumerationStateType() const { if (!ObjCFastEnumerationStateTypeDecl) { ObjCFastEnumerationStateTypeDecl = diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 5341f22ab9..13c8f6080f 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -66,6 +66,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const CodeGenOptions &CGO, TBAA(0), VTables(*this), ObjCRuntime(0), DebugInfo(0), ARCData(0), RRData(0), CFConstantStringClassRef(0), ConstantStringClassRef(0), + NSConstantStringType(0), VMContext(M.getContext()), NSConcreteGlobalBlockDecl(0), NSConcreteStackBlockDecl(0), NSConcreteGlobalBlock(0), NSConcreteStackBlock(0), @@ -1800,6 +1801,16 @@ CodeGenModule::GetAddrOfConstantCFString(const StringLiteral *Literal) { return GV; } +static RecordDecl * +CreateRecordDecl(const ASTContext &Ctx, RecordDecl::TagKind TK, + DeclContext *DC, IdentifierInfo *Id) { + SourceLocation Loc; + if (Ctx.getLangOptions().CPlusPlus) + return CXXRecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); + else + return RecordDecl::Create(Ctx, TK, DC, Loc, Loc, Id); +} + llvm::Constant * CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { unsigned StringLength = 0; @@ -1838,11 +1849,40 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { llvm::ConstantExpr::getGetElementPtr(GV, Zeros); } } - - QualType NSTy = getContext().getNSConstantStringType(); - - llvm::StructType *STy = - cast(getTypes().ConvertType(NSTy)); + + if (!NSConstantStringType) { + // Construct the type for a constant NSString. + RecordDecl *D = CreateRecordDecl(Context, TTK_Struct, + Context.getTranslationUnitDecl(), + &Context.Idents.get("__builtin_NSString")); + D->startDefinition(); + + QualType FieldTypes[3]; + + // const int *isa; + FieldTypes[0] = Context.getPointerType(Context.IntTy.withConst()); + // const char *str; + FieldTypes[1] = Context.getPointerType(Context.CharTy.withConst()); + // unsigned int length; + FieldTypes[2] = Context.UnsignedIntTy; + + // Create fields + for (unsigned i = 0; i < 3; ++i) { + FieldDecl *Field = FieldDecl::Create(Context, D, + SourceLocation(), + SourceLocation(), 0, + FieldTypes[i], /*TInfo=*/0, + /*BitWidth=*/0, + /*Mutable=*/false, + /*HasInit=*/false); + Field->setAccess(AS_public); + D->addDecl(Field); + } + + D->completeDefinition(); + QualType NSTy = Context.getTagDeclType(D); + NSConstantStringType = cast(getTypes().ConvertType(NSTy)); + } std::vector Fields(3); @@ -1870,7 +1910,7 @@ CodeGenModule::GetAddrOfConstantString(const StringLiteral *Literal) { Fields[2] = llvm::ConstantInt::get(Ty, StringLength); // The struct. - C = llvm::ConstantStruct::get(STy, Fields); + C = llvm::ConstantStruct::get(NSConstantStringType, Fields); GV = new llvm::GlobalVariable(getModule(), C->getType(), true, llvm::GlobalVariable::PrivateLinkage, C, "_unnamed_nsstring_"); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index ca72230559..56ff68cc8d 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -286,6 +286,9 @@ class CodeGenModule : public CodeGenTypeCache { /// run on termination. std::vector > CXXGlobalDtors; + /// @name Cache for Objective-C runtime types + /// @{ + /// CFConstantStringClassRef - Cached reference to the class for constant /// strings. This value has type int * but is actually an Obj-C class pointer. llvm::Constant *CFConstantStringClassRef; @@ -294,6 +297,11 @@ class CodeGenModule : public CodeGenTypeCache { /// strings. This value has type int * but is actually an Obj-C class pointer. llvm::Constant *ConstantStringClassRef; + /// \brief The LLVM type corresponding to NSConstantString. + llvm::StructType *NSConstantStringType; + + /// @} + /// Lazily create the Objective-C runtime void createObjCRuntime(); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 9659f46f17..d5cb6a6ced 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3041,8 +3041,6 @@ void ASTReader::InitializeContext(ASTContext &Ctx) { if (unsigned ObjCSelRedef = SpecialTypes[SPECIAL_TYPE_OBJC_SEL_REDEFINITION]) Context->ObjCSelRedefinitionType = GetType(ObjCSelRedef); - if (unsigned String = SpecialTypes[SPECIAL_TYPE_NS_CONSTANT_STRING]) - Context->setNSConstantStringType(GetType(String)); if (SpecialTypes[SPECIAL_TYPE_INT128_INSTALLED]) Context->setInt128Installed(); diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 256bf9da3e..6cdd6cad60 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2943,7 +2943,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef, MemorizeStatCalls *StatCalls, AddTypeRef(Context.getRawBlockdescriptorType(), SpecialTypes); AddTypeRef(Context.getRawBlockdescriptorExtendedType(), SpecialTypes); AddTypeRef(Context.ObjCSelRedefinitionType, SpecialTypes); - AddTypeRef(Context.getRawNSConstantStringType(), SpecialTypes); SpecialTypes.push_back(Context.isInt128Installed()); // Keep writing types and declarations until all types and -- 2.40.0