aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp3
-rw-r--r--clang/lib/CodeGen/CGExpr.cpp198
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.cpp100
-rw-r--r--clang/lib/CodeGen/CGHLSLRuntime.h34
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.cpp15
-rw-r--r--clang/lib/CodeGen/CGOpenMPRuntime.h4
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h9
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);