diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Parse/ParseExprCXX.cpp | 10 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 16 |
2 files changed, 26 insertions, 0 deletions
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 79d2ec21ab0..182f2f080d5 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -1966,6 +1966,16 @@ bool Parser::ParseUnqualifiedId(CXXScopeSpec &SS, bool EnteringContext, // Parse the '~'. SourceLocation TildeLoc = ConsumeToken(); + + if (SS.isEmpty() && Tok.is(tok::kw_decltype)) { + DeclSpec DS(AttrFactory); + SourceLocation EndLoc = ParseDecltypeSpecifier(DS); + if (ParsedType Type = Actions.getDestructorType(DS, ObjectType)) { + Result.setDestructorName(TildeLoc, Type, EndLoc); + return false; + } + return true; + } // Parse the class-name. if (Tok.isNot(tok::identifier)) { diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 06837fef847..af297840c39 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -265,6 +265,22 @@ ParsedType Sema::getDestructorName(SourceLocation TildeLoc, return ParsedType(); } +ParsedType Sema::getDestructorType(const DeclSpec& DS, ParsedType ObjectType) { + if (DS.getTypeSpecType() == DeclSpec::TST_error) + return ParsedType(); + assert(DS.getTypeSpecType() == DeclSpec::TST_decltype + && "only get destructor types from declspecs"); + QualType T = BuildDecltypeType(DS.getRepAsExpr(), DS.getTypeSpecTypeLoc()); + QualType SearchType = GetTypeFromParser(ObjectType); + if (SearchType->isDependentType() || Context.hasSameUnqualifiedType(SearchType, T)) { + return ParsedType::make(T); + } + + Diag(DS.getTypeSpecTypeLoc(), diag::err_destructor_expr_type_mismatch) + << T << SearchType; + return ParsedType(); +} + /// \brief Build a C++ typeid expression with a type operand. ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, |