@@ -89,9 +89,6 @@ class SyntaxDataRef {
8989 // / and released when \c this is destroyed.
9090 const SyntaxDataRef *Parent;
9191
92- // / Creates an *uninitialized* \c SyntaxDataRef.
93- SyntaxDataRef () {}
94-
9592 // / Creates a \c SyntaxDataRef. \p AbsoluteRaw must not be null. If \p Parent
9693 // / is a \c nullptr, this node represents the root of a tree.
9794 SyntaxDataRef (const AbsoluteRawSyntax &AbsoluteRaw,
@@ -101,16 +98,22 @@ class SyntaxDataRef {
10198
10299#ifndef NDEBUG
103100 virtual bool isRef () const { return true ; }
104- virtual ~SyntaxDataRef () {}
105101#endif
106102
107103public:
104+ // / Creates an *uninitialized* \c SyntaxDataRef.
105+ SyntaxDataRef () {}
106+
108107 SyntaxDataRef (const SyntaxDataRef &DataRef) = default ;
109108 SyntaxDataRef (SyntaxDataRef &&DataRef) = default ;
110109
111110 SyntaxDataRef &operator =(SyntaxDataRef const &other) = default ;
112111 SyntaxDataRef &operator =(SyntaxDataRef &&other) = default ;
113112
113+ #ifndef NDEBUG
114+ virtual ~SyntaxDataRef () {}
115+ #endif
116+
114117 // MARK: - Retrieving underlying data
115118
116119 const AbsoluteRawSyntax &getAbsoluteRaw () const {
@@ -138,6 +141,50 @@ class SyntaxDataRef {
138141 return getAbsoluteRaw ().getPosition ().getIndexInParent ();
139142 }
140143
144+ // / If \c this node has a child at \p Cursor, write the child's \c
145+ // / SyntaxDataRef to \p DataMem and return \c true.
146+ // / If no child exists at \p Cursor, leave \p DataMem untouched and return \c
147+ // / false.
148+ template <typename CursorType>
149+ bool getChildRef (CursorType Cursor, SyntaxDataRef *DataMem) const {
150+ return getChildRef (
151+ (AbsoluteSyntaxPosition::IndexInParentType)cursorIndex (Cursor),
152+ DataMem);
153+ }
154+
155+ // / If \c this node has a child at \p Index, write the child's \c
156+ // / SyntaxDataRef to \p DataMem and return \c true. If no child exists at \p
157+ // / Index, leave \p DataMem untouched and return \c false.
158+ bool getChildRef (AbsoluteSyntaxPosition::IndexInParentType Index,
159+ SyntaxDataRef *DataMem) const {
160+ auto AbsoluteRaw = getAbsoluteRaw ().getChild (Index);
161+ if (AbsoluteRaw) {
162+ new (DataMem) SyntaxDataRef (*AbsoluteRaw,
163+ /* Parent=*/ const_cast <SyntaxDataRef *>(this ));
164+ return true ;
165+ } else {
166+ return false ;
167+ }
168+ }
169+
170+ // / Assuming that the child at \p Cursor exists, write its \c SyntaxData to \p
171+ // / DataMem.
172+ template <typename CursorType>
173+ void getPresentChildRef (CursorType Cursor, SyntaxDataRef *DataMem) const {
174+ return getPresentChildRef (
175+ (AbsoluteSyntaxPosition::IndexInParentType)cursorIndex (Cursor),
176+ DataMem);
177+ }
178+
179+ // / Assuming that the child at \p Index exists, write its \c SyntaxData to \p
180+ // / DataMem.
181+ void getPresentChildRef (AbsoluteSyntaxPosition::IndexInParentType Index,
182+ SyntaxDataRef *DataMem) const {
183+ auto AbsoluteRaw = getAbsoluteRaw ().getPresentChild (Index);
184+ new (DataMem) SyntaxDataRef (AbsoluteRaw,
185+ /* Parent=*/ const_cast <SyntaxDataRef *>(this ));
186+ }
187+
141188 // MARK: - Retrieving source locations
142189
143190 // / Get the offset at which the leading trivia of this node starts.
0 commit comments