diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -10966,11 +10966,17 @@ ConstantInt *C = cast(EmitScalarExpr(E->getArg(1))); Value *InfoKind = ConstantInt::get(Int64Ty, C->getSExtValue()); + llvm::DIType *DbgInfo = + getDebugInfo()->getOrCreateStandaloneType(E->getArg(0)->getType(), + E->getArg(0)->getExprLoc()); + // Built the IR for the preserve_field_info intrinsic. 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}); + Fn->setMetadata(LLVMContext::MD_preserve_access_index, DbgInfo); + return Fn; } case BPF::BI__builtin_btf_type_id: { Value *FieldVal = nullptr; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -2582,6 +2582,15 @@ return false; } + // The second argument needs to be a constant int + Arg = TheCall->getArg(1); + llvm::APSInt Value; + if (!Arg->isIntegerConstantExpr(Value, Context)) { + Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const) + << 2 << Arg->getSourceRange(); + return true; + } + // 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 @@ -2590,21 +2599,14 @@ if (Arg->getType()->getAsPlaceholderType() || (Arg->IgnoreParens()->getObjectKind() != OK_BitField && !dyn_cast(Arg->IgnoreParens()) && - !dyn_cast(Arg->IgnoreParens()))) { + !dyn_cast(Arg->IgnoreParens()) && + // Value 2 here represents reloc kind FIELD_EXISTENCE. + (Value != 2 || !Arg->getType()->getAs()))) { 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); - llvm::APSInt Value; - if (!Arg->isIntegerConstantExpr(Value, Context)) { - Diag(Arg->getBeginLoc(), diag::err_preserve_field_info_not_const) - << 2 << Arg->getSourceRange(); - return true; - } - TheCall->setType(Context.UnsignedIntTy); return false; } diff --git a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp --- a/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp +++ b/llvm/lib/Target/BPF/BPFAbstractMemberAccess.cpp @@ -277,7 +277,7 @@ } if (GV->getName().startswith("llvm.bpf.preserve.field.info")) { CInfo.Kind = BPFPreserveFieldInfoAI; - CInfo.Metadata = nullptr; + CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index); // Check validity of info_kind as clang did not check this. uint64_t InfoKind = getConstant(Call->getArgOperand(1)); if (InfoKind >= BPFCoreSharedInfo::MAX_FIELD_RELOC_KIND) @@ -742,6 +742,13 @@ break; } + if (CInfo.Kind == BPFPreserveFieldInfoAI) { + // typedef type. + TypeName = std::string(PossibleTypeDef->getName()); + TypeMeta = PossibleTypeDef; + break; + } + assert(CInfo.Kind == BPFPreserveArrayAI); // Array entries will always be consumed for accumulative initial index.