@@ -39,16 +39,15 @@ using namespace ast_scope;
3939
4040static SourceLoc getLocAfterExtendedNominal (const ExtensionDecl *);
4141
42- // / Retrieve the character-based source range for the given source range.
43- static SourceRange getCharSourceRange (
44- SourceManager &sourceMgr, SourceRange range
45- ){
46- range.End = Lexer::getLocForEndOfToken (sourceMgr, range.End );
47- return range;
48- }
49-
5042void ASTScopeImpl::checkSourceRangeBeforeAddingChild (ASTScopeImpl *child,
5143 const ASTContext &ctx) const {
44+ // Ignore attributes on extensions, currently they exist outside of the
45+ // extension's source range due to the way we've setup the scope for
46+ // extension binding.
47+ // FIXME: We ought to fix the source range for extension scopes.
48+ if (isa<ExtensionScope>(this ) && child->isDeclAttribute ())
49+ return ;
50+
5251 // Ignore debugger bindings - they're a special mix of user code and implicit
5352 // wrapper code that is too difficult to check for consistency.
5453 if (auto d = getDeclIfAny ().getPtrOrNull ())
@@ -60,14 +59,14 @@ void ASTScopeImpl::checkSourceRangeBeforeAddingChild(ASTScopeImpl *child,
6059
6160 auto range = getCharSourceRangeOfScope (sourceMgr);
6261
63- std::function<bool (SourceRange)> containedInParent;
64- containedInParent = [&](SourceRange childCharRange) {
62+ auto containedInParent = [&](SourceRange childCharRange) {
6563 // HACK: For code completion. Handle replaced range.
64+ // Note that the replaced SourceRanges here are already disguised
65+ // CharSourceRanges, we don't need to adjust them. We use `rangeContains`
66+ // since we're only interested in comparing within a single buffer.
6667 for (const auto &pair : sourceMgr.getReplacedRanges ()) {
67- auto originalRange = getCharSourceRange (sourceMgr, pair.first );
68- auto newRange = getCharSourceRange (sourceMgr, pair.second );
69- if (sourceMgr.encloses (range, originalRange) &&
70- sourceMgr.encloses (newRange, childCharRange))
68+ if (sourceMgr.rangeContains (range, pair.first ) &&
69+ sourceMgr.rangeContains (pair.second , childCharRange))
7170 return true ;
7271 }
7372
@@ -77,11 +76,12 @@ void ASTScopeImpl::checkSourceRangeBeforeAddingChild(ASTScopeImpl *child,
7776 auto childCharRange = child->getCharSourceRangeOfScope (sourceMgr);
7877
7978 if (!containedInParent (childCharRange)) {
80- auto &out = verificationError () << " child not contained in its parent:\n " ;
81- child->print (out);
82- out << " \n ***Parent node***\n " ;
83- this ->print (out);
84- abort ();
79+ abortWithVerificationError ([&](llvm::raw_ostream &out) {
80+ out << " child not contained in its parent:\n " ;
81+ child->print (out);
82+ out << " \n ***Parent node***\n " ;
83+ this ->print (out);
84+ });
8585 }
8686
8787 if (!storedChildren.empty ()) {
@@ -90,13 +90,14 @@ void ASTScopeImpl::checkSourceRangeBeforeAddingChild(ASTScopeImpl *child,
9090 sourceMgr).End ;
9191
9292 if (!sourceMgr.isAtOrBefore (endOfPreviousChild, childCharRange.Start )) {
93- auto &out = verificationError () << " child overlaps previous child:\n " ;
94- child->print (out);
95- out << " \n ***Previous child\n " ;
96- previousChild->print (out);
97- out << " \n ***Parent node***\n " ;
98- this ->print (out);
99- abort ();
93+ abortWithVerificationError ([&](llvm::raw_ostream &out) {
94+ out << " child overlaps previous child:\n " ;
95+ child->print (out);
96+ out << " \n ***Previous child\n " ;
97+ previousChild->print (out);
98+ out << " \n ***Parent node***\n " ;
99+ this ->print (out);
100+ });
100101 }
101102 }
102103}
0 commit comments