File: objcgen.h

package info (click to toggle)
ldc 1%3A1.40.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 63,308 kB
  • sloc: cpp: 85,368; ansic: 21,877; makefile: 1,705; sh: 1,018; asm: 584; objc: 135; exp: 48; python: 12
file content (209 lines) | stat: -rw-r--r-- 6,868 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
//===-- gen/objcgen.cpp -----------------------------------------*- C++ -*-===//
//
//                         LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
//
// Functions for generating Objective-C method calls.
//
//===----------------------------------------------------------------------===//

#pragma once

#include <vector>
#include <unordered_map>
#include "llvm/ADT/StringMap.h"
#include "gen/tollvm.h"
#include "dmd/mtype.h"
#include "dmd/errors.h"

struct ObjcSelector;
namespace llvm {
class Constant;
class GlobalVariable;
class Module;
class Triple;
}

// Forward decl.
class Declaration;
class ClassDeclaration;
class FuncDeclaration;
class InterfaceDeclaration;
class VarDeclaration;
class Identifier;
class Type;

// Fwd declaration.
class ObjCState;

// class is a metaclass
#define RO_META               (1<<0)

// class is a root class
#define RO_ROOT               (1<<1)

// Section Names
#define OBJC_SECNAME_CLASSNAME             "__TEXT,__objc_classname, cstring_literals"
#define OBJC_SECNAME_METHNAME              "__TEXT,__objc_methname, cstring_literals"
#define OBJC_SECNAME_METHTYPE              "__TEXT,__objc_methtype, cstring_literals"
#define OBJC_SECNAME_SELREFS               "__DATA,__objc_selrefs, literal_pointers, no_dead_strip"
#define OBJC_SECNAME_IMAGEINFO             "__DATA,__objc_imageinfo, regular, no_dead_strip"
#define OBJC_SECNAME_CLASSREFS             "__DATA,__objc_classrefs, regular, no_dead_strip"
#define OBJC_SECNAME_CLASSLIST             "__DATA,__objc_classlist, regular, no_dead_strip"
#define OBJC_SECNAME_STUBS                 "__DATA,__objc_stubs, regular, no_dead_strip"
#define OBJC_SECNAME_CATLIST               "__DATA,__objc_catlist, regular, no_dead_strip"
#define OBJC_SECNAME_PROTOLIST             "__DATA,__objc_protolist, coalesced, no_dead_strip"
#define OBJC_SECNAME_PROTOREFS             "__DATA,__objc_protorefs, regular"
#define OBJC_SECNAME_CONST                 "__DATA,__objc_const"
#define OBJC_SECNAME_DATA                  "__DATA,__objc_data"
#define OBJC_SECNAME_IVAR                  "__DATA,__objc_ivar"

// Names of Objective-C runtime structs
#define OBJC_STRUCTNAME_CLASSRO   "class_ro_t"
#define OBJC_STRUCTNAME_CLASS     "class_t"
#define OBJC_STRUCTNAME_STUBCLASS "stub_class_t"
#define OBJC_STRUCTNAME_PROTO     "protocol_t"
#define OBJC_STRUCTNAME_IVAR      "ivar_t"
#define OBJC_STRUCTNAME_METHOD    "objc_method"

#define ObjcList std::vector
#define ObjcMap std::unordered_map

// Gets whether Objective-C is supported.
bool objc_isSupported(const llvm::Triple &triple);

// Generate name strings
std::string objcGetClassRoSymbol(const char *name, bool meta);
std::string objcGetClassSymbol(const char *name, bool meta);
std::string objcGetClassLabelSymbol(const char *name);
std::string objcGetClassMethodListSymbol(const char *className, bool meta);
std::string objcGetIvarListSymbol(const char *className);
std::string objcGetIvarSymbol(const char *className, const char *varName);
std::string objcGetProtoMethodListSymbol(const char *className, bool meta, bool optional);
std::string objcGetProtoSymbol(const char *name);
std::string objcGetProtoListSymbol(const char *name);
std::string objcGetSymbolName(const char *dsymPrefix, const char *dsymName);

// Utility which fetches the appropriate Objective-C
// name for a declaration.
const char *objcResolveName(Dsymbol *decl);

// Gets the Objective-C type encoding for D type t 
std::string objcGetTypeEncoding(Type *t);

// class_t
LLStructType *objcGetClassType(const llvm::Module& module);

// class_ro_t
LLStructType *objcGetClassRoType(const llvm::Module& module);

// stub_class_t
LLStructType *objcGetStubClassType(const llvm::Module& module);

// objc_method
LLStructType *objcGetMethodType(const llvm::Module& module);

// ivar_t
LLStructType *objcGetIvarType(const llvm::Module& module);

// protocol_t
LLStructType *objcGetProtocolType(const llvm::Module& module);

// xyz_list_t (count-only)
LLConstant *objcEmitList(llvm::Module &module, LLConstantList objects, bool alignSizeT = false, bool countOnly = false);

struct ObjcClassInfo {
  ClassDeclaration *decl;
  LLGlobalVariable *ref;

  LLGlobalVariable *name;
  LLGlobalVariable *table;
};

struct ObjcProtocolInfo {
  InterfaceDeclaration *decl;
  LLGlobalVariable *ref;

  LLGlobalVariable *name;
  LLGlobalVariable *table;
};

struct ObjcMethodInfo {
  FuncDeclaration *decl;
  
  LLGlobalVariable *name;
  LLGlobalVariable *type;
  LLGlobalVariable *selector;
  LLConstant *llfunction;
};

struct ObjcIvarInfo {
  VarDeclaration *decl;

  LLGlobalVariable *name;
  LLGlobalVariable *type;
  LLGlobalVariable *offset;
};

// Objective-C state tied to an LLVM module (object file).
class ObjCState {
public:

  ObjCState(llvm::Module &module) : module(module) { }

  ObjcClassInfo *getClass(ClassDeclaration *decl);
  ObjcProtocolInfo *getProtocol(InterfaceDeclaration *decl);
  ObjcMethodInfo *getMethod(FuncDeclaration *decl);
  ObjcIvarInfo *getIvar(VarDeclaration *decl);

  LLValue *deref(ClassDeclaration *decl, LLType *as);

  void finalize();

private:
  llvm::Module &module;

  // Creates an ivar_t struct which can be
  // used in ivar lists.
  ObjcMap<VarDeclaration *, ObjcIvarInfo> ivars;
  LLConstant *createIvarInfo(VarDeclaration *decl);
  LLConstant *createIvarList(ClassDeclaration *decl);

  // Creates an objc_method struct which can be
  // used in method lists.
  ObjcMap<FuncDeclaration *, ObjcMethodInfo> methods;
  LLConstant *createMethodInfo(FuncDeclaration *decl);
  LLConstant *createMethodList(ClassDeclaration *decl, bool optional = false);

  // class_t and class_ro_t generation.
  ObjcMap<ClassDeclaration *, ObjcClassInfo> classes;
  ObjcMap<ClassDeclaration *, LLGlobalVariable *> classTables;
  ObjcMap<ClassDeclaration *, LLGlobalVariable *> classRoTables;
  LLConstant *getClassRoTable(ClassDeclaration *decl);
  LLConstant *getClassTable(ClassDeclaration *decl);

  // Class names and refs need to be replicated
  // for RO structs, as such we store
  // then seperately.
  llvm::StringMap<LLGlobalVariable *> classNames;
  llvm::StringMap<LLGlobalVariable *> classRefs;
  LLConstant *getClassName(ClassDeclaration *decl);
  LLConstant *getClassRef(ClassDeclaration *decl);

  // protocol_t generation.
  ObjcMap<InterfaceDeclaration *, ObjcProtocolInfo> protocols;
  LLConstant *createProtocolTable(InterfaceDeclaration *decl);
  LLConstant *createProtocolList(ClassDeclaration *decl);

  // Private helpers
  ObjcList<FuncDeclaration *> getMethodsForType(ClassDeclaration *decl, bool optional = false);

  ObjcList<LLConstant *> retainedSymbols;
  void retain(LLConstant *symbol);
  void genImageInfo();
  void retainSymbols();
};