[PATCH] D80508: [AST] Fix the source range for TagDecl if there is no matched } brace.
Haojian Wu via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Thu May 28 08:42:35 PDT 2020
hokein marked an inline comment as done.
hokein added inline comments.
================
Comment at: clang/lib/AST/Decl.cpp:4129
SourceRange TagDecl::getSourceRange() const {
- SourceLocation RBraceLoc = BraceRange.getEnd();
- SourceLocation E = RBraceLoc.isValid() ? RBraceLoc : getLocation();
+ SourceLocation E = BraceRange.getBegin().isValid() ?
+ BraceRange.getEnd() : getLocation();
----------------
sammccall wrote:
> I'm confused about this change.
>
> We were using BR.end if it was valid, now we're using it if BR.start is valid. So this changes behavior in two cases:
> - BR.start is valid, BR.end is invalid: old was {getOuterLocStart(), getLocation()}. new is {getOuterLocStart(), invalid}
> - BR.end is valid, BR.start is invalid: old was {getOuterLocStart(), BraceRange.getEnd()}. new is {getOuterLocStart(), getLocation()}
>
> These both seem worse to me, what am I missing?
>
> Patch description refers to the first case, I wonder if this is just a bug in clangd cancelling out a bad AST (does it just mark tokens until EOF if the end location is invalid?)
> We were using BR.end if it was valid, now we're using it if BR.start is valid. So this changes behavior in two cases:
> BR.start is valid, BR.end is invalid: old was {getOuterLocStart(), getLocation()}. new is {getOuterLocStart(), invalid}
> BR.end is valid, BR.start is invalid: old was {getOuterLocStart(), BraceRange.getEnd()}. new is {getOuterLocStart(), getLocation()}
case 1), I think this is intended, though it looks like worse at first glance :( Invalid source location has subtle semantic in clang -- "BR.end() is invalid" implies that there is no `}` in the source code.
And `Missing-}` namespaceDecl in today's clang is using invalid loc (not the NameLoc) as the end loc:
```
// `-NamespaceDecl 0x8d27728 </tmp/t.cpp:2:1, <invalid sloc>> col:11 abc
namespace abc {
// missing }
```
case 2) is less interesting, I wonder whether we will encounter this case in practice, tried and failed to come up with an example to it happen. I think we can preserve the old behavior in this patch.
> I wonder if this is just a bug in clangd cancelling out a bad AST (does it just mark tokens until EOF if the end location is invalid?)
I assume "clangd" you mean "clang"? I think clang's behavior is fine, the AST is recovered well, it is an issue that the TagDecl::getSourceRange doesn't correctly claim the range of TagDecl.
e.g.
```
class Test {
int field;
// missing }
// `-CXXRecordDecl 0x96dd738 </tmp/t.cpp:1:1, col:7> col:7 class Test definition
// |-CXXRecordDecl 0x96dd878 <col:1, col:7> col:7 implicit class Test
// `-FieldDecl 0x96dd940 <line:2:3, col:7> col:7 field 'int'
```
And we may not set the BraceRange.end to the EOF position -- as it changes the semantic, making it valid implies we have a `}` in the source code.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D80508/new/
https://reviews.llvm.org/D80508
More information about the cfe-commits
mailing list