void OverrideVirtual::run() { if (preRun())
TraverseDecl(compiler.getASTContext().getTranslationUnitDecl());
} bool OverrideVirtual::VisitCXXMethodDecl(CXXMethodDecl const * decl) { // As a heuristic, ignore declarations where the name is spelled out in an // ignored location; that e.g. handles uses of the Q_OBJECT macro from // external QtCore/qobjectdefs.h: if (ignoreLocation(decl) || !decl->isFirstDecl()
|| decl->begin_overridden_methods() == decl->end_overridden_methods()
|| decl->hasAttr<OverrideAttr>()
|| ignoreLocation(
compiler.getSourceManager().getSpellingLoc(
decl->getNameInfo().getLoc())))
{ returntrue;
}
std::string over(
isInUnoIncludeFile(decl->getSourceRange().getBegin())
? "SAL_OVERRIDE" : "override"); if (rewriter != nullptr) { // In void MACRO(...); getSourceRange().getEnd() would (erroneously?) // point at "MACRO" rather than ")", so make the loop always terminate // at the first ";" or "{" instead of getSourceRange().getEnd(): unsigned parens = 0; bool seenSpace = false; //TODO: Whether to add a space after an inserted "SAL_OVERRIDE" should // depend on the following token at the spelling location where // "SAL_OVERRIDE" is inserted, not on the following token in the fully- // macro-expanded view: bool addSpace = bool();
SourceLocation loc; for (SourceLocation l(decl->getSourceRange().getBegin());;) {
SourceLocation sl(compiler.getSourceManager().getSpellingLoc(l)); unsigned n = Lexer::MeasureTokenLength(
sl, compiler.getSourceManager(), compiler.getLangOpts());
StringRef s(compiler.getSourceManager().getCharacterData(sl), n); //TODO: Looks like a Clang bug that in some cases like // (filter/source/svg/svgexport.cxx) // // | #define TEXT_FIELD_GET_CLASS_NAME_METHOD( class_name ) \ | // | virtual OUString getClassName() const \ | // | { \ | // | static const char className[] = #class_name; \ | // | return OUString( className ); \ | // | } | // | | // | TEXT_FIELD_GET_CLASS_NAME_METHOD( TextField ) | // // where "\<NL>" is followed directly by a real token without // intervening whitespace, tokens "\<NL>virtual" and "\<NL>{" are // reported: if (compat::starts_with(s, "\\\n")) {
s = s.drop_front(2);
} if (parens == 0) { if (s == "=" || s == "{") { if (!seenSpace) {
addSpace = true;
} break;
} if (s == ";") { break;
}
} if (s == "(") {
assert(parens < std::numeric_limits<unsigned>::max());
++parens;
} elseif (s == ")") {
assert(parens != 0);
--parens;
} if (s.empty()) { if (!seenSpace) {
addSpace = false;
}
seenSpace = true;
} elseif (compat::starts_with(s, "/*") || compat::starts_with(s, "//") || s == "\\") { if (!seenSpace) {
addSpace = true;
}
seenSpace = true;
} else {
seenSpace = false;
addSpace = false;
loc = sl;
} if (l.isMacroID()
&& compiler.getSourceManager().isAtEndOfImmediateMacroExpansion(
l, &l))
{
n = Lexer::MeasureTokenLength(
compiler.getSourceManager().getSpellingLoc(l),
compiler.getSourceManager(), compiler.getLangOpts());
}
l = l.getLocWithOffset(std::max<unsigned>(n, 1));
}
assert(loc.isValid()); if (!insertions_.insert(loc).second
|| insertTextAfterToken(
loc,
std::string(" ") + over + std::string(addSpace ? " " : "")))
{ returntrue;
}
}
report(
DiagnosticsEngine::Warning,
("overriding virtual function declaration not marked '%0'"),
decl->getLocation())
<< over << decl->getSourceRange(); for (auto i = decl->begin_overridden_methods();
i != decl->end_overridden_methods(); ++i)
{
report(
DiagnosticsEngine::Note, "overridden declaration is here",
(*i)->getLocation())
<< (*i)->getSourceRange();
} returntrue;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.