From: Anders Carlsson Date: Tue, 21 Aug 2007 00:21:21 +0000 (+0000) Subject: Implement code generation for constant CFStrings. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c9e2091efcb535110474434dd12015afdc3b1637;p=clang Implement code generation for constant CFStrings. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41206 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/CodeGen/CGBuiltin.cpp b/CodeGen/CGBuiltin.cpp index 0095bdef48..769fa5ce3b 100644 --- a/CodeGen/CGBuiltin.cpp +++ b/CodeGen/CGBuiltin.cpp @@ -15,6 +15,7 @@ #include "CodeGenModule.h" #include "clang/AST/Builtins.h" #include "clang/AST/Expr.h" +#include "llvm/Constant.h" using namespace clang; using namespace CodeGen; @@ -22,6 +23,17 @@ using namespace CodeGen; RValue CodeGenFunction::EmitBuiltinExpr(unsigned builtinID, const CallExpr *E) { switch (builtinID) { + case Builtin::BI__builtin___CFStringMakeConstantString: { + const Expr *Arg = E->getArg(0); + + while (const ParenExpr *PE = dyn_cast(Arg)) + Arg = PE->getSubExpr(); + + const StringLiteral *Literal = cast(Arg); + std::string S(Literal->getStrData(), Literal->getByteLength()); + + return RValue::get(CGM.GetAddrOfConstantCFString(S)); + } default: assert(0 && "Unknown builtin id"); } diff --git a/CodeGen/CodeGenModule.cpp b/CodeGen/CodeGenModule.cpp index 44cb91dd1d..74c7d43e1d 100644 --- a/CodeGen/CodeGenModule.cpp +++ b/CodeGen/CodeGenModule.cpp @@ -26,7 +26,7 @@ using namespace CodeGen; CodeGenModule::CodeGenModule(ASTContext &C, llvm::Module &M) - : Context(C), TheModule(M), Types(C, M) {} + : Context(C), TheModule(M), Types(C, M), CFConstantStringClassRef(0) {} llvm::Constant *CodeGenModule::GetAddrOfGlobalDecl(const Decl *D) { // See if it is already in the map. @@ -113,3 +113,59 @@ llvm::Function *CodeGenModule::getMemCpyFn() { } return MemCpyFn = llvm::Intrinsic::getDeclaration(&TheModule, IID); } + +llvm::Constant *CodeGenModule::GetAddrOfConstantCFString(const std::string &str) +{ + llvm::StringMapEntry &Entry = + CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]); + + if (Entry.getValue()) + return Entry.getValue(); + + std::vector Fields; + + if (!CFConstantStringClassRef) { + const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); + Ty = llvm::ArrayType::get(Ty, 0); + + CFConstantStringClassRef = + new llvm::GlobalVariable(Ty, false, + llvm::GlobalVariable::ExternalLinkage, 0, + "__CFConstantStringClassReference", + &getModule()); + } + + // Class pointer. + llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty); + llvm::Constant *Zeros[] = { Zero, Zero }; + llvm::Constant *C = + llvm::ConstantExpr::getGetElementPtr(CFConstantStringClassRef, Zeros, 2); + Fields.push_back(C); + + // Flags. + const llvm::Type *Ty = getTypes().ConvertType(getContext().IntTy); + Fields.push_back(llvm::ConstantInt::get(Ty, 1992)); + + // String pointer. + C = llvm::ConstantArray::get(str); + C = new llvm::GlobalVariable(C->getType(), true, + llvm::GlobalValue::InternalLinkage, + C, ".str", &getModule()); + + C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2); + Fields.push_back(C); + + // String length. + Ty = getTypes().ConvertType(getContext().LongTy); + Fields.push_back(llvm::ConstantInt::get(Ty, str.length())); + + // The struct. + Ty = getTypes().ConvertType(getContext().getCFConstantStringType()); + C = llvm::ConstantStruct::get(cast(Ty), Fields); + C = new llvm::GlobalVariable(C->getType(), true, + llvm::GlobalVariable::InternalLinkage, + C, "", &getModule()); + + Entry.setValue(C); + return C; +} diff --git a/CodeGen/CodeGenModule.h b/CodeGen/CodeGenModule.h index fbebdcfcf5..97d6a02f47 100644 --- a/CodeGen/CodeGenModule.h +++ b/CodeGen/CodeGenModule.h @@ -16,6 +16,7 @@ #include "CodeGenTypes.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" namespace llvm { class Module; @@ -40,6 +41,9 @@ class CodeGenModule { llvm::Function *MemCpyFn; llvm::DenseMap GlobalDeclMap; + + llvm::StringMap CFConstantStringMap; + llvm::Constant *CFConstantStringClassRef; public: CodeGenModule(ASTContext &C, llvm::Module &M); @@ -48,7 +52,7 @@ public: CodeGenTypes &getTypes() { return Types; } llvm::Constant *GetAddrOfGlobalDecl(const Decl *D); - + llvm::Constant *GetAddrOfConstantCFString(const std::string& str); llvm::Function *getMemCpyFn(); void EmitFunction(const FunctionDecl *FD); diff --git a/CodeGen/CodeGenTypes.cpp b/CodeGen/CodeGenTypes.cpp index 6a2bb1e273..3888538864 100644 --- a/CodeGen/CodeGenTypes.cpp +++ b/CodeGen/CodeGenTypes.cpp @@ -136,8 +136,11 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) { case Type::Tagged: const TagType &TT = cast(Ty); const TagDecl *TD = TT.getDecl(); - llvm::Type *ResultType; + llvm::Type *&ResultType = TagDeclTypes[TD]; + if (ResultType) + return ResultType; + if (!TD->isDefinition()) { ResultType = llvm::OpaqueType::get(); } else { diff --git a/CodeGen/CodeGenTypes.h b/CodeGen/CodeGenTypes.h index 1e3416c98c..1f6cbd8701 100644 --- a/CodeGen/CodeGenTypes.h +++ b/CodeGen/CodeGenTypes.h @@ -14,6 +14,7 @@ #ifndef CODEGEN_CODEGENTYPES_H #define CODEGEN_CODEGENTYPES_H +#include "llvm/ADT/DenseMap.h" #include namespace llvm { @@ -23,6 +24,7 @@ namespace llvm { namespace clang { class ASTContext; + class TagDecl; class TargetInfo; class QualType; class FunctionTypeProto; @@ -35,6 +37,8 @@ class CodeGenTypes { ASTContext &Context; TargetInfo &Target; llvm::Module& TheModule; + + llvm::DenseMap TagDeclTypes; public: CodeGenTypes(ASTContext &Ctx, llvm::Module &M); diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index b7047ee1b1..a372e33827 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 1A30A9E90B93A4C800201A91 /* ExprCXX.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A30A9E80B93A4C800201A91 /* ExprCXX.h */; }; 1A869A700BA2164C008DA07A /* LiteralSupport.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */; }; 1A869AA80BA21ABA008DA07A /* LiteralSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */; }; + 1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */; }; 84D9A8880C1A57E100AC7ABC /* AttributeList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */; }; 84D9A88C0C1A581300AC7ABC /* AttributeList.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 84D9A88B0C1A581300AC7ABC /* AttributeList.h */; }; DE01DA490B12ADA300AC22CE /* PPCallbacks.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DE01DA480B12ADA300AC22CE /* PPCallbacks.h */; }; @@ -197,6 +198,7 @@ 1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = ""; }; 1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = ""; }; 1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = ""; }; + 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = CodeGen/CGBuiltin.cpp; sourceTree = ""; }; 84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = ""; }; 84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = ""; }; 8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -430,6 +432,7 @@ DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */, DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */, DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */, + 1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */, DE4264FB0C113592005A861D /* CGDecl.cpp */, DEF2EFF20C6CDD74000C4259 /* CGAggExpr.cpp */, DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */, @@ -613,9 +616,11 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = ""; + projectRoot = ""; targets = ( 8DD76F620486A84900D96B5E /* clang */, ); @@ -687,6 +692,7 @@ DEF2EDA70C6A4252000C4259 /* StmtDumper.cpp in Sources */, DEF2EFF30C6CDD74000C4259 /* CGAggExpr.cpp in Sources */, DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */, + 1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; };