NonTrivialTypeInFfiChecker.cpp (1945B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #include "NonTrivialTypeInFfiChecker.h" 6 #include "CustomMatchers.h" 7 8 void NonTrivialTypeInFfiChecker::registerMatchers(MatchFinder *AstMatcher) { 9 AstMatcher->addMatcher(functionDecl(isExternC()).bind("func"), this); 10 } 11 12 void NonTrivialTypeInFfiChecker::check(const MatchFinder::MatchResult &Result) { 13 static DenseSet<const FunctionDecl *> CheckedFunctionDecls; 14 15 const FunctionDecl *func = Result.Nodes.getNodeAs<FunctionDecl>("func"); 16 // Don't report errors on the same declarations more than once. 17 if (!CheckedFunctionDecls.insert(func).second) { 18 return; 19 } 20 21 if (inThirdPartyPath(func)) { 22 return; 23 } 24 25 auto NoteFor = [](const QualType &T) -> std::string { 26 std::string s = "Please consider using a pointer or reference"; 27 if (T->getAs<TemplateSpecializationType>()) { 28 s += ", or explicitly instantiating the template"; 29 } 30 return s + " instead"; 31 }; 32 33 for (ParmVarDecl *p : func->parameters()) { 34 QualType T = p->getType().getUnqualifiedType(); 35 if (!T->isVoidType() && !T->isReferenceType() && 36 !T.isTriviallyCopyableType(*Result.Context)) { 37 diag(p->getLocation(), 38 "Type %0 must not be used as parameter to extern " 39 "\"C\" function", 40 DiagnosticIDs::Error) 41 << T; 42 diag(p->getLocation(), NoteFor(T), DiagnosticIDs::Note); 43 } 44 } 45 46 QualType T = func->getReturnType().getUnqualifiedType(); 47 if (!T->isVoidType() && !T->isReferenceType() && 48 !T.isTriviallyCopyableType(*Result.Context)) { 49 diag(func->getLocation(), 50 "Type %0 must not be used as return type of " 51 "extern \"C\" function", 52 DiagnosticIDs::Error) 53 << T; 54 diag(func->getLocation(), NoteFor(T), DiagnosticIDs::Note); 55 } 56 }