@@ -475,3 +475,78 @@ void ExpandChildTypeRefinementContextsRequest::cacheResult(
475475 TRC->Children = children;
476476 TRC->setNeedsExpansion (false );
477477}
478+
479+ // / Emit an error message, dump each context with its corresponding label, and
480+ // / abort.
481+ static void
482+ verificationError (ASTContext &ctx, llvm::StringRef msg,
483+ std::initializer_list<
484+ std::pair<const char *, const TypeRefinementContext *>>
485+ labelsAndNodes) {
486+ llvm::errs () << msg << " \n " ;
487+ for (auto pair : labelsAndNodes) {
488+ auto label = std::get<0 >(pair);
489+ auto context = std::get<1 >(pair);
490+ llvm::errs () << label << " :\n " ;
491+ context->print (llvm::errs (), ctx.SourceMgr );
492+ }
493+ abort ();
494+ }
495+
496+ void TypeRefinementContext::verify (const TypeRefinementContext *parent,
497+ ASTContext &ctx) const {
498+ // Verify the children first.
499+ for (auto child : Children) {
500+ child->verify (this , ctx);
501+ }
502+
503+ // Verify that the children are in sorted order and that their source ranges
504+ // do not overlap.
505+ auto &srcMgr = ctx.SourceMgr ;
506+ if (Children.size () > 1 ) {
507+ auto const *previous = Children.front ();
508+ for (auto const *current : ArrayRef (Children).drop_front ()) {
509+ if (!srcMgr.isAtOrBefore (previous->getSourceRange ().Start ,
510+ current->getSourceRange ().Start ))
511+ verificationError (
512+ ctx, " out of order children" ,
513+ {{" child 1" , previous}, {" child 2" , current}, {" parent" , this }});
514+
515+ if (srcMgr.containsLoc (previous->getSourceRange (),
516+ current->getSourceRange ().Start ))
517+ verificationError (
518+ ctx, " overlapping children" ,
519+ {{" child 1" , previous}, {" child 2" , current}, {" parent" , this }});
520+
521+ previous = current;
522+ }
523+ }
524+
525+ // Only root nodes are allowed to have no parent.
526+ if (!parent) {
527+ if (getReason () != Reason::Root)
528+ verificationError (ctx, " interior node without parent" , {{" node" , this }});
529+ return ;
530+ }
531+
532+ // All nodes with a parent must have a valid source range.
533+ if (!SrcRange.isValid ())
534+ verificationError (ctx, " invalid source range" , {{" node" , this }});
535+
536+ if (getReason () != Reason::Root) {
537+ auto parentRange = parent->SrcRange ;
538+ if (parentRange.isValid () &&
539+ !(srcMgr.isAtOrBefore (parentRange.Start , SrcRange.Start ) &&
540+ srcMgr.isAtOrBefore (SrcRange.End , parentRange.End )))
541+ verificationError (ctx, " child source range not contained" ,
542+ {{" child" , this }, {" parent" , this }});
543+ }
544+
545+ if (!AvailabilityInfo.isContainedIn (parent->AvailabilityInfo ))
546+ verificationError (ctx, " child availability range not contained" ,
547+ {{" child" , this }, {" parent" , this }});
548+ }
549+
550+ void TypeRefinementContext::verify (ASTContext &ctx) {
551+ verify (nullptr , ctx);
552+ }
0 commit comments