[clang] CodeGen: Make getOrEmitProtocol public for Swift

Summary:
Swift would like to use clang's apis to emit protocol declarations.

This commits adds the public API:

```
 emitObjCProtocolObject(CodeGenModule &CGM, const ObjCProtocolDecl *p);
```

rdar://60888524

Subscribers: cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D77077
This commit is contained in:
Arnold Schwaighofer 2020-03-30 11:11:19 -07:00
parent 0489d39ead
commit 153dadf3a3
5 changed files with 43 additions and 15 deletions

View File

@ -28,11 +28,12 @@
#include "clang/CodeGen/CGFunctionInfo.h"
namespace llvm {
class DataLayout;
class Module;
class Function;
class FunctionType;
class Type;
class Constant;
class DataLayout;
class Module;
class Function;
class FunctionType;
class Type;
}
namespace clang {
@ -44,6 +45,7 @@ class CoverageSourceInfo;
class DiagnosticsEngine;
class HeaderSearchOptions;
class ObjCMethodDecl;
class ObjCProtocolDecl;
class PreprocessorOptions;
namespace CodeGen {
@ -137,6 +139,13 @@ llvm::Function *getNonTrivialCStructDestructor(CodeGenModule &CGM,
CharUnits DstAlignment,
bool IsVolatile, QualType QT);
/// Get a pointer to a protocol object for the given declaration, emitting it if
/// it hasn't already been emitted in this translation unit. Note that the ABI
/// for emitting a protocol reference in code (e.g. for a protocol expression)
/// in most runtimes is not as simple as just materializing a pointer to this
/// object.
llvm::Constant *emitObjCProtocolObject(CodeGenModule &CGM,
const ObjCProtocolDecl *p);
} // end namespace CodeGen
} // end namespace clang

View File

@ -617,6 +617,13 @@ public:
llvm::Value *GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD) override;
void GenerateProtocol(const ObjCProtocolDecl *PD) override;
virtual llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD);
llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) override {
return GenerateProtocolRef(PD);
}
llvm::Function *ModuleInitFunction() override;
llvm::FunctionCallee GetPropertyGetFunction() override;
llvm::FunctionCallee GetPropertySetFunction() override;
@ -1348,7 +1355,7 @@ class CGObjCGNUstep2 : public CGObjCGNUstep {
void GenerateProtocol(const ObjCProtocolDecl *PD) override {
// Do nothing - we only emit referenced protocols.
}
llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD) {
llvm::Constant *GenerateProtocolRef(const ObjCProtocolDecl *PD) override {
std::string ProtocolName = PD->getNameAsString();
auto *&Protocol = ExistingProtocols[ProtocolName];
if (Protocol)
@ -3039,13 +3046,18 @@ CGObjCGNU::GenerateProtocolList(ArrayRef<std::string> Protocols) {
llvm::Value *CGObjCGNU::GenerateProtocolRef(CodeGenFunction &CGF,
const ObjCProtocolDecl *PD) {
auto protocol = GenerateProtocolRef(PD);
llvm::Type *T =
CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
}
llvm::Constant *CGObjCGNU::GenerateProtocolRef(const ObjCProtocolDecl *PD) {
llvm::Constant *&protocol = ExistingProtocols[PD->getNameAsString()];
if (!protocol)
GenerateProtocol(PD);
assert(protocol && "Unknown protocol");
llvm::Type *T =
CGM.getTypes().ConvertType(CGM.getContext().getObjCProtoType());
return CGF.Builder.CreateBitCast(protocol, llvm::PointerType::getUnqual(T));
return protocol;
}
llvm::Constant *

View File

@ -1107,11 +1107,6 @@ public:
void GenerateProtocol(const ObjCProtocolDecl *PD) override;
/// GetOrEmitProtocol - Get the protocol object for the given
/// declaration, emitting it if necessary. The return value has type
/// ProtocolPtrTy.
virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
/// GetOrEmitProtocolRef - Get a forward reference to the protocol
/// object for the given declaration, emitting it if needed. These
/// forward references will be filled in with empty bodies if no

View File

@ -13,14 +13,15 @@
//===----------------------------------------------------------------------===//
#include "CGObjCRuntime.h"
#include "CGCleanup.h"
#include "CGCXXABI.h"
#include "CGCleanup.h"
#include "CGRecordLayout.h"
#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "clang/AST/RecordLayout.h"
#include "clang/AST/StmtObjC.h"
#include "clang/CodeGen/CGFunctionInfo.h"
#include "clang/CodeGen/CodeGenABITypes.h"
#include "llvm/Support/SaveAndRestore.h"
using namespace clang;
@ -383,3 +384,9 @@ CGObjCRuntime::getMessageSendInfo(const ObjCMethodDecl *method,
CGM.getTypes().GetFunctionType(argsInfo)->getPointerTo();
return MessageSendInfo(argsInfo, signatureType);
}
llvm::Constant *
clang::CodeGen::emitObjCProtocolObject(CodeGenModule &CGM,
const ObjCProtocolDecl *protocol) {
return CGM.getObjCRuntime().GetOrEmitProtocol(protocol);
}

View File

@ -211,6 +211,11 @@ public:
/// implementations.
virtual void GenerateProtocol(const ObjCProtocolDecl *OPD) = 0;
/// GetOrEmitProtocol - Get the protocol object for the given
/// declaration, emitting it if necessary. The return value has type
/// ProtocolPtrTy.
virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD) = 0;
/// Generate a function preamble for a method with the specified
/// types.