Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

This commit is contained in:
hjk
2009-02-11 12:20:27 +01:00
29 changed files with 466 additions and 192 deletions

View File

@@ -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.

View File

@@ -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
{ {
QList<Symbol *> candidates;
if (!name)
return candidates;
if (QualifiedNameId *q = name->asQualifiedNameId()) { if (QualifiedNameId *q = name->asQualifiedNameId()) {
QList<Symbol *> candidates;
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);

View File

@@ -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;
} }

View File

@@ -80,7 +80,6 @@ OpenEditorsWidget::OpenEditorsWidget()
OpenEditorsWidget::~OpenEditorsWidget() OpenEditorsWidget::~OpenEditorsWidget()
{ {
} }
void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor) void OpenEditorsWidget::updateCurrentItem(Core::IEditor *editor)

View File

@@ -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,15 +522,12 @@ 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);
drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget); arrowOpt.rect.translate(0, 6);
drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
} else {
drawPrimitive(PE_IndicatorArrowDown, &arrowOpt, painter, widget);
}
painter->restore(); painter->restore();
} }
break; break;

View File

@@ -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)

View File

@@ -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);

View File

@@ -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
@@ -1125,15 +1116,13 @@ void CppCodeCompletion::complete(const TextEditor::CompletionItem &item)
extraChars += QLatin1Char('('); extraChars += QLatin1Char('(');
// 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(';');
} }
} }

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
} }
} }

View File

@@ -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

View File

@@ -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;
} }

View File

@@ -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()

View File

@@ -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 *) { }

View File

@@ -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;

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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());

View File

@@ -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:

View File

@@ -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; }

View File

@@ -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;
if (LA() == T_COLON_COLON) NewExpressionAST *ast = new (_pool) NewExpressionAST;
ast->scope_token = consumeToken(); if (LA() == T_COLON_COLON)
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);
node = ast;
return true;
}
} }
parseNewInitializer(ast->new_initializer);
node = ast;
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;
} }

View File

@@ -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);

View File

@@ -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) {
} out << '(';
if (ast->type_id) {
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;
} }

View File

@@ -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);

View File

@@ -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;

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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;"));