@@ -746,6 +746,9 @@ SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx,
746746 } else if (keyString == ABIRootKey) {
747747 Result = constructSDKNode (Ctx,
748748 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 ();
749752 } else {
750753 Ctx.diagnose (Pair.getKey (), diag::sdk_node_unrecognized_key,
751754 keyString);
@@ -2215,8 +2218,81 @@ static parseJsonEmit(SDKContext &Ctx, StringRef FileName) {
22152218 }
22162219 return {std::move (FileBufOrErr.get ()), Result};
22172220}
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+ };
22182273} // End of anonymous namespace
22192274
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+
22202296// Construct all roots vector from a given file where a forest was
22212297// previously dumped.
22222298void SwiftDeclCollector::deSerialize (StringRef Filename) {
@@ -2225,20 +2301,24 @@ void SwiftDeclCollector::deSerialize(StringRef Filename) {
22252301}
22262302
22272303// 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) {
22292306 std::error_code EC;
22302307 llvm::raw_fd_ostream fs (Filename, EC, llvm::sys::fs::OF_None);
22312308 json::Output yout (fs);
22322309 assert (Root->getKind () == SDKNodeKind::Root);
22332310 SDKNodeRoot &root = *static_cast <SDKNodeRoot*>(Root);
22342311 yout.beginObject ();
22352312 yout.mapRequired (ABIRootKey, root);
2313+ if (auto *constValues = OtherInfo.allContsValues ) {
2314+ yout.mapRequired (ConstValuesKey, *constValues);
2315+ }
22362316 yout.endObject ();
22372317}
22382318
22392319// Serialize the content of all roots to a given file using JSON format.
22402320void SwiftDeclCollector::serialize (StringRef Filename) {
2241- SwiftDeclCollector::serialize (Filename, RootNode);
2321+ SwiftDeclCollector::serialize (Filename, RootNode, PayLoad () );
22422322}
22432323
22442324SDKNodeRoot *
@@ -2304,16 +2384,21 @@ swift::ide::api::getSDKNodeRoot(SDKContext &SDKCtx,
23042384 return Collector.getSDKRoot ();
23052385}
23062386
2307- void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, StringRef OutputFile) {
2387+ void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, PayLoad load,
2388+ StringRef OutputFile) {
23082389 assert (Root);
23092390 auto Opts = Root->getSDKContext ().getOpts ();
23102391 if (Opts.Verbose )
23112392 llvm::errs () << " Dumping SDK...\n " ;
2312- SwiftDeclCollector::serialize (OutputFile, Root);
2393+ SwiftDeclCollector::serialize (OutputFile, Root, load );
23132394 if (Opts.Verbose )
23142395 llvm::errs () << " Dumped to " << OutputFile << " \n " ;
23152396}
23162397
2398+ void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, StringRef OutputFile) {
2399+ dumpSDKRoot (Root, PayLoad (), OutputFile);
2400+ }
2401+
23172402int swift::ide::api::dumpSDKContent (const CompilerInvocation &InitInvok,
23182403 const llvm::StringSet<> &ModuleNames,
23192404 StringRef OutputFile, CheckerOptions Opts) {
@@ -2356,7 +2441,11 @@ void swift::ide::api::dumpModuleContent(ModuleDecl *MD, StringRef OutputFile,
23562441 SDKContext ctx (opts);
23572442 SwiftDeclCollector collector (ctx);
23582443 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);
23602449}
23612450
23622451int swift::ide::api::findDeclUsr (StringRef dumpPath, CheckerOptions Opts) {
0 commit comments