Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ParamTraitsEnumChecker.h"
#include "CustomMatchers.h"
void ParamTraitsEnumChecker::registerMatchers(MatchFinder *AstMatcher) {
AstMatcher->addMatcher(
classTemplateSpecializationDecl(
hasName("ParamTraits"),
unless(anyOf(
// Exclude ParamTraits that derive from EnumSerializer (e.g.,
// ContiguousEnumSerializer) as these are the recommended way to
// serialize enums.
isDerivedFrom("EnumSerializer"),
// Exclude ParamTraits_IsEnumCase, which is an alternative to
// EnumSerializer.
isDerivedFrom("ParamTraits_IsEnumCase"),
// Exclude nsresult specifically, which has a legitimate
// ParamTraitsMozilla specialization.
hasTemplateArgument(
0, refersToType(hasDeclaration(namedDecl(hasName("nsresult"))))))))
.bind("decl"),
this);
}
void ParamTraitsEnumChecker::check(const MatchFinder::MatchResult &Result) {
const ClassTemplateSpecializationDecl *Decl =
Result.Nodes.getNodeAs<ClassTemplateSpecializationDecl>("decl");
const TemplateArgumentList &ArgumentList = Decl->getTemplateArgs();
if (ArgumentList.size() != 1) {
diag(Decl->getBeginLoc(),
"ParamTraits specialization should have exactly one template argument",
DiagnosticIDs::Error);
return;
}
QualType ArgType = ArgumentList[0].getAsType();
if (const clang::Type *TypePtr = ArgType.getTypePtrOrNull()) {
if (TypePtr->isEnumeralType()) {
diag(Decl->getBeginLoc(),
"Custom ParamTraits implementation for an enum type",
DiagnosticIDs::Error);
diag(Decl->getBeginLoc(),
"Please use a helper class for example ContiguousEnumSerializer",
DiagnosticIDs::Note);
}
}
}