diff options
author | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2019-10-07 14:31:32 +0200 |
---|---|---|
committer | Nikolai Kosjar <nikolai.kosjar@qt.io> | 2019-10-08 09:20:10 +0000 |
commit | 54fefd89b86f9b7c3496317bcfcf3882ff72e67c (patch) | |
tree | 284667f5855e901148f5e7f70aae87a4c28db275 /src | |
parent | c2aaa9340881f8220c5683d253a147c2cd77ff6e (diff) | |
download | qt-creator-54fefd89b86f9b7c3496317bcfcf3882ff72e67c.tar.gz |
C++: Transfer noexcept specifier for refactoring actions
This applies for e.g.
* "Add Definition..." (on function decl)
* "Move Definition..." (on function decl)
* "Insert Virtual Functions of Base Class" (on class specifier)
Fixes: QTCREATORBUG-11849
Fixes: QTCREATORBUG-19699
Change-Id: I0d259bc1782470f3b3f19617230005a5594a5cca
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/libs/3rdparty/cplusplus/Bind.cpp | 6 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Bind.h | 2 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Symbols.cpp | 6 | ||||
-rw-r--r-- | src/libs/3rdparty/cplusplus/Symbols.h | 6 | ||||
-rw-r--r-- | src/libs/cplusplus/CppRewriter.cpp | 1 | ||||
-rw-r--r-- | src/libs/cplusplus/TypePrettyPrinter.cpp | 6 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppeditorplugin.h | 1 | ||||
-rw-r--r-- | src/plugins/cppeditor/cppquickfix_test.cpp | 23 |
8 files changed, 49 insertions, 2 deletions
diff --git a/src/libs/3rdparty/cplusplus/Bind.cpp b/src/libs/3rdparty/cplusplus/Bind.cpp index 053d4f1388..486efffc3d 100644 --- a/src/libs/3rdparty/cplusplus/Bind.cpp +++ b/src/libs/3rdparty/cplusplus/Bind.cpp @@ -1232,7 +1232,7 @@ FullySpecifiedType Bind::trailingReturnType(TrailingReturnTypeAST *ast, const Fu return type; } -const StringLiteral *Bind::asStringLiteral(const ExpressionAST *ast) +const StringLiteral *Bind::asStringLiteral(const AST *ast) { CPP_ASSERT(ast, return nullptr); const int firstToken = ast->firstToken(); @@ -3265,7 +3265,11 @@ bool Bind::visit(FunctionDeclaratorAST *ast) Function::RvalueRefQualifier); } + // propagate exception spec this->exceptionSpecification(ast->exception_specification, type); + if (ExceptionSpecificationAST *spec = ast->exception_specification) + fun->setExceptionSpecification(asStringLiteral(spec)); + if (ast->as_cpp_initializer != nullptr) { fun->setAmbiguous(true); /*ExpressionTy as_cpp_initializer =*/ this->expression(ast->as_cpp_initializer); diff --git a/src/libs/3rdparty/cplusplus/Bind.h b/src/libs/3rdparty/cplusplus/Bind.h index 0898722964..ddeb46532e 100644 --- a/src/libs/3rdparty/cplusplus/Bind.h +++ b/src/libs/3rdparty/cplusplus/Bind.h @@ -104,7 +104,7 @@ protected: void capture(CaptureAST *ast); Function *lambdaDeclarator(LambdaDeclaratorAST *ast); FullySpecifiedType trailingReturnType(TrailingReturnTypeAST *ast, const FullySpecifiedType &init); - const StringLiteral *asStringLiteral(const ExpressionAST *ast); + const StringLiteral *asStringLiteral(const AST *ast); virtual bool preVisit(AST *); virtual void postVisit(AST *); diff --git a/src/libs/3rdparty/cplusplus/Symbols.cpp b/src/libs/3rdparty/cplusplus/Symbols.cpp index a895f7ed6c..aba1be3494 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.cpp +++ b/src/libs/3rdparty/cplusplus/Symbols.cpp @@ -303,6 +303,7 @@ Function::Function(TranslationUnit *translationUnit, int sourceLocation, const N Function::Function(Clone *clone, Subst *subst, Function *original) : Scope(clone, subst, original) , _returnType(clone->type(original->_returnType, subst)) + , _exceptionSpecification(original->_exceptionSpecification) , _flags(original->_flags) { } @@ -534,6 +535,11 @@ bool Function::maybeValidPrototype(int actualArgumentCount) const return true; } +const StringLiteral *Function::exceptionSpecification() +{ return _exceptionSpecification; } + +void Function::setExceptionSpecification(const StringLiteral *spec) +{ _exceptionSpecification = spec; } Block::Block(TranslationUnit *translationUnit, int sourceLocation) : Scope(translationUnit, sourceLocation, /*name = */ nullptr) diff --git a/src/libs/3rdparty/cplusplus/Symbols.h b/src/libs/3rdparty/cplusplus/Symbols.h index fd9417984e..71a076ac80 100644 --- a/src/libs/3rdparty/cplusplus/Symbols.h +++ b/src/libs/3rdparty/cplusplus/Symbols.h @@ -29,6 +29,8 @@ namespace CPlusPlus { +class StringLiteral; + class CPLUSPLUS_EXPORT UsingNamespaceDirective: public Symbol { public: @@ -363,6 +365,9 @@ public: bool maybeValidPrototype(int actualArgumentCount) const; + const StringLiteral *exceptionSpecification(); + void setExceptionSpecification(const StringLiteral *spec); + // Symbol's interface virtual FullySpecifiedType type() const; @@ -386,6 +391,7 @@ protected: private: FullySpecifiedType _returnType; + const StringLiteral *_exceptionSpecification = nullptr; struct Flags { unsigned _isVirtual: 1; unsigned _isOverride: 1; diff --git a/src/libs/cplusplus/CppRewriter.cpp b/src/libs/cplusplus/CppRewriter.cpp index fdb5de3851..c52963b023 100644 --- a/src/libs/cplusplus/CppRewriter.cpp +++ b/src/libs/cplusplus/CppRewriter.cpp @@ -136,6 +136,7 @@ public: funTy->setConst(type->isConst()); funTy->setVolatile(type->isVolatile()); funTy->setRefQualifier(type->refQualifier()); + funTy->setExceptionSpecification(type->exceptionSpecification()); funTy->setName(rewrite->rewriteName(type->name())); diff --git a/src/libs/cplusplus/TypePrettyPrinter.cpp b/src/libs/cplusplus/TypePrettyPrinter.cpp index c46117dde7..2ad59c55c8 100644 --- a/src/libs/cplusplus/TypePrettyPrinter.cpp +++ b/src/libs/cplusplus/TypePrettyPrinter.cpp @@ -487,6 +487,12 @@ void TypePrettyPrinter::visit(Function *type) ? QLatin1String("&") : QLatin1String("&&"); } + + // add exception specifier + if (const StringLiteral *spec = type->exceptionSpecification()) { + appendSpace(); + _text += QLatin1String(spec->chars()); + } } } diff --git a/src/plugins/cppeditor/cppeditorplugin.h b/src/plugins/cppeditor/cppeditorplugin.h index 40b251fbef..04b6aeb040 100644 --- a/src/plugins/cppeditor/cppeditorplugin.h +++ b/src/plugins/cppeditor/cppeditorplugin.h @@ -126,6 +126,7 @@ private slots: void test_quickfix_InsertDefFromDecl_ignoreSurroundingGeneratedDeclarations(); void test_quickfix_InsertDefFromDecl_respectWsInOperatorNames1(); void test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2(); + void test_quickfix_InsertDefFromDecl_noexcept_specifier(); void test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1(); void test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2(); void test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfFile(); diff --git a/src/plugins/cppeditor/cppquickfix_test.cpp b/src/plugins/cppeditor/cppquickfix_test.cpp index 4c7be6a228..63f1290b6a 100644 --- a/src/plugins/cppeditor/cppquickfix_test.cpp +++ b/src/plugins/cppeditor/cppquickfix_test.cpp @@ -2502,6 +2502,29 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2( QuickFixOperationTest(singleDocument(original, expected), &factory); } +/// Check that the noexcept exception specifier is transferred +void CppEditorPlugin::test_quickfix_InsertDefFromDecl_noexcept_specifier() +{ + QByteArray original = + "class Foo\n" + "{\n" + " void @foo() noexcept(false);\n" + "};\n"; + QByteArray expected = + "class Foo\n" + "{\n" + " void foo() noexcept(false);\n" + "};\n" + "\n" + "void Foo::foo() noexcept(false)\n" + "{\n" + "\n" + "}\n"; + + InsertDefFromDecl factory; + QuickFixOperationTest(singleDocument(original, expected), &factory); +} + /// Check if a function like macro use is not separated by the function to insert /// Case: Macro preceded by preproceesor directives and declaration. void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1() |