зеркало из https://github.com/microsoft/clang-1.git
Support @compatibility_alias at run time (GNUstep Runtime)
Patch by Niels Grewe! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@149401 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
2831092e80
Коммит
29254f4dd1
|
@ -18,7 +18,6 @@
|
|||
#include "CodeGenModule.h"
|
||||
#include "CodeGenFunction.h"
|
||||
#include "CGCleanup.h"
|
||||
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/Decl.h"
|
||||
#include "clang/AST/DeclObjC.h"
|
||||
|
@ -288,6 +287,10 @@ private:
|
|||
LazyRuntimeFunction IvarAssignFn, StrongCastAssignFn, MemMoveFn, WeakReadFn,
|
||||
WeakAssignFn, GlobalAssignFn;
|
||||
|
||||
typedef std::pair<std::string, std::string> ClassAliasPair;
|
||||
/// All classes that have aliases set for them.
|
||||
std::vector<ClassAliasPair> ClassAliases;
|
||||
|
||||
protected:
|
||||
/// Function used for throwing Objective-C exceptions.
|
||||
LazyRuntimeFunction ExceptionThrowFn;
|
||||
|
@ -466,6 +469,7 @@ public:
|
|||
const ObjCContainerDecl *CD);
|
||||
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
|
||||
virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
|
||||
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD);
|
||||
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
|
||||
const ObjCProtocolDecl *PD);
|
||||
virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
|
||||
|
@ -1934,6 +1938,15 @@ llvm::Constant *CGObjCGNU::GeneratePropertyList(const ObjCImplementationDecl *OI
|
|||
".objc_property_list");
|
||||
}
|
||||
|
||||
void CGObjCGNU::RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {
|
||||
// Get the class declaration for which the alias is specified.
|
||||
ObjCInterfaceDecl *ClassDecl =
|
||||
const_cast<ObjCInterfaceDecl *>(OAD->getClassInterface());
|
||||
std::string ClassName = ClassDecl->getNameAsString();
|
||||
std::string AliasName = OAD->getNameAsString();
|
||||
ClassAliases.push_back(ClassAliasPair(ClassName,AliasName));
|
||||
}
|
||||
|
||||
void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) {
|
||||
ASTContext &Context = CGM.getContext();
|
||||
|
||||
|
@ -2349,6 +2362,46 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() {
|
|||
llvm::PointerType::getUnqual(ModuleTy), true);
|
||||
llvm::Value *Register = CGM.CreateRuntimeFunction(FT, "__objc_exec_class");
|
||||
Builder.CreateCall(Register, Module);
|
||||
|
||||
if (0 != ClassAliases.size()) {
|
||||
llvm::Type *ArgTypes[2] = {PtrTy, PtrToInt8Ty};
|
||||
llvm::FunctionType *RegisterAliasTy =
|
||||
llvm::FunctionType::get(Builder.getVoidTy(),
|
||||
ArgTypes, false);
|
||||
llvm::Function *RegisterAlias = llvm::Function::Create(
|
||||
RegisterAliasTy,
|
||||
llvm::GlobalValue::ExternalWeakLinkage, "class_registerAlias_np",
|
||||
&TheModule);
|
||||
llvm::BasicBlock *AliasBB =
|
||||
llvm::BasicBlock::Create(VMContext, "alias", LoadFunction);
|
||||
llvm::BasicBlock *NoAliasBB =
|
||||
llvm::BasicBlock::Create(VMContext, "no_alias", LoadFunction);
|
||||
|
||||
// Branch based on whether the runtime provided class_registerAlias_np()
|
||||
llvm::Value *HasRegisterAlias = Builder.CreateICmpNE(RegisterAlias,
|
||||
llvm::Constant::getNullValue(RegisterAlias->getType()));
|
||||
Builder.CreateCondBr(HasRegisterAlias, AliasBB, NoAliasBB);
|
||||
|
||||
// The true branch (has alias registration fucntion):
|
||||
Builder.SetInsertPoint(AliasBB);
|
||||
// Emit alias registration calls:
|
||||
for (std::vector<ClassAliasPair>::iterator iter = ClassAliases.begin();
|
||||
iter != ClassAliases.end(); ++iter) {
|
||||
llvm::Constant *TheClass =
|
||||
TheModule.getGlobalVariable(("_OBJC_CLASS_" + iter->first).c_str(),
|
||||
true);
|
||||
if (0 != TheClass) {
|
||||
TheClass = llvm::ConstantExpr::getBitCast(TheClass, PtrTy);
|
||||
Builder.CreateCall2(RegisterAlias, TheClass,
|
||||
MakeConstantString(iter->second));
|
||||
}
|
||||
}
|
||||
// Jump to end:
|
||||
Builder.CreateBr(NoAliasBB);
|
||||
|
||||
// Missing alias registration function, just return from the function:
|
||||
Builder.SetInsertPoint(NoAliasBB);
|
||||
}
|
||||
Builder.CreateRetVoid();
|
||||
|
||||
return LoadFunction;
|
||||
|
|
|
@ -1084,6 +1084,8 @@ public:
|
|||
|
||||
virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
|
||||
|
||||
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {};
|
||||
|
||||
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
|
||||
const ObjCProtocolDecl *PD);
|
||||
|
||||
|
@ -1336,6 +1338,9 @@ public:
|
|||
virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD);
|
||||
|
||||
virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl);
|
||||
|
||||
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) {};
|
||||
|
||||
virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
|
||||
const ObjCProtocolDecl *PD);
|
||||
|
||||
|
|
|
@ -140,6 +140,9 @@ public:
|
|||
/// Generate a class structure for this class.
|
||||
virtual void GenerateClass(const ObjCImplementationDecl *OID) = 0;
|
||||
|
||||
/// Register an class alias.
|
||||
virtual void RegisterAlias(const ObjCCompatibleAliasDecl *OAD) = 0;
|
||||
|
||||
/// Generate an Objective-C message send operation.
|
||||
///
|
||||
/// \param Method - The method being called, this may be null if synthesizing
|
||||
|
|
|
@ -2421,7 +2421,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
|
|||
break;
|
||||
}
|
||||
case Decl::ObjCCompatibleAlias:
|
||||
// compatibility-alias is a directive and has no code gen.
|
||||
ObjCRuntime->RegisterAlias(cast<ObjCCompatibleAliasDecl>(D));
|
||||
break;
|
||||
|
||||
case Decl::LinkageSpec:
|
||||
|
|
Загрузка…
Ссылка в новой задаче