diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2022-08-17 18:10:53 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2022-08-23 13:52:11 +0000 |
commit | ca00b874a75d8cd64f9768d21959a530b928c6dc (patch) | |
tree | 8292188e0ac3952854cd653bfa573c1cf94772de /src/libs/3rdparty/cplusplus/Bind.cpp | |
parent | 5fab54d95aadaf28c4f7d10e601cc12feb682429 (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.cpp | 100 |
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); |