aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/Sema/SemaChecking.cpp
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2020-02-14 16:46:49 -0800
committerYonghong Song <yhs@fb.com>2020-05-15 09:44:54 -0700
commit072cde03aaa13a2c57acf62d79876bf79aa1919f (patch)
tree679d6492b681f88ce0b2f34c3e9cfa9219f7be03 /clang/lib/Sema/SemaChecking.cpp
parent9825d3daa80c19872326d8e137ada39a1727cfe8 (diff)
downloadllvm-072cde03aaa13a2c57acf62d79876bf79aa1919f.zip
llvm-072cde03aaa13a2c57acf62d79876bf79aa1919f.tar.gz
llvm-072cde03aaa13a2c57acf62d79876bf79aa1919f.tar.bz2
[Clang][BPF] implement __builtin_btf_type_id() builtin function
Such a builtin function is mostly useful to preserve btf type id for non-global data. For example, extern void foo(..., void *data, int size); int test(...) { struct t { int a; int b; int c; } d; d.a = ...; d.b = ...; d.c = ...; foo(..., &d, sizeof(d)); } The function "foo" in the above only see raw data and does not know what type of the data is. In certain cases, e.g., logging, the additional type information will help pretty print. This patch implemented a BPF specific builtin u32 btf_type_id = __builtin_btf_type_id(param, flag) which will return a btf type id for the "param". flag == 0 will indicate a BTF local relocation, which means btf type_id only adjusted when bpf program BTF changes. flag == 1 will indicate a BTF remote relocation, which means btf type_id is adjusted against linux kernel or future other entities. Differential Revision: https://reviews.llvm.org/D74668
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r--clang/lib/Sema/SemaChecking.cpp23
1 files changed, 20 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index fbf0fb0..370eece 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -2487,17 +2487,33 @@ bool Sema::CheckAArch64BuiltinFunctionCall(unsigned BuiltinID,
bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID,
CallExpr *TheCall) {
- assert(BuiltinID == BPF::BI__builtin_preserve_field_info &&
+ assert((BuiltinID == BPF::BI__builtin_preserve_field_info ||
+ BuiltinID == BPF::BI__builtin_btf_type_id) &&
"unexpected ARM builtin");
if (checkArgCount(*this, TheCall, 2))
return true;
+ Expr *Arg;
+ if (BuiltinID == BPF::BI__builtin_btf_type_id) {
+ // The second argument needs to be a constant int
+ llvm::APSInt Value;
+ Arg = TheCall->getArg(1);
+ if (!Arg->isIntegerConstantExpr(Value, Context)) {
+ Diag(Arg->getBeginLoc(), diag::err_btf_type_id_not_const)
+ << 2 << Arg->getSourceRange();
+ return true;
+ }
+
+ TheCall->setType(Context.UnsignedIntTy);
+ return false;
+ }
+
// The first argument needs to be a record field access.
// If it is an array element access, we delay decision
// to BPF backend to check whether the access is a
// field access or not.
- Expr *Arg = TheCall->getArg(0);
+ Arg = TheCall->getArg(0);
if (Arg->getType()->getAsPlaceholderType() ||
(Arg->IgnoreParens()->getObjectKind() != OK_BitField &&
!dyn_cast<MemberExpr>(Arg->IgnoreParens()) &&
@@ -2508,8 +2524,9 @@ bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID,
}
// The second argument needs to be a constant int
+ Arg = TheCall->getArg(1);
llvm::APSInt Value;
- if (!TheCall->getArg(1)->isIntegerConstantExpr(Value, Context)) {
+ if (!Arg->isIntegerConstantExpr(Value, Context)) {
Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const)
<< 2 << Arg->getSourceRange();
return true;