-
Notifications
You must be signed in to change notification settings - Fork 62
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add new match handler for Field declaration - copied from lavatool on
master
- Loading branch information
Showing
1 changed file
with
50 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#ifndef FIELDDECLARGADDITIONHANDLER_H | ||
#define FIELDDECLARGADDITIONHANDLER_H | ||
|
||
using namespace clang; | ||
|
||
/* | ||
A field in a struct or union that is fn pointer type | ||
field decl looks something like | ||
boolean (*empty_output_buffer) (j_compress_ptr cinfo); | ||
so all we need is to find location just after that open paren | ||
of fn arg type list | ||
*/ | ||
struct FieldDeclArgAdditionHandler : public LavaMatchHandler { | ||
using LavaMatchHandler::LavaMatchHandler; // Inherit constructor | ||
|
||
virtual void handle(const MatchFinder::MatchResult &Result) { | ||
const FieldDecl *fd = | ||
Result.Nodes.getNodeAs<FieldDecl>("fielddecl"); | ||
SourceLocation l1 = fd->getLocStart(); | ||
SourceLocation l2 = fd->getLocEnd(); | ||
bool inv; | ||
debug(FNARG) << "fielddecl : [" << getStringBetween(*Mod.sm, l1, l2, &inv) << "]\n"; | ||
if (inv) { | ||
debug(FNARG) << "... is invalid\n"; | ||
return; | ||
} | ||
const Type *ft = fd->getType().getTypePtr(); | ||
if (ft->isFunctionPointerType()) { | ||
// field is a fn pointer | ||
const Type *pt = ft->getPointeeType().IgnoreParens().getTypePtr(); | ||
assert(pt); | ||
const FunctionType *fun_type = dyn_cast<FunctionType>(pt); | ||
if (fun_type == NULL) { | ||
debug(FNARG) << "... clang could not determine function type, abort\n"; | ||
return; | ||
} | ||
|
||
assert(fun_type); | ||
const FunctionProtoType *prot = dyn_cast<FunctionProtoType>(fun_type); | ||
// add the data_flow arg | ||
SourceLocation l1 = fd->getLocStart(); | ||
SourceLocation l2 = fd->getLocEnd(); | ||
AddArgGen(Mod, l1, l2, false, prot->getNumParams(), 2); | ||
} | ||
} | ||
}; | ||
|
||
#endif |