108 changes: 42 additions & 66 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 @@ -5541,6 +5541,14 @@ bool CheckNoDoubleVectors(Sema *S, CallExpr *TheCall) {
checkDoubleVector);
}

bool CheckUnsignedIntRepresentation(Sema *S, CallExpr *TheCall) {
auto checkAllUnsignedTypes = [](clang::QualType PassedType) -> bool {
return !PassedType->hasUnsignedIntegerRepresentation();
};
return CheckArgsTypesAreCorrect(S, TheCall, S->Context.UnsignedIntTy,
checkAllUnsignedTypes);
}

void SetElementTypeAsReturnType(Sema *S, CallExpr *TheCall,
QualType ReturnType) {
auto *VecTyA = TheCall->getArg(0)->getType()->getAs<VectorType>();
Expand Down Expand Up @@ -5624,6 +5632,26 @@ 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_bitreverse: {
if (CheckUnsignedIntRepresentation(this, TheCall))
return true;
break;
}
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 @@ -5745,57 +5773,6 @@ static bool CheckInvalidVLENandLMUL(const TargetInfo &TI, CallExpr *TheCall,
bool Sema::CheckRISCVBuiltinFunctionCall(const TargetInfo &TI,
unsigned BuiltinID,
CallExpr *TheCall) {
// CodeGenFunction can also detect this, but this gives a better error
// message.
bool FeatureMissing = false;
SmallVector<StringRef> ReqFeatures;
StringRef Features = Context.BuiltinInfo.getRequiredFeatures(BuiltinID);
Features.split(ReqFeatures, ',', -1, false);

// Check if each required feature is included
for (StringRef F : ReqFeatures) {
SmallVector<StringRef> ReqOpFeatures;
F.split(ReqOpFeatures, '|');

if (llvm::none_of(ReqOpFeatures,
[&TI](StringRef OF) { return TI.hasFeature(OF); })) {
std::string FeatureStrs;
bool IsExtension = true;
for (StringRef OF : ReqOpFeatures) {
// If the feature is 64bit, alter the string so it will print better in
// the diagnostic.
if (OF == "64bit") {
assert(ReqOpFeatures.size() == 1 && "Expected '64bit' to be alone");
OF = "RV64";
IsExtension = false;
}
if (OF == "32bit") {
assert(ReqOpFeatures.size() == 1 && "Expected '32bit' to be alone");
OF = "RV32";
IsExtension = false;
}

// Convert features like "zbr" and "experimental-zbr" to "Zbr".
OF.consume_front("experimental-");
std::string FeatureStr = OF.str();
FeatureStr[0] = std::toupper(FeatureStr[0]);
// Combine strings.
FeatureStrs += FeatureStrs.empty() ? "" : ", ";
FeatureStrs += "'";
FeatureStrs += FeatureStr;
FeatureStrs += "'";
}
// Error message
FeatureMissing = true;
Diag(TheCall->getBeginLoc(), diag::err_riscv_builtin_requires_extension)
<< IsExtension
<< TheCall->getSourceRange() << StringRef(FeatureStrs);
}
}

if (FeatureMissing)
return true;

// vmulh.vv, vmulh.vx, vmulhu.vv, vmulhu.vx, vmulhsu.vv, vmulhsu.vx,
// vsmul.vv, vsmul.vx are not included for EEW=64 in Zve64*.
switch (BuiltinID) {
Expand Down Expand Up @@ -6699,36 +6676,35 @@ bool Sema::CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI,
return false;
}

void Sema::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D) {
const TargetInfo &TI = Context.getTargetInfo();

void Sema::checkRVVTypeSupport(QualType Ty, SourceLocation Loc, Decl *D,
const llvm::StringMap<bool> &FeatureMap) {
ASTContext::BuiltinVectorTypeInfo Info =
Context.getBuiltinVectorTypeInfo(Ty->castAs<BuiltinType>());
unsigned EltSize = Context.getTypeSize(Info.ElementType);
unsigned MinElts = Info.EC.getKnownMinValue();

if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Double) &&
!TI.hasFeature("zve64d"))
!FeatureMap.lookup("zve64d"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64d";
// (ELEN, LMUL) pairs of (8, mf8), (16, mf4), (32, mf2), (64, m1) requires at
// least zve64x
else if (((EltSize == 64 && Info.ElementType->isIntegerType()) ||
MinElts == 1) &&
!TI.hasFeature("zve64x"))
!FeatureMap.lookup("zve64x"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve64x";
else if (Info.ElementType->isFloat16Type() && !TI.hasFeature("zvfh") &&
!TI.hasFeature("zvfhmin"))
else if (Info.ElementType->isFloat16Type() && !FeatureMap.lookup("zvfh") &&
!FeatureMap.lookup("zvfhmin"))
Diag(Loc, diag::err_riscv_type_requires_extension, D)
<< Ty << "zvfh or zvfhmin";
else if (Info.ElementType->isBFloat16Type() &&
!TI.hasFeature("experimental-zvfbfmin"))
!FeatureMap.lookup("experimental-zvfbfmin"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zvfbfmin";
else if (Info.ElementType->isSpecificBuiltinType(BuiltinType::Float) &&
!TI.hasFeature("zve32f"))
!FeatureMap.lookup("zve32f"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32f";
// Given that caller already checked isRVVType() before calling this function,
// if we don't have at least zve32x supported, then we need to emit error.
else if (!TI.hasFeature("zve32x"))
else if (!FeatureMap.lookup("zve32x"))
Diag(Loc, diag::err_riscv_type_requires_extension, D) << Ty << "zve32x";
}

Expand Down Expand Up @@ -9694,7 +9670,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 +13005,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 +13065,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 +14028,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
201 changes: 135 additions & 66 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 @@ -8962,8 +8962,13 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
}
}

if (T->isRVVSizelessBuiltinType())
checkRVVTypeSupport(T, NewVD->getLocation(), cast<Decl>(CurContext));
if (T->isRVVSizelessBuiltinType() && isa<FunctionDecl>(CurContext)) {
const FunctionDecl *FD = cast<FunctionDecl>(CurContext);
llvm::StringMap<bool> CallerFeatureMap;
Context.getFunctionFeatureMap(CallerFeatureMap, FD);
checkRVVTypeSupport(T, NewVD->getLocation(), cast<Decl>(CurContext),
CallerFeatureMap);
}
}

/// Perform semantic checking on a newly-created variable
Expand Down Expand Up @@ -11260,11 +11265,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 @@ -11469,6 +11476,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 +11502,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 +11603,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 +11685,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 +11712,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 +11982,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: 7 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5271,6 +5271,9 @@ static void handleCallConvAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
case ParsedAttr::AT_PreserveNone:
D->addAttr(::new (S.Context) PreserveNoneAttr(S.Context, AL));
return;
case ParsedAttr::AT_RISCVVectorCC:
D->addAttr(::new (S.Context) RISCVVectorCCAttr(S.Context, AL));
return;
default:
llvm_unreachable("unexpected attribute kind");
}
Expand Down Expand Up @@ -5475,6 +5478,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
case ParsedAttr::AT_PreserveNone:
CC = CC_PreserveNone;
break;
case ParsedAttr::AT_RISCVVectorCC:
CC = CC_RISCVVectorCall;
break;
default: llvm_unreachable("unexpected attribute kind");
}

Expand Down Expand Up @@ -9637,6 +9643,7 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_AMDGPUKernelCall:
case ParsedAttr::AT_M68kRTD:
case ParsedAttr::AT_PreserveNone:
case ParsedAttr::AT_RISCVVectorCC:
handleCallConvAttr(S, D, AL);
break;
case ParsedAttr::AT_Suppress:
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
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
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ static void diagnoseBadTypeAttribute(Sema &S, const ParsedAttr &attr,
case ParsedAttr::AT_PreserveMost: \
case ParsedAttr::AT_PreserveAll: \
case ParsedAttr::AT_M68kRTD: \
case ParsedAttr::AT_PreserveNone
case ParsedAttr::AT_PreserveNone: \
case ParsedAttr::AT_RISCVVectorCC

// Function type attributes.
#define FUNCTION_TYPE_ATTRS_CASELIST \
Expand Down Expand Up @@ -7939,6 +7940,8 @@ static Attr *getCCTypeAttr(ASTContext &Ctx, ParsedAttr &Attr) {
return createSimpleAttr<M68kRTDAttr>(Ctx, Attr);
case ParsedAttr::AT_PreserveNone:
return createSimpleAttr<PreserveNoneAttr>(Ctx, Attr);
case ParsedAttr::AT_RISCVVectorCC:
return createSimpleAttr<RISCVVectorCCAttr>(Ctx, Attr);
}
llvm_unreachable("unexpected attribute kind!");
}
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
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
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
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()
39 changes: 39 additions & 0 deletions clang/test/APINotes/Inputs/Headers/Namespaces.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
namespace Namespace1 { namespace Nested1 {} }

namespace Namespace1 {
static int varInNamespace = 1;
struct char_box { char c; };
void funcInNamespace();

namespace Nested1 {
void funcInNestedNamespace(int i);
struct char_box {
char c;
};
}

namespace Nested1 {
static int varInNestedNamespace = 1;
void funcInNestedNamespace(int i);

namespace Namespace1 {
struct char_box { char c; };
} // namespace Namespace1
} // namespace Nested1

namespace Nested2 {
static int varInNestedNamespace = 2;
} // namespace Nested2

namespace Nested1 { namespace Namespace1 {} }
} // namespace Namespace1

namespace Namespace1 {
typedef int my_typedef;
using my_using_decl = int;
}

inline namespace InlineNamespace1 {
static int varInInlineNamespace = 3;
void funcInInlineNamespace();
}
4 changes: 4 additions & 0 deletions clang/test/APINotes/Inputs/Headers/PrivateLib.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Name: HeaderLib
Globals:
- Name: PrivateLib
Type: float
1 change: 1 addition & 0 deletions clang/test/APINotes/Inputs/Headers/PrivateLib.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int PrivateLib;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
garbage here because this file shouldn't get read
9 changes: 9 additions & 0 deletions clang/test/APINotes/Inputs/Headers/SwiftImportAs.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
Name: SwiftImportAs
Tags:
- Name: ImmortalRefType
SwiftImportAs: reference
- Name: RefCountedType
SwiftImportAs: reference
SwiftReleaseOp: RCRelease
SwiftRetainOp: RCRetain
6 changes: 6 additions & 0 deletions clang/test/APINotes/Inputs/Headers/SwiftImportAs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
struct ImmortalRefType {};

struct RefCountedType { int value; };

inline void RCRetain(RefCountedType *x) { x->value++; }
inline void RCRelease(RefCountedType *x) { x->value--; }
31 changes: 31 additions & 0 deletions clang/test/APINotes/Inputs/Headers/module.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module ExternCtx {
header "ExternCtx.h"
}

module HeaderLib {
header "HeaderLib.h"
}

module InstancetypeModule {
header "InstancetypeModule.h"
}

module BrokenTypes {
header "BrokenTypes.h"
}

module ModuleWithWrongCase {
header "ModuleWithWrongCase.h"
}

module ModuleWithWrongCasePrivate {
header "ModuleWithWrongCasePrivate.h"
}

module Namespaces {
header "Namespaces.h"
}

module SwiftImportAs {
header "SwiftImportAs.h"
}
5 changes: 5 additions & 0 deletions clang/test/APINotes/Inputs/Headers/module.private.modulemap
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module PrivateLib {
header "PrivateLib.h"
}

module ModuleWithWrongCasePrivate.Inner {}
65 changes: 65 additions & 0 deletions clang/test/APINotes/Inputs/yaml-reader-errors/UIKit.apinotes
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
Name: UIKit
Classes:
- Name: UIFont
Methods:
- Selector: 'fontWithName:size:'
MethodKind: Instance
Nullability: [ N ]
NullabilityOfRet: O
DesignatedInit: true
# CHECK: duplicate definition of method '-[UIFont fontWithName:size:]'
- Selector: 'fontWithName:size:'
MethodKind: Instance
Nullability: [ N ]
NullabilityOfRet: O
DesignatedInit: true
Properties:
- Name: familyName
Nullability: N
- Name: fontName
Nullability: N
# CHECK: duplicate definition of instance property 'UIFont.familyName'
- Name: familyName
Nullability: N
# CHECK: multiple definitions of class 'UIFont'
- Name: UIFont
Protocols:
- Name: MyProto
AuditedForNullability: true
# CHECK: multiple definitions of protocol 'MyProto'
- Name: MyProto
AuditedForNullability: true
Functions:
- Name: 'globalFoo'
Nullability: [ N, N, O, S ]
NullabilityOfRet: O
- Name: 'globalFoo2'
Nullability: [ N, N, O, S ]
NullabilityOfRet: O
Globals:
- Name: globalVar
Nullability: O
- Name: globalVar2
Nullability: O
Tags:
# CHECK: cannot mix EnumKind and FlagEnum (for FlagAndEnumKind)
- Name: FlagAndEnumKind
FlagEnum: true
EnumKind: CFOptions
# CHECK: cannot mix EnumKind and FlagEnum (for FlagAndEnumKind2)
- Name: FlagAndEnumKind2
EnumKind: CFOptions
FlagEnum: false
# CHECK: cannot mix EnumKind and EnumExtensibility (for ExtensibilityAndEnumKind)
- Name: ExtensibilityAndEnumKind
EnumExtensibility: open
EnumKind: CFOptions
# CHECK: cannot mix EnumKind and EnumExtensibility (for ExtensibilityAndEnumKind2)
- Name: ExtensibilityAndEnumKind2
EnumKind: CFOptions
EnumExtensibility: closed
# CHECK: cannot mix EnumKind and EnumExtensibility (for ExtensibilityAndEnumKind3)
- Name: ExtensibilityAndEnumKind3
EnumKind: none
EnumExtensibility: none
1 change: 1 addition & 0 deletions clang/test/APINotes/Inputs/yaml-reader-errors/UIKit.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
extern int yesOfCourseThisIsWhatUIKitLooksLike;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module UIKit {
header "UIKit.h"
}
48 changes: 48 additions & 0 deletions clang/test/APINotes/availability.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// RUN: rm -rf %t
// RUN: %clang_cc1 -fmodules -Wno-private-module -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify

#include "HeaderLib.h"
#import <SomeKit/SomeKit.h>
#import <SomeKit/SomeKit_Private.h>

int main() {
int i;
i = unavailable_function(); // expected-error{{'unavailable_function' is unavailable: I beg you not to use this}}
// expected-note@HeaderLib.h:8{{'unavailable_function' has been explicitly marked unavailable here}}
i = unavailable_global_int; // expected-error{{'unavailable_global_int' is unavailable}}
// expected-note@HeaderLib.h:9{{'unavailable_global_int' has been explicitly marked unavailable here}}

unavailable_typedef t; // expected-error{{'unavailable_typedef' is unavailable}}
// expected-note@HeaderLib.h:14{{'unavailable_typedef' has been explicitly marked unavailable here}}

struct unavailable_struct s; // expected-error{{'unavailable_struct' is unavailable}}
// expected-note@HeaderLib.h:15{{'unavailable_struct' has been explicitly marked unavailable here}}

B *b = 0; // expected-error{{'B' is unavailable: just don't}}
// expected-note@SomeKit/SomeKit.h:15{{'B' has been explicitly marked unavailable here}}

id<InternalProtocol> proto = 0; // expected-error{{'InternalProtocol' is unavailable: not for you}}
// expected-note@SomeKit/SomeKit_Private.h:12{{'InternalProtocol' has been explicitly marked unavailable here}}

A *a = 0;
i = a.intValue; // expected-error{{intValue' is unavailable: wouldn't work anyway}}
// expected-note@SomeKit/SomeKit.h:12{{'intValue' has been explicitly marked unavailable here}}

[a transform:a]; // expected-error{{'transform:' is unavailable: anything but this}}
// expected-note@SomeKit/SomeKit.h:6{{'transform:' has been explicitly marked unavailable here}}

[a implicitGetOnlyInstance]; // expected-error{{'implicitGetOnlyInstance' is unavailable: getter gone}}
// expected-note@SomeKit/SomeKit.h:53{{'implicitGetOnlyInstance' has been explicitly marked unavailable here}}
[A implicitGetOnlyClass]; // expected-error{{'implicitGetOnlyClass' is unavailable: getter gone}}
// expected-note@SomeKit/SomeKit.h:54{{'implicitGetOnlyClass' has been explicitly marked unavailable here}}
[a implicitGetSetInstance]; // expected-error{{'implicitGetSetInstance' is unavailable: getter gone}}
// expected-note@SomeKit/SomeKit.h:56{{'implicitGetSetInstance' has been explicitly marked unavailable here}}
[a setImplicitGetSetInstance: a]; // expected-error{{'setImplicitGetSetInstance:' is unavailable: setter gone}}
// expected-note@SomeKit/SomeKit.h:56{{'setImplicitGetSetInstance:' has been explicitly marked unavailable here}}
[A implicitGetSetClass]; // expected-error{{'implicitGetSetClass' is unavailable: getter gone}}
// expected-note@SomeKit/SomeKit.h:57{{'implicitGetSetClass' has been explicitly marked unavailable here}}
[A setImplicitGetSetClass: a]; // expected-error{{'setImplicitGetSetClass:' is unavailable: setter gone}}
// expected-note@SomeKit/SomeKit.h:57{{'setImplicitGetSetClass:' has been explicitly marked unavailable here}}
return 0;
}

19 changes: 19 additions & 0 deletions clang/test/APINotes/broken_types.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s 2> %t.err
// RUN: FileCheck %s < %t.err

#include "BrokenTypes.h"

// CHECK: <API Notes>:1:1: error: unknown type name 'not_a_type'
// CHECK-NEXT: not_a_type
// CHECK-NEXT: ^

// CHECK: <API Notes>:1:7: error: unparsed tokens following type
// CHECK-NEXT: int * with extra junk
// CHECK-NEXT: ^

// CHECK: BrokenTypes.h:4:6: error: API notes replacement type 'int *' has a different size from original type 'char'

// CHECK: BrokenTypes.h:6:13: error: API notes replacement type 'double' has a different size from original type 'char'

// CHECK: 5 errors generated.
22 changes: 22 additions & 0 deletions clang/test/APINotes/case-for-private-apinotes-file.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// REQUIRES: case-insensitive-filesystem

// RUN: rm -rf %t
// RUN: %clang_cc1 -fsyntax-only -fmodules -fapinotes-modules -fimplicit-module-maps -fmodules-cache-path=%t -F %S/Inputs/Frameworks -I %S/Inputs/Headers %s 2>&1 | FileCheck %s

// RUN: rm -rf %t
// RUN: %clang_cc1 -fsyntax-only -fmodules -fapinotes-modules -fimplicit-module-maps -fmodules-cache-path=%t -iframework %S/Inputs/Frameworks -isystem %S/Inputs/Headers %s -Werror

// RUN: rm -rf %t
// RUN: %clang_cc1 -fsyntax-only -fmodules -fapinotes-modules -fimplicit-module-maps -fmodules-cache-path=%t -iframework %S/Inputs/Frameworks -isystem %S/Inputs/Headers %s -Wnonportable-private-system-apinotes-path 2>&1 | FileCheck %s

#include <ModuleWithWrongCase.h>
#include <ModuleWithWrongCasePrivate.h>
#include <FrameworkWithWrongCase/FrameworkWithWrongCase.h>
#include <FrameworkWithWrongCasePrivate/FrameworkWithWrongCasePrivate.h>
#include <FrameworkWithActualPrivateModule/FrameworkWithActualPrivateModule_Private.h>

// CHECK-NOT: warning:
// CHECK: warning: private API notes file for module 'ModuleWithWrongCasePrivate' should be named 'ModuleWithWrongCasePrivate_private.apinotes', not 'ModuleWithWrongCasePrivate_Private.apinotes'
// CHECK-NOT: warning:
// CHECK: warning: private API notes file for module 'FrameworkWithWrongCasePrivate' should be named 'FrameworkWithWrongCasePrivate_private.apinotes', not 'FrameworkWithWrongCasePrivate_Private.apinotes'
// CHECK-NOT: warning:
23 changes: 23 additions & 0 deletions clang/test/APINotes/extern-context.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter globalInExternC -x c++ | FileCheck -check-prefix=CHECK-EXTERN-C %s
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter globalInExternCXX -x c++ | FileCheck -check-prefix=CHECK-EXTERN-CXX %s
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter globalFuncInExternC -x c++ | FileCheck -check-prefix=CHECK-FUNC-EXTERN-C %s
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -ast-dump -ast-dump-filter globalFuncInExternCXX -x c++ | FileCheck -check-prefix=CHECK-FUNC-EXTERN-CXX %s

#include "ExternCtx.h"

// CHECK-EXTERN-C: Dumping globalInExternC:
// CHECK-EXTERN-C: VarDecl {{.+}} imported in ExternCtx globalInExternC 'int'
// CHECK-EXTERN-C: UnavailableAttr {{.+}} <<invalid sloc>> "oh no"

// CHECK-EXTERN-CXX: Dumping globalInExternCXX:
// CHECK-EXTERN-CXX: VarDecl {{.+}} imported in ExternCtx globalInExternCXX 'int'
// CHECK-EXTERN-CXX: UnavailableAttr {{.+}} <<invalid sloc>> "oh no #2"

// CHECK-FUNC-EXTERN-C: Dumping globalFuncInExternC:
// CHECK-FUNC-EXTERN-C: FunctionDecl {{.+}} imported in ExternCtx globalFuncInExternC 'void ()'
// CHECK-FUNC-EXTERN-C: UnavailableAttr {{.+}} <<invalid sloc>> "oh no #3"

// CHECK-FUNC-EXTERN-CXX: Dumping globalFuncInExternCXX:
// CHECK-FUNC-EXTERN-CXX: FunctionDecl {{.+}} imported in ExternCtx globalFuncInExternCXX 'void ()'
// CHECK-FUNC-EXTERN-CXX: UnavailableAttr {{.+}} <<invalid sloc>> "oh no #4"
9 changes: 9 additions & 0 deletions clang/test/APINotes/instancetype.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -verify %s

@import InstancetypeModule;

void test() {
// The nullability is here to verify that the API notes were applied.
int good = [SomeSubclass instancetypeFactoryMethod]; // expected-error {{initializing 'int' with an expression of type 'SomeSubclass * _Nonnull'}}
int bad = [SomeSubclass staticFactoryMethod]; // expected-error {{initializing 'int' with an expression of type 'SomeBaseClass * _Nonnull'}}
}
65 changes: 65 additions & 0 deletions clang/test/APINotes/module-cache.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// RUN: rm -rf %t

// Set up directories
// RUN: mkdir -p %t/APINotes
// RUN: cp %S/Inputs/APINotes/SomeOtherKit.apinotes %t/APINotes/SomeOtherKit.apinotes
// RUN: mkdir -p %t/Frameworks
// RUN: cp -r %S/Inputs/Frameworks/SomeOtherKit.framework %t/Frameworks

// First build: check that 'methodB' is unavailable but 'methodA' is available.
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -F %t/Frameworks %s > %t/before.log 2>&1
// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/before.log
// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/before.log
// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/before.log

// Do it again; now we're using caches.
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -F %t/Frameworks %s > %t/before.log 2>&1
// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/before.log
// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/before.log
// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/before.log

// Add a blank line to the header to force the module to rebuild, without
// (yet) changing API notes.
// RUN: echo >> %t/Frameworks/SomeOtherKit.framework/Headers/SomeOtherKit.h
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -F %t/Frameworks %s > %t/before.log 2>&1
// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/before.log
// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/before.log
// RUN: FileCheck -check-prefix=CHECK-ONE-ERROR %s < %t/before.log

// Change the API notes file, after the module has rebuilt once.
// RUN: echo ' - Selector: "methodA"' >> %t/APINotes/SomeOtherKit.apinotes
// RUN: echo ' MethodKind: Instance' >> %t/APINotes/SomeOtherKit.apinotes
// RUN: echo ' Availability: none' >> %t/APINotes/SomeOtherKit.apinotes
// RUN: echo ' AvailabilityMsg: "not here either"' >> %t/APINotes/SomeOtherKit.apinotes

// Build again: check that both methods are now unavailable and that the module rebuilt.
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -F %t/Frameworks %s > %t/after.log 2>&1
// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/after.log
// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/after.log
// RUN: FileCheck -check-prefix=CHECK-REBUILD %s < %t/after.log
// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/after.log

// Run the build again: check that both methods are now unavailable
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -Rmodule-build -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %t/APINotes -F %t/Frameworks %s > %t/after.log 2>&1
// RUN: FileCheck -check-prefix=CHECK-METHODA %s < %t/after.log
// RUN: FileCheck -check-prefix=CHECK-METHODB %s < %t/after.log
// RUN: FileCheck -check-prefix=CHECK-WITHOUT-REBUILD %s < %t/after.log
// RUN: FileCheck -check-prefix=CHECK-TWO-ERRORS %s < %t/after.log

@import SomeOtherKit;

void test(A *a) {
// CHECK-METHODA: error: 'methodA' is unavailable: not here either
[a methodA];

// CHECK-METHODB: error: 'methodB' is unavailable: anything but this
[a methodB];
}

// CHECK-REBUILD: remark: building module{{.*}}SomeOtherKit

// CHECK-WITHOUT-REBUILD-NOT: remark: building module{{.*}}SomeOtherKit

// CHECK-ONE-ERROR: 1 error generated.
// CHECK-TWO-ERRORS: 2 errors generated.

69 changes: 69 additions & 0 deletions clang/test/APINotes/namespaces.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -x objective-c++
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::my_typedef -x objective-c++ | FileCheck -check-prefix=CHECK-TYPEDEF-IN-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::my_using_decl -x objective-c++ | FileCheck -check-prefix=CHECK-USING-DECL-IN-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::varInNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-GLOBAL-IN-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::funcInNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-FUNC-IN-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::varInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-GLOBAL-IN-NESTED-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested2::varInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-NESTED-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::funcInNestedNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-FUNC-IN-NESTED-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter Namespace1::Nested1::Namespace1::char_box -x objective-c++ | FileCheck -check-prefix=CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter varInInlineNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-GLOBAL-IN-INLINE-NAMESPACE %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter funcInInlineNamespace -x objective-c++ | FileCheck -check-prefix=CHECK-FUNC-IN-INLINE-NAMESPACE %s

#import <Namespaces.h>

// CHECK-TYPEDEF-IN-NAMESPACE: Dumping Namespace1::my_typedef:
// CHECK-TYPEDEF-IN-NAMESPACE-NEXT: TypedefDecl {{.+}} imported in Namespaces my_typedef 'int'
// CHECK-TYPEDEF-IN-NAMESPACE: SwiftNameAttr {{.+}} <<invalid sloc>> "SwiftTypedef"

// CHECK-USING-DECL-IN-NAMESPACE: Dumping Namespace1::my_using_decl:
// CHECK-USING-DECL-IN-NAMESPACE-NEXT: TypeAliasDecl {{.+}} imported in Namespaces my_using_decl 'int'
// CHECK-USING-DECL-IN-NAMESPACE: SwiftNameAttr {{.+}} <<invalid sloc>> "SwiftUsingDecl"

// CHECK-GLOBAL-IN-NAMESPACE: Dumping Namespace1::varInNamespace:
// CHECK-GLOBAL-IN-NAMESPACE-NEXT: VarDecl {{.+}} imported in Namespaces varInNamespace 'int' static cinit
// CHECK-GLOBAL-IN-NAMESPACE-NEXT: IntegerLiteral {{.+}} 'int' 1
// CHECK-GLOBAL-IN-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftVarInNamespace"

// CHECK-FUNC-IN-NAMESPACE: Dumping Namespace1::funcInNamespace:
// CHECK-FUNC-IN-NAMESPACE-NEXT: FunctionDecl {{.+}} imported in Namespaces funcInNamespace 'void ()'
// CHECK-FUNC-IN-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftFuncInNamespace()"

// CHECK-STRUCT-IN-NAMESPACE: Dumping Namespace1::char_box:
// CHECK-STRUCT-IN-NAMESPACE-NEXT: CXXRecordDecl {{.+}} imported in Namespaces <undeserialized declarations> struct char_box
// CHECK-STRUCT-IN-NAMESPACE: SwiftNameAttr {{.+}} <<invalid sloc>> "CharBox"

// CHECK-GLOBAL-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested1::varInNestedNamespace:
// CHECK-GLOBAL-IN-NESTED-NAMESPACE-NEXT: VarDecl {{.+}} imported in Namespaces varInNestedNamespace 'int' static cinit
// CHECK-GLOBAL-IN-NESTED-NAMESPACE-NEXT: IntegerLiteral {{.+}} 'int' 1
// CHECK-GLOBAL-IN-NESTED-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftVarInNestedNamespace"

// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested2::varInNestedNamespace:
// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE-NEXT: VarDecl {{.+}} imported in Namespaces varInNestedNamespace 'int' static cinit
// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE-NEXT: IntegerLiteral {{.+}} 'int' 2
// CHECK-ANOTHER-GLOBAL-IN-NESTED-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftAnotherVarInNestedNamespace"

// CHECK-FUNC-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested1::funcInNestedNamespace:
// CHECK-FUNC-IN-NESTED-NAMESPACE-NEXT: FunctionDecl {{.+}} imported in Namespaces funcInNestedNamespace 'void (int)'
// CHECK-FUNC-IN-NESTED-NAMESPACE-NEXT: ParmVarDecl {{.+}} i 'int'
// CHECK-FUNC-IN-NESTED-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftFuncInNestedNamespace(_:)"

// CHECK-STRUCT-IN-NESTED-NAMESPACE: Dumping Namespace1::Nested1::char_box:
// CHECK-STRUCT-IN-NESTED-NAMESPACE-NEXT: CXXRecordDecl {{.+}} imported in Namespaces <undeserialized declarations> struct char_box
// CHECK-STRUCT-IN-NESTED-NAMESPACE: SwiftNameAttr {{.+}} <<invalid sloc>> "NestedCharBox"

// CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE: Dumping Namespace1::Nested1::Namespace1::char_box:
// CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE-NEXT: CXXRecordDecl {{.+}} imported in Namespaces <undeserialized declarations> struct char_box
// CHECK-STRUCT-IN-DEEP-NESTED-NAMESPACE: SwiftNameAttr {{.+}} <<invalid sloc>> "DeepNestedCharBox"

// CHECK-GLOBAL-IN-INLINE-NAMESPACE: Dumping varInInlineNamespace:
// CHECK-GLOBAL-IN-INLINE-NAMESPACE-NEXT: VarDecl {{.+}} imported in Namespaces varInInlineNamespace 'int' static cinit
// CHECK-GLOBAL-IN-INLINE-NAMESPACE-NEXT: IntegerLiteral {{.+}} 'int' 3
// CHECK-GLOBAL-IN-INLINE-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftVarInInlineNamespace"

// CHECK-FUNC-IN-INLINE-NAMESPACE: Dumping funcInInlineNamespace:
// CHECK-FUNC-IN-INLINE-NAMESPACE-NEXT: FunctionDecl {{.+}} imported in Namespaces funcInInlineNamespace 'void ()'
// CHECK-FUNC-IN-INLINE-NAMESPACE-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "swiftFuncInInlineNamespace()"
21 changes: 21 additions & 0 deletions clang/test/APINotes/nullability.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify

#include "HeaderLib.h"

int main() {
custom_realloc(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}
int i = 0;
do_something_with_pointers(&i, 0);
do_something_with_pointers(0, &i); // expected-warning{{null passed to a callee that requires a non-null argument}}

extern void *p;
do_something_with_arrays(0, p); // expected-warning{{null passed to a callee that requires a non-null argument}}
do_something_with_arrays(p, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}

take_pointer_and_int(0, 0); // expected-warning{{null passed to a callee that requires a non-null argument}}

float *fp = global_int; // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'int * _Nonnull'}}
return 0;
}

46 changes: 46 additions & 0 deletions clang/test/APINotes/nullability.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -Wno-private-module -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify

// Test with Swift version 3.0. This should only affect the few APIs that have an entry in the 3.0 tables.

// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -Wno-private-module -fapinotes-swift-version=3.0 -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify -DSWIFT_VERSION_3_0 -fmodules-ignore-macro=SWIFT_VERSION_3_0

#import <SomeKit/SomeKit.h>

int main() {
A *a;

#if SWIFT_VERSION_3_0
float *fp = // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'A * _Nullable'}}
[a transform: 0 integer: 0];
#else
float *fp = // expected-warning{{incompatible pointer types initializing 'float *' with an expression of type 'A *'}}
[a transform: 0 integer: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
#endif

[a setNonnullAInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
[A setNonnullAInstance: 0]; // no warning
a.nonnullAInstance = 0; // expected-warning{{null passed to a callee that requires a non-null argument}}
A* _Nonnull aPtr = a.nonnullAInstance; // no warning

[a setNonnullAClass: 0]; // no warning
[A setNonnullAClass: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}

[a setNonnullABoth: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
[A setNonnullABoth: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}

[a setInternalProperty: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}

#if SWIFT_VERSION_3_0
// Version 3 information overrides header information.
[a setExplicitNonnullInstance: 0]; // okay
[a setExplicitNullableInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
#else
// Header information overrides unversioned information.
[a setExplicitNonnullInstance: 0]; // expected-warning{{null passed to a callee that requires a non-null argument}}
[a setExplicitNullableInstance: 0]; // okay
#endif

return 0;
}

12 changes: 12 additions & 0 deletions clang/test/APINotes/objc-forward-declarations.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fsyntax-only -F %S/Inputs/Frameworks %s -verify

@import LayeredKit;

void test(
UpwardClass *okayClass,
id <UpwardProto> okayProto,
PerfectlyNormalClass *badClass // expected-error {{'PerfectlyNormalClass' is unavailable}}
) {
// expected-note@LayeredKitImpl/LayeredKitImpl.h:4 {{'PerfectlyNormalClass' has been explicitly marked unavailable here}}
}
17 changes: 17 additions & 0 deletions clang/test/APINotes/objc_designated_inits.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -Wno-private-module -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify

#include "HeaderLib.h"
#import <SomeKit/SomeKit.h>

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

@implementation CSub
-(instancetype)initWithA:(A*)a { // expected-warning{{designated initializer missing a 'super' call to a designated initializer of the super class}}
// expected-note@SomeKit/SomeKit.h:20 2{{method marked as designated initializer of the class here}}
self = [super init]; // expected-warning{{designated initializer invoked a non-designated initializer}}
return self;
}
@end
42 changes: 42 additions & 0 deletions clang/test/APINotes/properties.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// RUN: rm -rf %t && mkdir -p %t

// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fblocks -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'TestProperties::' | FileCheck -check-prefix=CHECK -check-prefix=CHECK-4 %s
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fblocks -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter 'TestProperties::' -fapinotes-swift-version=3 | FileCheck -check-prefix=CHECK -check-prefix=CHECK-3 %s

@import VersionedKit;

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnly 'id'
// CHECK-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClass 'id'
// CHECK-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyInVersion3 'id'
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-4-NEXT: SwiftVersionedAdditionAttr {{.+}} 3.0{{$}}
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClassInVersion3 'id'
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-4-NEXT: SwiftVersionedAdditionAttr {{.+}} 3.0{{$}}
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyExceptInVersion3 'id'
// CHECK-3-NEXT: SwiftVersionedAdditionAttr {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-4-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}}
// CHECK-NOT: Attr

// CHECK-LABEL: ObjCPropertyDecl {{.+}} accessorsOnlyForClassExceptInVersion3 'id'
// CHECK-3-NEXT: SwiftVersionedAdditionAttr {{.+}} Implicit 3.0 IsReplacedByActive{{$}}
// CHECK-3-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-4-NEXT: SwiftImportPropertyAsAccessorsAttr {{.+}} <<invalid sloc>>
// CHECK-4-NEXT: SwiftVersionedRemovalAttr {{.+}} Implicit 3.0 {{[0-9]+}}
// CHECK-NOT: Attr

// CHECK-LABEL: Decl
38 changes: 38 additions & 0 deletions clang/test/APINotes/retain-count-convention.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fdisable-module-hash -fsyntax-only -F %S/Inputs/Frameworks %s
// RUN: %clang_cc1 -ast-print %t/ModulesCache/SimpleKit.pcm | FileCheck %s
// RUN: %clang_cc1 -ast-dump -ast-dump-filter 'DUMP' %t/ModulesCache/SimpleKit.pcm | FileCheck -check-prefix CHECK-DUMP %s

#import <SimpleKit/SimpleKit.h>

// CHECK: void *getCFOwnedToUnowned(void) __attribute__((cf_returns_not_retained));
// CHECK: void *getCFUnownedToOwned(void) __attribute__((cf_returns_retained));
// CHECK: void *getCFOwnedToNone(void) __attribute__((cf_unknown_transfer));
// CHECK: id getObjCOwnedToUnowned(void) __attribute__((ns_returns_not_retained));
// CHECK: id getObjCUnownedToOwned(void) __attribute__((ns_returns_retained));
// CHECK: int indirectGetCFOwnedToUnowned(void * _Nullable *out __attribute__((cf_returns_not_retained)));
// CHECK: int indirectGetCFUnownedToOwned(void * _Nullable *out __attribute__((cf_returns_retained)));
// CHECK: int indirectGetCFOwnedToNone(void * _Nullable *out);
// CHECK: int indirectGetCFNoneToOwned(void **out __attribute__((cf_returns_not_retained)));

// CHECK-LABEL: @interface MethodTest
// CHECK: - (id)getOwnedToUnowned __attribute__((ns_returns_not_retained));
// CHECK: - (id)getUnownedToOwned __attribute__((ns_returns_retained));
// CHECK: @end

// CHECK-DUMP-LABEL: Dumping getCFAuditedToUnowned_DUMP:
// CHECK-DUMP-NEXT: FunctionDecl
// CHECK-DUMP-NEXT: CFReturnsNotRetainedAttr
// CHECK-DUMP-NEXT: CFAuditedTransferAttr
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-LABEL: Dumping getCFAuditedToOwned_DUMP:
// CHECK-DUMP-NEXT: FunctionDecl
// CHECK-DUMP-NEXT: CFReturnsRetainedAttr
// CHECK-DUMP-NEXT: CFAuditedTransferAttr
// CHECK-DUMP-NOT: Attr

// CHECK-DUMP-LABEL: Dumping getCFAuditedToNone_DUMP:
// CHECK-DUMP-NEXT: FunctionDecl
// CHECK-DUMP-NEXT: CFUnknownTransferAttr
// CHECK-DUMP-NOT: Attr
25 changes: 25 additions & 0 deletions clang/test/APINotes/search-order.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: rm -rf %t && mkdir -p %t

// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_FRAMEWORK=1 -verify

// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -iapinotes-modules %S/Inputs/APINotes -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_SEARCH_PATH=1 -verify

// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -iapinotes-modules %S/Inputs/APINotes -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -DFROM_FRAMEWORK=1 -verify

@import SomeOtherKit;

void test(A *a) {
#if FROM_FRAMEWORK
[a methodA]; // expected-error{{unavailable}}
[a methodB];

// expected-note@SomeOtherKit/SomeOtherKit.h:5{{'methodA' has been explicitly marked unavailable here}}
#elif FROM_SEARCH_PATH
[a methodA];
[a methodB]; // expected-error{{unavailable}}

// expected-note@SomeOtherKit/SomeOtherKit.h:6{{'methodB' has been explicitly marked unavailable here}}
#else
# error Not something we need to test
#endif
}
16 changes: 16 additions & 0 deletions clang/test/APINotes/swift-import-as.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter ImmortalRefType | FileCheck -check-prefix=CHECK-IMMORTAL %s
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers %s -x c++ -ast-dump -ast-dump-filter RefCountedType | FileCheck -check-prefix=CHECK-REF-COUNTED %s

#include <SwiftImportAs.h>

// CHECK-IMMORTAL: Dumping ImmortalRefType:
// CHECK-IMMORTAL-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct ImmortalRefType
// CHECK-IMMORTAL: SwiftAttrAttr {{.+}} <<invalid sloc>> "import_reference"

// CHECK-REF-COUNTED: Dumping RefCountedType:
// CHECK-REF-COUNTED-NEXT: CXXRecordDecl {{.+}} imported in SwiftImportAs {{.+}} struct RefCountedType
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "import_reference"
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "retain:RCRetain"
// CHECK-REF-COUNTED: SwiftAttrAttr {{.+}} <<invalid sloc>> "release:RCRelease"
8 changes: 8 additions & 0 deletions clang/test/APINotes/top-level-private-modules.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -Wno-private-module -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify

#include <PrivateLib.h>
#include <TopLevelPrivateKit/TopLevelPrivateKit_Private.h>

void *testPlain = PrivateLib; // expected-error {{initializing 'void *' with an expression of incompatible type 'float'}}
void *testFramework = TopLevelPrivateKit_Private; // expected-error {{initializing 'void *' with an expression of incompatible type 'float'}}
28 changes: 28 additions & 0 deletions clang/test/APINotes/types.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// RUN: rm -rf %t && mkdir -p %t
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache -fapinotes-modules -Wno-private-module -fdisable-module-hash -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -verify
// RUN: %clang_cc1 -ast-print %t/ModulesCache/SimpleKit.pcm | FileCheck %s

#import <SomeKit/SomeKit.h>
#import <SimpleKit/SimpleKit.h>

// CHECK: struct __attribute__((swift_name("SuccessfullyRenamedA"))) RenamedAgainInAPINotesA {
// CHECK: struct __attribute__((swift_name("SuccessfullyRenamedB"))) RenamedAgainInAPINotesB {

void test(OverriddenTypes *overridden) {
int *ip1 = global_int_ptr; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'double (*)(int, int)'}}

int *ip2 = global_int_fun( // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'char *'}}
ip2, // expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'double *'}}
ip2); // expected-warning{{incompatible pointer types passing 'int *' to parameter of type 'float *'}}

int *ip3 = [overridden // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'char *'}}
methodToMangle: ip3 // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'double *'}}
second: ip3]; // expected-warning{{incompatible pointer types sending 'int *' to parameter of type 'float *'}}

int *ip4 = overridden.intPropertyToMangle; // expected-warning{{incompatible pointer types initializing 'int *' with an expression of type 'double *'}}
}

// expected-note@SomeKit/SomeKit.h:42{{passing argument to parameter 'ptr' here}}
// expected-note@SomeKit/SomeKit.h:42{{passing argument to parameter 'ptr2' here}}
// expected-note@SomeKit/SomeKit.h:48{{passing argument to parameter 'ptr1' here}}
// expected-note@SomeKit/SomeKit.h:48{{passing argument to parameter 'ptr2' here}}
Loading