]> granicus.if.org Git - clang/commitdiff
Implement code generation for constant CFStrings.
authorAnders Carlsson <andersca@mac.com>
Tue, 21 Aug 2007 00:21:21 +0000 (00:21 +0000)
committerAnders Carlsson <andersca@mac.com>
Tue, 21 Aug 2007 00:21:21 +0000 (00:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41206 91177308-0d34-0410-b5e6-96231b3b80d8

CodeGen/CGBuiltin.cpp
CodeGen/CodeGenModule.cpp
CodeGen/CodeGenModule.h
CodeGen/CodeGenTypes.cpp
CodeGen/CodeGenTypes.h
clang.xcodeproj/project.pbxproj

index 0095bdef48bd3e4f0639d86c9ac4d77882a8af0a..769fa5ce3bb365238e3e6c05d8124fc8dcd91a95 100644 (file)
@@ -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<const ParenExpr>(Arg))
+        Arg = PE->getSubExpr();
+      
+      const StringLiteral *Literal = cast<const StringLiteral>(Arg);
+      std::string S(Literal->getStrData(), Literal->getByteLength());
+      
+      return RValue::get(CGM.GetAddrOfConstantCFString(S));
+    }      
     default:
       assert(0 && "Unknown builtin id");
   }
index 44cb91dd1de5aa4a367dad27a50656f94ef1f120..74c7d43e1d2f3dfaa425c31ffbe2313a2e828bbc 100644 (file)
@@ -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<llvm::Constant *> &Entry = 
+    CFConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
+  
+  if (Entry.getValue())
+    return Entry.getValue();
+  
+  std::vector<llvm::Constant*> 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<llvm::StructType>(Ty), Fields);
+  C = new llvm::GlobalVariable(C->getType(), true, 
+                               llvm::GlobalVariable::InternalLinkage, 
+                               C, "", &getModule());
+  
+  Entry.setValue(C);
+  return C;
+}
index fbebdcfcf573a8723591c5fb584ddc55fa4cc2d1..97d6a02f47f51ec243acab566644ab0634a7d6ed 100644 (file)
@@ -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<const Decl*, llvm::Constant*> GlobalDeclMap;
+  
+  llvm::StringMap<llvm::Constant*> 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);
index 6a2bb1e273907f866e3c20c6c9d113918c82b6bc..3888538864c24f16943be028cfa5af692eaffdc4 100644 (file)
@@ -136,8 +136,11 @@ const llvm::Type *CodeGenTypes::ConvertType(QualType T) {
   case Type::Tagged:
     const TagType &TT = cast<TagType>(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 {
index 1e3416c98ce567bc2698c7c2c3b4d7ab44237cf1..1f6cbd87010db173627e99f33424e7587f212670 100644 (file)
@@ -14,6 +14,7 @@
 #ifndef CODEGEN_CODEGENTYPES_H
 #define CODEGEN_CODEGENTYPES_H
 
+#include "llvm/ADT/DenseMap.h"
 #include <vector>
 
 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<const TagDecl*, llvm::Type*> TagDeclTypes;
 public:
   CodeGenTypes(ASTContext &Ctx, llvm::Module &M);
   
index b7047ee1b1ce1fb24a292762b3dc61cb64de59d6..a372e33827875ef7d0d9d1850ec37fea75b08324 100644 (file)
@@ -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 */; };
                1A30A9E80B93A4C800201A91 /* ExprCXX.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ExprCXX.h; path = clang/AST/ExprCXX.h; sourceTree = "<group>"; };
                1A869A6E0BA2164C008DA07A /* LiteralSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LiteralSupport.h; sourceTree = "<group>"; };
                1A869AA70BA21ABA008DA07A /* LiteralSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = LiteralSupport.cpp; sourceTree = "<group>"; };
+               1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CGBuiltin.cpp; path = CodeGen/CGBuiltin.cpp; sourceTree = "<group>"; };
                84D9A8870C1A57E100AC7ABC /* AttributeList.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = AttributeList.cpp; path = Parse/AttributeList.cpp; sourceTree = "<group>"; };
                84D9A88B0C1A581300AC7ABC /* AttributeList.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = AttributeList.h; path = clang/Parse/AttributeList.h; sourceTree = "<group>"; };
                8DD76F6C0486A84900D96B5E /* clang */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = clang; sourceTree = BUILT_PRODUCTS_DIR; };
                                DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */,
                                DEEBC3BB0C2363BC00A9FE82 /* CodeGenTypes.cpp */,
                                DEEBC3B90C2363B800A9FE82 /* CodeGenTypes.h */,
+                               1ABC36930C7A4BDC006DB0AB /* CGBuiltin.cpp */,
                                DE4264FB0C113592005A861D /* CGDecl.cpp */,
                                DEF2EFF20C6CDD74000C4259 /* CGAggExpr.cpp */,
                                DE4772FB0C10EAEC002239E8 /* CGExpr.cpp */,
                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 */,
                        );
                                DEF2EDA70C6A4252000C4259 /* StmtDumper.cpp in Sources */,
                                DEF2EFF30C6CDD74000C4259 /* CGAggExpr.cpp in Sources */,
                                DEF2F0100C6CFED5000C4259 /* SemaChecking.cpp in Sources */,
+                               1ABC36940C7A4BDC006DB0AB /* CGBuiltin.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };