10 #include "clang/AST/ASTContext.h"
11 #include "clang/AST/Decl.h"
12 #include "clang/AST/DeclObjC.h"
13 #include "clang/ASTMatchers/ASTMatchFinder.h"
14 #include "clang/ASTMatchers/ASTMatchers.h"
15 #include "clang/Basic/Diagnostic.h"
23 void DispatchOnceNonstaticCheck::registerMatchers(MatchFinder *Finder) {
27 varDecl(hasLocalStorage(), hasType(asString(
"dispatch_once_t")))
28 .bind(
"non-static-var"),
35 objcIvarDecl(hasType(asString(
"dispatch_once_t"))).bind(
"ivar"),
this);
38 void DispatchOnceNonstaticCheck::check(
const MatchFinder::MatchResult &Result) {
39 if (
const auto *VD = Result.Nodes.getNodeAs<VarDecl>(
"non-static-var")) {
40 if (
const auto *PD = dyn_cast<ParmVarDecl>(VD)) {
43 diag(PD->getTypeSpecStartLoc(),
44 "dispatch_once_t variables must have static or global storage "
45 "duration; function parameters should be pointer references");
47 diag(VD->getTypeSpecStartLoc(),
"dispatch_once_t variables must have "
48 "static or global storage duration")
49 << FixItHint::CreateInsertion(VD->getTypeSpecStartLoc(),
"static ");
53 if (
const auto *D = Result.Nodes.getNodeAs<ObjCIvarDecl>(
"ivar")) {
54 diag(D->getTypeSpecStartLoc(),
55 "dispatch_once_t variables must have static or global storage "
56 "duration and cannot be Objective-C instance variables");