190 changes: 98 additions & 92 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3711,7 +3711,9 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {

// Forward declarations are emitted lazily on first use.
if (!FD->doesThisDeclarationHaveABody()) {
if (!FD->doesDeclarationForceExternallyVisibleDefinition())
if (!FD->doesDeclarationForceExternallyVisibleDefinition() &&
(!FD->isMultiVersion() ||
!FD->getASTContext().getTargetInfo().getTriple().isAArch64()))
return;

StringRef MangledName = getMangledName(GD);
Expand Down Expand Up @@ -3993,10 +3995,11 @@ void CodeGenModule::EmitMultiVersionFunctionDefinition(GlobalDecl GD,
auto *Spec = FD->getAttr<CPUSpecificAttr>();
for (unsigned I = 0; I < Spec->cpus_size(); ++I)
EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr);
} else if (FD->isTargetClonesMultiVersion()) {
auto *Clone = FD->getAttr<TargetClonesAttr>();
for (unsigned I = 0; I < Clone->featuresStrs_size(); ++I)
if (Clone->isFirstOfVersion(I))
} else if (auto *TC = FD->getAttr<TargetClonesAttr>()) {
for (unsigned I = 0; I < TC->featuresStrs_size(); ++I)
// AArch64 favors the default target version over the clone if any.
if ((!TC->isDefaultVersion(I) || !getTarget().getTriple().isAArch64()) &&
TC->isFirstOfVersion(I))
EmitGlobalFunctionDefinition(GD.getWithMultiVersionIndex(I), nullptr);
// Ensure that the resolver function is also emitted.
GetOrCreateMultiVersionResolver(GD);
Expand Down Expand Up @@ -4092,103 +4095,103 @@ llvm::GlobalValue::LinkageTypes getMultiversionLinkage(CodeGenModule &CGM,
return llvm::GlobalValue::WeakODRLinkage;
}

static FunctionDecl *createDefaultTargetVersionFrom(const FunctionDecl *FD) {
DeclContext *DeclCtx = FD->getASTContext().getTranslationUnitDecl();
TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
StorageClass SC = FD->getStorageClass();
DeclarationName Name = FD->getNameInfo().getName();

FunctionDecl *NewDecl =
FunctionDecl::Create(FD->getASTContext(), DeclCtx, FD->getBeginLoc(),
FD->getEndLoc(), Name, TInfo->getType(), TInfo, SC);

NewDecl->setIsMultiVersion();
NewDecl->addAttr(TargetVersionAttr::CreateImplicit(
NewDecl->getASTContext(), "default", NewDecl->getSourceRange()));

return NewDecl;
}

void CodeGenModule::emitMultiVersionFunctions() {
std::vector<GlobalDecl> MVFuncsToEmit;
MultiVersionFuncs.swap(MVFuncsToEmit);
for (GlobalDecl GD : MVFuncsToEmit) {
const auto *FD = cast<FunctionDecl>(GD.getDecl());
assert(FD && "Expected a FunctionDecl");

bool EmitResolver = !FD->isTargetVersionMultiVersion();
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;
if (FD->isTargetMultiVersion()) {
getContext().forEachMultiversionedFunctionVersion(
FD, [this, &GD, &Options, &EmitResolver](const FunctionDecl *CurFD) {
GlobalDecl CurGD{
(CurFD->isDefined() ? CurFD->getDefinition() : CurFD)};
StringRef MangledName = getMangledName(CurGD);
llvm::Constant *Func = GetGlobalValue(MangledName);
if (!Func) {
if (CurFD->isDefined()) {
EmitGlobalFunctionDefinition(CurGD, nullptr);
Func = GetGlobalValue(MangledName);
} else {
const CGFunctionInfo &FI =
getTypes().arrangeGlobalDeclaration(GD);
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
/*DontDefer=*/false, ForDefinition);
}
assert(Func && "This should have just been created");
}
if (CurFD->getMultiVersionKind() == MultiVersionKind::Target) {
const auto *TA = CurFD->getAttr<TargetAttr>();
llvm::SmallVector<StringRef, 8> Feats;
TA->getAddedFeatures(Feats);
Options.emplace_back(cast<llvm::Function>(Func),
TA->getArchitecture(), Feats);
} else {
const auto *TVA = CurFD->getAttr<TargetVersionAttr>();
if (CurFD->isUsed() || (TVA->isDefaultVersion() &&
CurFD->doesThisDeclarationHaveABody()))
EmitResolver = true;
llvm::SmallVector<StringRef, 8> Feats;
TVA->getFeatures(Feats);
Options.emplace_back(cast<llvm::Function>(Func),
/*Architecture*/ "", Feats);
}
});
} else if (FD->isTargetClonesMultiVersion()) {
const auto *TC = FD->getAttr<TargetClonesAttr>();
for (unsigned VersionIndex = 0; VersionIndex < TC->featuresStrs_size();
++VersionIndex) {
if (!TC->isFirstOfVersion(VersionIndex))
continue;
GlobalDecl CurGD{(FD->isDefined() ? FD->getDefinition() : FD),
VersionIndex};
StringRef Version = TC->getFeatureStr(VersionIndex);
StringRef MangledName = getMangledName(CurGD);
llvm::Constant *Func = GetGlobalValue(MangledName);
if (!Func) {
if (FD->isDefined()) {
EmitGlobalFunctionDefinition(CurGD, nullptr);
Func = GetGlobalValue(MangledName);
} else {
const CGFunctionInfo &FI =
getTypes().arrangeGlobalDeclaration(CurGD);
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
/*DontDefer=*/false, ForDefinition);
}
assert(Func && "This should have just been created");
auto createFunction = [&](const FunctionDecl *Decl, unsigned MVIdx = 0) {
GlobalDecl CurGD{Decl->isDefined() ? Decl->getDefinition() : Decl, MVIdx};
StringRef MangledName = getMangledName(CurGD);
llvm::Constant *Func = GetGlobalValue(MangledName);
if (!Func) {
if (Decl->isDefined()) {
EmitGlobalFunctionDefinition(CurGD, nullptr);
Func = GetGlobalValue(MangledName);
} else {
const CGFunctionInfo &FI = getTypes().arrangeGlobalDeclaration(CurGD);
llvm::FunctionType *Ty = getTypes().GetFunctionType(FI);
Func = GetAddrOfFunction(CurGD, Ty, /*ForVTable=*/false,
/*DontDefer=*/false, ForDefinition);
}
assert(Func && "This should have just been created");
}
return cast<llvm::Function>(Func);
};

StringRef Architecture;
llvm::SmallVector<StringRef, 1> Feature;
bool HasDefaultDecl = !FD->isTargetVersionMultiVersion();
bool ShouldEmitResolver =
!getContext().getTargetInfo().getTriple().isAArch64();
SmallVector<CodeGenFunction::MultiVersionResolverOption, 10> Options;

if (getTarget().getTriple().isAArch64()) {
if (Version != "default") {
llvm::SmallVector<StringRef, 8> VerFeats;
Version.split(VerFeats, "+");
for (auto &CurFeat : VerFeats)
Feature.push_back(CurFeat.trim());
}
} else {
if (Version.starts_with("arch="))
Architecture = Version.drop_front(sizeof("arch=") - 1);
else if (Version != "default")
Feature.push_back(Version);
}
getContext().forEachMultiversionedFunctionVersion(
FD, [&](const FunctionDecl *CurFD) {
llvm::SmallVector<StringRef, 8> Feats;

if (const auto *TA = CurFD->getAttr<TargetAttr>()) {
TA->getAddedFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
Options.emplace_back(Func, TA->getArchitecture(), Feats);
} else if (const auto *TVA = CurFD->getAttr<TargetVersionAttr>()) {
bool HasDefaultDef = TVA->isDefaultVersion() &&
CurFD->doesThisDeclarationHaveABody();
HasDefaultDecl |= TVA->isDefaultVersion();
ShouldEmitResolver |= (CurFD->isUsed() || HasDefaultDef);
TVA->getFeatures(Feats);
llvm::Function *Func = createFunction(CurFD);
Options.emplace_back(Func, /*Architecture*/ "", Feats);
} else if (const auto *TC = CurFD->getAttr<TargetClonesAttr>()) {
ShouldEmitResolver |= CurFD->doesThisDeclarationHaveABody();
for (unsigned I = 0; I < TC->featuresStrs_size(); ++I) {
if (!TC->isFirstOfVersion(I))
continue;

llvm::Function *Func = createFunction(CurFD, I);
StringRef Architecture;
Feats.clear();
if (getTarget().getTriple().isAArch64())
TC->getFeatures(Feats, I);
else {
StringRef Version = TC->getFeatureStr(I);
if (Version.starts_with("arch="))
Architecture = Version.drop_front(sizeof("arch=") - 1);
else if (Version != "default")
Feats.push_back(Version);
}
Options.emplace_back(Func, Architecture, Feats);
}
} else
llvm_unreachable("unexpected MultiVersionKind");
});

Options.emplace_back(cast<llvm::Function>(Func), Architecture, Feature);
}
} else {
assert(0 && "Expected a target or target_clones multiversion function");
if (!ShouldEmitResolver)
continue;
}

if (!EmitResolver)
continue;
if (!HasDefaultDecl) {
FunctionDecl *NewFD = createDefaultTargetVersionFrom(FD);
llvm::Function *Func = createFunction(NewFD);
llvm::SmallVector<StringRef, 1> Feats;
Options.emplace_back(Func, /*Architecture*/ "", Feats);
}

llvm::Constant *ResolverConstant = GetOrCreateMultiVersionResolver(GD);
if (auto *IFunc = dyn_cast<llvm::GlobalIFunc>(ResolverConstant)) {
Expand Down Expand Up @@ -4369,7 +4372,7 @@ void CodeGenModule::AddDeferredMultiVersionResolverToEmit(GlobalDecl GD) {
const auto *FD = cast<FunctionDecl>(GD.getDecl());
assert(FD && "Not a FunctionDecl?");

if (FD->isTargetVersionMultiVersion()) {
if (FD->isTargetVersionMultiVersion() || FD->isTargetClonesMultiVersion()) {
std::string MangledName =
getMangledNameImpl(*this, GD, FD, /*OmitMultiVersionMangling=*/true);
if (!DeferredResolversToEmit.insert(MangledName).second)
Expand Down Expand Up @@ -4480,7 +4483,10 @@ llvm::Constant *CodeGenModule::GetOrCreateLLVMFunction(

if (FD->isMultiVersion()) {
UpdateMultiVersionNames(GD, FD, MangledName);
if (!IsForDefinition)
if (FD->getASTContext().getTargetInfo().getTriple().isAArch64() &&
!FD->isUsed())
AddDeferredMultiVersionResolverToEmit(GD);
else if (!IsForDefinition)
return GetOrCreateMultiVersionResolver(GD);
}
}
Expand Down Expand Up @@ -6275,7 +6281,7 @@ CodeGenModule::GetConstantArrayFromStringLiteral(const StringLiteral *E) {
// Resize the string to the right size, which is indicated by its type.
const ConstantArrayType *CAT = Context.getAsConstantArrayType(E->getType());
assert(CAT && "String literal not of constant array type!");
Str.resize(CAT->getSize().getZExtValue());
Str.resize(CAT->getZExtSize());
return llvm::ConstantDataArray::getString(VMContext, Str, false);
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -601,7 +601,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
EltTy = llvm::Type::getInt8Ty(getLLVMContext());
}

ResultType = llvm::ArrayType::get(EltTy, A->getSize().getZExtValue());
ResultType = llvm::ArrayType::get(EltTy, A->getZExtSize());
break;
}
case Type::ExtVector:
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/SwiftCallingConv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) {

QualType eltType = arrayType->getElementType();
auto eltSize = CGM.getContext().getTypeSizeInChars(eltType);
for (uint64_t i = 0, e = arrayType->getSize().getZExtValue(); i != e; ++i) {
for (uint64_t i = 0, e = arrayType->getZExtSize(); i != e; ++i) {
addTypedData(eltType, begin + i * eltSize);
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,7 @@ bool ARMABIInfo::isIllegalVectorType(QualType Ty) const {
/// Return true if a type contains any 16-bit floating point vectors
bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {
if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
uint64_t NElements = AT->getSize().getZExtValue();
uint64_t NElements = AT->getZExtSize();
if (NElements == 0)
return false;
return containsAnyFP16Vectors(AT->getElementType());
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
}

if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
uint64_t ArraySize = ATy->getSize().getZExtValue();
uint64_t ArraySize = ATy->getZExtSize();
QualType EltTy = ATy->getElementType();
// Non-zero-length arrays of empty records make the struct ineligible to be
// passed via FARs in C++.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/RISCV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
}

if (const ConstantArrayType *ATy = getContext().getAsConstantArrayType(Ty)) {
uint64_t ArraySize = ATy->getSize().getZExtValue();
uint64_t ArraySize = ATy->getZExtSize();
QualType EltTy = ATy->getElementType();
// Non-zero-length arrays of empty records make the struct ineligible for
// the FP calling convention in C++.
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CodeGen/Targets/X86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1993,7 +1993,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
// this, but it isn't worth it and would be harder to verify.
Current = NoClass;
uint64_t EltSize = getContext().getTypeSize(AT->getElementType());
uint64_t ArraySize = AT->getSize().getZExtValue();
uint64_t ArraySize = AT->getZExtSize();

// The only case a 256-bit wide vector could be used is when the array
// contains a single 256-bit element. Since Lo and Hi logic isn't extended
Expand Down Expand Up @@ -2295,7 +2295,7 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,

if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
unsigned EltSize = (unsigned)Context.getTypeSize(AT->getElementType());
unsigned NumElts = (unsigned)AT->getSize().getZExtValue();
unsigned NumElts = (unsigned)AT->getZExtSize();

// Check each element to see if the element overlaps with the queried range.
for (unsigned i = 0; i != NumElts; ++i) {
Expand Down Expand Up @@ -2788,12 +2788,11 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs,
// memory), except in situations involving unions.
case X87Up:
case SSE:
++neededSSE;
HighPart = GetSSETypeAtOffset(CGT.ConvertType(Ty), 8, Ty, 8);

if (Lo == NoClass) // Pass HighPart at offset 8 in memory.
return ABIArgInfo::getDirect(HighPart, 8);

++neededSSE;
break;

// AMD64-ABI 3.2.3p3: Rule 4. If the class is SSEUP, the
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/Driver/ToolChains/Clang.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1776,6 +1776,9 @@ void Clang::AddAArch64TargetArgs(const ArgList &Args,
}

AddUnalignedAccessWarning(CmdArgs);

Args.addOptInFlag(CmdArgs, options::OPT_fptrauth_intrinsics,
options::OPT_fno_ptrauth_intrinsics);
}

void Clang::AddLoongArchTargetArgs(const ArgList &Args,
Expand Down Expand Up @@ -7258,10 +7261,6 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
// -fno-common is the default, set -fcommon only when that flag is set.
Args.addOptInFlag(CmdArgs, options::OPT_fcommon, options::OPT_fno_common);

if (Args.hasFlag(options::OPT_fptrauth_intrinsics,
options::OPT_fno_ptrauth_intrinsics, false))
CmdArgs.push_back("-fptrauth-intrinsics");

// -fsigned-bitfields is default, and clang doesn't yet support
// -funsigned-bitfields.
if (!Args.hasFlag(options::OPT_fsigned_bitfields,
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Format/WhitespaceManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1491,7 +1491,7 @@ WhitespaceManager::CellDescriptions WhitespaceManager::getCells(unsigned Start,
: Cell);
// Go to the next non-comment and ensure there is a break in front
const auto *NextNonComment = C.Tok->getNextNonComment();
while (NextNonComment->is(tok::comma))
while (NextNonComment && NextNonComment->is(tok::comma))
NextNonComment = NextNonComment->getNextNonComment();
auto j = i;
while (j < End && Changes[j].Tok != NextNonComment)
Expand Down
89 changes: 19 additions & 70 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,15 +392,6 @@ float3 cos(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
float4 cos(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double cos(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double2 cos(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double3 cos(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_cos)
double4 cos(double4);

//===----------------------------------------------------------------------===//
// dot product builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -737,15 +728,6 @@ float3 log(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log)
float4 log(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log)
double log(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log)
double2 log(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log)
double3 log(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log)
double4 log(double4);

//===----------------------------------------------------------------------===//
// log10 builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -779,15 +761,6 @@ float3 log10(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10)
float4 log10(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10)
double log10(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10)
double2 log10(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10)
double3 log10(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log10)
double4 log10(double4);

//===----------------------------------------------------------------------===//
// log2 builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -821,15 +794,6 @@ float3 log2(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2)
float4 log2(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2)
double log2(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2)
double2 log2(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2)
double3 log2(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_log2)
double4 log2(double4);

//===----------------------------------------------------------------------===//
// mad builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1174,15 +1138,6 @@ float3 pow(float3, float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_pow)
float4 pow(float4, float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_pow)
double pow(double, double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_pow)
double2 pow(double2, double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_pow)
double3 pow(double3, double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_pow)
double4 pow(double4, double4);

//===----------------------------------------------------------------------===//
// reversebits builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1393,15 +1348,6 @@ float3 sin(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin)
float4 sin(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin)
double sin(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin)
double2 sin(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin)
double3 sin(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sin)
double4 sin(double4);

//===----------------------------------------------------------------------===//
// sqrt builtins
//===----------------------------------------------------------------------===//
Expand All @@ -1411,14 +1357,26 @@ double4 sin(double4);
/// \param Val The input value.

_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_sqrtf16)
half sqrt(half In);

_HLSL_BUILTIN_ALIAS(__builtin_sqrtf)
float sqrt(float In);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
half sqrt(half);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
half2 sqrt(half2);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
half3 sqrt(half3);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
half4 sqrt(half4);

_HLSL_BUILTIN_ALIAS(__builtin_sqrt)
double sqrt(double In);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
float sqrt(float);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
float2 sqrt(float2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
float3 sqrt(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_sqrt)
float4 sqrt(float4);

//===----------------------------------------------------------------------===//
// trunc builtins
Expand Down Expand Up @@ -1450,15 +1408,6 @@ float3 trunc(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc)
float4 trunc(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc)
double trunc(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc)
double2 trunc(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc)
double3 trunc(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_trunc)
double4 trunc(double4);

//===----------------------------------------------------------------------===//
// Wave* builtins
//===----------------------------------------------------------------------===//
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/InstallAPI/DylibVerifier.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
//===- DylibVerifier.cpp ----------------------------------------*- C++--*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/InstallAPI/DylibVerifier.h"
#include "clang/InstallAPI/FrontendRecords.h"
#include "clang/InstallAPI/InstallAPIDiagnostic.h"
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/InstallAPI/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ std::unique_ptr<MemoryBuffer> createInputBuffer(InstallAPIContext &Ctx) {
SmallString<4096> Contents;
raw_svector_ostream OS(Contents);
for (const HeaderFile &H : Ctx.InputHeaders) {
if (H.isExcluded())
continue;
if (H.getType() != Ctx.Type)
continue;
if (Ctx.LangMode == Language::C || Ctx.LangMode == Language::CXX)
Expand Down
51 changes: 51 additions & 0 deletions clang/lib/InstallAPI/HeaderFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "clang/InstallAPI/HeaderFile.h"
#include "llvm/TextAPI/Utils.h"

using namespace llvm;
namespace clang::installapi {
Expand Down Expand Up @@ -34,4 +35,54 @@ std::optional<std::string> createIncludeHeaderName(const StringRef FullPath) {
return Matches[1].drop_front(Matches[1].rfind('/') + 1).str() + "/" +
Matches[3].str();
}

bool isHeaderFile(StringRef Path) {
return StringSwitch<bool>(sys::path::extension(Path))
.Cases(".h", ".H", ".hh", ".hpp", ".hxx", true)
.Default(false);
}

llvm::Expected<PathSeq> enumerateFiles(FileManager &FM, StringRef Directory) {
PathSeq Files;
std::error_code EC;
auto &FS = FM.getVirtualFileSystem();
for (llvm::vfs::recursive_directory_iterator i(FS, Directory, EC), ie;
i != ie; i.increment(EC)) {
if (EC)
return errorCodeToError(EC);

// Skip files that do not exist. This usually happens for broken symlinks.
if (FS.status(i->path()) == std::errc::no_such_file_or_directory)
continue;

StringRef Path = i->path();
if (isHeaderFile(Path))
Files.emplace_back(Path);
}

return Files;
}

HeaderGlob::HeaderGlob(StringRef GlobString, Regex &&Rule, HeaderType Type)
: GlobString(GlobString), Rule(std::move(Rule)), Type(Type) {}

bool HeaderGlob::match(const HeaderFile &Header) {
if (Header.getType() != Type)
return false;

bool Match = Rule.match(Header.getPath());
if (Match)
FoundMatch = true;
return Match;
}

Expected<std::unique_ptr<HeaderGlob>> HeaderGlob::create(StringRef GlobString,
HeaderType Type) {
auto Rule = MachO::createRegexFromGlob(GlobString);
if (!Rule)
return Rule.takeError();

return std::make_unique<HeaderGlob>(GlobString, std::move(*Rule), Type);
}

} // namespace clang::installapi
7 changes: 4 additions & 3 deletions clang/lib/InstallAPI/Visitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,9 +205,10 @@ bool InstallAPIVisitor::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
const ObjCInterfaceDecl *InterfaceD = D->getClassInterface();
const StringRef InterfaceName = InterfaceD->getName();

auto [Category, FA] = Ctx.Slice->addObjCCategory(InterfaceName, CategoryName,
Avail, D, *Access);
recordObjCInstanceVariables(D->getASTContext(), Category, InterfaceName,
std::pair<ObjCCategoryRecord *, FrontendAttrs *> Category =
Ctx.Slice->addObjCCategory(InterfaceName, CategoryName, Avail, D,
*Access);
recordObjCInstanceVariables(D->getASTContext(), Category.first, InterfaceName,
D->ivars());
return true;
}
Expand Down
33 changes: 18 additions & 15 deletions clang/lib/Interpreter/IncrementalExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupport.h"
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
#include "llvm/ExecutionEngine/Orc/TargetProcess/JITLoaderGDB.h"
Expand All @@ -36,26 +37,28 @@ LLVM_ATTRIBUTE_USED void linkComponents() {

namespace clang {

llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
IncrementalExecutor::createDefaultJITBuilder(
llvm::orc::JITTargetMachineBuilder JTMB) {
auto JITBuilder = std::make_unique<llvm::orc::LLJITBuilder>();
JITBuilder->setJITTargetMachineBuilder(std::move(JTMB));
JITBuilder->setPrePlatformSetup([](llvm::orc::LLJIT &J) {
// Try to enable debugging of JIT'd code (only works with JITLink for
// ELF and MachO).
consumeError(llvm::orc::enableDebuggerSupport(J));
return llvm::Error::success();
});
return std::move(JITBuilder);
}

IncrementalExecutor::IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
llvm::Error &Err,
const clang::TargetInfo &TI)
llvm::orc::LLJITBuilder &JITBuilder,
llvm::Error &Err)
: TSCtx(TSC) {
using namespace llvm::orc;
llvm::ErrorAsOutParameter EAO(&Err);

auto JTMB = JITTargetMachineBuilder(TI.getTriple());
JTMB.addFeatures(TI.getTargetOpts().Features);
LLJITBuilder Builder;
Builder.setJITTargetMachineBuilder(JTMB);
Builder.setPrePlatformSetup(
[](LLJIT &J) {
// Try to enable debugging of JIT'd code (only works with JITLink for
// ELF and MachO).
consumeError(enableDebuggerSupport(J));
return llvm::Error::success();
});

if (auto JitOrErr = Builder.create())
if (auto JitOrErr = JITBuilder.create())
Jit = std::move(*JitOrErr);
else {
Err = JitOrErr.takeError();
Expand Down
9 changes: 7 additions & 2 deletions clang/lib/Interpreter/IncrementalExecutor.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
namespace llvm {
class Error;
namespace orc {
class JITTargetMachineBuilder;
class LLJIT;
class LLJITBuilder;
class ThreadSafeContext;
} // namespace orc
} // namespace llvm
Expand All @@ -44,8 +46,8 @@ class IncrementalExecutor {
public:
enum SymbolNameKind { IRName, LinkerName };

IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC, llvm::Error &Err,
const clang::TargetInfo &TI);
IncrementalExecutor(llvm::orc::ThreadSafeContext &TSC,
llvm::orc::LLJITBuilder &JITBuilder, llvm::Error &Err);
~IncrementalExecutor();

llvm::Error addModule(PartialTranslationUnit &PTU);
Expand All @@ -56,6 +58,9 @@ class IncrementalExecutor {
getSymbolAddress(llvm::StringRef Name, SymbolNameKind NameKind) const;

llvm::orc::LLJIT &GetExecutionEngine() { return *Jit; }

static llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
createDefaultJITBuilder(llvm::orc::JITTargetMachineBuilder JTMB);
};

} // end namespace clang
Expand Down
18 changes: 12 additions & 6 deletions clang/lib/Interpreter/IncrementalParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,16 +375,22 @@ void IncrementalParser::CleanUpPTU(PartialTranslationUnit &PTU) {
TranslationUnitDecl *MostRecentTU = PTU.TUPart;
TranslationUnitDecl *FirstTU = MostRecentTU->getFirstDecl();
if (StoredDeclsMap *Map = FirstTU->getPrimaryContext()->getLookupPtr()) {
for (auto I = Map->begin(); I != Map->end(); ++I) {
StoredDeclsList &List = I->second;
for (auto &&[Key, List] : *Map) {
DeclContextLookupResult R = List.getLookupResult();
std::vector<NamedDecl *> NamedDeclsToRemove;
bool RemoveAll = true;
for (NamedDecl *D : R) {
if (D->getTranslationUnitDecl() == MostRecentTU) {
if (D->getTranslationUnitDecl() == MostRecentTU)
NamedDeclsToRemove.push_back(D);
else
RemoveAll = false;
}
if (LLVM_LIKELY(RemoveAll)) {
Map->erase(Key);
} else {
for (NamedDecl *D : NamedDeclsToRemove)
List.remove(D);
}
}
if (List.isNull())
Map->erase(I);
}
}
}
Expand Down
26 changes: 23 additions & 3 deletions clang/lib/Interpreter/Interpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,15 +372,35 @@ Interpreter::Parse(llvm::StringRef Code) {
return IncrParser->Parse(Code);
}

static llvm::Expected<llvm::orc::JITTargetMachineBuilder>
createJITTargetMachineBuilder(const std::string &TT) {
if (TT == llvm::sys::getProcessTriple())
// This fails immediately if the target backend is not registered
return llvm::orc::JITTargetMachineBuilder::detectHost();

// If the target backend is not registered, LLJITBuilder::create() will fail
return llvm::orc::JITTargetMachineBuilder(llvm::Triple(TT));
}

llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>>
Interpreter::CreateJITBuilder(CompilerInstance &CI) {
auto JTMB = createJITTargetMachineBuilder(CI.getTargetOpts().Triple);
if (!JTMB)
return JTMB.takeError();
return IncrementalExecutor::createDefaultJITBuilder(std::move(*JTMB));
}

llvm::Error Interpreter::CreateExecutor() {
const clang::TargetInfo &TI =
getCompilerInstance()->getASTContext().getTargetInfo();
if (IncrExecutor)
return llvm::make_error<llvm::StringError>("Operation failed. "
"Execution engine exists",
std::error_code());
llvm::Expected<std::unique_ptr<llvm::orc::LLJITBuilder>> JB =
CreateJITBuilder(*getCompilerInstance());
if (!JB)
return JB.takeError();
llvm::Error Err = llvm::Error::success();
auto Executor = std::make_unique<IncrementalExecutor>(*TSCtx, Err, TI);
auto Executor = std::make_unique<IncrementalExecutor>(*TSCtx, **JB, Err);
if (!Err)
IncrExecutor = std::move(Executor);

Expand Down
9 changes: 5 additions & 4 deletions clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ namespace sema {
class SemaPPCallbacks : public PPCallbacks {
Sema *S = nullptr;
llvm::SmallVector<SourceLocation, 8> IncludeStack;
llvm::SmallVector<llvm::TimeTraceProfilerEntry *, 8> ProfilerStack;

public:
void set(Sema &S) { this->S = &S; }
Expand All @@ -153,8 +154,8 @@ class SemaPPCallbacks : public PPCallbacks {
if (IncludeLoc.isValid()) {
if (llvm::timeTraceProfilerEnabled()) {
OptionalFileEntryRef FE = SM.getFileEntryRefForID(SM.getFileID(Loc));
llvm::timeTraceProfilerBegin("Source", FE ? FE->getName()
: StringRef("<unknown>"));
ProfilerStack.push_back(llvm::timeTraceAsyncProfilerBegin(
"Source", FE ? FE->getName() : StringRef("<unknown>")));
}

IncludeStack.push_back(IncludeLoc);
Expand All @@ -167,7 +168,7 @@ class SemaPPCallbacks : public PPCallbacks {
case ExitFile:
if (!IncludeStack.empty()) {
if (llvm::timeTraceProfilerEnabled())
llvm::timeTraceProfilerEnd();
llvm::timeTraceProfilerEnd(ProfilerStack.pop_back_val());

S->DiagnoseNonDefaultPragmaAlignPack(
Sema::PragmaAlignPackDiagnoseKind::ChangedStateAtExit,
Expand Down Expand Up @@ -2206,7 +2207,7 @@ static void checkEscapingByref(VarDecl *VD, Sema &S) {
// block copy/destroy functions. Resolve it here.
if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl())
if (CXXDestructorDecl *DD = RD->getDestructor()) {
auto *FPT = DD->getType()->getAs<FunctionProtoType>();
auto *FPT = DD->getType()->castAs<FunctionProtoType>();
S.ResolveExceptionSpec(Loc, FPT);
}
}
Expand Down
41 changes: 23 additions & 18 deletions clang/lib/Sema/SemaAPINotes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,49 +52,54 @@ static void applyNullability(Sema &S, Decl *D, NullabilityKind Nullability,
if (!Metadata.IsActive)
return;

auto IsModified = [&](Decl *D, QualType QT,
NullabilityKind Nullability) -> bool {
auto GetModified =
[&](Decl *D, QualType QT,
NullabilityKind Nullability) -> std::optional<QualType> {
QualType Original = QT;
S.CheckImplicitNullabilityTypeSpecifier(QT, Nullability, D->getLocation(),
isa<ParmVarDecl>(D),
/*OverrideExisting=*/true);
return QT.getTypePtr() != Original.getTypePtr();
return (QT.getTypePtr() != Original.getTypePtr()) ? std::optional(QT)
: std::nullopt;
};

if (auto Function = dyn_cast<FunctionDecl>(D)) {
if (IsModified(D, Function->getReturnType(), Nullability)) {
QualType FnType = Function->getType();
Function->setType(FnType);
if (auto Modified =
GetModified(D, Function->getReturnType(), Nullability)) {
const FunctionType *FnType = Function->getType()->castAs<FunctionType>();
if (const FunctionProtoType *proto = dyn_cast<FunctionProtoType>(FnType))
Function->setType(S.Context.getFunctionType(
*Modified, proto->getParamTypes(), proto->getExtProtoInfo()));
else
Function->setType(
S.Context.getFunctionNoProtoType(*Modified, FnType->getExtInfo()));
}
} else if (auto Method = dyn_cast<ObjCMethodDecl>(D)) {
QualType Type = Method->getReturnType();
if (IsModified(D, Type, Nullability)) {
Method->setReturnType(Type);
if (auto Modified = GetModified(D, Method->getReturnType(), Nullability)) {
Method->setReturnType(*Modified);

// Make it a context-sensitive keyword if we can.
if (!isIndirectPointerType(Type))
if (!isIndirectPointerType(*Modified))
Method->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
Method->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
}
} else if (auto Value = dyn_cast<ValueDecl>(D)) {
QualType Type = Value->getType();
if (IsModified(D, Type, Nullability)) {
Value->setType(Type);
if (auto Modified = GetModified(D, Value->getType(), Nullability)) {
Value->setType(*Modified);

// Make it a context-sensitive keyword if we can.
if (auto Parm = dyn_cast<ParmVarDecl>(D)) {
if (Parm->isObjCMethodParameter() && !isIndirectPointerType(Type))
if (Parm->isObjCMethodParameter() && !isIndirectPointerType(*Modified))
Parm->setObjCDeclQualifier(Decl::ObjCDeclQualifier(
Parm->getObjCDeclQualifier() | Decl::OBJC_TQ_CSNullability));
}
}
} else if (auto Property = dyn_cast<ObjCPropertyDecl>(D)) {
QualType Type = Property->getType();
if (IsModified(D, Type, Nullability)) {
Property->setType(Type, Property->getTypeSourceInfo());
if (auto Modified = GetModified(D, Property->getType(), Nullability)) {
Property->setType(*Modified, Property->getTypeSourceInfo());

// Make it a property attribute if we can.
if (!isIndirectPointerType(Type))
if (!isIndirectPointerType(*Modified))
Property->setPropertyAttributes(
ObjCPropertyAttribute::kind_null_resettable);
}
Expand Down
25 changes: 20 additions & 5 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ static bool ProcessFormatStringLiteral(const Expr *FormatExpr,
const ConstantArrayType *T =
Context.getAsConstantArrayType(Format->getType());
assert(T && "String literal not of constant array type!");
size_t TypeSize = T->getSize().getZExtValue();
size_t TypeSize = T->getZExtSize();
// In case there's a null byte somewhere.
StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, FormatStrRef.find(0));
return true;
Expand Down Expand Up @@ -5624,6 +5624,21 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
TheCall, /*CheckForFloatArgs*/
TheCall->getArg(0)->getType()->hasFloatingRepresentation()))
return true;
break;
}
// Note these are llvm builtins that we want to catch invalid intrinsic
// generation. Normal handling of these builitns will occur elsewhere.
case Builtin::BI__builtin_elementwise_cos:
case Builtin::BI__builtin_elementwise_sin:
case Builtin::BI__builtin_elementwise_log:
case Builtin::BI__builtin_elementwise_log2:
case Builtin::BI__builtin_elementwise_log10:
case Builtin::BI__builtin_elementwise_pow:
case Builtin::BI__builtin_elementwise_sqrt:
case Builtin::BI__builtin_elementwise_trunc: {
if (CheckFloatOrHalfRepresentations(this, TheCall))
return true;
break;
}
}
return false;
Expand Down Expand Up @@ -9694,7 +9709,7 @@ bool Sema::SemaBuiltinFPClassification(CallExpr *TheCall, unsigned NumArgs,
// vector argument can be supported in all of them.
if (ElementTy->isVectorType() && IsFPClass) {
VectorResultTy = GetSignedVectorType(ElementTy);
ElementTy = ElementTy->getAs<VectorType>()->getElementType();
ElementTy = ElementTy->castAs<VectorType>()->getElementType();
}

// This operation requires a non-_Complex floating-point number.
Expand Down Expand Up @@ -13029,7 +13044,7 @@ static void CheckFormatString(
const ConstantArrayType *T =
S.Context.getAsConstantArrayType(FExpr->getType());
assert(T && "String literal not of constant array type!");
size_t TypeSize = T->getSize().getZExtValue();
size_t TypeSize = T->getZExtSize();
size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size());
const unsigned numDataArgs = Args.size() - firstDataArg;

Expand Down Expand Up @@ -13089,7 +13104,7 @@ bool Sema::FormatStringHasSArg(const StringLiteral *FExpr) {
// Account for cases where the string literal is truncated in a declaration.
const ConstantArrayType *T = Context.getAsConstantArrayType(FExpr->getType());
assert(T && "String literal not of constant array type!");
size_t TypeSize = T->getSize().getZExtValue();
size_t TypeSize = T->getZExtSize();
size_t StrLen = std::min(std::max(TypeSize, size_t(1)) - 1, StrRef.size());
return analyze_format_string::ParseFormatStringHasSArg(Str, Str + StrLen,
getLangOpts(),
Expand Down Expand Up @@ -14052,7 +14067,7 @@ static bool isConstantSizeArrayWithMoreThanOneElement(QualType Ty,
// Only handle constant-sized or VLAs, but not flexible members.
if (const ConstantArrayType *CAT = Context.getAsConstantArrayType(Ty)) {
// Only issue the FIXIT for arrays of size > 1.
if (CAT->getSize().getSExtValue() <= 1)
if (CAT->getZExtSize() <= 1)
return false;
} else if (!Ty->isVariableArrayType()) {
return false;
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/Sema/SemaCodeComplete.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include "clang/AST/ExprConcepts.h"
#include "clang/AST/ExprObjC.h"
#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/OperationKinds.h"
#include "clang/AST/QualTypeNames.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
Expand Down Expand Up @@ -5678,6 +5679,10 @@ QualType getApproximateType(const Expr *E) {
return getApproximateType(VD->getInit());
}
}
if (const auto *UO = llvm::dyn_cast<UnaryOperator>(E)) {
if (UO->getOpcode() == UnaryOperatorKind::UO_Deref)
return UO->getSubExpr()->getType()->getPointeeType();
}
return Unresolved;
}

Expand Down
12 changes: 10 additions & 2 deletions clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1269,10 +1269,18 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
: SourceLocation()));
Atomic.ParameterMapping.emplace(TempArgs, OccurringIndices.count());
}
SourceLocation InstLocBegin =
ArgsAsWritten->arguments().empty()
? ArgsAsWritten->getLAngleLoc()
: ArgsAsWritten->arguments().front().getSourceRange().getBegin();
SourceLocation InstLocEnd =
ArgsAsWritten->arguments().empty()
? ArgsAsWritten->getRAngleLoc()
: ArgsAsWritten->arguments().front().getSourceRange().getEnd();
Sema::InstantiatingTemplate Inst(
S, ArgsAsWritten->arguments().front().getSourceRange().getBegin(),
S, InstLocBegin,
Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
ArgsAsWritten->arguments().front().getSourceRange());
{InstLocBegin, InstLocEnd});
if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
return true;

Expand Down
198 changes: 131 additions & 67 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8837,7 +8837,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
return;
}
const auto *ATy = dyn_cast<ConstantArrayType>(T.getTypePtr());
if (!ATy || ATy->getSize().getSExtValue() != 0) {
if (!ATy || ATy->getZExtSize() != 0) {
Diag(NewVD->getLocation(),
diag::err_typecheck_wasm_table_must_have_zero_length);
NewVD->setInvalidDecl();
Expand Down Expand Up @@ -11260,11 +11260,13 @@ static bool checkNonMultiVersionCompatAttributes(Sema &S,
return Diagnose(S, A);
break;
case attr::TargetVersion:
if (MVKind != MultiVersionKind::TargetVersion)
if (MVKind != MultiVersionKind::TargetVersion &&
MVKind != MultiVersionKind::TargetClones)
return Diagnose(S, A);
break;
case attr::TargetClones:
if (MVKind != MultiVersionKind::TargetClones)
if (MVKind != MultiVersionKind::TargetClones &&
MVKind != MultiVersionKind::TargetVersion)
return Diagnose(S, A);
break;
default:
Expand Down Expand Up @@ -11441,9 +11443,9 @@ static bool CheckMultiVersionFirstFunction(Sema &S, FunctionDecl *FD) {
"Function lacks multiversion attribute");
const auto *TA = FD->getAttr<TargetAttr>();
const auto *TVA = FD->getAttr<TargetVersionAttr>();
// Target and target_version only causes MV if it is default, otherwise this
// is a normal function.
if ((TA && !TA->isDefaultVersion()) || (TVA && !TVA->isDefaultVersion()))
// The target attribute only causes MV if this declaration is the default,
// otherwise it is treated as a normal function.
if (TA && !TA->isDefaultVersion())
return false;

if ((TA || TVA) && CheckMultiVersionValue(S, FD)) {
Expand All @@ -11469,6 +11471,22 @@ static bool PreviousDeclsHaveMultiVersionAttribute(const FunctionDecl *FD) {
return false;
}

static void patchDefaultTargetVersion(FunctionDecl *From, FunctionDecl *To) {
if (!From->getASTContext().getTargetInfo().getTriple().isAArch64())
return;

MultiVersionKind MVKindFrom = From->getMultiVersionKind();
MultiVersionKind MVKindTo = To->getMultiVersionKind();

if (MVKindTo == MultiVersionKind::None &&
(MVKindFrom == MultiVersionKind::TargetVersion ||
MVKindFrom == MultiVersionKind::TargetClones)) {
To->setIsMultiVersion();
To->addAttr(TargetVersionAttr::CreateImplicit(
To->getASTContext(), "default", To->getSourceRange()));
}
}

static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
FunctionDecl *NewFD,
bool &Redeclaration,
Expand All @@ -11479,10 +11497,7 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
// The definitions should be allowed in any order. If we have discovered
// a new target version and the preceeding was the default, then add the
// corresponding attribute to it.
if (OldFD->getMultiVersionKind() == MultiVersionKind::None &&
NewFD->getMultiVersionKind() == MultiVersionKind::TargetVersion)
OldFD->addAttr(TargetVersionAttr::CreateImplicit(S.Context, "default",
OldFD->getSourceRange()));
patchDefaultTargetVersion(NewFD, OldFD);

const auto *NewTA = NewFD->getAttr<TargetAttr>();
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
Expand Down Expand Up @@ -11583,36 +11598,60 @@ static bool CheckTargetCausesMultiVersioning(Sema &S, FunctionDecl *OldFD,
return false;
}

static bool MultiVersionTypesCompatible(MultiVersionKind Old,
MultiVersionKind New) {
if (Old == New || Old == MultiVersionKind::None ||
New == MultiVersionKind::None)
static bool MultiVersionTypesCompatible(FunctionDecl *Old, FunctionDecl *New) {
MultiVersionKind OldKind = Old->getMultiVersionKind();
MultiVersionKind NewKind = New->getMultiVersionKind();

if (OldKind == NewKind || OldKind == MultiVersionKind::None ||
NewKind == MultiVersionKind::None)
return true;

return (Old == MultiVersionKind::CPUDispatch &&
New == MultiVersionKind::CPUSpecific) ||
(Old == MultiVersionKind::CPUSpecific &&
New == MultiVersionKind::CPUDispatch);
if (Old->getASTContext().getTargetInfo().getTriple().isAArch64()) {
switch (OldKind) {
case MultiVersionKind::TargetVersion:
return NewKind == MultiVersionKind::TargetClones;
case MultiVersionKind::TargetClones:
return NewKind == MultiVersionKind::TargetVersion;
default:
return false;
}
} else {
switch (OldKind) {
case MultiVersionKind::CPUDispatch:
return NewKind == MultiVersionKind::CPUSpecific;
case MultiVersionKind::CPUSpecific:
return NewKind == MultiVersionKind::CPUDispatch;
default:
return false;
}
}
}

/// Check the validity of a new function declaration being added to an existing
/// multiversioned declaration collection.
static bool CheckMultiVersionAdditionalDecl(
Sema &S, FunctionDecl *OldFD, FunctionDecl *NewFD,
MultiVersionKind NewMVKind, const CPUDispatchAttr *NewCPUDisp,
const CPUSpecificAttr *NewCPUSpec, const TargetClonesAttr *NewClones,
bool &Redeclaration, NamedDecl *&OldDecl, LookupResult &Previous) {
const auto *NewTA = NewFD->getAttr<TargetAttr>();
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
MultiVersionKind OldMVKind = OldFD->getMultiVersionKind();
const CPUDispatchAttr *NewCPUDisp, const CPUSpecificAttr *NewCPUSpec,
const TargetClonesAttr *NewClones, bool &Redeclaration, NamedDecl *&OldDecl,
LookupResult &Previous) {

// Disallow mixing of multiversioning types.
if (!MultiVersionTypesCompatible(OldMVKind, NewMVKind)) {
if (!MultiVersionTypesCompatible(OldFD, NewFD)) {
S.Diag(NewFD->getLocation(), diag::err_multiversion_types_mixed);
S.Diag(OldFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
return true;
}

// Add the default target_version attribute if it's missing.
patchDefaultTargetVersion(OldFD, NewFD);
patchDefaultTargetVersion(NewFD, OldFD);

const auto *NewTA = NewFD->getAttr<TargetAttr>();
const auto *NewTVA = NewFD->getAttr<TargetVersionAttr>();
MultiVersionKind NewMVKind = NewFD->getMultiVersionKind();
[[maybe_unused]] MultiVersionKind OldMVKind = OldFD->getMultiVersionKind();

ParsedTargetAttr NewParsed;
if (NewTA) {
NewParsed = S.getASTContext().getTargetInfo().parseTargetAttr(
Expand Down Expand Up @@ -11641,19 +11680,6 @@ static bool CheckMultiVersionAdditionalDecl(
S.IsOverload(NewFD, CurFD, UseMemberUsingDeclRules))
continue;

if (NewMVKind == MultiVersionKind::None &&
OldMVKind == MultiVersionKind::TargetVersion) {
NewFD->addAttr(TargetVersionAttr::CreateImplicit(
S.Context, "default", NewFD->getSourceRange()));
NewFD->setIsMultiVersion();
NewMVKind = MultiVersionKind::TargetVersion;
if (!NewTVA) {
NewTVA = NewFD->getAttr<TargetVersionAttr>();
NewTVA->getFeatures(NewFeats);
llvm::sort(NewFeats);
}
}

switch (NewMVKind) {
case MultiVersionKind::None:
assert(OldMVKind == MultiVersionKind::TargetClones &&
Expand Down Expand Up @@ -11681,43 +11707,81 @@ static bool CheckMultiVersionAdditionalDecl(
break;
}
case MultiVersionKind::TargetVersion: {
const auto *CurTVA = CurFD->getAttr<TargetVersionAttr>();
if (CurTVA->getName() == NewTVA->getName()) {
NewFD->setIsMultiVersion();
Redeclaration = true;
OldDecl = ND;
return false;
}
llvm::SmallVector<StringRef, 8> CurFeats;
if (CurTVA) {
if (const auto *CurTVA = CurFD->getAttr<TargetVersionAttr>()) {
if (CurTVA->getName() == NewTVA->getName()) {
NewFD->setIsMultiVersion();
Redeclaration = true;
OldDecl = ND;
return false;
}
llvm::SmallVector<StringRef, 8> CurFeats;
CurTVA->getFeatures(CurFeats);
llvm::sort(CurFeats);
}
if (CurFeats == NewFeats) {
S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate);
S.Diag(CurFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
return true;

if (CurFeats == NewFeats) {
S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate);
S.Diag(CurFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
return true;
}
} else if (const auto *CurClones = CurFD->getAttr<TargetClonesAttr>()) {
// Default
if (NewFeats.empty())
break;

for (unsigned I = 0; I < CurClones->featuresStrs_size(); ++I) {
llvm::SmallVector<StringRef, 8> CurFeats;
CurClones->getFeatures(CurFeats, I);
llvm::sort(CurFeats);

if (CurFeats == NewFeats) {
S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate);
S.Diag(CurFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
return true;
}
}
}
break;
}
case MultiVersionKind::TargetClones: {
const auto *CurClones = CurFD->getAttr<TargetClonesAttr>();
assert(NewClones && "MultiVersionKind does not match attribute type");
if (const auto *CurClones = CurFD->getAttr<TargetClonesAttr>()) {
if (CurClones->featuresStrs_size() != NewClones->featuresStrs_size() ||
!std::equal(CurClones->featuresStrs_begin(),
CurClones->featuresStrs_end(),
NewClones->featuresStrs_begin())) {
S.Diag(NewFD->getLocation(), diag::err_target_clone_doesnt_match);
S.Diag(CurFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
return true;
}
} else if (const auto *CurTVA = CurFD->getAttr<TargetVersionAttr>()) {
llvm::SmallVector<StringRef, 8> CurFeats;
CurTVA->getFeatures(CurFeats);
llvm::sort(CurFeats);

// Default
if (CurFeats.empty())
break;

for (unsigned I = 0; I < NewClones->featuresStrs_size(); ++I) {
NewFeats.clear();
NewClones->getFeatures(NewFeats, I);
llvm::sort(NewFeats);

if (CurFeats == NewFeats) {
S.Diag(NewFD->getLocation(), diag::err_multiversion_duplicate);
S.Diag(CurFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
return true;
}
}
break;
}
Redeclaration = true;
OldDecl = CurFD;
NewFD->setIsMultiVersion();

if (CurClones && NewClones &&
(CurClones->featuresStrs_size() != NewClones->featuresStrs_size() ||
!std::equal(CurClones->featuresStrs_begin(),
CurClones->featuresStrs_end(),
NewClones->featuresStrs_begin()))) {
S.Diag(NewFD->getLocation(), diag::err_target_clone_doesnt_match);
S.Diag(CurFD->getLocation(), diag::note_previous_declaration);
NewFD->setInvalidDecl();
return true;
}

return false;
}
case MultiVersionKind::CPUSpecific:
Expand Down Expand Up @@ -11913,7 +11977,7 @@ static bool CheckMultiVersionFunction(Sema &S, FunctionDecl *NewFD,
// At this point, we have a multiversion function decl (in OldFD) AND an
// appropriate attribute in the current function decl. Resolve that these are
// still compatible with previous declarations.
return CheckMultiVersionAdditionalDecl(S, OldFD, NewFD, MVKind, NewCPUDisp,
return CheckMultiVersionAdditionalDecl(S, OldFD, NewFD, NewCPUDisp,
NewCPUSpec, NewClones, Redeclaration,
OldDecl, Previous);
}
Expand Down
7 changes: 4 additions & 3 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5282,7 +5282,7 @@ static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T) {
return true;

while (const ConstantArrayType *ArrayT = Context.getAsConstantArrayType(T)) {
if (!ArrayT->getSize())
if (ArrayT->isZeroSize())
return true;

T = ArrayT->getElementType();
Expand Down Expand Up @@ -11353,7 +11353,7 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
if (ConvType->isUndeducedAutoType()) {
Diag(Conversion->getTypeSpecStartLoc(), diag::err_auto_not_allowed)
<< getReturnTypeLoc(Conversion).getSourceRange()
<< llvm::to_underlying(ConvType->getAs<AutoType>()->getKeyword())
<< llvm::to_underlying(ConvType->castAs<AutoType>()->getKeyword())
<< /* in declaration of conversion function template= */ 24;
}

Expand Down Expand Up @@ -16202,7 +16202,8 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {

// Emit warning for non-trivial dtor in global scope (a real global,
// class-static, function-static).
Diag(VD->getLocation(), diag::warn_exit_time_destructor);
if (!VD->hasAttr<AlwaysDestroyAttr>())
Diag(VD->getLocation(), diag::warn_exit_time_destructor);

// TODO: this should be re-enabled for static locals by !CXAAtExit
if (!VD->isStaticLocal())
Expand Down
5 changes: 2 additions & 3 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6857,9 +6857,8 @@ Sema::CheckStaticArrayArgument(SourceLocation CallLoc,
ArgCAT->getElementType())) {
if (ArgCAT->getSize().ult(CAT->getSize())) {
Diag(CallLoc, diag::warn_static_array_too_small)
<< ArgExpr->getSourceRange()
<< (unsigned)ArgCAT->getSize().getZExtValue()
<< (unsigned)CAT->getSize().getZExtValue() << 0;
<< ArgExpr->getSourceRange() << (unsigned)ArgCAT->getZExtSize()
<< (unsigned)CAT->getZExtSize() << 0;
DiagnoseCalleeStaticArrayParam(*this, Param);
}
return;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6083,7 +6083,7 @@ static uint64_t EvaluateArrayTypeTrait(Sema &Self, ArrayTypeTrait ATT,

if (Matched && T->isArrayType()) {
if (const ConstantArrayType *CAT = Self.Context.getAsConstantArrayType(T))
return CAT->getSize().getLimitedValue();
return CAT->getLimitedSize();
}
}
return 0;
Expand Down
21 changes: 10 additions & 11 deletions clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
// Get the length of the string as parsed.
auto *ConstantArrayTy =
cast<ConstantArrayType>(Str->getType()->getAsArrayTypeUnsafe());
uint64_t StrLength = ConstantArrayTy->getSize().getZExtValue();
uint64_t StrLength = ConstantArrayTy->getZExtSize();

if (CheckC23ConstexprInit)
if (const StringLiteral *SL = dyn_cast<StringLiteral>(Str->IgnoreParens()))
Expand Down Expand Up @@ -246,14 +246,13 @@ static void CheckStringInit(Expr *Str, QualType &DeclT, const ArrayType *AT,
}

// [dcl.init.string]p2
if (StrLength > CAT->getSize().getZExtValue())
if (StrLength > CAT->getZExtSize())
S.Diag(Str->getBeginLoc(),
diag::err_initializer_string_for_char_array_too_long)
<< CAT->getSize().getZExtValue() << StrLength
<< Str->getSourceRange();
<< CAT->getZExtSize() << StrLength << Str->getSourceRange();
} else {
// C99 6.7.8p14.
if (StrLength-1 > CAT->getSize().getZExtValue())
if (StrLength - 1 > CAT->getZExtSize())
S.Diag(Str->getBeginLoc(),
diag::ext_initializer_string_for_char_array_too_long)
<< Str->getSourceRange();
Expand Down Expand Up @@ -879,7 +878,7 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
if (const ArrayType *AType = SemaRef.Context.getAsArrayType(ILE->getType())) {
ElementType = AType->getElementType();
if (const auto *CAType = dyn_cast<ConstantArrayType>(AType))
NumElements = CAType->getSize().getZExtValue();
NumElements = CAType->getZExtSize();
// For an array new with an unknown bound, ask for one additional element
// in order to populate the array filler.
if (Entity.isVariableLengthArrayNew())
Expand Down Expand Up @@ -1016,7 +1015,7 @@ int InitListChecker::numArrayElements(QualType DeclType) {
int maxElements = 0x7FFFFFFF;
if (const ConstantArrayType *CAT =
SemaRef.Context.getAsConstantArrayType(DeclType)) {
maxElements = static_cast<int>(CAT->getSize().getZExtValue());
maxElements = static_cast<int>(CAT->getZExtSize());
}
return maxElements;
}
Expand Down Expand Up @@ -3101,7 +3100,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
// Get the length of the string.
uint64_t StrLen = SL->getLength();
if (cast<ConstantArrayType>(AT)->getSize().ult(StrLen))
StrLen = cast<ConstantArrayType>(AT)->getSize().getZExtValue();
StrLen = cast<ConstantArrayType>(AT)->getZExtSize();
StructuredList->resizeInits(Context, StrLen);

// Build a literal for each character in the string, and put them into
Expand All @@ -3124,7 +3123,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
// Get the length of the string.
uint64_t StrLen = Str.size();
if (cast<ConstantArrayType>(AT)->getSize().ult(StrLen))
StrLen = cast<ConstantArrayType>(AT)->getSize().getZExtValue();
StrLen = cast<ConstantArrayType>(AT)->getZExtSize();
StructuredList->resizeInits(Context, StrLen);

// Build a literal for each character in the string, and put them into
Expand Down Expand Up @@ -3283,7 +3282,7 @@ InitListChecker::createInitListExpr(QualType CurrentObjectType,
if (const ArrayType *AType
= SemaRef.Context.getAsArrayType(CurrentObjectType)) {
if (const ConstantArrayType *CAType = dyn_cast<ConstantArrayType>(AType)) {
NumElements = CAType->getSize().getZExtValue();
NumElements = CAType->getZExtSize();
// Simple heuristic so that we don't allocate a very large
// initializer with many empty entries at the end.
if (NumElements > ExpectedNumInits)
Expand Down Expand Up @@ -5492,7 +5491,7 @@ static void TryOrBuildParenListInitialization(
// having k elements.
if (const ConstantArrayType *CAT =
S.getASTContext().getAsConstantArrayType(Entity.getType())) {
ArrayLength = CAT->getSize().getZExtValue();
ArrayLength = CAT->getZExtSize();
ResultType = Entity.getType();
} else if (const VariableArrayType *VAT =
S.getASTContext().getAsVariableArrayType(Entity.getType())) {
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Sema/SemaObjCProperty.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -638,15 +638,15 @@ ObjCPropertyDecl *Sema::CreatePropertyDecl(Scope *S,
PDecl->setInvalidDecl();
}

ProcessDeclAttributes(S, PDecl, FD.D);

// Regardless of setter/getter attribute, we save the default getter/setter
// selector names in anticipation of declaration of setter/getter methods.
PDecl->setGetterName(GetterSel, GetterNameLoc);
PDecl->setSetterName(SetterSel, SetterNameLoc);
PDecl->setPropertyAttributesAsWritten(
makePropertyAttributesAsWritten(AttributesAsWritten));

ProcessDeclAttributes(S, PDecl, FD.D);

if (Attributes & ObjCPropertyAttribute::kind_readonly)
PDecl->setPropertyAttributes(ObjCPropertyAttribute::kind_readonly);

Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaOpenMP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21284,7 +21284,7 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
if (isa<ArraySubscriptExpr>(E) ||
(OASE && OASE->getColonLocFirst().isInvalid())) {
if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
return ATy->getSize().getSExtValue() != 1;
return ATy->getSExtSize() != 1;
// Size can't be evaluated statically.
return false;
}
Expand Down Expand Up @@ -21325,7 +21325,7 @@ static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef,
return false; // Can't get the integer value as a constant.

llvm::APSInt ConstLength = Result.Val.getInt();
return CATy->getSize().getSExtValue() != ConstLength.getSExtValue();
return CATy->getSExtSize() != ConstLength.getSExtValue();
}

// Return true if it can be proven that the provided array expression (array
Expand All @@ -21350,7 +21350,7 @@ static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef,
// is pointer.
if (!Length) {
if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()))
return ATy->getSize().getSExtValue() != 1;
return ATy->getSExtSize() != 1;
// We cannot assume anything.
return false;
}
Expand Down
44 changes: 29 additions & 15 deletions clang/lib/Sema/SemaOverload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6865,6 +6865,32 @@ static bool IsAcceptableNonMemberOperatorCandidate(ASTContext &Context,
return false;
}

static bool isNonViableMultiVersionOverload(FunctionDecl *FD) {
if (FD->isTargetMultiVersionDefault())
return false;

if (!FD->getASTContext().getTargetInfo().getTriple().isAArch64())
return FD->isTargetMultiVersion();

if (!FD->isMultiVersion())
return false;

// Among multiple target versions consider either the default,
// or the first non-default in the absence of default version.
unsigned SeenAt = 0;
unsigned I = 0;
bool HasDefault = false;
FD->getASTContext().forEachMultiversionedFunctionVersion(
FD, [&](const FunctionDecl *CurFD) {
if (FD == CurFD)
SeenAt = I;
else if (CurFD->isTargetMultiVersionDefault())
HasDefault = true;
++I;
});
return HasDefault || SeenAt != 0;
}

/// AddOverloadCandidate - Adds the given function to the set of
/// candidate functions, using the given function call arguments. If
/// @p SuppressUserConversions, then don't allow user-defined
Expand Down Expand Up @@ -6970,11 +6996,7 @@ void Sema::AddOverloadCandidate(
}
}

if (Function->isMultiVersion() &&
((Function->hasAttr<TargetAttr>() &&
!Function->getAttr<TargetAttr>()->isDefaultVersion()) ||
(Function->hasAttr<TargetVersionAttr>() &&
!Function->getAttr<TargetVersionAttr>()->isDefaultVersion()))) {
if (isNonViableMultiVersionOverload(Function)) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_non_default_multiversion_function;
return;
Expand Down Expand Up @@ -7637,11 +7659,7 @@ Sema::AddMethodCandidate(CXXMethodDecl *Method, DeclAccessPair FoundDecl,
return;
}

if (Method->isMultiVersion() &&
((Method->hasAttr<TargetAttr>() &&
!Method->getAttr<TargetAttr>()->isDefaultVersion()) ||
(Method->hasAttr<TargetVersionAttr>() &&
!Method->getAttr<TargetVersionAttr>()->isDefaultVersion()))) {
if (isNonViableMultiVersionOverload(Method)) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_non_default_multiversion_function;
}
Expand Down Expand Up @@ -8127,11 +8145,7 @@ void Sema::AddConversionCandidate(
return;
}

if (Conversion->isMultiVersion() &&
((Conversion->hasAttr<TargetAttr>() &&
!Conversion->getAttr<TargetAttr>()->isDefaultVersion()) ||
(Conversion->hasAttr<TargetVersionAttr>() &&
!Conversion->getAttr<TargetVersionAttr>()->isDefaultVersion()))) {
if (isNonViableMultiVersionOverload(Conversion)) {
Candidate.Viable = false;
Candidate.FailureKind = ovl_non_default_multiversion_function;
}
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Sema::SemaDiagnosticBuilder Sema::SYCLDiagIfDeviceCode(SourceLocation Loc,

static bool isZeroSizedArray(Sema &SemaRef, QualType Ty) {
if (const auto *CAT = SemaRef.getASTContext().getAsConstantArrayType(Ty))
return CAT->getSize() == 0;
return CAT->isZeroSize();
return false;
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/StaticAnalyzer/Checkers/CXXDeleteChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ CXXDeleteChecker::PtrCastVisitor::VisitNode(const ExplodedNode *N,
/*addPosRange=*/true);
}

void ento::registerCXXArrayDeleteChecker(CheckerManager &mgr) {
void ento::registerArrayDeleteChecker(CheckerManager &mgr) {
mgr.registerChecker<CXXArrayDeleteChecker>();
}

bool ento::shouldRegisterCXXArrayDeleteChecker(const CheckerManager &mgr) {
bool ento::shouldRegisterArrayDeleteChecker(const CheckerManager &mgr) {
return true;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ static bool evenFlexibleArraySize(ASTContext &Ctx, CharUnits RegionSize,
FlexSize = Ctx.getTypeSizeInChars(ElemType);
if (ArrayTy->getSize() == 1 && TypeSize > FlexSize)
TypeSize -= FlexSize;
else if (ArrayTy->getSize() != 0)
else if (!ArrayTy->isZeroSize())
return false;
} else if (RD->hasFlexibleArrayMember()) {
FlexSize = Ctx.getTypeSizeInChars(ElemType);
Expand Down
27 changes: 21 additions & 6 deletions clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,8 +394,10 @@ class MallocChecker
const CallEvent &Call, CheckerContext &C)>;

const CallDescriptionMap<CheckFn> PreFnMap{
{{{"getline"}, 3}, &MallocChecker::preGetdelim},
{{{"getdelim"}, 4}, &MallocChecker::preGetdelim},
// NOTE: the following CallDescription also matches the C++ standard
// library function std::getline(); the callback will filter it out.
{{CDM::CLibrary, {"getline"}, 3}, &MallocChecker::preGetdelim},
{{CDM::CLibrary, {"getdelim"}, 4}, &MallocChecker::preGetdelim},
};

const CallDescriptionMap<CheckFn> FreeingMemFnMap{
Expand Down Expand Up @@ -446,8 +448,11 @@ class MallocChecker
std::bind(&MallocChecker::checkRealloc, _1, _2, _3, false)},
{{{"g_realloc_n"}, 3}, &MallocChecker::checkReallocN},
{{{"g_try_realloc_n"}, 3}, &MallocChecker::checkReallocN},
{{{"getline"}, 3}, &MallocChecker::checkGetdelim},
{{{"getdelim"}, 4}, &MallocChecker::checkGetdelim},

// NOTE: the following CallDescription also matches the C++ standard
// library function std::getline(); the callback will filter it out.
{{CDM::CLibrary, {"getline"}, 3}, &MallocChecker::checkGetdelim},
{{CDM::CLibrary, {"getdelim"}, 4}, &MallocChecker::checkGetdelim},
};

bool isMemCall(const CallEvent &Call) const;
Expand Down Expand Up @@ -1435,9 +1440,17 @@ void MallocChecker::checkGMallocN0(const CallEvent &Call,
C.addTransition(State);
}

static bool isFromStdNamespace(const CallEvent &Call) {
const Decl *FD = Call.getDecl();
assert(FD && "a CallDescription cannot match a call without a Decl");
return FD->isInStdNamespace();
}

void MallocChecker::preGetdelim(const CallEvent &Call,
CheckerContext &C) const {
if (!Call.isGlobalCFunction())
// Discard calls to the C++ standard library function std::getline(), which
// is completely unrelated to the POSIX getline() that we're checking.
if (isFromStdNamespace(Call))
return;

ProgramStateRef State = C.getState();
Expand All @@ -1458,7 +1471,9 @@ void MallocChecker::preGetdelim(const CallEvent &Call,

void MallocChecker::checkGetdelim(const CallEvent &Call,
CheckerContext &C) const {
if (!Call.isGlobalCFunction())
// Discard calls to the C++ standard library function std::getline(), which
// is completely unrelated to the POSIX getline() that we're checking.
if (isFromStdNamespace(Call))
return;

ProgramStateRef State = C.getState();
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
return;
uint64_t Elts = 0;
if (const ConstantArrayType *CArrTy = dyn_cast<ConstantArrayType>(ArrTy))
Elts = CArrTy->getSize().getZExtValue();
Elts = CArrTy->getZExtSize();
if (Elts == 0)
return;
const RecordType *RT = ArrTy->getElementType()->getAs<RecordType>();
Expand Down
36 changes: 26 additions & 10 deletions clang/lib/StaticAnalyzer/Core/BugReporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ class PathDiagnosticConstruct {
public:
PathDiagnosticConstruct(const PathDiagnosticConsumer *PDC,
const ExplodedNode *ErrorNode,
const PathSensitiveBugReport *R);
const PathSensitiveBugReport *R,
const Decl *AnalysisEntryPoint);

/// \returns the location context associated with the current position in the
/// bug path.
Expand Down Expand Up @@ -1323,24 +1324,26 @@ void PathDiagnosticBuilder::generatePathDiagnosticsForNode(
}

static std::unique_ptr<PathDiagnostic>
generateDiagnosticForBasicReport(const BasicBugReport *R) {
generateDiagnosticForBasicReport(const BasicBugReport *R,
const Decl *AnalysisEntryPoint) {
const BugType &BT = R->getBugType();
return std::make_unique<PathDiagnostic>(
BT.getCheckerName(), R->getDeclWithIssue(), BT.getDescription(),
R->getDescription(), R->getShortDescription(/*UseFallback=*/false),
BT.getCategory(), R->getUniqueingLocation(), R->getUniqueingDecl(),
std::make_unique<FilesToLineNumsMap>());
AnalysisEntryPoint, std::make_unique<FilesToLineNumsMap>());
}

static std::unique_ptr<PathDiagnostic>
generateEmptyDiagnosticForReport(const PathSensitiveBugReport *R,
const SourceManager &SM) {
const SourceManager &SM,
const Decl *AnalysisEntryPoint) {
const BugType &BT = R->getBugType();
return std::make_unique<PathDiagnostic>(
BT.getCheckerName(), R->getDeclWithIssue(), BT.getDescription(),
R->getDescription(), R->getShortDescription(/*UseFallback=*/false),
BT.getCategory(), R->getUniqueingLocation(), R->getUniqueingDecl(),
findExecutedLines(SM, R->getErrorNode()));
AnalysisEntryPoint, findExecutedLines(SM, R->getErrorNode()));
}

static const Stmt *getStmtParent(const Stmt *S, const ParentMap &PM) {
Expand Down Expand Up @@ -1976,10 +1979,11 @@ static void updateExecutedLinesWithDiagnosticPieces(PathDiagnostic &PD) {

PathDiagnosticConstruct::PathDiagnosticConstruct(
const PathDiagnosticConsumer *PDC, const ExplodedNode *ErrorNode,
const PathSensitiveBugReport *R)
const PathSensitiveBugReport *R, const Decl *AnalysisEntryPoint)
: Consumer(PDC), CurrentNode(ErrorNode),
SM(CurrentNode->getCodeDecl().getASTContext().getSourceManager()),
PD(generateEmptyDiagnosticForReport(R, getSourceManager())) {
PD(generateEmptyDiagnosticForReport(R, getSourceManager(),
AnalysisEntryPoint)) {
LCM[&PD->getActivePath()] = ErrorNode->getLocationContext();
}

Expand All @@ -1993,13 +1997,14 @@ PathDiagnosticBuilder::PathDiagnosticBuilder(

std::unique_ptr<PathDiagnostic>
PathDiagnosticBuilder::generate(const PathDiagnosticConsumer *PDC) const {
PathDiagnosticConstruct Construct(PDC, ErrorNode, R);
const Decl *EntryPoint = getBugReporter().getAnalysisEntryPoint();
PathDiagnosticConstruct Construct(PDC, ErrorNode, R, EntryPoint);

const SourceManager &SM = getSourceManager();
const AnalyzerOptions &Opts = getAnalyzerOptions();

if (!PDC->shouldGenerateDiagnostics())
return generateEmptyDiagnosticForReport(R, getSourceManager());
return generateEmptyDiagnosticForReport(R, getSourceManager(), EntryPoint);

// Construct the final (warning) event for the bug report.
auto EndNotes = VisitorsDiagnostics->find(ErrorNode);
Expand Down Expand Up @@ -3123,6 +3128,16 @@ void BugReporter::FlushReport(BugReportEquivClass& EQ) {
Pieces.back()->addFixit(I);

updateExecutedLinesWithDiagnosticPieces(*PD);

// If we are debugging, let's have the entry point as the first note.
if (getAnalyzerOptions().AnalyzerDisplayProgress ||
getAnalyzerOptions().AnalyzerNoteAnalysisEntryPoints) {
const Decl *EntryPoint = getAnalysisEntryPoint();
Pieces.push_front(std::make_shared<PathDiagnosticEventPiece>(
PathDiagnosticLocation{EntryPoint->getLocation(), getSourceManager()},
"[debug] analyzing from " +
AnalysisDeclContext::getFunctionName(EntryPoint)));
}
Consumer->HandlePathDiagnostic(std::move(PD));
}
}
Expand Down Expand Up @@ -3211,7 +3226,8 @@ BugReporter::generateDiagnosticForConsumerMap(
auto *basicReport = cast<BasicBugReport>(exampleReport);
auto Out = std::make_unique<DiagnosticForConsumerMapTy>();
for (auto *Consumer : consumers)
(*Out)[Consumer] = generateDiagnosticForBasicReport(basicReport);
(*Out)[Consumer] =
generateDiagnosticForBasicReport(basicReport, AnalysisEntryPoint);
return Out;
}

Expand Down
8 changes: 5 additions & 3 deletions clang/lib/StaticAnalyzer/Core/CheckerContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,11 @@ bool CheckerContext::isCLibraryFunction(const FunctionDecl *FD,
if (!II)
return false;

// Look through 'extern "C"' and anything similar invented in the future.
// If this function is not in TU directly, it is not a C library function.
if (!FD->getDeclContext()->getRedeclContext()->isTranslationUnit())
// C library functions are either declared directly within a TU (the common
// case) or they are accessed through the namespace `std` (when they are used
// in C++ via headers like <cstdlib>).
const DeclContext *DC = FD->getDeclContext()->getRedeclContext();
if (!(DC->isTranslationUnit() || DC->isStdNamespace()))
return false;

// If this function is not externally visible, it is not a C library function.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/StaticAnalyzer/Core/MemRegion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -825,7 +825,7 @@ DefinedOrUnknownSVal MemRegionManager::getStaticSize(const MemRegion *MR,
};
auto IsArrayOfZero = [](const ArrayType *AT) {
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
return CAT && CAT->getSize() == 0;
return CAT && CAT->isZeroSize();
};
auto IsArrayOfOne = [](const ArrayType *AT) {
const auto *CAT = dyn_cast<ConstantArrayType>(AT);
Expand Down
8 changes: 4 additions & 4 deletions clang/lib/StaticAnalyzer/Core/RegionStore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1166,7 +1166,7 @@ void InvalidateRegionsWorker::VisitCluster(const MemRegion *baseR,

// Compute lower and upper offsets for region within array.
if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
NumElements = CAT->getSize().getZExtValue();
NumElements = CAT->getZExtSize();
if (!NumElements) // We are not dealing with a constant size array
goto conjure_default;
QualType ElementTy = AT->getElementType();
Expand Down Expand Up @@ -1613,7 +1613,7 @@ getConstantArrayExtents(const ConstantArrayType *CAT) {
CAT = cast<ConstantArrayType>(CAT->getCanonicalTypeInternal());
SmallVector<uint64_t, 2> Extents;
do {
Extents.push_back(CAT->getSize().getZExtValue());
Extents.push_back(CAT->getZExtSize());
} while ((CAT = dyn_cast<ConstantArrayType>(CAT->getElementType())));
return Extents;
}
Expand Down Expand Up @@ -2436,7 +2436,7 @@ std::optional<RegionBindingsRef> RegionStoreManager::tryBindSmallArray(
return std::nullopt;

// If the array is too big, create a LCV instead.
uint64_t ArrSize = CAT->getSize().getLimitedValue();
uint64_t ArrSize = CAT->getLimitedSize();
if (ArrSize > SmallArrayLimit)
return std::nullopt;

Expand Down Expand Up @@ -2465,7 +2465,7 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B,
std::optional<uint64_t> Size;

if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(AT))
Size = CAT->getSize().getZExtValue();
Size = CAT->getZExtSize();

// Check if the init expr is a literal. If so, bind the rvalue instead.
// FIXME: It's not responsibility of the Store to transform this lvalue
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,8 @@ static void reportAnalyzerFunctionMisuse(const AnalyzerOptions &Opts,

void AnalysisConsumer::runAnalysisOnTranslationUnit(ASTContext &C) {
BugReporter BR(*Mgr);
TranslationUnitDecl *TU = C.getTranslationUnitDecl();
const TranslationUnitDecl *TU = C.getTranslationUnitDecl();
BR.setAnalysisEntryPoint(TU);
if (SyntaxCheckTimer)
SyntaxCheckTimer->startTimer();
checkerMgr->runCheckersOnASTDecl(TU, *Mgr, BR);
Expand Down Expand Up @@ -675,6 +676,7 @@ void AnalysisConsumer::HandleCode(Decl *D, AnalysisMode Mode,

DisplayFunction(D, Mode, IMode);
BugReporter BR(*Mgr);
BR.setAnalysisEntryPoint(D);

if (Mode & AM_Syntax) {
llvm::TimeRecord CheckerStartTime;
Expand Down
8 changes: 8 additions & 0 deletions clang/test/APINotes/Inputs/APINotes/SomeOtherKit.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Name: SomeOtherKit
Classes:
- Name: A
Methods:
- Selector: "methodB"
MethodKind: Instance
Availability: none
AvailabilityMsg: "anything but this"
5 changes: 5 additions & 0 deletions clang/test/APINotes/Inputs/BrokenHeaders/APINotes.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Name: SomeBrokenLib
Functions:
- Name: do_something_with_pointers
Nu llabilityOfRet: O
# the space is intentional, to make sure we don't crash on malformed API Notes
6 changes: 6 additions & 0 deletions clang/test/APINotes/Inputs/BrokenHeaders/SomeBrokenLib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef SOME_BROKEN_LIB_H
#define SOME_BROKEN_LIB_H

void do_something_with_pointers(int *ptr1, int *ptr2);

#endif // SOME_BROKEN_LIB_H
7 changes: 7 additions & 0 deletions clang/test/APINotes/Inputs/BrokenHeaders2/APINotes.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Name: SomeBrokenLib
Functions:
- Name: do_something_with_pointers
NullabilityOfRet: O
- Name: do_something_with_pointers
NullabilityOfRet: O

6 changes: 6 additions & 0 deletions clang/test/APINotes/Inputs/BrokenHeaders2/SomeBrokenLib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#ifndef SOME_BROKEN_LIB_H
#define SOME_BROKEN_LIB_H

void do_something_with_pointers(int *ptr1, int *ptr2);

#endif // SOME_BROKEN_LIB_H
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int FrameworkWithActualPrivateModule;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module FrameworkWithActualPrivateModule {
umbrella header "FrameworkWithActualPrivateModule.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module FrameworkWithActualPrivateModule_Private {
umbrella header "FrameworkWithActualPrivateModule_Private.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Name: FrameworkWithActualPrivateModule_Private
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#include <FrameworkWithActualPrivateModule/FrameworkWithActualPrivateModule.h>
extern int FrameworkWithActualPrivateModule_Private;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int FrameworkWithWrongCase;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module FrameworkWithWrongCase {
umbrella header "FrameworkWithWrongCase.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Name: FrameworkWithWrongCase
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int FrameworkWithWrongCasePrivate;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module FrameworkWithWrongCasePrivate {
umbrella header "FrameworkWithWrongCasePrivate.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module FrameworkWithWrongCasePrivate.Inner {}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Name: FrameworkWithWrongCasePrivate
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
@import LayeredKitImpl;

// @interface declarations already don't inherit attributes from forward
// declarations, so in order to test this properly we have to /not/ define
// UpwardClass anywhere.

// @interface UpwardClass
// @end

@protocol UpwardProto
@end
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module LayeredKit {
umbrella header "LayeredKit.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Name: LayeredKitImpl
Classes:
- Name: PerfectlyNormalClass
Availability: none
- Name: UpwardClass
Availability: none
Protocols:
- Name: UpwardProto
Availability: none
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@protocol UpwardProto;
@class UpwardClass;

@interface PerfectlyNormalClass
@end

void doImplementationThings(UpwardClass *first, id <UpwardProto> second) __attribute((unavailable));
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module LayeredKitImpl {
umbrella header "LayeredKitImpl.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module SimpleKit {
umbrella header "SimpleKit.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
Name: SomeKit
Classes:
- Name: A
Methods:
- Selector: "transform:"
MethodKind: Instance
Availability: none
AvailabilityMsg: "anything but this"
- Selector: "transform:integer:"
MethodKind: Instance
NullabilityOfRet: N
Nullability: [ N, S ]
Properties:
- Name: intValue
PropertyKind: Instance
Availability: none
AvailabilityMsg: "wouldn't work anyway"
- Name: nonnullAInstance
PropertyKind: Instance
Nullability: N
- Name: nonnullAClass
PropertyKind: Class
Nullability: N
- Name: nonnullABoth
Nullability: N
- Name: B
Availability: none
AvailabilityMsg: "just don't"
- Name: C
Methods:
- Selector: "initWithA:"
MethodKind: Instance
DesignatedInit: true
- Name: OverriddenTypes
Methods:
- Selector: "methodToMangle:second:"
MethodKind: Instance
ResultType: 'char *'
Parameters:
- Position: 0
Type: 'SOMEKIT_DOUBLE *'
- Position: 1
Type: 'float *'
Properties:
- Name: intPropertyToMangle
PropertyKind: Instance
Type: 'double *'
Functions:
- Name: global_int_fun
ResultType: 'char *'
Parameters:
- Position: 0
Type: 'double *'
- Position: 1
Type: 'float *'
Globals:
- Name: global_int_ptr
Type: 'double *'
SwiftVersions:
- Version: 3.0
Classes:
- Name: A
Methods:
- Selector: "transform:integer:"
MethodKind: Instance
NullabilityOfRet: O
Nullability: [ O, S ]
Properties:
- Name: explicitNonnullInstance
PropertyKind: Instance
Nullability: O
- Name: explicitNullableInstance
PropertyKind: Instance
Nullability: N
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Name: SomeKit
Classes:
- Name: A
Methods:
- Selector: "privateTransform:input:"
MethodKind: Instance
NullabilityOfRet: N
Nullability: [ N, S ]
Properties:
- Name: internalProperty
Nullability: N
Protocols:
- Name: InternalProtocol
Availability: none
AvailabilityMsg: "not for you"
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#ifndef SOMEKIT_H
#define SOMEKIT_H

#define ROOT_CLASS __attribute__((objc_root_class))

ROOT_CLASS
@interface A
-(A*)transform:(A*)input;
-(A*)transform:(A*)input integer:(int)integer;

@property (nonatomic, readonly, retain) A* someA;
@property (nonatomic, retain) A* someOtherA;

@property (nonatomic) int intValue;
@end

@interface B : A
@end

@interface C : A
- (instancetype)init;
- (instancetype)initWithA:(A*)a;
@end


@interface MyClass : A
- Inst;
+ Clas;
@end

struct CGRect {
float origin;
float size;
};
typedef struct CGRect NSRect;

@interface I
- (void) Meth : (NSRect[4])exposedRects;
- (void) Meth1 : (const I*)exposedRects;
- (void) Meth2 : (const I*)exposedRects;
- (void) Meth3 : (I*)exposedRects;
- (const I*) Meth4;
- (const I*) Meth5 : (int) Arg1 : (const I*)Arg2 : (double)Arg3 : (const I*) Arg4 :(const volatile id) Arg5;
- (volatile const I*) Meth6 : (const char *)Arg1 : (const char *)Arg2 : (double)Arg3 : (const I*) Arg4 :(const volatile id) Arg5;
@end

@class NSURL, NSArray, NSError;
@interface INTF_BLOCKS
+ (void)getNonLocalVersionsOfItemAtURL:(NSURL *)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+ (void *)getNonLocalVersionsOfItemAtURL2:(NSURL *)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+ (NSError **)getNonLocalVersionsOfItemAtURL3:(int)url completionHandler:(void (^)(NSArray *nonLocalFileVersions, NSError *error))completionHandler;
+ (id)getNonLocalVersionsOfItemAtURL4:(NSURL *)url completionHandler:(void (^)(int nonLocalFileVersions, NSError *error, NSURL*))completionHandler;
@end

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module SomeKit {
umbrella header "SomeKit.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module SomeKit.Private {
header "SomeKit_Private.h"
export *

explicit module NullAnnotation {
header "SomeKit_PrivateForNullAnnotation.h"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
explicit framework module SomeKit.Private {
header "SomeKit_Private.h"
explicit NullAnnotation { header "SomeKit_PrivateForNullAnnotation.h" }
export *
module * { export * }
syntax error

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#ifndef SOMEKIT_PRIVATE_H
#define SOMEKIT_PRIVATE_H

#import <SomeKit/SomeKit.h>

@interface A(Private)
-(A*)privateTransform:(A*)input;

@property (nonatomic) A* internalProperty;
@end

@protocol InternalProtocol
@end

#endif

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef SOMEKIT_PRIVATE_H
#define SOMEKIT_PRIVATE_H

#import <SomeKit/SomeKitForNullAnnotation.h>

@interface A(Private)
-(A*)privateTransform:(A*)input;

@property (nonatomic) A* internalProperty;
@end

@protocol InternalProtocol
- (id) MomeMethod;
@end

#endif

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Name: SomeKit
Classes:
- Name: A
Methods:
- Selector: "privateTransform:input:"
MethodKind: Instance
NullabilityOfRet: N
Nullability: [ N, S ]
Properties:
- Name: internalProperty
Nullability: N
Protocols:
- Name: InternalProtocol
Availability: none
AvailabilityMsg: "not for you"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Name: SomeOtherKit
Classes:
- Name: A
Methods:
- Selector: "methodA"
MethodKind: Instance
Availability: none
AvailabilityMsg: "anything but this"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Name: SomeOtherKit
Classes:
- Name: A
Methods:
- Selector: "methodA"
MethodKind: Instance
Availability: none
AvailabilityMsg: "anything but this"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#ifndef SOME_OTHER_KIT_H

__attribute__((objc_root_class))
@interface A
-(void)methodA;
-(void)methodB;
@end

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module SomeOtherKit {
umbrella header "SomeOtherKit.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int TopLevelPrivateKit_Public;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
garbage here because this file shouldn't get read
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module TopLevelPrivateKit {
umbrella header "TopLevelPrivateKit.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module TopLevelPrivateKit_Private {
umbrella header "TopLevelPrivateKit_Private.h"
export *
module * { export * }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
garbage here because this file shouldn't get read
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Name: TopLevelPrivateKit_Private
Globals:
- Name: TopLevelPrivateKit_Private
Type: float
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int TopLevelPrivateKit_Private;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
garbage here because this file shouldn't get read
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
Name: VersionedKit
Classes:
- Name: TestProperties
SwiftObjCMembers: true
Properties:
- Name: accessorsOnly
PropertyKind: Instance
SwiftImportAsAccessors: true
- Name: accessorsOnlyForClass
PropertyKind: Class
SwiftImportAsAccessors: true
- Name: accessorsOnlyExceptInVersion3
PropertyKind: Instance
SwiftImportAsAccessors: true
- Name: accessorsOnlyForClassExceptInVersion3
PropertyKind: Class
SwiftImportAsAccessors: true
Functions:
- Name: unversionedRenameDUMP
SwiftName: 'unversionedRename_NOTES()'
Tags:
- Name: APINotedFlagEnum
FlagEnum: true
- Name: APINotedOpenEnum
EnumExtensibility: open
- Name: APINotedClosedEnum
EnumExtensibility: closed
- Name: SoonToBeCFEnum
EnumKind: CFEnum
- Name: SoonToBeNSEnum
EnumKind: NSEnum
- Name: SoonToBeCFOptions
EnumKind: CFOptions
- Name: SoonToBeNSOptions
EnumKind: NSOptions
- Name: SoonToBeCFClosedEnum
EnumKind: CFClosedEnum
- Name: SoonToBeNSClosedEnum
EnumKind: NSClosedEnum
- Name: UndoAllThatHasBeenDoneToMe
EnumKind: none
Typedefs:
- Name: MultiVersionedTypedef34Notes
SwiftName: MultiVersionedTypedef34Notes_NEW
- Name: MultiVersionedTypedef345Notes
SwiftName: MultiVersionedTypedef345Notes_NEW
- Name: MultiVersionedTypedef4Notes
SwiftName: MultiVersionedTypedef4Notes_NEW
- Name: MultiVersionedTypedef45Notes
SwiftName: MultiVersionedTypedef45Notes_NEW
SwiftVersions:
- Version: 3.0
Classes:
- Name: MyReferenceType
SwiftBridge: ''
- Name: TestGenericDUMP
SwiftImportAsNonGeneric: true
- Name: TestProperties
SwiftObjCMembers: false
Properties:
- Name: accessorsOnlyInVersion3
PropertyKind: Instance
SwiftImportAsAccessors: true
- Name: accessorsOnlyForClassInVersion3
PropertyKind: Class
SwiftImportAsAccessors: true
- Name: accessorsOnlyExceptInVersion3
PropertyKind: Instance
SwiftImportAsAccessors: false
- Name: accessorsOnlyForClassExceptInVersion3
PropertyKind: Class
SwiftImportAsAccessors: false
- Name: Swift3RenamedOnlyDUMP
SwiftName: SpecialSwift3Name
- Name: Swift3RenamedAlsoDUMP
SwiftName: SpecialSwift3Also
Functions:
- Name: moveToPointDUMP
SwiftName: 'moveTo(a:b:)'
- Name: acceptClosure
Parameters:
- Position: 0
NoEscape: false
- Name: privateFunc
SwiftPrivate: false
Tags:
- Name: MyErrorCode
NSErrorDomain: ''
- Name: NewlyFlagEnum
FlagEnum: false
- Name: OpenToClosedEnum
EnumExtensibility: open
- Name: ClosedToOpenEnum
EnumExtensibility: closed
- Name: NewlyClosedEnum
EnumExtensibility: none
- Name: NewlyOpenEnum
EnumExtensibility: none
Typedefs:
- Name: MyDoubleWrapper
SwiftWrapper: none
- Name: MultiVersionedTypedef34
SwiftName: MultiVersionedTypedef34_3
- Name: MultiVersionedTypedef34Header
SwiftName: MultiVersionedTypedef34Header_3
- Name: MultiVersionedTypedef34Notes
SwiftName: MultiVersionedTypedef34Notes_3
- Name: MultiVersionedTypedef345
SwiftName: MultiVersionedTypedef345_3
- Name: MultiVersionedTypedef345Header
SwiftName: MultiVersionedTypedef345Header_3
- Name: MultiVersionedTypedef345Notes
SwiftName: MultiVersionedTypedef345Notes_3
- Version: 5
Typedefs:
- Name: MultiVersionedTypedef345
SwiftName: MultiVersionedTypedef345_5
- Name: MultiVersionedTypedef345Header
SwiftName: MultiVersionedTypedef345Header_5
- Name: MultiVersionedTypedef345Notes
SwiftName: MultiVersionedTypedef345Notes_5
- Name: MultiVersionedTypedef45
SwiftName: MultiVersionedTypedef45_5
- Name: MultiVersionedTypedef45Header
SwiftName: MultiVersionedTypedef45Header_5
- Name: MultiVersionedTypedef45Notes
SwiftName: MultiVersionedTypedef45Notes_5
- Version: 4 # Versions are deliberately ordered as "3, 5, 4" to catch bugs.
Classes:
- Name: Swift4RenamedDUMP
SwiftName: SpecialSwift4Name
Typedefs:
- Name: MultiVersionedTypedef34
SwiftName: MultiVersionedTypedef34_4
- Name: MultiVersionedTypedef34Header
SwiftName: MultiVersionedTypedef34Header_4
- Name: MultiVersionedTypedef34Notes
SwiftName: MultiVersionedTypedef34Notes_4
- Name: MultiVersionedTypedef345
SwiftName: MultiVersionedTypedef345_4
- Name: MultiVersionedTypedef345Header
SwiftName: MultiVersionedTypedef345Header_4
- Name: MultiVersionedTypedef345Notes
SwiftName: MultiVersionedTypedef345Notes_4
- Name: MultiVersionedTypedef4
SwiftName: MultiVersionedTypedef4_4
- Name: MultiVersionedTypedef4Header
SwiftName: MultiVersionedTypedef4Header_4
- Name: MultiVersionedTypedef4Notes
SwiftName: MultiVersionedTypedef4Notes_4
- Name: MultiVersionedTypedef45
SwiftName: MultiVersionedTypedef45_4
- Name: MultiVersionedTypedef45Header
SwiftName: MultiVersionedTypedef45Header_4
- Name: MultiVersionedTypedef45Notes
SwiftName: MultiVersionedTypedef45Notes_4
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
void moveToPointDUMP(double x, double y) __attribute__((swift_name("moveTo(x:y:)")));

void unversionedRenameDUMP(void) __attribute__((swift_name("unversionedRename_HEADER()")));

void acceptClosure(void (^ __attribute__((noescape)) block)(void));

void privateFunc(void) __attribute__((swift_private));

typedef double MyDoubleWrapper __attribute__((swift_wrapper(struct)));

#if __OBJC__
@class NSString;

extern NSString *MyErrorDomain;

enum __attribute__((ns_error_domain(MyErrorDomain))) MyErrorCode {
MyErrorCodeFailed = 1
};

__attribute__((swift_bridge("MyValueType")))
@interface MyReferenceType
@end

@interface TestProperties
@property (nonatomic, readwrite, retain) id accessorsOnly;
@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClass;

@property (nonatomic, readwrite, retain) id accessorsOnlyInVersion3;
@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClassInVersion3;

@property (nonatomic, readwrite, retain) id accessorsOnlyExceptInVersion3;
@property (nonatomic, readwrite, retain, class) id accessorsOnlyForClassExceptInVersion3;
@end

@interface Base
@end

@interface TestGenericDUMP<Element> : Base
- (Element)element;
@end

@interface Swift3RenamedOnlyDUMP
@end

__attribute__((swift_name("Swift4Name")))
@interface Swift3RenamedAlsoDUMP
@end

@interface Swift4RenamedDUMP
@end

#endif


enum __attribute__((flag_enum)) FlagEnum {
FlagEnumA = 1,
FlagEnumB = 2
};

enum __attribute__((flag_enum)) NewlyFlagEnum {
NewlyFlagEnumA = 1,
NewlyFlagEnumB = 2
};

enum APINotedFlagEnum {
APINotedFlagEnumA = 1,
APINotedFlagEnumB = 2
};


enum __attribute__((enum_extensibility(open))) OpenEnum {
OpenEnumA = 1,
};

enum __attribute__((enum_extensibility(open))) NewlyOpenEnum {
NewlyOpenEnumA = 1,
};

enum __attribute__((enum_extensibility(closed))) NewlyClosedEnum {
NewlyClosedEnumA = 1,
};

enum __attribute__((enum_extensibility(open))) ClosedToOpenEnum {
ClosedToOpenEnumA = 1,
};

enum __attribute__((enum_extensibility(closed))) OpenToClosedEnum {
OpenToClosedEnumA = 1,
};

enum APINotedOpenEnum {
APINotedOpenEnumA = 1,
};

enum APINotedClosedEnum {
APINotedClosedEnumA = 1,
};


enum SoonToBeCFEnum {
SoonToBeCFEnumA = 1
};
enum SoonToBeNSEnum {
SoonToBeNSEnumA = 1
};
enum SoonToBeCFOptions {
SoonToBeCFOptionsA = 1
};
enum SoonToBeNSOptions {
SoonToBeNSOptionsA = 1
};
enum SoonToBeCFClosedEnum {
SoonToBeCFClosedEnumA = 1
};
enum SoonToBeNSClosedEnum {
SoonToBeNSClosedEnumA = 1
};
enum UndoAllThatHasBeenDoneToMe {
UndoAllThatHasBeenDoneToMeA = 1
} __attribute__((flag_enum)) __attribute__((enum_extensibility(closed)));


typedef int MultiVersionedTypedef4;
typedef int MultiVersionedTypedef4Notes;
typedef int MultiVersionedTypedef4Header __attribute__((swift_name("MultiVersionedTypedef4Header_NEW")));

typedef int MultiVersionedTypedef34;
typedef int MultiVersionedTypedef34Notes;
typedef int MultiVersionedTypedef34Header __attribute__((swift_name("MultiVersionedTypedef34Header_NEW")));

typedef int MultiVersionedTypedef45;
typedef int MultiVersionedTypedef45Notes;
typedef int MultiVersionedTypedef45Header __attribute__((swift_name("MultiVersionedTypedef45Header_NEW")));

typedef int MultiVersionedTypedef345;
typedef int MultiVersionedTypedef345Notes;
typedef int MultiVersionedTypedef345Header __attribute__((swift_name("MultiVersionedTypedef345Header_NEW")));
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
framework module VersionedKit {
umbrella header "VersionedKit.h"
export *
module * { export * }
}
18 changes: 18 additions & 0 deletions clang/test/APINotes/Inputs/Headers/APINotes.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Name: HeaderLib
SwiftInferImportAsMember: true
Functions:
- Name: custom_realloc
NullabilityOfRet: N
Nullability: [ N, S ]
- Name: unavailable_function
Availability: none
AvailabilityMsg: "I beg you not to use this"
- Name: do_something_with_pointers
NullabilityOfRet: O
Nullability: [ N, O ]

Globals:
- Name: global_int
Nullability: N
- Name: unavailable_global_int
Availability: none
10 changes: 10 additions & 0 deletions clang/test/APINotes/Inputs/Headers/BrokenTypes.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Name: BrokenTypes
Functions:
- Name: break_me_function
ResultType: 'int * with extra junk'
Parameters:
- Position: 0
Type: 'not_a_type'
Globals:
- Name: break_me_variable
Type: 'double'
8 changes: 8 additions & 0 deletions clang/test/APINotes/Inputs/Headers/BrokenTypes.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#ifndef BROKEN_TYPES_H
#define BROKEN_TYPES_H

char break_me_function(void *ptr);

extern char break_me_variable;

#endif // BROKEN_TYPES_H
15 changes: 15 additions & 0 deletions clang/test/APINotes/Inputs/Headers/ExternCtx.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
Name: ExternCtx
Globals:
- Name: globalInExternC
Availability: none
AvailabilityMsg: "oh no"
- Name: globalInExternCXX
Availability: none
AvailabilityMsg: "oh no #2"
Functions:
- Name: globalFuncInExternC
Availability: none
AvailabilityMsg: "oh no #3"
- Name: globalFuncInExternCXX
Availability: none
AvailabilityMsg: "oh no #4"
11 changes: 11 additions & 0 deletions clang/test/APINotes/Inputs/Headers/ExternCtx.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
extern "C" {
static int globalInExternC = 1;

static void globalFuncInExternC() {}
}

extern "C++" {
static int globalInExternCXX = 2;

static void globalFuncInExternCXX() {}
}
37 changes: 37 additions & 0 deletions clang/test/APINotes/Inputs/Headers/HeaderLib.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
Name: HeaderLib
SwiftInferImportAsMember: true
Functions:
- Name: custom_realloc
NullabilityOfRet: N
Nullability: [ N, S ]
- Name: unavailable_function
Availability: none
AvailabilityMsg: "I beg you not to use this"
- Name: do_something_with_pointers
NullabilityOfRet: O
Nullability: [ N, O ]
- Name: do_something_with_arrays
Parameters:
- Position: 0
Nullability: N
- Position: 1
Nullability: N
- Name: take_pointer_and_int
Parameters:
- Position: 0
Nullability: N
NoEscape: true
- Position: 1
NoEscape: true
Globals:
- Name: global_int
Nullability: N
- Name: unavailable_global_int
Availability: none
Tags:
- Name: unavailable_struct
Availability: none

Typedefs:
- Name: unavailable_typedef
Availability: none
19 changes: 19 additions & 0 deletions clang/test/APINotes/Inputs/Headers/HeaderLib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef HEADER_LIB_H
#define HEADER_LIB_H

void *custom_realloc(void *member, unsigned size);

int *global_int;

int unavailable_function(void);
int unavailable_global_int;

void do_something_with_pointers(int *ptr1, int *ptr2);
void do_something_with_arrays(int simple[], int nested[][2]);

typedef int unavailable_typedef;
struct unavailable_struct { int x, y, z; };

void take_pointer_and_int(int *ptr1, int value);

#endif
10 changes: 10 additions & 0 deletions clang/test/APINotes/Inputs/Headers/InstancetypeModule.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Name: InstancetypeModule
Classes:
- Name: SomeBaseClass
Methods:
- Selector: instancetypeFactoryMethod
MethodKind: Class
ResultType: SomeBaseClass * _Nonnull
- Selector: staticFactoryMethod
MethodKind: Class
ResultType: SomeBaseClass * _Nonnull
10 changes: 10 additions & 0 deletions clang/test/APINotes/Inputs/Headers/InstancetypeModule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@interface Object
@end

@interface SomeBaseClass : Object
+ (nullable instancetype)instancetypeFactoryMethod;
+ (nullable SomeBaseClass *)staticFactoryMethod;
@end

@interface SomeSubclass : SomeBaseClass
@end
1 change: 1 addition & 0 deletions clang/test/APINotes/Inputs/Headers/ModuleWithWrongCase.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int ModuleWithWrongCase;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int ModuleWithWrongCasePrivate;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Name: ModuleWithWrongCasePrivate
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Name: ModuleWithWrongCasePrivate
53 changes: 53 additions & 0 deletions clang/test/APINotes/Inputs/Headers/Namespaces.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
Name: Namespaces
Globals:
- Name: varInInlineNamespace
SwiftName: swiftVarInInlineNamespace
Functions:
- Name: funcInNamespace
SwiftName: inWrongContext()
- Name: funcInInlineNamespace
SwiftName: swiftFuncInInlineNamespace()
Tags:
- Name: char_box
SwiftName: InWrongContext
Namespaces:
- Name: Namespace1
Typedefs:
- Name: my_typedef
SwiftName: SwiftTypedef
- Name: my_using_decl
SwiftName: SwiftUsingDecl
Globals:
- Name: varInNamespace
SwiftName: swiftVarInNamespace
Functions:
- Name: funcInNamespace
SwiftName: swiftFuncInNamespace()
Tags:
- Name: char_box
SwiftName: CharBox
Namespaces:
- Name: Nested1
Globals:
- Name: varInNestedNamespace
SwiftName: swiftVarInNestedNamespace
Functions:
- Name: funcInNestedNamespace
SwiftName: swiftFuncInNestedNamespace(_:)
Tags:
- Name: char_box
SwiftName: NestedCharBox
Namespaces:
- Name: Namespace1
Tags:
- Name: char_box
SwiftName: DeepNestedCharBox
- Name: Nested2
Globals:
- Name: varInNestedNamespace
SwiftName: swiftAnotherVarInNestedNamespace
- Name: InlineNamespace1
Functions:
- Name: funcInInlineNamespace
SwiftName: shouldNotSpellOutInlineNamespaces()
Loading