[clang] Add missing type source info of decltype specifier in destructor call to AST (#197680)
The type source info will be stored in `MemberExpr::MemberDNLoc`. This patch fixes the underlying issue of #195788.
This commit is contained in:
parent
cb96a3edf7
commit
ca9884dd06
8 changed files with 35 additions and 39 deletions
|
|
@ -895,19 +895,13 @@ private:
|
|||
// rather than the TypeLoc nested inside it.
|
||||
// We still traverse the TypeLoc, because it may contain other targeted
|
||||
// things like the T in ~Foo<T>().
|
||||
// FIXME: Investigate if getNamedTypeInfo() can still return null for
|
||||
// invalid cases, and drop these checks when it never returns null.
|
||||
if (const auto *CDD = N.get<CXXDestructorDecl>()) {
|
||||
if (auto *TypeInfo = CDD->getNameInfo().getNamedTypeInfo())
|
||||
return TypeInfo->getTypeLoc().getBeginLoc();
|
||||
}
|
||||
if (const auto *CDD = N.get<CXXDestructorDecl>())
|
||||
return CDD->getNameInfo().getNamedTypeInfo()->getTypeLoc().getBeginLoc();
|
||||
if (const auto *ME = N.get<MemberExpr>()) {
|
||||
auto NameInfo = ME->getMemberNameInfo();
|
||||
if (NameInfo.getName().getNameKind() ==
|
||||
DeclarationName::CXXDestructorName) {
|
||||
if (auto *TypeInfo = NameInfo.getNamedTypeInfo())
|
||||
return TypeInfo->getTypeLoc().getBeginLoc();
|
||||
}
|
||||
DeclarationName::CXXDestructorName)
|
||||
return NameInfo.getNamedTypeInfo()->getTypeLoc().getBeginLoc();
|
||||
}
|
||||
|
||||
return SourceRange();
|
||||
|
|
|
|||
|
|
@ -789,13 +789,12 @@ public:
|
|||
}
|
||||
|
||||
bool VisitCXXDestructorDecl(CXXDestructorDecl *D) {
|
||||
if (auto *TI = D->getNameInfo().getNamedTypeInfo()) {
|
||||
SourceLocation Loc = TI->getTypeLoc().getBeginLoc();
|
||||
H.addExtraModifier(Loc, HighlightingModifier::ConstructorOrDestructor);
|
||||
H.addExtraModifier(Loc, HighlightingModifier::Declaration);
|
||||
if (D->isThisDeclarationADefinition())
|
||||
H.addExtraModifier(Loc, HighlightingModifier::Definition);
|
||||
}
|
||||
SourceLocation Loc =
|
||||
D->getNameInfo().getNamedTypeInfo()->getTypeLoc().getBeginLoc();
|
||||
H.addExtraModifier(Loc, HighlightingModifier::ConstructorOrDestructor);
|
||||
H.addExtraModifier(Loc, HighlightingModifier::Declaration);
|
||||
if (D->isThisDeclarationADefinition())
|
||||
H.addExtraModifier(Loc, HighlightingModifier::Definition);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -804,12 +803,12 @@ public:
|
|||
// `(foo.*pointer_to_member_fun)(arg);`
|
||||
if (auto *D = CE->getMethodDecl()) {
|
||||
if (isa<CXXDestructorDecl>(D)) {
|
||||
if (auto *ME = dyn_cast<MemberExpr>(CE->getCallee())) {
|
||||
if (auto *TI = ME->getMemberNameInfo().getNamedTypeInfo()) {
|
||||
H.addExtraModifier(TI->getTypeLoc().getBeginLoc(),
|
||||
HighlightingModifier::ConstructorOrDestructor);
|
||||
}
|
||||
}
|
||||
if (auto *ME = dyn_cast<MemberExpr>(CE->getCallee()))
|
||||
H.addExtraModifier(ME->getMemberNameInfo()
|
||||
.getNamedTypeInfo()
|
||||
->getTypeLoc()
|
||||
.getBeginLoc(),
|
||||
HighlightingModifier::ConstructorOrDestructor);
|
||||
} else if (D->isOverloadedOperator()) {
|
||||
if (auto *ME = dyn_cast<MemberExpr>(CE->getCallee()))
|
||||
H.addToken(
|
||||
|
|
|
|||
|
|
@ -687,6 +687,7 @@ Bug Fixes to AST Handling
|
|||
- Fixed a crash when parsing Doxygen ``@param`` commands attached to invalid declarations or non-function entities. (#GH182737)
|
||||
- Fixed the SourceLocation and SourceRange of reversed rewritten CXXOperatorCallExpr. (#GH192467)
|
||||
- Fixed a assertion when ``__block`` is used on global variables in C mode. (#GH183974)
|
||||
- Added missing AST nodes representing the ``decltype`` specifiers in destructor call to AST.
|
||||
|
||||
Miscellaneous Bug Fixes
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
|
|||
|
|
@ -830,8 +830,8 @@ public:
|
|||
const DeclarationNameLoc &getInfo() const { return LocInfo; }
|
||||
void setInfo(const DeclarationNameLoc &Info) { LocInfo = Info; }
|
||||
|
||||
/// getNamedTypeInfo - Returns the source type info associated to
|
||||
/// the name. Assumes it is a constructor, destructor or conversion.
|
||||
/// @return The type source info associated to the name if it is a
|
||||
/// constructor, destructor or conversion function, `nullptr` otherwise.
|
||||
TypeSourceInfo *getNamedTypeInfo() const {
|
||||
if (Name.getNameKind() != DeclarationName::CXXConstructorName &&
|
||||
Name.getNameKind() != DeclarationName::CXXDestructorName &&
|
||||
|
|
|
|||
|
|
@ -479,7 +479,11 @@ ParsedType Sema::getDestructorTypeForDecltype(const DeclSpec &DS,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
return ParsedType::make(T);
|
||||
TypeLocBuilder TLB;
|
||||
DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T);
|
||||
DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc());
|
||||
DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd());
|
||||
return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
|
||||
}
|
||||
|
||||
bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
|
||||
|
|
|
|||
|
|
@ -3208,8 +3208,8 @@ void TestNonADLCall3() {
|
|||
// CHECK-NEXT: "tokLen": 1
|
||||
// CHECK-NEXT: },
|
||||
// CHECK-NEXT: "end": {
|
||||
// CHECK-NEXT: "offset": 1693,
|
||||
// CHECK-NEXT: "col": 5,
|
||||
// CHECK-NEXT: "offset": 1704,
|
||||
// CHECK-NEXT: "col": 16,
|
||||
// CHECK-NEXT: "tokLen": 1
|
||||
// CHECK-NEXT: }
|
||||
// CHECK-NEXT: },
|
||||
|
|
|
|||
|
|
@ -216,7 +216,7 @@ void PostfixExpressions(S a, S *p, U<int> *r) {
|
|||
// the construct above.
|
||||
a.~decltype(a)();
|
||||
// CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:18> 'void'
|
||||
// CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:5> '<bound member function type>' .~S 0x{{[^ ]*}}
|
||||
// CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:16> '<bound member function type>' .~S 0x{{[^ ]*}}
|
||||
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S' lvalue ParmVar 0x{{[^ ]*}} 'a' 'S'
|
||||
|
||||
p->::S::~S();
|
||||
|
|
|
|||
|
|
@ -671,10 +671,6 @@ TEST_P(BuildSyntaxTreeTest, UnqualifiedId_DecltypeDestructor) {
|
|||
R"cpp(
|
||||
struct X { };
|
||||
void test(X x) {
|
||||
// FIXME: Make `decltype(x)` a child of `MemberExpression`. It is currently
|
||||
// not because `Expr::getSourceRange()` returns the range of `x.~` for the
|
||||
// `MemberExpr` instead of the expected `x.~decltype(x)`, this is a bug in
|
||||
// clang.
|
||||
[[x.~decltype(x)()]];
|
||||
}
|
||||
)cpp",
|
||||
|
|
@ -687,12 +683,14 @@ CallExpression Expression
|
|||
| |-'.' AccessToken
|
||||
| `-IdExpression Member
|
||||
| `-UnqualifiedId UnqualifiedId
|
||||
| `-'~'
|
||||
|-'decltype'
|
||||
|-'('
|
||||
|-'x'
|
||||
|-')'
|
||||
|-'('
|
||||
| |-'~'
|
||||
| |-'decltype'
|
||||
| |-'('
|
||||
| |-IdExpression
|
||||
| | `-UnqualifiedId UnqualifiedId
|
||||
| | `-'x'
|
||||
| `-')'
|
||||
|-'(' OpenParen
|
||||
`-')' CloseParen
|
||||
)txt"}));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue