yonghong-song updated this revision to Diff 281481.
yonghong-song retitled this revision from "[clang][BPF] support expr with 
typedef/record type for TYPE_EXISTENCE reloc" to "[clang][BPF] support type 
existence/size and enum value relocations".
yonghong-song edited the summary of this revision.
yonghong-song added a comment.

support relocations for type_sizeof and enum_value as well.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D83242/new/

https://reviews.llvm.org/D83242

Files:
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/include/clang/Basic/TargetInfo.h
  clang/lib/Basic/Targets/BPF.h
  clang/lib/CodeGen/CGBuiltin.cpp
  clang/lib/Sema/SemaChecking.cpp
  clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c
  clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c
  clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c
  clang/test/Sema/builtins-bpf.c

Index: clang/test/Sema/builtins-bpf.c
===================================================================
--- clang/test/Sema/builtins-bpf.c
+++ clang/test/Sema/builtins-bpf.c
@@ -1,14 +1,36 @@
 // RUN: %clang_cc1 -x c -triple bpf-pc-linux-gnu -dwarf-version=4 -fsyntax-only -verify %s
 
-struct s { int a; int b[4]; int c:1; };
-union u { int a; int b[4]; int c:1; };
+struct s {
+  int a;
+  int b[4];
+  int c:1;
+};
+union u {
+  int a;
+  int b[4];
+  int c:1;
+};
+typedef struct {
+  int a;
+  int b;
+} __t;
+typedef int (*__f)(void);
+enum AA {
+  VAL1 = 1,
+  VAL2 = 2,
+  VAL3 = 10,
+};
+typedef enum {
+  VAL10 = 10,
+  VAL11 = 11,
+} __BB;
 
 unsigned invalid1(const int *arg) {
-  return __builtin_preserve_field_info(arg, 1); // expected-error {{__builtin_preserve_field_info argument 1 not a field access}}
+  return __builtin_preserve_field_info(arg, 1); // expected-error {{__builtin_preserve_field_info argument 1 invalid}}
 }
 
 unsigned invalid2(const int *arg) {
-  return __builtin_preserve_field_info(*arg, 1); // expected-error {{__builtin_preserve_field_info argument 1 not a field access}}
+  return __builtin_preserve_field_info(*arg, 1); // expected-error {{__builtin_preserve_field_info argument 1 invalid}}
 }
 
 void *invalid3(struct s *arg) {
@@ -46,3 +68,38 @@
 unsigned invalid11(struct s *arg, int info_kind) {
   return __builtin_preserve_field_info(arg->a, info_kind); // expected-error {{__builtin_preserve_field_info argument 2 not a constant}}
 }
+
+unsigned valid12() {
+  const struct s t;
+  return __builtin_preserve_field_info(t, 8) +
+         __builtin_preserve_field_info(*(struct s *)0, 8);
+}
+
+unsigned valid13() {
+  __t t;
+  return __builtin_preserve_field_info(t, 8) +
+         __builtin_preserve_field_info(*(__t *)0, 8);
+}
+
+unsigned valid14() {
+  enum AA t;
+  return __builtin_preserve_field_info(t, 8) +
+         __builtin_preserve_field_info(*(enum AA *)0, 8);
+}
+
+unsigned invalid15() {
+  return __builtin_preserve_field_info(*(__BB *)2, 10); // expected-error {{__builtin_preserve_field_info argument 1 invalid}}
+}
+
+unsigned invalid16() {
+  return __builtin_preserve_field_info(*(__BB *)VAL3, 10); // expected-error {{__builtin_preserve_field_info argument 1 invalid}}
+}
+
+unsigned invalid17(struct s *arg) {
+  return __builtin_preserve_field_info(arg->a + 2, 8); // expected-error {{__builtin_preserve_field_info argument 1 invalid}}
+}
+
+unsigned invalid18() {
+  enum AA t = 1;
+  return __builtin_preserve_field_info(t, 10); // expected-error {{__builtin_preserve_field_info argument 1 invalid}}
+}
Index: clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c
===================================================================
--- /dev/null
+++ clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c
@@ -0,0 +1,55 @@
+// REQUIRES: bpf-registered-target
+// RUN: %clang -target bpf -emit-llvm -S -g %s -o - | FileCheck %s
+
+#define _(x, y) (__builtin_preserve_field_info((x), (y)))
+
+struct s {
+  char a;
+};
+typedef int __int;
+enum AA {
+  VAL1 = 1,
+  VAL2 = 2,
+};
+typedef enum AA __AA;
+
+unsigned unit1() {
+  struct s v = {};
+  return _(v, 8) + _(*(struct s *)0, 8);
+}
+
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0s_struct.ss(%struct.s* %{{[0-9a-z]+}}, i64 8), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S:[0-9]+]]
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0s_struct.ss(%struct.s* null, i64 8), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S]]
+
+unsigned unit2() {
+  __int n;
+  return _(n, 8) + _(*(__int *)0, 8);
+}
+
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %{{[0-9a-z]+}}, i64 8), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[TYPEDEF_INT:[0-9]+]]
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i32(i32* null, i64 8), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[TYPEDEF_INT]]
+
+unsigned unit3() {
+  enum AA t;
+  return _(t, 8) + _(*(enum AA *)0, 8);
+}
+
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i32(i32* %{{[0-9a-z]+}}, i64 8), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[ENUM_AA:[0-9]+]]
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i32(i32* null, i64 8), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[ENUM_AA]]
+
+unsigned unit4() {
+  return _(*(enum AA *)VAL2, 10);
+}
+
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i32(i32* inttoptr (i64 2 to i32*), i64 10), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[ENUM_AA]]
+
+unsigned unit5() {
+  return _(*(__AA *)VAL2, 10);
+}
+
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i32(i32* inttoptr (i64 2 to i32*), i64 10), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[TYPEDEF_ENUM:[0-9]+]]
+
+// CHECK: ![[ENUM_AA]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA"
+// CHECK: ![[STRUCT_S]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s"
+// CHECK: ![[TYPEDEF_INT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__int"
+// CHECK: ![[TYPEDEF_ENUM]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__AA"
Index: clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c
===================================================================
--- clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c
+++ clang/test/CodeGen/builtins-bpf-preserve-field-info-2.c
@@ -12,15 +12,15 @@
 };
 
 unsigned unit1(struct s2 *arg) {
-  return _(arg->s.a, 10) + _(arg->s.b, 10);
+  return _(arg->s.a, 4) + _(arg->s.b, 4);
 }
 // CHECK: define dso_local i32 @unit1
 // CHECK: call %struct.s1* @llvm.preserve.struct.access.index.p0s_struct.s1s.p0s_struct.s2s(%struct.s2* %{{[0-9a-z]+}}, i32 0, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S2:[0-9]+]]
 // CHECK: call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1* %{{[0-9a-z]+}}, i32 0, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S1:[0-9]+]]
-// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 10), !dbg !{{[0-9]+}}
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 4), !dbg !{{[0-9]+}}
 // CHECK: call %struct.s1* @llvm.preserve.struct.access.index.p0s_struct.s1s.p0s_struct.s2s(%struct.s2* %{{[0-9a-z]+}}, i32 0, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S2:[0-9]+]]
 // CHECK: call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1* %{{[0-9a-z]+}}, i32 1, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S1:[0-9]+]]
-// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 10), !dbg !{{[0-9]+}}
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 4), !dbg !{{[0-9]+}}
 
 // CHECK: ![[STRUCT_S2]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s2"
 // CHECK: ![[STRUCT_S1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1"
Index: clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c
===================================================================
--- clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c
+++ clang/test/CodeGen/builtins-bpf-preserve-field-info-1.c
@@ -14,22 +14,22 @@
 };
 
 unsigned unit1(struct s1 *arg) {
-  return _(arg->a, 10) + _(arg->b, 10);
+  return _(arg->a, 4) + _(arg->b, 4);
 }
 // CHECK: define dso_local i32 @unit1
 // CHECK: call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1* %{{[0-9a-z]+}}, i32 0, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S1:[0-9]+]]
-// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 10), !dbg !{{[0-9]+}}
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 4), !dbg !{{[0-9]+}}
 // CHECK: call i8* @llvm.preserve.struct.access.index.p0i8.p0s_struct.s1s(%struct.s1* %{{[0-9a-z]+}}, i32 1, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[STRUCT_S1:[0-9]+]]
-// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 10), !dbg !{{[0-9]+}}
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 4), !dbg !{{[0-9]+}}
 
 unsigned unit2(union u1 *arg) {
-  return _(arg->a, 10) + _(arg->b, 10);
+  return _(arg->a, 4) + _(arg->b, 4);
 }
 // CHECK: define dso_local i32 @unit2
 // CHECK: call %union.u1* @llvm.preserve.union.access.index.p0s_union.u1s.p0s_union.u1s(%union.u1* %{{[0-9a-z]+}}, i32 0), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[UNION_U1:[0-9]+]]
-// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 10), !dbg !{{[0-9]+}}
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 4), !dbg !{{[0-9]+}}
 // CHECK: call i8* @llvm.preserve.struct.access.index.p0i8.p0s_union.u1s(%union.u1* %{{[0-9a-z]+}}, i32 0, i32 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[UNION_U1:[0-9]+]]
-// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 10), !dbg !{{[0-9]+}}
+// CHECK: call i32 @llvm.bpf.preserve.field.info.p0i8(i8* %{{[0-9a-z]+}}, i64 4), !dbg !{{[0-9]+}}
 
 // CHECK: ![[STRUCT_S1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s1"
 // CHECK: ![[UNION_U1]] = distinct !DICompositeType(tag: DW_TAG_union_type, name: "u1"
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -2557,11 +2557,111 @@
   return SemaBuiltinConstantArgRange(TheCall, i, l, u + l);
 }
 
+// For non TYPE_EXISTENCE/TYPE_SIZEOF/ENUM_VALUE relocation type,
+// 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.
+//
+// For TYPE_EXISTENCE/TYPE_SIZEOF relocation type,
+// the argument type should be a typedef, a named record type,
+// or a named enum type.
+//
+// For ENUM_VALUE relocation type, the argument type should be
+// an enum type or a typedef resolving into an enum type.
+// The enum value must be one of supported values in the
+// enum type.
+static bool isValidBPFPreserveFieldInfoArg(Sema &S, Expr *Arg,
+                                           int64_t RelocKind) {
+  QualType ArgType = Arg->getType();
+  if (ArgType->getAsPlaceholderType())
+    return false;
+
+  // struct/union field based relocations
+  bool IsEnumValue;
+  if (!S.Context.getTargetInfo().BPFTagIntrinsic(RelocKind, IsEnumValue)) {
+    if (Arg->IgnoreParens()->getObjectKind() == OK_BitField ||
+        dyn_cast<MemberExpr>(Arg->IgnoreParens()) ||
+        dyn_cast<ArraySubscriptExpr>(Arg->IgnoreParens())) {
+      return true;
+    }
+    return false;
+  }
+
+  // for TYPE_EXISTENCE/TYPE_SIZEOF reloc type
+  // format:
+  //   1. __builtin_preserve_field_info(*(<type> *)0, reloc_kind);
+  //   2. <type> var;
+  //      __builtin_preserve_field_info(var, reloc_kind);
+  if (!IsEnumValue) {
+    if (!dyn_cast<DeclRefExpr>(Arg->IgnoreParens()) &&
+        !dyn_cast<UnaryOperator>(Arg->IgnoreParens()))
+      return false;
+
+    if (ArgType->getAs<TypedefType>())
+      return true;
+
+    // Record type or Enum type.
+    const Type *Ty = ArgType->getUnqualifiedDesugaredType();
+    if (const auto *RT = Ty->getAs<RecordType>()) {
+      if (!RT->getDecl()->getDeclName().isEmpty())
+        return true;
+    } else if (const auto *ET = Ty->getAs<EnumType>()) {
+      if (!ET->getDecl()->getDeclName().isEmpty())
+        return true;
+    }
+    return false;
+  }
+
+  // for ENUM_VALUE reloc type
+  // format:
+  //   __builtin_preserve_field_info(*(<enum_type> *)<enum_value>,
+  //                                 ENUM_VALUE);
+  const auto *UO = dyn_cast<UnaryOperator>(Arg->IgnoreParens());
+  if (!UO)
+    return false;
+
+  const auto *CE = dyn_cast<CStyleCastExpr>(UO->getSubExpr());
+  if (!CE || CE->getCastKind() != CK_IntegralToPointer)
+    return false;
+
+  // The integer must be from an IntegerLiteral or an EnumConstantDecl.
+  llvm::APInt EnumValue;
+  const EnumConstantDecl *Enumerator = nullptr;
+  if (const auto *I = dyn_cast<IntegerLiteral>(CE->getSubExpr())) {
+    EnumValue = I->getValue();
+  } else if (const auto *DR = dyn_cast<DeclRefExpr>(CE->getSubExpr())) {
+    Enumerator = dyn_cast<EnumConstantDecl>(DR->getDecl());
+    if (!Enumerator)
+      return false;
+  } else {
+    return false;
+  }
+
+  // The type must be EnumType.
+  const Type *Ty = ArgType->getUnqualifiedDesugaredType();
+  const auto *ET = Ty->getAs<EnumType>();
+  if (!ET)
+    return false;
+
+  // The enum value must be supported.
+  for (auto *EDI : ET->getDecl()->enumerators()) {
+    if (Enumerator) {
+      if (EDI == Enumerator)
+        return true;
+    } else if (EDI->getInitVal() == EnumValue.getLimitedValue()) {
+        return true;
+    }
+  }
+
+  return false;
+}
+
 bool Sema::CheckBPFBuiltinFunctionCall(unsigned BuiltinID,
                                        CallExpr *TheCall) {
   assert((BuiltinID == BPF::BI__builtin_preserve_field_info ||
           BuiltinID == BPF::BI__builtin_btf_type_id) &&
-         "unexpected ARM builtin");
+         "unexpected BPF builtin");
 
   if (checkArgCount(*this, TheCall, 2))
     return true;
@@ -2580,28 +2680,23 @@
     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.
-  Arg = TheCall->getArg(0);
-  if (Arg->getType()->getAsPlaceholderType() ||
-      (Arg->IgnoreParens()->getObjectKind() != OK_BitField &&
-       !dyn_cast<MemberExpr>(Arg->IgnoreParens()) &&
-       !dyn_cast<ArraySubscriptExpr>(Arg->IgnoreParens()))) {
-    Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_field)
-        << 1 << Arg->getSourceRange();
-    return true;
-  }
-
   // The second argument needs to be a constant int
   Arg = TheCall->getArg(1);
-  if (!Arg->isIntegerConstantExpr(Context)) {
+  Optional<llvm::APSInt> Value = Arg->getIntegerConstantExpr(Context);
+  if (!Value) {
     Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const)
         << 2 << Arg->getSourceRange();
     return true;
   }
 
+  int64_t RelocKind = Value->getExtValue();
+  Arg = TheCall->getArg(0);
+  if (!isValidBPFPreserveFieldInfoArg(*this, Arg, RelocKind)) {
+    Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_invalid)
+        << 1 << Arg->getSourceRange();
+    return true;
+  }
+
   TheCall->setType(Context.UnsignedIntTy);
   return false;
 }
Index: clang/lib/CodeGen/CGBuiltin.cpp
===================================================================
--- clang/lib/CodeGen/CGBuiltin.cpp
+++ clang/lib/CodeGen/CGBuiltin.cpp
@@ -10960,11 +10960,14 @@
     llvm_unreachable("Unexpected BPF builtin");
   case BPF::BI__builtin_preserve_field_info: {
     const Expr *Arg = E->getArg(0);
+    bool IsLValue = Arg->isLValue();
     bool IsBitField = Arg->IgnoreParens()->getObjectKind() == OK_BitField;
 
     if (!getDebugInfo()) {
       CGM.Error(E->getExprLoc(),
                 "using __builtin_preserve_field_info() without -g");
+      if (!IsLValue)
+        return EmitScalarExpr(Arg);
       return IsBitField ? EmitLValue(Arg).getBitFieldPointer()
                         : EmitLValue(Arg).getPointer(*this);
     }
@@ -10972,8 +10975,12 @@
     // Enable underlying preserve_*_access_index() generation.
     bool OldIsInPreservedAIRegion = IsInPreservedAIRegion;
     IsInPreservedAIRegion = true;
-    Value *FieldAddr = IsBitField ? EmitLValue(Arg).getBitFieldPointer()
-                                  : EmitLValue(Arg).getPointer(*this);
+    Value *FieldAddr;
+    if (!IsLValue)
+      FieldAddr = EmitScalarExpr(Arg);
+    else
+      FieldAddr = IsBitField ? EmitLValue(Arg).getBitFieldPointer()
+                             : EmitLValue(Arg).getPointer(*this);
     IsInPreservedAIRegion = OldIsInPreservedAIRegion;
 
     ConstantInt *C = cast<ConstantInt>(EmitScalarExpr(E->getArg(1)));
@@ -10983,7 +10990,23 @@
     llvm::Function *FnGetFieldInfo = llvm::Intrinsic::getDeclaration(
         &CGM.getModule(), llvm::Intrinsic::bpf_preserve_field_info,
         {FieldAddr->getType()});
-    return Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind});
+    CallInst *Fn = Builder.CreateCall(FnGetFieldInfo, {FieldAddr, InfoKind});
+
+    // Add debuginfo metadata to bpf_preserve_field_info intrinsic
+    // for CORE relocation type TYPE_EXISTENCE/TYPE_SIZEOF/ENUM_VALUE.
+    // This is used to capture the existence/size of a typedef/record/enum
+    // type or a enum value, for which we do not have IR intrinsics
+    // generated.
+    bool IsEnumValue;
+    bool TagDbgInfo = getContext().getTargetInfo().BPFTagIntrinsic(
+        C->getSExtValue(), IsEnumValue);
+    if (TagDbgInfo) {
+      llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateStandaloneType(
+          E->getArg(0)->getType(), E->getArg(0)->getExprLoc());
+      Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo);
+    }
+
+    return Fn;
   }
   case BPF::BI__builtin_btf_type_id: {
     Value *FieldVal = nullptr;
Index: clang/lib/Basic/Targets/BPF.h
===================================================================
--- clang/lib/Basic/Targets/BPF.h
+++ clang/lib/Basic/Targets/BPF.h
@@ -44,6 +44,19 @@
     TLSSupported = false;
   }
 
+  bool BPFTagIntrinsic(int64_t RelocKind, bool &IsEnumValue) const override {
+    // Reloc Kind 8: TYPE_EXISTENCE, 9: TYPE_SIZEOF, 10: ENUM_VALUE
+    if (RelocKind == 8 || RelocKind == 9) {
+      IsEnumValue = false;
+      return true;
+    } else if (RelocKind == 10) {
+      IsEnumValue = true;
+      return true;
+    } else {
+      return false;
+    }
+  }
+
   void getTargetDefines(const LangOptions &Opts,
                         MacroBuilder &Builder) const override;
 
Index: clang/include/clang/Basic/TargetInfo.h
===================================================================
--- clang/include/clang/Basic/TargetInfo.h
+++ clang/include/clang/Basic/TargetInfo.h
@@ -856,6 +856,15 @@
   /// available on this target.
   bool hasAArch64SVETypes() const { return HasAArch64SVETypes; }
 
+  /// Returns whether or not the BPF target should add
+  /// debuginfo as meta data for a given relocation kind.
+  /// Also set IsEnumValue depending on whether the reloc kind is
+  /// for ENUM_VALUE.
+  virtual bool BPFTagIntrinsic(int64_t RelocKind, bool &IsEnumValue) const {
+    IsEnumValue = false;
+    return false;
+  }
+
   /// For ARM targets returns a mask defining which coprocessors are configured
   /// as Custom Datapath.
   uint32_t getARMCDECoprocMask() const { return ARMCDECoprocMask; }
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -10850,8 +10850,8 @@
   "import %select{module|name}0 cannot be applied to a function with a definition">,
   InGroup<IgnoredAttributes>;
 
-def err_preserve_field_info_not_field : Error<
-  "__builtin_preserve_field_info argument %0 not a field access">;
+def err_preserve_field_info_invalid : Error<
+  "__builtin_preserve_field_info argument %0 invalid">;
 def err_preserve_field_info_not_const: Error<
   "__builtin_preserve_field_info argument %0 not a constant">;
 def err_btf_type_id_not_const: Error<
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D83242: [clang][BPF]... Yonghong Song via Phabricator via cfe-commits

Reply via email to