forked from OSchip/llvm-project
Implement code generation for constant CFStrings.
llvm-svn: 41206
This commit is contained in:
parent
8e5b2c27a3
commit
b04ea61b79
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 = "<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; };
|
||||
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue