forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/3.6'
Conflicts: src/libs/3rdparty/modeling/qmt/model_widgets_ui/classmembersedit.cpp src/plugins/git/gitplugin.cpp Change-Id: I78a21510d484b655e01141a3543e08ee2123f9cd
This commit is contained in:
@@ -64,7 +64,11 @@
|
||||
|
||||
To show the file encoding of the current file on the editor toolbar (4),
|
||||
select \uicontrol Tools > \uicontrol Options > \uicontrol {Text Editor} >
|
||||
\uicontrol Display > \uicontrol {Display file encoding}.
|
||||
\uicontrol Display > \uicontrol {Display file encoding}. To change the
|
||||
encoding, click it on the toolbar and select new encoding in the
|
||||
\uicontrol {Text Encoding} dialog. To reload the file with the selected
|
||||
encoding, select \uicontrol {Reload with Encoding}. To save the file with
|
||||
the new encoding, select \uicontrol {Save with Encoding}.
|
||||
|
||||
\note Other convenient ways of navigating in \QC are provided by the
|
||||
\l{Searching with the Locator}{locator}, \l{Keyboard Shortcuts}
|
||||
|
@@ -26,7 +26,7 @@
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-usability.html
|
||||
\page creator-coding.html
|
||||
\nextpage creator-modeling.html
|
||||
\nextpage creator-editor-functions.html
|
||||
|
||||
\title Coding
|
||||
|
||||
@@ -34,12 +34,6 @@
|
||||
|
||||
\list
|
||||
|
||||
\li \l{Modeling}
|
||||
|
||||
You can use the experimental model editor to create Universal
|
||||
Modeling Language (UML) style models with structured diagrams and
|
||||
store them in XML format.
|
||||
|
||||
\li \l{Writing Code}
|
||||
|
||||
Writing, editing, and navigating in source code are core tasks in
|
||||
@@ -85,18 +79,11 @@
|
||||
to use for opening the file. If your files do not match the
|
||||
predefined MIME types, you can edit the MIME types.
|
||||
|
||||
\li \l{Comparing Files}
|
||||
\li \l{Modeling}
|
||||
|
||||
You can use a diff editor to compare two versions of a file and
|
||||
view the differences side-by-side in the \uicontrol Edit mode.
|
||||
|
||||
\li \l{Parsing C++ Files}
|
||||
|
||||
An experimental Clang code model plugin enables you to replace the
|
||||
built-in \QC code model with the Clang code model. Clang is a C
|
||||
language family front end for LLVM. Clang provides you with more
|
||||
accurate information than the built-in code model but can be slower
|
||||
to use for large projects.
|
||||
You can use the experimental model editor to create Universal
|
||||
Modeling Language (UML) style models with structured diagrams and
|
||||
store them in XML format.
|
||||
|
||||
\endlist
|
||||
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
/*!
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-modeling.html
|
||||
\previouspage creator-coding.html
|
||||
\page creator-editor-functions.html
|
||||
\nextpage creator-coding-navigating.html
|
||||
|
||||
@@ -93,4 +93,23 @@
|
||||
|
||||
\endlist
|
||||
|
||||
\section1 Related Topics
|
||||
|
||||
\list
|
||||
|
||||
\li \l{Comparing Files}
|
||||
|
||||
You can use a diff editor to compare two versions of a file and
|
||||
view the differences side-by-side in the \uicontrol Edit mode.
|
||||
|
||||
\li \l{Parsing C++ Files}
|
||||
|
||||
An experimental Clang code model plugin enables you to replace the
|
||||
built-in \QC code model with the Clang code model. Clang is a C
|
||||
language family front end for LLVM. Clang provides you with more
|
||||
accurate information than the built-in code model but can be slower
|
||||
to use for large projects.
|
||||
|
||||
\endlist
|
||||
|
||||
*/
|
||||
|
@@ -26,7 +26,7 @@
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-editor-fakevim.html
|
||||
\page creator-mime-types.html
|
||||
\nextpage creator-building-running.html
|
||||
\nextpage creator-modeling.html
|
||||
|
||||
\title Editing MIME Types
|
||||
|
||||
|
@@ -24,9 +24,9 @@
|
||||
|
||||
/*!
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-coding.html
|
||||
\previouspage creator-mime-types.html
|
||||
\page creator-modeling.html
|
||||
\nextpage creator-editor-functions.html
|
||||
\nextpage creator-building-running.html
|
||||
|
||||
\title Modeling
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
For more information about the supported device groups and reference devices,
|
||||
see \l{http://doc.qt.io/QtForDeviceCreation/qtee-supported-platforms.html}
|
||||
{Supported Platforms} in the {http://doc.qt.io/QtForDeviceCreation/index.html}
|
||||
{Supported Platforms} in the \l{http://doc.qt.io/QtForDeviceCreation/index.html}
|
||||
{Qt for Device Creation} documentation.
|
||||
|
||||
\section2 Mobile Devices
|
||||
|
@@ -24,7 +24,7 @@
|
||||
|
||||
/*!
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-mime-types.html
|
||||
\previouspage creator-modeling.html
|
||||
\page creator-building-running.html
|
||||
\nextpage creator-building-targets.html
|
||||
|
||||
|
@@ -72,11 +72,11 @@
|
||||
\endlist
|
||||
\li \b {\l{Coding}}
|
||||
\list
|
||||
\li \l{Modeling}
|
||||
\li \l{Writing Code}
|
||||
\li \l{Finding}
|
||||
\li \l{Refactoring}
|
||||
\li \l{Configuring the Editor}
|
||||
\li \l{Modeling}
|
||||
\endlist
|
||||
\row
|
||||
\li \inlineimage creator_buildingrunning.png
|
||||
@@ -113,7 +113,6 @@
|
||||
\li \l{Known Issues}
|
||||
\li \l{Glossary}
|
||||
\endlist
|
||||
\li
|
||||
\row
|
||||
\li {4,1} \note To report bugs and suggestions to the Qt Bug
|
||||
Tracker, select \uicontrol {Help > Report Bug}.
|
||||
@@ -194,7 +193,6 @@
|
||||
\endlist
|
||||
\li \l{Coding}
|
||||
\list
|
||||
\li \l{Modeling}
|
||||
\li \l{Writing Code}
|
||||
\list
|
||||
\li \l{Working in Edit Mode}
|
||||
@@ -221,6 +219,7 @@
|
||||
\li \l{Using FakeVim Mode}
|
||||
\endlist
|
||||
\li \l{Editing MIME Types}
|
||||
\li \l{Modeling}
|
||||
\endlist
|
||||
\li \l{Building and Running}
|
||||
\list
|
||||
|
@@ -25,7 +25,7 @@
|
||||
/*!
|
||||
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-using-qt-quick-designer.html
|
||||
\previouspage qmldesigner-connections.html
|
||||
\page quick-components.html
|
||||
\nextpage quick-buttons.html
|
||||
|
||||
|
@@ -31,7 +31,7 @@
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage qmldesigner-pathview-editor.html
|
||||
\page qmldesigner-connections.html
|
||||
\nextpage quick-export-to-qml.html
|
||||
\nextpage quick-components.html
|
||||
|
||||
\title Adding Connections
|
||||
|
||||
|
@@ -26,7 +26,7 @@
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-quick-ui-forms.html
|
||||
\page creator-using-qt-quick-designer.html
|
||||
\nextpage quick-components.html
|
||||
\nextpage qmldesigner-pathview-editor.html
|
||||
|
||||
\title Using Qt Quick Designer
|
||||
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
/*!
|
||||
\contentspage {Qt Creator Manual}
|
||||
\previouspage creator-qtquick-designer-extensions.html
|
||||
\previouspage creator-using-qt-quick-designer.html
|
||||
\page qmldesigner-pathview-editor.html
|
||||
\nextpage qmldesigner-connections.html
|
||||
|
||||
|
@@ -1034,9 +1034,8 @@ class DumperBase:
|
||||
# We cannot use str(addr) as it yields rubbish for char pointers
|
||||
# that might trigger Unicode encoding errors.
|
||||
#return addr.cast(lookupType("void").pointer())
|
||||
# We do not use "hex(...)" as it (sometimes?) adds a "L" suffix.
|
||||
try:
|
||||
return "0x%x" % toInteger(addr)
|
||||
return "0x%x" % toInteger(hex(addr), 16)
|
||||
except:
|
||||
warn("CANNOT CONVERT TYPE: %s" % type(addr))
|
||||
try:
|
||||
|
@@ -8,7 +8,7 @@
|
||||
"trDisplayCategory": "Application",
|
||||
"icon": "3dapplication.png",
|
||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQtCanvas3d" ],
|
||||
"enabled": "${JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0}",
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmakeProjectManager') >= 0}",
|
||||
|
||||
"options":
|
||||
[
|
||||
|
@@ -5,7 +5,7 @@
|
||||
"category": "H.Project",
|
||||
"trDescription": "Creates a Qt Quick 2 UI project with a QML entry point. To use it, you need to have a QML runtime environment such as qmlscene set up. Consider using a Qt Quick Application project instead.",
|
||||
"trDisplayName": "Qt Quick UI",
|
||||
"trDisplayCategory": "Application",
|
||||
"trDisplayCategory": "Other Project",
|
||||
"icon": "../../qmake/qtquickapplication/qml_wizard.png",
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmlProjectManager') >= 0}",
|
||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick.Controls.1.3", "QtSupport.Wizards.FeatureQtQuickProject", "QtSupport.Wizards.FeatureQt" ],
|
||||
|
@@ -5,7 +5,7 @@
|
||||
"category": "H.Project",
|
||||
"trDescription": "Creates a Qt Quick 2 UI project using Qt Quick Controls with a QML entry point. To use it, you need to have a QML runtime environment such as qmlscene set up. Consider using a Qt Quick Controls Application project instead.",
|
||||
"trDisplayName": "Qt Quick Controls UI",
|
||||
"trDisplayCategory": "Application",
|
||||
"trDisplayCategory": "Other Project",
|
||||
"icon": "../../qmake/qtquickapplication/qml_wizard.png",
|
||||
"enabled": "%{JS: [ %{Plugins} ].indexOf('QmlProjectManager') >= 0}",
|
||||
"featuresRequired": [ "QtSupport.Wizards.FeatureQtQuick.Controls.1.3", "QtSupport.Wizards.FeatureQtQuickProject", "QtSupport.Wizards.FeatureQt" ],
|
||||
|
@@ -1390,10 +1390,6 @@ Deploying local Qt libraries is incompatible with Android 5.</source>
|
||||
<source>Core plugin is disabled.</source>
|
||||
<translation>Базовый модуль отключён.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No valid theme "%1"</source>
|
||||
<translation>Подходящая тема «%1» не обнаружена</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>ApplicationWindowSpecifics</name>
|
||||
@@ -5382,6 +5378,10 @@ Continue?</source>
|
||||
</context>
|
||||
<context>
|
||||
<name>Core::Internal::CorePlugin</name>
|
||||
<message>
|
||||
<source>No themes found in installation.</source>
|
||||
<translation>Темы не установлены.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The current date (ISO).</source>
|
||||
<translation>Текущая дата (ISO).</translation>
|
||||
@@ -8285,26 +8285,6 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
|
||||
<source>Form</source>
|
||||
<translation></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Code Completion and Semantic Highlighting</source>
|
||||
<translation>Дополнение и подсветка кода</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>C</source>
|
||||
<translation>C</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>C++</source>
|
||||
<translation>C++</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Objective C</source>
|
||||
<translation>Objective C</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Objective C++</source>
|
||||
<translation>Objective C++</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pre-compiled Headers</source>
|
||||
<translation>Прекомпилированные заголовки</translation>
|
||||
@@ -8318,8 +8298,20 @@ In addition, Shift+Enter inserts an escape character at the cursor position and
|
||||
<translation>Игнорировать прекомпилированные заголовки</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Headers</source>
|
||||
<translation>Заголовочные</translation>
|
||||
<source><i>Activate the Clang Code Model plugin to enable the options here.</i></source>
|
||||
<translation><i>Включите модуль Clang Code Model, чтобы менять настройки.</i></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Clang Code Model</source>
|
||||
<translation>Использовать модель кода Clang</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Append additional command line options to Clang, one per line. <i>Use this with care.</i></source>
|
||||
<translation>Дополнительные параметры командной строки Clang, по одной на строке.<br><i>Используйте их с осторожностью.</i></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Reset Options</source>
|
||||
<translation>Сбросить</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
@@ -10437,14 +10429,6 @@ Flags: %3</source>
|
||||
<source>Changes the font size in the debugger views when the font size in the main editor changes.</source>
|
||||
<translation>Менять размер шрифта в окне отладчика при изменении его в основном окне редактора.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Populates the source file view automatically. This might slow down debugger startup considerably.</source>
|
||||
<translation>Автоматическое заполнение просмотра файлов исходных текстов. Может замедлить процесс запуска отладчика.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Populate source file view automatically</source>
|
||||
<translation>Автоматически заполнять представление исходных текстов</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Switch to previous mode on debugger exit</source>
|
||||
<translation>Переключаться в предыдущий режим при завершении отладчика</translation>
|
||||
@@ -11364,10 +11348,6 @@ Qt Creator не может подключиться к нему.</translation>
|
||||
<source>Use Tooltips in Stack View when Debugging</source>
|
||||
<translation>Подсказки в обзоре стека при отладке</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>List Source Files</source>
|
||||
<translation>Показать файлы исходников</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Skip Known Frames</source>
|
||||
<translation>Пропустить известные кадры</translation>
|
||||
@@ -22142,6 +22122,10 @@ Ids must begin with a lowercase letter.</source>
|
||||
</context>
|
||||
<context>
|
||||
<name>ProjectExplorer::Internal::DependenciesWidget</name>
|
||||
<message>
|
||||
<source>Synchronize configuration</source>
|
||||
<translation>Синхронизировать конфигурацию</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Synchronize active kit, build, and deploy configuration between projects.</source>
|
||||
<translation>Сихронизировать у проектов текущий комплект и конфигурации сборки и установки.</translation>
|
||||
@@ -34043,7 +34027,7 @@ with a password, which you can enter below.</source>
|
||||
<context>
|
||||
<name>TextEditor::FindInFiles</name>
|
||||
<message>
|
||||
<source>Files on File System</source>
|
||||
<source>Files in File System</source>
|
||||
<translation>Файлы в системе</translation>
|
||||
</message>
|
||||
<message>
|
||||
@@ -38740,6 +38724,10 @@ should a repository require SSH-authentication (see documentation on SSH and the
|
||||
</context>
|
||||
<context>
|
||||
<name>WinRt::Internal::WinRtDebugSupport</name>
|
||||
<message>
|
||||
<source>Not enough free ports for QML debugging.</source>
|
||||
<translation>Недостаточно свободных портов для отладки QML.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>The WinRT debugging helper is missing from your Qt Creator installation. It was assumed to be located at %1</source>
|
||||
<translation>Помощник отладчика WinRT отсутствует в составе установки вашего Qt Creator. Предполагается, что он находится в %1</translation>
|
||||
|
2
src/libs/3rdparty/cplusplus/AST.h
vendored
2
src/libs/3rdparty/cplusplus/AST.h
vendored
@@ -3349,7 +3349,7 @@ public:
|
||||
DeclarationAST *declaration;
|
||||
|
||||
public: // annotations
|
||||
Scope *symbol;
|
||||
Template *symbol;
|
||||
|
||||
public:
|
||||
TemplateDeclarationAST()
|
||||
|
40
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
40
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -1917,19 +1917,9 @@ bool Bind::visit(SimpleDeclarationAST *ast)
|
||||
methodKey = methodKeyForInvokableToken(tokenKind(ast->qt_invokable_token));
|
||||
|
||||
// unsigned qt_invokable_token = ast->qt_invokable_token;
|
||||
const ExpressionAST *declTypeExpression = 0;
|
||||
bool isTypedef = false;
|
||||
FullySpecifiedType type;
|
||||
for (SpecifierListAST *it = ast->decl_specifier_list; it; it = it->next) {
|
||||
type = this->specifier(it->value, type);
|
||||
if (type.isTypedef())
|
||||
isTypedef = true;
|
||||
|
||||
type.setTypedef(isTypedef);
|
||||
if (type.isDecltype()) {
|
||||
if (DecltypeSpecifierAST *decltypeSpec = it->value->asDecltypeSpecifier())
|
||||
declTypeExpression = decltypeSpec->expression;
|
||||
}
|
||||
}
|
||||
|
||||
List<Symbol *> **symbolTail = &ast->symbols;
|
||||
@@ -1985,8 +1975,6 @@ bool Bind::visit(SimpleDeclarationAST *ast)
|
||||
translationUnit()->error(location(declaratorId->name, ast->firstToken()), "auto-initialized variable must have an initializer");
|
||||
else if (initializer)
|
||||
decl->setInitializer(asStringLiteral(initializer));
|
||||
} else if (declTy.isDecltype()) {
|
||||
decl->setInitializer(asStringLiteral(declTypeExpression));
|
||||
}
|
||||
|
||||
if (_scope->isClass()) {
|
||||
@@ -2367,15 +2355,11 @@ bool Bind::visit(ParameterDeclarationAST *ast)
|
||||
|
||||
bool Bind::visit(TemplateDeclarationAST *ast)
|
||||
{
|
||||
Scope *scope = 0;
|
||||
if (ast->less_token)
|
||||
scope = control()->newTemplate(ast->firstToken(), 0);
|
||||
else
|
||||
scope = control()->newExplicitInstantiation(ast->firstToken(), 0);
|
||||
scope->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin());
|
||||
scope->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
|
||||
ast->symbol = scope;
|
||||
Scope *previousScope = switchScope(scope);
|
||||
Template *templ = control()->newTemplate(ast->firstToken(), 0);
|
||||
templ->setStartOffset(tokenAt(ast->firstToken()).utf16charsBegin());
|
||||
templ->setEndOffset(tokenAt(ast->lastToken() - 1).utf16charsEnd());
|
||||
ast->symbol = templ;
|
||||
Scope *previousScope = switchScope(templ);
|
||||
|
||||
for (DeclarationListAST *it = ast->template_parameter_list; it; it = it->next) {
|
||||
this->declaration(it->value);
|
||||
@@ -2384,17 +2368,12 @@ bool Bind::visit(TemplateDeclarationAST *ast)
|
||||
this->declaration(ast->declaration);
|
||||
(void) switchScope(previousScope);
|
||||
|
||||
Symbol *decl = 0;
|
||||
if (Template *templ = scope->asTemplate())
|
||||
decl = templ->declaration();
|
||||
else if (ExplicitInstantiation *inst = scope->asExplicitInstantiation())
|
||||
decl = inst->declaration();
|
||||
if (decl) {
|
||||
scope->setSourceLocation(decl->sourceLocation(), translationUnit());
|
||||
scope->setName(decl->name());
|
||||
if (Symbol *decl = templ->declaration()) {
|
||||
templ->setSourceLocation(decl->sourceLocation(), translationUnit());
|
||||
templ->setName(decl->name());
|
||||
}
|
||||
|
||||
_scope->addMember(scope);
|
||||
_scope->addMember(templ);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3039,7 +3018,6 @@ bool Bind::visit(TypeofSpecifierAST *ast)
|
||||
bool Bind::visit(DecltypeSpecifierAST *ast)
|
||||
{
|
||||
_type = this->expression(ast->expression);
|
||||
_type.setDecltype(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -112,7 +112,6 @@ class Function;
|
||||
class Namespace;
|
||||
class NamespaceAlias;
|
||||
class Template;
|
||||
class ExplicitInstantiation;
|
||||
class BaseClass;
|
||||
class Block;
|
||||
class Class;
|
||||
|
16
src/libs/3rdparty/cplusplus/Control.cpp
vendored
16
src/libs/3rdparty/cplusplus/Control.cpp
vendored
@@ -366,16 +366,9 @@ public:
|
||||
|
||||
Template *newTemplate(unsigned sourceLocation, const Name *name)
|
||||
{
|
||||
Template *templ = new Template(translationUnit, sourceLocation, name);
|
||||
symbols.push_back(templ);
|
||||
return templ;
|
||||
}
|
||||
|
||||
ExplicitInstantiation *newExplicitInstantiation(unsigned sourceLocation, const Name *name)
|
||||
{
|
||||
ExplicitInstantiation *inst = new ExplicitInstantiation(translationUnit, sourceLocation, name);
|
||||
symbols.push_back(inst);
|
||||
return inst;
|
||||
Template *ns = new Template(translationUnit, sourceLocation, name);
|
||||
symbols.push_back(ns);
|
||||
return ns;
|
||||
}
|
||||
|
||||
NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name)
|
||||
@@ -699,9 +692,6 @@ Namespace *Control::newNamespace(unsigned sourceLocation, const Name *name)
|
||||
Template *Control::newTemplate(unsigned sourceLocation, const Name *name)
|
||||
{ return d->newTemplate(sourceLocation, name); }
|
||||
|
||||
ExplicitInstantiation *Control::newExplicitInstantiation(unsigned sourceLocation, const Name *name)
|
||||
{ return d->newExplicitInstantiation(sourceLocation, name); }
|
||||
|
||||
NamespaceAlias *Control::newNamespaceAlias(unsigned sourceLocation, const Name *name)
|
||||
{ return d->newNamespaceAlias(sourceLocation, name); }
|
||||
|
||||
|
3
src/libs/3rdparty/cplusplus/Control.h
vendored
3
src/libs/3rdparty/cplusplus/Control.h
vendored
@@ -120,9 +120,6 @@ public:
|
||||
/// Creates a new Template symbol.
|
||||
Template *newTemplate(unsigned sourceLocation, const Name *name = 0);
|
||||
|
||||
/// Creates a new ExplicitInstantiation symbol.
|
||||
ExplicitInstantiation *newExplicitInstantiation(unsigned sourceLocation, const Name *name = 0);
|
||||
|
||||
/// Creates a new Namespace symbol.
|
||||
NamespaceAlias *newNamespaceAlias(unsigned sourceLocation, const Name *name = 0);
|
||||
|
||||
|
@@ -100,12 +100,6 @@ bool FullySpecifiedType::isAuto() const
|
||||
void FullySpecifiedType::setAuto(bool isAuto)
|
||||
{ f._isAuto = isAuto; }
|
||||
|
||||
bool FullySpecifiedType::isDecltype() const
|
||||
{ return f._isDecltype; }
|
||||
|
||||
void FullySpecifiedType::setDecltype(bool isDecltype)
|
||||
{ f._isDecltype = isDecltype; }
|
||||
|
||||
bool FullySpecifiedType::isRegister() const
|
||||
{ return f._isRegister; }
|
||||
|
||||
|
@@ -58,9 +58,6 @@ public:
|
||||
bool isAuto() const;
|
||||
void setAuto(bool isAuto);
|
||||
|
||||
bool isDecltype() const;
|
||||
void setDecltype(bool isDecltype);
|
||||
|
||||
bool isRegister() const;
|
||||
void setRegister(bool isRegister);
|
||||
|
||||
@@ -128,7 +125,6 @@ private:
|
||||
// storage class specifiers
|
||||
unsigned _isFriend: 1;
|
||||
unsigned _isAuto: 1;
|
||||
unsigned _isDecltype: 1;
|
||||
unsigned _isRegister: 1;
|
||||
unsigned _isStatic: 1;
|
||||
unsigned _isExtern: 1;
|
||||
|
11
src/libs/3rdparty/cplusplus/Matcher.cpp
vendored
11
src/libs/3rdparty/cplusplus/Matcher.cpp
vendored
@@ -218,17 +218,6 @@ bool Matcher::match(const Template *type, const Template *otherType)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Matcher::match(const ExplicitInstantiation *type, const ExplicitInstantiation *otherType)
|
||||
{
|
||||
if (type == otherType)
|
||||
return true;
|
||||
|
||||
if (! Matcher::match(type->name(), otherType->name(), this))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Matcher::match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType)
|
||||
{
|
||||
if (type == otherType)
|
||||
|
1
src/libs/3rdparty/cplusplus/Matcher.h
vendored
1
src/libs/3rdparty/cplusplus/Matcher.h
vendored
@@ -61,7 +61,6 @@ public:
|
||||
virtual bool match(const Enum *type, const Enum *otherType);
|
||||
virtual bool match(const Namespace *type, const Namespace *otherType);
|
||||
virtual bool match(const Template *type, const Template *otherType);
|
||||
virtual bool match(const ExplicitInstantiation *type, const ExplicitInstantiation *otherType);
|
||||
virtual bool match(const ForwardClassDeclaration *type, const ForwardClassDeclaration *otherType);
|
||||
virtual bool match(const Class *type, const Class *otherType);
|
||||
virtual bool match(const ObjCClass *type, const ObjCClass *otherType);
|
||||
|
2
src/libs/3rdparty/cplusplus/Names.h
vendored
2
src/libs/3rdparty/cplusplus/Names.h
vendored
@@ -100,7 +100,7 @@ public:
|
||||
TemplateArgumentIterator firstTemplateArgument() const { return _templateArguments.begin(); }
|
||||
TemplateArgumentIterator lastTemplateArgument() const { return _templateArguments.end(); }
|
||||
bool isSpecialization() const { return _isSpecialization; }
|
||||
// this is temporary solution needed in LookupScope::nestedType
|
||||
// this is temporary solution needed in ClassOrNamespace::nestedType
|
||||
// when we try to find correct specialization for instantiation
|
||||
void setIsSpecialization(bool isSpecialization) { _isSpecialization = isSpecialization; }
|
||||
|
||||
|
5
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
5
src/libs/3rdparty/cplusplus/Parser.cpp
vendored
@@ -1789,6 +1789,11 @@ bool Parser::parseEnumSpecifier(SpecifierListAST *&node)
|
||||
if (_languageFeatures.cxx11Enabled && (LA() == T_CLASS || LA() == T_STRUCT))
|
||||
ast->key_token = consumeToken();
|
||||
|
||||
|
||||
if (tok().isKeyword()) {
|
||||
error(cursor(), "expected identifier before '%s'", tok().spell());
|
||||
return false;
|
||||
}
|
||||
parseName(ast->name);
|
||||
|
||||
if (_languageFeatures.cxx11Enabled && LA() == T_COLON) {
|
||||
|
2
src/libs/3rdparty/cplusplus/Scope.cpp
vendored
2
src/libs/3rdparty/cplusplus/Scope.cpp
vendored
@@ -215,7 +215,7 @@ unsigned SymbolTable::symbolCount() const
|
||||
|
||||
Symbol *SymbolTable::symbolAt(unsigned index) const
|
||||
{
|
||||
if (! _symbols || index >= symbolCount())
|
||||
if (! _symbols)
|
||||
return 0;
|
||||
return _symbols[index];
|
||||
}
|
||||
|
3
src/libs/3rdparty/cplusplus/Symbol.cpp
vendored
3
src/libs/3rdparty/cplusplus/Symbol.cpp
vendored
@@ -361,9 +361,6 @@ bool Symbol::isNamespace() const
|
||||
bool Symbol::isTemplate() const
|
||||
{ return asTemplate() != 0; }
|
||||
|
||||
bool Symbol::isExplicitInstantiation() const
|
||||
{ return asExplicitInstantiation() != 0; }
|
||||
|
||||
bool Symbol::isClass() const
|
||||
{ return asClass() != 0; }
|
||||
|
||||
|
7
src/libs/3rdparty/cplusplus/Symbol.h
vendored
7
src/libs/3rdparty/cplusplus/Symbol.h
vendored
@@ -135,7 +135,7 @@ public:
|
||||
/// Returns true if this Symbol is an Enum.
|
||||
bool isEnum() const;
|
||||
|
||||
/// Returns true if this Symbol is a Function.
|
||||
/// Returns true if this Symbol is an Function.
|
||||
bool isFunction() const;
|
||||
|
||||
/// Returns true if this Symbol is a Namespace.
|
||||
@@ -144,9 +144,6 @@ public:
|
||||
/// Returns true if this Symbol is a Template.
|
||||
bool isTemplate() const;
|
||||
|
||||
/// Returns true if this Symbol is an ExplicitInstantiation.
|
||||
bool isExplicitInstantiation() const;
|
||||
|
||||
/// Returns true if this Symbol is a Class.
|
||||
bool isClass() const;
|
||||
|
||||
@@ -206,7 +203,6 @@ public:
|
||||
virtual const Function *asFunction() const { return 0; }
|
||||
virtual const Namespace *asNamespace() const { return 0; }
|
||||
virtual const Template *asTemplate() const { return 0; }
|
||||
virtual const ExplicitInstantiation *asExplicitInstantiation() const { return 0; }
|
||||
virtual const NamespaceAlias *asNamespaceAlias() const { return 0; }
|
||||
virtual const Class *asClass() const { return 0; }
|
||||
virtual const Block *asBlock() const { return 0; }
|
||||
@@ -233,7 +229,6 @@ public:
|
||||
virtual Function *asFunction() { return 0; }
|
||||
virtual Namespace *asNamespace() { return 0; }
|
||||
virtual Template *asTemplate() { return 0; }
|
||||
virtual ExplicitInstantiation *asExplicitInstantiation() { return 0; }
|
||||
virtual NamespaceAlias *asNamespaceAlias() { return 0; }
|
||||
virtual Class *asClass() { return 0; }
|
||||
virtual Block *asBlock() { return 0; }
|
||||
|
1
src/libs/3rdparty/cplusplus/SymbolVisitor.h
vendored
1
src/libs/3rdparty/cplusplus/SymbolVisitor.h
vendored
@@ -51,7 +51,6 @@ public:
|
||||
virtual bool visit(Function *) { return true; }
|
||||
virtual bool visit(Namespace *) { return true; }
|
||||
virtual bool visit(Template *) { return true; }
|
||||
virtual bool visit(ExplicitInstantiation *) { return true; }
|
||||
virtual bool visit(Class *) { return true; }
|
||||
virtual bool visit(Block *) { return true; }
|
||||
virtual bool visit(ForwardClassDeclaration *) { return true; }
|
||||
|
52
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
52
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
@@ -481,12 +481,10 @@ void Enum::visitSymbol0(SymbolVisitor *visitor)
|
||||
|
||||
Template::Template(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
|
||||
: Scope(translationUnit, sourceLocation, name)
|
||||
, _isExplicitInstantiation(false)
|
||||
{ }
|
||||
|
||||
Template::Template(Clone *clone, Subst *subst, Template *original)
|
||||
: Scope(clone, subst, original)
|
||||
, _isExplicitInstantiation(original->_isExplicitInstantiation)
|
||||
{ }
|
||||
|
||||
Template::~Template()
|
||||
@@ -539,56 +537,6 @@ bool Template::match0(const Type *otherType, Matcher *matcher) const
|
||||
return false;
|
||||
}
|
||||
|
||||
ExplicitInstantiation::ExplicitInstantiation(TranslationUnit *translationUnit,
|
||||
unsigned sourceLocation, const Name *name)
|
||||
: Scope(translationUnit, sourceLocation, name)
|
||||
{ }
|
||||
|
||||
ExplicitInstantiation::ExplicitInstantiation(Clone *clone, Subst *subst, ExplicitInstantiation *original)
|
||||
: Scope(clone, subst, original)
|
||||
{ }
|
||||
|
||||
ExplicitInstantiation::~ExplicitInstantiation()
|
||||
{ }
|
||||
|
||||
Symbol *ExplicitInstantiation::declaration() const
|
||||
{
|
||||
if (isEmpty())
|
||||
return 0;
|
||||
|
||||
if (Symbol *s = memberAt(memberCount() - 1)) {
|
||||
if (s->isClass() || s->isForwardClassDeclaration() ||
|
||||
s->isTemplate() || s->isExplicitInstantiation() ||
|
||||
s->isFunction() || s->isDeclaration()) {
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FullySpecifiedType ExplicitInstantiation::type() const
|
||||
{ return FullySpecifiedType(const_cast<ExplicitInstantiation *>(this)); }
|
||||
|
||||
void ExplicitInstantiation::visitSymbol0(SymbolVisitor *visitor)
|
||||
{
|
||||
if (visitor->visit(this)) {
|
||||
for (unsigned i = 0; i < memberCount(); ++i) {
|
||||
visitSymbol(memberAt(i), visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ExplicitInstantiation::accept0(TypeVisitor *visitor)
|
||||
{ visitor->visit(this); }
|
||||
|
||||
bool ExplicitInstantiation::match0(const Type *otherType, Matcher *matcher) const
|
||||
{
|
||||
if (const ExplicitInstantiation *otherTy = otherType->asExplicitInstantiationType())
|
||||
return matcher->match(this, otherTy);
|
||||
return false;
|
||||
}
|
||||
|
||||
Namespace::Namespace(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name)
|
||||
: Scope(translationUnit, sourceLocation, name)
|
||||
, _isInline(false)
|
||||
|
33
src/libs/3rdparty/cplusplus/Symbols.h
vendored
33
src/libs/3rdparty/cplusplus/Symbols.h
vendored
@@ -423,41 +423,8 @@ protected:
|
||||
virtual void visitSymbol0(SymbolVisitor *visitor);
|
||||
virtual void accept0(TypeVisitor *visitor);
|
||||
virtual bool match0(const Type *otherType, Matcher *matcher) const;
|
||||
|
||||
private:
|
||||
bool _isExplicitInstantiation;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT ExplicitInstantiation : public Scope, public Type
|
||||
{
|
||||
public:
|
||||
ExplicitInstantiation(TranslationUnit *translationUnit, unsigned sourceLocation, const Name *name);
|
||||
ExplicitInstantiation(Clone *clone, Subst *subst, ExplicitInstantiation *original);
|
||||
virtual ~ExplicitInstantiation();
|
||||
|
||||
Symbol *declaration() const;
|
||||
|
||||
// Symbol's interface
|
||||
virtual FullySpecifiedType type() const;
|
||||
|
||||
virtual const ExplicitInstantiation *asExplicitInstantiation() const
|
||||
{ return this; }
|
||||
|
||||
virtual ExplicitInstantiation *asExplicitInstantiation()
|
||||
{ return this; }
|
||||
|
||||
// Type's interface
|
||||
virtual const ExplicitInstantiation *asExplicitInstantiationType() const
|
||||
{ return this; }
|
||||
|
||||
virtual ExplicitInstantiation *asExplicitInstantiationType()
|
||||
{ return this; }
|
||||
|
||||
protected:
|
||||
virtual void visitSymbol0(SymbolVisitor *visitor);
|
||||
virtual void accept0(TypeVisitor *visitor);
|
||||
virtual bool match0(const Type *otherType, Matcher *matcher) const;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT Namespace: public Scope, public Type
|
||||
{
|
||||
|
18
src/libs/3rdparty/cplusplus/Templates.cpp
vendored
18
src/libs/3rdparty/cplusplus/Templates.cpp
vendored
@@ -125,12 +125,6 @@ void CloneType::visit(Template *type)
|
||||
_type = templ;
|
||||
}
|
||||
|
||||
void CloneType::visit(ExplicitInstantiation *type)
|
||||
{
|
||||
ExplicitInstantiation *inst = _clone->symbol(type, _subst)->asExplicitInstantiation();
|
||||
_type = inst;
|
||||
}
|
||||
|
||||
void CloneType::visit(Class *type)
|
||||
{
|
||||
Class *klass = _clone->symbol(type, _subst)->asClass();
|
||||
@@ -194,8 +188,10 @@ Symbol *CloneSymbol::cloneSymbol(Symbol *symbol, Subst *subst)
|
||||
|
||||
SymbolSubstPair symbolSubstPair = std::make_pair(symbol, subst);
|
||||
auto it = _cache.find(symbolSubstPair);
|
||||
if (it != _cache.end())
|
||||
if (it != _cache.end()) {
|
||||
if (it->second->enclosingScope() == symbol->enclosingScope())
|
||||
return it->second;
|
||||
}
|
||||
|
||||
Symbol *r = 0;
|
||||
std::swap(_subst, subst);
|
||||
@@ -297,14 +293,6 @@ bool CloneSymbol::visit(Template *symbol)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CloneSymbol::visit(ExplicitInstantiation *symbol)
|
||||
{
|
||||
ExplicitInstantiation *inst = new ExplicitInstantiation(_clone, _subst, symbol);
|
||||
_symbol = inst;
|
||||
_control->addSymbol(inst);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CloneSymbol::visit(Class *symbol)
|
||||
{
|
||||
Class *klass = new Class(_clone, _subst, symbol);
|
||||
|
2
src/libs/3rdparty/cplusplus/Templates.h
vendored
2
src/libs/3rdparty/cplusplus/Templates.h
vendored
@@ -85,7 +85,6 @@ protected:
|
||||
virtual void visit(Function *type);
|
||||
virtual void visit(Namespace *type);
|
||||
virtual void visit(Template *type);
|
||||
virtual void visit(ExplicitInstantiation *type);
|
||||
virtual void visit(Class *type);
|
||||
virtual void visit(Enum *type);
|
||||
virtual void visit(ForwardClassDeclaration *type);
|
||||
@@ -153,7 +152,6 @@ protected:
|
||||
virtual bool visit(Function *symbol);
|
||||
virtual bool visit(Namespace *symbol);
|
||||
virtual bool visit(Template *symbol);
|
||||
virtual bool visit(ExplicitInstantiation *symbol);
|
||||
virtual bool visit(Class *symbol);
|
||||
virtual bool visit(Block *symbol);
|
||||
virtual bool visit(ForwardClassDeclaration *symbol);
|
||||
|
3
src/libs/3rdparty/cplusplus/Type.cpp
vendored
3
src/libs/3rdparty/cplusplus/Type.cpp
vendored
@@ -68,9 +68,6 @@ bool Type::isNamespaceType() const
|
||||
bool Type::isTemplateType() const
|
||||
{ return asTemplateType() != 0; }
|
||||
|
||||
bool Type::isExplicitInstantiationType() const
|
||||
{ return asExplicitInstantiationType() != 0; }
|
||||
|
||||
bool Type::isClassType() const
|
||||
{ return asClassType() != 0; }
|
||||
|
||||
|
3
src/libs/3rdparty/cplusplus/Type.h
vendored
3
src/libs/3rdparty/cplusplus/Type.h
vendored
@@ -43,7 +43,6 @@ public:
|
||||
bool isFunctionType() const;
|
||||
bool isNamespaceType() const;
|
||||
bool isTemplateType() const;
|
||||
bool isExplicitInstantiationType() const;
|
||||
bool isClassType() const;
|
||||
bool isEnumType() const;
|
||||
bool isForwardClassDeclarationType() const;
|
||||
@@ -65,7 +64,6 @@ public:
|
||||
virtual const Function *asFunctionType() const { return 0; }
|
||||
virtual const Namespace *asNamespaceType() const { return 0; }
|
||||
virtual const Template *asTemplateType() const { return 0; }
|
||||
virtual const ExplicitInstantiation *asExplicitInstantiationType() const { return 0; }
|
||||
virtual const Class *asClassType() const { return 0; }
|
||||
virtual const Enum *asEnumType() const { return 0; }
|
||||
virtual const ForwardClassDeclaration *asForwardClassDeclarationType() const { return 0; }
|
||||
@@ -87,7 +85,6 @@ public:
|
||||
virtual Function *asFunctionType() { return 0; }
|
||||
virtual Namespace *asNamespaceType() { return 0; }
|
||||
virtual Template *asTemplateType() { return 0; }
|
||||
virtual ExplicitInstantiation *asExplicitInstantiationType() { return 0; }
|
||||
virtual Class *asClassType() { return 0; }
|
||||
virtual Enum *asEnumType() { return 0; }
|
||||
virtual ForwardClassDeclaration *asForwardClassDeclarationType() { return 0; }
|
||||
|
1
src/libs/3rdparty/cplusplus/TypeVisitor.h
vendored
1
src/libs/3rdparty/cplusplus/TypeVisitor.h
vendored
@@ -51,7 +51,6 @@ public:
|
||||
virtual void visit(Function *) {}
|
||||
virtual void visit(Namespace *) {}
|
||||
virtual void visit(Template *) {}
|
||||
virtual void visit(ExplicitInstantiation *) {}
|
||||
virtual void visit(Class *) {}
|
||||
virtual void visit(Enum *) {}
|
||||
virtual void visit(ForwardClassDeclaration *) {}
|
||||
|
@@ -490,7 +490,8 @@ QList<MClassMember> ClassMembersEdit::parse(const QString &text, bool *ok)
|
||||
member.setProperties(member.properties() | MClassMember::PropertyQslot);
|
||||
word = cursor.readWord().toLower();
|
||||
} else if (word == QStringLiteral("invokable") || word == QStringLiteral("qInvokable")) {
|
||||
member.setProperties(member.properties() | MClassMember::PropertyQinvokable);
|
||||
member.setProperties(member.getProperties() | MClassMember::PROPERTY_QINVOKABLE);
|
||||
word = cursor.readWord().toLower();
|
||||
} else if (word == QStringLiteral(":")) {
|
||||
word = cursor.readWord().toLower();
|
||||
} else {
|
||||
|
@@ -53,5 +53,28 @@ enum class DiagnosticSeverity // one to one mapping of the clang enum numbers
|
||||
Error = 3,
|
||||
Fatal = 4
|
||||
};
|
||||
|
||||
enum class HighlightingType
|
||||
{
|
||||
Invalid,
|
||||
Keyword,
|
||||
StringLiteral,
|
||||
NumberLiteral,
|
||||
Comment,
|
||||
Function,
|
||||
VirtualFunction,
|
||||
Type,
|
||||
LocalVariable,
|
||||
Field,
|
||||
GlobalVariable,
|
||||
Enumeration,
|
||||
Operator,
|
||||
Preprocessor,
|
||||
PreprocessorDefinition,
|
||||
PreprocessorExpansion,
|
||||
Label,
|
||||
OutputArgument
|
||||
};
|
||||
|
||||
}
|
||||
#endif // CLANGBACKENDIPC_GLOBAL_H
|
||||
|
@@ -379,7 +379,7 @@ FullySpecifiedType SubstitutionMap::apply(const Name *name, Rewrite *) const
|
||||
}
|
||||
|
||||
|
||||
UseMinimalNames::UseMinimalNames(LookupScope *target)
|
||||
UseMinimalNames::UseMinimalNames(ClassOrNamespace *target)
|
||||
: _target(target)
|
||||
{
|
||||
|
||||
|
@@ -89,13 +89,13 @@ private:
|
||||
class CPLUSPLUS_EXPORT UseMinimalNames: public Substitution
|
||||
{
|
||||
public:
|
||||
UseMinimalNames(LookupScope *target);
|
||||
UseMinimalNames(ClassOrNamespace *target);
|
||||
virtual ~UseMinimalNames();
|
||||
|
||||
virtual FullySpecifiedType apply(const Name *name, Rewrite *rewrite) const;
|
||||
|
||||
private:
|
||||
LookupScope *_target;
|
||||
ClassOrNamespace *_target;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT UseQualifiedNames: public UseMinimalNames
|
||||
|
430
src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp
Normal file
430
src/libs/cplusplus/DeprecatedGenTemplateInstance.cpp
Normal file
@@ -0,0 +1,430 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "DeprecatedGenTemplateInstance.h"
|
||||
#include "Overview.h"
|
||||
|
||||
#include <cplusplus/Control.h>
|
||||
#include <cplusplus/Scope.h>
|
||||
#include <cplusplus/Names.h>
|
||||
#include <cplusplus/Symbols.h>
|
||||
#include <cplusplus/CoreTypes.h>
|
||||
#include <cplusplus/Literals.h>
|
||||
|
||||
#include <QVarLengthArray>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace CPlusPlus;
|
||||
|
||||
namespace {
|
||||
|
||||
class ApplySubstitution
|
||||
{
|
||||
public:
|
||||
ApplySubstitution(Control *control, Symbol *symbol, const DeprecatedGenTemplateInstance::Substitution &substitution);
|
||||
~ApplySubstitution();
|
||||
|
||||
inline Control *control() const { return _control; }
|
||||
|
||||
FullySpecifiedType apply(const Name *name);
|
||||
FullySpecifiedType apply(const FullySpecifiedType &type);
|
||||
|
||||
int findSubstitution(const Identifier *id) const;
|
||||
FullySpecifiedType applySubstitution(int index) const;
|
||||
|
||||
private:
|
||||
class ApplyToType: protected TypeVisitor
|
||||
{
|
||||
public:
|
||||
ApplyToType(ApplySubstitution *q)
|
||||
: q(q) {}
|
||||
|
||||
FullySpecifiedType operator()(const FullySpecifiedType &ty)
|
||||
{
|
||||
FullySpecifiedType previousType = switchType(ty);
|
||||
accept(ty.type());
|
||||
return switchType(previousType);
|
||||
}
|
||||
|
||||
protected:
|
||||
using TypeVisitor::visit;
|
||||
|
||||
Control *control() const
|
||||
{ return q->control(); }
|
||||
|
||||
FullySpecifiedType switchType(const FullySpecifiedType &type)
|
||||
{
|
||||
FullySpecifiedType previousType = _type;
|
||||
_type = type;
|
||||
return previousType;
|
||||
}
|
||||
|
||||
virtual void visit(VoidType *)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
virtual void visit(IntegerType *)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
virtual void visit(FloatType *)
|
||||
{
|
||||
// nothing to do
|
||||
}
|
||||
|
||||
virtual void visit(PointerToMemberType *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO; // ### TODO
|
||||
}
|
||||
|
||||
virtual void visit(PointerType *ptrTy)
|
||||
{
|
||||
_type.setType(control()->pointerType(q->apply(ptrTy->elementType())));
|
||||
}
|
||||
|
||||
virtual void visit(ReferenceType *refTy)
|
||||
{
|
||||
_type.setType(control()->referenceType(q->apply(refTy->elementType()), refTy->isRvalueReference()));
|
||||
}
|
||||
|
||||
virtual void visit(ArrayType *arrayTy)
|
||||
{
|
||||
_type.setType(control()->arrayType(q->apply(arrayTy->elementType()), arrayTy->size()));
|
||||
}
|
||||
|
||||
virtual void visit(NamedType *ty)
|
||||
{
|
||||
FullySpecifiedType n = q->apply(ty->name());
|
||||
_type.setType(n.type());
|
||||
}
|
||||
|
||||
virtual void visit(Function *funTy)
|
||||
{
|
||||
Function *fun = control()->newFunction(/*sourceLocation=*/ 0, funTy->name());
|
||||
fun->setEnclosingScope(funTy->enclosingScope());
|
||||
fun->setConst(funTy->isConst());
|
||||
fun->setVolatile(funTy->isVolatile());
|
||||
fun->setVirtual(funTy->isVirtual());
|
||||
fun->setOverride(funTy->isOverride());
|
||||
fun->setFinal(funTy->isFinal());
|
||||
fun->setAmbiguous(funTy->isAmbiguous());
|
||||
fun->setVariadic(funTy->isVariadic());
|
||||
|
||||
fun->setReturnType(q->apply(funTy->returnType()));
|
||||
|
||||
for (unsigned i = 0, argc = funTy->argumentCount(); i < argc; ++i) {
|
||||
Argument *originalArgument = funTy->argumentAt(i)->asArgument();
|
||||
Argument *arg = control()->newArgument(/*sourceLocation*/ 0,
|
||||
originalArgument->name());
|
||||
|
||||
arg->setType(q->apply(originalArgument->type()));
|
||||
arg->setInitializer(originalArgument->initializer());
|
||||
fun->addMember(arg);
|
||||
}
|
||||
|
||||
_type.setType(fun);
|
||||
}
|
||||
|
||||
virtual void visit(Namespace *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(Class *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(Enum *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(ForwardClassDeclaration *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(ObjCClass *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(ObjCProtocol *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(ObjCMethod *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(ObjCForwardClassDeclaration *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
virtual void visit(ObjCForwardProtocolDeclaration *)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
}
|
||||
|
||||
private:
|
||||
ApplySubstitution *q;
|
||||
FullySpecifiedType _type;
|
||||
QHash<Symbol *, FullySpecifiedType> _processed;
|
||||
};
|
||||
|
||||
class ApplyToName: protected NameVisitor
|
||||
{
|
||||
public:
|
||||
ApplyToName(ApplySubstitution *q): q(q) {}
|
||||
|
||||
FullySpecifiedType operator()(const Name *name)
|
||||
{
|
||||
FullySpecifiedType previousType = switchType(FullySpecifiedType());
|
||||
accept(name);
|
||||
return switchType(previousType);
|
||||
}
|
||||
|
||||
protected:
|
||||
Control *control() const
|
||||
{ return q->control(); }
|
||||
|
||||
int findSubstitution(const Identifier *id) const
|
||||
{ return q->findSubstitution(id); }
|
||||
|
||||
FullySpecifiedType applySubstitution(int index) const
|
||||
{ return q->applySubstitution(index); }
|
||||
|
||||
FullySpecifiedType switchType(const FullySpecifiedType &type)
|
||||
{
|
||||
FullySpecifiedType previousType = _type;
|
||||
_type = type;
|
||||
return previousType;
|
||||
}
|
||||
|
||||
virtual void visit(const Identifier *name)
|
||||
{
|
||||
int index = findSubstitution(name->identifier());
|
||||
|
||||
if (index != -1)
|
||||
_type = applySubstitution(index);
|
||||
|
||||
else
|
||||
_type = control()->namedType(name);
|
||||
}
|
||||
|
||||
virtual void visit(const TemplateNameId *name)
|
||||
{
|
||||
QVarLengthArray<FullySpecifiedType, 8> arguments(name->templateArgumentCount());
|
||||
for (unsigned i = 0; i < name->templateArgumentCount(); ++i) {
|
||||
FullySpecifiedType argTy = name->templateArgumentAt(i);
|
||||
arguments[i] = q->apply(argTy);
|
||||
}
|
||||
|
||||
const TemplateNameId *templId = control()->templateNameId(name->identifier(),
|
||||
name->isSpecialization(),
|
||||
arguments.data(),
|
||||
arguments.size());
|
||||
_type = control()->namedType(templId);
|
||||
}
|
||||
|
||||
const Name *instantiate(const Name *name)
|
||||
{
|
||||
if (! name)
|
||||
return name;
|
||||
|
||||
if (const Identifier *nameId = name->asNameId()) {
|
||||
const Identifier *id = control()->identifier(nameId->chars(), nameId->size());
|
||||
return id;
|
||||
|
||||
} else if (const TemplateNameId *templId = name->asTemplateNameId()) {
|
||||
QVarLengthArray<FullySpecifiedType, 8> arguments(templId->templateArgumentCount());
|
||||
for (unsigned templateArgIndex = 0; templateArgIndex < templId->templateArgumentCount();
|
||||
++templateArgIndex) {
|
||||
FullySpecifiedType argTy = templId->templateArgumentAt(templateArgIndex);
|
||||
arguments[templateArgIndex] = q->apply(argTy);
|
||||
}
|
||||
const Identifier *id = control()->identifier(templId->identifier()->chars(),
|
||||
templId->identifier()->size());
|
||||
return control()->templateNameId(id, templId->isSpecialization(), arguments.data(),
|
||||
arguments.size());
|
||||
|
||||
} else if (const QualifiedNameId *qq = name->asQualifiedNameId()) {
|
||||
const Name *base = instantiate(qq->base());
|
||||
const Name *name = instantiate(qq->name());
|
||||
|
||||
return control()->qualifiedNameId(base, name);
|
||||
|
||||
} else if (const OperatorNameId *op = name->asOperatorNameId()) {
|
||||
return control()->operatorNameId(op->kind());
|
||||
|
||||
} else if (const ConversionNameId *c = name->asConversionNameId()) {
|
||||
FullySpecifiedType ty = q->apply(c->type());
|
||||
return control()->conversionNameId(ty);
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void visit(const QualifiedNameId *name)
|
||||
{
|
||||
if (const Name *n = instantiate(name))
|
||||
_type = control()->namedType(n);
|
||||
}
|
||||
|
||||
virtual void visit(const DestructorNameId *name)
|
||||
{
|
||||
Overview oo;
|
||||
qWarning() << "ignored name:" << oo.prettyName(name);
|
||||
}
|
||||
|
||||
virtual void visit(const OperatorNameId *name)
|
||||
{
|
||||
Overview oo;
|
||||
qWarning() << "ignored name:" << oo.prettyName(name);
|
||||
}
|
||||
|
||||
virtual void visit(const ConversionNameId *name)
|
||||
{
|
||||
Overview oo;
|
||||
qWarning() << "ignored name:" << oo.prettyName(name);
|
||||
}
|
||||
|
||||
virtual void visit(const SelectorNameId *name)
|
||||
{
|
||||
Overview oo;
|
||||
qWarning() << "ignored name:" << oo.prettyName(name);
|
||||
}
|
||||
|
||||
private:
|
||||
ApplySubstitution *q;
|
||||
FullySpecifiedType _type;
|
||||
};
|
||||
|
||||
public: // attributes
|
||||
Control *_control;
|
||||
Symbol *symbol;
|
||||
DeprecatedGenTemplateInstance::Substitution substitution;
|
||||
ApplyToType applyToType;
|
||||
ApplyToName applyToName;
|
||||
};
|
||||
|
||||
ApplySubstitution::ApplySubstitution(Control *control, Symbol *symbol,
|
||||
const DeprecatedGenTemplateInstance::Substitution &substitution)
|
||||
: _control(control), symbol(symbol),
|
||||
substitution(substitution),
|
||||
applyToType(this), applyToName(this)
|
||||
{ }
|
||||
|
||||
ApplySubstitution::~ApplySubstitution()
|
||||
{
|
||||
}
|
||||
|
||||
FullySpecifiedType ApplySubstitution::apply(const Name *name)
|
||||
{
|
||||
FullySpecifiedType ty = applyToName(name);
|
||||
return ty;
|
||||
}
|
||||
|
||||
FullySpecifiedType ApplySubstitution::apply(const FullySpecifiedType &type)
|
||||
{
|
||||
FullySpecifiedType ty = applyToType(type);
|
||||
return ty;
|
||||
}
|
||||
|
||||
int ApplySubstitution::findSubstitution(const Identifier *id) const
|
||||
{
|
||||
Q_ASSERT(id != 0);
|
||||
|
||||
for (int index = 0; index < substitution.size(); ++index) {
|
||||
QPair<const Identifier *, FullySpecifiedType> s = substitution.at(index);
|
||||
|
||||
if (id->match(s.first))
|
||||
return index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
FullySpecifiedType ApplySubstitution::applySubstitution(int index) const
|
||||
{
|
||||
Q_ASSERT(index != -1);
|
||||
Q_ASSERT(index < substitution.size());
|
||||
|
||||
return substitution.at(index).second;
|
||||
}
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
DeprecatedGenTemplateInstance::DeprecatedGenTemplateInstance(QSharedPointer<Control> control, const Substitution &substitution)
|
||||
: _control(control),
|
||||
_substitution(substitution)
|
||||
{ }
|
||||
|
||||
FullySpecifiedType DeprecatedGenTemplateInstance::gen(Symbol *symbol)
|
||||
{
|
||||
ApplySubstitution o(_control.data(), symbol, _substitution);
|
||||
return o.apply(symbol->type());
|
||||
}
|
||||
|
||||
FullySpecifiedType DeprecatedGenTemplateInstance::instantiate(const Name *className, Symbol *candidate,
|
||||
QSharedPointer<Control> control)
|
||||
{
|
||||
if (className) {
|
||||
if (const TemplateNameId *templId = className->asTemplateNameId()) {
|
||||
if (Template *templ = candidate->enclosingTemplate()) {
|
||||
DeprecatedGenTemplateInstance::Substitution subst;
|
||||
|
||||
for (unsigned i = 0; i < templId->templateArgumentCount(); ++i) {
|
||||
FullySpecifiedType templArgTy = templId->templateArgumentAt(i);
|
||||
|
||||
if (i < templ->templateParameterCount()) {
|
||||
const Name *templArgName = templ->templateParameterAt(i)->name();
|
||||
|
||||
if (templArgName && templArgName->identifier()) {
|
||||
const Identifier *templArgId = templArgName->identifier();
|
||||
subst.append(qMakePair(templArgId, templArgTy));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DeprecatedGenTemplateInstance inst(control, subst);
|
||||
return inst.gen(candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
return candidate->type();
|
||||
}
|
@@ -28,41 +28,36 @@
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef TYPERESOLVER_H
|
||||
#define TYPERESOLVER_H
|
||||
#ifndef CPLUSPLUS_DEPRECATEDGENTEMPLATEINSTANCE_H
|
||||
#define CPLUSPLUS_DEPRECATEDGENTEMPLATEINSTANCE_H
|
||||
|
||||
#include "LookupContext.h"
|
||||
#include <cplusplus/TypeVisitor.h>
|
||||
#include <cplusplus/NameVisitor.h>
|
||||
#include <cplusplus/FullySpecifiedType.h>
|
||||
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QSharedPointer>
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
class TypeResolver
|
||||
class CPLUSPLUS_EXPORT DeprecatedGenTemplateInstance
|
||||
{
|
||||
public:
|
||||
TypeResolver(CreateBindings &factory) : _factory(factory) {}
|
||||
void resolve(FullySpecifiedType *type, Scope **scope, LookupScope *binding);
|
||||
static QList<LookupItem> resolveDeclInitializer(
|
||||
CreateBindings &factory, const Declaration *decl,
|
||||
const QSet<const Declaration *> &declarationsBeingResolved,
|
||||
const Identifier *id = 0);
|
||||
typedef QList< QPair<const Identifier *, FullySpecifiedType> > Substitution;
|
||||
|
||||
public:
|
||||
static FullySpecifiedType instantiate(const Name *className, Symbol *candidate, QSharedPointer<Control> control);
|
||||
|
||||
private:
|
||||
NamedType *getNamedType(FullySpecifiedType& type) const;
|
||||
DeprecatedGenTemplateInstance(QSharedPointer<Control> control, const Substitution &substitution);
|
||||
FullySpecifiedType gen(Symbol *symbol);
|
||||
|
||||
QList<LookupItem> getNamedTypeItems(const Name *name, Scope *scope,
|
||||
LookupScope *binding) const;
|
||||
|
||||
static QList<LookupItem> typedefsFromScopeUpToFunctionScope(const Name *name, Scope *scope);
|
||||
|
||||
static bool isTypedefWithName(const Declaration *declaration, const Name *name);
|
||||
|
||||
bool findTypedef(const QList<LookupItem>& namedTypeItems, FullySpecifiedType *type,
|
||||
Scope **scope, QSet<Symbol *>& visited);
|
||||
|
||||
CreateBindings &_factory;
|
||||
// binding has to be remembered in case of resolving typedefs for templates
|
||||
LookupScope *_binding;
|
||||
private:
|
||||
QSharedPointer<Control> _control;
|
||||
const Substitution _substitution;
|
||||
};
|
||||
|
||||
} // namespace CPlusPlus
|
||||
|
||||
#endif // TYPERESOLVER_H
|
||||
#endif // CPLUSPLUS_DEPRECATEDGENTEMPLATEINSTANCE_H
|
@@ -532,7 +532,7 @@ void FindUsages::memInitializer(MemInitializerAST *ast)
|
||||
if (_currentScope->isFunction()) {
|
||||
Class *classScope = _currentScope->enclosingClass();
|
||||
if (! classScope) {
|
||||
if (LookupScope *binding = _context.lookupType(_currentScope)) {
|
||||
if (ClassOrNamespace *binding = _context.lookupType(_currentScope)) {
|
||||
foreach (Symbol *s, binding->symbols()) {
|
||||
if (Class *k = s->asClass()) {
|
||||
classScope = k;
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,6 @@
|
||||
#include <cplusplus/Control.h>
|
||||
#include <cplusplus/Name.h>
|
||||
|
||||
#include <QEnableSharedFromThis>
|
||||
#include <QSet>
|
||||
#include <QMap>
|
||||
|
||||
@@ -59,78 +58,158 @@ struct FullyQualifiedName
|
||||
: fqn(fqn)
|
||||
{}
|
||||
};
|
||||
class LookupScopePrivate;
|
||||
class Instantiator;
|
||||
} // namespace Internal;
|
||||
|
||||
class CreateBindings;
|
||||
|
||||
class CPLUSPLUS_EXPORT LookupScope
|
||||
class CPLUSPLUS_EXPORT ClassOrNamespace
|
||||
{
|
||||
Q_DISABLE_COPY(LookupScope)
|
||||
Q_DISABLE_COPY(ClassOrNamespace)
|
||||
|
||||
LookupScope(CreateBindings *factory, LookupScope *parent);
|
||||
ClassOrNamespace(CreateBindings *factory, ClassOrNamespace *parent);
|
||||
|
||||
public:
|
||||
~LookupScope();
|
||||
~ClassOrNamespace();
|
||||
|
||||
LookupScope *instantiationOrigin() const;
|
||||
const TemplateNameId *templateId() const;
|
||||
ClassOrNamespace *instantiationOrigin() const;
|
||||
|
||||
LookupScope *parent() const;
|
||||
QList<LookupScope *> usings() const;
|
||||
ClassOrNamespace *parent() const;
|
||||
QList<ClassOrNamespace *> usings() const;
|
||||
QList<Enum *> unscopedEnums() const;
|
||||
QList<Symbol *> symbols() const;
|
||||
|
||||
ClassOrNamespace *globalNamespace() const;
|
||||
|
||||
QList<LookupItem> lookup(const Name *name);
|
||||
QList<LookupItem> find(const Name *name);
|
||||
|
||||
LookupScope *lookupType(const Name *name);
|
||||
LookupScope *lookupType(const Name *name, Block *block);
|
||||
LookupScope *findType(const Name *name);
|
||||
LookupScope *findBlock(Block *block);
|
||||
ClassOrNamespace *lookupType(const Name *name);
|
||||
ClassOrNamespace *lookupType(const Name *name, Block *block);
|
||||
ClassOrNamespace *findType(const Name *name);
|
||||
ClassOrNamespace *findBlock(Block *block);
|
||||
|
||||
/// The class this LookupScope is based on.
|
||||
Class *rootClass() const;
|
||||
Symbol *lookupInScope(const QList<const Name *> &fullName);
|
||||
|
||||
/// The class this ClassOrNamespace is based on.
|
||||
Class *rootClass() const { return _rootClass; }
|
||||
|
||||
private:
|
||||
Internal::LookupScopePrivate *d;
|
||||
typedef std::map<const Name *, ClassOrNamespace *, Name::Compare> Table;
|
||||
typedef std::map<const TemplateNameId *, ClassOrNamespace *, TemplateNameId::Compare> TemplateNameIdTable;
|
||||
typedef QHash<const AnonymousNameId *, ClassOrNamespace *> Anonymouses;
|
||||
|
||||
/// \internal
|
||||
void flush();
|
||||
|
||||
/// \internal
|
||||
ClassOrNamespace *findOrCreateType(const Name *name, ClassOrNamespace *origin = 0,
|
||||
Class *clazz = 0);
|
||||
|
||||
ClassOrNamespace *findOrCreateNestedAnonymousType(const AnonymousNameId *anonymousNameId);
|
||||
|
||||
void addTodo(Symbol *symbol);
|
||||
void addSymbol(Symbol *symbol);
|
||||
void addUnscopedEnum(Enum *e);
|
||||
void addUsing(ClassOrNamespace *u);
|
||||
void addNestedType(const Name *alias, ClassOrNamespace *e);
|
||||
|
||||
QList<LookupItem> lookup_helper(const Name *name, bool searchInEnclosingScope);
|
||||
|
||||
void lookup_helper(const Name *name, ClassOrNamespace *binding,
|
||||
QList<LookupItem> *result,
|
||||
QSet<ClassOrNamespace *> *processed,
|
||||
const TemplateNameId *templateId);
|
||||
|
||||
ClassOrNamespace *lookupType_helper(const Name *name, QSet<ClassOrNamespace *> *processed,
|
||||
bool searchInEnclosingScope, ClassOrNamespace *origin);
|
||||
|
||||
ClassOrNamespace *findBlock_helper(Block *block, QSet<ClassOrNamespace *> *processed,
|
||||
bool searchInEnclosingScope);
|
||||
|
||||
ClassOrNamespace *nestedType(const Name *name, ClassOrNamespace *origin);
|
||||
|
||||
void instantiateNestedClasses(ClassOrNamespace *enclosingTemplateClass,
|
||||
Clone &cloner,
|
||||
Subst &subst,
|
||||
ClassOrNamespace *enclosingTemplateClassInstantiation);
|
||||
ClassOrNamespace *findSpecialization(const TemplateNameId *templId,
|
||||
const TemplateNameIdTable &specializations);
|
||||
|
||||
CreateBindings *_factory;
|
||||
ClassOrNamespace *_parent;
|
||||
QList<Symbol *> _symbols;
|
||||
QList<ClassOrNamespace *> _usings;
|
||||
Table _classOrNamespaces;
|
||||
QHash<Block *, ClassOrNamespace *> _blocks;
|
||||
QList<Enum *> _enums;
|
||||
QList<Symbol *> _todo;
|
||||
QSharedPointer<Control> _control;
|
||||
TemplateNameIdTable _specializations;
|
||||
QMap<const TemplateNameId *, ClassOrNamespace *> _instantiations;
|
||||
Anonymouses _anonymouses;
|
||||
QSet<const AnonymousNameId *> _declaredOrTypedefedAnonymouses;
|
||||
|
||||
QHash<Internal::FullyQualifiedName, Symbol *> *_scopeLookupCache;
|
||||
|
||||
// it's an instantiation.
|
||||
const TemplateNameId *_templateId;
|
||||
ClassOrNamespace *_instantiationOrigin;
|
||||
|
||||
AlreadyConsideredClassContainer<Class> _alreadyConsideredClasses;
|
||||
AlreadyConsideredClassContainer<TemplateNameId> _alreadyConsideredTemplates;
|
||||
|
||||
Class *_rootClass;
|
||||
|
||||
class NestedClassInstantiator
|
||||
{
|
||||
public:
|
||||
NestedClassInstantiator(CreateBindings *factory, Clone &cloner, Subst &subst)
|
||||
: _factory(factory)
|
||||
, _cloner(cloner)
|
||||
, _subst(subst)
|
||||
{}
|
||||
void instantiate(ClassOrNamespace *enclosingTemplateClass,
|
||||
ClassOrNamespace *enclosingTemplateClassInstantiation);
|
||||
private:
|
||||
bool isInstantiateNestedClassNeeded(const QList<Symbol *> &symbols) const;
|
||||
bool containsTemplateType(Declaration *declaration) const;
|
||||
bool containsTemplateType(Function *function) const;
|
||||
NamedType *findNamedType(Type *memberType) const;
|
||||
|
||||
QSet<ClassOrNamespace *> _alreadyConsideredNestedClassInstantiations;
|
||||
CreateBindings *_factory;
|
||||
Clone &_cloner;
|
||||
Subst &_subst;
|
||||
};
|
||||
|
||||
public:
|
||||
const Name *_name; // For debug
|
||||
|
||||
friend class Internal::LookupScopePrivate;
|
||||
friend class Internal::Instantiator;
|
||||
friend class CreateBindings;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT CreateBindings
|
||||
: protected SymbolVisitor
|
||||
, public QEnableSharedFromThis<CreateBindings>
|
||||
class CPLUSPLUS_EXPORT CreateBindings: protected SymbolVisitor
|
||||
{
|
||||
Q_DISABLE_COPY(CreateBindings)
|
||||
|
||||
public:
|
||||
typedef QSharedPointer<CreateBindings> Ptr;
|
||||
|
||||
CreateBindings(Document::Ptr thisDocument, const Snapshot &snapshot);
|
||||
virtual ~CreateBindings();
|
||||
|
||||
/// Returns the binding for the global namespace.
|
||||
LookupScope *globalNamespace() const;
|
||||
ClassOrNamespace *globalNamespace() const;
|
||||
|
||||
/// Finds the binding associated to the given symbol.
|
||||
LookupScope *lookupType(Symbol *symbol, LookupScope *enclosingBinding = 0);
|
||||
LookupScope *lookupType(const QList<const Name *> &path, LookupScope *enclosingBinding = 0);
|
||||
ClassOrNamespace *lookupType(Symbol *symbol, ClassOrNamespace *enclosingBinding = 0);
|
||||
ClassOrNamespace *lookupType(const QList<const Name *> &path,
|
||||
ClassOrNamespace *enclosingBinding = 0);
|
||||
|
||||
/// Returns the Control that must be used to create temporary symbols.
|
||||
/// \internal
|
||||
QSharedPointer<Control> control() const
|
||||
{ return _control; }
|
||||
|
||||
Snapshot &snapshot()
|
||||
{ return _snapshot; }
|
||||
|
||||
/// Adds an expression document in order to keep their symbols and names alive
|
||||
void addExpressionDocument(Document::Ptr document)
|
||||
{ _expressionDocuments.append(document); }
|
||||
|
||||
bool expandTemplates() const
|
||||
{ return _expandTemplates; }
|
||||
void setExpandTemplates(bool expandTemplates)
|
||||
@@ -140,36 +219,28 @@ public:
|
||||
/// Store the result in \a results.
|
||||
/// \internal
|
||||
void lookupInScope(const Name *name, Scope *scope, QList<LookupItem> *result,
|
||||
LookupScope *binding = 0);
|
||||
const TemplateNameId *templateId, ClassOrNamespace *binding);
|
||||
|
||||
/// Create bindings for the symbols reachable from \a rootSymbol.
|
||||
/// \internal
|
||||
void process(Symbol *rootSymbol, LookupScope *lookupScope);
|
||||
void process(Symbol *rootSymbol, ClassOrNamespace *classOrNamespace);
|
||||
|
||||
/// Create an empty LookupScope binding with the given \a parent.
|
||||
/// Create an empty ClassOrNamespace binding with the given \a parent.
|
||||
/// \internal
|
||||
LookupScope *allocLookupScope(LookupScope *parent, const Name *name);
|
||||
|
||||
FullySpecifiedType resolveTemplateArgument(Clone &cloner, Subst &subst,
|
||||
LookupScope *origin,
|
||||
const Template *specialization,
|
||||
const TemplateNameId *instantiation,
|
||||
unsigned index);
|
||||
void initializeSubst(Clone &cloner, Subst &subst, LookupScope *origin,
|
||||
const Template *specialization, const TemplateNameId *instantiation);
|
||||
ClassOrNamespace *allocClassOrNamespace(ClassOrNamespace *parent);
|
||||
|
||||
protected:
|
||||
using SymbolVisitor::visit;
|
||||
|
||||
/// Change the current LookupScope binding.
|
||||
LookupScope *switchCurrentLookupScope(LookupScope *lookupScope);
|
||||
/// Change the current ClassOrNamespace binding.
|
||||
ClassOrNamespace *switchCurrentClassOrNamespace(ClassOrNamespace *classOrNamespace);
|
||||
|
||||
/// Enters the LookupScope binding associated with the given \a symbol.
|
||||
LookupScope *enterLookupScopeBinding(Symbol *symbol);
|
||||
/// Enters the ClassOrNamespace binding associated with the given \a symbol.
|
||||
ClassOrNamespace *enterClassOrNamespaceBinding(Symbol *symbol);
|
||||
|
||||
/// Enters a LookupScope binding for the given \a symbol in the global
|
||||
/// Enters a ClassOrNamespace binding for the given \a symbol in the global
|
||||
/// namespace binding.
|
||||
LookupScope *enterGlobalLookupScope(Symbol *symbol);
|
||||
ClassOrNamespace *enterGlobalClassOrNamespace(Symbol *symbol);
|
||||
|
||||
/// Creates bindings for the given \a document.
|
||||
void process(Document::Ptr document);
|
||||
@@ -178,7 +249,6 @@ protected:
|
||||
void process(Symbol *root);
|
||||
|
||||
virtual bool visit(Template *templ);
|
||||
virtual bool visit(ExplicitInstantiation *inst);
|
||||
virtual bool visit(Namespace *ns);
|
||||
virtual bool visit(Class *klass);
|
||||
virtual bool visit(ForwardClassDeclaration *klass);
|
||||
@@ -201,15 +271,16 @@ protected:
|
||||
virtual bool visit(ObjCMethod *);
|
||||
|
||||
private:
|
||||
Symbol *instantiateTemplateFunction(const TemplateNameId *instantiation,
|
||||
Template *specialization) const;
|
||||
|
||||
Snapshot _snapshot;
|
||||
QSharedPointer<Control> _control;
|
||||
QList<Document::Ptr> _expressionDocuments;
|
||||
QSet<Namespace *> _processed;
|
||||
QList<LookupScope *> _entities;
|
||||
LookupScope *_globalNamespace;
|
||||
LookupScope *_currentLookupScope;
|
||||
QList<ClassOrNamespace *> _entities;
|
||||
ClassOrNamespace *_globalNamespace;
|
||||
ClassOrNamespace *_currentClassOrNamespace;
|
||||
bool _expandTemplates;
|
||||
int _depth;
|
||||
};
|
||||
|
||||
class CPLUSPLUS_EXPORT LookupContext
|
||||
@@ -223,7 +294,7 @@ public:
|
||||
LookupContext(Document::Ptr expressionDocument,
|
||||
Document::Ptr thisDocument,
|
||||
const Snapshot &snapshot,
|
||||
CreateBindings::Ptr bindings = CreateBindings::Ptr());
|
||||
QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>());
|
||||
|
||||
LookupContext(const LookupContext &other);
|
||||
LookupContext &operator = (const LookupContext &other);
|
||||
@@ -233,25 +304,25 @@ public:
|
||||
Document::Ptr document(const QString &fileName) const;
|
||||
Snapshot snapshot() const;
|
||||
|
||||
LookupScope *globalNamespace() const;
|
||||
ClassOrNamespace *globalNamespace() const;
|
||||
|
||||
QList<LookupItem> lookup(const Name *name, Scope *scope) const;
|
||||
LookupScope *lookupType(const Name *name, Scope *scope,
|
||||
LookupScope *enclosingBinding = 0,
|
||||
ClassOrNamespace *lookupType(const Name *name, Scope *scope,
|
||||
ClassOrNamespace *enclosingBinding = 0,
|
||||
QSet<const Declaration *> typedefsBeingResolved
|
||||
= QSet<const Declaration *>()) const;
|
||||
LookupScope *lookupType(Symbol *symbol,
|
||||
LookupScope *enclosingBinding = 0) const;
|
||||
LookupScope *lookupParent(Symbol *symbol) const;
|
||||
ClassOrNamespace *lookupType(Symbol *symbol,
|
||||
ClassOrNamespace *enclosingBinding = 0) const;
|
||||
ClassOrNamespace *lookupParent(Symbol *symbol) const;
|
||||
|
||||
/// \internal
|
||||
CreateBindings::Ptr bindings() const
|
||||
QSharedPointer<CreateBindings> bindings() const
|
||||
{ return _bindings; }
|
||||
|
||||
static QList<const Name *> fullyQualifiedName(Symbol *symbol);
|
||||
static QList<const Name *> path(Symbol *symbol);
|
||||
|
||||
static const Name *minimalName(Symbol *symbol, LookupScope *target, Control *control);
|
||||
static const Name *minimalName(Symbol *symbol, ClassOrNamespace *target, Control *control);
|
||||
|
||||
void setExpandTemplates(bool expandTemplates)
|
||||
{
|
||||
@@ -261,7 +332,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
QList<LookupItem> lookupByUsing(const Name *name, LookupScope *bindingScope) const;
|
||||
QList<LookupItem> lookupByUsing(const Name *name, ClassOrNamespace *bindingScope) const;
|
||||
|
||||
// The current expression.
|
||||
Document::Ptr _expressionDocument;
|
||||
@@ -273,7 +344,7 @@ private:
|
||||
Snapshot _snapshot;
|
||||
|
||||
// Bindings
|
||||
CreateBindings::Ptr _bindings;
|
||||
QSharedPointer<CreateBindings> _bindings;
|
||||
|
||||
bool m_expandTemplates;
|
||||
};
|
||||
|
@@ -77,10 +77,10 @@ Scope *LookupItem::scope() const
|
||||
void LookupItem::setScope(Scope *scope)
|
||||
{ _scope = scope; }
|
||||
|
||||
LookupScope *LookupItem::binding() const
|
||||
ClassOrNamespace *LookupItem::binding() const
|
||||
{ return _binding; }
|
||||
|
||||
void LookupItem::setBinding(LookupScope *binding)
|
||||
void LookupItem::setBinding(ClassOrNamespace *binding)
|
||||
{ _binding = binding; }
|
||||
|
||||
bool LookupItem::operator == (const LookupItem &other) const
|
||||
|
@@ -37,7 +37,7 @@
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
class LookupScope;
|
||||
class ClassOrNamespace;
|
||||
|
||||
class CPLUSPLUS_EXPORT LookupItem
|
||||
{
|
||||
@@ -63,8 +63,8 @@ public:
|
||||
/// Sets this item's scope.
|
||||
void setScope(Scope *scope);
|
||||
|
||||
LookupScope *binding() const;
|
||||
void setBinding(LookupScope *binding);
|
||||
ClassOrNamespace *binding() const;
|
||||
void setBinding(ClassOrNamespace *binding);
|
||||
|
||||
bool operator == (const LookupItem &other) const;
|
||||
bool operator != (const LookupItem &other) const;
|
||||
@@ -73,7 +73,7 @@ private:
|
||||
FullySpecifiedType _type;
|
||||
Scope *_scope;
|
||||
Symbol *_declaration;
|
||||
LookupScope *_binding;
|
||||
ClassOrNamespace *_binding;
|
||||
};
|
||||
|
||||
uint qHash(const CPlusPlus::LookupItem &result);
|
||||
|
@@ -32,9 +32,9 @@
|
||||
|
||||
#include "LookupContext.h"
|
||||
#include "Overview.h"
|
||||
#include "DeprecatedGenTemplateInstance.h"
|
||||
#include "CppRewriter.h"
|
||||
#include "TypeOfExpression.h"
|
||||
#include "TypeResolver.h"
|
||||
|
||||
#include <cplusplus/Control.h>
|
||||
#include <cplusplus/AST.h>
|
||||
@@ -75,6 +75,131 @@ static QList<T> removeDuplicates(const QList<T> &results)
|
||||
return uniqueList;
|
||||
}
|
||||
|
||||
class TypedefsResolver
|
||||
{
|
||||
public:
|
||||
TypedefsResolver(const LookupContext &context) : _context(context) {}
|
||||
void resolve(FullySpecifiedType *type, Scope **scope, ClassOrNamespace *binding)
|
||||
{
|
||||
QSet<Symbol *> visited;
|
||||
_binding = binding;
|
||||
// Use a hard limit when trying to resolve typedefs. Typedefs in templates can refer to
|
||||
// each other, each time enhancing the template argument and thus making it impossible to
|
||||
// use an "alreadyResolved" container. FIXME: We might overcome this by resolving the
|
||||
// template parameters.
|
||||
unsigned maxDepth = 15;
|
||||
for (NamedType *namedTy = 0; maxDepth && (namedTy = getNamedType(*type)); --maxDepth) {
|
||||
QList<LookupItem> namedTypeItems = getNamedTypeItems(namedTy->name(), *scope, _binding);
|
||||
|
||||
if (Q_UNLIKELY(debug))
|
||||
qDebug() << "-- we have" << namedTypeItems.size() << "candidates";
|
||||
|
||||
if (!findTypedef(namedTypeItems, type, scope, visited))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
NamedType *getNamedType(FullySpecifiedType& type) const
|
||||
{
|
||||
NamedType *namedTy = type->asNamedType();
|
||||
if (! namedTy) {
|
||||
if (PointerType *pointerTy = type->asPointerType())
|
||||
namedTy = pointerTy->elementType()->asNamedType();
|
||||
}
|
||||
return namedTy;
|
||||
}
|
||||
|
||||
QList<LookupItem> getNamedTypeItems(const Name *name, Scope *scope,
|
||||
ClassOrNamespace *binding) const
|
||||
{
|
||||
QList<LookupItem> namedTypeItems = typedefsFromScopeUpToFunctionScope(name, scope);
|
||||
if (namedTypeItems.isEmpty()) {
|
||||
if (binding)
|
||||
namedTypeItems = binding->lookup(name);
|
||||
if (ClassOrNamespace *scopeCon = _context.lookupType(scope))
|
||||
namedTypeItems += scopeCon->lookup(name);
|
||||
}
|
||||
|
||||
return namedTypeItems;
|
||||
}
|
||||
|
||||
/// Return all typedefs with given name from given scope up to function scope.
|
||||
static QList<LookupItem> typedefsFromScopeUpToFunctionScope(const Name *name, Scope *scope)
|
||||
{
|
||||
QList<LookupItem> results;
|
||||
if (!scope)
|
||||
return results;
|
||||
Scope *enclosingBlockScope = 0;
|
||||
for (Block *block = scope->asBlock(); block;
|
||||
block = enclosingBlockScope ? enclosingBlockScope->asBlock() : 0) {
|
||||
const unsigned memberCount = block->memberCount();
|
||||
for (unsigned i = 0; i < memberCount; ++i) {
|
||||
Symbol *symbol = block->memberAt(i);
|
||||
if (Declaration *declaration = symbol->asDeclaration()) {
|
||||
if (isTypedefWithName(declaration, name)) {
|
||||
LookupItem item;
|
||||
item.setDeclaration(declaration);
|
||||
item.setScope(block);
|
||||
item.setType(declaration->type());
|
||||
results.append(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
enclosingBlockScope = block->enclosingScope();
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
static bool isTypedefWithName(const Declaration *declaration, const Name *name)
|
||||
{
|
||||
if (declaration->isTypedef()) {
|
||||
const Identifier *identifier = declaration->name()->identifier();
|
||||
if (name->identifier()->match(identifier))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool findTypedef(const QList<LookupItem>& namedTypeItems, FullySpecifiedType *type,
|
||||
Scope **scope, QSet<Symbol *>& visited)
|
||||
{
|
||||
bool foundTypedef = false;
|
||||
foreach (const LookupItem &it, namedTypeItems) {
|
||||
Symbol *declaration = it.declaration();
|
||||
if (declaration && declaration->isTypedef()) {
|
||||
if (visited.contains(declaration))
|
||||
break;
|
||||
visited.insert(declaration);
|
||||
|
||||
// continue working with the typedefed type and scope
|
||||
if (type->type()->isPointerType()) {
|
||||
*type = FullySpecifiedType(
|
||||
_context.bindings()->control()->pointerType(declaration->type()));
|
||||
} else if (type->type()->isReferenceType()) {
|
||||
*type = FullySpecifiedType(
|
||||
_context.bindings()->control()->referenceType(
|
||||
declaration->type(),
|
||||
declaration->type()->asReferenceType()->isRvalueReference()));
|
||||
} else {
|
||||
*type = declaration->type();
|
||||
}
|
||||
|
||||
*scope = it.scope();
|
||||
_binding = it.binding();
|
||||
foundTypedef = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return foundTypedef;
|
||||
}
|
||||
|
||||
const LookupContext &_context;
|
||||
// binding has to be remembered in case of resolving typedefs for templates
|
||||
ClassOrNamespace *_binding;
|
||||
};
|
||||
|
||||
static int evaluateFunctionArgument(const FullySpecifiedType &actualTy,
|
||||
const FullySpecifiedType &formalTy)
|
||||
{
|
||||
@@ -176,7 +301,7 @@ void ResolveExpression::addResults(const QList<LookupItem> &items)
|
||||
}
|
||||
|
||||
void ResolveExpression::addResult(const FullySpecifiedType &ty, Scope *scope,
|
||||
LookupScope *binding)
|
||||
ClassOrNamespace *binding)
|
||||
{
|
||||
LookupItem item;
|
||||
item.setType(ty);
|
||||
@@ -206,7 +331,7 @@ bool ResolveExpression::visit(BinaryExpressionAST *ast)
|
||||
if (d->core_declarator) {
|
||||
if (DeclaratorIdAST *declaratorId = d->core_declarator->asDeclaratorId()) {
|
||||
if (NameAST *nameAST = declaratorId->name) {
|
||||
if (LookupScope *binding = baseExpression(_results, T_ARROW)) {
|
||||
if (ClassOrNamespace *binding = baseExpression(_results, T_ARROW)) {
|
||||
_results.clear();
|
||||
addResults(binding->lookup(nameAST->name));
|
||||
}
|
||||
@@ -487,14 +612,15 @@ bool ResolveExpression::visit(UnaryExpressionAST *ast)
|
||||
added = true;
|
||||
} else if (namedTy != 0) {
|
||||
const Name *starOp = control()->operatorNameId(OperatorNameId::StarOp);
|
||||
if (LookupScope *b = _context.lookupType(namedTy->name(), p.scope(), p.binding())) {
|
||||
if (ClassOrNamespace *b = _context.lookupType(namedTy->name(), p.scope(), p.binding())) {
|
||||
foreach (const LookupItem &r, b->find(starOp)) {
|
||||
Symbol *overload = r.declaration();
|
||||
if (Function *funTy = overload->type()->asFunctionType()) {
|
||||
if (maybeValidPrototype(funTy, 0)) {
|
||||
FullySpecifiedType retTy = funTy->returnType().simplified();
|
||||
if (Function *proto = instantiate(b->templateId(), funTy)->asFunctionType()) {
|
||||
FullySpecifiedType retTy = proto->returnType().simplified();
|
||||
p.setType(retTy);
|
||||
p.setScope(funTy->enclosingScope());
|
||||
p.setScope(proto->enclosingScope());
|
||||
it.setValue(p);
|
||||
added = true;
|
||||
break;
|
||||
@@ -503,6 +629,7 @@ bool ResolveExpression::visit(UnaryExpressionAST *ast)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!added)
|
||||
it.remove();
|
||||
}
|
||||
@@ -526,6 +653,48 @@ bool ResolveExpression::visit(QualifiedNameAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class DeduceAutoCheck : public ASTVisitor
|
||||
{
|
||||
public:
|
||||
DeduceAutoCheck(const Identifier *id, TranslationUnit *tu)
|
||||
: ASTVisitor(tu), _id(id), _block(false)
|
||||
{
|
||||
accept(tu->ast());
|
||||
}
|
||||
|
||||
virtual bool preVisit(AST *)
|
||||
{
|
||||
if (_block)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool visit(SimpleNameAST *ast)
|
||||
{
|
||||
if (ast->name
|
||||
&& ast->name->identifier()
|
||||
&& strcmp(ast->name->identifier()->chars(), _id->chars()) == 0) {
|
||||
_block = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(MemberAccessAST *ast)
|
||||
{
|
||||
accept(ast->base_expression);
|
||||
return false;
|
||||
}
|
||||
|
||||
const Identifier *_id;
|
||||
bool _block;
|
||||
};
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
bool ResolveExpression::visit(SimpleNameAST *ast)
|
||||
{
|
||||
QList<LookupItem> candidates = _context.lookup(ast->name, _scope);
|
||||
@@ -539,7 +708,7 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
||||
if (item.declaration() == 0)
|
||||
continue;
|
||||
|
||||
if (item.type().isAuto() || item.type().isDecltype()) {
|
||||
if (item.type().isAuto()) {
|
||||
const Declaration *decl = item.declaration()->asDeclaration();
|
||||
if (!decl)
|
||||
continue;
|
||||
@@ -548,10 +717,53 @@ bool ResolveExpression::visit(SimpleNameAST *ast)
|
||||
if (_autoDeclarationsBeingResolved.contains(decl))
|
||||
continue;
|
||||
|
||||
newCandidates +=
|
||||
TypeResolver::resolveDeclInitializer(*_context.bindings(), decl,
|
||||
_autoDeclarationsBeingResolved << decl,
|
||||
ast->name->identifier());
|
||||
const StringLiteral *initializationString = decl->getInitializer();
|
||||
if (initializationString == 0)
|
||||
continue;
|
||||
|
||||
const QByteArray &initializer =
|
||||
QByteArray::fromRawData(initializationString->chars(),
|
||||
initializationString->size()).trimmed();
|
||||
|
||||
// Skip lambda-function initializers
|
||||
if (initializer.length() > 0 && initializer[0] == '[')
|
||||
continue;
|
||||
|
||||
TypeOfExpression exprTyper;
|
||||
exprTyper.setExpandTemplates(true);
|
||||
Document::Ptr doc = _context.snapshot().document(QString::fromLocal8Bit(decl->fileName()));
|
||||
exprTyper.init(doc, _context.snapshot(), _context.bindings(),
|
||||
QSet<const Declaration* >(_autoDeclarationsBeingResolved) << decl);
|
||||
|
||||
Document::Ptr exprDoc =
|
||||
documentForExpression(exprTyper.preprocessedExpression(initializer));
|
||||
exprDoc->check();
|
||||
|
||||
DeduceAutoCheck deduceAuto(ast->name->identifier(), exprDoc->translationUnit());
|
||||
if (deduceAuto._block)
|
||||
continue;
|
||||
|
||||
const QList<LookupItem> &typeItems = exprTyper(extractExpressionAST(exprDoc), exprDoc,
|
||||
decl->enclosingScope());
|
||||
if (typeItems.empty())
|
||||
continue;
|
||||
|
||||
Clone cloner(_context.bindings()->control().data());
|
||||
|
||||
for (int n = 0; n < typeItems.size(); ++ n) {
|
||||
FullySpecifiedType newType = cloner.type(typeItems[n].type(), 0);
|
||||
if (n == 0) {
|
||||
item.setType(newType);
|
||||
item.setScope(typeItems[n].scope());
|
||||
item.setBinding(typeItems[n].binding());
|
||||
} else {
|
||||
LookupItem newItem(item);
|
||||
newItem.setType(newType);
|
||||
newItem.setScope(typeItems[n].scope());
|
||||
newItem.setBinding(typeItems[n].binding());
|
||||
newCandidates.push_back(newItem);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
item.setType(item.declaration()->type());
|
||||
item.setScope(item.declaration()->enclosingScope());
|
||||
@@ -661,12 +873,14 @@ bool ResolveExpression::visit(CallAST *ast)
|
||||
Scope *scope = result.scope();
|
||||
|
||||
if (NamedType *namedTy = ty->asNamedType()) {
|
||||
if (LookupScope *b = _context.lookupType(namedTy->name(), scope)) {
|
||||
if (ClassOrNamespace *b = _context.lookupType(namedTy->name(), scope)) {
|
||||
foreach (const LookupItem &r, b->find(functionCallOp)) {
|
||||
Symbol *overload = r.declaration();
|
||||
if (Function *funTy = overload->type()->asFunctionType()) {
|
||||
if (maybeValidPrototype(funTy, actualArgumentCount))
|
||||
addResult(funTy->returnType().simplified(), scope);
|
||||
if (maybeValidPrototype(funTy, actualArgumentCount)) {
|
||||
if (Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType())
|
||||
addResult(proto->returnType().simplified(), scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -679,6 +893,14 @@ bool ResolveExpression::visit(CallAST *ast)
|
||||
// Constructor call
|
||||
FullySpecifiedType ctorTy = control()->namedType(classTy->name());
|
||||
addResult(ctorTy, scope);
|
||||
} else if (Template *templateTy = ty->asTemplateType()) {
|
||||
// template function
|
||||
if (Symbol *declaration = templateTy->declaration()) {
|
||||
if (Function *funTy = declaration->asFunction()) {
|
||||
if (maybeValidPrototype(funTy, actualArgumentCount))
|
||||
addResult(funTy->returnType().simplified(), scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -694,8 +916,8 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
|
||||
FullySpecifiedType ty = result.type().simplified();
|
||||
Scope *scope = result.scope();
|
||||
|
||||
TypeResolver typeResolver(*_context.bindings());
|
||||
typeResolver.resolve(&ty, &scope, result.binding());
|
||||
TypedefsResolver typedefsResolver(_context);
|
||||
typedefsResolver.resolve(&ty, &scope, result.binding());
|
||||
|
||||
if (PointerType *ptrTy = ty->asPointerType()) {
|
||||
addResult(ptrTy->elementType().simplified(), scope);
|
||||
@@ -704,12 +926,13 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
|
||||
addResult(arrTy->elementType().simplified(), scope);
|
||||
|
||||
} else if (NamedType *namedTy = ty->asNamedType()) {
|
||||
if (LookupScope *b = _context.lookupType(namedTy->name(), scope)) {
|
||||
if (ClassOrNamespace *b = _context.lookupType(namedTy->name(), scope)) {
|
||||
foreach (const LookupItem &r, b->find(arrayAccessOp)) {
|
||||
Symbol *overload = r.declaration();
|
||||
if (Function *funTy = overload->type()->asFunctionType()) {
|
||||
if (Function *proto = instantiate(namedTy->name(), funTy)->asFunctionType())
|
||||
// ### TODO: check the actual arguments
|
||||
addResult(funTy->returnType().simplified(), scope);
|
||||
addResult(proto->returnType().simplified(), scope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -719,7 +942,7 @@ bool ResolveExpression::visit(ArrayAccessAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
QList<LookupItem> ResolveExpression::getMembers(LookupScope *binding, const Name *memberName) const
|
||||
QList<LookupItem> ResolveExpression::getMembers(ClassOrNamespace *binding, const Name *memberName) const
|
||||
{
|
||||
Q_UNUSED(binding);
|
||||
Q_UNUSED(memberName);
|
||||
@@ -788,17 +1011,17 @@ bool ResolveExpression::visit(MemberAccessAST *ast)
|
||||
// Remember the access operator.
|
||||
const int accessOp = tokenKind(ast->access_token);
|
||||
|
||||
if (LookupScope *binding = baseExpression(baseResults, accessOp))
|
||||
if (ClassOrNamespace *binding = baseExpression(baseResults, accessOp))
|
||||
addResults(binding->find(memberName));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
LookupScope *ResolveExpression::findClass(const FullySpecifiedType &originalTy, Scope *scope,
|
||||
LookupScope *enclosingBinding) const
|
||||
ClassOrNamespace *ResolveExpression::findClass(const FullySpecifiedType &originalTy, Scope *scope,
|
||||
ClassOrNamespace *enclosingBinding) const
|
||||
{
|
||||
FullySpecifiedType ty = originalTy.simplified();
|
||||
LookupScope *binding = 0;
|
||||
ClassOrNamespace *binding = 0;
|
||||
|
||||
if (Class *klass = ty->asClassType()) {
|
||||
if (scope->isBlock())
|
||||
@@ -816,14 +1039,15 @@ LookupScope *ResolveExpression::findClass(const FullySpecifiedType &originalTy,
|
||||
return binding;
|
||||
}
|
||||
|
||||
LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResults,
|
||||
ClassOrNamespace *ResolveExpression::baseExpression(const QList<LookupItem> &baseResults,
|
||||
int accessOp,
|
||||
bool *replacedDotOperator) const
|
||||
{
|
||||
if (Q_UNLIKELY(debug))
|
||||
qDebug() << "In ResolveExpression::baseExpression with" << baseResults.size() << "results...";
|
||||
int i = 0;
|
||||
TypeResolver typeResolver(*_context.bindings());
|
||||
Overview oo;
|
||||
TypedefsResolver typedefsResolver(_context);
|
||||
|
||||
foreach (const LookupItem &r, baseResults) {
|
||||
if (!r.type().type() || !r.scope())
|
||||
@@ -832,18 +1056,36 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
|
||||
FullySpecifiedType originalType = ty;
|
||||
Scope *scope = r.scope();
|
||||
|
||||
if (Q_UNLIKELY(debug))
|
||||
if (Q_UNLIKELY(debug)) {
|
||||
qDebug("trying result #%d", ++i);
|
||||
qDebug() << "- before typedef resolving we have:" << oo(ty);
|
||||
}
|
||||
|
||||
typeResolver.resolve(&ty, &scope, r.binding());
|
||||
typedefsResolver.resolve(&ty, &scope, r.binding());
|
||||
|
||||
if (Q_UNLIKELY(debug))
|
||||
qDebug() << "- after typedef resolving:" << oo(ty);
|
||||
|
||||
if (accessOp == T_ARROW) {
|
||||
if (PointerType *ptrTy = ty->asPointerType()) {
|
||||
FullySpecifiedType type = ptrTy->elementType();
|
||||
if (LookupScope *binding = findClass(type, scope))
|
||||
if (ClassOrNamespace *binding
|
||||
= findClassForTemplateParameterInExpressionScope(r.binding(),
|
||||
type)) {
|
||||
return binding;
|
||||
}
|
||||
if (ClassOrNamespace *binding = findClass(type, scope))
|
||||
return binding;
|
||||
|
||||
} else if (LookupScope *binding = findClass(ty, scope, r.binding())) {
|
||||
} else {
|
||||
ClassOrNamespace *binding
|
||||
= findClassForTemplateParameterInExpressionScope(r.binding(),
|
||||
ty);
|
||||
|
||||
if (! binding)
|
||||
binding = findClass(ty, scope, r.binding());
|
||||
|
||||
if (binding){
|
||||
// lookup for overloads of operator->
|
||||
|
||||
const OperatorNameId *arrowOp
|
||||
@@ -854,10 +1096,16 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
|
||||
continue;
|
||||
Scope *functionScope = overload->enclosingScope();
|
||||
|
||||
if (Function *funTy = overload->type()->asFunctionType()) {
|
||||
FullySpecifiedType retTy = funTy->returnType().simplified();
|
||||
if (overload->type()->isFunctionType()) {
|
||||
FullySpecifiedType overloadTy
|
||||
= instantiate(binding->templateId(), overload);
|
||||
Function *instantiatedFunction = overloadTy->asFunctionType();
|
||||
Q_ASSERT(instantiatedFunction != 0);
|
||||
|
||||
typeResolver.resolve(&retTy, &functionScope, r.binding());
|
||||
FullySpecifiedType retTy
|
||||
= instantiatedFunction->returnType().simplified();
|
||||
|
||||
typedefsResolver.resolve(&retTy, &functionScope, r.binding());
|
||||
|
||||
if (! retTy->isPointerType() && ! retTy->isNamedType())
|
||||
continue;
|
||||
@@ -865,20 +1113,20 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
|
||||
if (PointerType *ptrTy = retTy->asPointerType())
|
||||
retTy = ptrTy->elementType();
|
||||
|
||||
if (LookupScope *retBinding = findClass(retTy, functionScope))
|
||||
if (ClassOrNamespace *retBinding = findClass(retTy, functionScope))
|
||||
return retBinding;
|
||||
|
||||
if (scope != functionScope) {
|
||||
if (LookupScope *retBinding = findClass(retTy, scope))
|
||||
if (ClassOrNamespace *retBinding = findClass(retTy, scope))
|
||||
return retBinding;
|
||||
}
|
||||
|
||||
if (LookupScope *origin = binding->instantiationOrigin()) {
|
||||
if (ClassOrNamespace *origin = binding->instantiationOrigin()) {
|
||||
foreach (Symbol *originSymbol, origin->symbols()) {
|
||||
Scope *originScope = originSymbol->asScope();
|
||||
if (originScope && originScope != scope
|
||||
&& originScope != functionScope) {
|
||||
if (LookupScope *retBinding
|
||||
if (ClassOrNamespace *retBinding
|
||||
= findClass(retTy, originScope))
|
||||
return retBinding;
|
||||
}
|
||||
@@ -887,6 +1135,7 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (accessOp == T_DOT) {
|
||||
if (replacedDotOperator) {
|
||||
*replacedDotOperator = originalType->isPointerType() || ty->isPointerType();
|
||||
@@ -894,13 +1143,19 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
|
||||
ty = ptrTy->elementType();
|
||||
}
|
||||
|
||||
LookupScope *enclosingBinding = 0;
|
||||
if (LookupScope *binding = r.binding()) {
|
||||
if (ClassOrNamespace *binding
|
||||
= findClassForTemplateParameterInExpressionScope(r.binding(),
|
||||
ty)) {
|
||||
return binding;
|
||||
}
|
||||
|
||||
ClassOrNamespace *enclosingBinding = 0;
|
||||
if (ClassOrNamespace *binding = r.binding()) {
|
||||
if (binding->instantiationOrigin())
|
||||
enclosingBinding = binding;
|
||||
}
|
||||
|
||||
if (LookupScope *binding = findClass(ty, scope, enclosingBinding))
|
||||
if (ClassOrNamespace *binding = findClass(ty, scope, enclosingBinding))
|
||||
return binding;
|
||||
}
|
||||
}
|
||||
@@ -908,6 +1163,30 @@ LookupScope *ResolveExpression::baseExpression(const QList<LookupItem> &baseResu
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClassOrNamespace *ResolveExpression::findClassForTemplateParameterInExpressionScope(
|
||||
ClassOrNamespace *resultBinding,
|
||||
const FullySpecifiedType &ty) const
|
||||
{
|
||||
if (resultBinding) {
|
||||
if (ClassOrNamespace *origin = resultBinding->instantiationOrigin()) {
|
||||
foreach (Symbol *originSymbol, origin->symbols()) {
|
||||
if (Scope *originScope = originSymbol->asScope()) {
|
||||
if (ClassOrNamespace *retBinding = findClass(ty, originScope))
|
||||
return retBinding;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
FullySpecifiedType ResolveExpression::instantiate(const Name *className, Symbol *candidate) const
|
||||
{
|
||||
return DeprecatedGenTemplateInstance::instantiate(className, candidate,
|
||||
_context.bindings()->control());
|
||||
}
|
||||
|
||||
bool ResolveExpression::visit(PostIncrDecrAST *ast)
|
||||
{
|
||||
const QList<LookupItem> baseResults = resolve(ast->base_expression, _scope);
|
||||
@@ -921,7 +1200,7 @@ bool ResolveExpression::visit(ObjCMessageExpressionAST *ast)
|
||||
|
||||
foreach (const LookupItem &result, receiverResults) {
|
||||
FullySpecifiedType ty = result.type().simplified();
|
||||
LookupScope *binding = 0;
|
||||
ClassOrNamespace *binding = 0;
|
||||
|
||||
if (ObjCClass *clazz = ty->asObjCClassType()) {
|
||||
// static access, e.g.:
|
||||
|
@@ -53,25 +53,26 @@ public:
|
||||
QList<LookupItem> resolve(ExpressionAST *ast, Scope *scope, bool ref = false);
|
||||
QList<LookupItem> reference(ExpressionAST *ast, Scope *scope);
|
||||
|
||||
LookupScope *baseExpression(const QList<LookupItem> &baseResults,
|
||||
ClassOrNamespace *baseExpression(const QList<LookupItem> &baseResults,
|
||||
int accessOp,
|
||||
bool *replacedDotOperator = 0) const;
|
||||
|
||||
const LookupContext &context() const;
|
||||
|
||||
protected:
|
||||
LookupScope *findClass(const FullySpecifiedType &ty, Scope *scope,
|
||||
LookupScope *enclosingBinding = 0) const;
|
||||
ClassOrNamespace *findClass(const FullySpecifiedType &ty, Scope *scope,
|
||||
ClassOrNamespace *enclosingBinding = 0) const;
|
||||
|
||||
QList<LookupItem> expression(ExpressionAST *ast);
|
||||
|
||||
QList<LookupItem> switchResults(const QList<LookupItem> &symbols);
|
||||
FullySpecifiedType instantiate(const Name *className, Symbol *candidate) const;
|
||||
|
||||
QList<LookupItem> getMembers(LookupScope *binding, const Name *memberName) const;
|
||||
QList<LookupItem> getMembers(ClassOrNamespace *binding, const Name *memberName) const;
|
||||
|
||||
void thisObject();
|
||||
|
||||
void addResult(const FullySpecifiedType &ty, Scope *scope, LookupScope *binding = 0);
|
||||
void addResult(const FullySpecifiedType &ty, Scope *scope, ClassOrNamespace *binding = 0);
|
||||
void addResults(const QList<Symbol *> &symbols);
|
||||
void addResults(const QList<LookupItem> &items);
|
||||
|
||||
@@ -125,6 +126,10 @@ protected:
|
||||
|
||||
|
||||
private:
|
||||
ClassOrNamespace *findClassForTemplateParameterInExpressionScope(
|
||||
ClassOrNamespace *resultBinding,
|
||||
const FullySpecifiedType &ty) const;
|
||||
|
||||
Scope *_scope;
|
||||
const LookupContext& _context;
|
||||
Bind bind;
|
||||
|
@@ -50,7 +50,7 @@ TypeOfExpression::TypeOfExpression():
|
||||
}
|
||||
|
||||
void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot,
|
||||
CreateBindings::Ptr bindings,
|
||||
QSharedPointer<CreateBindings> bindings,
|
||||
const QSet<const Declaration *> &autoDeclarationsBeingResolved)
|
||||
{
|
||||
m_thisDocument = thisDocument;
|
||||
@@ -62,7 +62,7 @@ void TypeOfExpression::init(Document::Ptr thisDocument, const Snapshot &snapshot
|
||||
Q_ASSERT(m_bindings.isNull());
|
||||
m_bindings = bindings;
|
||||
if (m_bindings.isNull())
|
||||
m_bindings = CreateBindings::Ptr(new CreateBindings(thisDocument, snapshot));
|
||||
m_bindings = QSharedPointer<CreateBindings>(new CreateBindings(thisDocument, snapshot));
|
||||
|
||||
m_environment.clear();
|
||||
m_autoDeclarationsBeingResolved = autoDeclarationsBeingResolved;
|
||||
@@ -105,7 +105,7 @@ QList<LookupItem> TypeOfExpression::operator()(ExpressionAST *expression,
|
||||
|
||||
m_scope = scope;
|
||||
|
||||
m_bindings->addExpressionDocument(document);
|
||||
m_documents.append(document);
|
||||
m_lookupContext = LookupContext(document, m_thisDocument, m_snapshot, m_bindings);
|
||||
Q_ASSERT(!m_bindings.isNull());
|
||||
m_lookupContext.setExpandTemplates(m_expandTemplates);
|
||||
@@ -122,7 +122,7 @@ QList<LookupItem> TypeOfExpression::reference(ExpressionAST *expression,
|
||||
|
||||
m_scope = scope;
|
||||
|
||||
m_bindings->addExpressionDocument(document);
|
||||
m_documents.append(document);
|
||||
m_lookupContext = LookupContext(document, m_thisDocument, m_snapshot, m_bindings);
|
||||
Q_ASSERT(!m_bindings.isNull());
|
||||
m_lookupContext.setExpandTemplates(m_expandTemplates);
|
||||
|
@@ -62,7 +62,7 @@ public:
|
||||
*/
|
||||
void init(Document::Ptr thisDocument,
|
||||
const Snapshot &snapshot,
|
||||
CreateBindings::Ptr bindings = CreateBindings::Ptr(),
|
||||
QSharedPointer<CreateBindings> bindings = QSharedPointer<CreateBindings>(),
|
||||
const QSet<const Declaration *> &autoDeclarationsBeingResolved
|
||||
= QSet<const Declaration *>());
|
||||
|
||||
@@ -135,6 +135,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void processEnvironment(Document::Ptr doc, Environment *env,
|
||||
QSet<QString> *processed) const;
|
||||
|
||||
@@ -142,13 +143,20 @@ private:
|
||||
private:
|
||||
Document::Ptr m_thisDocument;
|
||||
Snapshot m_snapshot;
|
||||
CreateBindings::Ptr m_bindings;
|
||||
QSharedPointer<CreateBindings> m_bindings;
|
||||
ExpressionAST *m_ast;
|
||||
Scope *m_scope;
|
||||
LookupContext m_lookupContext;
|
||||
mutable QSharedPointer<Environment> m_environment;
|
||||
QSet<const Declaration *> m_autoDeclarationsBeingResolved;
|
||||
|
||||
bool m_expandTemplates;
|
||||
|
||||
// FIXME: This is a temporary hack to avoid dangling pointers.
|
||||
// Keep the expression documents and thus all the symbols and
|
||||
// their types alive until they are not needed any more.
|
||||
QList<Document::Ptr> m_documents;
|
||||
|
||||
QSet<const Declaration *> m_autoDeclarationsBeingResolved;
|
||||
};
|
||||
|
||||
ExpressionAST CPLUSPLUS_EXPORT *extractExpressionAST(Document::Ptr doc);
|
||||
|
@@ -1,262 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "TypeResolver.h"
|
||||
#include "Overview.h"
|
||||
#include "TypeOfExpression.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
static const bool debug = ! qgetenv("QTC_LOOKUPCONTEXT_DEBUG").isEmpty();
|
||||
|
||||
namespace CPlusPlus {
|
||||
|
||||
namespace {
|
||||
|
||||
class DeduceAutoCheck : public ASTVisitor
|
||||
{
|
||||
public:
|
||||
DeduceAutoCheck(const Identifier *id, TranslationUnit *tu)
|
||||
: ASTVisitor(tu), _id(id), _block(false)
|
||||
{
|
||||
accept(tu->ast());
|
||||
}
|
||||
|
||||
virtual bool preVisit(AST *)
|
||||
{
|
||||
if (_block)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual bool visit(SimpleNameAST *ast)
|
||||
{
|
||||
if (ast->name
|
||||
&& ast->name->identifier()
|
||||
&& strcmp(ast->name->identifier()->chars(), _id->chars()) == 0) {
|
||||
_block = true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual bool visit(MemberAccessAST *ast)
|
||||
{
|
||||
accept(ast->base_expression);
|
||||
return false;
|
||||
}
|
||||
|
||||
const Identifier *_id;
|
||||
bool _block;
|
||||
};
|
||||
|
||||
} // namespace anonymous
|
||||
|
||||
void TypeResolver::resolve(FullySpecifiedType *type, Scope **scope, LookupScope *binding)
|
||||
{
|
||||
QSet<Symbol *> visited;
|
||||
_binding = binding;
|
||||
// Use a hard limit when trying to resolve typedefs. Typedefs in templates can refer to
|
||||
// each other, each time enhancing the template argument and thus making it impossible to
|
||||
// use an "alreadyResolved" container. FIXME: We might overcome this by resolving the
|
||||
// template parameters.
|
||||
unsigned maxDepth = 15;
|
||||
Overview oo;
|
||||
if (Q_UNLIKELY(debug))
|
||||
qDebug() << "- before typedef resolving we have:" << oo(*type);
|
||||
for (NamedType *namedTy = 0; maxDepth && (namedTy = getNamedType(*type)); --maxDepth) {
|
||||
QList<LookupItem> namedTypeItems = getNamedTypeItems(namedTy->name(), *scope, _binding);
|
||||
|
||||
if (Q_UNLIKELY(debug))
|
||||
qDebug() << "-- we have" << namedTypeItems.size() << "candidates";
|
||||
|
||||
if (!findTypedef(namedTypeItems, type, scope, visited))
|
||||
break;
|
||||
}
|
||||
if (Q_UNLIKELY(debug))
|
||||
qDebug() << "- after typedef resolving:" << oo(*type);
|
||||
}
|
||||
|
||||
NamedType *TypeResolver::getNamedType(FullySpecifiedType &type) const
|
||||
{
|
||||
NamedType *namedTy = type->asNamedType();
|
||||
if (! namedTy) {
|
||||
if (PointerType *pointerTy = type->asPointerType())
|
||||
namedTy = pointerTy->elementType()->asNamedType();
|
||||
}
|
||||
return namedTy;
|
||||
}
|
||||
|
||||
QList<LookupItem> TypeResolver::getNamedTypeItems(const Name *name, Scope *scope,
|
||||
LookupScope *binding) const
|
||||
{
|
||||
QList<LookupItem> namedTypeItems = typedefsFromScopeUpToFunctionScope(name, scope);
|
||||
if (namedTypeItems.isEmpty()) {
|
||||
if (binding)
|
||||
namedTypeItems = binding->lookup(name);
|
||||
if (LookupScope *scopeCon = _factory.lookupType(scope)) {
|
||||
if (scopeCon != binding)
|
||||
namedTypeItems += scopeCon->lookup(name);
|
||||
}
|
||||
}
|
||||
|
||||
return namedTypeItems;
|
||||
}
|
||||
|
||||
/// Return all typedefs with given name from given scope up to function scope.
|
||||
QList<LookupItem> TypeResolver::typedefsFromScopeUpToFunctionScope(const Name *name, Scope *scope)
|
||||
{
|
||||
QList<LookupItem> results;
|
||||
if (!scope)
|
||||
return results;
|
||||
Scope *enclosingBlockScope = 0;
|
||||
for (Block *block = scope->asBlock(); block;
|
||||
block = enclosingBlockScope ? enclosingBlockScope->asBlock() : 0) {
|
||||
const unsigned memberCount = block->memberCount();
|
||||
for (unsigned i = 0; i < memberCount; ++i) {
|
||||
Symbol *symbol = block->memberAt(i);
|
||||
if (Declaration *declaration = symbol->asDeclaration()) {
|
||||
if (isTypedefWithName(declaration, name)) {
|
||||
LookupItem item;
|
||||
item.setDeclaration(declaration);
|
||||
item.setScope(block);
|
||||
item.setType(declaration->type());
|
||||
results.append(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
enclosingBlockScope = block->enclosingScope();
|
||||
if (enclosingBlockScope) {
|
||||
// For lambda, step beyond the function to its enclosing block
|
||||
if (Function *enclosingFunction = enclosingBlockScope->asFunction()) {
|
||||
if (!enclosingFunction->name())
|
||||
enclosingBlockScope = enclosingBlockScope->enclosingScope();
|
||||
}
|
||||
}
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
// Resolves auto and decltype initializer string
|
||||
QList<LookupItem> TypeResolver::resolveDeclInitializer(
|
||||
CreateBindings &factory, const Declaration *decl,
|
||||
const QSet<const Declaration* > &declarationsBeingResolved,
|
||||
const Identifier *id)
|
||||
{
|
||||
const StringLiteral *initializationString = decl->getInitializer();
|
||||
if (initializationString == 0)
|
||||
return QList<LookupItem>();
|
||||
|
||||
const QByteArray &initializer =
|
||||
QByteArray::fromRawData(initializationString->chars(),
|
||||
initializationString->size()).trimmed();
|
||||
|
||||
// Skip lambda-function initializers
|
||||
if (initializer.length() > 0 && initializer[0] == '[')
|
||||
return QList<LookupItem>();
|
||||
|
||||
TypeOfExpression exprTyper;
|
||||
exprTyper.setExpandTemplates(true);
|
||||
Document::Ptr doc = factory.snapshot().document(QString::fromLocal8Bit(decl->fileName()));
|
||||
exprTyper.init(doc, factory.snapshot(), factory.sharedFromThis(), declarationsBeingResolved);
|
||||
|
||||
Document::Ptr exprDoc =
|
||||
documentForExpression(exprTyper.preprocessedExpression(initializer));
|
||||
factory.addExpressionDocument(exprDoc);
|
||||
exprDoc->check();
|
||||
|
||||
if (id) {
|
||||
DeduceAutoCheck deduceAuto(id, exprDoc->translationUnit());
|
||||
if (deduceAuto._block)
|
||||
return QList<LookupItem>();
|
||||
}
|
||||
|
||||
return exprTyper(extractExpressionAST(exprDoc), exprDoc, decl->enclosingScope());
|
||||
}
|
||||
|
||||
bool TypeResolver::isTypedefWithName(const Declaration *declaration, const Name *name)
|
||||
{
|
||||
if (declaration->isTypedef()) {
|
||||
const Identifier *identifier = declaration->name()->identifier();
|
||||
if (name->identifier()->match(identifier))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TypeResolver::findTypedef(const QList<LookupItem> &namedTypeItems, FullySpecifiedType *type,
|
||||
Scope **scope, QSet<Symbol *> &visited)
|
||||
{
|
||||
foreach (const LookupItem &it, namedTypeItems) {
|
||||
Symbol *declaration = it.declaration();
|
||||
if (!declaration)
|
||||
continue;
|
||||
if (Template *specialization = declaration->asTemplate())
|
||||
declaration = specialization->declaration();
|
||||
if (!declaration || (!declaration->isTypedef() && !declaration->type().isDecltype()))
|
||||
continue;
|
||||
if (visited.contains(declaration))
|
||||
break;
|
||||
visited.insert(declaration);
|
||||
|
||||
// continue working with the typedefed type and scope
|
||||
if (type->type()->isPointerType()) {
|
||||
*type = FullySpecifiedType(
|
||||
_factory.control()->pointerType(declaration->type()));
|
||||
} else if (type->type()->isReferenceType()) {
|
||||
*type = FullySpecifiedType(
|
||||
_factory.control()->referenceType(
|
||||
declaration->type(),
|
||||
declaration->type()->asReferenceType()->isRvalueReference()));
|
||||
} else if (declaration->type().isDecltype()) {
|
||||
Declaration *decl = declaration->asDeclaration();
|
||||
const QList<LookupItem> resolved =
|
||||
resolveDeclInitializer(_factory, decl, QSet<const Declaration* >() << decl);
|
||||
if (!resolved.isEmpty()) {
|
||||
LookupItem item = resolved.first();
|
||||
*type = item.type();
|
||||
*scope = item.scope();
|
||||
_binding = item.binding();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
*type = it.type();
|
||||
}
|
||||
|
||||
*scope = it.scope();
|
||||
_binding = it.binding();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace CPlusPlus
|
@@ -36,7 +36,6 @@ HEADERS += \
|
||||
$$PWD/NamePrettyPrinter.h \
|
||||
$$PWD/TypeOfExpression.h \
|
||||
$$PWD/TypePrettyPrinter.h \
|
||||
$$PWD/TypeResolver.h \
|
||||
$$PWD/ResolveExpression.h \
|
||||
$$PWD/LookupItem.h \
|
||||
$$PWD/AlreadyConsideredClassContainer.h \
|
||||
@@ -45,6 +44,7 @@ HEADERS += \
|
||||
$$PWD/ASTPath.h \
|
||||
$$PWD/SnapshotSymbolVisitor.h \
|
||||
$$PWD/SymbolNameVisitor.h \
|
||||
$$PWD/DeprecatedGenTemplateInstance.h \
|
||||
$$PWD/FindUsages.h \
|
||||
$$PWD/DependencyTable.h \
|
||||
$$PWD/PreprocessorClient.h \
|
||||
@@ -67,7 +67,6 @@ SOURCES += \
|
||||
$$PWD/NamePrettyPrinter.cpp \
|
||||
$$PWD/TypeOfExpression.cpp \
|
||||
$$PWD/TypePrettyPrinter.cpp \
|
||||
$$PWD/TypeResolver.cpp \
|
||||
$$PWD/ResolveExpression.cpp \
|
||||
$$PWD/LookupItem.cpp \
|
||||
$$PWD/LookupContext.cpp \
|
||||
@@ -75,6 +74,7 @@ SOURCES += \
|
||||
$$PWD/ASTPath.cpp \
|
||||
$$PWD/SnapshotSymbolVisitor.cpp \
|
||||
$$PWD/SymbolNameVisitor.cpp \
|
||||
$$PWD/DeprecatedGenTemplateInstance.cpp \
|
||||
$$PWD/FindUsages.cpp \
|
||||
$$PWD/DependencyTable.cpp \
|
||||
$$PWD/PreprocessorClient.cpp \
|
||||
|
@@ -96,6 +96,7 @@ QtcLibrary {
|
||||
"CppRewriter.cpp", "CppRewriter.h",
|
||||
"cppmodelmanagerbase.cpp", "cppmodelmanagerbase.h",
|
||||
"DependencyTable.cpp", "DependencyTable.h",
|
||||
"DeprecatedGenTemplateInstance.cpp", "DeprecatedGenTemplateInstance.h",
|
||||
"ExpressionUnderCursor.cpp", "ExpressionUnderCursor.h",
|
||||
"FastPreprocessor.cpp", "FastPreprocessor.h",
|
||||
"FindUsages.cpp", "FindUsages.h",
|
||||
@@ -116,7 +117,6 @@ QtcLibrary {
|
||||
"SymbolNameVisitor.cpp", "SymbolNameVisitor.h",
|
||||
"TypeOfExpression.cpp", "TypeOfExpression.h",
|
||||
"TypePrettyPrinter.cpp", "TypePrettyPrinter.h",
|
||||
"TypeResolver.cpp", "TypeResolver.h",
|
||||
"cplusplus.qrc",
|
||||
"findcdbbreakpoint.cpp", "findcdbbreakpoint.h",
|
||||
"pp-cctype.h",
|
||||
|
@@ -795,7 +795,7 @@ static void buildContextProperties(
|
||||
Scope *typeScope = result.scope();
|
||||
if (!typeScope)
|
||||
typeScope = scope; // incorrect but may be an ok fallback
|
||||
LookupScope *binding = typeOf.context().lookupType(namedType->name(), typeScope);
|
||||
ClassOrNamespace *binding = typeOf.context().lookupType(namedType->name(), typeScope);
|
||||
if (binding && !binding->symbols().isEmpty()) {
|
||||
// find the best 'Class' symbol
|
||||
for (int i = binding->symbols().size() - 1; i >= 0; --i) {
|
||||
|
@@ -1453,9 +1453,10 @@ void CppQmlTypes::load(const QString &originId, const T &fakeMetaObjects, const
|
||||
object->setPrototype(proto);
|
||||
}
|
||||
}
|
||||
|
||||
// explicitly instantiate load for list and hash
|
||||
template void CppQmlTypes::load< QList<FakeMetaObject::ConstPtr> >(const QString &, const QList<FakeMetaObject::ConstPtr> &, const QString &);
|
||||
template void CppQmlTypes::load< QHash<QString, FakeMetaObject::ConstPtr> >(const QString &, const QHash<QString, FakeMetaObject::ConstPtr> &, const QString &);
|
||||
template QMLJS_EXPORT void CppQmlTypes::load< QList<FakeMetaObject::ConstPtr> >(const QString &, const QList<FakeMetaObject::ConstPtr> &, const QString &);
|
||||
template QMLJS_EXPORT void CppQmlTypes::load< QHash<QString, FakeMetaObject::ConstPtr> >(const QString &, const QHash<QString, FakeMetaObject::ConstPtr> &, const QString &);
|
||||
|
||||
QList<const CppComponentValue *> CppQmlTypes::createObjectsForImport(const QString &package, ComponentVersion version)
|
||||
{
|
||||
|
@@ -158,6 +158,11 @@ bool Utf8String::endsWith(const Utf8String &text) const
|
||||
return byteArray.endsWith(text.byteArray);
|
||||
}
|
||||
|
||||
bool Utf8String::isNull() const
|
||||
{
|
||||
return byteArray.isNull();
|
||||
}
|
||||
|
||||
bool Utf8String::isEmpty() const
|
||||
{
|
||||
return byteArray.isEmpty();
|
||||
|
@@ -86,6 +86,7 @@ public:
|
||||
bool startsWith(const char *text) const;
|
||||
bool startsWith(char character) const;
|
||||
bool endsWith(const Utf8String &text) const;
|
||||
bool isNull() const;
|
||||
bool isEmpty() const;
|
||||
bool hasContent() const;
|
||||
|
||||
|
@@ -173,7 +173,7 @@ void SshKeyGenerator::generateOpenSslPublicKeyString(const KeyPtr &key)
|
||||
void SshKeyGenerator::generateOpenSslPrivateKeyString(const KeyPtr &key)
|
||||
{
|
||||
QList<BigInt> params;
|
||||
const char *label;
|
||||
const char *label = "";
|
||||
switch (m_type) {
|
||||
case Rsa: {
|
||||
const QSharedPointer<RSA_PrivateKey> rsaKey
|
||||
@@ -197,6 +197,7 @@ void SshKeyGenerator::generateOpenSslPrivateKeyString(const KeyPtr &key)
|
||||
case Ecdsa:
|
||||
params << key.dynamicCast<ECDSA_PrivateKey>()->private_value();
|
||||
label = "EC PRIVATE KEY";
|
||||
break;
|
||||
}
|
||||
|
||||
DER_Encoder encoder;
|
||||
|
@@ -63,6 +63,7 @@ Item {
|
||||
cursorShape: dragging ? Qt.ClosedHandCursor : Qt.OpenHandCursor
|
||||
drag.minimumY: dragging ? 0 : -dragOffset // Account for parent change below
|
||||
drag.maximumY: draggerParent.height - (dragging ? 0 : dragOffset)
|
||||
drag.axis: Drag.YAxis
|
||||
}
|
||||
|
||||
DropArea {
|
||||
|
@@ -102,7 +102,7 @@ Flickable {
|
||||
draggerParent: categories
|
||||
width: 150
|
||||
height: parent.height
|
||||
dragOffset: parent.y
|
||||
dragOffset: loader.y
|
||||
|
||||
onDropped: {
|
||||
categories.moveCategories(sourceIndex, targetIndex);
|
||||
|
@@ -250,6 +250,10 @@ PathChooser::PathChooser(QWidget *parent) :
|
||||
|
||||
PathChooser::~PathChooser()
|
||||
{
|
||||
// Since it is our focusProxy it can receive focus-out and emit the signal
|
||||
// even when the possible ancestor-receiver is in mid of its destruction.
|
||||
disconnect(d->m_lineEdit, &QLineEdit::editingFinished, this, &PathChooser::editingFinished);
|
||||
|
||||
delete d;
|
||||
}
|
||||
|
||||
|
@@ -67,7 +67,7 @@ GdbServerProvider::GdbServerProvider(const QString &id)
|
||||
}
|
||||
|
||||
GdbServerProvider::GdbServerProvider(const GdbServerProvider &other)
|
||||
: m_id(other.m_id)
|
||||
: m_id(createId(other.m_id))
|
||||
, m_startupMode(other.m_startupMode)
|
||||
, m_initCommands(other.m_initCommands)
|
||||
, m_resetCommands(other.m_resetCommands)
|
||||
|
@@ -41,6 +41,8 @@
|
||||
#include <cpptools/cppprojects.h>
|
||||
#include <cpptools/cppworkingcopy.h>
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QDir>
|
||||
@@ -122,7 +124,7 @@ public:
|
||||
|
||||
optionsBuilder.addToolchainAndProjectDefines();
|
||||
|
||||
optionsBuilder.addResourceDirOptions();
|
||||
optionsBuilder.addPredefinedMacrosAndHeaderPathsOptions();
|
||||
optionsBuilder.addWrappedQtHeadersIncludePath();
|
||||
optionsBuilder.addHeaderPathOptions();
|
||||
optionsBuilder.addProjectConfigFileInclude();
|
||||
@@ -154,7 +156,21 @@ private:
|
||||
return false;
|
||||
}
|
||||
|
||||
void addResourceDirOptions()
|
||||
void addPredefinedMacrosAndHeaderPathsOptions()
|
||||
{
|
||||
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID)
|
||||
addPredefinedMacrosAndHeaderPathsOptionsForMsvc();
|
||||
else
|
||||
addPredefinedMacrosAndHeaderPathsOptionsForNonMsvc();
|
||||
}
|
||||
|
||||
void addPredefinedMacrosAndHeaderPathsOptionsForMsvc()
|
||||
{
|
||||
add(QLatin1String("-nostdinc"));
|
||||
add(QLatin1String("-undef"));
|
||||
}
|
||||
|
||||
void addPredefinedMacrosAndHeaderPathsOptionsForNonMsvc()
|
||||
{
|
||||
static const QString resourceDir = getResourceDir();
|
||||
if (!resourceDir.isEmpty()) {
|
||||
|
@@ -387,7 +387,7 @@ void CppEditorWidget::switchDeclarationDefinition(bool inNextSplit)
|
||||
} else if (functionDefinitionSymbol) {
|
||||
const Snapshot snapshot = d->m_modelManager->snapshot();
|
||||
LookupContext context(d->m_lastSemanticInfo.doc, snapshot);
|
||||
LookupScope *binding = context.lookupType(functionDefinitionSymbol);
|
||||
ClassOrNamespace *binding = context.lookupType(functionDefinitionSymbol);
|
||||
const QList<LookupItem> declarations = context.lookup(functionDefinitionSymbol->name(),
|
||||
functionDefinitionSymbol->enclosingScope());
|
||||
|
||||
|
@@ -331,10 +331,10 @@ bool CppClass::operator==(const CppClass &other)
|
||||
|
||||
void CppClass::lookupBases(Symbol *declaration, const LookupContext &context)
|
||||
{
|
||||
typedef QPair<LookupScope *, CppClass *> Data;
|
||||
typedef QPair<ClassOrNamespace *, CppClass *> Data;
|
||||
|
||||
if (LookupScope *clazz = context.lookupType(declaration)) {
|
||||
QSet<LookupScope *> visited;
|
||||
if (ClassOrNamespace *clazz = context.lookupType(declaration)) {
|
||||
QSet<ClassOrNamespace *> visited;
|
||||
|
||||
QQueue<Data> q;
|
||||
q.enqueue(qMakePair(clazz, this));
|
||||
@@ -342,8 +342,8 @@ void CppClass::lookupBases(Symbol *declaration, const LookupContext &context)
|
||||
Data current = q.dequeue();
|
||||
clazz = current.first;
|
||||
visited.insert(clazz);
|
||||
const QList<LookupScope *> &bases = clazz->usings();
|
||||
foreach (LookupScope *baseClass, bases) {
|
||||
const QList<ClassOrNamespace *> &bases = clazz->usings();
|
||||
foreach (ClassOrNamespace *baseClass, bases) {
|
||||
const QList<Symbol *> &symbols = baseClass->symbols();
|
||||
foreach (Symbol *symbol, symbols) {
|
||||
if (symbol->isClass() && (
|
||||
@@ -433,7 +433,7 @@ CppVariable::CppVariable(Symbol *declaration, const LookupContext &context, Scop
|
||||
}
|
||||
|
||||
if (typeName) {
|
||||
if (LookupScope *clazz = context.lookupType(typeName, scope)) {
|
||||
if (ClassOrNamespace *clazz = context.lookupType(typeName, scope)) {
|
||||
if (!clazz->symbols().isEmpty()) {
|
||||
Overview overview;
|
||||
Symbol *symbol = clazz->symbols().at(0);
|
||||
|
@@ -38,7 +38,6 @@
|
||||
#include <cplusplus/ExpressionUnderCursor.h>
|
||||
#include <cplusplus/ResolveExpression.h>
|
||||
#include <cplusplus/SimpleLexer.h>
|
||||
#include <cplusplus/Templates.h>
|
||||
#include <cplusplus/TypeOfExpression.h>
|
||||
#include <cpptools/cppmodelmanager.h>
|
||||
#include <cpptools/functionutils.h>
|
||||
@@ -184,7 +183,7 @@ Class *VirtualFunctionHelper::staticClassOfFunctionCallExpression_internal() con
|
||||
const QList<LookupItem> items = m_typeOfExpression(memberAccessAST->base_expression,
|
||||
m_expressionDocument, m_scope);
|
||||
ResolveExpression resolveExpression(m_typeOfExpression.context());
|
||||
LookupScope *binding = resolveExpression.baseExpression(items, m_accessTokenKind);
|
||||
ClassOrNamespace *binding = resolveExpression.baseExpression(items, m_accessTokenKind);
|
||||
if (binding) {
|
||||
if (Class *klass = binding->rootClass()) {
|
||||
result = klass;
|
||||
|
@@ -607,7 +607,7 @@ ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targetOffse
|
||||
SubstitutionEnvironment env;
|
||||
env.setContext(sourceContext);
|
||||
env.switchScope(sourceFunction->enclosingScope());
|
||||
LookupScope *targetCoN = targetContext.lookupType(targetFunction->enclosingScope());
|
||||
ClassOrNamespace *targetCoN = targetContext.lookupType(targetFunction->enclosingScope());
|
||||
if (!targetCoN)
|
||||
targetCoN = targetContext.globalNamespace();
|
||||
UseMinimalNames q(targetCoN);
|
||||
@@ -653,7 +653,7 @@ ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targetOffse
|
||||
SubstitutionEnvironment env;
|
||||
env.setContext(sourceContext);
|
||||
env.switchScope(sourceFunction);
|
||||
LookupScope *targetCoN = targetContext.lookupType(targetFunction);
|
||||
ClassOrNamespace *targetCoN = targetContext.lookupType(targetFunction);
|
||||
if (!targetCoN)
|
||||
targetCoN = targetContext.globalNamespace();
|
||||
UseMinimalNames q(targetCoN);
|
||||
|
@@ -567,15 +567,15 @@ public:
|
||||
|
||||
// Determine base classes
|
||||
QList<const Class *> baseClasses;
|
||||
QQueue<LookupScope *> baseClassQueue;
|
||||
QSet<LookupScope *> visitedBaseClasses;
|
||||
if (LookupScope *clazz = interface.context().lookupType(m_classAST->symbol))
|
||||
QQueue<ClassOrNamespace *> baseClassQueue;
|
||||
QSet<ClassOrNamespace *> visitedBaseClasses;
|
||||
if (ClassOrNamespace *clazz = interface.context().lookupType(m_classAST->symbol))
|
||||
baseClassQueue.enqueue(clazz);
|
||||
while (!baseClassQueue.isEmpty()) {
|
||||
LookupScope *clazz = baseClassQueue.dequeue();
|
||||
ClassOrNamespace *clazz = baseClassQueue.dequeue();
|
||||
visitedBaseClasses.insert(clazz);
|
||||
const QList<LookupScope *> bases = clazz->usings();
|
||||
foreach (LookupScope *baseClass, bases) {
|
||||
const QList<ClassOrNamespace *> bases = clazz->usings();
|
||||
foreach (ClassOrNamespace *baseClass, bases) {
|
||||
foreach (Symbol *symbol, baseClass->symbols()) {
|
||||
Class *base = symbol->asClass();
|
||||
if (base
|
||||
@@ -769,7 +769,7 @@ public:
|
||||
const LookupContext targetContext(headerFile->cppDocument(), snapshot());
|
||||
|
||||
const Class *targetClass = m_classAST->symbol;
|
||||
LookupScope *targetCoN = targetContext.lookupType(targetClass->enclosingScope());
|
||||
ClassOrNamespace *targetCoN = targetContext.lookupType(targetClass->enclosingScope());
|
||||
if (!targetCoN)
|
||||
targetCoN = targetContext.globalNamespace();
|
||||
UseMinimalNames useMinimalNames(targetCoN);
|
||||
@@ -866,7 +866,7 @@ public:
|
||||
implementationDoc->translationUnit()->getPosition(insertPos, &line, &column);
|
||||
Scope *targetScope = implementationDoc->scopeAt(line, column);
|
||||
const LookupContext targetContext(implementationDoc, snapshot());
|
||||
LookupScope *targetCoN = targetContext.lookupType(targetScope);
|
||||
ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
|
||||
if (!targetCoN)
|
||||
targetCoN = targetContext.globalNamespace();
|
||||
|
||||
|
@@ -219,7 +219,7 @@ Class *isMemberFunction(const LookupContext &context, Function *function)
|
||||
if (!q->base())
|
||||
return 0;
|
||||
|
||||
if (LookupScope *binding = context.lookupType(q->base(), enclosingScope)) {
|
||||
if (ClassOrNamespace *binding = context.lookupType(q->base(), enclosingScope)) {
|
||||
foreach (Symbol *s, binding->symbols()) {
|
||||
if (Class *matchingClass = s->asClass())
|
||||
return matchingClass;
|
||||
@@ -257,7 +257,7 @@ Namespace *isNamespaceFunction(const LookupContext &context, Function *function)
|
||||
if (!q->base())
|
||||
return 0;
|
||||
|
||||
if (LookupScope *binding = context.lookupType(q->base(), enclosingScope)) {
|
||||
if (ClassOrNamespace *binding = context.lookupType(q->base(), enclosingScope)) {
|
||||
foreach (Symbol *s, binding->symbols()) {
|
||||
if (Namespace *matchingNamespace = s->asNamespace())
|
||||
return matchingNamespace;
|
||||
@@ -1331,7 +1331,7 @@ void TranslateStringLiteral::match(const CppQuickFixInterface &interface,
|
||||
for (int i = path.size() - 1; i >= 0; --i) {
|
||||
if (FunctionDefinitionAST *definition = path.at(i)->asFunctionDefinition()) {
|
||||
Function *function = definition->symbol;
|
||||
LookupScope *b = interface.context().lookupType(function);
|
||||
ClassOrNamespace *b = interface.context().lookupType(function);
|
||||
if (b) {
|
||||
// Do we have a tr function?
|
||||
foreach (const LookupItem &r, b->find(trName)) {
|
||||
@@ -1592,7 +1592,7 @@ public:
|
||||
SubstitutionEnvironment env;
|
||||
env.setContext(context());
|
||||
env.switchScope(result.first().scope());
|
||||
LookupScope *con = typeOfExpression.context().lookupType(scope);
|
||||
ClassOrNamespace *con = typeOfExpression.context().lookupType(scope);
|
||||
if (!con)
|
||||
con = typeOfExpression.context().globalNamespace();
|
||||
UseMinimalNames q(con);
|
||||
@@ -2284,7 +2284,7 @@ Enum *findEnum(const QList<LookupItem> &results, const LookupContext &ctxt)
|
||||
if (Enum *e = type->asEnumType())
|
||||
return e;
|
||||
if (const NamedType *namedType = type->asNamedType()) {
|
||||
if (LookupScope *con = ctxt.lookupType(namedType->name(), result.scope())) {
|
||||
if (ClassOrNamespace *con = ctxt.lookupType(namedType->name(), result.scope())) {
|
||||
const QList<Enum *> enums = con->unscopedEnums();
|
||||
const Name *referenceName = namedType->name();
|
||||
if (const QualifiedNameId *qualifiedName = referenceName->asQualifiedNameId())
|
||||
@@ -2581,7 +2581,7 @@ public:
|
||||
Document::Ptr targetDoc = targetFile->cppDocument();
|
||||
Scope *targetScope = targetDoc->scopeAt(m_loc.line(), m_loc.column());
|
||||
LookupContext targetContext(targetDoc, snapshot());
|
||||
LookupScope *targetCoN = targetContext.lookupType(targetScope);
|
||||
ClassOrNamespace *targetCoN = targetContext.lookupType(targetScope);
|
||||
if (!targetCoN)
|
||||
targetCoN = targetContext.globalNamespace();
|
||||
|
||||
@@ -3215,7 +3215,7 @@ public:
|
||||
SubstitutionEnvironment env;
|
||||
env.setContext(context());
|
||||
env.switchScope(refFunc);
|
||||
LookupScope *targetCoN = context().lookupType(refFunc->enclosingScope());
|
||||
ClassOrNamespace *targetCoN = context().lookupType(refFunc->enclosingScope());
|
||||
if (!targetCoN)
|
||||
targetCoN = context().globalNamespace();
|
||||
UseMinimalNames subs(targetCoN);
|
||||
@@ -4644,7 +4644,7 @@ QString definitionSignature(const CppQuickFixInterface *assist,
|
||||
QTC_ASSERT(func, return QString());
|
||||
|
||||
LookupContext cppContext(targetFile->cppDocument(), assist->snapshot());
|
||||
LookupScope *cppCoN = cppContext.lookupType(scope);
|
||||
ClassOrNamespace *cppCoN = cppContext.lookupType(scope);
|
||||
if (!cppCoN)
|
||||
cppCoN = cppContext.globalNamespace();
|
||||
SubstitutionEnvironment env;
|
||||
@@ -5125,7 +5125,7 @@ public:
|
||||
SubstitutionEnvironment env;
|
||||
env.setContext(context());
|
||||
env.switchScope(result.first().scope());
|
||||
LookupScope *con = typeOfExpression.context().lookupType(scope);
|
||||
ClassOrNamespace *con = typeOfExpression.context().lookupType(scope);
|
||||
if (!con)
|
||||
con = typeOfExpression.context().globalNamespace();
|
||||
UseMinimalNames q(con);
|
||||
@@ -5724,7 +5724,7 @@ PointerType *determineConvertedType(NamedType *namedType, const LookupContext &c
|
||||
{
|
||||
if (!namedType)
|
||||
return 0;
|
||||
if (LookupScope *binding = context.lookupType(namedType->name(), scope)) {
|
||||
if (ClassOrNamespace *binding = context.lookupType(namedType->name(), scope)) {
|
||||
if (Symbol *objectClassSymbol = skipForwardDeclarations(binding->symbols())) {
|
||||
if (Class *klass = objectClassSymbol->asClass()) {
|
||||
for (auto it = klass->memberBegin(), end = klass->memberEnd(); it != end; ++it) {
|
||||
@@ -5782,7 +5782,7 @@ Class *senderOrReceiverClass(const CppQuickFixInterface &interface,
|
||||
NamedType *objectType = objectTypeBase->asNamedType();
|
||||
QTC_ASSERT(objectType, return 0);
|
||||
|
||||
LookupScope *objectClassCON = context.lookupType(objectType->name(), objectPointerScope);
|
||||
ClassOrNamespace *objectClassCON = context.lookupType(objectType->name(), objectPointerScope);
|
||||
QTC_ASSERT(objectClassCON, return 0);
|
||||
QTC_ASSERT(!objectClassCON->symbols().isEmpty(), return 0);
|
||||
|
||||
@@ -5834,7 +5834,7 @@ bool findConnectReplacement(const CppQuickFixInterface &interface,
|
||||
|
||||
// Minimize qualification
|
||||
Control *control = context.bindings()->control().data();
|
||||
LookupScope *functionCON = context.lookupParent(scope);
|
||||
ClassOrNamespace *functionCON = context.lookupParent(scope);
|
||||
const Name *shortName = LookupContext::minimalName(method, functionCON, control);
|
||||
if (!shortName->asQualifiedNameId())
|
||||
shortName = control->qualifiedNameId(classOfMethod->name(), shortName);
|
||||
|
@@ -152,8 +152,8 @@ public:
|
||||
QTC_ASSERT(m_params.staticClass, return 0);
|
||||
QTC_ASSERT(!m_params.snapshot.isEmpty(), return 0);
|
||||
|
||||
Class *functionsClass = m_finder.findMatchingClassDeclaration(
|
||||
m_params.function, m_params.snapshot, &m_params.typeOfExpression->context());
|
||||
Class *functionsClass = m_finder.findMatchingClassDeclaration(m_params.function,
|
||||
m_params.snapshot);
|
||||
if (!functionsClass)
|
||||
return 0;
|
||||
|
||||
|
@@ -972,20 +972,6 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_data()
|
||||
"template<class $T>\n"
|
||||
"using Foo = Bar<@T>;\n"
|
||||
);
|
||||
|
||||
QTest::newRow("qualifiedNames") << _(
|
||||
"struct C\n"
|
||||
"{\n"
|
||||
" struct Nested { int $member; };\n"
|
||||
" void f();\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void C::f()\n"
|
||||
"{\n"
|
||||
" C::Nested object;\n"
|
||||
" object.@member;\n"
|
||||
"}\n"
|
||||
);
|
||||
}
|
||||
|
||||
void CppEditorPlugin::test_FollowSymbolUnderCursor()
|
||||
@@ -1390,7 +1376,7 @@ void CppEditorPlugin::test_FollowSymbolUnderCursor_virtualFunctionCall_data()
|
||||
"template <class T> struct A { virtual void virt() {} };\n"
|
||||
"void f(A<int> *l) { l->$@virt(); }\n")
|
||||
<< (OverrideItemList()
|
||||
<< OverrideItem(QLatin1String("A<int>::virt"), 1));
|
||||
<< OverrideItem(QLatin1String("A::virt"), 1));
|
||||
|
||||
/// Check: Static type is nicely resolved, especially for QSharedPointers.
|
||||
QTest::newRow("QSharedPointer") << _(
|
||||
|
@@ -669,7 +669,7 @@ bool CheckSymbols::visit(NewExpressionAST *ast)
|
||||
if (highlightCtorDtorAsType) {
|
||||
accept(ast->new_type_id);
|
||||
} else {
|
||||
LookupScope *binding = 0;
|
||||
ClassOrNamespace *binding = 0;
|
||||
NameAST *nameAST = 0;
|
||||
if (ast->new_type_id) {
|
||||
for (SpecifierListAST *it = ast->new_type_id->type_specifier_list; it; it = it->next) {
|
||||
@@ -735,7 +735,7 @@ void CheckSymbols::checkNamespace(NameAST *name)
|
||||
unsigned line, column;
|
||||
getTokenStartPosition(name->firstToken(), &line, &column);
|
||||
|
||||
if (LookupScope *b = _context.lookupType(name->name, enclosingScope())) {
|
||||
if (ClassOrNamespace *b = _context.lookupType(name->name, enclosingScope())) {
|
||||
foreach (Symbol *s, b->symbols()) {
|
||||
if (s->isNamespace())
|
||||
return;
|
||||
@@ -768,14 +768,14 @@ bool CheckSymbols::hasVirtualDestructor(Class *klass) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckSymbols::hasVirtualDestructor(LookupScope *binding) const
|
||||
bool CheckSymbols::hasVirtualDestructor(ClassOrNamespace *binding) const
|
||||
{
|
||||
QSet<LookupScope *> processed;
|
||||
QList<LookupScope *> todo;
|
||||
QSet<ClassOrNamespace *> processed;
|
||||
QList<ClassOrNamespace *> todo;
|
||||
todo.append(binding);
|
||||
|
||||
while (!todo.isEmpty()) {
|
||||
LookupScope *b = todo.takeFirst();
|
||||
ClassOrNamespace *b = todo.takeFirst();
|
||||
if (b && !processed.contains(b)) {
|
||||
processed.insert(b);
|
||||
foreach (Symbol *s, b->symbols()) {
|
||||
@@ -857,7 +857,7 @@ bool CheckSymbols::visit(QualifiedNameAST *ast)
|
||||
{
|
||||
if (ast->name) {
|
||||
|
||||
LookupScope *binding = checkNestedName(ast);
|
||||
ClassOrNamespace *binding = checkNestedName(ast);
|
||||
|
||||
if (binding && ast->unqualified_name) {
|
||||
if (ast->unqualified_name->asDestructorName() != 0) {
|
||||
@@ -886,9 +886,9 @@ bool CheckSymbols::visit(QualifiedNameAST *ast)
|
||||
return false;
|
||||
}
|
||||
|
||||
LookupScope *CheckSymbols::checkNestedName(QualifiedNameAST *ast)
|
||||
ClassOrNamespace *CheckSymbols::checkNestedName(QualifiedNameAST *ast)
|
||||
{
|
||||
LookupScope *binding = 0;
|
||||
ClassOrNamespace *binding = 0;
|
||||
|
||||
if (ast->name) {
|
||||
if (NestedNameSpecifierListAST *it = ast->nested_name_specifier_list) {
|
||||
@@ -954,7 +954,7 @@ bool CheckSymbols::visit(MemInitializerAST *ast)
|
||||
{
|
||||
if (FunctionDefinitionAST *enclosingFunction = enclosingFunctionDefinition()) {
|
||||
if (ast->name && enclosingFunction->symbol) {
|
||||
if (LookupScope *binding = _context.lookupType(enclosingFunction->symbol)) {
|
||||
if (ClassOrNamespace *binding = _context.lookupType(enclosingFunction->symbol)) {
|
||||
foreach (Symbol *s, binding->symbols()) {
|
||||
if (Class *klass = s->asClass()) {
|
||||
NameAST *nameAST = ast->name;
|
||||
@@ -1157,7 +1157,7 @@ void CheckSymbols::addUse(const Result &use)
|
||||
_usages.append(use);
|
||||
}
|
||||
|
||||
void CheckSymbols::addType(LookupScope *b, NameAST *ast)
|
||||
void CheckSymbols::addType(ClassOrNamespace *b, NameAST *ast)
|
||||
{
|
||||
unsigned startToken;
|
||||
if (!b || !acceptName(ast, &startToken))
|
||||
@@ -1296,8 +1296,12 @@ bool CheckSymbols::maybeAddFunction(const QList<LookupItem> &candidates, NameAST
|
||||
isConstructor = isConstructorDeclaration(c);
|
||||
|
||||
Function *funTy = c->type()->asFunctionType();
|
||||
if (!funTy) // Template function has an overridden type
|
||||
funTy = r.type()->asFunctionType();
|
||||
if (!funTy) {
|
||||
//Try to find a template function
|
||||
if (Template * t = r.type()->asTemplateType())
|
||||
if ((c = t->declaration()))
|
||||
funTy = c->type()->asFunctionType();
|
||||
}
|
||||
if (!funTy || funTy->isAmbiguous())
|
||||
continue; // TODO: add diagnostic messages and color call-operators calls too?
|
||||
|
||||
|
@@ -105,7 +105,7 @@ protected:
|
||||
const QList<Result> &otherUses);
|
||||
|
||||
bool hasVirtualDestructor(CPlusPlus::Class *klass) const;
|
||||
bool hasVirtualDestructor(CPlusPlus::LookupScope *binding) const;
|
||||
bool hasVirtualDestructor(CPlusPlus::ClassOrNamespace *binding) const;
|
||||
|
||||
bool warning(unsigned line, unsigned column, const QString &text, unsigned length = 0);
|
||||
bool warning(CPlusPlus::AST *ast, const QString &text);
|
||||
@@ -119,13 +119,13 @@ protected:
|
||||
|
||||
void checkNamespace(CPlusPlus::NameAST *name);
|
||||
void checkName(CPlusPlus::NameAST *ast, CPlusPlus::Scope *scope = 0);
|
||||
CPlusPlus::LookupScope *checkNestedName(CPlusPlus::QualifiedNameAST *ast);
|
||||
CPlusPlus::ClassOrNamespace *checkNestedName(CPlusPlus::QualifiedNameAST *ast);
|
||||
|
||||
void addUse(const Result &use);
|
||||
void addUse(unsigned tokenIndex, Kind kind);
|
||||
void addUse(CPlusPlus::NameAST *name, Kind kind);
|
||||
|
||||
void addType(CPlusPlus::LookupScope *b, CPlusPlus::NameAST *ast);
|
||||
void addType(CPlusPlus::ClassOrNamespace *b, CPlusPlus::NameAST *ast);
|
||||
|
||||
bool maybeAddTypeOrStatic(const QList<CPlusPlus::LookupItem> &candidates,
|
||||
CPlusPlus::NameAST *ast);
|
||||
|
@@ -328,17 +328,16 @@ void CppToolsPlugin::test_completion()
|
||||
actualCompletions.sort();
|
||||
expectedCompletions.sort();
|
||||
|
||||
QEXPECT_FAIL("template_as_base: typedef not available in derived",
|
||||
"We can live with that...", Abort);
|
||||
QEXPECT_FAIL("template_specialization_with_reference", "test of reverted change", Abort);
|
||||
QEXPECT_FAIL("specialization_multiple_arguments", "test of reverted change", Abort);
|
||||
QEXPECT_FAIL("specialization_with_default_value", "test of reverted change", Abort);
|
||||
QEXPECT_FAIL("template_as_base: explicit typedef from base", "QTCREATORBUG-14218", Abort);
|
||||
QEXPECT_FAIL("enum_in_function_in_struct_in_function", "QTCREATORBUG-13757", Abort);
|
||||
QEXPECT_FAIL("enum_in_function_in_struct_in_function_cxx11", "QTCREATORBUG-13757", Abort);
|
||||
QEXPECT_FAIL("enum_in_function_in_struct_in_function_anon", "QTCREATORBUG-13757", Abort);
|
||||
QEXPECT_FAIL("enum_in_class_accessed_in_member_func_cxx11", "QTCREATORBUG-13757", Abort);
|
||||
QEXPECT_FAIL("enum_in_class_accessed_in_member_func_inline_cxx11", "QTCREATORBUG-13757", Abort);
|
||||
QEXPECT_FAIL("recursive_instantiation_of_template_type", "QTCREATORBUG-14237", Abort);
|
||||
QEXPECT_FAIL("pointer_indirect_specialization", "QTCREATORBUG-14141", Abort);
|
||||
QEXPECT_FAIL("pointer_indirect_specialization_typedef", "QTCREATORBUG-14141", Abort);
|
||||
QEXPECT_FAIL("pointer_indirect_specialization_double_indirection", "QTCREATORBUG-14141", Abort);
|
||||
QEXPECT_FAIL("pointer_indirect_specialization_double_indirection_with_base", "QTCREATORBUG-14141", Abort);
|
||||
QCOMPARE(actualCompletions, expectedCompletions);
|
||||
}
|
||||
|
||||
@@ -802,21 +801,6 @@ void CppToolsPlugin::test_completion_data()
|
||||
<< QLatin1String("Data")
|
||||
<< QLatin1String("dataMember"));
|
||||
|
||||
QTest::newRow("explicit_instantiation") << _(
|
||||
"template<class T>\n"
|
||||
"struct Foo { T bar; };\n"
|
||||
"\n"
|
||||
"template class Foo<int>;\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Foo<int> foo;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("foo.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("use_global_identifier_as_base_class: derived as global and base as global") << _(
|
||||
"struct Global\n"
|
||||
"{\n"
|
||||
@@ -1327,29 +1311,22 @@ void CppToolsPlugin::test_completion_data()
|
||||
<< QLatin1String("Template1"));
|
||||
|
||||
QTest::newRow("template_specialization_with_pointer") << _(
|
||||
"template <typename T> struct Temp { T variable; };\n"
|
||||
"template <typename T> struct Temp<T *> { T *pointer; };\n"
|
||||
"void func()\n"
|
||||
"template <typename T>\n"
|
||||
"struct Template\n"
|
||||
"{\n"
|
||||
" Temp<int*> templ;\n"
|
||||
" @\n"
|
||||
"}"
|
||||
" T variable;\n"
|
||||
"};\n"
|
||||
"template <typename T>\n"
|
||||
"struct Template<T *>\n"
|
||||
"{\n"
|
||||
" T *pointer;\n"
|
||||
"};\n"
|
||||
"Template<int*> templ;\n"
|
||||
"@\n"
|
||||
) << _("templ.") << (QStringList()
|
||||
<< QLatin1String("Temp")
|
||||
<< QLatin1String("Template")
|
||||
<< QLatin1String("pointer"));
|
||||
|
||||
QTest::newRow("template_specialization_with_reference") << _(
|
||||
"template <typename T> struct Temp { T variable; };\n"
|
||||
"template <typename T> struct Temp<T &> { T reference; };\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Temp<int&> templ;\n"
|
||||
" @\n"
|
||||
"}"
|
||||
) << _("templ.") << (QStringList()
|
||||
<< QLatin1String("Temp")
|
||||
<< QLatin1String("reference"));
|
||||
|
||||
QTest::newRow("typedef_using_templates1") << _(
|
||||
"namespace NS1\n"
|
||||
"{\n"
|
||||
@@ -1572,29 +1549,6 @@ void CppToolsPlugin::test_completion_data()
|
||||
<< QLatin1String("C")
|
||||
<< QLatin1String("m"));
|
||||
|
||||
QTest::newRow("type_and_using_declaration: type in nested namespace and using in global") << _(
|
||||
"namespace Ns {\n"
|
||||
"namespace Nested {\n"
|
||||
"struct Foo\n"
|
||||
"{\n"
|
||||
" void func();\n"
|
||||
" int m_bar;\n"
|
||||
"};\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
"\n"
|
||||
"using namespace Ns::Nested;\n"
|
||||
"\n"
|
||||
"namespace Ns\n"
|
||||
"{\n"
|
||||
"void Foo::func()\n"
|
||||
"{\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
"}\n"
|
||||
) << _("m_") << (QStringList()
|
||||
<< QLatin1String("m_bar"));
|
||||
|
||||
QTest::newRow("instantiate_template_with_anonymous_class") << _(
|
||||
"template <typename T>\n"
|
||||
"struct S\n"
|
||||
@@ -2568,21 +2522,6 @@ void CppToolsPlugin::test_completion_data()
|
||||
) << _("ar") << (QStringList()
|
||||
<< QLatin1String("arg1"));
|
||||
|
||||
QTest::newRow("local_typedef_access_in_lambda") << _(
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" typedef Foo F;\n"
|
||||
" []() {\n"
|
||||
" F f;\n"
|
||||
" @\n"
|
||||
" };\n"
|
||||
"}\n"
|
||||
) << _("f.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("default_arguments_for_class_templates_and_base_class_QTCREATORBUG-12605") << _(
|
||||
"struct Foo { int foo; };\n"
|
||||
"template <typename T = Foo>\n"
|
||||
@@ -2689,78 +2628,6 @@ void CppToolsPlugin::test_completion_data()
|
||||
) << _("s.") << (QStringList()
|
||||
<< QLatin1String("S"));
|
||||
|
||||
QTest::newRow("partial_specialization") << _(
|
||||
"struct b {};\n"
|
||||
"template<class X, class Y> struct s { float f; };\n"
|
||||
"template<class X> struct s<X, b> { int i; };\n"
|
||||
"\n"
|
||||
"void f()\n"
|
||||
"{\n"
|
||||
" s<int, b> var;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("var.") << (QStringList()
|
||||
<< QLatin1String("i")
|
||||
<< QLatin1String("s"));
|
||||
|
||||
// QTest::newRow("partial_specialization_with_pointer") << _(
|
||||
// "struct b {};\n"
|
||||
// "struct a : b {};\n"
|
||||
// "template<class X, class Y> struct s { float f; };\n"
|
||||
// "template<class X> struct s<X, b*> { int i; };\n"
|
||||
// "template<class X> struct s<X, a*> { char j; };\n"
|
||||
// "\n"
|
||||
// "void f()\n"
|
||||
// "{\n"
|
||||
// " s<int, a*> var;\n"
|
||||
// " @\n"
|
||||
// "}\n"
|
||||
// ) << _("var.") << (QStringList()
|
||||
// << QLatin1String("j")
|
||||
// << QLatin1String("s"));
|
||||
|
||||
QTest::newRow("partial_specialization_templated_argument") << _(
|
||||
"template<class T> struct t {};\n"
|
||||
"\n"
|
||||
"template<class> struct s { float f; };\n"
|
||||
"template<class X> struct s<t<X>> { int i; };\n"
|
||||
"\n"
|
||||
"void f()\n"
|
||||
"{\n"
|
||||
" s<t<char>> var;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("var.") << (QStringList()
|
||||
<< QLatin1String("i")
|
||||
<< QLatin1String("s"));
|
||||
|
||||
QTest::newRow("specialization_multiple_arguments") << _(
|
||||
"class false_type {};\n"
|
||||
"class true_type {};\n"
|
||||
"template<class T1, class T2> class and_type { false_type f; };\n"
|
||||
"template<> class and_type<true_type, true_type> { true_type t; };\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" and_type<true_type, false_type> a;\n"
|
||||
" @;\n"
|
||||
"}\n"
|
||||
) << _("a.") << (QStringList()
|
||||
<< QLatin1String("f")
|
||||
<< QLatin1String("and_type"));
|
||||
|
||||
QTest::newRow("specialization_with_default_value") << _(
|
||||
"class Foo {};\n"
|
||||
"template<class T1 = Foo> class Temp;\n"
|
||||
"template<> class Temp<Foo> { int var; };\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Temp<> t;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("t.") << (QStringList()
|
||||
<< QLatin1String("var")
|
||||
<< QLatin1String("Temp"));
|
||||
|
||||
QTest::newRow("auto_declaration_in_if_condition") << _(
|
||||
"struct Foo { int bar; };\n"
|
||||
"void fun() {\n"
|
||||
@@ -2966,28 +2833,6 @@ void CppToolsPlugin::test_completion_data()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("instantiation_of_indirect_typedef") << _(
|
||||
"template<typename _Tp>\n"
|
||||
"struct Indirect { _Tp t; };\n"
|
||||
"\n"
|
||||
"template<typename T>\n"
|
||||
"struct Temp\n"
|
||||
"{\n"
|
||||
" typedef T MyT;\n"
|
||||
" typedef Indirect<MyT> indirect;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Temp<Foo>::indirect i;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("i.t.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));;
|
||||
|
||||
QTest::newRow("pointer_indirect_specialization_double_indirection_with_base") << _(
|
||||
"template<typename _Tp>\n"
|
||||
"struct Traits { };\n"
|
||||
@@ -3024,337 +2869,6 @@ void CppToolsPlugin::test_completion_data()
|
||||
) << _("t.p->") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("recursive_instantiation_of_template_type") << _(
|
||||
"template<typename _Tp>\n"
|
||||
"struct Temp { typedef _Tp value_type; };\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Temp<Temp<Foo> >::value_type::value_type *p;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("p->") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("recursive_instantiation_of_template_type_2") << _(
|
||||
"template<typename _Tp>\n"
|
||||
"struct Temp { typedef _Tp value_type; };\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Temp<Temp<Foo>::value_type>::value_type *p;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("p->") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("template_using_instantiation") << _(
|
||||
"template<typename _Tp>\n"
|
||||
"using T = _Tp;\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" T<Foo> p;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("p.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("nested_template_using_instantiation") << _(
|
||||
"struct Parent {\n"
|
||||
" template<typename _Tp>\n"
|
||||
" using T = _Tp;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Parent::T<Foo> p;\n"
|
||||
" @;\n"
|
||||
"}\n"
|
||||
) << _("p.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("nested_template_using_instantiation_in_template_class") << _(
|
||||
"template<typename ParentT>\n"
|
||||
"struct Parent {\n"
|
||||
" template<typename _Tp>\n"
|
||||
" using T = _Tp;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Parent<Foo>::T<Foo> p;\n"
|
||||
" @;\n"
|
||||
"}\n"
|
||||
) << _("p.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("recursive_nested_template_using_instantiation") << _(
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"struct A { typedef Foo value_type; };\n"
|
||||
"\n"
|
||||
"template<typename T>\n"
|
||||
"struct Traits\n"
|
||||
"{\n"
|
||||
" typedef Foo value_type;\n"
|
||||
"\n"
|
||||
" template<typename _Tp>\n"
|
||||
" using U = T;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template<typename T>\n"
|
||||
"struct Temp\n"
|
||||
"{\n"
|
||||
" typedef Traits<T> TraitsT;\n"
|
||||
" typedef typename T::value_type value_type;\n"
|
||||
" typedef typename TraitsT::template U<Foo> rebind;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" typename Temp<typename Temp<A>::rebind>::value_type p;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("p.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("qualified_name_in_nested_type") << _(
|
||||
"template<typename _Tp>\n"
|
||||
"struct Temp {\n"
|
||||
" struct Nested {\n"
|
||||
" typedef typename _Tp::Nested2 N;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct Foo {\n"
|
||||
" struct Nested2 {\n"
|
||||
" int bar;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Temp<Foo>::Nested::N p;\n"
|
||||
" @;\n"
|
||||
"}\n"
|
||||
) << _("p.") << (QStringList()
|
||||
<< QLatin1String("Nested2")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("simple_decltype_declaration") << _(
|
||||
"struct Foo { int bar; };\n"
|
||||
"Foo foo;\n"
|
||||
"void fun() {\n"
|
||||
" decltype(foo) s;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("s.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("typedefed_decltype_declaration") << _(
|
||||
"struct Foo { int bar; };\n"
|
||||
"Foo foo;\n"
|
||||
"typedef decltype(foo) TypedefedFooWithDecltype;\n"
|
||||
"void fun() {\n"
|
||||
" TypedefedFooWithDecltype s;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("s.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("nested_instantiation_typedefed_decltype_declaration") << _(
|
||||
"template <typename T>\n"
|
||||
"struct Temp\n"
|
||||
"{\n"
|
||||
" struct Nested\n"
|
||||
" {\n"
|
||||
" static T f();\n"
|
||||
" typedef decltype(f()) type;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void fun()\n"
|
||||
"{\n"
|
||||
" Temp<Foo>::Nested::type s;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("s.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("typedefed_decltype_of_template_function") << _(
|
||||
"template<typename T>\n"
|
||||
"static T f();\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void fun()\n"
|
||||
"{\n"
|
||||
" decltype(f<Foo>()) s;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("s.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("nested_instantiation_typedefed_decltype_declaration_of_template_function") << _(
|
||||
"template <typename T, typename D = T>\n"
|
||||
"struct Temp\n"
|
||||
"{\n"
|
||||
" struct Nested\n"
|
||||
" {\n"
|
||||
" template<typename U> static T* __test(...);\n"
|
||||
" typedef decltype(__test<D>(0)) type;\n"
|
||||
" };\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" Temp<Foo>::Nested::type s;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("s.") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
|
||||
QTest::newRow("typedef for templates in namespace") << _(
|
||||
"namespace N {\n"
|
||||
"\n"
|
||||
"struct Data { int x; };\n"
|
||||
"template <typename T> struct Foo { T member; };\n"
|
||||
"typedef Foo<Data> Bar;\n"
|
||||
"\n"
|
||||
"} // N\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"void f()\n"
|
||||
"{\n"
|
||||
" N::Bar o;\n"
|
||||
" @\n"
|
||||
"}\n"
|
||||
) << _("o.member.") << (QStringList()
|
||||
<< QLatin1String("Data")
|
||||
<< QLatin1String("x"));
|
||||
|
||||
QTest::newRow("std vector") << _(
|
||||
"namespace std\n"
|
||||
"{\n"
|
||||
"template<typename _Tp>\n"
|
||||
"struct allocator\n"
|
||||
"{\n"
|
||||
" typedef _Tp value_type;\n"
|
||||
"\n"
|
||||
" template<typename _Tp1>\n"
|
||||
" struct rebind\n"
|
||||
" { typedef allocator<_Tp1> other; };\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template<typename _Alloc, typename _Tp>\n"
|
||||
"struct __alloctr_rebind\n"
|
||||
"{\n"
|
||||
" typedef typename _Alloc::template rebind<_Tp>::other __type;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template<typename _Alloc>\n"
|
||||
"struct allocator_traits\n"
|
||||
"{\n"
|
||||
" typedef typename _Alloc::value_type value_type;\n"
|
||||
"\n"
|
||||
" template<typename _Tp>\n"
|
||||
" using rebind_alloc = typename __alloctr_rebind<_Alloc, _Tp>::__type;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template<typename _Iterator>\n"
|
||||
"struct iterator_traits { };\n"
|
||||
"\n"
|
||||
"template<typename _Tp>\n"
|
||||
"struct iterator_traits<_Tp*>\n"
|
||||
"{\n"
|
||||
" typedef _Tp* pointer;\n"
|
||||
"};\n"
|
||||
"} // namespace std\n"
|
||||
"\n"
|
||||
"namespace __gnu_cxx\n"
|
||||
"{\n"
|
||||
"template<typename _Alloc>\n"
|
||||
"struct __alloc_traits\n"
|
||||
"{\n"
|
||||
" typedef _Alloc allocator_type;\n"
|
||||
" typedef std::allocator_traits<_Alloc> _Base_type;\n"
|
||||
" typedef typename _Alloc::value_type value_type;\n"
|
||||
"\n"
|
||||
" static value_type *_S_pointer_helper(...);\n"
|
||||
" typedef decltype(_S_pointer_helper((_Alloc*)0)) __pointer;\n"
|
||||
" typedef __pointer pointer;\n"
|
||||
"\n"
|
||||
" template<typename _Tp>\n"
|
||||
" struct rebind\n"
|
||||
" { typedef typename _Base_type::template rebind_alloc<_Tp> other; };\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template<typename _Iterator, typename _Container>\n"
|
||||
"struct __normal_iterator\n"
|
||||
"{\n"
|
||||
" typedef std::iterator_traits<_Iterator> __traits_type;\n"
|
||||
" typedef typename __traits_type::pointer pointer;\n"
|
||||
"\n"
|
||||
" pointer p;\n"
|
||||
"};\n"
|
||||
"} // namespace __gnu_cxx\n"
|
||||
"\n"
|
||||
"namespace std {\n"
|
||||
"template<typename _Tp, typename _Alloc>\n"
|
||||
"struct _Vector_Base\n"
|
||||
"{\n"
|
||||
" typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template\n"
|
||||
" rebind<_Tp>::other _Tp_alloc_type;\n"
|
||||
" typedef typename __gnu_cxx::__alloc_traits<_Tp_alloc_type>::pointer\n"
|
||||
" pointer;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"template<typename _Tp, typename _Alloc = std::allocator<_Tp> >\n"
|
||||
"struct vector : protected _Vector_Base<_Tp, _Alloc>\n"
|
||||
"{\n"
|
||||
" typedef _Vector_Base<_Tp, _Alloc> _Base;\n"
|
||||
" typedef typename _Base::pointer pointer;\n"
|
||||
" typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;\n"
|
||||
"};\n"
|
||||
"} // namespace std\n"
|
||||
"\n"
|
||||
"struct Foo { int bar; };\n"
|
||||
"\n"
|
||||
"void func()\n"
|
||||
"{\n"
|
||||
" std::vector<Foo>::iterator it;\n"
|
||||
" @;\n"
|
||||
"}\n"
|
||||
) << _("it.p->") << (QStringList()
|
||||
<< QLatin1String("Foo")
|
||||
<< QLatin1String("bar"));
|
||||
}
|
||||
|
||||
void CppToolsPlugin::test_completion_member_access_operator()
|
||||
|
@@ -753,7 +753,7 @@ bool canCompleteClassNameAt2ndOr4thConnectArgument(
|
||||
|| eater.eatConnectOpenParenthesisExpressionCommaAmpersandExpressionComma();
|
||||
}
|
||||
|
||||
LookupScope *lookupScopeFromLookupItem(const LookupItem &lookupItem,
|
||||
ClassOrNamespace *classOrNamespaceFromLookupItem(const LookupItem &lookupItem,
|
||||
const LookupContext &context)
|
||||
{
|
||||
const Name *name = 0;
|
||||
@@ -783,7 +783,7 @@ LookupScope *lookupScopeFromLookupItem(const LookupItem &lookupItem,
|
||||
|
||||
Class *classFromLookupItem(const LookupItem &lookupItem, const LookupContext &context)
|
||||
{
|
||||
LookupScope *b = lookupScopeFromLookupItem(lookupItem, context);
|
||||
ClassOrNamespace *b = classOrNamespaceFromLookupItem(lookupItem, context);
|
||||
if (!b)
|
||||
return 0;
|
||||
|
||||
@@ -796,7 +796,7 @@ Class *classFromLookupItem(const LookupItem &lookupItem, const LookupContext &co
|
||||
|
||||
const Name *minimalName(Symbol *symbol, Scope *targetScope, const LookupContext &context)
|
||||
{
|
||||
LookupScope *target = context.lookupType(targetScope);
|
||||
ClassOrNamespace *target = context.lookupType(targetScope);
|
||||
if (!target)
|
||||
target = context.globalNamespace();
|
||||
return context.minimalName(symbol, target, context.bindings()->control().data());
|
||||
@@ -1219,12 +1219,12 @@ bool InternalCppCompletionAssistProcessor::tryObjCCompletion()
|
||||
ty = ty->asPointerType()->elementType().simplified();
|
||||
|
||||
if (NamedType *namedTy = ty->asNamedType()) {
|
||||
LookupScope *binding = lookupContext.lookupType(namedTy->name(), item.scope());
|
||||
ClassOrNamespace *binding = lookupContext.lookupType(namedTy->name(), item.scope());
|
||||
completeObjCMsgSend(binding, false);
|
||||
}
|
||||
} else {
|
||||
if (ObjCClass *clazz = ty->asObjCClassType()) {
|
||||
LookupScope *binding = lookupContext.lookupType(clazz->name(), item.scope());
|
||||
ClassOrNamespace *binding = lookupContext.lookupType(clazz->name(), item.scope());
|
||||
completeObjCMsgSend(binding, true);
|
||||
}
|
||||
}
|
||||
@@ -1273,7 +1273,7 @@ void InternalCppCompletionAssistProcessor::addCompletionItem(Symbol *symbol, int
|
||||
}
|
||||
}
|
||||
|
||||
void InternalCppCompletionAssistProcessor::completeObjCMsgSend(LookupScope *binding,
|
||||
void InternalCppCompletionAssistProcessor::completeObjCMsgSend(ClassOrNamespace *binding,
|
||||
bool staticClassAccess)
|
||||
{
|
||||
QList<Scope*> memberScopes;
|
||||
@@ -1542,26 +1542,26 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope)
|
||||
return !m_completions.isEmpty();
|
||||
}
|
||||
|
||||
QList<LookupScope *> usingBindings;
|
||||
LookupScope *currentBinding = 0;
|
||||
QList<ClassOrNamespace *> usingBindings;
|
||||
ClassOrNamespace *currentBinding = 0;
|
||||
|
||||
for (Scope *scope = currentScope; scope; scope = scope->enclosingScope()) {
|
||||
if (Block *block = scope->asBlock()) {
|
||||
if (LookupScope *binding = context.lookupType(scope)) {
|
||||
if (ClassOrNamespace *binding = context.lookupType(scope)) {
|
||||
for (unsigned i = 0; i < scope->memberCount(); ++i) {
|
||||
Symbol *member = scope->memberAt(i);
|
||||
if (member->isEnum()) {
|
||||
if (LookupScope *b = binding->findBlock(block))
|
||||
if (ClassOrNamespace *b = binding->findBlock(block))
|
||||
completeNamespace(b);
|
||||
}
|
||||
if (!member->name())
|
||||
continue;
|
||||
if (UsingNamespaceDirective *u = member->asUsingNamespaceDirective()) {
|
||||
if (LookupScope *b = binding->lookupType(u->name()))
|
||||
if (ClassOrNamespace *b = binding->lookupType(u->name()))
|
||||
usingBindings.append(b);
|
||||
} else if (Class *c = member->asClass()) {
|
||||
if (c->name()->isAnonymousNameId()) {
|
||||
if (LookupScope *b = binding->findBlock(block))
|
||||
if (ClassOrNamespace *b = binding->findBlock(block))
|
||||
completeClass(b);
|
||||
}
|
||||
}
|
||||
@@ -1588,7 +1588,7 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope)
|
||||
}
|
||||
|
||||
for (; currentBinding; currentBinding = currentBinding->parent()) {
|
||||
foreach (LookupScope* u, currentBinding->usings())
|
||||
foreach (ClassOrNamespace* u, currentBinding->usings())
|
||||
usingBindings.append(u);
|
||||
|
||||
const QList<Symbol *> symbols = currentBinding->symbols();
|
||||
@@ -1601,7 +1601,7 @@ bool InternalCppCompletionAssistProcessor::globalCompletion(Scope *currentScope)
|
||||
}
|
||||
}
|
||||
|
||||
foreach (LookupScope *b, usingBindings)
|
||||
foreach (ClassOrNamespace *b, usingBindings)
|
||||
completeNamespace(b);
|
||||
|
||||
addKeywords();
|
||||
@@ -1624,7 +1624,7 @@ bool InternalCppCompletionAssistProcessor::completeMember(const QList<LookupItem
|
||||
if (!m_interface->languageFeatures().objCEnabled)
|
||||
replaceDotForArrow = &m_model->m_replaceDotForArrow;
|
||||
|
||||
if (LookupScope *binding =
|
||||
if (ClassOrNamespace *binding =
|
||||
resolveExpression.baseExpression(baseResults,
|
||||
m_model->m_completionOperator,
|
||||
replaceDotForArrow)) {
|
||||
@@ -1648,27 +1648,27 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem>
|
||||
Scope *scope = result.scope();
|
||||
|
||||
if (NamedType *namedTy = ty->asNamedType()) {
|
||||
if (LookupScope *b = context.lookupType(namedTy->name(), scope)) {
|
||||
if (ClassOrNamespace *b = context.lookupType(namedTy->name(), scope)) {
|
||||
completeClass(b);
|
||||
break;
|
||||
}
|
||||
|
||||
} else if (Class *classTy = ty->asClassType()) {
|
||||
if (LookupScope *b = context.lookupType(classTy)) {
|
||||
if (ClassOrNamespace *b = context.lookupType(classTy)) {
|
||||
completeClass(b);
|
||||
break;
|
||||
}
|
||||
|
||||
// it can be class defined inside a block
|
||||
if (classTy->enclosingScope()->isBlock()) {
|
||||
if (LookupScope *b = context.lookupType(classTy->name(), classTy->enclosingScope())) {
|
||||
if (ClassOrNamespace *b = context.lookupType(classTy->name(), classTy->enclosingScope())) {
|
||||
completeClass(b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else if (Namespace *nsTy = ty->asNamespaceType()) {
|
||||
if (LookupScope *b = context.lookupType(nsTy)) {
|
||||
if (ClassOrNamespace *b = context.lookupType(nsTy)) {
|
||||
completeNamespace(b);
|
||||
break;
|
||||
}
|
||||
@@ -1676,7 +1676,7 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem>
|
||||
} else if (Template *templ = ty->asTemplateType()) {
|
||||
if (!result.binding())
|
||||
continue;
|
||||
if (LookupScope *b = result.binding()->lookupType(templ->name())) {
|
||||
if (ClassOrNamespace *b = result.binding()->lookupType(templ->name())) {
|
||||
completeClass(b);
|
||||
break;
|
||||
}
|
||||
@@ -1684,16 +1684,16 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem>
|
||||
} else if (Enum *e = ty->asEnumType()) {
|
||||
// it can be class defined inside a block
|
||||
if (e->enclosingScope()->isBlock()) {
|
||||
if (LookupScope *b = context.lookupType(e)) {
|
||||
if (ClassOrNamespace *b = context.lookupType(e)) {
|
||||
Block *block = e->enclosingScope()->asBlock();
|
||||
if (LookupScope *bb = b->findBlock(block)) {
|
||||
if (ClassOrNamespace *bb = b->findBlock(block)) {
|
||||
completeNamespace(bb);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LookupScope *b = context.lookupType(e)) {
|
||||
if (ClassOrNamespace *b = context.lookupType(e)) {
|
||||
completeNamespace(b);
|
||||
break;
|
||||
}
|
||||
@@ -1704,14 +1704,14 @@ bool InternalCppCompletionAssistProcessor::completeScope(const QList<LookupItem>
|
||||
return !m_completions.isEmpty();
|
||||
}
|
||||
|
||||
void InternalCppCompletionAssistProcessor::completeNamespace(LookupScope *b)
|
||||
void InternalCppCompletionAssistProcessor::completeNamespace(ClassOrNamespace *b)
|
||||
{
|
||||
QSet<LookupScope *> bindingsVisited;
|
||||
QList<LookupScope *> bindingsToVisit;
|
||||
QSet<ClassOrNamespace *> bindingsVisited;
|
||||
QList<ClassOrNamespace *> bindingsToVisit;
|
||||
bindingsToVisit.append(b);
|
||||
|
||||
while (!bindingsToVisit.isEmpty()) {
|
||||
LookupScope *binding = bindingsToVisit.takeFirst();
|
||||
ClassOrNamespace *binding = bindingsToVisit.takeFirst();
|
||||
if (!binding || bindingsVisited.contains(binding))
|
||||
continue;
|
||||
|
||||
@@ -1744,14 +1744,14 @@ void InternalCppCompletionAssistProcessor::completeNamespace(LookupScope *b)
|
||||
}
|
||||
}
|
||||
|
||||
void InternalCppCompletionAssistProcessor::completeClass(LookupScope *b, bool staticLookup)
|
||||
void InternalCppCompletionAssistProcessor::completeClass(ClassOrNamespace *b, bool staticLookup)
|
||||
{
|
||||
QSet<LookupScope *> bindingsVisited;
|
||||
QList<LookupScope *> bindingsToVisit;
|
||||
QSet<ClassOrNamespace *> bindingsVisited;
|
||||
QList<ClassOrNamespace *> bindingsToVisit;
|
||||
bindingsToVisit.append(b);
|
||||
|
||||
while (!bindingsToVisit.isEmpty()) {
|
||||
LookupScope *binding = bindingsToVisit.takeFirst();
|
||||
ClassOrNamespace *binding = bindingsToVisit.takeFirst();
|
||||
if (!binding || bindingsVisited.contains(binding))
|
||||
continue;
|
||||
|
||||
@@ -1838,16 +1838,16 @@ bool InternalCppCompletionAssistProcessor::completeQtMethod(const QList<LookupIt
|
||||
|
||||
QSet<QString> signatures;
|
||||
foreach (const LookupItem &lookupItem, results) {
|
||||
LookupScope *b = lookupScopeFromLookupItem(lookupItem, context);
|
||||
ClassOrNamespace *b = classOrNamespaceFromLookupItem(lookupItem, context);
|
||||
if (!b)
|
||||
continue;
|
||||
|
||||
QList<LookupScope *>todo;
|
||||
QSet<LookupScope *> processed;
|
||||
QList<ClassOrNamespace *>todo;
|
||||
QSet<ClassOrNamespace *> processed;
|
||||
QList<Scope *> scopes;
|
||||
todo.append(b);
|
||||
while (!todo.isEmpty()) {
|
||||
LookupScope *binding = todo.takeLast();
|
||||
ClassOrNamespace *binding = todo.takeLast();
|
||||
if (!processed.contains(binding)) {
|
||||
processed.insert(binding);
|
||||
|
||||
@@ -2063,7 +2063,7 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q
|
||||
Scope *scope = result.scope();
|
||||
|
||||
if (NamedType *namedTy = ty->asNamedType()) {
|
||||
if (LookupScope *b = context.lookupType(namedTy->name(), scope)) {
|
||||
if (ClassOrNamespace *b = context.lookupType(namedTy->name(), scope)) {
|
||||
foreach (const LookupItem &r, b->lookup(functionCallOp)) {
|
||||
Symbol *overload = r.declaration();
|
||||
FullySpecifiedType overloadTy = overload->type().simplified();
|
||||
@@ -2145,7 +2145,7 @@ bool InternalCppCompletionAssistProcessor::completeConstructorOrFunction(const Q
|
||||
SubstitutionEnvironment env;
|
||||
env.setContext(context);
|
||||
env.switchScope(sc);
|
||||
LookupScope *targetCoN = context.lookupType(sc);
|
||||
ClassOrNamespace *targetCoN = context.lookupType(sc);
|
||||
if (!targetCoN)
|
||||
targetCoN = context.globalNamespace();
|
||||
UseMinimalNames q(targetCoN);
|
||||
|
@@ -53,7 +53,7 @@
|
||||
|
||||
namespace CPlusPlus {
|
||||
class LookupItem;
|
||||
class LookupScope;
|
||||
class ClassOrNamespace;
|
||||
class Function;
|
||||
class LookupContext;
|
||||
} // namespace CPlusPlus
|
||||
@@ -121,7 +121,7 @@ private:
|
||||
const QString &expression,
|
||||
int endOfExpression);
|
||||
|
||||
void completeObjCMsgSend(CPlusPlus::LookupScope *binding, bool staticClassAccess);
|
||||
void completeObjCMsgSend(CPlusPlus::ClassOrNamespace *binding, bool staticClassAccess);
|
||||
bool completeInclude(const QTextCursor &cursor);
|
||||
void completeInclude(const QString &realPath, const QStringList &suffixes);
|
||||
void completePreprocessor();
|
||||
@@ -130,8 +130,8 @@ private:
|
||||
bool toolTipOnly);
|
||||
bool completeMember(const QList<CPlusPlus::LookupItem> &results);
|
||||
bool completeScope(const QList<CPlusPlus::LookupItem> &results);
|
||||
void completeNamespace(CPlusPlus::LookupScope *binding);
|
||||
void completeClass(CPlusPlus::LookupScope *b, bool staticLookup = true);
|
||||
void completeNamespace(CPlusPlus::ClassOrNamespace *binding);
|
||||
void completeClass(CPlusPlus::ClassOrNamespace *b, bool staticLookup = true);
|
||||
void addClassMembersToCompletion(CPlusPlus::Scope *scope, bool staticLookup);
|
||||
enum CompleteQtMethodMode {
|
||||
CompleteQt4Signals,
|
||||
|
@@ -109,7 +109,7 @@ bool isOwnershipRAIIType(Symbol *symbol, const LookupContext &context)
|
||||
Declaration *declaration = symbol->asDeclaration();
|
||||
const NamedType *namedType = declaration->type()->asNamedType();
|
||||
if (namedType) {
|
||||
LookupScope *clazz = context.lookupType(namedType->name(),
|
||||
ClassOrNamespace *clazz = context.lookupType(namedType->name(),
|
||||
declaration->enclosingScope());
|
||||
if (clazz && !clazz->symbols().isEmpty()) {
|
||||
Overview overview;
|
||||
|
@@ -151,7 +151,7 @@ Function *SymbolFinder::findMatchingDefinition(Symbol *declaration,
|
||||
|
||||
QList<Function *> viableFunctions;
|
||||
|
||||
LookupScope *enclosingType = context.lookupType(declaration);
|
||||
ClassOrNamespace *enclosingType = context.lookupType(declaration);
|
||||
if (!enclosingType)
|
||||
continue; // nothing to do
|
||||
|
||||
@@ -214,15 +214,13 @@ Function *SymbolFinder::findMatchingDefinition(Symbol *declaration,
|
||||
return 0;
|
||||
}
|
||||
|
||||
Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Snapshot &snapshot,
|
||||
const LookupContext *context)
|
||||
Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Snapshot &snapshot)
|
||||
{
|
||||
if (!declaration->identifier())
|
||||
return 0;
|
||||
|
||||
QString declFile = QString::fromUtf8(declaration->fileName(), declaration->fileNameLength());
|
||||
|
||||
const bool useLocalContext = !context;
|
||||
foreach (const QString &file, fileIterationOrder(declFile, snapshot)) {
|
||||
Document::Ptr doc = snapshot.document(file);
|
||||
if (!doc) {
|
||||
@@ -234,13 +232,9 @@ Class *SymbolFinder::findMatchingClassDeclaration(Symbol *declaration, const Sna
|
||||
declaration->identifier()->size()))
|
||||
continue;
|
||||
|
||||
QScopedPointer<LookupContext> localContext;
|
||||
if (useLocalContext) {
|
||||
localContext.reset(new LookupContext(doc, snapshot));
|
||||
context = localContext.data();
|
||||
}
|
||||
LookupContext context(doc, snapshot);
|
||||
|
||||
LookupScope *type = context->lookupType(declaration);
|
||||
ClassOrNamespace *type = context.lookupType(declaration);
|
||||
if (!type)
|
||||
continue;
|
||||
|
||||
@@ -289,7 +283,7 @@ void SymbolFinder::findMatchingDeclaration(const LookupContext &context,
|
||||
if (!functionName)
|
||||
return;
|
||||
|
||||
LookupScope *binding = 0;
|
||||
ClassOrNamespace *binding = 0;
|
||||
const QualifiedNameId *qName = functionName->asQualifiedNameId();
|
||||
if (qName) {
|
||||
if (qName->base())
|
||||
|
@@ -61,8 +61,7 @@ public:
|
||||
bool strict = false);
|
||||
|
||||
CPlusPlus::Class *findMatchingClassDeclaration(CPlusPlus::Symbol *declaration,
|
||||
const CPlusPlus::Snapshot &snapshot,
|
||||
const CPlusPlus::LookupContext *context = 0);
|
||||
const CPlusPlus::Snapshot &snapshot);
|
||||
|
||||
void findMatchingDeclaration(const CPlusPlus::LookupContext &context,
|
||||
CPlusPlus::Function *functionType,
|
||||
|
@@ -68,6 +68,9 @@ QHash<QString, QStringList> sortFilesIntoPaths(const QString &base, const QSet<Q
|
||||
relativeFilePath.chop(1);
|
||||
}
|
||||
|
||||
if (relativeFilePath == QLatin1String("."))
|
||||
relativeFilePath.clear();
|
||||
|
||||
filesInPath[relativeFilePath].append(absoluteFileName);
|
||||
}
|
||||
return filesInPath;
|
||||
|
@@ -75,6 +75,8 @@ public:
|
||||
const QStringList &extraOptions = QStringList());
|
||||
void revertAll(const QString &workingDir, const QString &revision = QString(),
|
||||
const QStringList &extraOptions = QStringList());
|
||||
|
||||
public slots:
|
||||
void view(const QString &source, const QString &id,
|
||||
const QStringList &extraOptions = QStringList());
|
||||
|
||||
|
@@ -483,6 +483,7 @@ Abi Abi::abiFromTargetTriplet(const QString &triple)
|
||||
} else if (p == QLatin1String("i386") || p == QLatin1String("i486") || p == QLatin1String("i586")
|
||||
|| p == QLatin1String("i686") || p == QLatin1String("x86")) {
|
||||
arch = Abi::X86Architecture;
|
||||
width = 32;
|
||||
} else if (p.startsWith(QLatin1String("arm"))) {
|
||||
arch = Abi::ArmArchitecture;
|
||||
width = p.contains(QLatin1String("64")) ? 64 : 32;
|
||||
@@ -1057,27 +1058,27 @@ void ProjectExplorer::ProjectExplorerPlugin::testAbiFromTargetTriplet_data()
|
||||
|
||||
QTest::newRow("i586-pc-mingw32msvc") << int(Abi::X86Architecture)
|
||||
<< int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor)
|
||||
<< int(Abi::PEFormat) << 0;
|
||||
<< int(Abi::PEFormat) << 32;
|
||||
|
||||
QTest::newRow("i686-linux-gnu") << int(Abi::X86Architecture)
|
||||
<< int(Abi::LinuxOS) << int(Abi::GenericLinuxFlavor)
|
||||
<< int(Abi::ElfFormat) << 0;
|
||||
<< int(Abi::ElfFormat) << 32;
|
||||
|
||||
QTest::newRow("i686-linux-android") << int(Abi::X86Architecture)
|
||||
<< int(Abi::LinuxOS) << int(Abi::AndroidLinuxFlavor)
|
||||
<< int(Abi::ElfFormat) << 0;
|
||||
<< int(Abi::ElfFormat) << 32;
|
||||
|
||||
QTest::newRow("i686-pc-linux-android") << int(Abi::X86Architecture)
|
||||
<< int(Abi::LinuxOS) << int(Abi::AndroidLinuxFlavor)
|
||||
<< int(Abi::ElfFormat) << 0;
|
||||
<< int(Abi::ElfFormat) << 32;
|
||||
|
||||
QTest::newRow("i686-pc-mingw32") << int(Abi::X86Architecture)
|
||||
<< int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor)
|
||||
<< int(Abi::PEFormat) << 0;
|
||||
<< int(Abi::PEFormat) << 32;
|
||||
|
||||
QTest::newRow("i686-w64-mingw32") << int(Abi::X86Architecture)
|
||||
<< int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor)
|
||||
<< int(Abi::PEFormat) << 0;
|
||||
<< int(Abi::PEFormat) << 32;
|
||||
|
||||
QTest::newRow("x86_64-pc-msys") << int(Abi::X86Architecture)
|
||||
<< int(Abi::WindowsOS) << int(Abi::WindowsMSysFlavor)
|
||||
|
@@ -40,6 +40,7 @@
|
||||
#include <coreplugin/messagemanager.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
@@ -358,7 +359,6 @@ CustomWizard *CustomWizard::createWizard(const CustomProjectWizard::CustomWizard
|
||||
|
||||
QList<Core::IWizardFactory *> CustomWizard::createWizards()
|
||||
{
|
||||
QList<Core::IWizardFactory *> rc;
|
||||
QString errorMessage;
|
||||
QString verboseLog;
|
||||
const QString templateDirName = Core::ICore::resourcePath() +
|
||||
@@ -371,29 +371,32 @@ QList<Core::IWizardFactory *> CustomWizard::createWizards()
|
||||
|
||||
const QDir templateDir(templateDirName);
|
||||
if (CustomWizardPrivate::verbose)
|
||||
verboseLog = QString::fromLatin1("### CustomWizard: Checking \"%1\"\n").arg(templateDirName);
|
||||
verboseLog += QString::fromLatin1("### CustomWizard: Checking \"%1\"\n").arg(templateDirName);
|
||||
if (!templateDir.exists()) {
|
||||
if (CustomWizardPrivate::verbose)
|
||||
qWarning("Custom project template path %s does not exist.", qPrintable(templateDir.absolutePath()));
|
||||
return rc;
|
||||
return QList<Core::IWizardFactory *>();
|
||||
}
|
||||
|
||||
const QDir userTemplateDir(userTemplateDirName);
|
||||
if (CustomWizardPrivate::verbose)
|
||||
verboseLog = QString::fromLatin1("### CustomWizard: Checking \"%1\"\n").arg(userTemplateDirName);
|
||||
verboseLog += QString::fromLatin1("### CustomWizard: Checking \"%1\"\n").arg(userTemplateDirName);
|
||||
|
||||
const QDir::Filters filters = QDir::Dirs|QDir::Readable|QDir::NoDotAndDotDot;
|
||||
const QDir::SortFlags sortflags = QDir::Name|QDir::IgnoreCase;
|
||||
QList<QFileInfo> dirs = templateDir.entryInfoList(filters, sortflags);
|
||||
QList<QFileInfo> dirs;
|
||||
if (userTemplateDir.exists()) {
|
||||
if (CustomWizardPrivate::verbose)
|
||||
verboseLog = QString::fromLatin1("### CustomWizard: userTemplateDir \"%1\" found, adding\n").arg(userTemplateDirName);
|
||||
verboseLog += QString::fromLatin1("### CustomWizard: userTemplateDir \"%1\" found, adding\n").arg(userTemplateDirName);
|
||||
dirs += userTemplateDir.entryInfoList(filters, sortflags);
|
||||
}
|
||||
dirs += templateDir.entryInfoList(filters, sortflags);
|
||||
|
||||
const QString configFile = QLatin1String(configFileC);
|
||||
// Check and parse config file in each directory.
|
||||
|
||||
QList<CustomWizardParametersPtr> toCreate;
|
||||
|
||||
while (!dirs.isEmpty()) {
|
||||
const QFileInfo dirFi = dirs.takeFirst();
|
||||
const QDir dir(dirFi.absoluteFilePath());
|
||||
@@ -403,11 +406,13 @@ QList<Core::IWizardFactory *> CustomWizard::createWizards()
|
||||
CustomWizardParametersPtr parameters(new CustomWizardParameters);
|
||||
switch (parameters->parse(dir.absoluteFilePath(configFile), &errorMessage)) {
|
||||
case CustomWizardParameters::ParseOk:
|
||||
if (!Utils::contains(toCreate, [parameters](CustomWizardParametersPtr p) { return parameters->id == p->id; })) {
|
||||
parameters->directory = dir.absolutePath();
|
||||
if (CustomWizard *w = createWizard(parameters))
|
||||
rc.push_back(w);
|
||||
else
|
||||
qWarning("Custom wizard factory function failed for %s", qPrintable(parameters->id.toString()));
|
||||
toCreate.append(parameters);
|
||||
} else {
|
||||
verboseLog += QString::fromLatin1("Customwizard: Ignoring wizard in %1 due to duplicate Id %2.\n")
|
||||
.arg(dir.absolutePath()).arg(parameters->id.toString());
|
||||
}
|
||||
break;
|
||||
case CustomWizardParameters::ParseDisabled:
|
||||
if (CustomWizardPrivate::verbose)
|
||||
@@ -429,6 +434,18 @@ QList<Core::IWizardFactory *> CustomWizard::createWizards()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QList<Core::IWizardFactory *> rc;
|
||||
foreach (CustomWizardParametersPtr p, toCreate) {
|
||||
if (CustomWizard *w = createWizard(p)) {
|
||||
rc.push_back(w);
|
||||
} else {
|
||||
qWarning("Custom wizard factory function failed for %s from %s.",
|
||||
qPrintable(p->id.toString()), qPrintable(p->directory));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (CustomWizardPrivate::verbose) { // Print to output pane for Windows.
|
||||
qWarning("%s", qPrintable(verboseLog));
|
||||
Core::MessageManager::write(verboseLog, Core::MessageManager::ModeSwitch);
|
||||
|
@@ -568,6 +568,7 @@ static void appendNodeToEndOfTheRow(const ModelNode &modelNode, const ItemRow &n
|
||||
parentPropertyItem->appendRow(newItemRow.toList());
|
||||
} else {
|
||||
QStandardItem *parentDefaultPropertyItem = parentRow.idItem;
|
||||
if (parentDefaultPropertyItem)
|
||||
parentDefaultPropertyItem->appendRow(newItemRow.toList());
|
||||
}
|
||||
} else { // root node
|
||||
|
@@ -885,7 +885,7 @@ void PathItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
if (pickedControlPoint.isEditPoint()) {
|
||||
createEditPointContextMenu(pickedControlPoint, event->screenPos());
|
||||
} else {
|
||||
double t;
|
||||
double t = 0.0;
|
||||
CubicSegment minimumDistanceSegment = getMinimumDistanceSegment(event->pos(), m_cubicSegments, 20., &t);
|
||||
if (minimumDistanceSegment.isValid())
|
||||
createCubicSegmentContextMenu(minimumDistanceSegment, event->screenPos(), t);
|
||||
|
@@ -104,16 +104,24 @@ void QmlProfilerTraceTime::setTime(qint64 startTime, qint64 endTime)
|
||||
|
||||
void QmlProfilerTraceTime::decreaseStartTime(qint64 time)
|
||||
{
|
||||
if (m_startTime > time) {
|
||||
if (m_startTime > time || m_startTime == -1) {
|
||||
m_startTime = time;
|
||||
if (m_endTime == -1)
|
||||
m_endTime = m_startTime;
|
||||
else
|
||||
QTC_ASSERT(m_endTime >= m_startTime, m_endTime = m_startTime);
|
||||
emit timeChanged(time, m_endTime);
|
||||
}
|
||||
}
|
||||
|
||||
void QmlProfilerTraceTime::increaseEndTime(qint64 time)
|
||||
{
|
||||
if (m_endTime < time) {
|
||||
if (m_endTime < time || m_endTime == -1) {
|
||||
m_endTime = time;
|
||||
if (m_startTime == -1)
|
||||
m_startTime = m_endTime;
|
||||
else
|
||||
QTC_ASSERT(m_endTime >= m_startTime, m_startTime = m_endTime);
|
||||
emit timeChanged(m_startTime, time);
|
||||
}
|
||||
}
|
||||
@@ -152,6 +160,8 @@ QmlProfilerModelManager::QmlProfilerModelManager(Utils::FileInProjectFinder *fin
|
||||
QObject(parent), d(new QmlProfilerModelManagerPrivate(this))
|
||||
{
|
||||
d->totalWeight = 0;
|
||||
d->previousProgress = 0;
|
||||
d->progress = 0;
|
||||
d->availableFeatures = 0;
|
||||
d->visibleFeatures = 0;
|
||||
d->recordedFeatures = 0;
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
|
Submodule src/shared/qbs updated: 94aaf3b94f...ca3974a082
@@ -53,6 +53,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
ClangBackEnd::Messages::registerMessages();
|
||||
|
||||
clang_toggleCrashRecovery(true);
|
||||
clang_enableStackTraces();
|
||||
|
||||
ClangBackEnd::ClangIpcServer clangIpcServer;
|
||||
ClangBackEnd::ConnectionServer connectionServer(application.arguments()[1]);
|
||||
connectionServer.start();
|
||||
|
@@ -25,7 +25,13 @@ HEADERS += $$PWD/clangipcserver.h \
|
||||
$$PWD/diagnosticsetiterator.h \
|
||||
$$PWD/clangfilesystemwatcher.h \
|
||||
$$PWD/translationunitalreadyexistsexception.h \
|
||||
$$PWD/commandlinearguments.h
|
||||
$$PWD/commandlinearguments.h \
|
||||
$$PWD/cursor.h \
|
||||
$$PWD/type.h \
|
||||
$$PWD/highlightinginformations.h \
|
||||
$$PWD/highlightinginformation.h \
|
||||
$$PWD/highlightinginformationsiterator.h \
|
||||
$$PWD/skippedsourceranges.h
|
||||
|
||||
SOURCES += $$PWD/clangipcserver.cpp \
|
||||
$$PWD/codecompleter.cpp \
|
||||
@@ -51,4 +57,9 @@ SOURCES += $$PWD/clangipcserver.cpp \
|
||||
$$PWD/fixit.cpp \
|
||||
$$PWD/clangfilesystemwatcher.cpp \
|
||||
$$PWD/translationunitalreadyexistsexception.cpp \
|
||||
$$PWD/commandlinearguments.cpp
|
||||
$$PWD/commandlinearguments.cpp \
|
||||
$$PWD/cursor.cpp \
|
||||
$$PWD/type.cpp \
|
||||
$$PWD/highlightinginformations.cpp \
|
||||
$$PWD/highlightinginformation.cpp \
|
||||
$$PWD/skippedsourceranges.cpp
|
||||
|
@@ -61,6 +61,11 @@ ClangString &ClangString::operator=(ClangString &&other)
|
||||
return *this;
|
||||
}
|
||||
|
||||
const char *ClangString::cString() const
|
||||
{
|
||||
return clang_getCString(cxString);
|
||||
}
|
||||
|
||||
ClangString::ClangString(ClangString &&other)
|
||||
: cxString(std::move(other.cxString))
|
||||
{
|
||||
@@ -70,7 +75,7 @@ ClangString::ClangString(ClangString &&other)
|
||||
|
||||
ClangString::operator Utf8String() const
|
||||
{
|
||||
return Utf8String(clang_getCString(cxString), -1);
|
||||
return Utf8String(cString(), -1);
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
@@ -51,6 +51,8 @@ public:
|
||||
|
||||
operator Utf8String() const;
|
||||
|
||||
const char *cString() const;
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
private:
|
||||
|
351
src/tools/clangbackend/ipcsource/cursor.cpp
Normal file
351
src/tools/clangbackend/ipcsource/cursor.cpp
Normal file
@@ -0,0 +1,351 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "cursor.h"
|
||||
|
||||
#include "clangstring.h"
|
||||
#include "sourcelocation.h"
|
||||
#include "sourcerange.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
Cursor::Cursor()
|
||||
: cxCursor(clang_getNullCursor())
|
||||
{
|
||||
}
|
||||
|
||||
Cursor::Cursor(CXCursor cxCursor)
|
||||
: cxCursor(cxCursor)
|
||||
{
|
||||
}
|
||||
|
||||
bool Cursor::isNull() const
|
||||
{
|
||||
return clang_Cursor_isNull(cxCursor);
|
||||
}
|
||||
|
||||
bool Cursor::isValid() const
|
||||
{
|
||||
return !clang_isInvalid(kind());
|
||||
}
|
||||
|
||||
bool Cursor::isTranslationUnit() const
|
||||
{
|
||||
return clang_isTranslationUnit(kind());
|
||||
}
|
||||
|
||||
bool Cursor::isDefinition() const
|
||||
{
|
||||
return clang_isCursorDefinition(cxCursor);
|
||||
}
|
||||
|
||||
bool Cursor::isDynamicCall() const
|
||||
{
|
||||
return clang_Cursor_isDynamicCall(cxCursor);
|
||||
}
|
||||
|
||||
bool Cursor::isVirtualMethod() const
|
||||
{
|
||||
return clang_CXXMethod_isVirtual(cxCursor);
|
||||
}
|
||||
|
||||
bool Cursor::isPureVirtualMethod() const
|
||||
{
|
||||
return clang_CXXMethod_isPureVirtual(cxCursor);
|
||||
}
|
||||
|
||||
bool Cursor::isConstantMethod() const
|
||||
{
|
||||
return clang_CXXMethod_isConst(cxCursor);
|
||||
}
|
||||
|
||||
bool Cursor::isStaticMethod() const
|
||||
{
|
||||
return clang_CXXMethod_isStatic(cxCursor);
|
||||
}
|
||||
|
||||
bool Cursor::isCompoundType() const
|
||||
{
|
||||
switch (kind()) {
|
||||
case CXCursor_ClassDecl:
|
||||
case CXCursor_StructDecl:
|
||||
case CXCursor_UnionDecl: return true;
|
||||
default: return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cursor::isDeclaration() const
|
||||
{
|
||||
return clang_isDeclaration(kind());
|
||||
}
|
||||
|
||||
bool Cursor::isLocalVariable() const
|
||||
{
|
||||
switch (semanticParent().kind()) {
|
||||
case CXCursor_FunctionDecl:
|
||||
case CXCursor_CXXMethod:
|
||||
case CXCursor_Constructor:
|
||||
case CXCursor_Destructor:
|
||||
case CXCursor_ConversionFunction:
|
||||
case CXCursor_FunctionTemplate:
|
||||
case CXCursor_ObjCInstanceMethodDecl: return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Cursor::hasFinalFunctionAttribute() const
|
||||
{
|
||||
bool hasFinal = false;
|
||||
|
||||
visit([&] (Cursor cursor, Cursor /*parent*/) {
|
||||
if (cursor.kind() == CXCursor_CXXFinalAttr) {
|
||||
hasFinal = true;
|
||||
return CXChildVisit_Break;
|
||||
} else {
|
||||
return CXChildVisit_Recurse;
|
||||
}
|
||||
});
|
||||
|
||||
return hasFinal;
|
||||
}
|
||||
|
||||
bool Cursor::hasFinalClassAttribute() const
|
||||
{
|
||||
bool hasFinal = false;
|
||||
|
||||
visit([&] (Cursor cursor, Cursor /*parent*/) {
|
||||
switch (cursor.kind()) {
|
||||
case CXCursor_CXXFinalAttr:
|
||||
hasFinal = true;
|
||||
return CXChildVisit_Break;
|
||||
case CXCursor_CXXMethod:
|
||||
return CXChildVisit_Break;
|
||||
default:
|
||||
return CXChildVisit_Recurse;
|
||||
}
|
||||
});
|
||||
|
||||
return hasFinal;
|
||||
}
|
||||
|
||||
bool Cursor::isUnexposed() const
|
||||
{
|
||||
return clang_isUnexposed(kind());
|
||||
}
|
||||
|
||||
Utf8String Cursor::unifiedSymbolResolution() const
|
||||
{
|
||||
return ClangString(clang_getCursorUSR(cxCursor));
|
||||
}
|
||||
|
||||
Utf8String Cursor::mangling() const
|
||||
{
|
||||
return ClangString(clang_Cursor_getMangling(cxCursor));
|
||||
}
|
||||
|
||||
ClangString Cursor::spelling() const
|
||||
{
|
||||
return ClangString(clang_getCursorSpelling(cxCursor));
|
||||
}
|
||||
|
||||
Utf8String Cursor::displayName() const
|
||||
{
|
||||
return ClangString(clang_getCursorDisplayName(cxCursor));
|
||||
}
|
||||
|
||||
Utf8String Cursor::briefComment() const
|
||||
{
|
||||
return ClangString(clang_Cursor_getBriefCommentText(cxCursor));
|
||||
}
|
||||
|
||||
Utf8String Cursor::rawComment() const
|
||||
{
|
||||
return ClangString(clang_Cursor_getRawCommentText(cxCursor));
|
||||
}
|
||||
|
||||
int Cursor::argumentCount() const
|
||||
{
|
||||
return clang_Cursor_getNumArguments(cxCursor);
|
||||
}
|
||||
|
||||
Type Cursor::type() const
|
||||
{
|
||||
return clang_getCursorType(cxCursor);
|
||||
}
|
||||
|
||||
Type Cursor::nonPointerTupe() const
|
||||
{
|
||||
auto typeResult = type();
|
||||
|
||||
if (typeResult.isPointer())
|
||||
typeResult = typeResult.pointeeType();
|
||||
|
||||
return typeResult;
|
||||
}
|
||||
|
||||
SourceLocation Cursor::sourceLocation() const
|
||||
{
|
||||
return clang_getCursorLocation(cxCursor);
|
||||
}
|
||||
|
||||
SourceRange Cursor::sourceRange() const
|
||||
{
|
||||
return clang_getCursorExtent(cxCursor);
|
||||
}
|
||||
|
||||
SourceRange Cursor::commentRange() const
|
||||
{
|
||||
return clang_Cursor_getCommentRange(cxCursor);
|
||||
}
|
||||
|
||||
Cursor Cursor::definition() const
|
||||
{
|
||||
return clang_getCursorDefinition(cxCursor);
|
||||
}
|
||||
|
||||
Cursor Cursor::canonical() const
|
||||
{
|
||||
return clang_getCanonicalCursor(cxCursor);
|
||||
}
|
||||
|
||||
Cursor Cursor::referenced() const
|
||||
{
|
||||
return clang_getCursorReferenced(cxCursor);
|
||||
}
|
||||
|
||||
Cursor Cursor::semanticParent() const
|
||||
{
|
||||
return clang_getCursorSemanticParent(cxCursor);
|
||||
}
|
||||
|
||||
Cursor Cursor::lexicalParent() const
|
||||
{
|
||||
return clang_getCursorLexicalParent(cxCursor);
|
||||
}
|
||||
|
||||
Cursor Cursor::functionBaseDeclaration() const
|
||||
{
|
||||
auto functionBaseCursor = functionBase();
|
||||
|
||||
if (functionBaseCursor.isValid())
|
||||
return functionBaseCursor.nonPointerTupe().canonical().declaration();
|
||||
else
|
||||
return semanticParent().semanticParent();
|
||||
}
|
||||
|
||||
Cursor Cursor::functionBase() const
|
||||
{
|
||||
Cursor functionBaseCursor;
|
||||
|
||||
visit([&] (Cursor cursor, Cursor /*parentCursor*/) {
|
||||
switch (cursor.kind()) {
|
||||
case CXCursor_DeclRefExpr:
|
||||
functionBaseCursor = cursor; ;
|
||||
return CXChildVisit_Break;
|
||||
default:
|
||||
return CXChildVisit_Recurse;
|
||||
}
|
||||
});
|
||||
|
||||
return functionBaseCursor;
|
||||
}
|
||||
|
||||
Cursor Cursor::argument(int index) const
|
||||
{
|
||||
return clang_Cursor_getArgument(cxCursor, index);
|
||||
}
|
||||
namespace {
|
||||
void collectOutputArguments(const Cursor &callExpression,
|
||||
std::vector<Cursor> &outputArguments)
|
||||
{
|
||||
auto callExpressionType = callExpression.referenced().type();
|
||||
auto argumentCount = callExpression.argumentCount();
|
||||
outputArguments.reserve(argumentCount);
|
||||
|
||||
for (int argumentIndex = 0; argumentIndex < argumentCount; ++argumentIndex) {
|
||||
auto argument = callExpression.argument(argumentIndex);
|
||||
auto argumentType = callExpressionType.argument(argumentIndex);
|
||||
|
||||
if (!argument.isUnexposed() && argumentType.isOutputParameter())
|
||||
outputArguments.push_back(callExpression.argument(argumentIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Cursor> Cursor::outputArguments() const
|
||||
{
|
||||
std::vector<Cursor> outputArguments;
|
||||
|
||||
if (kind() == CXCursor_CallExpr)
|
||||
collectOutputArguments(*this, outputArguments);
|
||||
|
||||
return outputArguments;
|
||||
}
|
||||
|
||||
CXCursorKind Cursor::kind() const
|
||||
{
|
||||
return clang_getCursorKind(cxCursor);
|
||||
}
|
||||
|
||||
bool operator==(const Cursor &first, const Cursor &second)
|
||||
{
|
||||
return clang_equalCursors(first.cxCursor, second.cxCursor);
|
||||
}
|
||||
|
||||
void PrintTo(CXCursorKind cursorKind, ::std::ostream *os)
|
||||
{
|
||||
ClangString cursorKindSpelling(clang_getCursorKindSpelling(cursorKind));
|
||||
*os << cursorKindSpelling.cString();
|
||||
}
|
||||
|
||||
void PrintTo(const Cursor &cursor, ::std::ostream*os)
|
||||
{
|
||||
if (cursor.isValid()) {
|
||||
ClangString cursorKindSpelling(clang_getCursorKindSpelling(cursor.kind()));
|
||||
*os << cursorKindSpelling.cString() << " ";
|
||||
|
||||
auto identifier = cursor.displayName();
|
||||
if (identifier.hasContent()) {
|
||||
*os << "\""
|
||||
<< identifier.constData()
|
||||
<< "\": ";
|
||||
}
|
||||
|
||||
PrintTo(cursor.sourceLocation(), os);
|
||||
} else {
|
||||
*os << "Invalid cursor!";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ClangBackEnd
|
||||
|
129
src/tools/clangbackend/ipcsource/cursor.h
Normal file
129
src/tools/clangbackend/ipcsource/cursor.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef CLANGBACKEND_CURSOR_H
|
||||
#define CLANGBACKEND_CURSOR_H
|
||||
|
||||
#include "type.h"
|
||||
|
||||
#include <clang-c/Index.h>
|
||||
|
||||
#include <iosfwd>
|
||||
|
||||
#include <vector>
|
||||
|
||||
class Utf8String;
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
class SourceLocation;
|
||||
class SourceRange;
|
||||
class ClangString;
|
||||
|
||||
class Cursor
|
||||
{
|
||||
friend class Type;
|
||||
friend bool operator==(const Cursor &first, const Cursor &second);
|
||||
public:
|
||||
Cursor();
|
||||
Cursor(CXCursor cxCursor);
|
||||
|
||||
bool isNull() const;
|
||||
bool isValid() const;
|
||||
|
||||
bool isTranslationUnit() const;
|
||||
bool isDefinition() const;
|
||||
bool isDynamicCall() const;
|
||||
bool isVirtualMethod() const;
|
||||
bool isPureVirtualMethod() const;
|
||||
bool isConstantMethod() const;
|
||||
bool isStaticMethod() const;
|
||||
bool isCompoundType() const;
|
||||
bool isDeclaration() const;
|
||||
bool isLocalVariable() const;
|
||||
bool hasFinalFunctionAttribute() const;
|
||||
bool hasFinalClassAttribute() const;
|
||||
bool isUnexposed() const;
|
||||
|
||||
Utf8String unifiedSymbolResolution() const;
|
||||
Utf8String mangling() const;
|
||||
ClangString spelling() const;
|
||||
Utf8String displayName() const;
|
||||
Utf8String briefComment() const;
|
||||
Utf8String rawComment() const;
|
||||
int argumentCount() const;
|
||||
|
||||
Type type() const;
|
||||
Type nonPointerTupe() const;
|
||||
|
||||
SourceLocation sourceLocation() const;
|
||||
SourceRange sourceRange() const;
|
||||
SourceRange commentRange() const;
|
||||
|
||||
Cursor definition() const;
|
||||
Cursor canonical() const;
|
||||
Cursor alias() const;
|
||||
Cursor referenced() const;
|
||||
Cursor semanticParent() const;
|
||||
Cursor lexicalParent() const;
|
||||
Cursor functionBaseDeclaration() const;
|
||||
Cursor functionBase() const;
|
||||
Cursor argument(int index) const;
|
||||
std::vector<Cursor> outputArguments() const;
|
||||
|
||||
CXCursorKind kind() const;
|
||||
|
||||
template <class VisitorCallback>
|
||||
void visit(VisitorCallback visitorCallback) const;
|
||||
|
||||
private:
|
||||
CXCursor cxCursor;
|
||||
};
|
||||
|
||||
template <class VisitorCallback>
|
||||
void Cursor::visit(VisitorCallback visitorCallback) const
|
||||
{
|
||||
auto visitor = [] (CXCursor cursor, CXCursor parent, CXClientData lambda) -> CXChildVisitResult {
|
||||
auto &visitorCallback = *static_cast<VisitorCallback*>(lambda);
|
||||
|
||||
return visitorCallback(cursor, parent);
|
||||
};
|
||||
|
||||
clang_visitChildren(cxCursor, visitor, &visitorCallback);
|
||||
}
|
||||
|
||||
bool operator==(const Cursor &first, const Cursor &second);
|
||||
|
||||
void PrintTo(CXCursorKind cursorKind, ::std::ostream *os);
|
||||
void PrintTo(const Cursor &cursor, ::std::ostream* os);
|
||||
} // namespace ClangBackEnd
|
||||
|
||||
|
||||
#endif // CLANGBACKEND_CURSOR_H
|
@@ -113,7 +113,7 @@ std::vector<SourceRange> Diagnostic::ranges() const
|
||||
const SourceRange sourceRange(clang_getDiagnosticRange(cxDiagnostic, index));
|
||||
|
||||
if (sourceRange.isValid())
|
||||
ranges.push_back(SourceRange(clang_getDiagnosticRange(cxDiagnostic, index)));
|
||||
ranges.push_back(std::move(sourceRange));
|
||||
}
|
||||
|
||||
return ranges;
|
||||
|
304
src/tools/clangbackend/ipcsource/highlightinginformation.cpp
Normal file
304
src/tools/clangbackend/ipcsource/highlightinginformation.cpp
Normal file
@@ -0,0 +1,304 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2015 The Qt Company Ltd.
|
||||
** Contact: http://www.qt.io/licensing
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms and
|
||||
** conditions see http://www.qt.io/terms-conditions. For further information
|
||||
** use the contact form at http://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 or version 3 as published by the Free
|
||||
** Software Foundation and appearing in the file LICENSE.LGPLv21 and
|
||||
** LICENSE.LGPLv3 included in the packaging of this file. Please review the
|
||||
** following information to ensure the GNU Lesser General Public License
|
||||
** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
|
||||
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, The Qt Company gives you certain additional
|
||||
** rights. These rights are described in The Qt Company LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "clangstring.h"
|
||||
#include "cursor.h"
|
||||
#include "highlightinginformation.h"
|
||||
#include "sourcelocation.h"
|
||||
#include "sourcerange.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
namespace ClangBackEnd {
|
||||
|
||||
HighlightingInformation::HighlightingInformation(const CXCursor &cxCursor,
|
||||
CXToken *cxToken,
|
||||
CXTranslationUnit cxTranslationUnit)
|
||||
{
|
||||
const SourceRange sourceRange = clang_getTokenExtent(cxTranslationUnit, *cxToken);
|
||||
const auto start = sourceRange.start();
|
||||
const auto end = sourceRange.end();
|
||||
|
||||
originalCursor = cxCursor;
|
||||
line = start.line();
|
||||
column = start.column();
|
||||
length = end.offset() - start.offset();
|
||||
type = kind(cxToken, originalCursor);
|
||||
}
|
||||
|
||||
HighlightingInformation::HighlightingInformation(uint line, uint column, uint length, HighlightingType type)
|
||||
: line(line),
|
||||
column(column),
|
||||
length(length),
|
||||
type(type)
|
||||
{
|
||||
}
|
||||
|
||||
bool HighlightingInformation::hasType(HighlightingType type) const
|
||||
{
|
||||
return this->type == type;
|
||||
}
|
||||
|
||||
bool HighlightingInformation::hasFunctionArguments() const
|
||||
{
|
||||
return originalCursor.argumentCount() > 0;
|
||||
}
|
||||
|
||||
QVector<HighlightingInformation> HighlightingInformation::outputFunctionArguments() const
|
||||
{
|
||||
QVector<HighlightingInformation> outputFunctionArguments;
|
||||
|
||||
return outputFunctionArguments;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
bool isFinalFunction(const Cursor &cursor)
|
||||
{
|
||||
auto referencedCursor = cursor.referenced();
|
||||
if (referencedCursor.hasFinalFunctionAttribute())
|
||||
return true;
|
||||
|
||||
else return false;
|
||||
}
|
||||
|
||||
bool isFunctionInFinalClass(const Cursor &cursor)
|
||||
{
|
||||
auto functionBase = cursor.functionBaseDeclaration();
|
||||
if (functionBase.isValid() && functionBase.hasFinalClassAttribute())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
HighlightingType HighlightingInformation::memberReferenceKind(const Cursor &cursor) const
|
||||
{
|
||||
if (cursor.isDynamicCall()) {
|
||||
if (isFinalFunction(cursor) || isFunctionInFinalClass(cursor))
|
||||
return HighlightingType::Function;
|
||||
else
|
||||
return HighlightingType::VirtualFunction;
|
||||
}
|
||||
|
||||
return identifierKind(cursor.referenced());
|
||||
|
||||
}
|
||||
|
||||
HighlightingType HighlightingInformation::referencedTypeKind(const Cursor &cursor) const
|
||||
{
|
||||
const Cursor referencedCursor = cursor.referenced();
|
||||
|
||||
switch (referencedCursor.kind()) {
|
||||
case CXCursor_ClassDecl:
|
||||
case CXCursor_StructDecl:
|
||||
case CXCursor_UnionDecl:
|
||||
case CXCursor_TemplateTypeParameter:
|
||||
case CXCursor_TypeAliasDecl: return HighlightingType::Type;
|
||||
case CXCursor_EnumDecl: return HighlightingType::Enumeration;
|
||||
default: return HighlightingType::Invalid;
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
HighlightingType HighlightingInformation::variableKind(const Cursor &cursor) const
|
||||
{
|
||||
if (cursor.isLocalVariable())
|
||||
return HighlightingType::LocalVariable;
|
||||
else
|
||||
return HighlightingType::GlobalVariable;
|
||||
}
|
||||
|
||||
bool HighlightingInformation::isVirtualMethodDeclarationOrDefinition(const Cursor &cursor) const
|
||||
{
|
||||
return cursor.isVirtualMethod()
|
||||
&& (originalCursor.isDeclaration() || originalCursor.isDefinition());
|
||||
}
|
||||
namespace {
|
||||
bool isNotFinalFunction(const Cursor &cursor)
|
||||
{
|
||||
return !cursor.hasFinalFunctionAttribute();
|
||||
}
|
||||
|
||||
}
|
||||
bool HighlightingInformation::isRealDynamicCall(const Cursor &cursor) const
|
||||
{
|
||||
|
||||
return originalCursor.isDynamicCall() && isNotFinalFunction(cursor);
|
||||
}
|
||||
|
||||
HighlightingType HighlightingInformation::functionKind(const Cursor &cursor) const
|
||||
{
|
||||
if (isRealDynamicCall(cursor) || isVirtualMethodDeclarationOrDefinition(cursor))
|
||||
return HighlightingType::VirtualFunction;
|
||||
else
|
||||
return HighlightingType::Function;
|
||||
}
|
||||
|
||||
HighlightingType HighlightingInformation::identifierKind(const Cursor &cursor) const
|
||||
{
|
||||
switch (cursor.kind()) {
|
||||
case CXCursor_Destructor:
|
||||
case CXCursor_Constructor:
|
||||
case CXCursor_FunctionDecl:
|
||||
case CXCursor_CallExpr:
|
||||
case CXCursor_CXXMethod: return functionKind(cursor);
|
||||
case CXCursor_NonTypeTemplateParameter:
|
||||
case CXCursor_ParmDecl: return HighlightingType::LocalVariable;
|
||||
case CXCursor_VarDecl: return variableKind(cursor);
|
||||
case CXCursor_DeclRefExpr: return identifierKind(cursor.referenced());
|
||||
case CXCursor_MemberRefExpr: return memberReferenceKind(cursor);
|
||||
case CXCursor_FieldDecl:
|
||||
case CXCursor_MemberRef:
|
||||
case CXCursor_ObjCIvarDecl:
|
||||
case CXCursor_ObjCPropertyDecl:
|
||||
case CXCursor_ObjCClassMethodDecl:
|
||||
case CXCursor_ObjCInstanceMethodDecl:
|
||||
case CXCursor_ObjCSynthesizeDecl:
|
||||
case CXCursor_ObjCDynamicDecl: return HighlightingType::Field;
|
||||
case CXCursor_TypeRef: return referencedTypeKind(cursor);
|
||||
case CXCursor_ClassDecl:
|
||||
case CXCursor_TemplateTypeParameter:
|
||||
case CXCursor_TemplateTemplateParameter:
|
||||
case CXCursor_UnionDecl:
|
||||
case CXCursor_StructDecl:
|
||||
case CXCursor_TemplateRef:
|
||||
case CXCursor_Namespace:
|
||||
case CXCursor_NamespaceRef:
|
||||
case CXCursor_NamespaceAlias:
|
||||
case CXCursor_TypeAliasDecl:
|
||||
case CXCursor_ClassTemplate:
|
||||
case CXCursor_UnexposedDecl:
|
||||
case CXCursor_CXXStaticCastExpr:
|
||||
case CXCursor_CXXReinterpretCastExpr:
|
||||
case CXCursor_ObjCCategoryDecl:
|
||||
case CXCursor_ObjCCategoryImplDecl:
|
||||
case CXCursor_ObjCImplementationDecl:
|
||||
case CXCursor_ObjCInterfaceDecl:
|
||||
case CXCursor_ObjCProtocolDecl:
|
||||
case CXCursor_ObjCProtocolRef:
|
||||
case CXCursor_ObjCClassRef:
|
||||
case CXCursor_ObjCSuperClassRef: return HighlightingType::Type;
|
||||
case CXCursor_FunctionTemplate: return HighlightingType::Function;
|
||||
case CXCursor_EnumConstantDecl: return HighlightingType::Enumeration;
|
||||
case CXCursor_EnumDecl: return referencedTypeKind(cursor);
|
||||
case CXCursor_PreprocessingDirective: return HighlightingType::Preprocessor;
|
||||
case CXCursor_MacroExpansion: return HighlightingType::PreprocessorExpansion;
|
||||
case CXCursor_MacroDefinition: return HighlightingType::PreprocessorDefinition;
|
||||
case CXCursor_InclusionDirective: return HighlightingType::StringLiteral;
|
||||
case CXCursor_LabelRef:
|
||||
case CXCursor_LabelStmt: return HighlightingType::Label;
|
||||
default: return HighlightingType::Invalid;
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
namespace {
|
||||
HighlightingType literalKind(const Cursor &cursor)
|
||||
{
|
||||
switch (cursor.kind()) {
|
||||
case CXCursor_CharacterLiteral:
|
||||
case CXCursor_StringLiteral:
|
||||
case CXCursor_ObjCStringLiteral: return HighlightingType::StringLiteral;
|
||||
case CXCursor_IntegerLiteral:
|
||||
case CXCursor_ImaginaryLiteral:
|
||||
case CXCursor_FloatingLiteral: return HighlightingType::NumberLiteral;
|
||||
default: return HighlightingType::Invalid;
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
HighlightingType punctationKind(const Cursor &cursor)
|
||||
{
|
||||
switch (cursor.kind()) {
|
||||
case CXCursor_DeclRefExpr: return HighlightingType::Operator;
|
||||
default: return HighlightingType::Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
HighlightingType HighlightingInformation::kind(CXToken *cxToken, const Cursor &cursor) const
|
||||
{
|
||||
auto cxTokenKind = clang_getTokenKind(*cxToken);
|
||||
|
||||
switch (cxTokenKind) {
|
||||
case CXToken_Keyword: return HighlightingType::Keyword;
|
||||
case CXToken_Punctuation: return punctationKind(cursor);
|
||||
case CXToken_Identifier: return identifierKind(cursor);
|
||||
case CXToken_Comment: return HighlightingType::Comment;
|
||||
case CXToken_Literal: return literalKind(cursor);
|
||||
}
|
||||
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
void PrintTo(const HighlightingInformation& information, ::std::ostream *os)
|
||||
{
|
||||
*os << "type: ";
|
||||
PrintTo(information.type, os);
|
||||
*os << " line: " << information.line
|
||||
<< " column: " << information.column
|
||||
<< " length: " << information.length;
|
||||
}
|
||||
|
||||
void PrintTo(HighlightingType highlightingType, std::ostream *os)
|
||||
{
|
||||
switch (highlightingType) {
|
||||
case HighlightingType::Invalid: *os << "Invalid"; break;
|
||||
case HighlightingType::Comment: *os << "Comment"; break;
|
||||
case HighlightingType::Keyword: *os << "Keyword"; break;
|
||||
case HighlightingType::StringLiteral: *os << "StringLiteral"; break;
|
||||
case HighlightingType::NumberLiteral: *os << "NumberLiteral"; break;
|
||||
case HighlightingType::Function: *os << "Function"; break;
|
||||
case HighlightingType::VirtualFunction: *os << "VirtualFunction"; break;
|
||||
case HighlightingType::Type: *os << "Type"; break;
|
||||
case HighlightingType::LocalVariable: *os << "LocalVariable"; break;
|
||||
case HighlightingType::GlobalVariable: *os << "GlobalVariable"; break;
|
||||
case HighlightingType::Field: *os << "Field"; break;
|
||||
case HighlightingType::Enumeration: *os << "Enumeration"; break;
|
||||
case HighlightingType::Operator: *os << "Operator"; break;
|
||||
case HighlightingType::Preprocessor: *os << "Preprocessor"; break;
|
||||
case HighlightingType::Label: *os << "Label"; break;
|
||||
case HighlightingType::OutputArgument: *os << "OutputArgument"; break;
|
||||
case HighlightingType::PreprocessorDefinition: *os << "PreprocessorDefinition"; break;
|
||||
case HighlightingType::PreprocessorExpansion: *os << "PreprocessorExpansion"; break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace ClangBackEnd
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user