@@ -746,6 +746,9 @@ SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx,
746
746
} else if (keyString == ABIRootKey) {
747
747
Result = constructSDKNode (Ctx,
748
748
cast<llvm::yaml::MappingNode>(Pair.getValue ()));
749
+ } else if (keyString == ConstValuesKey) {
750
+ // We don't need to consume the const values from the compiler-side
751
+ Pair.skip ();
749
752
} else {
750
753
Ctx.diagnose (Pair.getKey (), diag::sdk_node_unrecognized_key,
751
754
keyString);
@@ -2215,8 +2218,81 @@ static parseJsonEmit(SDKContext &Ctx, StringRef FileName) {
2215
2218
}
2216
2219
return {std::move (FileBufOrErr.get ()), Result};
2217
2220
}
2221
+ enum class ConstKind : uint8_t {
2222
+ String = 0 ,
2223
+ Int,
2224
+ };
2225
+
2226
+ struct ConstExprInfo {
2227
+ StringRef filePath;
2228
+ ConstKind kind;
2229
+ unsigned offset = 0 ;
2230
+ unsigned length = 0 ;
2231
+ StringRef value;
2232
+ ConstExprInfo (StringRef filePath, ConstKind kind, unsigned offset,
2233
+ unsigned length, StringRef value):
2234
+ filePath (filePath), kind(kind), offset(offset), length(length), value(value) {}
2235
+ ConstExprInfo () = default ;
2236
+ };
2237
+
2238
+ class ConstExtractor : public ASTWalker {
2239
+ SDKContext &SCtx;
2240
+ ASTContext &Ctx;
2241
+ SourceManager &SM;
2242
+ std::vector<ConstExprInfo> allConsts;
2243
+
2244
+ void record (Expr *E, ConstKind kind, StringRef Value) {
2245
+ auto startLoc = E->getStartLoc ();
2246
+ // Asserts?
2247
+ if (startLoc.isInvalid ())
2248
+ return ;
2249
+ auto endLoc = E->getEndLoc ();
2250
+ assert (endLoc.isValid ());
2251
+ endLoc = Lexer::getLocForEndOfToken (SM, endLoc);
2252
+ auto bufferId = SM.findBufferContainingLoc (startLoc);
2253
+ auto length = SM.getByteDistance (startLoc, endLoc);
2254
+ auto file = SM.getIdentifierForBuffer (bufferId);
2255
+ auto offset = SM.getLocOffsetInBuffer (startLoc, bufferId);
2256
+ allConsts.emplace_back (file, kind, offset, length, Value);
2257
+ }
2258
+
2259
+ std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
2260
+ if (E->isSemanticallyConstExpr ()) {
2261
+ if (auto *SL = dyn_cast<StringLiteralExpr>(E)) {
2262
+ record (SL, ConstKind::String, SL->getValue ());
2263
+ }
2264
+ }
2265
+ return { true , E };
2266
+ }
2267
+ public:
2268
+ ConstExtractor (SDKContext &SCtx, ASTContext &Ctx): SCtx(SCtx), Ctx(Ctx),
2269
+ SM (Ctx.SourceMgr) {}
2270
+ void extract (ModuleDecl *MD) { MD->walk (*this ); }
2271
+ std::vector<ConstExprInfo> &getAllConstValues () { return allConsts; }
2272
+ };
2218
2273
} // End of anonymous namespace
2219
2274
2275
+ template <> struct swift ::json::ObjectTraits<ConstExprInfo> {
2276
+ static void mapping (Output &out, ConstExprInfo &info) {
2277
+ out.mapRequired (" filePath" , info.filePath );
2278
+ StringRef kind;
2279
+ switch (info.kind ) {
2280
+ #define CASE (X ) case ConstKind::X: kind = #X; break ;
2281
+ CASE (String)
2282
+ CASE (Int)
2283
+ #undef CASE
2284
+ }
2285
+ out.mapRequired (" kind" , kind);
2286
+ out.mapRequired (" offset" , info.offset );
2287
+ out.mapRequired (" length" , info.length );
2288
+ out.mapRequired (" value" , info.value );
2289
+ }
2290
+ };
2291
+
2292
+ struct swift ::ide::api::PayLoad {
2293
+ std::vector<ConstExprInfo> *allContsValues = nullptr ;
2294
+ };
2295
+
2220
2296
// Construct all roots vector from a given file where a forest was
2221
2297
// previously dumped.
2222
2298
void SwiftDeclCollector::deSerialize (StringRef Filename) {
@@ -2225,20 +2301,24 @@ void SwiftDeclCollector::deSerialize(StringRef Filename) {
2225
2301
}
2226
2302
2227
2303
// Serialize the content of all roots to a given file using JSON format.
2228
- void SwiftDeclCollector::serialize (StringRef Filename, SDKNode *Root) {
2304
+ void SwiftDeclCollector::serialize (StringRef Filename, SDKNode *Root,
2305
+ PayLoad OtherInfo) {
2229
2306
std::error_code EC;
2230
2307
llvm::raw_fd_ostream fs (Filename, EC, llvm::sys::fs::OF_None);
2231
2308
json::Output yout (fs);
2232
2309
assert (Root->getKind () == SDKNodeKind::Root);
2233
2310
SDKNodeRoot &root = *static_cast <SDKNodeRoot*>(Root);
2234
2311
yout.beginObject ();
2235
2312
yout.mapRequired (ABIRootKey, root);
2313
+ if (auto *constValues = OtherInfo.allContsValues ) {
2314
+ yout.mapRequired (ConstValuesKey, *constValues);
2315
+ }
2236
2316
yout.endObject ();
2237
2317
}
2238
2318
2239
2319
// Serialize the content of all roots to a given file using JSON format.
2240
2320
void SwiftDeclCollector::serialize (StringRef Filename) {
2241
- SwiftDeclCollector::serialize (Filename, RootNode);
2321
+ SwiftDeclCollector::serialize (Filename, RootNode, PayLoad () );
2242
2322
}
2243
2323
2244
2324
SDKNodeRoot *
@@ -2304,16 +2384,21 @@ swift::ide::api::getSDKNodeRoot(SDKContext &SDKCtx,
2304
2384
return Collector.getSDKRoot ();
2305
2385
}
2306
2386
2307
- void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, StringRef OutputFile) {
2387
+ void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, PayLoad load,
2388
+ StringRef OutputFile) {
2308
2389
assert (Root);
2309
2390
auto Opts = Root->getSDKContext ().getOpts ();
2310
2391
if (Opts.Verbose )
2311
2392
llvm::errs () << " Dumping SDK...\n " ;
2312
- SwiftDeclCollector::serialize (OutputFile, Root);
2393
+ SwiftDeclCollector::serialize (OutputFile, Root, load );
2313
2394
if (Opts.Verbose )
2314
2395
llvm::errs () << " Dumped to " << OutputFile << " \n " ;
2315
2396
}
2316
2397
2398
+ void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, StringRef OutputFile) {
2399
+ dumpSDKRoot (Root, PayLoad (), OutputFile);
2400
+ }
2401
+
2317
2402
int swift::ide::api::dumpSDKContent (const CompilerInvocation &InitInvok,
2318
2403
const llvm::StringSet<> &ModuleNames,
2319
2404
StringRef OutputFile, CheckerOptions Opts) {
@@ -2356,7 +2441,11 @@ void swift::ide::api::dumpModuleContent(ModuleDecl *MD, StringRef OutputFile,
2356
2441
SDKContext ctx (opts);
2357
2442
SwiftDeclCollector collector (ctx);
2358
2443
collector.lookupVisibleDecls ({MD});
2359
- dumpSDKRoot (collector.getSDKRoot (), OutputFile);
2444
+ ConstExtractor extractor (ctx, MD->getASTContext ());
2445
+ extractor.extract (MD);
2446
+ PayLoad payload;
2447
+ payload.allContsValues = &extractor.getAllConstValues ();
2448
+ dumpSDKRoot (collector.getSDKRoot (), payload, OutputFile);
2360
2449
}
2361
2450
2362
2451
int swift::ide::api::findDeclUsr (StringRef dumpPath, CheckerOptions Opts) {
0 commit comments