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