Author: majnemer Date: Tue Sep 3 17:36:22 2013 New Revision: 189867 URL: http://llvm.org/viewvc/llvm-project?rev=189867&view=rev Log: 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 Modified: cfe/trunk/lib/Parse/Parser.cpp cfe/trunk/test/Parser/MicrosoftExtensions.cpp Modified: cfe/trunk/lib/Parse/Parser.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=189867&r1=189866&r2=189867&view=diff ============================================================================== --- cfe/trunk/lib/Parse/Parser.cpp (original) +++ cfe/trunk/lib/Parse/Parser.cpp Tue Sep 3 17:36:22 2013 @@ -1480,6 +1480,23 @@ bool Parser::TryAnnotateTypeOrScopeToken && "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 // 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" Modified: cfe/trunk/test/Parser/MicrosoftExtensions.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/MicrosoftExtensions.cpp?rev=189867&r1=189866&r2=189867&view=diff ============================================================================== --- cfe/trunk/test/Parser/MicrosoftExtensions.cpp (original) +++ cfe/trunk/test/Parser/MicrosoftExtensions.cpp Tue Sep 3 17:36:22 2013 @@ -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 { _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
