forked from qt-creator/qt-creator
C++11: Fix use of >> in template arguments.
Change-Id: Ic99ca897e7a3b9c82cf8c5093a90bf9c88dbb0ed Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
23
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
23
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -107,7 +107,7 @@ inline int precedence(int tokenKind, bool templateArguments)
|
|||||||
{
|
{
|
||||||
// ### this will/might need some tuning for C++0x
|
// ### this will/might need some tuning for C++0x
|
||||||
// (see: [temp.names]p3)
|
// (see: [temp.names]p3)
|
||||||
if (templateArguments && tokenKind == T_GREATER)
|
if (templateArguments && (tokenKind == T_GREATER || tokenKind == T_GREATER_GREATER))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (lookAtAssignmentOperator(tokenKind))
|
if (lookAtAssignmentOperator(tokenKind))
|
||||||
@@ -212,6 +212,11 @@ bool Parser::switchTemplateArguments(bool templateArguments)
|
|||||||
return previousTemplateArguments;
|
return previousTemplateArguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Parser::maybeSplitGreaterGreaterToken(int n)
|
||||||
|
{
|
||||||
|
return _translationUnit->maybeSplitGreaterGreaterToken(_tokenIndex + n - 1);
|
||||||
|
}
|
||||||
|
|
||||||
bool Parser::blockErrors(bool block)
|
bool Parser::blockErrors(bool block)
|
||||||
{ return _translationUnit->blockErrors(block); }
|
{ return _translationUnit->blockErrors(block); }
|
||||||
|
|
||||||
@@ -433,9 +438,9 @@ bool Parser::parseTemplateId(NameAST *&node, unsigned template_token)
|
|||||||
ast->template_token = template_token;
|
ast->template_token = template_token;
|
||||||
ast->identifier_token = consumeToken();
|
ast->identifier_token = consumeToken();
|
||||||
ast->less_token = consumeToken();
|
ast->less_token = consumeToken();
|
||||||
if (LA() == T_GREATER || parseTemplateArgumentList(
|
if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER || parseTemplateArgumentList(
|
||||||
ast->template_argument_list)) {
|
ast->template_argument_list)) {
|
||||||
if (LA() == T_GREATER) {
|
if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER) {
|
||||||
ast->greater_token = consumeToken();
|
ast->greater_token = consumeToken();
|
||||||
node = ast;
|
node = ast;
|
||||||
return true;
|
return true;
|
||||||
@@ -1103,7 +1108,7 @@ bool Parser::parseTemplateDeclaration(DeclarationAST *&node)
|
|||||||
|
|
||||||
if (LA() == T_LESS) {
|
if (LA() == T_LESS) {
|
||||||
ast->less_token = consumeToken();
|
ast->less_token = consumeToken();
|
||||||
if (LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list))
|
if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER || parseTemplateParameterList(ast->template_parameter_list))
|
||||||
match(T_GREATER, &ast->greater_token);
|
match(T_GREATER, &ast->greater_token);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1318,7 +1323,7 @@ bool Parser::parseTemplateArgument(ExpressionAST *&node)
|
|||||||
if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
|
if (_cxx0xEnabled && LA() == T_DOT_DOT_DOT)
|
||||||
index = 2;
|
index = 2;
|
||||||
|
|
||||||
if (LA(index) == T_COMMA || LA(index) == T_GREATER)
|
if (LA(index) == T_COMMA || maybeSplitGreaterGreaterToken(index) || LA(index) == T_GREATER)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1796,7 +1801,7 @@ bool Parser::parseTemplateTypeParameter(DeclarationAST *&node)
|
|||||||
if (LA() == T_LESS)
|
if (LA() == T_LESS)
|
||||||
ast->less_token = consumeToken();
|
ast->less_token = consumeToken();
|
||||||
parseTemplateParameterList(ast->template_parameter_list);
|
parseTemplateParameterList(ast->template_parameter_list);
|
||||||
if (LA() == T_GREATER)
|
if (maybeSplitGreaterGreaterToken() || LA() == T_GREATER)
|
||||||
ast->greater_token = consumeToken();
|
ast->greater_token = consumeToken();
|
||||||
if (LA() == T_CLASS)
|
if (LA() == T_CLASS)
|
||||||
ast->class_token = consumeToken();
|
ast->class_token = consumeToken();
|
||||||
@@ -1816,7 +1821,7 @@ bool Parser::parseTemplateTypeParameter(DeclarationAST *&node)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::lookAtTypeParameter() const
|
bool Parser::lookAtTypeParameter()
|
||||||
{
|
{
|
||||||
if (LA() == T_CLASS || LA() == T_TYPENAME) {
|
if (LA() == T_CLASS || LA() == T_TYPENAME) {
|
||||||
if (LA(2) == T_IDENTIFIER) {
|
if (LA(2) == T_IDENTIFIER) {
|
||||||
@@ -1827,7 +1832,7 @@ bool Parser::lookAtTypeParameter() const
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return false;
|
return maybeSplitGreaterGreaterToken(3);
|
||||||
}
|
}
|
||||||
} else if (LA(2) == T_COLON_COLON) {
|
} else if (LA(2) == T_COLON_COLON) {
|
||||||
// found something like template <typename ::foo::bar>...
|
// found something like template <typename ::foo::bar>...
|
||||||
@@ -2947,7 +2952,7 @@ bool Parser::parseUnqualifiedName(NameAST *&node, bool acceptTemplateId)
|
|||||||
if (acceptTemplateId && LA(2) == T_LESS) {
|
if (acceptTemplateId && LA(2) == T_LESS) {
|
||||||
bool blocked = blockErrors(true);
|
bool blocked = blockErrors(true);
|
||||||
if (parseTemplateId(node)
|
if (parseTemplateId(node)
|
||||||
&& (! _templateArguments || (LA() == T_COMMA || LA() == T_GREATER ||
|
&& (! _templateArguments || (LA() == T_COMMA || maybeSplitGreaterGreaterToken() || LA() == T_GREATER ||
|
||||||
LA() == T_LPAREN || LA() == T_RPAREN ||
|
LA() == T_LPAREN || LA() == T_RPAREN ||
|
||||||
LA() == T_STAR || LA() == T_AMPER || // ptr-operators
|
LA() == T_STAR || LA() == T_AMPER || // ptr-operators
|
||||||
LA() == T_COLON_COLON))) {
|
LA() == T_COLON_COLON))) {
|
||||||
|
|||||||
3
src/libs/3rdparty/cplusplus/Parser.h
vendored
3
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -259,7 +259,7 @@ public:
|
|||||||
bool skip(int l, int r);
|
bool skip(int l, int r);
|
||||||
int find(int token, int stopAt);
|
int find(int token, int stopAt);
|
||||||
|
|
||||||
bool lookAtTypeParameter() const;
|
bool lookAtTypeParameter();
|
||||||
bool lookAtCVQualifier() const;
|
bool lookAtCVQualifier() const;
|
||||||
bool lookAtFunctionSpecifier() const;
|
bool lookAtFunctionSpecifier() const;
|
||||||
bool lookAtStorageClassSpecifier() const;
|
bool lookAtStorageClassSpecifier() const;
|
||||||
@@ -277,6 +277,7 @@ public:
|
|||||||
int peekAtQtContextKeyword() const;
|
int peekAtQtContextKeyword() const;
|
||||||
|
|
||||||
bool switchTemplateArguments(bool templateArguments);
|
bool switchTemplateArguments(bool templateArguments);
|
||||||
|
bool maybeSplitGreaterGreaterToken(int n = 1);
|
||||||
|
|
||||||
bool blockErrors(bool block);
|
bool blockErrors(bool block);
|
||||||
void warning(unsigned index, const char *format, ...);
|
void warning(unsigned index, const char *format, ...);
|
||||||
|
|||||||
28
src/libs/3rdparty/cplusplus/TranslationUnit.cpp
vendored
28
src/libs/3rdparty/cplusplus/TranslationUnit.cpp
vendored
@@ -552,6 +552,34 @@ unsigned TranslationUnit::findPreviousLineOffset(unsigned tokenIndex) const
|
|||||||
return lineOffset;
|
return lineOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslationUnit::maybeSplitGreaterGreaterToken(unsigned tokenIndex)
|
||||||
|
{
|
||||||
|
Token &tok = _tokens->at(tokenIndex);
|
||||||
|
if (tok.kind() != T_GREATER_GREATER)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
tok.f.kind = T_GREATER;
|
||||||
|
tok.f.length = 1;
|
||||||
|
|
||||||
|
Token newGreater;
|
||||||
|
newGreater.f.kind = T_GREATER;
|
||||||
|
newGreater.f.expanded = tok.f.expanded;
|
||||||
|
newGreater.f.generated = tok.f.generated;
|
||||||
|
newGreater.f.length = 1;
|
||||||
|
newGreater.offset = tok.offset + 1;
|
||||||
|
|
||||||
|
_tokens->insert(_tokens->begin() + tokenIndex + 1, newGreater);
|
||||||
|
|
||||||
|
std::map<unsigned, std::pair<unsigned, unsigned> >::const_iterator it =
|
||||||
|
_expandedLineColumn.find(tok.offset);
|
||||||
|
if (it != _expandedLineColumn.end()) {
|
||||||
|
const std::pair<unsigned, unsigned> newPosition(it->second.first, it->second.second + 1);
|
||||||
|
_expandedLineColumn.insert(std::make_pair(newGreater.offset, newPosition));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void TranslationUnit::showErrorLine(unsigned index, unsigned column, FILE *out)
|
void TranslationUnit::showErrorLine(unsigned index, unsigned column, FILE *out)
|
||||||
{
|
{
|
||||||
unsigned lineOffset = _lineOffsets[findLineNumber(_tokens->at(index).offset)];
|
unsigned lineOffset = _lineOffsets[findLineNumber(_tokens->at(index).offset)];
|
||||||
|
|||||||
@@ -134,6 +134,8 @@ public:
|
|||||||
|
|
||||||
unsigned findPreviousLineOffset(unsigned tokenIndex) const;
|
unsigned findPreviousLineOffset(unsigned tokenIndex) const;
|
||||||
|
|
||||||
|
bool maybeSplitGreaterGreaterToken(unsigned tokenIndex);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct PPLine {
|
struct PPLine {
|
||||||
unsigned offset;
|
unsigned offset;
|
||||||
|
|||||||
10
tests/auto/cplusplus/cxx11/data/templateGreaterGreater.1.cpp
Normal file
10
tests/auto/cplusplus/cxx11/data/templateGreaterGreater.1.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
template <class i, int j = 1>
|
||||||
|
class Y {};
|
||||||
|
template <int i>
|
||||||
|
class X {};
|
||||||
|
|
||||||
|
Y<X<6>, 7> x;
|
||||||
|
Y<X<1>> y;
|
||||||
|
X< (1 >> 2) > z;
|
||||||
|
auto a = static_cast<X<1>>(X<1>());
|
||||||
|
|
||||||
@@ -144,6 +144,7 @@ void tst_cxx11::parse_data()
|
|||||||
QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << "";
|
QTest::newRow("rangeFor.1") << "rangeFor.1.cpp" << "";
|
||||||
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
|
QTest::newRow("aliasDecl.1") << "aliasDecl.1.cpp" << "";
|
||||||
QTest::newRow("enums.1") << "enums.1.cpp" << "";
|
QTest::newRow("enums.1") << "enums.1.cpp" << "";
|
||||||
|
QTest::newRow("templateGreaterGreater.1") << "templateGreaterGreater.1.cpp" << "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void tst_cxx11::parse()
|
void tst_cxx11::parse()
|
||||||
|
|||||||
Reference in New Issue
Block a user