C++: Remove workaround for crashing if parsing invalid code

This reverts the changes

    commit beac7b9539
    C++: Fix highlighting after "invalid code"

    commit 78ab287fc6
    C++: Stop parsing a declaration after two tries

which were a work around for QTCREATORBUG-12890.

A follow-up patch provides a proper fix.

Task-number: QTCREATORBUG-12890
Change-Id: I2650a8e41c8ff1180cad9f069e463fc51bd2f1b1
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-02-06 15:04:23 +01:00
parent d68fc038cc
commit ae3aa07c4d
8 changed files with 8 additions and 55 deletions

View File

@@ -265,13 +265,12 @@ inline void debugPrintCheckCache(bool) {}
return true; \ return true; \
} }
Parser::Parser(TranslationUnit *unit, int retryParseDeclarationLimit) Parser::Parser(TranslationUnit *unit)
: _translationUnit(unit), : _translationUnit(unit),
_control(unit->control()), _control(unit->control()),
_pool(unit->memoryPool()), _pool(unit->memoryPool()),
_languageFeatures(unit->languageFeatures()), _languageFeatures(unit->languageFeatures()),
_tokenIndex(1), _tokenIndex(1),
_retryParseDeclarationLimit(retryParseDeclarationLimit),
_templateArguments(0), _templateArguments(0),
_inFunctionBody(false), _inFunctionBody(false),
_inExpressionStatement(false), _inExpressionStatement(false),
@@ -311,20 +310,6 @@ bool Parser::skipUntil(int token)
return false; return false;
} }
void Parser::skipUntilAfterSemicolonOrRightBrace()
{
while (int tk = LA()) {
switch (tk) {
case T_SEMICOLON:
case T_RBRACE:
consumeToken();
return;
default:
consumeToken();
}
}
}
void Parser::skipUntilDeclaration() void Parser::skipUntilDeclaration()
{ {
for (; ; consumeToken()) { for (; ; consumeToken()) {
@@ -641,25 +626,19 @@ bool Parser::parseTranslationUnit(TranslationUnitAST *&node)
TranslationUnitAST *ast = new (_pool) TranslationUnitAST; TranslationUnitAST *ast = new (_pool) TranslationUnitAST;
DeclarationListAST **decl = &ast->declaration_list; DeclarationListAST **decl = &ast->declaration_list;
int declarationsInRowFailedToParse = 0;
while (LA()) { while (LA()) {
unsigned start_declaration = cursor(); unsigned start_declaration = cursor();
DeclarationAST *declaration = 0; DeclarationAST *declaration = 0;
if (parseDeclaration(declaration)) { if (parseDeclaration(declaration)) {
declarationsInRowFailedToParse = 0;
*decl = new (_pool) DeclarationListAST; *decl = new (_pool) DeclarationListAST;
(*decl)->value = declaration; (*decl)->value = declaration;
decl = &(*decl)->next; decl = &(*decl)->next;
} else { } else {
error(start_declaration, "expected a declaration"); error(start_declaration, "expected a declaration");
rewind(start_declaration + 1); rewind(start_declaration + 1);
if (++declarationsInRowFailedToParse == _retryParseDeclarationLimit) skipUntilDeclaration();
skipUntilAfterSemicolonOrRightBrace();
else
skipUntilDeclaration();
} }
@@ -808,8 +787,6 @@ bool Parser::parseLinkageBody(DeclarationAST *&node)
ast->lbrace_token = consumeToken(); ast->lbrace_token = consumeToken();
DeclarationListAST **declaration_ptr = &ast->declaration_list; DeclarationListAST **declaration_ptr = &ast->declaration_list;
int declarationsInRowFailedToParse = 0;
while (int tk = LA()) { while (int tk = LA()) {
if (tk == T_RBRACE) if (tk == T_RBRACE)
break; break;
@@ -817,17 +794,13 @@ bool Parser::parseLinkageBody(DeclarationAST *&node)
unsigned start_declaration = cursor(); unsigned start_declaration = cursor();
DeclarationAST *declaration = 0; DeclarationAST *declaration = 0;
if (parseDeclaration(declaration)) { if (parseDeclaration(declaration)) {
declarationsInRowFailedToParse = 0;
*declaration_ptr = new (_pool) DeclarationListAST; *declaration_ptr = new (_pool) DeclarationListAST;
(*declaration_ptr)->value = declaration; (*declaration_ptr)->value = declaration;
declaration_ptr = &(*declaration_ptr)->next; declaration_ptr = &(*declaration_ptr)->next;
} else { } else {
error(start_declaration, "expected a declaration"); error(start_declaration, "expected a declaration");
rewind(start_declaration + 1); rewind(start_declaration + 1);
if (++declarationsInRowFailedToParse == _retryParseDeclarationLimit) skipUntilDeclaration();
skipUntilAfterSemicolonOrRightBrace();
else
skipUntilDeclaration();
} }
_templateArgumentList.clear(); _templateArgumentList.clear();

View File

@@ -33,7 +33,7 @@ namespace CPlusPlus {
class CPLUSPLUS_EXPORT Parser class CPLUSPLUS_EXPORT Parser
{ {
public: public:
Parser(TranslationUnit *translationUnit, int retryParseDeclarationLimit); Parser(TranslationUnit *translationUnit);
~Parser(); ~Parser();
bool parseTranslationUnit(TranslationUnitAST *&node); bool parseTranslationUnit(TranslationUnitAST *&node);
@@ -254,7 +254,6 @@ public:
bool parseDesignator(DesignatorAST *&node); bool parseDesignator(DesignatorAST *&node);
bool skipUntil(int token); bool skipUntil(int token);
void skipUntilAfterSemicolonOrRightBrace();
void skipUntilDeclaration(); void skipUntilDeclaration();
bool skipUntilStatement(); bool skipUntilStatement();
bool skip(int l, int r); bool skip(int l, int r);
@@ -317,7 +316,6 @@ private:
MemoryPool *_pool; MemoryPool *_pool;
LanguageFeatures _languageFeatures; LanguageFeatures _languageFeatures;
unsigned _tokenIndex; unsigned _tokenIndex;
int _retryParseDeclarationLimit;
bool _templateArguments: 1; bool _templateArguments: 1;
bool _inFunctionBody: 1; bool _inFunctionBody: 1;
bool _inExpressionStatement: 1; bool _inExpressionStatement: 1;

View File

@@ -49,8 +49,7 @@ TranslationUnit::TranslationUnit(Control *control, const StringLiteral *fileId)
_lastSourceChar(0), _lastSourceChar(0),
_pool(0), _pool(0),
_ast(0), _ast(0),
_flags(0), _flags(0)
_retryParseDeclarationLimit(defaultRetryParseDeclarationLimit())
{ {
_tokens = new std::vector<Token>(); _tokens = new std::vector<Token>();
_comments = new std::vector<Token>(); _comments = new std::vector<Token>();
@@ -300,7 +299,7 @@ bool TranslationUnit::parse(ParseMode mode)
f._parsed = true; f._parsed = true;
Parser parser(this, _retryParseDeclarationLimit); Parser parser(this);
bool parsed = false; bool parsed = false;
switch (mode) { switch (mode) {

View File

@@ -149,9 +149,6 @@ public:
LanguageFeatures languageFeatures() const { return _languageFeatures; } LanguageFeatures languageFeatures() const { return _languageFeatures; }
void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; } void setLanguageFeatures(LanguageFeatures features) { _languageFeatures = features; }
static int defaultRetryParseDeclarationLimit() { return 2; }
void setRetryParseDeclarationLimit(int limit) { _retryParseDeclarationLimit = limit; }
private: private:
struct PPLine { struct PPLine {
unsigned utf16charOffset; unsigned utf16charOffset;
@@ -213,8 +210,6 @@ private:
Flags f; Flags f;
}; };
LanguageFeatures _languageFeatures; LanguageFeatures _languageFeatures;
int _retryParseDeclarationLimit;
}; };
} // namespace CPlusPlus } // namespace CPlusPlus

View File

@@ -623,13 +623,6 @@ void Document::tokenize()
_translationUnit->tokenize(); _translationUnit->tokenize();
} }
void Document::setRetryHarderToParseDeclarations(bool yesno)
{
_translationUnit->setRetryParseDeclarationLimit(
yesno ? 1000
: TranslationUnit::defaultRetryParseDeclarationLimit());
}
bool Document::isParsed() const bool Document::isParsed() const
{ {
return _translationUnit->isParsed(); return _translationUnit->isParsed();

View File

@@ -129,7 +129,6 @@ public:
bool isTokenized() const; bool isTokenized() const;
void tokenize(); void tokenize();
void setRetryHarderToParseDeclarations(bool yesno);
bool isParsed() const; bool isParsed() const;
bool parse(ParseMode mode = ParseTranlationUnit); bool parse(ParseMode mode = ParseTranlationUnit);

View File

@@ -125,7 +125,6 @@ SemanticInfo SemanticInfoUpdaterPrivate::update(const SemanticInfo::Source &sour
Document::Ptr doc = newSemanticInfo.snapshot.preprocessedDocument(source.code, source.fileName); Document::Ptr doc = newSemanticInfo.snapshot.preprocessedDocument(source.code, source.fileName);
if (processor) if (processor)
doc->control()->setTopLevelDeclarationProcessor(processor); doc->control()->setTopLevelDeclarationProcessor(processor);
doc->setRetryHarderToParseDeclarations(true);
doc->check(); doc->check();
if (processor && processor->isCanceled()) if (processor && processor->isCanceled())
newSemanticInfo.complete = false; newSemanticInfo.complete = false;

View File

@@ -51,9 +51,7 @@ public:
TranslationUnit::ParseMode mode, TranslationUnit::ParseMode mode,
bool blockErrors = false, bool blockErrors = false,
bool qtMocRun = false, bool qtMocRun = false,
bool cxx11Enabled = false, bool cxx11Enabled = false)
int retryParseDeclarationLimit
= TranslationUnit::defaultRetryParseDeclarationLimit())
{ {
const StringLiteral *fileId = control.stringLiteral("<stdin>"); const StringLiteral *fileId = control.stringLiteral("<stdin>");
LanguageFeatures features; LanguageFeatures features;
@@ -64,7 +62,6 @@ public:
features.qtMocRunEnabled = qtMocRun; features.qtMocRunEnabled = qtMocRun;
TranslationUnit *unit = new TranslationUnit(&control, fileId); TranslationUnit *unit = new TranslationUnit(&control, fileId);
unit->setLanguageFeatures(features); unit->setLanguageFeatures(features);
unit->setRetryParseDeclarationLimit(retryParseDeclarationLimit);
unit->setSource(source.constData(), source.length()); unit->setSource(source.constData(), source.length());
unit->blockErrors(blockErrors); unit->blockErrors(blockErrors);
unit->parse(mode); unit->parse(mode);
@@ -1866,7 +1863,7 @@ void tst_AST::invalidCode()
"class Foo {};\n"; "class Foo {};\n";
QSharedPointer<TranslationUnit> unit(parse(invalidCode, TranslationUnit::ParseTranlationUnit, QSharedPointer<TranslationUnit> unit(parse(invalidCode, TranslationUnit::ParseTranlationUnit,
false, false, false, 1000)); false, false, false));
QVERIFY(unit->ast()); QVERIFY(unit->ast());
TranslationUnitAST *unitAST = unit->ast()->asTranslationUnit(); TranslationUnitAST *unitAST = unit->ast()->asTranslationUnit();
QVERIFY(unitAST->declaration_list); QVERIFY(unitAST->declaration_list);