forked from qt-creator/qt-creator
Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline
This commit is contained in:
@@ -240,6 +240,9 @@ void Document::startSkippingBlocks(unsigned start)
|
|||||||
|
|
||||||
void Document::stopSkippingBlocks(unsigned stop)
|
void Document::stopSkippingBlocks(unsigned stop)
|
||||||
{
|
{
|
||||||
|
if (_skippedBlocks.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
unsigned start = _skippedBlocks.back().begin();
|
unsigned start = _skippedBlocks.back().begin();
|
||||||
if (start > stop)
|
if (start > stop)
|
||||||
_skippedBlocks.removeLast(); // Ignore this block, it's invalid.
|
_skippedBlocks.removeLast(); // Ignore this block, it's invalid.
|
||||||
|
|||||||
@@ -159,8 +159,12 @@ bool LookupContext::maybeValidSymbol(Symbol *symbol,
|
|||||||
QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visibleScopes,
|
QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visibleScopes,
|
||||||
ResolveMode mode) const
|
ResolveMode mode) const
|
||||||
{
|
{
|
||||||
if (QualifiedNameId *q = name->asQualifiedNameId()) {
|
|
||||||
QList<Symbol *> candidates;
|
QList<Symbol *> candidates;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return candidates;
|
||||||
|
|
||||||
|
if (QualifiedNameId *q = name->asQualifiedNameId()) {
|
||||||
QList<Scope *> scopes = visibleScopes;
|
QList<Scope *> scopes = visibleScopes;
|
||||||
for (unsigned i = 0; i < q->nameCount(); ++i) {
|
for (unsigned i = 0; i < q->nameCount(); ++i) {
|
||||||
Name *name = q->nameAt(i);
|
Name *name = q->nameAt(i);
|
||||||
@@ -210,7 +214,6 @@ QList<Symbol *> LookupContext::resolve(Name *name, const QList<Scope *> &visible
|
|||||||
return candidates;
|
return candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<Symbol *> candidates;
|
|
||||||
if (Identifier *id = identifier(name)) {
|
if (Identifier *id = identifier(name)) {
|
||||||
for (int scopeIndex = 0; scopeIndex < visibleScopes.size(); ++scopeIndex) {
|
for (int scopeIndex = 0; scopeIndex < visibleScopes.size(); ++scopeIndex) {
|
||||||
Scope *scope = visibleScopes.at(scopeIndex);
|
Scope *scope = visibleScopes.at(scopeIndex);
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ QVariant OverviewModel::data(const QModelIndex &index, int role) const
|
|||||||
if (! symbol->isScopedSymbol() || symbol->isFunction()) {
|
if (! symbol->isScopedSymbol() || symbol->isFunction()) {
|
||||||
QString type = _overview.prettyType(symbol->type());
|
QString type = _overview.prettyType(symbol->type());
|
||||||
if (! type.isEmpty()) {
|
if (! type.isEmpty()) {
|
||||||
if (symbol->type() && ! symbol->type()->isFunctionType())
|
if (! symbol->type()->isFunctionType())
|
||||||
name += QLatin1String(": ");
|
name += QLatin1String(": ");
|
||||||
name += type;
|
name += type;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ OpenEditorsWidget::OpenEditorsWidget()
|
|||||||
|
|
||||||
OpenEditorsWidget::~OpenEditorsWidget()
|
OpenEditorsWidget::~OpenEditorsWidget()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor)
|
void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor)
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ void ManhattanStyle::polish(QWidget *widget)
|
|||||||
if (qobject_cast<QToolButton*>(widget)) {
|
if (qobject_cast<QToolButton*>(widget)) {
|
||||||
widget->setAttribute(Qt::WA_Hover);
|
widget->setAttribute(Qt::WA_Hover);
|
||||||
widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
|
widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
|
||||||
|
widget->setAttribute(Qt::WA_Hover);
|
||||||
}
|
}
|
||||||
else if (qobject_cast<QLineEdit*>(widget)) {
|
else if (qobject_cast<QLineEdit*>(widget)) {
|
||||||
widget->setAttribute(Qt::WA_Hover);
|
widget->setAttribute(Qt::WA_Hover);
|
||||||
@@ -325,8 +326,10 @@ void ManhattanStyle::polish(QWidget *widget)
|
|||||||
widget->setMinimumHeight(StyleHelper::navigationWidgetHeight());
|
widget->setMinimumHeight(StyleHelper::navigationWidgetHeight());
|
||||||
else if (qobject_cast<QStatusBar*>(widget))
|
else if (qobject_cast<QStatusBar*>(widget))
|
||||||
widget->setFixedHeight(StyleHelper::navigationWidgetHeight() + 2);
|
widget->setFixedHeight(StyleHelper::navigationWidgetHeight() + 2);
|
||||||
else if (qobject_cast<QComboBox*>(widget))
|
else if (qobject_cast<QComboBox*>(widget)) {
|
||||||
widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
|
widget->setMaximumHeight(StyleHelper::navigationWidgetHeight() - 2);
|
||||||
|
widget->setAttribute(Qt::WA_Hover);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,6 +341,8 @@ void ManhattanStyle::unpolish(QWidget *widget)
|
|||||||
widget->setAttribute(Qt::WA_Hover, false);
|
widget->setAttribute(Qt::WA_Hover, false);
|
||||||
else if (qobject_cast<QToolBar*>(widget))
|
else if (qobject_cast<QToolBar*>(widget))
|
||||||
widget->setAttribute(Qt::WA_Hover, false);
|
widget->setAttribute(Qt::WA_Hover, false);
|
||||||
|
else if (qobject_cast<QComboBox*>(widget))
|
||||||
|
widget->setAttribute(Qt::WA_Hover, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,14 +522,11 @@ void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption
|
|||||||
painter->drawLine(rect.topRight(), rect.bottomRight());
|
painter->drawLine(rect.topRight(), rect.bottomRight());
|
||||||
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
|
painter->drawLine(rect.bottomLeft(), rect.bottomRight());
|
||||||
}
|
}
|
||||||
#ifndef Q_WS_MAC
|
|
||||||
else if (option->state & State_Enabled &&
|
else if (option->state & State_Enabled &&
|
||||||
option->state & State_MouseOver) {
|
option->state & State_MouseOver) {
|
||||||
QColor lighter(255, 255, 255, 35);
|
QColor lighter(255, 255, 255, 35);
|
||||||
painter->fillRect(rect, lighter);
|
painter->fillRect(rect, lighter);
|
||||||
painter->drawLine(rect.topRight(), rect.bottomRight());
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -676,11 +678,11 @@ void ManhattanStyle::drawPrimitive(PrimitiveElement element, const QStyleOption
|
|||||||
imagePainter.setBrush(option->palette.mid().color());
|
imagePainter.setBrush(option->palette.mid().color());
|
||||||
imagePainter.setPen(option->palette.mid().color());
|
imagePainter.setPen(option->palette.mid().color());
|
||||||
} else {
|
} else {
|
||||||
QColor shadow(0, 0, 0, 50);
|
QColor shadow(0, 0, 0, 100);
|
||||||
imagePainter.translate(0, 1);
|
imagePainter.translate(0, 1);
|
||||||
imagePainter.setPen(shadow);
|
imagePainter.setPen(shadow);
|
||||||
imagePainter.setBrush(shadow);
|
imagePainter.setBrush(shadow);
|
||||||
QColor foreGround(255, 255, 255, 220);
|
QColor foreGround(255, 255, 255, 210);
|
||||||
imagePainter.drawPolygon(a);
|
imagePainter.drawPolygon(a);
|
||||||
imagePainter.translate(0, -1);
|
imagePainter.translate(0, -1);
|
||||||
imagePainter.setPen(foreGround);
|
imagePainter.setPen(foreGround);
|
||||||
@@ -1018,17 +1020,21 @@ void ManhattanStyle::drawComplexControl(ComplexControl control, const QStyleOpti
|
|||||||
|
|
||||||
// Draw tool button
|
// Draw tool button
|
||||||
QLinearGradient grad(option->rect.topRight(), option->rect.bottomRight());
|
QLinearGradient grad(option->rect.topRight(), option->rect.bottomRight());
|
||||||
grad.setColorAt(0, Qt::transparent);
|
grad.setColorAt(0, QColor(255, 255, 255, 20));
|
||||||
grad.setColorAt(0.4, QColor(255, 255, 255, 30));
|
grad.setColorAt(0.4, QColor(255, 255, 255, 60));
|
||||||
grad.setColorAt(1, Qt::transparent);
|
grad.setColorAt(0.7, QColor(255, 255, 255, 50));
|
||||||
|
grad.setColorAt(1, QColor(255, 255, 255, 40));
|
||||||
painter->setPen(QPen(grad, 0));
|
painter->setPen(QPen(grad, 0));
|
||||||
painter->drawLine(rect.topRight(), rect.bottomRight());
|
painter->drawLine(rect.topRight(), rect.bottomRight());
|
||||||
grad.setColorAt(0, Qt::transparent);
|
grad.setColorAt(0, QColor(0, 0, 0, 20));
|
||||||
grad.setColorAt(0.4, QColor(0, 0, 0, 30));
|
grad.setColorAt(0.4, QColor(0, 0, 0, 70));
|
||||||
grad.setColorAt(1, Qt::transparent);
|
grad.setColorAt(0.7, QColor(0, 0, 0, 70));
|
||||||
|
grad.setColorAt(1, QColor(0, 0, 0, 40));
|
||||||
painter->setPen(QPen(grad, 0));
|
painter->setPen(QPen(grad, 0));
|
||||||
painter->drawLine(rect.topRight() - QPoint(1,0), rect.bottomRight() - QPoint(1,0));
|
painter->drawLine(rect.topRight() - QPoint(1,0), rect.bottomRight() - QPoint(1,0));
|
||||||
drawPrimitive(PE_PanelButtonTool, option, painter, widget);
|
QStyleOption toolbutton = *option;
|
||||||
|
toolbutton.rect.adjust(0, 0, -2, 0);
|
||||||
|
drawPrimitive(PE_PanelButtonTool, &toolbutton, painter, widget);
|
||||||
|
|
||||||
// Draw arrow
|
// Draw arrow
|
||||||
int menuButtonWidth = 12;
|
int menuButtonWidth = 12;
|
||||||
@@ -1042,11 +1048,14 @@ void ManhattanStyle::drawComplexControl(ComplexControl control, const QStyleOpti
|
|||||||
QStyleOption arrowOpt = *option;
|
QStyleOption arrowOpt = *option;
|
||||||
arrowOpt.rect = arrowRect;
|
arrowOpt.rect = arrowRect;
|
||||||
QPalette pal = option->palette;
|
QPalette pal = option->palette;
|
||||||
pal.setBrush(QPalette::All, QPalette::ButtonText, StyleHelper::panelTextColor());
|
if (styleHint(SH_ComboBox_Popup, option, widget)) {
|
||||||
arrowOpt.palette = pal;
|
arrowOpt.rect.translate(0, -3);
|
||||||
|
drawPrimitive(PE_IndicatorArrowUp, &arrowOpt, painter, widget);
|
||||||
|
arrowOpt.rect.translate(0, 6);
|
||||||
drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
|
drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
|
||||||
|
} else {
|
||||||
|
drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
|
||||||
|
}
|
||||||
painter->restore();
|
painter->restore();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -593,8 +593,6 @@ Symbol *CPPEditor::findDefinition(Symbol *symbol)
|
|||||||
{
|
{
|
||||||
if (symbol->isFunction())
|
if (symbol->isFunction())
|
||||||
return 0; // symbol is a function definition.
|
return 0; // symbol is a function definition.
|
||||||
else if (! symbol->type())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
Function *funTy = symbol->type()->asFunctionType();
|
Function *funTy = symbol->type()->asFunctionType();
|
||||||
if (! funTy)
|
if (! funTy)
|
||||||
|
|||||||
@@ -165,6 +165,9 @@ static QString buildHelpId(const FullySpecifiedType &type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (! name)
|
||||||
|
return QString();
|
||||||
|
|
||||||
Overview overview;
|
Overview overview;
|
||||||
overview.setShowArgumentNames(false);
|
overview.setShowArgumentNames(false);
|
||||||
overview.setShowReturnTypes(false);
|
overview.setShowReturnTypes(false);
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ FunctionArgumentWidget::FunctionArgumentWidget()
|
|||||||
setParent(m_popupFrame);
|
setParent(m_popupFrame);
|
||||||
setFocusPolicy(Qt::NoFocus);
|
setFocusPolicy(Qt::NoFocus);
|
||||||
|
|
||||||
QVBoxLayout *layout = new QVBoxLayout();
|
QVBoxLayout *layout = new QVBoxLayout;
|
||||||
layout->addWidget(this);
|
layout->addWidget(this);
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
m_popupFrame->setLayout(layout);
|
m_popupFrame->setLayout(layout);
|
||||||
@@ -578,8 +578,6 @@ bool CppCodeCompletion::completeFunction(FullySpecifiedType exprTy,
|
|||||||
QSet<QString> signatures;
|
QSet<QString> signatures;
|
||||||
foreach (TypeOfExpression::Result p, resolvedTypes) {
|
foreach (TypeOfExpression::Result p, resolvedTypes) {
|
||||||
FullySpecifiedType ty = p.first;
|
FullySpecifiedType ty = p.first;
|
||||||
if (! ty)
|
|
||||||
continue;
|
|
||||||
if (Function *fun = ty->asFunctionType()) {
|
if (Function *fun = ty->asFunctionType()) {
|
||||||
if (TextEditor::CompletionItem item = toCompletionItem(fun)) {
|
if (TextEditor::CompletionItem item = toCompletionItem(fun)) {
|
||||||
QString signature;
|
QString signature;
|
||||||
@@ -602,7 +600,7 @@ bool CppCodeCompletion::completeFunction(FullySpecifiedType exprTy,
|
|||||||
bool CppCodeCompletion::completeMember(const QList<TypeOfExpression::Result> &results,
|
bool CppCodeCompletion::completeMember(const QList<TypeOfExpression::Result> &results,
|
||||||
const LookupContext &context)
|
const LookupContext &context)
|
||||||
{
|
{
|
||||||
if (results.isEmpty() || ! results.first().first)
|
if (results.isEmpty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
TypeOfExpression::Result result = results.first();
|
TypeOfExpression::Result result = results.first();
|
||||||
@@ -898,10 +896,7 @@ bool CppCodeCompletion::completeConstructors(Class *klass)
|
|||||||
|
|
||||||
for (unsigned i = 0; i < klass->memberCount(); ++i) {
|
for (unsigned i = 0; i < klass->memberCount(); ++i) {
|
||||||
Symbol *member = klass->memberAt(i);
|
Symbol *member = klass->memberAt(i);
|
||||||
FullySpecifiedType memberTy = member->type();
|
if (! member->type()->isFunctionType())
|
||||||
if (! memberTy)
|
|
||||||
continue;
|
|
||||||
else if (! memberTy->isFunctionType())
|
|
||||||
continue;
|
continue;
|
||||||
else if (! member->identity())
|
else if (! member->identity())
|
||||||
continue;
|
continue;
|
||||||
@@ -935,12 +930,8 @@ bool CppCodeCompletion::completeQtMethod(CPlusPlus::FullySpecifiedType,
|
|||||||
QSet<QString> signatures;
|
QSet<QString> signatures;
|
||||||
foreach (TypeOfExpression::Result p, results) {
|
foreach (TypeOfExpression::Result p, results) {
|
||||||
FullySpecifiedType ty = p.first;
|
FullySpecifiedType ty = p.first;
|
||||||
if (! ty)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (ReferenceType *refTy = ty->asReferenceType())
|
if (ReferenceType *refTy = ty->asReferenceType())
|
||||||
ty = refTy->elementType();
|
ty = refTy->elementType();
|
||||||
|
|
||||||
if (PointerType *ptrTy = ty->asPointerType())
|
if (PointerType *ptrTy = ty->asPointerType())
|
||||||
ty = ptrTy->elementType();
|
ty = ptrTy->elementType();
|
||||||
else
|
else
|
||||||
@@ -1126,14 +1117,12 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
|
|||||||
|
|
||||||
// If the function takes no arguments, automatically place the closing parenthesis
|
// If the function takes no arguments, automatically place the closing parenthesis
|
||||||
if (function->argumentCount() == 0 || (function->argumentCount() == 1 &&
|
if (function->argumentCount() == 0 || (function->argumentCount() == 1 &&
|
||||||
function->argumentAt(0)->type() &&
|
|
||||||
function->argumentAt(0)->type()->isVoidType())) {
|
function->argumentAt(0)->type()->isVoidType())) {
|
||||||
extraChars += QLatin1Char(')');
|
extraChars += QLatin1Char(')');
|
||||||
|
|
||||||
// If the function doesn't return anything, automatically place the semicolon,
|
// If the function doesn't return anything, automatically place the semicolon,
|
||||||
// unless we're doing a scope completion (then it might be function definition).
|
// unless we're doing a scope completion (then it might be function definition).
|
||||||
FullySpecifiedType retTy = function->returnType();
|
if (function->returnType()->isVoidType() && m_completionOperator != T_COLON_COLON) {
|
||||||
if (retTy && retTy->isVoidType() && m_completionOperator != T_COLON_COLON) {
|
|
||||||
extraChars += QLatin1Char(';');
|
extraChars += QLatin1Char(';');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QMutexLocker>
|
#include <QtCore/QMutexLocker>
|
||||||
#include <QtCore/QTime>
|
#include <QtCore/QTime>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
|
||||||
using namespace CppTools;
|
using namespace CppTools;
|
||||||
using namespace CppTools::Internal;
|
using namespace CppTools::Internal;
|
||||||
@@ -454,6 +455,12 @@ CppModelManager::CppModelManager(QObject *parent)
|
|||||||
ProjectExplorer::SessionManager *session = m_projectExplorer->session();
|
ProjectExplorer::SessionManager *session = m_projectExplorer->session();
|
||||||
QTC_ASSERT(session, return);
|
QTC_ASSERT(session, return);
|
||||||
|
|
||||||
|
m_updateEditorSelectionsTimer = new QTimer(this);
|
||||||
|
m_updateEditorSelectionsTimer->setInterval(500);
|
||||||
|
m_updateEditorSelectionsTimer->setSingleShot(true);
|
||||||
|
connect(m_updateEditorSelectionsTimer, SIGNAL(timeout()),
|
||||||
|
this, SLOT(updateEditorSelections()));
|
||||||
|
|
||||||
connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
|
connect(session, SIGNAL(projectAdded(ProjectExplorer::Project*)),
|
||||||
this, SLOT(onProjectAdded(ProjectExplorer::Project*)));
|
this, SLOT(onProjectAdded(ProjectExplorer::Project*)));
|
||||||
|
|
||||||
@@ -717,8 +724,8 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
|||||||
continue;
|
continue;
|
||||||
else if (lines.contains(m.line()))
|
else if (lines.contains(m.line()))
|
||||||
continue;
|
continue;
|
||||||
else if (lines.size() == MAX_SELECTION_COUNT)
|
//else if (lines.size() == MAX_SELECTION_COUNT)
|
||||||
break; // we're done.
|
//break; // we're done.
|
||||||
|
|
||||||
lines.insert(m.line());
|
lines.insert(m.line());
|
||||||
|
|
||||||
@@ -740,12 +747,42 @@ void CppModelManager::onDocumentUpdated(Document::Ptr doc)
|
|||||||
sel.cursor = c;
|
sel.cursor = c;
|
||||||
selections.append(sel);
|
selections.append(sel);
|
||||||
}
|
}
|
||||||
ed->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection, selections);
|
|
||||||
|
QList<Editor> todo;
|
||||||
|
foreach (Editor e, todo) {
|
||||||
|
if (e.widget != ed)
|
||||||
|
todo.append(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Editor e;
|
||||||
|
e.widget = ed;
|
||||||
|
e.selections = selections;
|
||||||
|
todo.append(e);
|
||||||
|
m_todo = todo;
|
||||||
|
postEditorUpdate();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CppModelManager::postEditorUpdate()
|
||||||
|
{
|
||||||
|
m_updateEditorSelectionsTimer->start(500);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppModelManager::updateEditorSelections()
|
||||||
|
{
|
||||||
|
foreach (Editor ed, m_todo) {
|
||||||
|
if (! ed.widget)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ed.widget->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection,
|
||||||
|
ed.selections);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_todo.clear();
|
||||||
|
}
|
||||||
|
|
||||||
void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
|
void CppModelManager::onProjectAdded(ProjectExplorer::Project *)
|
||||||
{
|
{
|
||||||
QMutexLocker locker(&mutex);
|
QMutexLocker locker(&mutex);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
#include <QMap>
|
#include <QMap>
|
||||||
#include <QFutureInterface>
|
#include <QFutureInterface>
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QTextEdit>
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class ICore;
|
class ICore;
|
||||||
@@ -49,6 +51,7 @@ class IEditor;
|
|||||||
|
|
||||||
namespace TextEditor {
|
namespace TextEditor {
|
||||||
class ITextEditor;
|
class ITextEditor;
|
||||||
|
class BaseTextEditor;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
@@ -86,6 +89,9 @@ public:
|
|||||||
|
|
||||||
void emitDocumentUpdated(CPlusPlus::Document::Ptr doc);
|
void emitDocumentUpdated(CPlusPlus::Document::Ptr doc);
|
||||||
|
|
||||||
|
void stopEditorSelectionsUpdate()
|
||||||
|
{ m_updateEditorSelectionsTimer->stop(); }
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void projectPathChanged(const QString &projectPath);
|
void projectPathChanged(const QString &projectPath);
|
||||||
|
|
||||||
@@ -102,6 +108,8 @@ private Q_SLOTS:
|
|||||||
void onAboutToRemoveProject(ProjectExplorer::Project *project);
|
void onAboutToRemoveProject(ProjectExplorer::Project *project);
|
||||||
void onSessionUnloaded();
|
void onSessionUnloaded();
|
||||||
void onProjectAdded(ProjectExplorer::Project *project);
|
void onProjectAdded(ProjectExplorer::Project *project);
|
||||||
|
void postEditorUpdate();
|
||||||
|
void updateEditorSelections();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QMap<QString, QByteArray> buildWorkingCopyList();
|
QMap<QString, QByteArray> buildWorkingCopyList();
|
||||||
@@ -163,6 +171,15 @@ private:
|
|||||||
enum {
|
enum {
|
||||||
MAX_SELECTION_COUNT = 5
|
MAX_SELECTION_COUNT = 5
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Editor {
|
||||||
|
QPointer<TextEditor::BaseTextEditor> widget;
|
||||||
|
QList<QTextEdit::ExtraSelection> selections;
|
||||||
|
};
|
||||||
|
|
||||||
|
QList<Editor> m_todo;
|
||||||
|
|
||||||
|
QTimer *m_updateEditorSelectionsTimer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
#include "cppmodelmanager.h"
|
#include "cppmodelmanager.h"
|
||||||
|
|
||||||
#include <texteditor/itexteditor.h>
|
#include <texteditor/itexteditor.h>
|
||||||
|
#include <texteditor/basetexteditor.h>
|
||||||
|
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
@@ -68,12 +69,14 @@ void CppEditorSupport::setTextEditor(TextEditor::ITextEditor *textEditor)
|
|||||||
updateDocument();
|
updateDocument();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString CppEditorSupport::contents() const
|
QString CppEditorSupport::contents()
|
||||||
{
|
{
|
||||||
if (! _textEditor)
|
if (! _textEditor)
|
||||||
return QString();
|
return QString();
|
||||||
|
else if (! _cachedContents.isEmpty())
|
||||||
|
_cachedContents = _textEditor->contents();
|
||||||
|
|
||||||
return _textEditor->contents();
|
return _cachedContents;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CppEditorSupport::updateDocumentInterval() const
|
int CppEditorSupport::updateDocumentInterval() const
|
||||||
@@ -83,7 +86,20 @@ void CppEditorSupport::setUpdateDocumentInterval(int updateDocumentInterval)
|
|||||||
{ _updateDocumentInterval = updateDocumentInterval; }
|
{ _updateDocumentInterval = updateDocumentInterval; }
|
||||||
|
|
||||||
void CppEditorSupport::updateDocument()
|
void CppEditorSupport::updateDocument()
|
||||||
{ _updateDocumentTimer->start(_updateDocumentInterval); }
|
{
|
||||||
|
if (TextEditor::BaseTextEditor *edit = qobject_cast<TextEditor::BaseTextEditor*>(_textEditor->widget())) {
|
||||||
|
const QList<QTextEdit::ExtraSelection> selections =
|
||||||
|
edit->extraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection);
|
||||||
|
|
||||||
|
if (! selections.isEmpty())
|
||||||
|
edit->setExtraSelections(TextEditor::BaseTextEditor::CodeWarningsSelection,
|
||||||
|
QList<QTextEdit::ExtraSelection>());
|
||||||
|
|
||||||
|
_modelManager->stopEditorSelectionsUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateDocumentTimer->start(_updateDocumentInterval);
|
||||||
|
}
|
||||||
|
|
||||||
void CppEditorSupport::updateDocumentNow()
|
void CppEditorSupport::updateDocumentNow()
|
||||||
{
|
{
|
||||||
@@ -91,7 +107,9 @@ void CppEditorSupport::updateDocumentNow()
|
|||||||
_updateDocumentTimer->start(_updateDocumentInterval);
|
_updateDocumentTimer->start(_updateDocumentInterval);
|
||||||
} else {
|
} else {
|
||||||
_updateDocumentTimer->stop();
|
_updateDocumentTimer->stop();
|
||||||
|
|
||||||
QStringList sourceFiles(_textEditor->file()->fileName());
|
QStringList sourceFiles(_textEditor->file()->fileName());
|
||||||
|
_cachedContents = _textEditor->contents();
|
||||||
_documentParser = _modelManager->refreshSourceFiles(sourceFiles);
|
_documentParser = _modelManager->refreshSourceFiles(sourceFiles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public:
|
|||||||
int updateDocumentInterval() const;
|
int updateDocumentInterval() const;
|
||||||
void setUpdateDocumentInterval(int updateDocumentInterval);
|
void setUpdateDocumentInterval(int updateDocumentInterval);
|
||||||
|
|
||||||
QString contents() const;
|
QString contents();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void updateDocument();
|
void updateDocument();
|
||||||
@@ -79,6 +79,7 @@ private:
|
|||||||
QTimer *_updateDocumentTimer;
|
QTimer *_updateDocumentTimer;
|
||||||
int _updateDocumentInterval;
|
int _updateDocumentInterval;
|
||||||
QFuture<void> _documentParser;
|
QFuture<void> _documentParser;
|
||||||
|
QString _cachedContents;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
@@ -2225,56 +2225,79 @@ unsigned NestedNameSpecifierAST::lastToken() const
|
|||||||
return class_or_namespace_name->lastToken();
|
return class_or_namespace_name->lastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
NewDeclaratorAST *NewDeclaratorAST::clone(MemoryPool *pool) const
|
NewPlacementAST *NewPlacementAST::clone(MemoryPool *pool) const
|
||||||
{
|
{
|
||||||
NewDeclaratorAST *ast = new (pool) NewDeclaratorAST;
|
NewPlacementAST *ast = new (pool) NewPlacementAST;
|
||||||
if (ptr_operators)
|
ast->lparen_token = lparen_token;
|
||||||
ast->ptr_operators = ptr_operators->clone(pool);
|
if (expression_list)
|
||||||
if (declarator)
|
ast->expression_list = expression_list->clone(pool);
|
||||||
ast->declarator = declarator->clone(pool);
|
ast->rparen_token = rparen_token;
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NewDeclaratorAST::accept0(ASTVisitor *visitor)
|
void NewPlacementAST::accept0(ASTVisitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
for (PtrOperatorAST *ptr_op = ptr_operators; ptr_op;
|
for (ExpressionListAST *it = expression_list; it; it = it->next) {
|
||||||
ptr_op = static_cast<PtrOperatorAST *>(ptr_op->next)) {
|
accept(it->expression, visitor);
|
||||||
accept(ptr_op, visitor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
accept(declarator, visitor);
|
|
||||||
}
|
}
|
||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NewDeclaratorAST::firstToken() const
|
unsigned NewPlacementAST::firstToken() const
|
||||||
{
|
{
|
||||||
return ptr_operators->firstToken();
|
return lparen_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned NewDeclaratorAST::lastToken() const
|
unsigned NewPlacementAST::lastToken() const
|
||||||
{
|
{
|
||||||
if (declarator)
|
return rparen_token + 1;
|
||||||
return declarator->lastToken();
|
}
|
||||||
|
|
||||||
for (PtrOperatorAST *it = ptr_operators; it; it = it->next) {
|
NewArrayDeclaratorAST *NewArrayDeclaratorAST::clone(MemoryPool *pool) const
|
||||||
if (! it->next)
|
{
|
||||||
return it->lastToken();
|
NewArrayDeclaratorAST *ast = new (pool) NewArrayDeclaratorAST;
|
||||||
|
ast->lbracket_token = lbracket_token;
|
||||||
|
if (expression)
|
||||||
|
ast->expression = expression->clone(pool);
|
||||||
|
ast->rbracket_token = rbracket_token;
|
||||||
|
if (next)
|
||||||
|
ast->next = next->clone(pool);
|
||||||
|
return ast;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NewArrayDeclaratorAST::accept0(ASTVisitor *visitor)
|
||||||
|
{
|
||||||
|
if (visitor->visit(this)) {
|
||||||
|
accept(expression, visitor);
|
||||||
|
accept(next, visitor);
|
||||||
}
|
}
|
||||||
|
visitor->endVisit(this);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
unsigned NewArrayDeclaratorAST::firstToken() const
|
||||||
|
{
|
||||||
|
return lbracket_token;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned NewArrayDeclaratorAST::lastToken() const
|
||||||
|
{
|
||||||
|
return rbracket_token + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewExpressionAST *NewExpressionAST::clone(MemoryPool *pool) const
|
NewExpressionAST *NewExpressionAST::clone(MemoryPool *pool) const
|
||||||
{
|
{
|
||||||
NewExpressionAST *ast = new (pool) NewExpressionAST;
|
NewExpressionAST *ast = new (pool) NewExpressionAST;
|
||||||
|
|
||||||
ast->scope_token = scope_token;
|
ast->scope_token = scope_token;
|
||||||
ast->new_token = new_token;
|
ast->new_token = new_token;
|
||||||
if (expression)
|
if (new_placement)
|
||||||
ast->expression = expression->clone(pool);
|
ast->new_placement = new_placement->clone(pool);
|
||||||
|
ast->lparen_token = lparen_token;
|
||||||
if (type_id)
|
if (type_id)
|
||||||
ast->type_id = type_id->clone(pool);
|
ast->type_id = type_id->clone(pool);
|
||||||
|
ast->rparen_token = rparen_token;
|
||||||
if (new_type_id)
|
if (new_type_id)
|
||||||
ast->new_type_id = new_type_id->clone(pool);
|
ast->new_type_id = new_type_id->clone(pool);
|
||||||
if (new_initializer)
|
if (new_initializer)
|
||||||
@@ -2285,7 +2308,7 @@ NewExpressionAST *NewExpressionAST::clone(MemoryPool *pool) const
|
|||||||
void NewExpressionAST::accept0(ASTVisitor *visitor)
|
void NewExpressionAST::accept0(ASTVisitor *visitor)
|
||||||
{
|
{
|
||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
accept(expression, visitor);
|
accept(new_placement, visitor);
|
||||||
accept(type_id, visitor);
|
accept(type_id, visitor);
|
||||||
accept(new_type_id, visitor);
|
accept(new_type_id, visitor);
|
||||||
accept(new_initializer, visitor);
|
accept(new_initializer, visitor);
|
||||||
@@ -2302,15 +2325,8 @@ unsigned NewExpressionAST::firstToken() const
|
|||||||
|
|
||||||
unsigned NewExpressionAST::lastToken() const
|
unsigned NewExpressionAST::lastToken() const
|
||||||
{
|
{
|
||||||
if (new_initializer)
|
// ### FIXME
|
||||||
return new_initializer->lastToken();
|
if (new_token)
|
||||||
else if (new_type_id)
|
|
||||||
return new_type_id->lastToken();
|
|
||||||
else if (type_id)
|
|
||||||
return type_id->lastToken();
|
|
||||||
else if (expression)
|
|
||||||
return expression->lastToken();
|
|
||||||
else if (new_token)
|
|
||||||
return new_token + 1;
|
return new_token + 1;
|
||||||
else if (scope_token)
|
else if (scope_token)
|
||||||
return scope_token + 1;
|
return scope_token + 1;
|
||||||
@@ -2363,12 +2379,13 @@ TypeIdAST *TypeIdAST::clone(MemoryPool *pool) const
|
|||||||
NewTypeIdAST *NewTypeIdAST::clone(MemoryPool *pool) const
|
NewTypeIdAST *NewTypeIdAST::clone(MemoryPool *pool) const
|
||||||
{
|
{
|
||||||
NewTypeIdAST *ast = new (pool) NewTypeIdAST;
|
NewTypeIdAST *ast = new (pool) NewTypeIdAST;
|
||||||
|
|
||||||
if (type_specifier)
|
if (type_specifier)
|
||||||
ast->type_specifier = type_specifier->clone(pool);
|
ast->type_specifier = type_specifier->clone(pool);
|
||||||
if (new_initializer)
|
if (ptr_operators)
|
||||||
ast->new_initializer = new_initializer->clone(pool);
|
ast->ptr_operators = ptr_operators->clone(pool);
|
||||||
if (new_declarator)
|
if (new_array_declarators)
|
||||||
ast->new_declarator = new_declarator->clone(pool);
|
ast->new_array_declarators = new_array_declarators->clone(pool);
|
||||||
return ast;
|
return ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2377,8 +2394,13 @@ void NewTypeIdAST::accept0(ASTVisitor *visitor)
|
|||||||
if (visitor->visit(this)) {
|
if (visitor->visit(this)) {
|
||||||
for (SpecifierAST *spec = type_specifier; spec; spec = spec->next)
|
for (SpecifierAST *spec = type_specifier; spec; spec = spec->next)
|
||||||
accept(spec, visitor);
|
accept(spec, visitor);
|
||||||
accept(new_initializer, visitor);
|
|
||||||
accept(new_declarator, visitor);
|
for (PtrOperatorAST *it = ptr_operators; it; it = it->next)
|
||||||
|
accept(it, visitor);
|
||||||
|
|
||||||
|
for (NewArrayDeclaratorAST *it = new_array_declarators; it; it = it->next)
|
||||||
|
accept(it, visitor);
|
||||||
|
|
||||||
}
|
}
|
||||||
visitor->endVisit(this);
|
visitor->endVisit(this);
|
||||||
}
|
}
|
||||||
@@ -2390,15 +2412,19 @@ unsigned NewTypeIdAST::firstToken() const
|
|||||||
|
|
||||||
unsigned NewTypeIdAST::lastToken() const
|
unsigned NewTypeIdAST::lastToken() const
|
||||||
{
|
{
|
||||||
if (new_declarator)
|
for (NewArrayDeclaratorAST *it = new_array_declarators; it; it = it->next) {
|
||||||
return new_declarator->lastToken();
|
|
||||||
else if (new_initializer)
|
|
||||||
return new_initializer->lastToken();
|
|
||||||
for (SpecifierAST *it = type_specifier; it; it = it->next) {
|
|
||||||
if (! it->next)
|
if (! it->next)
|
||||||
return it->lastToken();
|
return it->lastToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (PtrOperatorAST *it = ptr_operators; it; it = it->next) {
|
||||||
|
if (it->next)
|
||||||
|
return it->lastToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type_specifier)
|
||||||
|
return type_specifier->lastToken();
|
||||||
|
|
||||||
// ### assert?
|
// ### assert?
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,8 @@ public:
|
|||||||
virtual NestedDeclaratorAST *asNestedDeclarator() { return 0; }
|
virtual NestedDeclaratorAST *asNestedDeclarator() { return 0; }
|
||||||
virtual NestedExpressionAST *asNestedExpression() { return 0; }
|
virtual NestedExpressionAST *asNestedExpression() { return 0; }
|
||||||
virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return 0; }
|
virtual NestedNameSpecifierAST *asNestedNameSpecifier() { return 0; }
|
||||||
virtual NewDeclaratorAST *asNewDeclarator() { return 0; }
|
virtual NewPlacementAST *asNewPlacement() { return 0; }
|
||||||
|
virtual NewArrayDeclaratorAST *asNewArrayDeclarator() { return 0; }
|
||||||
virtual NewExpressionAST *asNewExpression() { return 0; }
|
virtual NewExpressionAST *asNewExpression() { return 0; }
|
||||||
virtual NewInitializerAST *asNewInitializer() { return 0; }
|
virtual NewInitializerAST *asNewInitializer() { return 0; }
|
||||||
virtual NewTypeIdAST *asNewTypeId() { return 0; }
|
virtual NewTypeIdAST *asNewTypeId() { return 0; }
|
||||||
@@ -1440,20 +1441,42 @@ protected:
|
|||||||
virtual void accept0(ASTVisitor *visitor);
|
virtual void accept0(ASTVisitor *visitor);
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPLUSPLUS_EXPORT NewDeclaratorAST: public AST
|
class CPLUSPLUS_EXPORT NewPlacementAST: public AST
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PtrOperatorAST *ptr_operators;
|
unsigned lparen_token;
|
||||||
NewDeclaratorAST *declarator;
|
ExpressionListAST *expression_list;
|
||||||
|
unsigned rparen_token;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual NewDeclaratorAST *asNewDeclarator()
|
virtual NewPlacementAST *asNewPlacement()
|
||||||
{ return this; }
|
{ return this; }
|
||||||
|
|
||||||
virtual unsigned firstToken() const;
|
virtual unsigned firstToken() const;
|
||||||
virtual unsigned lastToken() const;
|
virtual unsigned lastToken() const;
|
||||||
|
|
||||||
virtual NewDeclaratorAST *clone(MemoryPool *pool) const;
|
virtual NewPlacementAST *clone(MemoryPool *pool) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void accept0(ASTVisitor *visitor);
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPLUSPLUS_EXPORT NewArrayDeclaratorAST: public AST
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
unsigned lbracket_token;
|
||||||
|
ExpressionAST *expression;
|
||||||
|
unsigned rbracket_token;
|
||||||
|
NewArrayDeclaratorAST *next;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual NewArrayDeclaratorAST *asNewArrayDeclarator()
|
||||||
|
{ return this; }
|
||||||
|
|
||||||
|
virtual unsigned firstToken() const;
|
||||||
|
virtual unsigned lastToken() const;
|
||||||
|
|
||||||
|
virtual NewArrayDeclaratorAST *clone(MemoryPool *pool) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void accept0(ASTVisitor *visitor);
|
virtual void accept0(ASTVisitor *visitor);
|
||||||
@@ -1464,9 +1487,14 @@ class CPLUSPLUS_EXPORT NewExpressionAST: public ExpressionAST
|
|||||||
public:
|
public:
|
||||||
unsigned scope_token;
|
unsigned scope_token;
|
||||||
unsigned new_token;
|
unsigned new_token;
|
||||||
ExpressionAST *expression;
|
NewPlacementAST *new_placement;
|
||||||
|
|
||||||
|
unsigned lparen_token;
|
||||||
ExpressionAST *type_id;
|
ExpressionAST *type_id;
|
||||||
|
unsigned rparen_token;
|
||||||
|
|
||||||
NewTypeIdAST *new_type_id;
|
NewTypeIdAST *new_type_id;
|
||||||
|
|
||||||
NewInitializerAST *new_initializer;
|
NewInitializerAST *new_initializer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -1506,8 +1534,8 @@ class CPLUSPLUS_EXPORT NewTypeIdAST: public AST
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SpecifierAST *type_specifier;
|
SpecifierAST *type_specifier;
|
||||||
NewInitializerAST *new_initializer;
|
PtrOperatorAST *ptr_operators;
|
||||||
NewDeclaratorAST *new_declarator;
|
NewArrayDeclaratorAST *new_array_declarators;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual NewTypeIdAST *asNewTypeId()
|
virtual NewTypeIdAST *asNewTypeId()
|
||||||
|
|||||||
@@ -144,7 +144,8 @@ public:
|
|||||||
virtual bool visit(NestedDeclaratorAST *) { return true; }
|
virtual bool visit(NestedDeclaratorAST *) { return true; }
|
||||||
virtual bool visit(NestedExpressionAST *) { return true; }
|
virtual bool visit(NestedExpressionAST *) { return true; }
|
||||||
virtual bool visit(NestedNameSpecifierAST *) { return true; }
|
virtual bool visit(NestedNameSpecifierAST *) { return true; }
|
||||||
virtual bool visit(NewDeclaratorAST *) { return true; }
|
virtual bool visit(NewPlacementAST *) { return true; }
|
||||||
|
virtual bool visit(NewArrayDeclaratorAST *) { return true; }
|
||||||
virtual bool visit(NewExpressionAST *) { return true; }
|
virtual bool visit(NewExpressionAST *) { return true; }
|
||||||
virtual bool visit(NewInitializerAST *) { return true; }
|
virtual bool visit(NewInitializerAST *) { return true; }
|
||||||
virtual bool visit(NewTypeIdAST *) { return true; }
|
virtual bool visit(NewTypeIdAST *) { return true; }
|
||||||
@@ -248,7 +249,8 @@ public:
|
|||||||
virtual void endVisit(NestedDeclaratorAST *) { }
|
virtual void endVisit(NestedDeclaratorAST *) { }
|
||||||
virtual void endVisit(NestedExpressionAST *) { }
|
virtual void endVisit(NestedExpressionAST *) { }
|
||||||
virtual void endVisit(NestedNameSpecifierAST *) { }
|
virtual void endVisit(NestedNameSpecifierAST *) { }
|
||||||
virtual void endVisit(NewDeclaratorAST *) { }
|
virtual void endVisit(NewPlacementAST *) { }
|
||||||
|
virtual void endVisit(NewArrayDeclaratorAST *) { }
|
||||||
virtual void endVisit(NewExpressionAST *) { }
|
virtual void endVisit(NewExpressionAST *) { }
|
||||||
virtual void endVisit(NewInitializerAST *) { }
|
virtual void endVisit(NewInitializerAST *) { }
|
||||||
virtual void endVisit(NewTypeIdAST *) { }
|
virtual void endVisit(NewTypeIdAST *) { }
|
||||||
|
|||||||
@@ -121,8 +121,9 @@ class NamespaceAliasDefinitionAST;
|
|||||||
class NestedDeclaratorAST;
|
class NestedDeclaratorAST;
|
||||||
class NestedExpressionAST;
|
class NestedExpressionAST;
|
||||||
class NestedNameSpecifierAST;
|
class NestedNameSpecifierAST;
|
||||||
class NewDeclaratorAST;
|
class NewArrayDeclaratorAST;
|
||||||
class NewExpressionAST;
|
class NewExpressionAST;
|
||||||
|
class NewPlacementAST;
|
||||||
class NewInitializerAST;
|
class NewInitializerAST;
|
||||||
class NewTypeIdAST;
|
class NewTypeIdAST;
|
||||||
class NumericLiteralAST;
|
class NumericLiteralAST;
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ class QualifiedNameId;
|
|||||||
class FullySpecifiedType;
|
class FullySpecifiedType;
|
||||||
class TypeVisitor;
|
class TypeVisitor;
|
||||||
class Type;
|
class Type;
|
||||||
|
class UndefinedType;
|
||||||
class VoidType;
|
class VoidType;
|
||||||
class IntegerType;
|
class IntegerType;
|
||||||
class FloatType;
|
class FloatType;
|
||||||
|
|||||||
@@ -214,8 +214,9 @@ bool CheckExpression::visit(TemplateIdAST *ast)
|
|||||||
|
|
||||||
bool CheckExpression::visit(NewExpressionAST *ast)
|
bool CheckExpression::visit(NewExpressionAST *ast)
|
||||||
{
|
{
|
||||||
FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
|
// ### FIXME
|
||||||
FullySpecifiedType typeIdTy = semantic()->check(ast->type_id, _scope);
|
//FullySpecifiedType exprTy = semantic()->check(ast->expression, _scope);
|
||||||
|
//FullySpecifiedType typeIdTy = semantic()->check(ast->type_id, _scope);
|
||||||
// ### process new-typeid
|
// ### process new-typeid
|
||||||
// ### process new-initializer
|
// ### process new-initializer
|
||||||
return false;
|
return false;
|
||||||
@@ -319,8 +320,8 @@ bool CheckExpression::visit(QtMethodAST *ast)
|
|||||||
Scope dummy;
|
Scope dummy;
|
||||||
FullySpecifiedType methTy = semantic()->check(ast->declarator, FullySpecifiedType(),
|
FullySpecifiedType methTy = semantic()->check(ast->declarator, FullySpecifiedType(),
|
||||||
&dummy, &name);
|
&dummy, &name);
|
||||||
Function *fty = 0;
|
Function *fty = methTy->asFunctionType();
|
||||||
if (! methTy || 0 == (fty = methTy->asFunctionType()))
|
if (! fty)
|
||||||
translationUnit()->warning(ast->firstToken(), "expected a function declarator");
|
translationUnit()->warning(ast->firstToken(), "expected a function declarator");
|
||||||
else {
|
else {
|
||||||
for (unsigned i = 0; i < fty->argumentCount(); ++i) {
|
for (unsigned i = 0; i < fty->argumentCount(); ++i) {
|
||||||
|
|||||||
@@ -200,30 +200,30 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_CHAR:
|
case T_CHAR:
|
||||||
if (_fullySpecifiedType.type())
|
if (_fullySpecifiedType)
|
||||||
translationUnit()->error(ast->specifier_token,
|
translationUnit()->error(ast->specifier_token,
|
||||||
"duplicate data type in declaration");
|
"duplicate data type in declaration");
|
||||||
_fullySpecifiedType.setType(control()->integerType(IntegerType::Char));
|
_fullySpecifiedType.setType(control()->integerType(IntegerType::Char));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_WCHAR_T:
|
case T_WCHAR_T:
|
||||||
if (_fullySpecifiedType.type())
|
if (_fullySpecifiedType)
|
||||||
translationUnit()->error(ast->specifier_token,
|
translationUnit()->error(ast->specifier_token,
|
||||||
"duplicate data type in declaration");
|
"duplicate data type in declaration");
|
||||||
_fullySpecifiedType.setType(control()->integerType(IntegerType::WideChar));
|
_fullySpecifiedType.setType(control()->integerType(IntegerType::WideChar));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_BOOL:
|
case T_BOOL:
|
||||||
if (_fullySpecifiedType.type())
|
if (_fullySpecifiedType)
|
||||||
translationUnit()->error(ast->specifier_token,
|
translationUnit()->error(ast->specifier_token,
|
||||||
"duplicate data type in declaration");
|
"duplicate data type in declaration");
|
||||||
_fullySpecifiedType.setType(control()->integerType(IntegerType::Bool));
|
_fullySpecifiedType.setType(control()->integerType(IntegerType::Bool));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_SHORT:
|
case T_SHORT:
|
||||||
if (Type *tp = _fullySpecifiedType.type()) {
|
if (_fullySpecifiedType) {
|
||||||
IntegerType *intType = control()->integerType(IntegerType::Int);
|
IntegerType *intType = control()->integerType(IntegerType::Int);
|
||||||
if (tp != intType)
|
if (_fullySpecifiedType.type() != intType)
|
||||||
translationUnit()->error(ast->specifier_token,
|
translationUnit()->error(ast->specifier_token,
|
||||||
"duplicate data type in declaration");
|
"duplicate data type in declaration");
|
||||||
}
|
}
|
||||||
@@ -231,7 +231,8 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_INT:
|
case T_INT:
|
||||||
if (Type *tp = _fullySpecifiedType.type()) {
|
if (_fullySpecifiedType) {
|
||||||
|
Type *tp = _fullySpecifiedType.type();
|
||||||
IntegerType *shortType = control()->integerType(IntegerType::Short);
|
IntegerType *shortType = control()->integerType(IntegerType::Short);
|
||||||
IntegerType *longType = control()->integerType(IntegerType::Long);
|
IntegerType *longType = control()->integerType(IntegerType::Long);
|
||||||
IntegerType *longLongType = control()->integerType(IntegerType::LongLong);
|
IntegerType *longLongType = control()->integerType(IntegerType::LongLong);
|
||||||
@@ -244,7 +245,8 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_LONG:
|
case T_LONG:
|
||||||
if (Type *tp = _fullySpecifiedType.type()) {
|
if (_fullySpecifiedType) {
|
||||||
|
Type *tp = _fullySpecifiedType.type();
|
||||||
IntegerType *intType = control()->integerType(IntegerType::Int);
|
IntegerType *intType = control()->integerType(IntegerType::Int);
|
||||||
IntegerType *longType = control()->integerType(IntegerType::Long);
|
IntegerType *longType = control()->integerType(IntegerType::Long);
|
||||||
FloatType *doubleType = control()->floatType(FloatType::Double);
|
FloatType *doubleType = control()->floatType(FloatType::Double);
|
||||||
@@ -263,16 +265,16 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_FLOAT:
|
case T_FLOAT:
|
||||||
if (_fullySpecifiedType.type())
|
if (_fullySpecifiedType)
|
||||||
translationUnit()->error(ast->specifier_token,
|
translationUnit()->error(ast->specifier_token,
|
||||||
"duplicate data type in declaration");
|
"duplicate data type in declaration");
|
||||||
_fullySpecifiedType.setType(control()->floatType(FloatType::Float));
|
_fullySpecifiedType.setType(control()->floatType(FloatType::Float));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_DOUBLE:
|
case T_DOUBLE:
|
||||||
if (Type *tp = _fullySpecifiedType.type()) {
|
if (_fullySpecifiedType) {
|
||||||
IntegerType *longType = control()->integerType(IntegerType::Long);
|
IntegerType *longType = control()->integerType(IntegerType::Long);
|
||||||
if (tp == longType) {
|
if (_fullySpecifiedType.type() == longType) {
|
||||||
_fullySpecifiedType.setType(control()->floatType(FloatType::LongDouble));
|
_fullySpecifiedType.setType(control()->floatType(FloatType::LongDouble));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -283,7 +285,7 @@ bool CheckSpecifier::visit(SimpleSpecifierAST *ast)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case T_VOID:
|
case T_VOID:
|
||||||
if (_fullySpecifiedType.type())
|
if (_fullySpecifiedType)
|
||||||
translationUnit()->error(ast->specifier_token,
|
translationUnit()->error(ast->specifier_token,
|
||||||
"duplicate data type in declaration");
|
"duplicate data type in declaration");
|
||||||
_fullySpecifiedType.setType(control()->voidType());
|
_fullySpecifiedType.setType(control()->voidType());
|
||||||
|
|||||||
@@ -61,6 +61,23 @@
|
|||||||
CPLUSPLUS_BEGIN_HEADER
|
CPLUSPLUS_BEGIN_HEADER
|
||||||
CPLUSPLUS_BEGIN_NAMESPACE
|
CPLUSPLUS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
|
class CPLUSPLUS_EXPORT UndefinedType : public Type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static UndefinedType *instance()
|
||||||
|
{
|
||||||
|
static UndefinedType t;
|
||||||
|
return &t;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool isEqualTo(const Type *other) const
|
||||||
|
{ return this == other; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void accept0(TypeVisitor *)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
class CPLUSPLUS_EXPORT VoidType: public Type
|
class CPLUSPLUS_EXPORT VoidType: public Type
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -52,18 +52,22 @@
|
|||||||
|
|
||||||
#include "FullySpecifiedType.h"
|
#include "FullySpecifiedType.h"
|
||||||
#include "Type.h"
|
#include "Type.h"
|
||||||
|
#include "CoreTypes.h"
|
||||||
|
|
||||||
CPLUSPLUS_BEGIN_NAMESPACE
|
CPLUSPLUS_BEGIN_NAMESPACE
|
||||||
|
|
||||||
FullySpecifiedType::FullySpecifiedType(Type *type) :
|
FullySpecifiedType::FullySpecifiedType(Type *type) :
|
||||||
_type(type), _flags(0)
|
_type(type), _flags(0)
|
||||||
{ }
|
{
|
||||||
|
if (! type)
|
||||||
|
_type = UndefinedType::instance();
|
||||||
|
}
|
||||||
|
|
||||||
FullySpecifiedType::~FullySpecifiedType()
|
FullySpecifiedType::~FullySpecifiedType()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
bool FullySpecifiedType::isValid() const
|
bool FullySpecifiedType::isValid() const
|
||||||
{ return _type != 0; }
|
{ return _type != UndefinedType::instance(); }
|
||||||
|
|
||||||
Type *FullySpecifiedType::type() const
|
Type *FullySpecifiedType::type() const
|
||||||
{ return _type; }
|
{ return _type; }
|
||||||
@@ -177,7 +181,7 @@ Type &FullySpecifiedType::operator*()
|
|||||||
{ return *_type; }
|
{ return *_type; }
|
||||||
|
|
||||||
FullySpecifiedType::operator bool() const
|
FullySpecifiedType::operator bool() const
|
||||||
{ return _type != 0; }
|
{ return _type != UndefinedType::instance(); }
|
||||||
|
|
||||||
const Type &FullySpecifiedType::operator*() const
|
const Type &FullySpecifiedType::operator*() const
|
||||||
{ return *_type; }
|
{ return *_type; }
|
||||||
|
|||||||
@@ -3104,37 +3104,91 @@ bool Parser::parseUnaryExpression(ExpressionAST *&node)
|
|||||||
return parsePostfixExpression(node);
|
return parsePostfixExpression(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new-placement ::= T_LPAREN expression-list T_RPAREN
|
||||||
|
bool Parser::parseNewPlacement(NewPlacementAST *&node)
|
||||||
|
{
|
||||||
|
if (LA() == T_LPAREN) {
|
||||||
|
unsigned lparen_token = consumeToken();
|
||||||
|
ExpressionListAST *expression_list = 0;
|
||||||
|
if (parseExpressionList(expression_list) && expression_list && LA() == T_RPAREN) {
|
||||||
|
unsigned rparen_token = consumeToken();
|
||||||
|
NewPlacementAST *ast = new (_pool) NewPlacementAST;
|
||||||
|
ast->lparen_token = lparen_token;
|
||||||
|
ast->expression_list = expression_list;
|
||||||
|
ast->rparen_token = rparen_token;
|
||||||
|
node = ast;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
|
||||||
|
// new-type-id new-initializer.opt
|
||||||
|
// new-expression ::= T_COLON_COLON? T_NEW new-placement.opt
|
||||||
|
// T_LPAREN type-id T_RPAREN new-initializer.opt
|
||||||
bool Parser::parseNewExpression(ExpressionAST *&node)
|
bool Parser::parseNewExpression(ExpressionAST *&node)
|
||||||
{
|
{
|
||||||
if (LA() == T_NEW || (LA() == T_COLON_COLON && LA(2) == T_NEW)) {
|
if (! (LA() == T_NEW || (LA() == T_COLON_COLON && LA(2) == T_NEW)))
|
||||||
NewExpressionAST *ast = new (_pool) NewExpressionAST;
|
return false;
|
||||||
|
|
||||||
|
NewExpressionAST *ast = new (_pool) NewExpressionAST;
|
||||||
if (LA() == T_COLON_COLON)
|
if (LA() == T_COLON_COLON)
|
||||||
ast->scope_token = consumeToken();
|
ast->scope_token = consumeToken();
|
||||||
|
|
||||||
ast->new_token = consumeToken();
|
ast->new_token = consumeToken();
|
||||||
|
|
||||||
if (LA() == T_LPAREN) {
|
NewPlacementAST *new_placement = 0;
|
||||||
consumeToken();
|
|
||||||
parseExpression(ast->expression);
|
if (parseNewPlacement(new_placement)) {
|
||||||
if (LA() == T_RPAREN)
|
unsigned after_new_placement = cursor();
|
||||||
consumeToken();
|
|
||||||
|
NewTypeIdAST *new_type_id = 0;
|
||||||
|
if (parseNewTypeId(new_type_id)) {
|
||||||
|
ast->new_placement = new_placement;
|
||||||
|
ast->new_type_id = new_type_id;
|
||||||
|
parseNewInitializer(ast->new_initializer);
|
||||||
|
// recognized new-placement.opt new-type-id new-initializer.opt
|
||||||
|
node = ast;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rewind(after_new_placement);
|
||||||
if (LA() == T_LPAREN) {
|
if (LA() == T_LPAREN) {
|
||||||
consumeToken();
|
unsigned lparen_token = consumeToken();
|
||||||
parseTypeId(ast->type_id);
|
ExpressionAST *type_id = 0;
|
||||||
if (LA() == T_RPAREN)
|
if (parseTypeId(type_id) && LA() == T_RPAREN) {
|
||||||
consumeToken();
|
ast->new_placement = new_placement;
|
||||||
} else {
|
ast->lparen_token = lparen_token;
|
||||||
parseNewTypeId(ast->new_type_id);
|
ast->type_id = type_id;
|
||||||
}
|
ast->rparen_token = consumeToken();
|
||||||
|
|
||||||
parseNewInitializer(ast->new_initializer);
|
parseNewInitializer(ast->new_initializer);
|
||||||
node = ast;
|
node = ast;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
rewind(ast->new_token + 1);
|
||||||
|
|
||||||
|
if (LA() == T_LPAREN) {
|
||||||
|
unsigned lparen_token = consumeToken();
|
||||||
|
ExpressionAST *type_id = 0;
|
||||||
|
if (parseTypeId(type_id) && LA() == T_RPAREN) {
|
||||||
|
ast->lparen_token = lparen_token;
|
||||||
|
ast->type_id = type_id;
|
||||||
|
ast->rparen_token = consumeToken();
|
||||||
|
parseNewInitializer(ast->new_initializer);
|
||||||
|
node = ast;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
parseNewTypeId(ast->new_type_id);
|
||||||
|
parseNewInitializer(ast->new_initializer);
|
||||||
|
node = ast;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::parseNewTypeId(NewTypeIdAST *&node)
|
bool Parser::parseNewTypeId(NewTypeIdAST *&node)
|
||||||
@@ -3145,27 +3199,26 @@ bool Parser::parseNewTypeId(NewTypeIdAST *&node)
|
|||||||
|
|
||||||
NewTypeIdAST *ast = new (_pool) NewTypeIdAST;
|
NewTypeIdAST *ast = new (_pool) NewTypeIdAST;
|
||||||
ast->type_specifier = typeSpec;
|
ast->type_specifier = typeSpec;
|
||||||
parseNewDeclarator(ast->new_declarator);
|
PtrOperatorAST **ptrop_it = &ast->ptr_operators;
|
||||||
|
while (parsePtrOperator(*ptrop_it))
|
||||||
|
ptrop_it = &(*ptrop_it)->next;
|
||||||
|
NewArrayDeclaratorAST **it = &ast->new_array_declarators;
|
||||||
|
while (parseNewArrayDeclarator(*it))
|
||||||
|
it = &(*it)->next;
|
||||||
node = ast;
|
node = ast;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::parseNewDeclarator(NewDeclaratorAST *&node)
|
|
||||||
|
bool Parser::parseNewArrayDeclarator(NewArrayDeclaratorAST *&node)
|
||||||
{
|
{
|
||||||
NewDeclaratorAST *ast = new (_pool) NewDeclaratorAST;
|
if (LA() != T_LBRACKET)
|
||||||
|
return false;
|
||||||
PtrOperatorAST **ptr_operators_tail = &ast->ptr_operators;
|
|
||||||
while (parsePtrOperator(*ptr_operators_tail))
|
|
||||||
ptr_operators_tail = &(*ptr_operators_tail)->next;
|
|
||||||
|
|
||||||
while (LA() == T_LBRACKET) { // ### create the AST
|
|
||||||
consumeToken();
|
|
||||||
ExpressionAST *expression = 0;
|
|
||||||
parseExpression(expression);
|
|
||||||
unsigned rbracket_token = 0;
|
|
||||||
match(T_RBRACKET, &rbracket_token);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
NewArrayDeclaratorAST *ast = new (_pool) NewArrayDeclaratorAST;
|
||||||
|
ast->lbracket_token = consumeToken();
|
||||||
|
parseExpression(ast->expression);
|
||||||
|
match(T_RBRACKET, &ast->rbracket_token);
|
||||||
node = ast;
|
node = ast;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,8 +150,9 @@ public:
|
|||||||
bool parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name, bool acceptTemplateId);
|
bool parseNestedNameSpecifierOpt(NestedNameSpecifierAST *&name, bool acceptTemplateId);
|
||||||
bool parseNamespace(DeclarationAST *&node);
|
bool parseNamespace(DeclarationAST *&node);
|
||||||
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
|
bool parseNamespaceAliasDefinition(DeclarationAST *&node);
|
||||||
bool parseNewDeclarator(NewDeclaratorAST *&node);
|
bool parseNewArrayDeclarator(NewArrayDeclaratorAST *&node);
|
||||||
bool parseNewExpression(ExpressionAST *&node);
|
bool parseNewExpression(ExpressionAST *&node);
|
||||||
|
bool parseNewPlacement(NewPlacementAST *&node);
|
||||||
bool parseNewInitializer(NewInitializerAST *&node);
|
bool parseNewInitializer(NewInitializerAST *&node);
|
||||||
bool parseNewTypeId(NewTypeIdAST *&node);
|
bool parseNewTypeId(NewTypeIdAST *&node);
|
||||||
bool parseOperator(OperatorAST *&node);
|
bool parseOperator(OperatorAST *&node);
|
||||||
|
|||||||
@@ -764,15 +764,11 @@ bool PrettyPrinter::visit(NestedNameSpecifierAST *ast)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PrettyPrinter::visit(NewDeclaratorAST *ast)
|
bool PrettyPrinter::visit(NewArrayDeclaratorAST *ast)
|
||||||
{
|
{
|
||||||
for (PtrOperatorAST *it = ast->ptr_operators; it; it = it->next) {
|
out << '[';
|
||||||
accept(it);
|
accept(ast->expression);
|
||||||
if (it->next)
|
out << ']';
|
||||||
out << ' ';
|
|
||||||
}
|
|
||||||
if (ast->declarator)
|
|
||||||
accept(ast->declarator);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -782,25 +778,32 @@ bool PrettyPrinter::visit(NewExpressionAST *ast)
|
|||||||
out << "::";
|
out << "::";
|
||||||
out << "new";
|
out << "new";
|
||||||
out << ' ';
|
out << ' ';
|
||||||
if (ast->expression) {
|
accept(ast->new_placement);
|
||||||
accept(ast->expression);
|
if (ast->new_placement)
|
||||||
if (ast->type_id)
|
|
||||||
out << ' ';
|
out << ' ';
|
||||||
}
|
if (ast->lparen_token) {
|
||||||
if (ast->type_id) {
|
out << '(';
|
||||||
accept(ast->type_id);
|
accept(ast->type_id);
|
||||||
if (ast->new_type_id)
|
out << ')';
|
||||||
out << ' ';
|
} else {
|
||||||
}
|
|
||||||
if (ast->new_type_id) {
|
|
||||||
accept(ast->new_type_id);
|
accept(ast->new_type_id);
|
||||||
if (ast->new_initializer)
|
|
||||||
out << ' ';
|
|
||||||
}
|
}
|
||||||
accept(ast->new_initializer);
|
accept(ast->new_initializer);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PrettyPrinter::visit(NewPlacementAST *ast)
|
||||||
|
{
|
||||||
|
out << '(';
|
||||||
|
for (ExpressionListAST *it = ast->expression_list; it; it = it->next) {
|
||||||
|
accept(it->expression);
|
||||||
|
if (it->next)
|
||||||
|
out << ", ";
|
||||||
|
}
|
||||||
|
out << ')';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool PrettyPrinter::visit(NewInitializerAST *ast)
|
bool PrettyPrinter::visit(NewInitializerAST *ast)
|
||||||
{
|
{
|
||||||
out << '(';
|
out << '(';
|
||||||
@@ -812,18 +815,16 @@ bool PrettyPrinter::visit(NewInitializerAST *ast)
|
|||||||
bool PrettyPrinter::visit(NewTypeIdAST *ast)
|
bool PrettyPrinter::visit(NewTypeIdAST *ast)
|
||||||
{
|
{
|
||||||
for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
|
for (SpecifierAST *it = ast->type_specifier; it; it = it->next) {
|
||||||
|
if (it != ast->type_specifier)
|
||||||
|
out << ' ';
|
||||||
accept(it);
|
accept(it);
|
||||||
if (it->next)
|
|
||||||
out << ' ';
|
|
||||||
}
|
}
|
||||||
if (ast->type_specifier)
|
for (PtrOperatorAST *it = ast->ptr_operators; it; it = it->next) {
|
||||||
out << ' ';
|
accept(it);
|
||||||
if (ast->new_initializer) {
|
}
|
||||||
accept(ast->new_initializer);
|
for (NewArrayDeclaratorAST *it = ast->new_array_declarators; it; it = it->next) {
|
||||||
if (ast->new_declarator)
|
accept(it);
|
||||||
out << ' ';
|
|
||||||
}
|
}
|
||||||
accept(ast->new_declarator);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -106,7 +106,8 @@ protected:
|
|||||||
virtual bool visit(NestedDeclaratorAST *ast);
|
virtual bool visit(NestedDeclaratorAST *ast);
|
||||||
virtual bool visit(NestedExpressionAST *ast);
|
virtual bool visit(NestedExpressionAST *ast);
|
||||||
virtual bool visit(NestedNameSpecifierAST *ast);
|
virtual bool visit(NestedNameSpecifierAST *ast);
|
||||||
virtual bool visit(NewDeclaratorAST *ast);
|
virtual bool visit(NewArrayDeclaratorAST *ast);
|
||||||
|
virtual bool visit(NewPlacementAST *ast);
|
||||||
virtual bool visit(NewExpressionAST *ast);
|
virtual bool visit(NewExpressionAST *ast);
|
||||||
virtual bool visit(NewInitializerAST *ast);
|
virtual bool visit(NewInitializerAST *ast);
|
||||||
virtual bool visit(NewTypeIdAST *ast);
|
virtual bool visit(NewTypeIdAST *ast);
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ void Scope::enterSymbol(Symbol *symbol)
|
|||||||
|
|
||||||
Symbol *Scope::lookat(Identifier *id) const
|
Symbol *Scope::lookat(Identifier *id) const
|
||||||
{
|
{
|
||||||
if (! _hash)
|
if (! _hash || ! id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const unsigned h = id->hashCode() % _hashSize;
|
const unsigned h = id->hashCode() % _hashSize;
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ Type::Type()
|
|||||||
Type::~Type()
|
Type::~Type()
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
|
bool Type::isUndefinedType() const
|
||||||
|
{ return this == UndefinedType::instance(); }
|
||||||
|
|
||||||
bool Type::isVoidType() const
|
bool Type::isVoidType() const
|
||||||
{ return asVoidType() != 0; }
|
{ return asVoidType() != 0; }
|
||||||
|
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public:
|
|||||||
Type();
|
Type();
|
||||||
virtual ~Type();
|
virtual ~Type();
|
||||||
|
|
||||||
|
bool isUndefinedType() const;
|
||||||
bool isVoidType() const;
|
bool isVoidType() const;
|
||||||
bool isIntegerType() const;
|
bool isIntegerType() const;
|
||||||
bool isFloatType() const;
|
bool isFloatType() const;
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ private slots:
|
|||||||
// expressions
|
// expressions
|
||||||
void simple_name();
|
void simple_name();
|
||||||
void template_id();
|
void template_id();
|
||||||
|
void new_expression_1();
|
||||||
|
void new_expression_2();
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
void if_statement();
|
void if_statement();
|
||||||
@@ -91,6 +93,59 @@ void tst_AST::template_id()
|
|||||||
QCOMPARE(ast->asTemplateId()->greater_token, 4U);
|
QCOMPARE(ast->asTemplateId()->greater_token, 4U);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_AST::new_expression_1()
|
||||||
|
{
|
||||||
|
QSharedPointer<TranslationUnit> unit(parseExpression("\n"
|
||||||
|
"new char"
|
||||||
|
));
|
||||||
|
|
||||||
|
AST *ast = unit->ast();
|
||||||
|
QVERIFY(ast != 0);
|
||||||
|
|
||||||
|
NewExpressionAST *expr = ast->asNewExpression();
|
||||||
|
QVERIFY(expr != 0);
|
||||||
|
|
||||||
|
QCOMPARE(expr->scope_token, 0U);
|
||||||
|
QCOMPARE(expr->new_token, 1U);
|
||||||
|
QVERIFY(expr->new_placement == 0);
|
||||||
|
QCOMPARE(expr->lparen_token, 0U);
|
||||||
|
QVERIFY(expr->type_id == 0);
|
||||||
|
QCOMPARE(expr->rparen_token, 0U);
|
||||||
|
QVERIFY(expr->new_type_id != 0);
|
||||||
|
QVERIFY(expr->new_initializer == 0);
|
||||||
|
|
||||||
|
QVERIFY(expr->new_type_id->type_specifier != 0);
|
||||||
|
QVERIFY(expr->new_type_id->ptr_operators == 0);
|
||||||
|
QVERIFY(expr->new_type_id->new_array_declarators == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void tst_AST::new_expression_2()
|
||||||
|
{
|
||||||
|
QSharedPointer<TranslationUnit> unit(parseStatement("\n"
|
||||||
|
"::new(__p) _Tp(__val);"
|
||||||
|
));
|
||||||
|
|
||||||
|
AST *ast = unit->ast();
|
||||||
|
QVERIFY(ast != 0);
|
||||||
|
|
||||||
|
ExpressionStatementAST *stmt = ast->asExpressionStatement();
|
||||||
|
QVERIFY(stmt != 0);
|
||||||
|
QVERIFY(stmt->expression != 0);
|
||||||
|
QVERIFY(stmt->semicolon_token != 0);
|
||||||
|
|
||||||
|
NewExpressionAST *expr = stmt->expression->asNewExpression();
|
||||||
|
QVERIFY(expr != 0);
|
||||||
|
|
||||||
|
QCOMPARE(expr->scope_token, 1U);
|
||||||
|
QCOMPARE(expr->new_token, 2U);
|
||||||
|
QVERIFY(expr->new_placement != 0);
|
||||||
|
QCOMPARE(expr->lparen_token, 0U);
|
||||||
|
QVERIFY(expr->type_id == 0);
|
||||||
|
QCOMPARE(expr->rparen_token, 0U);
|
||||||
|
QVERIFY(expr->new_type_id != 0);
|
||||||
|
QVERIFY(expr->new_initializer != 0);
|
||||||
|
}
|
||||||
|
|
||||||
void tst_AST::if_statement()
|
void tst_AST::if_statement()
|
||||||
{
|
{
|
||||||
QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b;"));
|
QSharedPointer<TranslationUnit> unit(parseStatement("if (a) b;"));
|
||||||
|
|||||||
Reference in New Issue
Block a user