/*! Handle return types of function definitions */ bool PointerDeclarationFormatter::visit(FunctionDefinitionAST *ast) { CHECK_RV(ast, "Invalid AST", true); printCandidate(ast); DeclaratorAST *declarator = ast->declarator; CHECK_RV(declarator, "No declarator", true); CHECK_RV(declarator->ptr_operator_list, "No Pointer or references", true); Symbol *symbol = ast->symbol; PostfixDeclaratorListAST *pfDeclaratorList = declarator->postfix_declarator_list; CHECK_RV(pfDeclaratorList, "No postfix declarator list", true); PostfixDeclaratorAST *pfDeclarator = pfDeclaratorList->value; CHECK_RV(pfDeclarator, "No postfix declarator", true); FunctionDeclaratorAST *functionDeclarator = pfDeclarator->asFunctionDeclarator(); CHECK_RV(functionDeclarator, "No function declarator", true); // Specify activation range bool foundBegin = false; const unsigned lastActivationToken = functionDeclarator->lparen_token - 1; const unsigned firstActivationToken = firstTypeSpecifierWithoutFollowingAttribute( ast->decl_specifier_list, m_cppRefactoringFile->cppDocument()->translationUnit(), lastActivationToken, &foundBegin); CHECK_RV(foundBegin, "Declaration without attributes not supported", true); TokenRange range(firstActivationToken, lastActivationToken); checkAndRewrite(declarator, symbol, range); return true; }
void CppSelectionChanger::fineTuneASTNodePositions(ASTNodePositions &positions) const { AST *ast = positions.ast; if (ast->asCompoundStatement()) { // Allow first selecting the contents of the scope, without selecting the braces, and // afterwards select the contents together with braces. if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting inner contents of compound statement."; unsigned firstInnerTokenIndex = positions.firstTokenIndex + 1; unsigned lastInnerTokenIndex = positions.lastTokenIndex - 2; Token firstInnerToken = m_unit->tokenAt(firstInnerTokenIndex); Token lastInnerToken = m_unit->tokenAt(lastInnerTokenIndex); if (debug) { qDebug() << "LastInnerToken:" << lastInnerToken.spell(); qDebug() << "FirstInnerToken:" << firstInnerToken.spell(); } // Check if compound statement is empty, then select just the blank space inside it. int newPosStart, newPosEnd; if (positions.secondToLastTokenIndex - positions.firstTokenIndex <= 1) { // TODO: If the empty space has a new tab character, or spaces, and the document is // not saved, the last semantic info is not updated, and the selection is not // properly computed. Figure out how to work around this. newPosStart = getTokenEndCursorPosition(positions.firstTokenIndex, m_workingCursor); newPosEnd = getTokenStartCursorPosition(positions.secondToLastTokenIndex, m_workingCursor); if (debug) qDebug() << "Selecting inner contents of compound statement which is empty."; } else { // Select the inner contents of the scope, without the braces. newPosStart = getTokenStartCursorPosition(firstInnerTokenIndex, m_workingCursor); newPosEnd = getTokenEndCursorPosition(lastInnerTokenIndex, m_workingCursor); } if (debug) { qDebug() << "New" << newPosStart << newPosEnd << "Old" << m_workingCursor.anchor() << m_workingCursor.position(); } positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } // Next time, we select the braces as well. Reverse for shrinking. // The positions already have the correct selection, so no need to set them. } else if (CallAST *callAST = ast->asCall()) { unsigned firstParenTokenIndex = callAST->lparen_token; unsigned lastParenTokenIndex = callAST->rparen_token; Token firstParenToken = m_unit->tokenAt(firstParenTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstParenToken:" << firstParenToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } // Select the parenthesis of the call, and everything between. int newPosStart = getTokenStartCursorPosition(firstParenTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); bool isInFunctionName = m_initialChangeSelectionCursor.position() <= newPosStart; // If cursor is inside the function name, select the name implicitly (because it's a // different AST node), and then the whole call expression (so just one step). // If cursor is inside parentheses, on first step select everything inside them, // on second step select the everything inside parentheses including them, // on third step select the whole call expression. if (currentASTStep() == 1 && !isInFunctionName) { if (debug) qDebug() << "Selecting everything inside parentheses."; positions.astPosStart = newPosStart + 1; positions.astPosEnd = newPosEnd - 1; } if (currentASTStep() == 2 && !isInFunctionName) { if (debug) qDebug() << "Selecting everything inside and including " "the parentheses of the function call."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (StringLiteralAST *stringLiteralAST = ast->asStringLiteral()) { // Select literal without quotes on first step, and the whole literal on next step. if (currentASTStep() == 1) { Token firstToken = m_unit->tokenAt(stringLiteralAST->firstToken()); bool isRawLiteral = firstToken.f.kind >= T_FIRST_RAW_STRING_LITERAL && firstToken.f.kind <= T_RAW_UTF32_STRING_LITERAL; if (debug && isRawLiteral) qDebug() << "Is raw literal."; // Start from positions that include quotes. int newPosEnd = positions.astPosEnd; // Decrement last position to skip last quote. --newPosEnd; // If raw literal also skip parenthesis. if (isRawLiteral) --newPosEnd; // Start position will be the end position minus the size of the actual contents of the // literal. int newPosStart = newPosEnd - static_cast<int>(firstToken.string->size()); // Skip raw literal parentheses. if (isRawLiteral) newPosStart += 2; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; if (debug) qDebug() << "Selecting inner contents of string literal."; } } else if (NumericLiteralAST *numericLiteralAST = ast->asNumericLiteral()) { Token firstToken = m_unit->tokenAt(numericLiteralAST->firstToken()); // If char literal, select it without quotes on first step. if (firstToken.isCharLiteral()) { if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting inner contents of char literal."; positions.astPosEnd = positions.astPosEnd - 1; positions.astPosStart = positions.astPosEnd - int(firstToken.literal->size()); } } } else if (ForStatementAST *forStatementAST = ast->asForStatement()) { unsigned firstParenTokenIndex = forStatementAST->lparen_token; unsigned lastParenTokenIndex = forStatementAST->rparen_token; fineTuneForStatementPositions(firstParenTokenIndex, lastParenTokenIndex, positions); } else if (RangeBasedForStatementAST *rangeForStatementAST = ast->asRangeBasedForStatement()) { unsigned firstParenTokenIndex = rangeForStatementAST->lparen_token; unsigned lastParenTokenIndex = rangeForStatementAST->rparen_token; fineTuneForStatementPositions(firstParenTokenIndex, lastParenTokenIndex, positions); } else if (ClassSpecifierAST *classSpecificerAST = ast->asClassSpecifier()) { unsigned firstBraceTokenIndex = classSpecificerAST->lbrace_token; unsigned lastBraceTokenIndex = classSpecificerAST->rbrace_token; unsigned classKeywordTokenIndex = classSpecificerAST->classkey_token; Token firstBraceToken = m_unit->tokenAt(firstBraceTokenIndex); Token lastBraceToken = m_unit->tokenAt(lastBraceTokenIndex); Token classKeywordToken = m_unit->tokenAt(classKeywordTokenIndex); if (debug) { qDebug() << "firstBraceToken:" << firstBraceToken.spell(); qDebug() << "lastBraceToken:" << lastBraceToken.spell(); qDebug() << "classKeywordToken:" << classKeywordToken.spell(); } int newPosStart = getTokenStartCursorPosition(firstBraceTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastBraceTokenIndex, m_workingCursor); bool isOutsideBraces = m_initialChangeSelectionCursor.position() <= newPosStart; bool isInsideBraces = !isOutsideBraces; int classKeywordPosStart = getTokenStartCursorPosition(classKeywordTokenIndex, m_workingCursor); int classKeywordPosEnd = getTokenEndCursorPosition(classKeywordTokenIndex, m_workingCursor); bool isInClassKeyword = m_initialChangeSelectionCursor.anchor() >= classKeywordPosStart && m_initialChangeSelectionCursor.position() <= classKeywordPosEnd; bool isInClassName = false; int classNamePosEnd = newPosEnd; NameAST *nameAST = classSpecificerAST->name; if (nameAST) { SimpleNameAST *classNameAST = nameAST->asSimpleName(); if (classNameAST) { unsigned identifierTokenIndex = classNameAST->identifier_token; Token identifierToken = m_unit->tokenAt(identifierTokenIndex); if (debug) qDebug() << "identifierToken:" << identifierToken.spell(); int classNamePosStart = getTokenStartCursorPosition(identifierTokenIndex, m_workingCursor); classNamePosEnd = getTokenEndCursorPosition(identifierTokenIndex, m_workingCursor); isInClassName = m_initialChangeSelectionCursor.anchor() >= classNamePosStart && m_initialChangeSelectionCursor.position() <= classNamePosEnd; } } if (currentASTStep() == 1 && isInsideBraces) { if (debug) qDebug() << "Selecting everything inside braces of class statement."; positions.astPosStart = newPosStart + 1; positions.astPosEnd = newPosEnd - 1; } if (currentASTStep() == 2 && isInsideBraces) { if (debug) qDebug() << "Selecting braces of class statement."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } if (currentASTStep() == 1 && isInClassKeyword) { if (debug) qDebug() << "Selecting class keyword."; positions.astPosStart = classKeywordPosStart; positions.astPosEnd = classKeywordPosEnd; } if (currentASTStep() == 2 && isInClassKeyword) { if (debug) qDebug() << "Selecting class keyword and name."; positions.astPosStart = classKeywordPosStart; positions.astPosEnd = classNamePosEnd; } if (currentASTStep() == 1 && isInClassName) { if (debug) qDebug() << "Selecting class keyword and name."; positions.astPosStart = classKeywordPosStart; positions.astPosEnd = classNamePosEnd; } } else if (NamespaceAST *namespaceAST = ast->asNamespace()) { unsigned namespaceTokenIndex = namespaceAST->namespace_token; unsigned identifierTokenIndex = namespaceAST->identifier_token; Token namespaceToken = m_unit->tokenAt(namespaceTokenIndex); Token identifierToken = m_unit->tokenAt(identifierTokenIndex); if (debug) { qDebug() << "namespace token:" << namespaceToken.spell(); qDebug() << "identifier token:" << identifierToken.spell(); } int namespacePosStart = getTokenStartCursorPosition(namespaceTokenIndex, m_workingCursor); int namespacePosEnd = getTokenEndCursorPosition(namespaceTokenIndex, m_workingCursor); int identifierPosStart = getTokenStartCursorPosition(identifierTokenIndex, m_workingCursor); int identifierPosEnd = getTokenEndCursorPosition(identifierTokenIndex, m_workingCursor); bool isInNamespaceKeyword = m_initialChangeSelectionCursor.position() <= namespacePosEnd; bool isInNamespaceIdentifier = m_initialChangeSelectionCursor.anchor() >= identifierPosStart && m_initialChangeSelectionCursor.position() <= identifierPosEnd; if (currentASTStep() == 1) { if (isInNamespaceKeyword) { if (debug) qDebug() << "Selecting namespace keyword."; positions.astPosStart = namespacePosStart; positions.astPosEnd = namespacePosEnd; } else if (isInNamespaceIdentifier) { if (debug) qDebug() << "Selecting namespace identifier."; positions.astPosStart = identifierPosStart; positions.astPosEnd = identifierPosEnd; } } else if (currentASTStep() == 2) { if (isInNamespaceKeyword || isInNamespaceIdentifier) { if (debug) qDebug() << "Selecting namespace keyword and identifier."; positions.astPosStart = namespacePosStart; positions.astPosEnd = identifierPosEnd; } } } else if (ExpressionListParenAST *parenAST = ast->asExpressionListParen()) { unsigned firstParenTokenIndex = parenAST->lparen_token; unsigned lastParenTokenIndex = parenAST->rparen_token; Token firstParenToken = m_unit->tokenAt(firstParenTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstParenToken:" << firstParenToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } // Select the parentheses, and everything between. int newPosStart = getTokenStartCursorPosition(firstParenTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting everything inside parentheses."; positions.astPosStart = newPosStart + 1; positions.astPosEnd = newPosEnd - 1; } if (currentASTStep() == 2) { if (debug) qDebug() << "Selecting everything inside including the parentheses."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (FunctionDeclaratorAST* functionDeclaratorAST = ast->asFunctionDeclarator()) { unsigned firstParenTokenIndex = functionDeclaratorAST->lparen_token; unsigned lastParenTokenIndex = functionDeclaratorAST->rparen_token; Token firstParenToken = m_unit->tokenAt(firstParenTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstParenToken:" << firstParenToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } int newPosStart = getTokenStartCursorPosition(firstParenTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); if (currentASTStep() == 1) { if (debug) qDebug() << "Selecting everything inside and including the parentheses."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (FunctionDefinitionAST *functionDefinitionAST = ast->asFunctionDefinition()) { if (!functionDefinitionAST->function_body) return; CompoundStatementAST *compoundStatementAST = functionDefinitionAST->function_body->asCompoundStatement(); if (!compoundStatementAST) return; if (!functionDefinitionAST->decl_specifier_list || !functionDefinitionAST->decl_specifier_list->value) return; SimpleSpecifierAST *simpleSpecifierAST = functionDefinitionAST->decl_specifier_list->value->asSimpleSpecifier(); if (!simpleSpecifierAST) return; unsigned firstBraceTokenIndex = compoundStatementAST->lbrace_token; unsigned specifierTokenIndex = simpleSpecifierAST->firstToken(); Token firstBraceToken = m_unit->tokenAt(firstBraceTokenIndex); Token specifierToken = m_unit->tokenAt(specifierTokenIndex); if (debug) { qDebug() << "firstBraceToken:" << firstBraceToken.spell(); qDebug() << "specifierToken:" << specifierToken.spell(); } int firstBracePosEnd = getTokenStartCursorPosition(firstBraceTokenIndex, m_workingCursor); bool isOutsideBraces = m_initialChangeSelectionCursor.position() <= firstBracePosEnd; if (currentASTStep() == 1 && isOutsideBraces) { int newPosStart = getTokenStartCursorPosition(specifierTokenIndex, m_workingCursor); if (debug) qDebug() << "Selecting everything to the left of the function braces."; positions.astPosStart = newPosStart; positions.astPosEnd = firstBracePosEnd - 1; } } else if (DeclaratorAST *declaratorAST = ast->asDeclarator()) { PostfixDeclaratorListAST *list = declaratorAST->postfix_declarator_list; if (!list) return; PostfixDeclaratorAST *postfixDeclarator = list->value; if (!postfixDeclarator) return; FunctionDeclaratorAST *functionDeclarator = postfixDeclarator->asFunctionDeclarator(); if (!functionDeclarator) return; SpecifierListAST *cv_list = functionDeclarator->cv_qualifier_list; if (!cv_list) return; SpecifierAST *first_cv = cv_list->value; if (!first_cv) return; unsigned firstCVTokenIndex = first_cv->firstToken(); Token firstCVToken = m_unit->tokenAt(firstCVTokenIndex); if (debug) { qDebug() << "firstCVTokenIndex:" << firstCVToken.spell(); } int cvPosStart = getTokenStartCursorPosition(firstCVTokenIndex, m_workingCursor); bool isBeforeCVList = m_initialChangeSelectionCursor.position() < cvPosStart; if (currentASTStep() == 1 && isBeforeCVList) { if (debug) qDebug() << "Selecting function declarator without CV qualifiers."; int newPosEnd = cvPosStart; positions.astPosEnd = newPosEnd - 1; } } else if (TemplateIdAST *templateIdAST = ast->asTemplateId()) { unsigned identifierTokenIndex = templateIdAST->identifier_token; Token identifierToken = m_unit->tokenAt(identifierTokenIndex); if (debug) { qDebug() << "identifierTokenIndex:" << identifierToken.spell(); } int newPosStart = getTokenStartCursorPosition(identifierTokenIndex, m_workingCursor); int newPosEnd = getTokenEndCursorPosition(identifierTokenIndex, m_workingCursor); bool isInsideIdentifier = m_initialChangeSelectionCursor.anchor() >= newPosStart && m_initialChangeSelectionCursor.position() <= newPosEnd; if (currentASTStep() == 1 && isInsideIdentifier) { if (debug) qDebug() << "Selecting just identifier before selecting template id."; positions.astPosStart = newPosStart; positions.astPosEnd = newPosEnd; } } else if (TemplateDeclarationAST *templateDeclarationAST = ast->asTemplateDeclaration()) { unsigned templateKeywordTokenIndex = templateDeclarationAST->template_token; unsigned greaterTokenIndex = templateDeclarationAST->greater_token; Token templateKeywordToken = m_unit->tokenAt(templateKeywordTokenIndex); Token greaterToken = m_unit->tokenAt(greaterTokenIndex); if (debug) { qDebug() << "templateKeywordTokenIndex:" << templateKeywordToken.spell(); qDebug() << "greaterTokenIndex:" << greaterToken.spell(); } int templateKeywordPosStart = getTokenStartCursorPosition(templateKeywordTokenIndex, m_workingCursor); int templateKeywordPosEnd = getTokenEndCursorPosition(templateKeywordTokenIndex, m_workingCursor); int templateParametersPosEnd = getTokenEndCursorPosition(greaterTokenIndex, m_workingCursor); bool isInsideTemplateKeyword = m_initialChangeSelectionCursor.anchor() >= templateKeywordPosStart && m_initialChangeSelectionCursor.position() <= templateKeywordPosEnd; if (currentASTStep() == 1 && isInsideTemplateKeyword) { if (debug) qDebug() << "Selecting template keyword."; positions.astPosStart = templateKeywordPosStart; positions.astPosEnd = templateKeywordPosEnd; } if (currentASTStep() == 2 && isInsideTemplateKeyword) { if (debug) qDebug() << "Selecting template keyword and parameters."; positions.astPosStart = templateKeywordPosStart; positions.astPosEnd = templateParametersPosEnd; } } else if (LambdaExpressionAST *lambdaExpressionAST = ast->asLambdaExpression()) { // TODO: Fix more lambda cases. LambdaIntroducerAST *lambdaIntroducerAST = lambdaExpressionAST->lambda_introducer; LambdaDeclaratorAST *lambdaDeclaratorAST = lambdaExpressionAST->lambda_declarator; if (!lambdaDeclaratorAST) return; TrailingReturnTypeAST *trailingReturnTypeAST = lambdaDeclaratorAST->trailing_return_type; unsigned firstSquareBracketTokenIndex = lambdaIntroducerAST->lbracket_token; unsigned lastParenTokenIndex = lambdaDeclaratorAST->rparen_token; Token firstSquareBracketToken = m_unit->tokenAt(firstSquareBracketTokenIndex); Token lastParenToken = m_unit->tokenAt(lastParenTokenIndex); if (debug) { qDebug() << "firstSquareBracketToken:" << firstSquareBracketToken.spell(); qDebug() << "lastParenToken:" << lastParenToken.spell(); } int firstSquareBracketPosStart = getTokenStartCursorPosition(firstSquareBracketTokenIndex, m_workingCursor); int lastParenPosEnd = getTokenEndCursorPosition(lastParenTokenIndex, m_workingCursor); bool isInsideDeclarator = m_initialChangeSelectionCursor.anchor() >= firstSquareBracketPosStart && m_initialChangeSelectionCursor.position() <= lastParenPosEnd; if (currentASTStep() == 1 && isInsideDeclarator) { if (debug) qDebug() << "Selecting lambda capture group and arguments."; positions.astPosStart = firstSquareBracketPosStart; positions.astPosEnd = lastParenPosEnd; } if (currentASTStep() == 2 && isInsideDeclarator && trailingReturnTypeAST) { if (debug) qDebug() << "Selecting lambda prototype."; unsigned lastReturnTypeTokenIndex = trailingReturnTypeAST->lastToken(); Token lastReturnTypeToken = m_unit->tokenAt(lastReturnTypeTokenIndex); if (debug) qDebug() << "lastReturnTypeToken:" << lastReturnTypeToken.spell(); int lastReturnTypePosEnd = getTokenEndCursorPosition(lastReturnTypeTokenIndex, m_workingCursor); positions.astPosStart = firstSquareBracketPosStart; positions.astPosEnd = lastReturnTypePosEnd - 2; } } }
/*! Handle (1) Simple declarations like in "char *s, *t, *int foo();" (2) Return types of function declarations. */ bool PointerDeclarationFormatter::visit(SimpleDeclarationAST *ast) { CHECK_RV(ast, "Invalid AST", true); printCandidate(ast); const unsigned tokenKind = tokenAt(ast->firstToken()).kind(); const bool astIsOk = tokenKind != T_CLASS && tokenKind != T_STRUCT && tokenKind != T_ENUM; CHECK_RV(astIsOk, "Nothing to do for class/struct/enum", true); DeclaratorListAST *declaratorList = ast->declarator_list; CHECK_RV(declaratorList, "No declarator list", true); DeclaratorAST *firstDeclarator = declaratorList->value; CHECK_RV(firstDeclarator, "No declarator", true); CHECK_RV(ast->symbols, "No Symbols", true); CHECK_RV(ast->symbols->value, "No Symbol", true); List<Symbol *> *sit = ast->symbols; DeclaratorListAST *dit = declaratorList; for (; sit && dit; sit = sit->next, dit = dit->next) { DeclaratorAST *declarator = dit->value; Symbol *symbol = sit->value; const bool isFirstDeclarator = declarator == firstDeclarator; // If were not handling the first declarator, we need to remove // characters from the beginning since our rewritten declaration // will contain all type specifiers. int charactersToRemove = 0; if (!isFirstDeclarator) { const int startAST = m_cppRefactoringFile->startOf(ast); const int startFirstDeclarator = m_cppRefactoringFile->startOf(firstDeclarator); CHECK_RV(startAST < startFirstDeclarator, "No specifier", true); charactersToRemove = startFirstDeclarator - startAST; } // Specify activation range int lastActivationToken = 0; TokenRange range; // (2) Handle function declaration's return type if (symbol->type()->asFunctionType()) { PostfixDeclaratorListAST *pfDeclaratorList = declarator->postfix_declarator_list; CHECK_RV(pfDeclaratorList, "No postfix declarator list", true); PostfixDeclaratorAST *pfDeclarator = pfDeclaratorList->value; CHECK_RV(pfDeclarator, "No postfix declarator", true); FunctionDeclaratorAST *functionDeclarator = pfDeclarator->asFunctionDeclarator(); CHECK_RV(functionDeclarator, "No function declarator", true); // End the activation range before the '(' token. lastActivationToken = functionDeclarator->lparen_token - 1; SpecifierListAST *specifierList = isFirstDeclarator ? ast->decl_specifier_list : declarator->attribute_list; unsigned firstActivationToken = 0; bool foundBegin = false; firstActivationToken = firstTypeSpecifierWithoutFollowingAttribute( specifierList, m_cppRefactoringFile->cppDocument()->translationUnit(), lastActivationToken, &foundBegin); if (!foundBegin) { CHECK_RV(!isFirstDeclarator, "Declaration without attributes not supported", true); firstActivationToken = declarator->firstToken(); } range.start = firstActivationToken; // (1) Handle 'normal' declarations. } else { if (isFirstDeclarator) { bool foundBegin = false; unsigned firstActivationToken = firstTypeSpecifierWithoutFollowingAttribute( ast->decl_specifier_list, m_cppRefactoringFile->cppDocument()->translationUnit(), declarator->firstToken(), &foundBegin); CHECK_RV(foundBegin, "Declaration without attributes not supported", true); range.start = firstActivationToken; } else { range.start = declarator->firstToken(); } lastActivationToken = declarator->equal_token ? declarator->equal_token - 1 : declarator->lastToken() - 1; } range.end = lastActivationToken; checkAndRewrite(declarator, symbol, range, charactersToRemove); } return true; }