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;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const StringLiteral *Bind::asStringLiteral(const ExpressionAST *ast)
|
const StringLiteral *Bind::asStringLiteral(const AST *ast)
|
||||||
{
|
{
|
||||||
CPP_ASSERT(ast, return nullptr);
|
CPP_ASSERT(ast, return nullptr);
|
||||||
const int firstToken = ast->firstToken();
|
const int firstToken = ast->firstToken();
|
||||||
@@ -3265,7 +3265,11 @@ bool Bind::visit(FunctionDeclaratorAST *ast)
|
|||||||
Function::RvalueRefQualifier);
|
Function::RvalueRefQualifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// propagate exception spec
|
||||||
this->exceptionSpecification(ast->exception_specification, type);
|
this->exceptionSpecification(ast->exception_specification, type);
|
||||||
|
if (ExceptionSpecificationAST *spec = ast->exception_specification)
|
||||||
|
fun->setExceptionSpecification(asStringLiteral(spec));
|
||||||
|
|
||||||
if (ast->as_cpp_initializer != nullptr) {
|
if (ast->as_cpp_initializer != nullptr) {
|
||||||
fun->setAmbiguous(true);
|
fun->setAmbiguous(true);
|
||||||
/*ExpressionTy as_cpp_initializer =*/ this->expression(ast->as_cpp_initializer);
|
/*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);
|
void capture(CaptureAST *ast);
|
||||||
Function *lambdaDeclarator(LambdaDeclaratorAST *ast);
|
Function *lambdaDeclarator(LambdaDeclaratorAST *ast);
|
||||||
FullySpecifiedType trailingReturnType(TrailingReturnTypeAST *ast, const FullySpecifiedType &init);
|
FullySpecifiedType trailingReturnType(TrailingReturnTypeAST *ast, const FullySpecifiedType &init);
|
||||||
const StringLiteral *asStringLiteral(const ExpressionAST *ast);
|
const StringLiteral *asStringLiteral(const AST *ast);
|
||||||
|
|
||||||
virtual bool preVisit(AST *);
|
virtual bool preVisit(AST *);
|
||||||
virtual void postVisit(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)
|
Function::Function(Clone *clone, Subst *subst, Function *original)
|
||||||
: Scope(clone, subst, original)
|
: Scope(clone, subst, original)
|
||||||
, _returnType(clone->type(original->_returnType, subst))
|
, _returnType(clone->type(original->_returnType, subst))
|
||||||
|
, _exceptionSpecification(original->_exceptionSpecification)
|
||||||
, _flags(original->_flags)
|
, _flags(original->_flags)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
@@ -534,6 +535,11 @@ bool Function::maybeValidPrototype(int actualArgumentCount) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const StringLiteral *Function::exceptionSpecification()
|
||||||
|
{ return _exceptionSpecification; }
|
||||||
|
|
||||||
|
void Function::setExceptionSpecification(const StringLiteral *spec)
|
||||||
|
{ _exceptionSpecification = spec; }
|
||||||
|
|
||||||
Block::Block(TranslationUnit *translationUnit, int sourceLocation)
|
Block::Block(TranslationUnit *translationUnit, int sourceLocation)
|
||||||
: Scope(translationUnit, sourceLocation, /*name = */ nullptr)
|
: 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 {
|
namespace CPlusPlus {
|
||||||
|
|
||||||
|
class StringLiteral;
|
||||||
|
|
||||||
class CPLUSPLUS_EXPORT UsingNamespaceDirective: public Symbol
|
class CPLUSPLUS_EXPORT UsingNamespaceDirective: public Symbol
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -363,6 +365,9 @@ public:
|
|||||||
|
|
||||||
bool maybeValidPrototype(int actualArgumentCount) const;
|
bool maybeValidPrototype(int actualArgumentCount) const;
|
||||||
|
|
||||||
|
const StringLiteral *exceptionSpecification();
|
||||||
|
void setExceptionSpecification(const StringLiteral *spec);
|
||||||
|
|
||||||
// Symbol's interface
|
// Symbol's interface
|
||||||
virtual FullySpecifiedType type() const;
|
virtual FullySpecifiedType type() const;
|
||||||
|
|
||||||
@@ -386,6 +391,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
FullySpecifiedType _returnType;
|
FullySpecifiedType _returnType;
|
||||||
|
const StringLiteral *_exceptionSpecification = nullptr;
|
||||||
struct Flags {
|
struct Flags {
|
||||||
unsigned _isVirtual: 1;
|
unsigned _isVirtual: 1;
|
||||||
unsigned _isOverride: 1;
|
unsigned _isOverride: 1;
|
||||||
|
@@ -136,6 +136,7 @@ public:
|
|||||||
funTy->setConst(type->isConst());
|
funTy->setConst(type->isConst());
|
||||||
funTy->setVolatile(type->isVolatile());
|
funTy->setVolatile(type->isVolatile());
|
||||||
funTy->setRefQualifier(type->refQualifier());
|
funTy->setRefQualifier(type->refQualifier());
|
||||||
|
funTy->setExceptionSpecification(type->exceptionSpecification());
|
||||||
|
|
||||||
funTy->setName(rewrite->rewriteName(type->name()));
|
funTy->setName(rewrite->rewriteName(type->name()));
|
||||||
|
|
||||||
|
@@ -487,6 +487,12 @@ void TypePrettyPrinter::visit(Function *type)
|
|||||||
? QLatin1String("&")
|
? QLatin1String("&")
|
||||||
: 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_ignoreSurroundingGeneratedDeclarations();
|
||||||
void test_quickfix_InsertDefFromDecl_respectWsInOperatorNames1();
|
void test_quickfix_InsertDefFromDecl_respectWsInOperatorNames1();
|
||||||
void test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2();
|
void test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2();
|
||||||
|
void test_quickfix_InsertDefFromDecl_noexcept_specifier();
|
||||||
void test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1();
|
void test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1();
|
||||||
void test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2();
|
void test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile2();
|
||||||
void test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfFile();
|
void test_quickfix_InsertDefFromDecl_erroneousStatementAtEndOfFile();
|
||||||
|
@@ -2502,6 +2502,29 @@ void CppEditorPlugin::test_quickfix_InsertDefFromDecl_respectWsInOperatorNames2(
|
|||||||
QuickFixOperationTest(singleDocument(original, expected), &factory);
|
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
|
/// Check if a function like macro use is not separated by the function to insert
|
||||||
/// Case: Macro preceded by preproceesor directives and declaration.
|
/// Case: Macro preceded by preproceesor directives and declaration.
|
||||||
void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1()
|
void CppEditorPlugin::test_quickfix_InsertDefFromDecl_macroUsesAtEndOfFile1()
|
||||||
|
Reference in New Issue
Block a user