Skip to content

Commit e0a97ed

Browse files
authored
Merge pull request #12421 from xedin/metadata-reader-fn-flags
[RemoteAST/Reflection] Changes to MetadataReader and its users to track function parameter flags
2 parents 5992e08 + c9d70dc commit e0a97ed

File tree

9 files changed

+268
-132
lines changed

9 files changed

+268
-132
lines changed

include/swift/AST/Types.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1430,6 +1430,11 @@ class ParameterTypeFlags {
14301430
bool isInOut() const { return value.contains(InOut); }
14311431
bool isShared() const { return value.contains(Shared); }
14321432

1433+
ParameterTypeFlags withVariadic(bool variadic) const {
1434+
return ParameterTypeFlags(variadic ? value | ParameterTypeFlags::Variadic
1435+
: value - ParameterTypeFlags::Variadic);
1436+
}
1437+
14331438
ParameterTypeFlags withEscaping(bool escaping) const {
14341439
return ParameterTypeFlags(escaping ? value | ParameterTypeFlags::Escaping
14351440
: value - ParameterTypeFlags::Escaping);

include/swift/Reflection/TypeRef.h

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "llvm/ADT/DenseMap.h"
2222
#include "llvm/Support/Casting.h"
2323
#include "swift/ABI/MetadataValues.h"
24+
#include "swift/Remote/MetadataReader.h"
2425
#include "swift/Runtime/Unreachable.h"
2526

2627
#include <iostream>
@@ -331,39 +332,39 @@ class TupleTypeRef final : public TypeRef {
331332
};
332333

333334
class FunctionTypeRef final : public TypeRef {
334-
std::vector<const TypeRef *> Arguments;
335+
using Param = remote::FunctionParam<const TypeRef *>;
336+
337+
std::vector<Param> Parameters;
335338
const TypeRef *Result;
336339
FunctionTypeFlags Flags;
337340

338-
static TypeRefID Profile(const std::vector<const TypeRef *> &Arguments,
339-
const TypeRef *Result,
340-
FunctionTypeFlags Flags) {
341+
static TypeRefID Profile(const std::vector<Param> &Parameters,
342+
const TypeRef *Result, FunctionTypeFlags Flags) {
341343
TypeRefID ID;
342-
for (auto Argument : Arguments) {
343-
ID.addPointer(Argument);
344+
for (const auto &Param : Parameters) {
345+
ID.addString(Param.getLabel().str());
346+
ID.addPointer(Param.getType());
347+
ID.addInteger(static_cast<uint32_t>(Param.getFlags().toRaw()));
344348
}
345349
ID.addPointer(Result);
346350
ID.addInteger(static_cast<uint64_t>(Flags.getIntValue()));
347351
return ID;
348352
}
349353

350354
public:
351-
FunctionTypeRef(std::vector<const TypeRef *> Arguments, const TypeRef *Result,
355+
FunctionTypeRef(std::vector<Param> Params, const TypeRef *Result,
352356
FunctionTypeFlags Flags)
353-
: TypeRef(TypeRefKind::Function), Arguments(Arguments), Result(Result),
354-
Flags(Flags) {}
357+
: TypeRef(TypeRefKind::Function), Parameters(Params), Result(Result),
358+
Flags(Flags) {}
355359

356360
template <typename Allocator>
357-
static const FunctionTypeRef *create(Allocator &A,
358-
std::vector<const TypeRef *> Arguments,
361+
static const FunctionTypeRef *create(Allocator &A, std::vector<Param> Params,
359362
const TypeRef *Result,
360363
FunctionTypeFlags Flags) {
361-
FIND_OR_CREATE_TYPEREF(A, FunctionTypeRef, Arguments, Result, Flags);
364+
FIND_OR_CREATE_TYPEREF(A, FunctionTypeRef, Params, Result, Flags);
362365
}
363366

364-
const std::vector<const TypeRef *> &getArguments() const {
365-
return Arguments;
366-
};
367+
const std::vector<Param> &getParameters() const { return Parameters; };
367368

368369
const TypeRef *getResult() const {
369370
return Result;

include/swift/Reflection/TypeRefBuilder.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,10 @@ class TypeRefBuilder {
209209
return TupleTypeRef::create(*this, elements, isVariadic);
210210
}
211211

212-
const FunctionTypeRef *
213-
createFunctionType(const std::vector<const TypeRef *> &args,
214-
const std::vector<bool> &inOutArgs,
215-
const TypeRef *result,
216-
FunctionTypeFlags flags) {
217-
// FIXME: don't ignore inOutArgs
218-
// and add test to unittests/Reflection/TypeRef.cpp
219-
return FunctionTypeRef::create(*this, args, result, flags);
212+
const FunctionTypeRef *createFunctionType(
213+
const std::vector<remote::FunctionParam<const TypeRef *>> &params,
214+
const TypeRef *result, FunctionTypeFlags flags) {
215+
return FunctionTypeRef::create(*this, params, result, flags);
220216
}
221217

222218
const ProtocolTypeRef *createProtocolType(const std::string &mangledName,

include/swift/Remote/MetadataReader.h

Lines changed: 121 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#ifndef SWIFT_REMOTE_METADATAREADER_H
1818
#define SWIFT_REMOTE_METADATAREADER_H
1919

20+
#include "swift/AST/Types.h"
2021
#include "swift/Runtime/Metadata.h"
2122
#include "swift/Remote/MemoryReader.h"
2223
#include "swift/Demangling/Demangler.h"
@@ -29,6 +30,43 @@
2930
namespace swift {
3031
namespace remote {
3132

33+
template <typename BuiltType> class FunctionParam {
34+
StringRef Label;
35+
BuiltType Type;
36+
ParameterTypeFlags Flags;
37+
38+
FunctionParam(StringRef label, BuiltType type, ParameterTypeFlags flags)
39+
: Label(label), Type(type), Flags(flags) {}
40+
41+
public:
42+
explicit FunctionParam() {}
43+
44+
FunctionParam(BuiltType type) : Type(type) {}
45+
46+
StringRef getLabel() const { return Label; }
47+
BuiltType getType() const { return Type; }
48+
ParameterTypeFlags getFlags() const { return Flags; }
49+
50+
void setLabel(StringRef label) { Label = label; }
51+
void setType(BuiltType type) { Type = type; }
52+
53+
void setVariadic() { Flags = Flags.withVariadic(true); }
54+
void setShared() { Flags = Flags.withShared(true); }
55+
void setInOut() { Flags = Flags.withInOut(true); }
56+
57+
FunctionParam withLabel(StringRef label) const {
58+
return FunctionParam(label, Type, Flags);
59+
}
60+
61+
FunctionParam withType(BuiltType type) const {
62+
return FunctionParam(Label, type, Flags);
63+
}
64+
65+
FunctionParam withFlags(ParameterTypeFlags flags) const {
66+
return FunctionParam(Label, Type, flags);
67+
}
68+
};
69+
3270
/// A utility class for constructing abstract types from
3371
/// a textual mangling.
3472
template <typename BuilderType>
@@ -219,16 +257,14 @@ class TypeDecoder {
219257
Node->getChild(0)->getKind() == NodeKind::ThrowsAnnotation;
220258
flags = flags.withThrows(true);
221259

222-
std::vector<BuiltType> arguments;
223-
std::vector<bool> argsAreInOut;
260+
std::vector<FunctionParam<BuiltType>> parameters;
224261
if (!decodeMangledFunctionInputType(Node->getChild(isThrow ? 1 : 0),
225-
arguments, argsAreInOut, flags))
262+
parameters))
226263
return BuiltType();
227264

228265
auto result = decodeMangledType(Node->getChild(isThrow ? 2 : 1));
229266
if (!result) return BuiltType();
230-
return Builder.createFunctionType(arguments, argsAreInOut,
231-
result, flags);
267+
return Builder.createFunctionType(parameters, result, flags);
232268
}
233269
case NodeKind::ImplFunctionType: {
234270
// Minimal support for lowered function types. These come up in
@@ -263,15 +299,13 @@ class TypeDecoder {
263299
}
264300

265301
// Completely punt on argument types and results.
266-
std::vector<BuiltType> arguments;
267-
std::vector<bool> argsAreInOut;
302+
std::vector<FunctionParam<BuiltType>> parameters;
268303

269304
std::vector<BuiltType> elements;
270305
std::string labels;
271306
auto result = Builder.createTupleType(elements, std::move(labels), false);
272307

273-
return Builder.createFunctionType(arguments, argsAreInOut,
274-
result, flags);
308+
return Builder.createFunctionType(parameters, result, flags);
275309
}
276310
case NodeKind::ArgumentTuple:
277311
return decodeMangledType(Node->getChild(0));
@@ -397,55 +431,92 @@ class TypeDecoder {
397431
return true;
398432
}
399433

400-
bool decodeMangledFunctionInputType(const Demangle::NodePointer &node,
401-
std::vector<BuiltType> &args,
402-
std::vector<bool> &argsAreInOut,
403-
FunctionTypeFlags &flags) {
434+
bool decodeMangledFunctionInputType(
435+
const Demangle::NodePointer &node,
436+
std::vector<FunctionParam<BuiltType>> &params) {
404437
// Look through a couple of sugar nodes.
405438
if (node->getKind() == NodeKind::Type ||
406439
node->getKind() == NodeKind::ArgumentTuple) {
407-
return decodeMangledFunctionInputType(node->getFirstChild(),
408-
args, argsAreInOut, flags);
440+
return decodeMangledFunctionInputType(node->getFirstChild(), params);
409441
}
410442

411-
auto decodeSingleHelper =
412-
[&](const Demangle::NodePointer &typeNode, bool argIsInOut) -> bool {
413-
BuiltType argType = decodeMangledType(typeNode);
414-
if (!argType) return false;
443+
auto decodeParamTypeAndFlags =
444+
[&](const Demangle::NodePointer &typeNode,
445+
FunctionParam<BuiltType> &param) -> bool {
446+
Demangle::NodePointer node = typeNode;
447+
switch (node->getKind()) {
448+
case NodeKind::InOut:
449+
param.setInOut();
450+
node = node->getFirstChild();
451+
break;
452+
453+
case NodeKind::Shared:
454+
param.setShared();
455+
node = node->getFirstChild();
456+
break;
457+
458+
default:
459+
break;
460+
}
461+
462+
auto paramType = decodeMangledType(node);
463+
if (!paramType)
464+
return false;
415465

416-
args.push_back(argType);
417-
argsAreInOut.push_back(argIsInOut);
466+
param.setType(paramType);
418467
return true;
419468
};
420-
auto decodeSingle =
421-
[&](const Demangle::NodePointer &typeNode) -> bool {
422-
if (typeNode->getKind() == NodeKind::InOut) {
423-
return decodeSingleHelper(typeNode->getFirstChild(), true);
424-
} else {
425-
return decodeSingleHelper(typeNode, false);
469+
470+
auto decodeParam = [&](const Demangle::NodePointer &paramNode)
471+
-> Optional<FunctionParam<BuiltType>> {
472+
if (paramNode->getKind() != NodeKind::TupleElement)
473+
return None;
474+
475+
FunctionParam<BuiltType> param;
476+
for (const auto &child : *paramNode) {
477+
switch (child->getKind()) {
478+
case NodeKind::TupleElementName:
479+
param.setLabel(child->getText());
480+
break;
481+
482+
case NodeKind::VariadicMarker:
483+
param.setVariadic();
484+
break;
485+
486+
case NodeKind::Type:
487+
if (!decodeParamTypeAndFlags(child->getFirstChild(), param))
488+
return None;
489+
break;
490+
491+
default:
492+
return None;
493+
}
426494
}
495+
496+
return param;
427497
};
428498

429499
// Expand a single level of tuple.
430500
if (node->getKind() == NodeKind::Tuple) {
431-
// TODO: preserve variadic somewhere?
432-
433501
// Decode all the elements as separate arguments.
434502
for (const auto &elt : *node) {
435-
if (elt->getKind() != NodeKind::TupleElement)
436-
return false;
437-
auto typeNode = elt->getChild(elt->getNumChildren() - 1);
438-
if (typeNode->getKind() != NodeKind::Type)
439-
return false;
440-
if (!decodeSingle(typeNode->getFirstChild()))
503+
auto param = decodeParam(elt);
504+
if (!param)
441505
return false;
506+
507+
params.push_back(std::move(*param));
442508
}
443509

444510
return true;
445511
}
446512

447513
// Otherwise, handle the type as a single argument.
448-
return decodeSingle(node);
514+
FunctionParam<BuiltType> param;
515+
if (!decodeParamTypeAndFlags(node, param))
516+
return false;
517+
518+
params.push_back(std::move(param));
519+
return true;
449520
}
450521
};
451522

@@ -734,8 +805,7 @@ class MetadataReader {
734805
case MetadataKind::Function: {
735806
auto Function = cast<TargetFunctionTypeMetadata<Runtime>>(Meta);
736807

737-
std::vector<BuiltType> Arguments;
738-
std::vector<bool> ArgumentIsInOut;
808+
std::vector<FunctionParam<BuiltType>> Parameters;
739809
StoredPointer ArgumentAddress = MetadataAddress +
740810
sizeof(TargetFunctionTypeMetadata<Runtime>);
741811
for (StoredPointer i = 0; i < Function->getNumArguments(); ++i,
@@ -745,15 +815,21 @@ class MetadataReader {
745815
&FlaggedArgumentAddress))
746816
return BuiltType();
747817

818+
FunctionParam<BuiltType> Param;
819+
748820
// TODO: Use target-agnostic FlaggedPointer to mask this!
749821
const auto InOutMask = (StoredPointer) 1;
750-
ArgumentIsInOut.push_back((FlaggedArgumentAddress & InOutMask) != 0);
751-
FlaggedArgumentAddress &= ~InOutMask;
822+
// FIXME: Add import parameter related flags from metadata
823+
if ((FlaggedArgumentAddress & InOutMask) != 0)
824+
Param.setInOut();
752825

753-
if (auto ArgumentTypeRef = readTypeFromMetadata(FlaggedArgumentAddress))
754-
Arguments.push_back(ArgumentTypeRef);
755-
else
826+
FlaggedArgumentAddress &= ~InOutMask;
827+
if (auto ParamTypeRef = readTypeFromMetadata(FlaggedArgumentAddress)) {
828+
Param.setType(ParamTypeRef);
829+
Parameters.push_back(std::move(Param));
830+
} else {
756831
return BuiltType();
832+
}
757833
}
758834

759835
auto Result = readTypeFromMetadata(Function->ResultType);
@@ -762,9 +838,8 @@ class MetadataReader {
762838

763839
auto flags = FunctionTypeFlags().withConvention(Function->getConvention())
764840
.withThrows(Function->throws());
765-
auto BuiltFunction = Builder.createFunctionType(Arguments,
766-
ArgumentIsInOut,
767-
Result, flags);
841+
auto BuiltFunction =
842+
Builder.createFunctionType(Parameters, Result, flags);
768843
TypeCache[MetadataAddress] = BuiltFunction;
769844
return BuiltFunction;
770845
}

0 commit comments

Comments
 (0)