@@ -2220,8 +2220,12 @@ static parseJsonEmit(SDKContext &Ctx, StringRef FileName) {
22202220 return {std::move (FileBufOrErr.get ()), Result};
22212221}
22222222enum class ConstKind : uint8_t {
2223- String = 0 ,
2224- Int,
2223+ StringLiteral = 0 ,
2224+ IntegerLiteral,
2225+ FloatLiteral,
2226+ BooleanLiteral,
2227+ Array,
2228+ Dictionary,
22252229};
22262230
22272231struct ConstExprInfo {
@@ -2230,9 +2234,11 @@ struct ConstExprInfo {
22302234 unsigned offset = 0 ;
22312235 unsigned length = 0 ;
22322236 StringRef value;
2237+ StringRef referencedD;
22332238 ConstExprInfo (StringRef filePath, ConstKind kind, unsigned offset,
2234- unsigned length, StringRef value):
2235- filePath (filePath), kind(kind), offset(offset), length(length), value(value) {}
2239+ unsigned length, StringRef value, StringRef referencedD):
2240+ filePath (filePath), kind(kind), offset(offset), length(length), value(value),
2241+ referencedD (referencedD) {}
22362242 ConstExprInfo () = default ;
22372243};
22382244
@@ -2242,7 +2248,7 @@ class ConstExtractor: public ASTWalker {
22422248 SourceManager &SM;
22432249 std::vector<ConstExprInfo> allConsts;
22442250
2245- void record (Expr *E, ConstKind kind, StringRef Value) {
2251+ void record (Expr *E, ConstKind kind, StringRef Value, StringRef ReferencedD ) {
22462252 auto startLoc = E->getStartLoc ();
22472253 // Asserts?
22482254 if (startLoc.isInvalid ())
@@ -2254,14 +2260,70 @@ class ConstExtractor: public ASTWalker {
22542260 auto length = SM.getByteDistance (startLoc, endLoc);
22552261 auto file = SM.getIdentifierForBuffer (bufferId);
22562262 auto offset = SM.getLocOffsetInBuffer (startLoc, bufferId);
2257- allConsts.emplace_back (file, kind, offset, length, Value);
2263+ allConsts.emplace_back (file, kind, offset, length, Value, ReferencedD);
2264+ }
2265+
2266+ void record (Expr *E, Expr *ValueProvider, StringRef ReferecedD = " " ) {
2267+ std::string content;
2268+ llvm::raw_string_ostream os (content);
2269+ ValueProvider->printConstExprValue (&os);
2270+ assert (!content.empty ());
2271+ auto buffered = SCtx.buffer (content);
2272+ switch (ValueProvider->getKind ()) {
2273+ #define CASE (X ) case ExprKind::X: record(E, ConstKind::X, buffered, ReferecedD); break ;
2274+ CASE (StringLiteral)
2275+ CASE (IntegerLiteral)
2276+ CASE (FloatLiteral)
2277+ CASE (BooleanLiteral)
2278+ CASE (Dictionary)
2279+ CASE (Array)
2280+ #undef CASE
2281+ default :
2282+ return ;
2283+ }
2284+ }
2285+
2286+ StringRef getDeclName (Decl *D) {
2287+ if (auto *VD = dyn_cast<ValueDecl>(D)) {
2288+ std::string content;
2289+ llvm::raw_string_ostream os (content);
2290+ VD->getName ().print (os);
2291+ return SCtx.buffer (content);
2292+ }
2293+ return StringRef ();
22582294 }
22592295
2296+ bool handleSimpleReference (Expr *E) {
2297+ assert (E);
2298+ Decl *ReferencedDecl = nullptr ;
2299+ if (auto *MRE = dyn_cast<MemberRefExpr>(E)) {
2300+ ReferencedDecl = MRE->getDecl ().getDecl ();
2301+ } else if (auto *DRE = dyn_cast<DeclRefExpr>(E)) {
2302+ ReferencedDecl = DRE->getDecl ();
2303+ } else {
2304+ return false ;
2305+ }
2306+ assert (ReferencedDecl);
2307+ if (auto *VAR = dyn_cast<VarDecl>(ReferencedDecl)) {
2308+ if (!VAR->getAttrs ().hasAttribute <CompileTimeConstAttr>()) {
2309+ return false ;
2310+ }
2311+ if (auto *PD = VAR->getParentPatternBinding ()) {
2312+ if (auto *init = PD->getInit (PD->getPatternEntryIndexForVarDecl (VAR))) {
2313+ record (E, init, getDeclName (ReferencedDecl));
2314+ return true ;
2315+ }
2316+ }
2317+ }
2318+ return false ;
2319+ }
22602320 std::pair<bool , Expr *> walkToExprPre (Expr *E) override {
22612321 if (E->isSemanticallyConstExpr ()) {
2262- if (auto *SL = dyn_cast<StringLiteralExpr>(E)) {
2263- record (SL, ConstKind::String, SL->getValue ());
2264- }
2322+ record (E, E);
2323+ return { false , E };
2324+ }
2325+ if (handleSimpleReference (E)) {
2326+ return { false , E };
22652327 }
22662328 return { true , E };
22672329 }
@@ -2279,14 +2341,20 @@ template <> struct swift::json::ObjectTraits<ConstExprInfo> {
22792341 StringRef kind;
22802342 switch (info.kind ) {
22812343#define CASE (X ) case ConstKind::X: kind = #X; break ;
2282- CASE (String)
2283- CASE (Int)
2344+ CASE (StringLiteral)
2345+ CASE (IntegerLiteral)
2346+ CASE (FloatLiteral)
2347+ CASE (BooleanLiteral)
2348+ CASE (Dictionary)
2349+ CASE (Array)
22842350#undef CASE
22852351 }
22862352 out.mapRequired (" kind" , kind);
22872353 out.mapRequired (" offset" , info.offset );
22882354 out.mapRequired (" length" , info.length );
22892355 out.mapRequired (" value" , info.value );
2356+ if (!info.referencedD .empty ())
2357+ out.mapRequired (" decl" , info.referencedD );
22902358 }
22912359};
22922360
0 commit comments