forked from qt-creator/qt-creator
C++: Remove workaround for crashing if parsing invalid code
This reverts the changes commitbeac7b9539
C++: Fix highlighting after "invalid code" commit78ab287fc6
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:
29
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
29
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -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,24 +626,18 @@ 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)
|
|
||||||
skipUntilAfterSemicolonOrRightBrace();
|
|
||||||
else
|
|
||||||
skipUntilDeclaration();
|
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,16 +794,12 @@ 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)
|
|
||||||
skipUntilAfterSemicolonOrRightBrace();
|
|
||||||
else
|
|
||||||
skipUntilDeclaration();
|
skipUntilDeclaration();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
4
src/libs/3rdparty/cplusplus/Parser.h
vendored
4
src/libs/3rdparty/cplusplus/Parser.h
vendored
@@ -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;
|
||||||
|
@@ -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) {
|
||||||
|
@@ -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
|
||||||
|
@@ -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();
|
||||||
|
@@ -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);
|
||||||
|
|
||||||
|
@@ -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;
|
||||||
|
@@ -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);
|
||||||
|
Reference in New Issue
Block a user