Skip to content

Commit ca16fba

Browse files
[swift-api-extract] BumpPtrAllocate API structs
Fix a bug that pointers to ObjCInterfaces can be invalid when std vector expended. Now allocate all the interfaces in BumpPtrAllocator so the pointers to APIs are always valid as long as API class is alive. rdar://76155450
1 parent 3028548 commit ca16fba

File tree

2 files changed

+30
-25
lines changed

2 files changed

+30
-25
lines changed

lib/TBDGen/APIGen.cpp

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -27,24 +27,27 @@ namespace apigen {
2727
void API::addSymbol(llvm::StringRef symbol, APILoc loc, APILinkage linkage,
2828
APIFlags flags, APIAccess access,
2929
APIAvailability availability) {
30-
globals.emplace_back(symbol, loc, linkage, flags, access, GVKind::Function,
31-
availability);
30+
auto *global = new (allocator) GlobalRecord(
31+
symbol, loc, linkage, flags, access, GVKind::Function, availability);
32+
globals.push_back(global);
3233
}
3334

3435
ObjCInterfaceRecord *API::addObjCClass(llvm::StringRef name, APILinkage linkage,
3536
APILoc loc, APIAccess access,
3637
APIAvailability availability,
3738
llvm::StringRef superClassName) {
38-
interfaces.emplace_back(name, linkage, loc, access, availability,
39-
superClassName);
40-
return &interfaces.back();
39+
auto *interface = new (allocator) ObjCInterfaceRecord(
40+
name, linkage, loc, access, availability, superClassName);
41+
interfaces.push_back(interface);
42+
return interface;
4143
}
4244

4345
void API::addObjCMethod(ObjCInterfaceRecord *cls, llvm::StringRef name,
4446
APILoc loc, APIAccess access, bool isInstanceMethod,
4547
bool isOptional, APIAvailability availability) {
46-
cls->methods.emplace_back(name, loc, access, isInstanceMethod, isOptional,
47-
availability);
48+
auto method = new (allocator) ObjCMethodRecord(
49+
name, loc, access, isInstanceMethod, isOptional, availability);
50+
cls->methods.push_back(method);
4851
}
4952

5053
static void serialize(llvm::json::OStream &OS, APIAccess access) {
@@ -120,6 +123,10 @@ static void serialize(llvm::json::OStream &OS, const ObjCMethodRecord &record) {
120123
});
121124
}
122125

126+
static bool sortAPIRecords(const APIRecord *base, const APIRecord *compare) {
127+
return base->name < compare->name;
128+
}
129+
123130
static void serialize(llvm::json::OStream &OS,
124131
const ObjCInterfaceRecord &record) {
125132
OS.object([&]() {
@@ -131,39 +138,34 @@ static void serialize(llvm::json::OStream &OS,
131138
OS.attribute("super", record.superClassName);
132139
OS.attributeArray("instanceMethods", [&]() {
133140
for (auto &method : record.methods) {
134-
if (method.isInstanceMethod)
135-
serialize(OS, method);
141+
if (method->isInstanceMethod)
142+
serialize(OS, *method);
136143
}
137144
});
138145
OS.attributeArray("classMethods", [&]() {
139146
for (auto &method : record.methods) {
140-
if (!method.isInstanceMethod)
141-
serialize(OS, method);
147+
if (!method->isInstanceMethod)
148+
serialize(OS, *method);
142149
}
143150
});
144151
});
145152
}
146153

147-
static bool sortAPIRecords(const APIRecord &base, const APIRecord &compare) {
148-
return base.name < compare.name;
149-
}
150-
151154
void API::writeAPIJSONFile(llvm::raw_ostream &os, bool PrettyPrint) {
152155
unsigned indentSize = PrettyPrint ? 2 : 0;
153156
llvm::json::OStream JSON(os, indentSize);
154157

155-
// FIXME: only write PublicSDKContentRoot now.
156158
JSON.object([&]() {
157159
JSON.attribute("target", target.str());
158160
JSON.attributeArray("globals", [&]() {
159161
llvm::sort(globals, sortAPIRecords);
160-
for (const auto &g : globals)
161-
serialize(JSON, g);
162+
for (const auto *g : globals)
163+
serialize(JSON, *g);
162164
});
163165
JSON.attributeArray("interfaces", [&]() {
164166
llvm::sort(interfaces, sortAPIRecords);
165-
for (const auto &i : interfaces)
166-
serialize(JSON, i);
167+
for (const auto *i : interfaces)
168+
serialize(JSON, *i);
167169
});
168170
JSON.attribute("version", "1.0");
169171
});

lib/TBDGen/APIGen.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "llvm/ADT/StringRef.h"
1919
#include "llvm/ADT/StringSet.h"
2020
#include "llvm/ADT/Triple.h"
21+
#include "llvm/Support/Allocator.h"
2122
#include "llvm/Support/Error.h"
2223

2324
namespace llvm {
@@ -86,7 +87,7 @@ struct APIRecord {
8687

8788
APIRecord(llvm::StringRef name, APILoc loc, APILinkage linkage,
8889
APIFlags flags, APIAccess access, APIAvailability availability)
89-
: name(name.str()), loc(loc), linkage(linkage), flags(flags),
90+
: name(name.data(), name.size()), loc(loc), linkage(linkage), flags(flags),
9091
access(access), availability(availability) {}
9192

9293
bool isWeakDefined() const {
@@ -135,7 +136,7 @@ struct ObjCMethodRecord : APIRecord {
135136
};
136137

137138
struct ObjCContainerRecord : APIRecord {
138-
std::vector<ObjCMethodRecord> methods;
139+
std::vector<ObjCMethodRecord*> methods;
139140

140141
ObjCContainerRecord(llvm::StringRef name, APILinkage linkage, APILoc loc,
141142
APIAccess access, const APIAvailability &availability)
@@ -148,12 +149,13 @@ struct ObjCInterfaceRecord : ObjCContainerRecord {
148149
APIAccess access, APIAvailability availability,
149150
llvm::StringRef superClassName)
150151
: ObjCContainerRecord(name, linkage, loc, access, availability),
151-
superClassName(superClassName.str()) {}
152+
superClassName(superClassName.data(), superClassName.size()) {}
152153
};
153154

154155
class API {
155156
public:
156157
API(const llvm::Triple &triple) : target(triple) {}
158+
157159
const llvm::Triple &getTarget() const { return target; }
158160

159161
void addSymbol(llvm::StringRef symbol, APILoc loc, APILinkage linkage,
@@ -174,8 +176,9 @@ class API {
174176
private:
175177
const llvm::Triple target;
176178

177-
std::vector<GlobalRecord> globals;
178-
std::vector<ObjCInterfaceRecord> interfaces;
179+
llvm::BumpPtrAllocator allocator;
180+
std::vector<GlobalRecord*> globals;
181+
std::vector<ObjCInterfaceRecord*> interfaces;
179182
};
180183

181184
} // end namespace apigen

0 commit comments

Comments
 (0)