aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/3rdparty/cplusplus/Bind.cpp
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2022-08-17 18:10:53 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2022-08-23 13:52:11 +0000
commitca00b874a75d8cd64f9768d21959a530b928c6dc (patch)
tree8292188e0ac3952854cd653bfa573c1cf94772de /src/libs/3rdparty/cplusplus/Bind.cpp
parent5fab54d95aadaf28c4f7d10e601cc12feb682429 (diff)
CPlusPlus: Support structured bindings
While we do recommend clangd for modern code bases, we should still be able to parse basic language constructs. Fixes: QTCREATORBUG-27975 Change-Id: I189b991685a5cd5f62f2afce77878b60c895e8f9 Reviewed-by: <github-actions-qt-creator@cristianadam.eu> Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src/libs/3rdparty/cplusplus/Bind.cpp')
-rw-r--r--src/libs/3rdparty/cplusplus/Bind.cpp100
1 files changed, 64 insertions, 36 deletions
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp
index 89ea441842..2f3f465c8e 100644
--- a/src/libs/3rdparty/cplusplus/Bind.cpp
+++ b/src/libs/3rdparty/cplusplus/Bind.cpp
@@ -35,6 +35,7 @@
#include <string>
#include <memory>
#include <sstream>
+#include <utility>
using namespace CPlusPlus;
@@ -46,6 +47,7 @@ Bind::Bind(TranslationUnit *unit)
_expression(nullptr),
_name(nullptr),
_declaratorId(nullptr),
+ _decompositionDeclarator(nullptr),
_visibility(Symbol::Public),
_objcVisibility(Symbol::Public),
_methodKey(Function::NormalMethod),
@@ -341,7 +343,9 @@ bool Bind::visit(DeclaratorAST *ast)
return false;
}
-FullySpecifiedType Bind::declarator(DeclaratorAST *ast, const FullySpecifiedType &init, DeclaratorIdAST **declaratorId)
+FullySpecifiedType Bind::declarator(DeclaratorAST *ast, const FullySpecifiedType &init,
+ DeclaratorIdAST **declaratorId,
+ DecompositionDeclaratorAST **decompDeclarator)
{
FullySpecifiedType type = init;
@@ -349,6 +353,7 @@ FullySpecifiedType Bind::declarator(DeclaratorAST *ast, const FullySpecifiedType
return type;
std::swap(_declaratorId, declaratorId);
+ std::swap(_decompositionDeclarator, decompDeclarator);
bool isAuto = false;
const bool cxx11Enabled = translationUnit()->languageFeatures().cxx11Enabled;
if (cxx11Enabled)
@@ -380,6 +385,7 @@ FullySpecifiedType Bind::declarator(DeclaratorAST *ast, const FullySpecifiedType
}
std::swap(_declaratorId, declaratorId);
+ std::swap(_decompositionDeclarator, decompDeclarator);
return type;
}
@@ -1997,51 +2003,65 @@ bool Bind::visit(SimpleDeclarationAST *ast)
for (DeclaratorListAST *it = ast->declarator_list; it; it = it->next) {
DeclaratorIdAST *declaratorId = nullptr;
- FullySpecifiedType declTy = this->declarator(it->value, type, &declaratorId);
+ DecompositionDeclaratorAST *decompDeclarator = nullptr;
+ FullySpecifiedType declTy = this->declarator(it->value, type, &declaratorId,
+ &decompDeclarator);
- const Name *declName = nullptr;
- int sourceLocation = location(it->value, ast->firstToken());
- if (declaratorId && declaratorId->name)
- declName = declaratorId->name->name;
+ std::vector<std::pair<const Name *, int>> namesAndLocations;
+ if (declaratorId && declaratorId->name) {
+ namesAndLocations.push_back({declaratorId->name->name,
+ location(it->value, ast->firstToken())});
+ } else if (decompDeclarator) {
+ for (auto it = decompDeclarator->identifiers->begin();
+ it != decompDeclarator->identifiers->end(); ++it) {
+ if ((*it)->name)
+ namesAndLocations.push_back({(*it)->name, (*it)->firstToken()});
+ }
+ }
- Declaration *decl = control()->newDeclaration(sourceLocation, declName);
- decl->setType(declTy);
- setDeclSpecifiers(decl, type);
+ for (const auto &nameAndLoc : qAsConst(namesAndLocations)) {
+ const int sourceLocation = nameAndLoc.second;
+ Declaration *decl = control()->newDeclaration(sourceLocation, nameAndLoc.first);
+ decl->setType(declTy);
+ setDeclSpecifiers(decl, type);
- if (Function *fun = decl->type()->asFunctionType()) {
- fun->setEnclosingScope(_scope);
- fun->setSourceLocation(sourceLocation, translationUnit());
+ if (Function *fun = decl->type()->asFunctionType()) {
+ fun->setEnclosingScope(_scope);
+ fun->setSourceLocation(sourceLocation, translationUnit());
- setDeclSpecifiers(fun, type);
- if (declaratorId && declaratorId->name)
- fun->setName(declaratorId->name->name); // update the function name
- }
- else if (declTy.isAuto()) {
- const ExpressionAST *initializer = it->value->initializer;
- if (!initializer && declaratorId)
- translationUnit()->error(location(declaratorId->name, ast->firstToken()), "auto-initialized variable must have an initializer");
- else if (initializer)
- decl->setInitializer(asStringLiteral(initializer));
- }
+ setDeclSpecifiers(fun, type);
+ if (declaratorId && declaratorId->name)
+ fun->setName(declaratorId->name->name); // update the function name
+ }
+ else if (declTy.isAuto()) {
+ const ExpressionAST *initializer = it->value->initializer;
+ if (!initializer && declaratorId) {
+ translationUnit()->error(location(declaratorId->name, ast->firstToken()),
+ "auto-initialized variable must have an initializer");
+ } else if (initializer) {
+ decl->setInitializer(asStringLiteral(initializer));
+ }
+ }
- if (_scope->asClass()) {
- decl->setVisibility(_visibility);
+ if (_scope->asClass()) {
+ decl->setVisibility(_visibility);
- if (Function *funTy = decl->type()->asFunctionType()) {
- funTy->setMethodKey(methodKey);
+ if (Function *funTy = decl->type()->asFunctionType()) {
+ funTy->setMethodKey(methodKey);
- bool pureVirtualInit = it->value->equal_token
- && it->value->initializer
- && it->value->initializer->asNumericLiteral();
- if (funTy->isVirtual() && pureVirtualInit)
- funTy->setPureVirtual(true);
+ bool pureVirtualInit = it->value->equal_token
+ && it->value->initializer
+ && it->value->initializer->asNumericLiteral();
+ if (funTy->isVirtual() && pureVirtualInit)
+ funTy->setPureVirtual(true);
+ }
}
- }
- _scope->addMember(decl);
+ _scope->addMember(decl);
- *symbolTail = new (translationUnit()->memoryPool()) List<Symbol *>(decl);
- symbolTail = &(*symbolTail)->next;
+ *symbolTail = new (translationUnit()->memoryPool()) List<Symbol *>(decl);
+ symbolTail = &(*symbolTail)->next;
+ }
}
return false;
}
@@ -3319,6 +3339,14 @@ bool Bind::visit(DeclaratorIdAST *ast)
return false;
}
+bool Bind::visit(DecompositionDeclaratorAST *ast)
+{
+ for (auto it = ast->identifiers->begin(); it != ast->identifiers->end(); ++it)
+ name(*it);
+ *_decompositionDeclarator = ast;
+ return false;
+}
+
bool Bind::visit(NestedDeclaratorAST *ast)
{
_type = this->declarator(ast->declarator, _type, _declaratorId);