mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-25 19:36:05 +00:00
Parser: support Microsoft syntax for 'typename typedef'
Summary: Transform the token sequence for: typename typedef T U; to: typename T typedef U; Raise a diagnostic when this happens but only if we succeeded handling the typename. Reviewers: rsmith, rnk Reviewed By: rsmith CC: cfe-commits Differential Revision: http://llvm-reviews.chandlerc.com/D1433 llvm-svn: 189867
This commit is contained in:
parent
e13ce180f2
commit
ad01851f32
@ -1480,6 +1480,23 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
|
||||
&& "Cannot be a type or scope token!");
|
||||
|
||||
if (Tok.is(tok::kw_typename)) {
|
||||
// MSVC lets you do stuff like:
|
||||
// typename typedef T_::D D;
|
||||
//
|
||||
// We will consume the typedef token here and put it back after we have
|
||||
// parsed the first identifier, transforming it into something more like:
|
||||
// typename T_::D typedef D;
|
||||
if (getLangOpts().MicrosoftMode && NextToken().is(tok::kw_typedef)) {
|
||||
Token TypedefToken;
|
||||
PP.Lex(TypedefToken);
|
||||
bool Result = TryAnnotateTypeOrScopeToken(EnteringContext, NeedType);
|
||||
PP.EnterToken(Tok);
|
||||
Tok = TypedefToken;
|
||||
if (!Result)
|
||||
Diag(Tok.getLocation(), diag::warn_expected_qualified_after_typename);
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Parse a C++ typename-specifier, e.g., "typename T::type".
|
||||
//
|
||||
// typename-specifier:
|
||||
@ -1498,7 +1515,7 @@ bool Parser::TryAnnotateTypeOrScopeToken(bool EnteringContext, bool NeedType) {
|
||||
// Attempt to recover by skipping the invalid 'typename'
|
||||
if (Tok.is(tok::annot_decltype) ||
|
||||
(!TryAnnotateTypeOrScopeToken(EnteringContext, NeedType) &&
|
||||
Tok.isAnnotation())) {
|
||||
Tok.isAnnotation())) {
|
||||
unsigned DiagID = diag::err_expected_qualified_after_typename;
|
||||
// MS compatibility: MSVC permits using known types with typename.
|
||||
// e.g. "typedef typename T* pointer_type"
|
||||
|
@ -152,7 +152,9 @@ void missing_template_keyword(){
|
||||
|
||||
|
||||
|
||||
class AAAA { };
|
||||
class AAAA {
|
||||
typedef int D;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
class SimpleTemplate {};
|
||||
@ -174,6 +176,12 @@ void redundant_typename() {
|
||||
int k = typename var;// expected-error {{expected a qualified name after 'typename'}}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct TypenameWrongPlace {
|
||||
typename typedef T::D D;// expected-warning {{expected a qualified name after 'typename'}}
|
||||
};
|
||||
|
||||
extern TypenameWrongPlace<AAAA> PR16925;
|
||||
|
||||
__interface MicrosoftInterface;
|
||||
__interface MicrosoftInterface {
|
||||
|
Loading…
x
Reference in New Issue
Block a user