diff options
Diffstat (limited to 'clang/lib/CodeGen')
| -rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 3 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 198 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGHLSLRuntime.cpp | 100 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGHLSLRuntime.h | 34 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.cpp | 15 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CGOpenMPRuntime.h | 4 | ||||
| -rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.h | 9 |
7 files changed, 118 insertions, 245 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index c423c4b..468c930 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -684,7 +684,8 @@ static void addKCFIPass(const Triple &TargetTriple, const LangOptions &LangOpts, PassBuilder &PB) { // If the back-end supports KCFI operand bundle lowering, skip KCFIPass. if (TargetTriple.getArch() == llvm::Triple::x86_64 || - TargetTriple.isAArch64(64) || TargetTriple.isRISCV()) + TargetTriple.isAArch64(64) || TargetTriple.isRISCV() || + TargetTriple.isARM() || TargetTriple.isThumb()) return; // Ensure we lower KCFI operand bundles with -O0. diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index fd73314..301d577 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -29,6 +29,7 @@ #include "clang/AST/ASTLambda.h" #include "clang/AST/Attr.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/InferAlloc.h" #include "clang/AST/NSAPI.h" #include "clang/AST/ParentMapContext.h" #include "clang/AST/StmtVisitor.h" @@ -1273,194 +1274,39 @@ void CodeGenFunction::EmitBoundsCheckImpl(const Expr *E, llvm::Value *Bound, EmitCheck(std::make_pair(Check, CheckKind), CheckHandler, StaticData, Index); } -static bool -typeContainsPointer(QualType T, - llvm::SmallPtrSet<const RecordDecl *, 4> &VisitedRD, - bool &IncompleteType) { - QualType CanonicalType = T.getCanonicalType(); - if (CanonicalType->isPointerType()) - return true; // base case - - // Look through typedef chain to check for special types. - for (QualType CurrentT = T; const auto *TT = CurrentT->getAs<TypedefType>(); - CurrentT = TT->getDecl()->getUnderlyingType()) { - const IdentifierInfo *II = TT->getDecl()->getIdentifier(); - // Special Case: Syntactically uintptr_t is not a pointer; semantically, - // however, very likely used as such. Therefore, classify uintptr_t as a - // pointer, too. - if (II && II->isStr("uintptr_t")) - return true; - } - - // The type is an array; check the element type. - if (const ArrayType *AT = dyn_cast<ArrayType>(CanonicalType)) - return typeContainsPointer(AT->getElementType(), VisitedRD, IncompleteType); - // The type is a struct, class, or union. - if (const RecordDecl *RD = CanonicalType->getAsRecordDecl()) { - if (!RD->isCompleteDefinition()) { - IncompleteType = true; - return false; - } - if (!VisitedRD.insert(RD).second) - return false; // already visited - // Check all fields. - for (const FieldDecl *Field : RD->fields()) { - if (typeContainsPointer(Field->getType(), VisitedRD, IncompleteType)) - return true; - } - // For C++ classes, also check base classes. - if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { - // Polymorphic types require a vptr. - if (CXXRD->isDynamicClass()) - return true; - for (const CXXBaseSpecifier &Base : CXXRD->bases()) { - if (typeContainsPointer(Base.getType(), VisitedRD, IncompleteType)) - return true; - } - } - } - return false; -} - -void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB, QualType AllocType) { - assert(SanOpts.has(SanitizerKind::AllocToken) && - "Only needed with -fsanitize=alloc-token"); +llvm::MDNode *CodeGenFunction::buildAllocToken(QualType AllocType) { + auto ATMD = infer_alloc::getAllocTokenMetadata(AllocType, getContext()); + if (!ATMD) + return nullptr; llvm::MDBuilder MDB(getLLVMContext()); - - // Get unique type name. - PrintingPolicy Policy(CGM.getContext().getLangOpts()); - Policy.SuppressTagKeyword = true; - Policy.FullyQualifiedName = true; - SmallString<64> TypeName; - llvm::raw_svector_ostream TypeNameOS(TypeName); - AllocType.getCanonicalType().print(TypeNameOS, Policy); - auto *TypeNameMD = MDB.createString(TypeNameOS.str()); - - // Check if QualType contains a pointer. Implements a simple DFS to - // recursively check if a type contains a pointer type. - llvm::SmallPtrSet<const RecordDecl *, 4> VisitedRD; - bool IncompleteType = false; - const bool ContainsPtr = - typeContainsPointer(AllocType, VisitedRD, IncompleteType); - if (!ContainsPtr && IncompleteType) - return; - auto *ContainsPtrC = Builder.getInt1(ContainsPtr); + auto *TypeNameMD = MDB.createString(ATMD->TypeName); + auto *ContainsPtrC = Builder.getInt1(ATMD->ContainsPointer); auto *ContainsPtrMD = MDB.createConstant(ContainsPtrC); // Format: !{<type-name>, <contains-pointer>} - auto *MDN = - llvm::MDNode::get(CGM.getLLVMContext(), {TypeNameMD, ContainsPtrMD}); - CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN); -} - -namespace { -/// Infer type from a simple sizeof expression. -QualType inferTypeFromSizeofExpr(const Expr *E) { - const Expr *Arg = E->IgnoreParenImpCasts(); - if (const auto *UET = dyn_cast<UnaryExprOrTypeTraitExpr>(Arg)) { - if (UET->getKind() == UETT_SizeOf) { - if (UET->isArgumentType()) - return UET->getArgumentTypeInfo()->getType(); - else - return UET->getArgumentExpr()->getType(); - } - } - return QualType(); -} - -/// Infer type from an arithmetic expression involving a sizeof. For example: -/// -/// malloc(sizeof(MyType) + padding); // infers 'MyType' -/// malloc(sizeof(MyType) * 32); // infers 'MyType' -/// malloc(32 * sizeof(MyType)); // infers 'MyType' -/// malloc(sizeof(MyType) << 1); // infers 'MyType' -/// ... -/// -/// More complex arithmetic expressions are supported, but are a heuristic, e.g. -/// when considering allocations for structs with flexible array members: -/// -/// malloc(sizeof(HasFlexArray) + sizeof(int) * 32); // infers 'HasFlexArray' -/// -QualType inferPossibleTypeFromArithSizeofExpr(const Expr *E) { - const Expr *Arg = E->IgnoreParenImpCasts(); - // The argument is a lone sizeof expression. - if (QualType T = inferTypeFromSizeofExpr(Arg); !T.isNull()) - return T; - if (const auto *BO = dyn_cast<BinaryOperator>(Arg)) { - // Argument is an arithmetic expression. Cover common arithmetic patterns - // involving sizeof. - switch (BO->getOpcode()) { - case BO_Add: - case BO_Div: - case BO_Mul: - case BO_Shl: - case BO_Shr: - case BO_Sub: - if (QualType T = inferPossibleTypeFromArithSizeofExpr(BO->getLHS()); - !T.isNull()) - return T; - if (QualType T = inferPossibleTypeFromArithSizeofExpr(BO->getRHS()); - !T.isNull()) - return T; - break; - default: - break; - } - } - return QualType(); + return llvm::MDNode::get(CGM.getLLVMContext(), {TypeNameMD, ContainsPtrMD}); } -/// If the expression E is a reference to a variable, infer the type from a -/// variable's initializer if it contains a sizeof. Beware, this is a heuristic -/// and ignores if a variable is later reassigned. For example: -/// -/// size_t my_size = sizeof(MyType); -/// void *x = malloc(my_size); // infers 'MyType' -/// -QualType inferPossibleTypeFromVarInitSizeofExpr(const Expr *E) { - const Expr *Arg = E->IgnoreParenImpCasts(); - if (const auto *DRE = dyn_cast<DeclRefExpr>(Arg)) { - if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { - if (const Expr *Init = VD->getInit()) - return inferPossibleTypeFromArithSizeofExpr(Init); - } - } - return QualType(); +void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB, QualType AllocType) { + assert(SanOpts.has(SanitizerKind::AllocToken) && + "Only needed with -fsanitize=alloc-token"); + CB->setMetadata(llvm::LLVMContext::MD_alloc_token, + buildAllocToken(AllocType)); } -/// Deduces the allocated type by checking if the allocation call's result -/// is immediately used in a cast expression. For example: -/// -/// MyType *x = (MyType *)malloc(4096); // infers 'MyType' -/// -QualType inferPossibleTypeFromCastExpr(const CallExpr *CallE, - const CastExpr *CastE) { - if (!CastE) - return QualType(); - QualType PtrType = CastE->getType(); - if (PtrType->isPointerType()) - return PtrType->getPointeeType(); - return QualType(); +llvm::MDNode *CodeGenFunction::buildAllocToken(const CallExpr *E) { + QualType AllocType = infer_alloc::inferPossibleType(E, getContext(), CurCast); + if (!AllocType.isNull()) + return buildAllocToken(AllocType); + return nullptr; } -} // end anonymous namespace void CodeGenFunction::EmitAllocToken(llvm::CallBase *CB, const CallExpr *E) { - QualType AllocType; - // First check arguments. - for (const Expr *Arg : E->arguments()) { - AllocType = inferPossibleTypeFromArithSizeofExpr(Arg); - if (AllocType.isNull()) - AllocType = inferPossibleTypeFromVarInitSizeofExpr(Arg); - if (!AllocType.isNull()) - break; - } - // Then check later casts. - if (AllocType.isNull()) - AllocType = inferPossibleTypeFromCastExpr(E, CurCast); - // Emit if we were able to infer the type. - if (!AllocType.isNull()) - EmitAllocToken(CB, AllocType); + assert(SanOpts.has(SanitizerKind::AllocToken) && + "Only needed with -fsanitize=alloc-token"); + if (llvm::MDNode *MDN = buildAllocToken(E)) + CB->setMetadata(llvm::LLVMContext::MD_alloc_token, MDN); } CodeGenFunction::ComplexPairTy CodeGenFunction:: diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index ecab933..945f9e2 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -562,17 +562,16 @@ static llvm::Value *createSPIRVBuiltinLoad(IRBuilder<> &B, llvm::Module &M, return B.CreateLoad(Ty, GV); } -llvm::Value * -CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, - const clang::DeclaratorDecl *Decl, - SemanticInfo &ActiveSemantic) { - if (isa<HLSLSV_GroupIndexAttr>(ActiveSemantic.Semantic)) { +llvm::Value *CGHLSLRuntime::emitSystemSemanticLoad( + IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, + Attr *Semantic, std::optional<unsigned> Index) { + if (isa<HLSLSV_GroupIndexAttr>(Semantic)) { llvm::Function *GroupIndex = CGM.getIntrinsic(getFlattenedThreadIdInGroupIntrinsic()); return B.CreateCall(FunctionCallee(GroupIndex)); } - if (isa<HLSLSV_DispatchThreadIDAttr>(ActiveSemantic.Semantic)) { + if (isa<HLSLSV_DispatchThreadIDAttr>(Semantic)) { llvm::Intrinsic::ID IntrinID = getThreadIdIntrinsic(); llvm::Function *ThreadIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) @@ -581,7 +580,7 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, return buildVectorInput(B, ThreadIDIntrinsic, Type); } - if (isa<HLSLSV_GroupThreadIDAttr>(ActiveSemantic.Semantic)) { + if (isa<HLSLSV_GroupThreadIDAttr>(Semantic)) { llvm::Intrinsic::ID IntrinID = getGroupThreadIdIntrinsic(); llvm::Function *GroupThreadIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) @@ -590,7 +589,7 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, return buildVectorInput(B, GroupThreadIDIntrinsic, Type); } - if (isa<HLSLSV_GroupIDAttr>(ActiveSemantic.Semantic)) { + if (isa<HLSLSV_GroupIDAttr>(Semantic)) { llvm::Intrinsic::ID IntrinID = getGroupIdIntrinsic(); llvm::Function *GroupIDIntrinsic = llvm::Intrinsic::isOverloaded(IntrinID) @@ -599,8 +598,7 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, return buildVectorInput(B, GroupIDIntrinsic, Type); } - if (HLSLSV_PositionAttr *S = - dyn_cast<HLSLSV_PositionAttr>(ActiveSemantic.Semantic)) { + if (HLSLSV_PositionAttr *S = dyn_cast<HLSLSV_PositionAttr>(Semantic)) { if (CGM.getTriple().getEnvironment() == Triple::EnvironmentType::Pixel) return createSPIRVBuiltinLoad(B, CGM.getModule(), Type, S->getAttrName()->getName(), @@ -611,29 +609,56 @@ CGHLSLRuntime::emitSystemSemanticLoad(IRBuilder<> &B, llvm::Type *Type, } llvm::Value * -CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, llvm::Type *Type, - const clang::DeclaratorDecl *Decl, - SemanticInfo &ActiveSemantic) { - - if (!ActiveSemantic.Semantic) { - ActiveSemantic.Semantic = Decl->getAttr<HLSLSemanticAttr>(); - if (!ActiveSemantic.Semantic) { - CGM.getDiags().Report(Decl->getInnerLocStart(), - diag::err_hlsl_semantic_missing); - return nullptr; +CGHLSLRuntime::handleScalarSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, + llvm::Type *Type, + const clang::DeclaratorDecl *Decl) { + + HLSLSemanticAttr *Semantic = nullptr; + for (HLSLSemanticAttr *Item : FD->specific_attrs<HLSLSemanticAttr>()) { + if (Item->getTargetDecl() == Decl) { + Semantic = Item; + break; } - ActiveSemantic.Index = ActiveSemantic.Semantic->getSemanticIndex(); } + // Sema must create one attribute per scalar field. + assert(Semantic); - return emitSystemSemanticLoad(B, Type, Decl, ActiveSemantic); + std::optional<unsigned> Index = std::nullopt; + if (Semantic->isSemanticIndexExplicit()) + Index = Semantic->getSemanticIndex(); + return emitSystemSemanticLoad(B, Type, Decl, Semantic, Index); } llvm::Value * -CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, llvm::Type *Type, - const clang::DeclaratorDecl *Decl, - SemanticInfo &ActiveSemantic) { - assert(!Type->isStructTy()); - return handleScalarSemanticLoad(B, Type, Decl, ActiveSemantic); +CGHLSLRuntime::handleStructSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, + llvm::Type *Type, + const clang::DeclaratorDecl *Decl) { + const llvm::StructType *ST = cast<StructType>(Type); + const clang::RecordDecl *RD = Decl->getType()->getAsRecordDecl(); + + assert(std::distance(RD->field_begin(), RD->field_end()) == + ST->getNumElements()); + + llvm::Value *Aggregate = llvm::PoisonValue::get(Type); + auto FieldDecl = RD->field_begin(); + for (unsigned I = 0; I < ST->getNumElements(); ++I) { + llvm::Value *ChildValue = + handleSemanticLoad(B, FD, ST->getElementType(I), *FieldDecl); + assert(ChildValue); + Aggregate = B.CreateInsertValue(Aggregate, ChildValue, I); + ++FieldDecl; + } + + return Aggregate; +} + +llvm::Value * +CGHLSLRuntime::handleSemanticLoad(IRBuilder<> &B, const FunctionDecl *FD, + llvm::Type *Type, + const clang::DeclaratorDecl *Decl) { + if (Type->isStructTy()) + return handleStructSemanticLoad(B, FD, Type, Decl); + return handleScalarSemanticLoad(B, FD, Type, Decl); } void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, @@ -680,8 +705,25 @@ void CGHLSLRuntime::emitEntryFunction(const FunctionDecl *FD, } const ParmVarDecl *PD = FD->getParamDecl(Param.getArgNo() - SRetOffset); - SemanticInfo ActiveSemantic = {nullptr, 0}; - Args.push_back(handleSemanticLoad(B, Param.getType(), PD, ActiveSemantic)); + llvm::Value *SemanticValue = nullptr; + if ([[maybe_unused]] HLSLParamModifierAttr *MA = + PD->getAttr<HLSLParamModifierAttr>()) { + llvm_unreachable("Not handled yet"); + } else { + llvm::Type *ParamType = + Param.hasByValAttr() ? Param.getParamByValType() : Param.getType(); + SemanticValue = handleSemanticLoad(B, FD, ParamType, PD); + if (!SemanticValue) + return; + if (Param.hasByValAttr()) { + llvm::Value *Var = B.CreateAlloca(Param.getParamByValType()); + B.CreateStore(SemanticValue, Var); + SemanticValue = Var; + } + } + + assert(SemanticValue); + Args.push_back(SemanticValue); } CallInst *CI = B.CreateCall(FunctionCallee(Fn), Args, OB); diff --git a/clang/lib/CodeGen/CGHLSLRuntime.h b/clang/lib/CodeGen/CGHLSLRuntime.h index 103b4a9..d35df52 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.h +++ b/clang/lib/CodeGen/CGHLSLRuntime.h @@ -144,26 +144,24 @@ public: protected: CodeGenModule &CGM; - void collectInputSemantic(llvm::IRBuilder<> &B, const DeclaratorDecl *D, - llvm::Type *Type, - SmallVectorImpl<llvm::Value *> &Inputs); - - struct SemanticInfo { - clang::HLSLSemanticAttr *Semantic; - uint32_t Index; - }; - llvm::Value *emitSystemSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, const clang::DeclaratorDecl *Decl, - SemanticInfo &ActiveSemantic); - - llvm::Value *handleScalarSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, - const clang::DeclaratorDecl *Decl, - SemanticInfo &ActiveSemantic); - - llvm::Value *handleSemanticLoad(llvm::IRBuilder<> &B, llvm::Type *Type, - const clang::DeclaratorDecl *Decl, - SemanticInfo &ActiveSemantic); + Attr *Semantic, + std::optional<unsigned> Index); + + llvm::Value *handleScalarSemanticLoad(llvm::IRBuilder<> &B, + const FunctionDecl *FD, + llvm::Type *Type, + const clang::DeclaratorDecl *Decl); + + llvm::Value *handleStructSemanticLoad(llvm::IRBuilder<> &B, + const FunctionDecl *FD, + llvm::Type *Type, + const clang::DeclaratorDecl *Decl); + + llvm::Value *handleSemanticLoad(llvm::IRBuilder<> &B, const FunctionDecl *FD, + llvm::Type *Type, + const clang::DeclaratorDecl *Decl); public: CGHLSLRuntime(CodeGenModule &CGM) : CGM(CGM) {} diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp index 85b2404..66fea92 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp @@ -2713,14 +2713,6 @@ llvm::Value *CGOpenMPRuntime::emitMessageClause(CodeGenFunction &CGF, } llvm::Value * -CGOpenMPRuntime::emitMessageClause(CodeGenFunction &CGF, - const OMPMessageClause *MessageClause) { - return emitMessageClause( - CGF, MessageClause ? MessageClause->getMessageString() : nullptr, - MessageClause->getBeginLoc()); -} - -llvm::Value * CGOpenMPRuntime::emitSeverityClause(OpenMPSeverityClauseKind Severity, SourceLocation Loc) { // OpenMP 6.0, 10.4: "If no severity clause is specified then the effect is @@ -2729,13 +2721,6 @@ CGOpenMPRuntime::emitSeverityClause(OpenMPSeverityClauseKind Severity, Severity == OMPC_SEVERITY_warning ? 1 : 2); } -llvm::Value * -CGOpenMPRuntime::emitSeverityClause(const OMPSeverityClause *SeverityClause) { - return emitSeverityClause(SeverityClause ? SeverityClause->getSeverityKind() - : OMPC_SEVERITY_unknown, - SeverityClause->getBeginLoc()); -} - void CGOpenMPRuntime::emitNumThreadsClause( CodeGenFunction &CGF, llvm::Value *NumThreads, SourceLocation Loc, OpenMPNumThreadsClauseModifier Modifier, OpenMPSeverityClauseKind Severity, diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.h b/clang/lib/CodeGen/CGOpenMPRuntime.h index ba76ba6b..6bfd7d6 100644 --- a/clang/lib/CodeGen/CGOpenMPRuntime.h +++ b/clang/lib/CodeGen/CGOpenMPRuntime.h @@ -1051,13 +1051,9 @@ public: virtual llvm::Value *emitMessageClause(CodeGenFunction &CGF, const Expr *Message, SourceLocation Loc); - virtual llvm::Value *emitMessageClause(CodeGenFunction &CGF, - const OMPMessageClause *MessageClause); virtual llvm::Value *emitSeverityClause(OpenMPSeverityClauseKind Severity, SourceLocation Loc); - virtual llvm::Value * - emitSeverityClause(const OMPSeverityClause *SeverityClause); /// Emits call to void __kmpc_push_num_threads(ident_t *loc, kmp_int32 /// global_tid, kmp_int32 num_threads) to generate code for 'num_threads' diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 1f0be2d..8c4c1c8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -3352,9 +3352,14 @@ public: SanitizerAnnotateDebugInfo(ArrayRef<SanitizerKind::SanitizerOrdinal> Ordinals, SanitizerHandler Handler); - /// Emit additional metadata used by the AllocToken instrumentation. + /// Build metadata used by the AllocToken instrumentation. + llvm::MDNode *buildAllocToken(QualType AllocType); + /// Emit and set additional metadata used by the AllocToken instrumentation. void EmitAllocToken(llvm::CallBase *CB, QualType AllocType); - /// Emit additional metadata used by the AllocToken instrumentation, + /// Build additional metadata used by the AllocToken instrumentation, + /// inferring the type from an allocation call expression. + llvm::MDNode *buildAllocToken(const CallExpr *E); + /// Emit and set additional metadata used by the AllocToken instrumentation, /// inferring the type from an allocation call expression. void EmitAllocToken(llvm::CallBase *CB, const CallExpr *E); |
