@@ -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);
@@ -2216,8 +2219,81 @@ static parseJsonEmit(SDKContext &Ctx, StringRef FileName) {
22162219 }
22172220 return {std::move (FileBufOrErr.get ()), Result};
22182221}
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+ };
22192274} // End of anonymous namespace
22202275
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+
22212297// Construct all roots vector from a given file where a forest was
22222298// previously dumped.
22232299void SwiftDeclCollector::deSerialize (StringRef Filename) {
@@ -2226,20 +2302,24 @@ void SwiftDeclCollector::deSerialize(StringRef Filename) {
22262302}
22272303
22282304// 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) {
22302307 std::error_code EC;
22312308 llvm::raw_fd_ostream fs (Filename, EC, llvm::sys::fs::OF_None);
22322309 json::Output yout (fs);
22332310 assert (Root->getKind () == SDKNodeKind::Root);
22342311 SDKNodeRoot &root = *static_cast <SDKNodeRoot*>(Root);
22352312 yout.beginObject ();
22362313 yout.mapRequired (ABIRootKey, root);
2314+ if (auto *constValues = OtherInfo.allContsValues ) {
2315+ yout.mapRequired (ConstValuesKey, *constValues);
2316+ }
22372317 yout.endObject ();
22382318}
22392319
22402320// Serialize the content of all roots to a given file using JSON format.
22412321void SwiftDeclCollector::serialize (StringRef Filename) {
2242- SwiftDeclCollector::serialize (Filename, RootNode);
2322+ SwiftDeclCollector::serialize (Filename, RootNode, PayLoad () );
22432323}
22442324
22452325SDKNodeRoot *
@@ -2305,16 +2385,21 @@ swift::ide::api::getSDKNodeRoot(SDKContext &SDKCtx,
23052385 return Collector.getSDKRoot ();
23062386}
23072387
2308- void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, StringRef OutputFile) {
2388+ void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, PayLoad load,
2389+ StringRef OutputFile) {
23092390 assert (Root);
23102391 auto Opts = Root->getSDKContext ().getOpts ();
23112392 if (Opts.Verbose )
23122393 llvm::errs () << " Dumping SDK...\n " ;
2313- SwiftDeclCollector::serialize (OutputFile, Root);
2394+ SwiftDeclCollector::serialize (OutputFile, Root, load );
23142395 if (Opts.Verbose )
23152396 llvm::errs () << " Dumped to " << OutputFile << " \n " ;
23162397}
23172398
2399+ void swift::ide::api::dumpSDKRoot (SDKNodeRoot *Root, StringRef OutputFile) {
2400+ dumpSDKRoot (Root, PayLoad (), OutputFile);
2401+ }
2402+
23182403int swift::ide::api::dumpSDKContent (const CompilerInvocation &InitInvok,
23192404 const llvm::StringSet<> &ModuleNames,
23202405 StringRef OutputFile, CheckerOptions Opts) {
@@ -2357,7 +2442,11 @@ void swift::ide::api::dumpModuleContent(ModuleDecl *MD, StringRef OutputFile,
23572442 SDKContext ctx (opts);
23582443 SwiftDeclCollector collector (ctx);
23592444 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);
23612450}
23622451
23632452int swift::ide::api::findDeclUsr (StringRef dumpPath, CheckerOptions Opts) {
0 commit comments