@@ -42,15 +42,9 @@ class DiagnosticEngine;
4242struct AnyRequestVTable {
4343 template <typename Request>
4444 struct Impl {
45- static void copy (const void *input, void *output) {
46- new (output) Request (*static_cast <const Request *>(input));
47- }
4845 static hash_code getHash (const void *ptr) {
4946 return hash_value (*static_cast <const Request *>(ptr));
5047 }
51- static void deleter (void *ptr) {
52- static_cast <Request *>(ptr)->~Request ();
53- }
5448 static bool isEqual (const void *lhs, const void *rhs) {
5549 return *static_cast <const Request *>(lhs) ==
5650 *static_cast <const Request *>(rhs);
@@ -64,63 +58,24 @@ struct AnyRequestVTable {
6458 static void noteCycleStep (const void *ptr, DiagnosticEngine &diags) {
6559 static_cast <const Request *>(ptr)->noteCycleStep (diags);
6660 }
67- static SourceLoc getNearestLoc (const void *ptr) {
68- return static_cast <const Request *>(ptr)->getNearestLoc ();
69- }
70- static bool isCached (const void *ptr) {
71- return static_cast <const Request *>(ptr)->isCached ();
72- }
7361 };
7462
7563 const uint64_t typeID;
76- const size_t requestSize;
77- const std::function<void (const void *, void *)> copy;
7864 const std::function<hash_code(const void *)> getHash;
79- const std::function<void (void *)> deleter;
8065 const std::function<bool (const void *, const void *)> isEqual;
8166 const std::function<void (const void *, llvm::raw_ostream &)> simpleDisplay;
8267 const std::function<void (const void *, DiagnosticEngine &)> diagnoseCycle;
8368 const std::function<void (const void *, DiagnosticEngine &)> noteCycleStep;
84- const std::function<SourceLoc(const void *)> getNearestLoc;
85- const std::function<bool (const void *)> isCached;
86- bool isDependencySource;
8769
88- template <typename Request,
89- typename std::enable_if<Request::isEverCached>::type * = nullptr >
90- static const AnyRequestVTable *get () {
91- static const AnyRequestVTable vtable = {
92- TypeID<Request>::value,
93- sizeof (Request),
94- &Impl<Request>::copy,
95- &Impl<Request>::getHash,
96- &Impl<Request>::deleter,
97- &Impl<Request>::isEqual,
98- &Impl<Request>::simpleDisplay,
99- &Impl<Request>::diagnoseCycle,
100- &Impl<Request>::noteCycleStep,
101- &Impl<Request>::getNearestLoc,
102- &Impl<Request>::isCached,
103- Request::isDependencySource,
104- };
105- return &vtable;
106- }
107-
108- template <typename Request,
109- typename std::enable_if<!Request::isEverCached>::type * = nullptr >
70+ template <typename Request>
11071 static const AnyRequestVTable *get () {
11172 static const AnyRequestVTable vtable = {
11273 TypeID<Request>::value,
113- sizeof (Request),
114- &Impl<Request>::copy,
11574 &Impl<Request>::getHash,
116- &Impl<Request>::deleter,
11775 &Impl<Request>::isEqual,
11876 &Impl<Request>::simpleDisplay,
11977 &Impl<Request>::diagnoseCycle,
120- &Impl<Request>::noteCycleStep,
121- &Impl<Request>::getNearestLoc,
122- [](auto ){ return false ; },
123- Request::isDependencySource,
78+ &Impl<Request>::noteCycleStep
12479 };
12580 return &vtable;
12681 }
@@ -218,19 +173,6 @@ class AnyRequestBase {
218173 getVTable ()->noteCycleStep (getRawStorage (), diags);
219174 }
220175
221- // / Retrieve the nearest source location to which this request applies.
222- SourceLoc getNearestLoc () const {
223- return getVTable ()->getNearestLoc (getRawStorage ());
224- }
225-
226- bool isCached () const {
227- return getVTable ()->isCached (getRawStorage ());
228- }
229-
230- bool isDependencySource () const {
231- return getVTable ()->isDependencySource ;
232- }
233-
234176 // / Compare two instances for equality.
235177 friend bool operator ==(const AnyRequestBase<Derived> &lhs,
236178 const AnyRequestBase<Derived> &rhs) {
@@ -274,7 +216,6 @@ class AnyRequestBase {
274216// /
275217// / Requests must be value types and provide the following API:
276218// /
277- // / - Copy constructor
278219// / - Equality operator (==)
279220// / - Hashing support (hash_value)
280221// / - TypeID support (see swift/Basic/TypeID.h)
@@ -288,7 +229,6 @@ class ActiveRequest final : public AnyRequestBase<ActiveRequest> {
288229 template <typename T>
289230 friend class AnyRequestBase ;
290231
291- friend class AnyRequest ;
292232 friend llvm::DenseMapInfo<ActiveRequest>;
293233
294234 // / Pointer to the request stored on the stack.
@@ -310,117 +250,6 @@ class ActiveRequest final : public AnyRequestBase<ActiveRequest> {
310250 }
311251};
312252
313- // / Stores a request (for the \c Evaluator class) of any kind. Unlike
314- // / \c ActiveRequest, this wrapper has ownership of the underlying request.
315- // /
316- // / Requests must be value types and provide the following API to be stored in
317- // / an \c AnyRequest instance:
318- // /
319- // / - Copy constructor
320- // / - Equality operator (==)
321- // / - Hashing support (hash_value)
322- // / - TypeID support (see swift/Basic/TypeID.h)
323- // / - Display support (free function):
324- // / void simple_display(llvm::raw_ostream &, const T &);
325- // / - Cycle diagnostics operations:
326- // / void diagnoseCycle(DiagnosticEngine &diags) const;
327- // / void noteCycleStep(DiagnosticEngine &diags) const;
328- // /
329- class AnyRequest final : public AnyRequestBase<AnyRequest> {
330- template <typename T>
331- friend class AnyRequestBase ;
332-
333- friend llvm::DenseMapInfo<AnyRequest>;
334-
335- // / Pointer to the request on the heap.
336- void *storage;
337-
338- // / Creates an \c AnyRequest without storage.
339- explicit AnyRequest (StorageKind storageKind)
340- : AnyRequestBase(/* vtable*/ nullptr , storageKind) {}
341-
342- const void *getRawStorage () const { return storage; }
343-
344- // / Whether this wrapper is storing the same underlying request as an
345- // / \c ActiveRequest.
346- bool isStorageEqual (const ActiveRequest &other) const {
347- // If either wrapper isn't storing anything, just return false.
348- if (!hasStorage () || !other.hasStorage ())
349- return false ;
350-
351- if (getVTable ()->typeID != other.getVTable ()->typeID )
352- return false ;
353-
354- return getVTable ()->isEqual (getRawStorage (), other.getRawStorage ());
355- }
356-
357- public:
358- AnyRequest (const AnyRequest &other) : AnyRequestBase(other) {
359- if (hasStorage ()) {
360- // For now, just allocate a new buffer and copy across the request. This
361- // should only happen when performing operations on the (disabled by
362- // default) dependency graph.
363- storage = llvm::safe_malloc (getVTable ()->requestSize );
364- getVTable ()->copy (other.storage , storage);
365- }
366- }
367- AnyRequest &operator =(const AnyRequest &other) {
368- if (&other != this ) {
369- this ->~AnyRequest ();
370- new (this ) AnyRequest (other);
371- }
372- return *this ;
373- }
374-
375- AnyRequest (AnyRequest &&other) : AnyRequestBase(other),
376- storage (other.storage) {
377- new (&other) AnyRequest (StorageKind::Empty);
378- }
379-
380- AnyRequest &operator =(AnyRequest &&other) {
381- if (&other != this ) {
382- this ->~AnyRequest ();
383- new (this ) AnyRequest (std::move (other));
384- }
385- return *this ;
386- }
387-
388- // Create a local template typename `Request` in the template specialization
389- // so that we can refer to it in the SFINAE condition as well as the body of
390- // the template itself. The SFINAE condition allows us to remove this
391- // constructor from candidacy when evaluating explicit construction with an
392- // instance of `AnyRequest`. If we do not do so, we will find ourselves with
393- // ambiguity with this constructor and the defined move constructor above.
394- // / Construct a new instance with the given value.
395- template <typename T, typename Request = std::decay_t <T>,
396- typename = typename std::enable_if<
397- !std::is_same<Request, AnyRequest>::value>::type>
398- explicit AnyRequest (T &&request)
399- : AnyRequestBase(AnyRequestVTable::get<Request>(), StorageKind::Normal) {
400- storage = llvm::safe_malloc (sizeof (Request));
401- new (storage) Request (std::forward<T>(request));
402- }
403-
404- // / Construct an \c AnyRequest from an \c ActiveRequest, allowing the
405- // / underlying request to persist.
406- explicit AnyRequest (const ActiveRequest &req)
407- : AnyRequestBase(req.getVTable(), StorageKind::Normal) {
408- assert (req.hasStorage ());
409- storage = llvm::safe_malloc (getVTable ()->requestSize );
410- getVTable ()->copy (req.storage , storage);
411- }
412-
413- ~AnyRequest () {
414- if (hasStorage ()) {
415- getVTable ()->deleter (storage);
416- std::free (storage);
417- }
418- }
419-
420- // / Return the result of calling simple_display as a string.
421- std::string getAsString () const ;
422- };
423-
424253} // end namespace swift
425254
426255namespace llvm {
@@ -441,44 +270,6 @@ namespace llvm {
441270 }
442271 };
443272
444- template <>
445- struct DenseMapInfo <swift::AnyRequest> {
446- using AnyRequest = swift::AnyRequest;
447- using ActiveRequest = swift::ActiveRequest;
448-
449- static inline AnyRequest getEmptyKey () {
450- return AnyRequest (AnyRequest::StorageKind::Empty);
451- }
452- static inline swift::AnyRequest getTombstoneKey () {
453- return AnyRequest (AnyRequest::StorageKind::Tombstone);
454- }
455- static unsigned getHashValue (const AnyRequest &request) {
456- return hash_value (request);
457- }
458- template <typename Request>
459- static unsigned getHashValue (const Request &request) {
460- return AnyRequest::hashForHolder (swift::TypeID<Request>::value,
461- hash_value (request));
462- }
463- static unsigned getHashValue (const ActiveRequest &request) {
464- return hash_value (request);
465- }
466- static bool isEqual (const AnyRequest &lhs, const AnyRequest &rhs) {
467- return lhs == rhs;
468- }
469- template <typename Request>
470- static bool isEqual (const Request &lhs, const AnyRequest &rhs) {
471- if (!rhs.hasStorage ())
472- return false ;
473-
474- auto *rhsRequest = rhs.getAs <Request>();
475- return rhsRequest && lhs == *rhsRequest;
476- }
477- static bool isEqual (const ActiveRequest &lhs, const AnyRequest &rhs) {
478- return rhs.isStorageEqual (lhs);
479- }
480- };
481-
482273} // end namespace llvm
483274
484275#endif // SWIFT_AST_ANYREQUEST_H
0 commit comments