From 0d13f6fdbdd6f06e2449b8834dda53334abd399a Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Sat, 23 Jan 2010 02:40:42 +0000 Subject: [PATCH] Created __builtin___NSStringMakeConstantString() builtin, which generates constant Objective-C strings. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94274 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/Builtins.def | 1 + lib/AST/ExprConstant.cpp | 4 +++- lib/CodeGen/CGBuiltin.cpp | 1 + lib/CodeGen/CGExprConstant.cpp | 14 +++++++++++--- lib/CodeGen/CGObjC.cpp | 3 ++- lib/CodeGen/CGObjCGNU.cpp | 25 +++++++++++++++---------- lib/CodeGen/CGObjCMac.cpp | 6 +++--- lib/CodeGen/CGObjCRuntime.h | 2 +- lib/CodeGen/CodeGenModule.cpp | 9 +++++++++ lib/CodeGen/CodeGenModule.h | 5 ++++- 10 files changed, 50 insertions(+), 20 deletions(-) diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 14f735655f..08945635e6 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -270,6 +270,7 @@ BUILTIN(__builtin_bswap64, "ULLiULLi", "nc") BUILTIN(__builtin_constant_p, "Us.", "nc") BUILTIN(__builtin_classify_type, "i.", "nc") BUILTIN(__builtin___CFStringMakeConstantString, "FC*cC*", "nc") +BUILTIN(__builtin___NSStringMakeConstantString, "FC*cC*", "nc") BUILTIN(__builtin_va_start, "vA.", "n") BUILTIN(__builtin_va_end, "vA", "n") BUILTIN(__builtin_va_copy, "vAA", "n") diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index c8d4e2b2b6..086249c811 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -506,7 +506,9 @@ APValue PointerExprEvaluator::VisitCastExpr(CastExpr* E) { APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) { if (E->isBuiltinCall(Info.Ctx) == - Builtin::BI__builtin___CFStringMakeConstantString) + Builtin::BI__builtin___CFStringMakeConstantString || + E->isBuiltinCall(Info.Ctx) == + Builtin::BI__builtin___NSStringMakeConstantString) return APValue(E); return APValue(); } diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 7b903c833c..f11d52e433 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -72,6 +72,7 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD, switch (BuiltinID) { default: break; // Handle intrinsics and libm functions below. case Builtin::BI__builtin___CFStringMakeConstantString: + case Builtin::BI__builtin___NSStringMakeConstantString: return RValue::get(CGM.EmitConstantExpr(E, E->getType(), 0)); case Builtin::BI__builtin_stdarg_start: case Builtin::BI__builtin_va_start: diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp index dec06e2953..7d5b3da0b6 100644 --- a/lib/CodeGen/CGExprConstant.cpp +++ b/lib/CodeGen/CGExprConstant.cpp @@ -742,7 +742,8 @@ public: return CGM.GetAddrOfConstantStringFromObjCEncode(cast(E)); case Expr::ObjCStringLiteralClass: { ObjCStringLiteral* SL = cast(E); - llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(SL); + llvm::Constant *C = + CGM.getObjCRuntime().GenerateConstantString(SL->getString()); return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); } case Expr::PredefinedExprClass: { @@ -764,11 +765,18 @@ public: } case Expr::CallExprClass: { CallExpr* CE = cast(E); - if (CE->isBuiltinCall(CGM.getContext()) != - Builtin::BI__builtin___CFStringMakeConstantString) + unsigned builtin = CE->isBuiltinCall(CGM.getContext()); + if (builtin != + Builtin::BI__builtin___CFStringMakeConstantString && + builtin != + Builtin::BI__builtin___NSStringMakeConstantString) break; const Expr *Arg = CE->getArg(0)->IgnoreParenCasts(); const StringLiteral *Literal = cast(Arg); + if (builtin == + Builtin::BI__builtin___NSStringMakeConstantString) { + return CGM.getObjCRuntime().GenerateConstantString(Literal); + } // FIXME: need to deal with UCN conversion issues. return CGM.GetAddrOfConstantCFString(Literal); } diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index ac391d99a1..896d2207ea 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -26,7 +26,8 @@ using namespace CodeGen; /// Emits an instance of NSConstantString representing the object. llvm::Value *CodeGenFunction::EmitObjCStringLiteral(const ObjCStringLiteral *E) { - llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(E); + llvm::Constant *C = + CGM.getObjCRuntime().GenerateConstantString(E->getString()); // FIXME: This bitcast should just be made an invariant on the Runtime. return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); } diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index e7a2093aa2..77be9fb582 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -124,7 +124,7 @@ private: void EmitClassRef(const std::string &className); public: CGObjCGNU(CodeGen::CodeGenModule &cgm); - virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *); + virtual llvm::Constant *GenerateConstantString(const StringLiteral *); virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, QualType ResultType, @@ -240,15 +240,23 @@ CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) Zeros[1] = Zeros[0]; NULLPtr = llvm::ConstantPointerNull::get(PtrToInt8Ty); // Get the selector Type. - SelectorTy = cast( - CGM.getTypes().ConvertType(CGM.getContext().getObjCSelType())); + QualType selTy = CGM.getContext().getObjCSelType(); + if (QualType() == selTy) { + SelectorTy = PtrToInt8Ty; + } else { + SelectorTy = cast(CGM.getTypes().ConvertType(selTy)); + } PtrToIntTy = llvm::PointerType::getUnqual(IntTy); PtrTy = PtrToInt8Ty; // Object type ASTIdTy = CGM.getContext().getObjCIdType(); - IdTy = cast(CGM.getTypes().ConvertType(ASTIdTy)); + if (QualType() == ASTIdTy) { + IdTy = PtrToInt8Ty; + } else { + IdTy = cast(CGM.getTypes().ConvertType(ASTIdTy)); + } // IMP type std::vector IMPArgs; @@ -348,12 +356,9 @@ llvm::Constant *CGObjCGNU::MakeGlobal(const llvm::ArrayType *Ty, } /// Generate an NSConstantString object. -//TODO: In case there are any crazy people still using the GNU runtime without -//an OpenStep implementation, this should let them select their own class for -//constant strings. -llvm::Constant *CGObjCGNU::GenerateConstantString(const ObjCStringLiteral *SL) { - std::string Str(SL->getString()->getStrData(), - SL->getString()->getByteLength()); +llvm::Constant *CGObjCGNU::GenerateConstantString(const StringLiteral *SL) { + std::string Str(SL->getStrData(), SL->getByteLength()); + std::vector Ivars; Ivars.push_back(NULLPtr); Ivars.push_back(MakeConstantString(Str)); diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp index 727746fbbc..137ea51721 100644 --- a/lib/CodeGen/CGObjCMac.cpp +++ b/lib/CodeGen/CGObjCMac.cpp @@ -952,7 +952,7 @@ public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm), VMContext(cgm.getLLVMContext()) { } - virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *SL); + virtual llvm::Constant *GenerateConstantString(const StringLiteral *SL); virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD=0); @@ -1454,8 +1454,8 @@ llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, const ObjCMethodDecl */ llvm::Constant *CGObjCCommonMac::GenerateConstantString( - const ObjCStringLiteral *SL) { - return CGM.GetAddrOfConstantCFString(SL->getString()); + const StringLiteral *SL) { + return CGM.GetAddrOfConstantCFString(SL); } /// Generates a message send where the super is the receiver. This is diff --git a/lib/CodeGen/CGObjCRuntime.h b/lib/CodeGen/CGObjCRuntime.h index 6b45562397..ff5d40bfbc 100644 --- a/lib/CodeGen/CGObjCRuntime.h +++ b/lib/CodeGen/CGObjCRuntime.h @@ -106,7 +106,7 @@ public: const ObjCMethodDecl *Method) = 0; /// Generate a constant string object. - virtual llvm::Constant *GenerateConstantString(const ObjCStringLiteral *) = 0; + virtual llvm::Constant *GenerateConstantString(const StringLiteral *) = 0; /// Generate a category. A category contains a list of methods (and /// accompanying metadata) and a list of protocols. diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index 5ecc30eb4e..cf504a7c2a 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -67,6 +67,15 @@ CodeGenModule::~CodeGenModule() { delete DebugInfo; } +void CodeGenModule::createObjCRuntime() { + if (!Features.NeXTRuntime) + Runtime = CreateGNUObjCRuntime(*this); + else if (Features.ObjCNonFragileABI) + Runtime = CreateMacNonFragileABIObjCRuntime(*this); + else + Runtime = CreateMacObjCRuntime(*this); +} + void CodeGenModule::Release() { EmitDeferred(); EmitCXXGlobalInitFunc(); diff --git a/lib/CodeGen/CodeGenModule.h b/lib/CodeGen/CodeGenModule.h index c7aa7a47a8..81f39791fc 100644 --- a/lib/CodeGen/CodeGenModule.h +++ b/lib/CodeGen/CodeGenModule.h @@ -161,6 +161,9 @@ class CodeGenModule : public BlockModule { /// strings. This value has type int * but is actually an Obj-C class pointer. llvm::Constant *CFConstantStringClassRef; + /// Lazily create the Objective-C runtime + void createObjCRuntime(); + llvm::LLVMContext &VMContext; public: CodeGenModule(ASTContext &C, const CodeGenOptions &CodeGenOpts, @@ -174,7 +177,7 @@ public: /// getObjCRuntime() - Return a reference to the configured /// Objective-C runtime. CGObjCRuntime &getObjCRuntime() { - assert(Runtime && "No Objective-C runtime has been configured."); + if (!Runtime) createObjCRuntime(); return *Runtime; } -- 2.40.0