34 #include <llvm/ADT/APInt.h>
35 #include <llvm/IR/GlobalVariable.h>
45 auto *Call = dyn_cast<CallInst>(U);
47 assert(Call->getNumArgOperands() == 4);
49 Value *Ptr(Call->getArgOperand(0));
50 StringRef Name(ExtractStringConstant(Call->getArgOperand(1)));
51 StringRef Filename(ExtractStringConstant(Call->getArgOperand(2)));
52 APInt Line = dyn_cast<ConstantInt>(Call->getArgOperand(3))->getValue();
54 const string FIELD =
"field:";
56 if (!Name.startswith(FIELD))
59 size_t Dot(Name.find(
'.'));
60 StringRef StructName(Name.slice(FIELD.length(), Dot));
61 StringRef FieldName(Name.substr(Dot + 1));
63 return new FieldAnnotation(Call, Ptr, StructName, FieldName, Filename, Line);
66 StringRef PtrAnnotation::ExtractStringConstant(
const Value *V) {
67 auto *Ptr = dyn_cast<ConstantExpr>(V);
68 assert(Ptr && Ptr->isGEPWithNoNotionalOverIndexing());
70 auto *Var = dyn_cast<GlobalVariable>(Ptr->getOperand(0));
71 auto *Array = dyn_cast<ConstantDataArray>(Var->getInitializer());
73 return Array->getAsString();
78 string Complete = (StructName +
"." + FieldName).str();
81 Complete.resize(
strnlen(Complete.c_str(), Complete.length()));