forked from qt-creator/qt-creator
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>
This commit is contained in:
6
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
6
src/libs/3rdparty/cplusplus/Bind.cpp
vendored
@@ -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);
|
||||
|
2
src/libs/3rdparty/cplusplus/Bind.h
vendored
2
src/libs/3rdparty/cplusplus/Bind.h
vendored
@@ -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 *);
|
||||
|
6
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
6
src/libs/3rdparty/cplusplus/Symbols.cpp
vendored
@@ -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)
|
||||
|
6
src/libs/3rdparty/cplusplus/Symbols.h
vendored
6
src/libs/3rdparty/cplusplus/Symbols.h
vendored
@@ -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;
|
||||
|
@@ -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()));
|
||||
|
||||
|
@@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -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();
|
||||
|
@@ -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()
|
||||
|
Reference in New Issue
Block a user