mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Merge pull request #41367 from nkcsgexi/set-up-payload-for-const
ABIChecker: teach ABI descriptor JSON to also keep track of constant values known at compile-time
This commit is contained in:
@@ -746,6 +746,9 @@ SDKNode* SDKNode::constructSDKNode(SDKContext &Ctx,
|
||||
} else if (keyString == ABIRootKey) {
|
||||
Result = constructSDKNode(Ctx,
|
||||
cast<llvm::yaml::MappingNode>(Pair.getValue()));
|
||||
} else if (keyString == ConstValuesKey) {
|
||||
// We don't need to consume the const values from the compiler-side
|
||||
Pair.skip();
|
||||
} else {
|
||||
Ctx.diagnose(Pair.getKey(), diag::sdk_node_unrecognized_key,
|
||||
keyString);
|
||||
@@ -2216,8 +2219,81 @@ static parseJsonEmit(SDKContext &Ctx, StringRef FileName) {
|
||||
}
|
||||
return {std::move(FileBufOrErr.get()), Result};
|
||||
}
|
||||
enum class ConstKind: uint8_t {
|
||||
String = 0,
|
||||
Int,
|
||||
};
|
||||
|
||||
struct ConstExprInfo {
|
||||
StringRef filePath;
|
||||
ConstKind kind;
|
||||
unsigned offset = 0;
|
||||
unsigned length = 0;
|
||||
StringRef value;
|
||||
ConstExprInfo(StringRef filePath, ConstKind kind, unsigned offset,
|
||||
unsigned length, StringRef value):
|
||||
filePath(filePath), kind(kind), offset(offset), length(length), value(value) {}
|
||||
ConstExprInfo() = default;
|
||||
};
|
||||
|
||||
class ConstExtractor: public ASTWalker {
|
||||
SDKContext &SCtx;
|
||||
ASTContext &Ctx;
|
||||
SourceManager &SM;
|
||||
std::vector<ConstExprInfo> allConsts;
|
||||
|
||||
void record(Expr *E, ConstKind kind, StringRef Value) {
|
||||
auto startLoc = E->getStartLoc();
|
||||
// Asserts?
|
||||
if (startLoc.isInvalid())
|
||||
return;
|
||||
auto endLoc = E->getEndLoc();
|
||||
assert(endLoc.isValid());
|
||||
endLoc = Lexer::getLocForEndOfToken(SM, endLoc);
|
||||
auto bufferId = SM.findBufferContainingLoc(startLoc);
|
||||
auto length = SM.getByteDistance(startLoc, endLoc);
|
||||
auto file = SM.getIdentifierForBuffer(bufferId);
|
||||
auto offset = SM.getLocOffsetInBuffer(startLoc, bufferId);
|
||||
allConsts.emplace_back(file, kind, offset, length, Value);
|
||||
}
|
||||
|
||||
std::pair<bool, Expr *> walkToExprPre(Expr *E) override {
|
||||
if (E->isSemanticallyConstExpr()) {
|
||||
if (auto *SL = dyn_cast<StringLiteralExpr>(E)) {
|
||||
record(SL, ConstKind::String, SL->getValue());
|
||||
}
|
||||
}
|
||||
return { true, E };
|
||||
}
|
||||
public:
|
||||
ConstExtractor(SDKContext &SCtx, ASTContext &Ctx): SCtx(SCtx), Ctx(Ctx),
|
||||
SM(Ctx.SourceMgr) {}
|
||||
void extract(ModuleDecl *MD) { MD->walk(*this); }
|
||||
std::vector<ConstExprInfo> &getAllConstValues() { return allConsts; }
|
||||
};
|
||||
} // End of anonymous namespace
|
||||
|
||||
template <> struct swift::json::ObjectTraits<ConstExprInfo> {
|
||||
static void mapping(Output &out, ConstExprInfo &info) {
|
||||
out.mapRequired("filePath", info.filePath);
|
||||
StringRef kind;
|
||||
switch(info.kind) {
|
||||
#define CASE(X) case ConstKind::X: kind = #X; break;
|
||||
CASE(String)
|
||||
CASE(Int)
|
||||
#undef CASE
|
||||
}
|
||||
out.mapRequired("kind", kind);
|
||||
out.mapRequired("offset", info.offset);
|
||||
out.mapRequired("length", info.length);
|
||||
out.mapRequired("value", info.value);
|
||||
}
|
||||
};
|
||||
|
||||
struct swift::ide::api::PayLoad {
|
||||
std::vector<ConstExprInfo> *allContsValues = nullptr;
|
||||
};
|
||||
|
||||
// Construct all roots vector from a given file where a forest was
|
||||
// previously dumped.
|
||||
void SwiftDeclCollector::deSerialize(StringRef Filename) {
|
||||
@@ -2226,7 +2302,8 @@ void SwiftDeclCollector::deSerialize(StringRef Filename) {
|
||||
}
|
||||
|
||||
// Serialize the content of all roots to a given file using JSON format.
|
||||
void SwiftDeclCollector::serialize(StringRef Filename, SDKNode *Root) {
|
||||
void SwiftDeclCollector::serialize(StringRef Filename, SDKNode *Root,
|
||||
PayLoad OtherInfo) {
|
||||
std::error_code EC;
|
||||
llvm::raw_fd_ostream fs(Filename, EC, llvm::sys::fs::OF_None);
|
||||
json::Output yout(fs);
|
||||
@@ -2234,12 +2311,15 @@ void SwiftDeclCollector::serialize(StringRef Filename, SDKNode *Root) {
|
||||
SDKNodeRoot &root = *static_cast<SDKNodeRoot*>(Root);
|
||||
yout.beginObject();
|
||||
yout.mapRequired(ABIRootKey, root);
|
||||
if (auto *constValues = OtherInfo.allContsValues) {
|
||||
yout.mapRequired(ConstValuesKey, *constValues);
|
||||
}
|
||||
yout.endObject();
|
||||
}
|
||||
|
||||
// Serialize the content of all roots to a given file using JSON format.
|
||||
void SwiftDeclCollector::serialize(StringRef Filename) {
|
||||
SwiftDeclCollector::serialize(Filename, RootNode);
|
||||
SwiftDeclCollector::serialize(Filename, RootNode, PayLoad());
|
||||
}
|
||||
|
||||
SDKNodeRoot *
|
||||
@@ -2305,16 +2385,21 @@ swift::ide::api::getSDKNodeRoot(SDKContext &SDKCtx,
|
||||
return Collector.getSDKRoot();
|
||||
}
|
||||
|
||||
void swift::ide::api::dumpSDKRoot(SDKNodeRoot *Root, StringRef OutputFile) {
|
||||
void swift::ide::api::dumpSDKRoot(SDKNodeRoot *Root, PayLoad load,
|
||||
StringRef OutputFile) {
|
||||
assert(Root);
|
||||
auto Opts = Root->getSDKContext().getOpts();
|
||||
if (Opts.Verbose)
|
||||
llvm::errs() << "Dumping SDK...\n";
|
||||
SwiftDeclCollector::serialize(OutputFile, Root);
|
||||
SwiftDeclCollector::serialize(OutputFile, Root, load);
|
||||
if (Opts.Verbose)
|
||||
llvm::errs() << "Dumped to "<< OutputFile << "\n";
|
||||
}
|
||||
|
||||
void swift::ide::api::dumpSDKRoot(SDKNodeRoot *Root, StringRef OutputFile) {
|
||||
dumpSDKRoot(Root, PayLoad(), OutputFile);
|
||||
}
|
||||
|
||||
int swift::ide::api::dumpSDKContent(const CompilerInvocation &InitInvok,
|
||||
const llvm::StringSet<> &ModuleNames,
|
||||
StringRef OutputFile, CheckerOptions Opts) {
|
||||
@@ -2357,7 +2442,11 @@ void swift::ide::api::dumpModuleContent(ModuleDecl *MD, StringRef OutputFile,
|
||||
SDKContext ctx(opts);
|
||||
SwiftDeclCollector collector(ctx);
|
||||
collector.lookupVisibleDecls({MD});
|
||||
dumpSDKRoot(collector.getSDKRoot(), OutputFile);
|
||||
ConstExtractor extractor(ctx, MD->getASTContext());
|
||||
extractor.extract(MD);
|
||||
PayLoad payload;
|
||||
payload.allContsValues = &extractor.getAllConstValues();
|
||||
dumpSDKRoot(collector.getSDKRoot(), payload, OutputFile);
|
||||
}
|
||||
|
||||
int swift::ide::api::findDeclUsr(StringRef dumpPath, CheckerOptions Opts) {
|
||||
|
||||
Reference in New Issue
Block a user