62 changes: 59 additions & 3 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,8 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
TemplateSpecializationTypes(this_()),
DependentTemplateSpecializationTypes(this_()), AutoTypes(this_()),
DependentBitIntTypes(this_()), SubstTemplateTemplateParmPacks(this_()),
CanonTemplateTemplateParms(this_()), SourceMgr(SM), LangOpts(LOpts),
ArrayParameterTypes(this_()), CanonTemplateTemplateParms(this_()),
SourceMgr(SM), LangOpts(LOpts),
NoSanitizeL(new NoSanitizeList(LangOpts.NoSanitizeFiles, SM)),
XRayFilter(new XRayFunctionFilter(LangOpts.XRayAlwaysInstrumentFiles,
LangOpts.XRayNeverInstrumentFiles,
Expand Down Expand Up @@ -1906,7 +1907,8 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {

case Type::IncompleteArray:
case Type::VariableArray:
case Type::ConstantArray: {
case Type::ConstantArray:
case Type::ArrayParameter: {
// Model non-constant sized arrays as size zero, but track the alignment.
uint64_t Size = 0;
if (const auto *CAT = dyn_cast<ConstantArrayType>(T))
Expand Down Expand Up @@ -3396,6 +3398,37 @@ QualType ASTContext::getDecayedType(QualType T) const {
return getDecayedType(T, Decayed);
}

QualType ASTContext::getArrayParameterType(QualType Ty) const {
if (Ty->isArrayParameterType())
return Ty;
assert(Ty->isConstantArrayType() && "Ty must be an array type.");
const auto *ATy = cast<ConstantArrayType>(Ty);
llvm::FoldingSetNodeID ID;
ATy->Profile(ID, *this, ATy->getElementType(), ATy->getZExtSize(),
ATy->getSizeExpr(), ATy->getSizeModifier(),
ATy->getIndexTypeQualifiers().getAsOpaqueValue());
void *InsertPos = nullptr;
ArrayParameterType *AT =
ArrayParameterTypes.FindNodeOrInsertPos(ID, InsertPos);
if (AT)
return QualType(AT, 0);

QualType Canonical;
if (!Ty.isCanonical()) {
Canonical = getArrayParameterType(getCanonicalType(Ty));

// Get the new insert position for the node we care about.
AT = ArrayParameterTypes.FindNodeOrInsertPos(ID, InsertPos);
assert(!AT && "Shouldn't be in the map!");
}

AT = new (*this, alignof(ArrayParameterType))
ArrayParameterType(ATy, Canonical);
Types.push_back(AT);
ArrayParameterTypes.InsertNode(AT, InsertPos);
return QualType(AT, 0);
}

/// getBlockPointerType - Return the uniqued reference to the type for
/// a pointer to the specified block.
QualType ASTContext::getBlockPointerType(QualType T) const {
Expand Down Expand Up @@ -3642,6 +3675,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const {
case Type::PackIndexing:
case Type::BitInt:
case Type::DependentBitInt:
case Type::ArrayParameter:
llvm_unreachable("type should never be variably-modified");

// These types can be variably-modified but should never need to
Expand Down Expand Up @@ -6051,7 +6085,9 @@ CanQualType ASTContext::getCanonicalParamType(QualType T) const {
T = getVariableArrayDecayedType(T);
const Type *Ty = T.getTypePtr();
QualType Result;
if (isa<ArrayType>(Ty)) {
if (getLangOpts().HLSL && isa<ConstantArrayType>(Ty)) {
Result = getArrayParameterType(QualType(Ty, 0));
} else if (isa<ArrayType>(Ty)) {
Result = getArrayDecayedType(QualType(Ty,0));
} else if (isa<FunctionType>(Ty)) {
Result = getPointerType(QualType(Ty, 0));
Expand Down Expand Up @@ -6973,6 +7009,8 @@ const ArrayType *ASTContext::getAsArrayType(QualType T) const {
}

QualType ASTContext::getAdjustedParameterType(QualType T) const {
if (getLangOpts().HLSL && T->isConstantArrayType())
return getArrayParameterType(T);
if (T->isArrayType() || T->isFunctionType())
return getDecayedType(T);
return T;
Expand Down Expand Up @@ -8583,6 +8621,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
case Type::DeducedTemplateSpecialization:
return;

case Type::ArrayParameter:
case Type::Pipe:
#define ABSTRACT_TYPE(KIND, BASE)
#define TYPE(KIND, BASE)
Expand Down Expand Up @@ -10926,6 +10965,10 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS, bool OfBlockPointer,
assert(LHS != RHS &&
"Equivalent pipe types should have already been handled!");
return {};
case Type::ArrayParameter:
assert(LHS != RHS &&
"Equivalent ArrayParameter types should have already been handled!");
return {};
case Type::BitInt: {
// Merge two bit-precise int types, while trying to preserve typedef info.
bool LHSUnsigned = LHS->castAs<BitIntType>()->isUnsigned();
Expand Down Expand Up @@ -12817,6 +12860,18 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
getCommonArrayElementType(Ctx, AX, QX, AY, QY), AX->getSize(), SizeExpr,
getCommonSizeModifier(AX, AY), getCommonIndexTypeCVRQualifiers(AX, AY));
}
case Type::ArrayParameter: {
const auto *AX = cast<ArrayParameterType>(X),
*AY = cast<ArrayParameterType>(Y);
assert(AX->getSize() == AY->getSize());
const Expr *SizeExpr = Ctx.hasSameExpr(AX->getSizeExpr(), AY->getSizeExpr())
? AX->getSizeExpr()
: nullptr;
auto ArrayTy = Ctx.getConstantArrayType(
getCommonArrayElementType(Ctx, AX, QX, AY, QY), AX->getSize(), SizeExpr,
getCommonSizeModifier(AX, AY), getCommonIndexTypeCVRQualifiers(AX, AY));
return Ctx.getArrayParameterType(ArrayTy);
}
case Type::Atomic: {
const auto *AX = cast<AtomicType>(X), *AY = cast<AtomicType>(Y);
return Ctx.getAtomicType(
Expand Down Expand Up @@ -13078,6 +13133,7 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
CANONICAL_TYPE(Builtin)
CANONICAL_TYPE(Complex)
CANONICAL_TYPE(ConstantArray)
CANONICAL_TYPE(ArrayParameter)
CANONICAL_TYPE(ConstantMatrix)
CANONICAL_TYPE(Enum)
CANONICAL_TYPE(ExtVector)
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/AST/ASTImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,15 @@ ASTNodeImporter::VisitConstantArrayType(const ConstantArrayType *T) {
T->getIndexTypeCVRQualifiers());
}

ExpectedType
ASTNodeImporter::VisitArrayParameterType(const ArrayParameterType *T) {
ExpectedType ToArrayTypeOrErr = VisitConstantArrayType(T);
if (!ToArrayTypeOrErr)
return ToArrayTypeOrErr.takeError();

return Importer.getToContext().getArrayParameterType(*ToArrayTypeOrErr);
}

ExpectedType
ASTNodeImporter::VisitIncompleteArrayType(const IncompleteArrayType *T) {
ExpectedType ToElementTypeOrErr = import(T->getElementType());
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/ASTStructuralEquivalence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,

case Type::Adjusted:
case Type::Decayed:
case Type::ArrayParameter:
if (!IsStructurallyEquivalent(Context,
cast<AdjustedType>(T1)->getOriginalType(),
cast<AdjustedType>(T2)->getOriginalType()))
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/AST/DeclBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1102,9 +1102,13 @@ bool Decl::isInAnotherModuleUnit() const {
return M != getASTContext().getCurrentNamedModule();
}

bool Decl::isFromExplicitGlobalModule() const {
return getOwningModule() && getOwningModule()->isExplicitGlobalModule();
}

bool Decl::shouldSkipCheckingODR() const {
return getASTContext().getLangOpts().SkipODRCheckInGMF && getOwningModule() &&
getOwningModule()->isExplicitGlobalModule();
return getASTContext().getLangOpts().SkipODRCheckInGMF &&
isFromExplicitGlobalModule();
}

static Decl::Kind getKind(const Decl *D) { return D->getKind(); }
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1948,6 +1948,7 @@ bool CastExpr::CastConsistency() const {
case CK_UserDefinedConversion: // operator bool()
case CK_BuiltinFnToFnPtr:
case CK_FixedPointToBoolean:
case CK_HLSLArrayRValue:
CheckNoBasePath:
assert(path_empty() && "Cast kind should not have a base path!");
break;
Expand Down
33 changes: 23 additions & 10 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11699,6 +11699,7 @@ GCCTypeClass EvaluateBuiltinClassifyType(QualType T,
case Type::IncompleteArray:
case Type::FunctionNoProto:
case Type::FunctionProto:
case Type::ArrayParameter:
return GCCTypeClass::Pointer;

case Type::MemberPointer:
Expand Down Expand Up @@ -12361,12 +12362,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;

std::optional<APSInt> Fallback;
if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
APSInt FallbackTemp;
if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
return false;
Fallback = FallbackTemp;
}

if (!Val) {
if (BuiltinOp == Builtin::BI__builtin_clzg && E->getNumArgs() > 1) {
if (!EvaluateInteger(E->getArg(1), Val, Info))
return false;
return Success(Val, E);
}
if (Fallback)
return Success(*Fallback, E);

// When the argument is 0, the result of GCC builtins is undefined,
// whereas for Microsoft intrinsics, the result is the bit-width of the
Expand Down Expand Up @@ -12425,12 +12431,17 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
if (!EvaluateInteger(E->getArg(0), Val, Info))
return false;

std::optional<APSInt> Fallback;
if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
APSInt FallbackTemp;
if (!EvaluateInteger(E->getArg(1), FallbackTemp, Info))
return false;
Fallback = FallbackTemp;
}

if (!Val) {
if (BuiltinOp == Builtin::BI__builtin_ctzg && E->getNumArgs() > 1) {
if (!EvaluateInteger(E->getArg(1), Val, Info))
return false;
return Success(Val, E);
}
if (Fallback)
return Success(*Fallback, E);

return Error(E);
}
Expand Down Expand Up @@ -14075,6 +14086,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_AtomicToNonAtomic:
case CK_NoOp:
case CK_LValueToRValueBitCast:
case CK_HLSLArrayRValue:
return ExprEvaluatorBaseTy::VisitCastExpr(E);

case CK_MemberPointerToBoolean:
Expand Down Expand Up @@ -14903,6 +14915,7 @@ bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
case CK_AtomicToNonAtomic:
case CK_NoOp:
case CK_LValueToRValueBitCast:
case CK_HLSLArrayRValue:
return ExprEvaluatorBaseTy::VisitCastExpr(E);

case CK_Dependent:
Expand Down
29 changes: 19 additions & 10 deletions clang/lib/AST/FormatString.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
return Match;
if (const auto *BT = argTy->getAs<BuiltinType>()) {
// Check if the only difference between them is signed vs unsigned
// if true, we consider they are compatible.
// if true, return match signedness.
switch (BT->getKind()) {
default:
break;
Expand All @@ -423,44 +423,53 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
[[fallthrough]];
case BuiltinType::Char_S:
case BuiltinType::SChar:
if (T == C.UnsignedShortTy || T == C.ShortTy)
return NoMatchTypeConfusion;
if (T == C.UnsignedCharTy)
return NoMatchSignedness;
if (T == C.SignedCharTy)
return Match;
break;
case BuiltinType::Char_U:
case BuiltinType::UChar:
if (T == C.UnsignedShortTy || T == C.ShortTy)
return NoMatchTypeConfusion;
if (T == C.UnsignedCharTy || T == C.SignedCharTy)
if (T == C.UnsignedCharTy)
return Match;
if (T == C.SignedCharTy)
return NoMatchSignedness;
break;
case BuiltinType::Short:
if (T == C.UnsignedShortTy)
return Match;
return NoMatchSignedness;
break;
case BuiltinType::UShort:
if (T == C.ShortTy)
return Match;
return NoMatchSignedness;
break;
case BuiltinType::Int:
if (T == C.UnsignedIntTy)
return Match;
return NoMatchSignedness;
break;
case BuiltinType::UInt:
if (T == C.IntTy)
return Match;
return NoMatchSignedness;
break;
case BuiltinType::Long:
if (T == C.UnsignedLongTy)
return Match;
return NoMatchSignedness;
break;
case BuiltinType::ULong:
if (T == C.LongTy)
return Match;
return NoMatchSignedness;
break;
case BuiltinType::LongLong:
if (T == C.UnsignedLongLongTy)
return Match;
return NoMatchSignedness;
break;
case BuiltinType::ULongLong:
if (T == C.LongLongTy)
return Match;
return NoMatchSignedness;
break;
}
// "Partially matched" because of promotions?
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/Interp/ByteCodeStmtGen.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class ByteCodeStmtGen final : public ByteCodeExprGen<Emitter> {
OptLabelTy DefaultLabel;
};

extern template class ByteCodeStmtGen<ByteCodeEmitter>;
extern template class ByteCodeExprGen<EvalEmitter>;

} // namespace interp
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2398,6 +2398,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::Complex:
case Type::Adjusted:
case Type::Decayed:
case Type::ArrayParameter:
case Type::Pointer:
case Type::BlockPointer:
case Type::LValueReference:
Expand Down Expand Up @@ -4446,6 +4447,10 @@ void CXXNameMangler::mangleType(const DependentBitIntType *T) {
Out << "_";
}

void CXXNameMangler::mangleType(const ArrayParameterType *T) {
mangleType(cast<ConstantArrayType>(T));
}

void CXXNameMangler::mangleIntegerLiteral(QualType T,
const llvm::APSInt &Value) {
// <expr-primary> ::= L <type> <value number> E # integer literal
Expand Down
5 changes: 5 additions & 0 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3079,6 +3079,11 @@ void MicrosoftCXXNameMangler::mangleArrayType(const ArrayType *T) {
mangleType(ElementTy, SourceRange(), QMM_Escape);
}

void MicrosoftCXXNameMangler::mangleType(const ArrayParameterType *T,
Qualifiers, SourceRange) {
mangleArrayType(cast<ConstantArrayType>(T));
}

// <type> ::= <pointer-to-member-type>
// <pointer-to-member-type> ::= <pointer-cvr-qualifiers> <cvr-qualifiers>
// <class name> <type>
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/AST/ODRHash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,10 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
VisitArrayType(T);
}

void VisitArrayParameterType(const ArrayParameterType *T) {
VisitConstantArrayType(T);
}

void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
AddStmt(T->getSizeExpr());
VisitArrayType(T);
Expand Down
13 changes: 13 additions & 0 deletions clang/lib/AST/TextNodeDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,19 @@ void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) {
}
}

void TextNodeDumper::VisitCXXDeductionGuideDecl(
const CXXDeductionGuideDecl *D) {
VisitFunctionDecl(D);
switch (D->getDeductionCandidateKind()) {
case DeductionCandidate::Normal:
case DeductionCandidate::Copy:
return;
case DeductionCandidate::Aggregate:
OS << " aggregate ";
break;
}
}

void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl(
const LifetimeExtendedTemporaryDecl *D) {
OS << " extended by ";
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/AST/Type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,14 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
return Ctx.getDecayedType(originalType);
}

QualType VisitArrayParameterType(const ArrayParameterType *T) {
QualType ArrTy = VisitConstantArrayType(T);
if (ArrTy.isNull())
return {};

return Ctx.getArrayParameterType(ArrTy);
}

SUGARED_TYPE_CLASS(TypeOfExpr)
SUGARED_TYPE_CLASS(TypeOf)
SUGARED_TYPE_CLASS(Decltype)
Expand Down Expand Up @@ -4454,6 +4462,7 @@ static CachedProperties computeCachedProperties(const Type *T) {
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
case Type::ArrayParameter:
return Cache::get(cast<ArrayType>(T)->getElementType());
case Type::Vector:
case Type::ExtVector:
Expand Down Expand Up @@ -4542,6 +4551,7 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
case Type::ArrayParameter:
return computeTypeLinkageInfo(cast<ArrayType>(T)->getElementType());
case Type::Vector:
case Type::ExtVector:
Expand Down Expand Up @@ -4736,6 +4746,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
case Type::Pipe:
case Type::BitInt:
case Type::DependentBitInt:
case Type::ArrayParameter:
return false;
}
llvm_unreachable("bad type kind!");
Expand Down
11 changes: 11 additions & 0 deletions clang/lib/AST/TypePrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,

case Type::Adjusted:
case Type::Decayed:
case Type::ArrayParameter:
case Type::Pointer:
case Type::BlockPointer:
case Type::LValueReference:
Expand Down Expand Up @@ -595,6 +596,16 @@ void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {
printAdjustedBefore(T, OS);
}

void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,
raw_ostream &OS) {
printConstantArrayAfter(T, OS);
}

void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,
raw_ostream &OS) {
printConstantArrayBefore(T, OS);
}

void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {
printAdjustedAfter(T, OS);
}
Expand Down
36 changes: 36 additions & 0 deletions clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,42 @@ getFieldsForInitListExpr(const InitListExpr *InitList) {
return Fields;
}

RecordInitListHelper::RecordInitListHelper(const InitListExpr *InitList) {
auto *RD = InitList->getType()->getAsCXXRecordDecl();
assert(RD != nullptr);

std::vector<const FieldDecl *> Fields = getFieldsForInitListExpr(InitList);
ArrayRef<Expr *> Inits = InitList->inits();

// Unions initialized with an empty initializer list need special treatment.
// For structs/classes initialized with an empty initializer list, Clang
// puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions,
// it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves.
SmallVector<Expr *> InitsForUnion;
if (InitList->getType()->isUnionType() && Inits.empty()) {
assert(Fields.size() == 1);
ImplicitValueInitForUnion.emplace(Fields.front()->getType());
InitsForUnion.push_back(&*ImplicitValueInitForUnion);
Inits = InitsForUnion;
}

size_t InitIdx = 0;

assert(Fields.size() + RD->getNumBases() == Inits.size());
for (const CXXBaseSpecifier &Base : RD->bases()) {
assert(InitIdx < Inits.size());
Expr *Init = Inits[InitIdx++];
BaseInits.emplace_back(&Base, Init);
}

assert(Fields.size() == Inits.size() - InitIdx);
for (const FieldDecl *Field : Fields) {
assert(InitIdx < Inits.size());
Expr *Init = Inits[InitIdx++];
FieldInits.emplace_back(Field, Init);
}
}

RecordValue &refreshRecordValue(RecordStorageLocation &Loc, Environment &Env) {
auto &NewVal = Env.create<RecordValue>(Loc);
Env.setValue(Loc, NewVal);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -512,27 +512,26 @@ void constructOptionalValue(const Expr &E, Environment &Env,
/// Returns a symbolic value for the "has_value" property of an `optional<T>`
/// value that is constructed/assigned from a value of type `U` or `optional<U>`
/// where `T` is constructible from `U`.
BoolValue &valueOrConversionHasValue(const FunctionDecl &F, const Expr &E,
BoolValue &valueOrConversionHasValue(QualType DestType, const Expr &E,
const MatchFinder::MatchResult &MatchRes,
LatticeTransferState &State) {
assert(F.getTemplateSpecializationArgs() != nullptr);
assert(F.getTemplateSpecializationArgs()->size() > 0);

const int TemplateParamOptionalWrappersCount =
countOptionalWrappers(*MatchRes.Context, F.getTemplateSpecializationArgs()
->get(0)
.getAsType()
.getNonReferenceType());
const int DestTypeOptionalWrappersCount =
countOptionalWrappers(*MatchRes.Context, DestType);
const int ArgTypeOptionalWrappersCount = countOptionalWrappers(
*MatchRes.Context, E.getType().getNonReferenceType());

// Check if this is a constructor/assignment call for `optional<T>` with
// argument of type `U` such that `T` is constructible from `U`.
if (TemplateParamOptionalWrappersCount == ArgTypeOptionalWrappersCount)
// Is this an constructor of the form `template<class U> optional(U &&)` /
// assignment of the form `template<class U> optional& operator=(U &&)`
// (where `T` is assignable / constructible from `U`)?
// We recognize this because the number of optionals in the optional being
// assigned to is different from the function argument type.
if (DestTypeOptionalWrappersCount != ArgTypeOptionalWrappersCount)
return State.Env.getBoolLiteralValue(true);

// This is a constructor/assignment call for `optional<T>` with argument of
// type `optional<U>` such that `T` is constructible from `U`.
// Otherwise, this must be a constructor of the form
// `template <class U> optional<optional<U> &&)` / assignment of the form
// `template <class U> optional& operator=(optional<U> &&)
// (where, again, `T` is assignable / constructible from `U`).
auto *Loc = State.Env.get<RecordStorageLocation>(E);
if (auto *HasValueVal = getHasValue(State.Env, Loc))
return *HasValueVal;
Expand All @@ -544,10 +543,11 @@ void transferValueOrConversionConstructor(
LatticeTransferState &State) {
assert(E->getNumArgs() > 0);

constructOptionalValue(*E, State.Env,
valueOrConversionHasValue(*E->getConstructor(),
*E->getArg(0), MatchRes,
State));
constructOptionalValue(
*E, State.Env,
valueOrConversionHasValue(
E->getConstructor()->getThisType()->getPointeeType(), *E->getArg(0),
MatchRes, State));
}

void transferAssignment(const CXXOperatorCallExpr *E, BoolValue &HasValueVal,
Expand All @@ -566,10 +566,11 @@ void transferValueOrConversionAssignment(
const CXXOperatorCallExpr *E, const MatchFinder::MatchResult &MatchRes,
LatticeTransferState &State) {
assert(E->getNumArgs() > 1);
transferAssignment(E,
valueOrConversionHasValue(*E->getDirectCallee(),
*E->getArg(1), MatchRes, State),
State);
transferAssignment(
E,
valueOrConversionHasValue(E->getArg(0)->getType().getNonReferenceType(),
*E->getArg(1), MatchRes, State),
State);
}

void transferNulloptAssignment(const CXXOperatorCallExpr *E,
Expand Down
61 changes: 16 additions & 45 deletions clang/lib/Analysis/FlowSensitive/Transfer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,51 +689,22 @@ class TransferVisitor : public ConstStmtVisitor<TransferVisitor> {
}

llvm::DenseMap<const ValueDecl *, StorageLocation *> FieldLocs;

// This only contains the direct fields for the given type.
std::vector<const FieldDecl *> FieldsForInit = getFieldsForInitListExpr(S);

// `S->inits()` contains all the initializer expressions, including the
// ones for direct base classes.
ArrayRef<Expr *> Inits = S->inits();
size_t InitIdx = 0;

// Unions initialized with an empty initializer list need special treatment.
// For structs/classes initialized with an empty initializer list, Clang
// puts `ImplicitValueInitExpr`s in `InitListExpr::inits()`, but for unions,
// it doesn't do this -- so we create an `ImplicitValueInitExpr` ourselves.
std::optional<ImplicitValueInitExpr> ImplicitValueInitForUnion;
SmallVector<Expr *> InitsForUnion;
if (S->getType()->isUnionType() && Inits.empty()) {
assert(FieldsForInit.size() == 1);
ImplicitValueInitForUnion.emplace(FieldsForInit.front()->getType());
InitsForUnion.push_back(&*ImplicitValueInitForUnion);
Inits = InitsForUnion;
}

// Initialize base classes.
if (auto* R = S->getType()->getAsCXXRecordDecl()) {
assert(FieldsForInit.size() + R->getNumBases() == Inits.size());
for ([[maybe_unused]] const CXXBaseSpecifier &Base : R->bases()) {
assert(InitIdx < Inits.size());
auto Init = Inits[InitIdx++];
assert(Base.getType().getCanonicalType() ==
Init->getType().getCanonicalType());
auto *BaseVal = Env.get<RecordValue>(*Init);
if (!BaseVal)
BaseVal = cast<RecordValue>(Env.createValue(Init->getType()));
// Take ownership of the fields of the `RecordValue` for the base class
// and incorporate them into the "flattened" set of fields for the
// derived class.
auto Children = BaseVal->getLoc().children();
FieldLocs.insert(Children.begin(), Children.end());
}
}

assert(FieldsForInit.size() == Inits.size() - InitIdx);
for (auto Field : FieldsForInit) {
assert(InitIdx < Inits.size());
auto Init = Inits[InitIdx++];
RecordInitListHelper InitListHelper(S);

for (auto [Base, Init] : InitListHelper.base_inits()) {
assert(Base->getType().getCanonicalType() ==
Init->getType().getCanonicalType());
auto *BaseVal = Env.get<RecordValue>(*Init);
if (!BaseVal)
BaseVal = cast<RecordValue>(Env.createValue(Init->getType()));
// Take ownership of the fields of the `RecordValue` for the base class
// and incorporate them into the "flattened" set of fields for the
// derived class.
auto Children = BaseVal->getLoc().children();
FieldLocs.insert(Children.begin(), Children.end());
}

for (auto [Field, Init] : InitListHelper.field_inits()) {
assert(
// The types are same, or
Field->getType().getCanonicalType().getUnqualifiedType() ==
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/TargetInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,7 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : Triple(T) {
HasAArch64SVETypes = false;
HasRISCVVTypes = false;
AllowAMDGPUUnsafeFPAtomics = false;
HasUnalignedAccess = false;
ARMCDECoprocMask = 0;

// Default to no types using fpret.
Expand Down
7 changes: 5 additions & 2 deletions clang/lib/Basic/Targets/AArch64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,8 @@ AArch64TargetInfo::AArch64TargetInfo(const llvm::Triple &Triple,
assert(UseBitFieldTypeAlignment && "bitfields affect type alignment");
UseZeroLengthBitfieldAlignment = true;

HasUnalignedAccess = true;

// AArch64 targets default to using the ARM C++ ABI.
TheCXXABI.set(TargetCXXABI::GenericAArch64);

Expand Down Expand Up @@ -496,7 +498,7 @@ void AArch64TargetInfo::getTargetDefines(const LangOptions &Opts,
if (HasPAuthLR)
Builder.defineMacro("__ARM_FEATURE_PAUTH_LR", "1");

if (HasUnaligned)
if (HasUnalignedAccess)
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");

if ((FPU & NeonMode) && HasFullFP16)
Expand Down Expand Up @@ -921,7 +923,8 @@ bool AArch64TargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
HasSM4 = true;
}
if (Feature == "+strict-align")
HasUnaligned = false;
HasUnalignedAccess = false;

// All predecessor archs are added but select the latest one for ArchKind.
if (Feature == "+v8a" && ArchInfo->Version < llvm::AArch64::ARMV8A.Version)
ArchInfo = &llvm::AArch64::ARMV8A;
Expand Down
1 change: 0 additions & 1 deletion clang/lib/Basic/Targets/AArch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ class LLVM_LIBRARY_VISIBILITY AArch64TargetInfo : public TargetInfo {
bool HasSHA2 = false;
bool HasSHA3 = false;
bool HasSM4 = false;
bool HasUnaligned = true;
bool HasFullFP16 = false;
bool HasDotProd = false;
bool HasFP16FML = false;
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Basic/Targets/ARM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
SHA2 = 0;
AES = 0;
DSP = 0;
Unaligned = 1;
HasUnalignedAccess = true;
SoftFloat = false;
// Note that SoftFloatABI is initialized in our constructor.
HWDiv = 0;
Expand Down Expand Up @@ -576,7 +576,7 @@ bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
return false;
}
} else if (Feature == "+strict-align") {
Unaligned = 0;
HasUnalignedAccess = false;
} else if (Feature == "+fp16") {
HW_FP |= HW_FP_HP;
} else if (Feature == "+fullfp16") {
Expand Down Expand Up @@ -785,7 +785,7 @@ void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");

// ACLE 6.4.3 Unaligned access supported in hardware
if (Unaligned)
if (HasUnalignedAccess)
Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");

// ACLE 6.4.4 LDREX/STREX
Expand Down
2 changes: 0 additions & 2 deletions clang/lib/Basic/Targets/ARM.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,6 @@ class LLVM_LIBRARY_VISIBILITY ARMTargetInfo : public TargetInfo {
LLVM_PREFERRED_TYPE(bool)
unsigned DSP : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned Unaligned : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned DotProd : 1;
LLVM_PREFERRED_TYPE(bool)
unsigned HasMatMul : 1;
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/LoongArch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,8 @@ bool LoongArchTargetInfo::handleTargetFeatures(
HasFeatureLSX = true;
else if (Feature == "+lasx")
HasFeatureLASX = true;
else if (Feature == "-ual")
HasUnalignedAccess = false;
}
return true;
}
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/LoongArch.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArch64TargetInfo
: LoongArchTargetInfo(Triple, Opts) {
LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
IntMaxType = Int64Type = SignedLong;
HasUnalignedAccess = true;
resetDataLayout("e-m:e-p:64:64-i64:64-i128:128-n64-S128");
// TODO: select appropriate ABI.
setABI("lp64d");
Expand Down
2 changes: 2 additions & 0 deletions clang/lib/Basic/Targets/Mips.h
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ class LLVM_LIBRARY_VISIBILITY MipsTargetInfo : public TargetInfo {
IsMips16 = true;
else if (Feature == "+micromips")
IsMicromips = true;
else if (Feature == "+mips32r6" || Feature == "+mips64r6")
HasUnalignedAccess = true;
else if (Feature == "+dsp")
DspRev = std::max(DspRev, DSP1);
else if (Feature == "+dspr2")
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/PPC.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class LLVM_LIBRARY_VISIBILITY PPCTargetInfo : public TargetInfo {
LongDoubleFormat = &llvm::APFloat::PPCDoubleDouble();
HasStrictFP = true;
HasIbm128 = true;
HasUnalignedAccess = true;
}

// Set the language option for altivec based on our value.
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/SystemZ.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
LongDoubleFormat = &llvm::APFloat::IEEEquad();
DefaultAlignForAttributeAligned = 64;
MinGlobalAlign = 16;
HasUnalignedAccess = true;
if (Triple.isOSzOS()) {
TLSSupported = false;
// All vector types are default aligned on an 8-byte boundary, even if the
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/VE.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class LLVM_LIBRARY_VISIBILITY VETargetInfo : public TargetInfo {
Int64Type = SignedLong;
RegParmMax = 8;
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 64;
HasUnalignedAccess = true;

WCharType = UnsignedInt;
WIntType = UnsignedInt;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/WebAssembly.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class LLVM_LIBRARY_VISIBILITY WebAssemblyTargetInfo : public TargetInfo {
SizeType = UnsignedLong;
PtrDiffType = SignedLong;
IntPtrType = SignedLong;
HasUnalignedAccess = true;
}

StringRef getABI() const override;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Basic/Targets/X86.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ class LLVM_LIBRARY_VISIBILITY X86TargetInfo : public TargetInfo {
LongDoubleFormat = &llvm::APFloat::x87DoubleExtended();
AddrSpaceMap = &X86AddrSpaceMap;
HasStrictFP = true;
HasUnalignedAccess = true;

bool IsWinCOFF =
getTriple().isOSWindows() && getTriple().isOSBinFormatCOFF();
Expand Down
7 changes: 3 additions & 4 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,20 +101,19 @@ namespace llvm {
extern cl::opt<bool> PrintPipelinePasses;

cl::opt<bool> ClRemoveTraps("clang-remove-traps", cl::Optional,
cl::desc("Insert remove-traps pass."),
cl::init(false));
cl::desc("Insert remove-traps pass."));

// Experiment to move sanitizers earlier.
static cl::opt<bool> ClSanitizeOnOptimizerEarlyEP(
"sanitizer-early-opt-ep", cl::Optional,
cl::desc("Insert sanitizers on OptimizerEarlyEP."), cl::init(false));
cl::desc("Insert sanitizers on OptimizerEarlyEP."));

extern cl::opt<InstrProfCorrelator::ProfCorrelatorKind> ProfileCorrelate;

// Re-link builtin bitcodes after optimization
cl::opt<bool> ClRelinkBuiltinBitcodePostop(
"relink-builtin-bitcode-postop", cl::Optional,
cl::desc("Re-link builtin bitcodes after optimization."), cl::init(false));
cl::desc("Re-link builtin bitcodes after optimization."));
} // namespace llvm

namespace {
Expand Down
93 changes: 92 additions & 1 deletion clang/lib/CodeGen/CGBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1131,8 +1131,92 @@ struct BitTest {

static BitTest decodeBitTestBuiltin(unsigned BuiltinID);
};

// Returns the first convergence entry/loop/anchor instruction found in |BB|.
// std::nullptr otherwise.
llvm::IntrinsicInst *getConvergenceToken(llvm::BasicBlock *BB) {
for (auto &I : *BB) {
auto *II = dyn_cast<llvm::IntrinsicInst>(&I);
if (II && isConvergenceControlIntrinsic(II->getIntrinsicID()))
return II;
}
return nullptr;
}

} // namespace

llvm::CallBase *
CodeGenFunction::addConvergenceControlToken(llvm::CallBase *Input,
llvm::Value *ParentToken) {
llvm::Value *bundleArgs[] = {ParentToken};
llvm::OperandBundleDef OB("convergencectrl", bundleArgs);
auto Output = llvm::CallBase::addOperandBundle(
Input, llvm::LLVMContext::OB_convergencectrl, OB, Input);
Input->replaceAllUsesWith(Output);
Input->eraseFromParent();
return Output;
}

llvm::IntrinsicInst *
CodeGenFunction::emitConvergenceLoopToken(llvm::BasicBlock *BB,
llvm::Value *ParentToken) {
CGBuilderTy::InsertPoint IP = Builder.saveIP();
Builder.SetInsertPoint(&BB->front());
auto CB = Builder.CreateIntrinsic(
llvm::Intrinsic::experimental_convergence_loop, {}, {});
Builder.restoreIP(IP);

auto I = addConvergenceControlToken(CB, ParentToken);
return cast<llvm::IntrinsicInst>(I);
}

llvm::IntrinsicInst *
CodeGenFunction::getOrEmitConvergenceEntryToken(llvm::Function *F) {
auto *BB = &F->getEntryBlock();
auto *token = getConvergenceToken(BB);
if (token)
return token;

// Adding a convergence token requires the function to be marked as
// convergent.
F->setConvergent();

CGBuilderTy::InsertPoint IP = Builder.saveIP();
Builder.SetInsertPoint(&BB->front());
auto I = Builder.CreateIntrinsic(
llvm::Intrinsic::experimental_convergence_entry, {}, {});
assert(isa<llvm::IntrinsicInst>(I));
Builder.restoreIP(IP);

return cast<llvm::IntrinsicInst>(I);
}

llvm::IntrinsicInst *
CodeGenFunction::getOrEmitConvergenceLoopToken(const LoopInfo *LI) {
assert(LI != nullptr);

auto *token = getConvergenceToken(LI->getHeader());
if (token)
return token;

llvm::IntrinsicInst *PII =
LI->getParent()
? emitConvergenceLoopToken(
LI->getHeader(), getOrEmitConvergenceLoopToken(LI->getParent()))
: getOrEmitConvergenceEntryToken(LI->getHeader()->getParent());

return emitConvergenceLoopToken(LI->getHeader(), PII);
}

llvm::CallBase *
CodeGenFunction::addControlledConvergenceToken(llvm::CallBase *Input) {
llvm::Value *ParentToken =
LoopStack.hasInfo()
? getOrEmitConvergenceLoopToken(&LoopStack.getInfo())
: getOrEmitConvergenceEntryToken(Input->getFunction());
return addConvergenceControlToken(Input, ParentToken);
}

BitTest BitTest::decodeBitTestBuiltin(unsigned BuiltinID) {
switch (BuiltinID) {
// Main portable variants.
Expand Down Expand Up @@ -5808,7 +5892,6 @@ RValue CodeGenFunction::EmitBuiltinExpr(const GlobalDecl GD, unsigned BuiltinID,
Name),
{NDRange, Kernel, Block}));
}

case Builtin::BI__builtin_store_half:
case Builtin::BI__builtin_store_halff: {
Value *Val = EmitScalarExpr(E->getArg(0));
Expand Down Expand Up @@ -18224,6 +18307,14 @@ Value *CodeGenFunction::EmitHLSLBuiltinExpr(unsigned BuiltinID,
/*ReturnType=*/Op0->getType(), Intrinsic::dx_rsqrt,
ArrayRef<Value *>{Op0}, nullptr, "dx.rsqrt");
}
case Builtin::BI__builtin_hlsl_wave_get_lane_index: {
auto *CI = EmitRuntimeCall(CGM.CreateRuntimeFunction(
llvm::FunctionType::get(IntTy, {}, false), "__hlsl_wave_get_lane_index",
{}, false, true));
if (getTarget().getTriple().isSPIRVLogical())
CI = dyn_cast<CallInst>(addControlledConvergenceToken(CI));
return CI;
}
}
return nullptr;
}
Expand Down
6 changes: 5 additions & 1 deletion clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4719,7 +4719,8 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
}

if (HasAggregateEvalKind && isa<ImplicitCastExpr>(E) &&
cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue) {
cast<CastExpr>(E)->getCastKind() == CK_LValueToRValue &&
!type->isArrayParameterType()) {
LValue L = EmitLValue(cast<CastExpr>(E)->getSubExpr());
assert(L.isSimple());
args.addUncopiedAggregate(L, type);
Expand Down Expand Up @@ -5715,6 +5716,9 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (!CI->getType()->isVoidTy())
CI->setName("call");

if (getTarget().getTriple().isSPIRVLogical() && CI->isConvergent())
CI = addControlledConvergenceToken(CI);

// Update largest vector width from the return type.
LargestVectorWidth =
std::max(LargestVectorWidth, getMaxVectorWidth(CI->getType()));
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1440,8 +1440,7 @@ static unsigned getDwarfCC(CallingConv CC) {
case CC_Swift:
return llvm::dwarf::DW_CC_LLVM_Swift;
case CC_SwiftAsync:
// [FIXME: swiftasynccc] Update to SwiftAsync once LLVM support lands.
return llvm::dwarf::DW_CC_LLVM_Swift;
return llvm::dwarf::DW_CC_LLVM_SwiftTail;
case CC_PreserveMost:
return llvm::dwarf::DW_CC_LLVM_PreserveMost;
case CC_PreserveAll:
Expand Down Expand Up @@ -3642,6 +3641,7 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
case Type::ConstantArray:
case Type::VariableArray:
case Type::IncompleteArray:
case Type::ArrayParameter:
return CreateType(cast<ArrayType>(Ty), Unit);

case Type::LValueReference:
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,7 @@ using namespace CodeGen;
// Experiment to make sanitizers easier to debug
static llvm::cl::opt<bool> ClSanitizeDebugDeoptimization(
"ubsan-unique-traps", llvm::cl::Optional,
llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"),
llvm::cl::init(false));
llvm::cl::desc("Deoptimize traps for UBSAN so there is 1 trap per check"));

//===--------------------------------------------------------------------===//
// Miscellaneous Helper Methods
Expand Down Expand Up @@ -5190,6 +5189,7 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
case CK_IntegralToFixedPoint:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLArrayRValue:
return EmitUnsupportedLValue(E, "unexpected cast lvalue");

case CK_Dependent:
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/CGExprAgg.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -883,6 +883,9 @@ void AggExprEmitter::VisitCastExpr(CastExpr *E) {

[[fallthrough]];

case CK_HLSLArrayRValue:
Visit(E->getSubExpr());
break;

case CK_NoOp:
case CK_UserDefinedConversion:
Expand Down Expand Up @@ -1524,6 +1527,7 @@ static bool castPreservesZero(const CastExpr *CE) {
case CK_LValueToRValue:
case CK_LValueToRValueBitCast:
case CK_UncheckedDerivedToBase:
case CK_HLSLArrayRValue:
return false;
}
llvm_unreachable("Unhandled clang::CastKind enum");
Expand Down
8 changes: 6 additions & 2 deletions clang/lib/CodeGen/CGExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -354,8 +354,12 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (IsImplicitObjectCXXThis || isa<DeclRefExpr>(IOA))
SkippedChecks.set(SanitizerKind::Null, true);
}
EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc, This,
C.getRecordType(CalleeDecl->getParent()), SkippedChecks);

if (sanitizePerformTypeCheck())
EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc,
This.emitRawPointer(*this),
C.getRecordType(CalleeDecl->getParent()),
/*Alignment=*/CharUnits::Zero(), SkippedChecks);

// C++ [class.virtual]p12:
// Explicit qualification with the scope operator (5.1) suppresses the
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/CodeGen/CGExprComplex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ class ComplexExprEmitter
const BinOpInfo &Op);

QualType GetHigherPrecisionFPType(QualType ElementType) {
const auto *CurrentBT = dyn_cast<BuiltinType>(ElementType);
const auto *CurrentBT = cast<BuiltinType>(ElementType);
switch (CurrentBT->getKind()) {
case BuiltinType::Kind::Float16:
return CGF.getContext().FloatTy;
Expand Down Expand Up @@ -616,6 +616,7 @@ ComplexPairTy ComplexExprEmitter::EmitCast(CastKind CK, Expr *Op,
case CK_IntegralToFixedPoint:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLArrayRValue:
llvm_unreachable("invalid cast kind for complex value");

case CK_FloatingRealToComplex:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1226,6 +1226,7 @@ class ConstExprEmitter :
case CK_ZeroToOCLOpaqueType:
case CK_MatrixCast:
case CK_HLSLVectorTruncation:
case CK_HLSLArrayRValue:
return nullptr;
}
llvm_unreachable("Invalid CastKind");
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CGExprScalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2329,6 +2329,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
case CK_FloatingComplexToIntegralComplex:
case CK_ConstructorConversion:
case CK_ToUnion:
case CK_HLSLArrayRValue:
llvm_unreachable("scalar cast to non-scalar value");

case CK_LValueToRValue:
Expand Down
7 changes: 6 additions & 1 deletion clang/lib/CodeGen/CGLoopInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,10 @@ class LoopInfo {
/// been processed.
void finish();

/// Returns the first outer loop containing this loop if any, nullptr
/// otherwise.
const LoopInfo *getParent() const { return Parent; }

private:
/// Loop ID metadata.
llvm::TempMDTuple TempLoopID;
Expand Down Expand Up @@ -291,12 +295,13 @@ class LoopInfoStack {
/// Set no progress for the next loop pushed.
void setMustProgress(bool P) { StagedAttrs.MustProgress = P; }

private:
/// Returns true if there is LoopInfo on the stack.
bool hasInfo() const { return !Active.empty(); }
/// Return the LoopInfo for the current loop. HasInfo should be called
/// first to ensure LoopInfo is present.
const LoopInfo &getInfo() const { return *Active.back(); }

private:
/// The set of attributes that will be applied to the next pushed loop.
LoopAttributes StagedAttrs;
/// Stack of active loops.
Expand Down
394 changes: 294 additions & 100 deletions clang/lib/CodeGen/CGRecordLayoutBuilder.cpp

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ TypeEvaluationKind CodeGenFunction::getEvaluationKind(QualType type) {
case Type::Record:
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ArrayParameter:
return TEK_Aggregate;

// We operate on atomic values according to their underlying type.
Expand Down Expand Up @@ -2361,6 +2362,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
type = cast<MemberPointerType>(ty)->getPointeeType();
break;

case Type::ArrayParameter:
case Type::ConstantArray:
case Type::IncompleteArray:
// Losing element qualification here is fine.
Expand Down
19 changes: 19 additions & 0 deletions clang/lib/CodeGen/CodeGenFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4985,6 +4985,25 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::Value *emitBoolVecConversion(llvm::Value *SrcVec,
unsigned NumElementsDst,
const llvm::Twine &Name = "");
// Adds a convergence_ctrl token to |Input| and emits the required parent
// convergence instructions.
llvm::CallBase *addControlledConvergenceToken(llvm::CallBase *Input);

private:
// Emits a convergence_loop instruction for the given |BB|, with |ParentToken|
// as it's parent convergence instr.
llvm::IntrinsicInst *emitConvergenceLoopToken(llvm::BasicBlock *BB,
llvm::Value *ParentToken);
// Adds a convergence_ctrl token with |ParentToken| as parent convergence
// instr to the call |Input|.
llvm::CallBase *addConvergenceControlToken(llvm::CallBase *Input,
llvm::Value *ParentToken);
// Find the convergence_entry instruction |F|, or emits ones if none exists.
// Returns the convergence instruction.
llvm::IntrinsicInst *getOrEmitConvergenceEntryToken(llvm::Function *F);
// Find the convergence_loop instruction for the loop defined by |LI|, or
// emits one if none exists. Returns the convergence instruction.
llvm::IntrinsicInst *getOrEmitConvergenceLoopToken(const LoopInfo *LI);

private:
llvm::MDNode *getRangeForLoadFromType(QualType Ty);
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/CodeGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
ResultType = llvm::ArrayType::get(ResultType, 0);
break;
}
case Type::ArrayParameter:
case Type::ConstantArray: {
const ConstantArrayType *A = cast<ConstantArrayType>(Ty);
llvm::Type *EltTy = ConvertTypeForMem(A->getElementType());
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/CodeGen/ItaniumCXXABI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3584,6 +3584,9 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty) {
case Type::Pipe:
llvm_unreachable("Pipe types shouldn't get here");

case Type::ArrayParameter:
llvm_unreachable("Array Parameter types should not get here.");

case Type::Builtin:
case Type::BitInt:
// GCC treats vector and complex types as fundamental types.
Expand Down Expand Up @@ -3868,6 +3871,7 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
case Type::ConstantArray:
case Type::IncompleteArray:
case Type::VariableArray:
case Type::ArrayParameter:
// Itanium C++ ABI 2.9.5p5:
// abi::__array_type_info adds no data members to std::type_info.
break;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/Targets/PPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ void AIXTargetCodeGenInfo::setTargetAttributes(
if (!isa<llvm::GlobalVariable>(GV))
return;

auto *GVar = dyn_cast<llvm::GlobalVariable>(GV);
auto *GVar = cast<llvm::GlobalVariable>(GV);
auto GVId = GV->getName();

// Is this a global variable specified by the user as toc-data?
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Driver/ToolChains/AIX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,7 @@ static void addTocDataOptions(const llvm::opt::ArgList &Args,
// the global setting of tocdata in TOCDataGloballyinEffect.
// Those that have the opposite setting to TOCDataGloballyinEffect, are added
// to ExplicitlySpecifiedGlobals.
llvm::StringSet<> ExplicitlySpecifiedGlobals;
std::set<llvm::StringRef> ExplicitlySpecifiedGlobals;
for (const auto Arg :
Args.filtered(options::OPT_mtocdata_EQ, options::OPT_mno_tocdata_EQ)) {
TOCDataSetting ArgTocDataSetting =
Expand All @@ -486,7 +486,7 @@ static void addTocDataOptions(const llvm::opt::ArgList &Args,
ExplicitlySpecifiedGlobals.erase(Val);
}

auto buildExceptionList = [](const llvm::StringSet<> &ExplicitValues,
auto buildExceptionList = [](const std::set<llvm::StringRef> &ExplicitValues,
const char *OptionSpelling) {
std::string Option(OptionSpelling);
bool IsFirst = true;
Expand All @@ -495,7 +495,7 @@ static void addTocDataOptions(const llvm::opt::ArgList &Args,
Option += ",";

IsFirst = false;
Option += E.first();
Option += E.str();
}
return Option;
};
Expand Down
58 changes: 22 additions & 36 deletions clang/lib/Driver/ToolChains/CommonArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1075,53 +1075,38 @@ void tools::addLTOOptions(const ToolChain &ToolChain, const ArgList &Args,

/// Adds the '-lcgpu' and '-lmgpu' libraries to the compilation to include the
/// LLVM C library for GPUs.
static void addOpenMPDeviceLibC(const ToolChain &TC, const ArgList &Args,
static void addOpenMPDeviceLibC(const Compilation &C, const ArgList &Args,
ArgStringList &CmdArgs) {
if (Args.hasArg(options::OPT_nogpulib) || Args.hasArg(options::OPT_nolibc))
return;

// Check the resource directory for the LLVM libc GPU declarations. If it's
// found we can assume that LLVM was built with support for the GPU libc.
SmallString<256> LibCDecls(TC.getDriver().ResourceDir);
SmallString<256> LibCDecls(C.getDriver().ResourceDir);
llvm::sys::path::append(LibCDecls, "include", "llvm_libc_wrappers",
"llvm-libc-decls");
bool HasLibC = llvm::sys::fs::exists(LibCDecls) &&
llvm::sys::fs::is_directory(LibCDecls);
if (!Args.hasFlag(options::OPT_gpulibc, options::OPT_nogpulibc, HasLibC))
return;

// We don't have access to the offloading toolchains here, so determine from
// the arguments if we have any active NVPTX or AMDGPU toolchains.
llvm::DenseSet<const char *> Libraries;
if (const Arg *Targets = Args.getLastArg(options::OPT_fopenmp_targets_EQ)) {
if (llvm::any_of(Targets->getValues(),
[](auto S) { return llvm::Triple(S).isAMDGPU(); })) {
Libraries.insert("-lcgpu-amdgpu");
Libraries.insert("-lmgpu-amdgpu");
}
if (llvm::any_of(Targets->getValues(),
[](auto S) { return llvm::Triple(S).isNVPTX(); })) {
Libraries.insert("-lcgpu-nvptx");
Libraries.insert("-lmgpu-nvptx");
}
}
SmallVector<const ToolChain *> ToolChains;
auto TCRange = C.getOffloadToolChains(Action::OFK_OpenMP);
for (auto TI = TCRange.first, TE = TCRange.second; TI != TE; ++TI)
ToolChains.push_back(TI->second);

for (StringRef Arch : Args.getAllArgValues(options::OPT_offload_arch_EQ)) {
if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
return IsAMDGpuArch(StringToCudaArch(Str));
})) {
Libraries.insert("-lcgpu-amdgpu");
Libraries.insert("-lmgpu-amdgpu");
}
if (llvm::any_of(llvm::split(Arch, ","), [](StringRef Str) {
return IsNVIDIAGpuArch(StringToCudaArch(Str));
})) {
Libraries.insert("-lcgpu-nvptx");
Libraries.insert("-lmgpu-nvptx");
}
if (llvm::any_of(ToolChains, [](const ToolChain *TC) {
return TC->getTriple().isAMDGPU();
})) {
CmdArgs.push_back("-lcgpu-amdgpu");
CmdArgs.push_back("-lmgpu-amdgpu");
}
if (llvm::any_of(ToolChains, [](const ToolChain *TC) {
return TC->getTriple().isNVPTX();
})) {
CmdArgs.push_back("-lcgpu-nvptx");
CmdArgs.push_back("-lmgpu-nvptx");
}

llvm::append_range(CmdArgs, Libraries);
}

void tools::addOpenMPRuntimeLibraryPath(const ToolChain &TC,
Expand Down Expand Up @@ -1153,9 +1138,10 @@ void tools::addArchSpecificRPath(const ToolChain &TC, const ArgList &Args,
}
}

bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
const ArgList &Args, bool ForceStaticHostRuntime,
bool IsOffloadingHost, bool GompNeedsRT) {
bool tools::addOpenMPRuntime(const Compilation &C, ArgStringList &CmdArgs,
const ToolChain &TC, const ArgList &Args,
bool ForceStaticHostRuntime, bool IsOffloadingHost,
bool GompNeedsRT) {
if (!Args.hasFlag(options::OPT_fopenmp, options::OPT_fopenmp_EQ,
options::OPT_fno_openmp, false))
return false;
Expand Down Expand Up @@ -1196,7 +1182,7 @@ bool tools::addOpenMPRuntime(ArgStringList &CmdArgs, const ToolChain &TC,
CmdArgs.push_back("-lomptarget.devicertl");

if (IsOffloadingHost)
addOpenMPDeviceLibC(TC, Args, CmdArgs);
addOpenMPDeviceLibC(C, Args, CmdArgs);

addArchSpecificRPath(TC, Args, CmdArgs);
addOpenMPRuntimeLibraryPath(TC, Args, CmdArgs);
Expand Down
4 changes: 2 additions & 2 deletions clang/lib/Driver/ToolChains/CommonArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ void addOpenMPRuntimeLibraryPath(const ToolChain &TC,
const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs);
/// Returns true, if an OpenMP runtime has been added.
bool addOpenMPRuntime(llvm::opt::ArgStringList &CmdArgs, const ToolChain &TC,
const llvm::opt::ArgList &Args,
bool addOpenMPRuntime(const Compilation &C, llvm::opt::ArgStringList &CmdArgs,
const ToolChain &TC, const llvm::opt::ArgList &Args,
bool ForceStaticHostRuntime = false,
bool IsOffloadingHost = false, bool GompNeedsRT = false);

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Darwin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,7 +686,7 @@ void darwin::Linker::ConstructJob(Compilation &C, const JobAction &JA,
}

if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs))
addOpenMPRuntime(CmdArgs, getToolChain(), Args);
addOpenMPRuntime(C, CmdArgs, getToolChain(), Args);

if (isObjCRuntimeLinked(Args) &&
!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/DragonFly.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA,

// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);

if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/FreeBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
!Args.hasArg(options::OPT_static);
addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);

if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ void tools::gnutools::Linker::ConstructJob(Compilation &C, const JobAction &JA,

// FIXME: Only pass GompNeedsRT = true for platforms with libgomp that
// require librt. Most modern Linux platforms do, but some may not.
if (addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP,
if (addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP,
JA.isHostOffloading(Action::OFK_OpenMP),
/* GompNeedsRT= */ true))
// OpenMP runtimes implies pthreads when using the GNU toolchain.
Expand Down
4 changes: 1 addition & 3 deletions clang/lib/Driver/ToolChains/HLSL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,7 @@ HLSLToolChain::TranslateArgs(const DerivedArgList &Args, StringRef BoundArch,
if (!DAL->hasArg(options::OPT_O_Group)) {
DAL->AddJoinedArg(nullptr, Opts.getOption(options::OPT_O), "3");
}
// FIXME: add validation for enable_16bit_types should be after HLSL 2018 and
// shader model 6.2.
// See: https://github.com/llvm/llvm-project/issues/57876

return DAL;
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Haiku.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ void haiku::Linker::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_r)) {
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);

if (D.CCCIsCXX() && ToolChain.ShouldLinkCXXStdlib(Args))
ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Driver/ToolChains/MSVC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
CmdArgs.push_back(
Args.MakeArgString(std::string("-out:") + Output.getFilename()));

if (Args.hasArg(options::OPT_marm64x))
CmdArgs.push_back("-machine:arm64x");
else if (TC.getTriple().isWindowsArm64EC())
CmdArgs.push_back("-machine:arm64ec");

if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles) &&
!C.getDriver().IsCLMode() && !C.getDriver().IsFlangMode()) {
CmdArgs.push_back("-defaultlib:libcmt");
Expand Down Expand Up @@ -1017,4 +1022,7 @@ void MSVCToolChain::addClangTargetOptions(
if (DriverArgs.hasFlag(options::OPT_fno_rtti, options::OPT_frtti,
/*Default=*/false))
CC1Args.push_back("-D_HAS_STATIC_RTTI=0");

if (Arg *A = DriverArgs.getLastArgNoClaim(options::OPT_marm64x))
A->ignoreTargetSpecific();
}
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/NetBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ void netbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_r)) {
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);

if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/OpenBSD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
options::OPT_r)) {
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static;
addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);

if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/Driver/ToolChains/Solaris.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
// Use the static OpenMP runtime with -static-openmp
bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) &&
!Args.hasArg(options::OPT_static);
addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP);
addOpenMPRuntime(C, CmdArgs, ToolChain, Args, StaticOpenMP);

if (D.CCCIsCXX()) {
if (ToolChain.ShouldLinkCXXStdlib(Args))
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Edit/RewriteObjCFoundationAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,7 @@ static bool rewriteToNumericBoxedExpression(const ObjCMessageExpr *Msg,
case CK_LValueToRValue:
case CK_NoOp:
case CK_UserDefinedConversion:
case CK_HLSLArrayRValue:
break;

case CK_IntegralCast: {
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Format/TokenAnnotator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4827,6 +4827,10 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
Right.is(TT_TemplateOpener)) {
return true;
}
if (Left.is(tok::identifier) && Right.is(tok::numeric_constant) &&
Right.TokenText[0] == '.') {
return false;
}
} else if (Style.isProto()) {
if (Right.is(tok::period) &&
Left.isOneOf(Keywords.kw_optional, Keywords.kw_required,
Expand Down
46 changes: 28 additions & 18 deletions clang/lib/Frontend/CompilerInstance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1206,16 +1206,6 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
// Note the name of the module we're building.
Invocation->getLangOpts().CurrentModule = std::string(ModuleName);

// Make sure that the failed-module structure has been allocated in
// the importing instance, and propagate the pointer to the newly-created
// instance.
PreprocessorOptions &ImportingPPOpts
= ImportingInstance.getInvocation().getPreprocessorOpts();
if (!ImportingPPOpts.FailedModules)
ImportingPPOpts.FailedModules =
std::make_shared<PreprocessorOptions::FailedModulesSet>();
PPOpts.FailedModules = ImportingPPOpts.FailedModules;

// If there is a module map file, build the module using the module map.
// Set up the inputs/outputs so that we build the module from its umbrella
// header.
Expand Down Expand Up @@ -1269,6 +1259,13 @@ compileModuleImpl(CompilerInstance &ImportingInstance, SourceLocation ImportLoc,
SourceMgr.pushModuleBuildStack(ModuleName,
FullSourceLoc(ImportLoc, ImportingInstance.getSourceManager()));

// Make sure that the failed-module structure has been allocated in
// the importing instance, and propagate the pointer to the newly-created
// instance.
if (!ImportingInstance.hasFailedModulesSet())
ImportingInstance.createFailedModulesSet();
Instance.setFailedModulesSet(ImportingInstance.getFailedModulesSetPtr());

// If we're collecting module dependencies, we need to share a collector
// between all of the module CompilerInstances. Other than that, we don't
// want to produce any dependency output from the module build.
Expand Down Expand Up @@ -1337,9 +1334,24 @@ static bool compileModule(CompilerInstance &ImportingInstance,
// Get or create the module map that we'll use to build this module.
ModuleMap &ModMap
= ImportingInstance.getPreprocessor().getHeaderSearchInfo().getModuleMap();
SourceManager &SourceMgr = ImportingInstance.getSourceManager();
bool Result;
if (OptionalFileEntryRef ModuleMapFile =
ModMap.getContainingModuleMapFile(Module)) {
if (FileID ModuleMapFID = ModMap.getContainingModuleMapFileID(Module);
ModuleMapFID.isValid()) {
// We want to use the top-level module map. If we don't, the compiling
// instance may think the containing module map is a top-level one, while
// the importing instance knows it's included from a parent module map via
// the extern directive. This mismatch could bite us later.
SourceLocation Loc = SourceMgr.getIncludeLoc(ModuleMapFID);
while (Loc.isValid() && isModuleMap(SourceMgr.getFileCharacteristic(Loc))) {
ModuleMapFID = SourceMgr.getFileID(Loc);
Loc = SourceMgr.getIncludeLoc(ModuleMapFID);
}

OptionalFileEntryRef ModuleMapFile =
SourceMgr.getFileEntryRefForID(ModuleMapFID);
assert(ModuleMapFile && "Top-level module map with no FileID");

// Canonicalize compilation to start with the public module map. This is
// vital for submodules declarations in the private module maps to be
// correctly parsed when depending on a top level module in the public one.
Expand Down Expand Up @@ -1977,10 +1989,8 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
return nullptr;
}

// Check whether we have already attempted to build this module (but
// failed).
if (getPreprocessorOpts().FailedModules &&
getPreprocessorOpts().FailedModules->hasAlreadyFailed(ModuleName)) {
// Check whether we have already attempted to build this module (but failed).
if (FailedModules && FailedModules->hasAlreadyFailed(ModuleName)) {
getDiagnostics().Report(ModuleNameLoc, diag::err_module_not_built)
<< ModuleName << SourceRange(ImportLoc, ModuleNameLoc);
return nullptr;
Expand All @@ -1991,8 +2001,8 @@ ModuleLoadResult CompilerInstance::findOrCompileModuleAndReadAST(
ModuleFilename)) {
assert(getDiagnostics().hasErrorOccurred() &&
"undiagnosed error in compileModuleAndReadAST");
if (getPreprocessorOpts().FailedModules)
getPreprocessorOpts().FailedModules->addFailed(ModuleName);
if (FailedModules)
FailedModules->addFailed(ModuleName);
return nullptr;
}

Expand Down
19 changes: 19 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4284,11 +4284,30 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
<< ShaderModel << T.getOSName() << T.str();
}
// Validate that if fnative-half-type is given, that
// the language standard is at least hlsl2018, and that
// the target shader model is at least 6.2.
if (Args.getLastArg(OPT_fnative_half_type)) {
const LangStandard &Std =
LangStandard::getLangStandardForKind(Opts.LangStd);
if (!(Opts.LangStd >= LangStandard::lang_hlsl2018 &&
T.getOSVersion() >= VersionTuple(6, 2)))
Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
<< "-enable-16bit-types" << true << Std.getName()
<< T.getOSVersion().getAsString();
}
} else if (T.isSPIRVLogical()) {
if (!T.isVulkanOS() || T.getVulkanVersion() == VersionTuple(0)) {
Diags.Report(diag::err_drv_hlsl_bad_shader_unsupported)
<< VulkanEnv << T.getOSName() << T.str();
}
if (Args.getLastArg(OPT_fnative_half_type)) {
const LangStandard &Std =
LangStandard::getLangStandardForKind(Opts.LangStd);
if (!(Opts.LangStd >= LangStandard::lang_hlsl2018))
Diags.Report(diag::err_drv_hlsl_16bit_types_unsupported)
<< "-fnative-half-type" << false << Std.getName();
}
} else {
llvm_unreachable("expected DXIL or SPIR-V target");
}
Expand Down
10 changes: 8 additions & 2 deletions clang/lib/Frontend/FrontendAction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -535,8 +535,14 @@ static Module *prepareToBuildModule(CompilerInstance &CI,
if (*OriginalModuleMap != CI.getSourceManager().getFileEntryRefForID(
CI.getSourceManager().getMainFileID())) {
M->IsInferred = true;
CI.getPreprocessor().getHeaderSearchInfo().getModuleMap()
.setInferredModuleAllowedBy(M, *OriginalModuleMap);
auto FileCharacter =
M->IsSystem ? SrcMgr::C_System_ModuleMap : SrcMgr::C_User_ModuleMap;
FileID OriginalModuleMapFID = CI.getSourceManager().getOrCreateFileID(
*OriginalModuleMap, FileCharacter);
CI.getPreprocessor()
.getHeaderSearchInfo()
.getModuleMap()
.setInferredModuleAllowedBy(M, OriginalModuleMapFID);
}
}

Expand Down
7 changes: 6 additions & 1 deletion clang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,10 @@ void InitOnlyAction::ExecuteAction() {

// Basically PreprocessOnlyAction::ExecuteAction.
void ReadPCHAndPreprocessAction::ExecuteAction() {
Preprocessor &PP = getCompilerInstance().getPreprocessor();
CompilerInstance &CI = getCompilerInstance();
AdjustCI(CI);

Preprocessor &PP = CI.getPreprocessor();

// Ignore unknown pragmas.
PP.IgnorePragmas();
Expand Down Expand Up @@ -1188,6 +1191,8 @@ void PrintDependencyDirectivesSourceMinimizerAction::ExecuteAction() {

void GetDependenciesByModuleNameAction::ExecuteAction() {
CompilerInstance &CI = getCompilerInstance();
AdjustCI(CI);

Preprocessor &PP = CI.getPreprocessor();
SourceManager &SM = PP.getSourceManager();
FileID MainFileID = SM.getMainFileID();
Expand Down
41 changes: 14 additions & 27 deletions clang/lib/Headers/hlsl/hlsl_intrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -243,15 +243,6 @@ float3 ceil(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
float4 ceil(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
double ceil(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
double2 ceil(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
double3 ceil(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_ceil)
double4 ceil(double4);

//===----------------------------------------------------------------------===//
// clamp builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -585,15 +576,6 @@ float3 floor(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor)
float4 floor(float4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor)
double floor(double);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor)
double2 floor(double2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor)
double3 floor(double3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_floor)
double4 floor(double4);

//===----------------------------------------------------------------------===//
// frac builtins
//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1266,25 +1248,25 @@ float4 rsqrt(float4);
/// rounded to the nearest even value.

_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
half round(half);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
half2 round(half2);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
half3 round(half3);
_HLSL_16BIT_AVAILABILITY(shadermodel, 6.2)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
half4 round(half4);

_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
float round(float);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
float2 round(float2);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
float3 round(float3);
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_round)
_HLSL_BUILTIN_ALIAS(__builtin_elementwise_roundeven)
float4 round(float4);

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -1389,7 +1371,12 @@ float4 trunc(float4);
/// true, across all active lanes in the current wave.
_HLSL_AVAILABILITY(shadermodel, 6.0)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_active_count_bits)
uint WaveActiveCountBits(bool Val);
__attribute__((convergent)) uint WaveActiveCountBits(bool Val);

/// \brief Returns the index of the current lane within the current wave.
_HLSL_AVAILABILITY(shadermodel, 6.0)
_HLSL_BUILTIN_ALIAS(__builtin_hlsl_wave_get_lane_index)
__attribute__((convergent)) uint WaveGetLaneIndex();

} // namespace hlsl
#endif //_HLSL_HLSL_INTRINSICS_H_
1 change: 1 addition & 0 deletions clang/lib/InstallAPI/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
set(LLVM_LINK_COMPONENTS
Support
TextAPI
TextAPIBinaryReader
Demangle
Core
)
Expand Down
71 changes: 54 additions & 17 deletions clang/lib/InstallAPI/DylibVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include "clang/InstallAPI/FrontendRecords.h"
#include "clang/InstallAPI/InstallAPIDiagnostic.h"
#include "llvm/Demangle/Demangle.h"
#include "llvm/TextAPI/DylibReader.h"

using namespace llvm::MachO;

Expand All @@ -35,6 +36,14 @@ struct DylibVerifier::SymbolContext {
bool Inlined = false;
};

struct DylibVerifier::DWARFContext {
// Track whether DSYM parsing has already been attempted to avoid re-parsing.
bool ParsedDSYM{false};

// Lookup table for source locations by symbol name.
DylibReader::SymbolToSourceLocMap SourceLocs{};
};

static bool isCppMangled(StringRef Name) {
// InstallAPI currently only supports itanium manglings.
return (Name.starts_with("_Z") || Name.starts_with("__Z") ||
Expand Down Expand Up @@ -511,14 +520,16 @@ DylibVerifier::Result DylibVerifier::verify(GlobalRecord *R,
return verifyImpl(R, SymCtx);
}

void DylibVerifier::VerifierContext::emitDiag(
llvm::function_ref<void()> Report) {
void DylibVerifier::VerifierContext::emitDiag(llvm::function_ref<void()> Report,
RecordLoc *Loc) {
if (!DiscoveredFirstError) {
Diag->Report(diag::warn_target)
<< (PrintArch ? getArchitectureName(Target.Arch)
: getTargetTripleName(Target));
DiscoveredFirstError = true;
}
if (Loc && Loc->isValid())
llvm::errs() << Loc->File << ":" << Loc->Line << ":" << 0 << ": ";

Report();
}
Expand Down Expand Up @@ -561,37 +572,49 @@ void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) {
return;
}

// All checks at this point classify as some kind of violation that should be
// reported.
const bool IsLinkerSymbol = SymbolName.starts_with("$ld$");

// All checks at this point classify as some kind of violation.
// The different verification modes dictate whether they are reported to the
// user.
if (IsLinkerSymbol || (Mode > VerificationMode::ErrorsOnly))
accumulateSrcLocForDylibSymbols();
RecordLoc Loc = DWARFCtx->SourceLocs.lookup(SymCtx.SymbolName);

// Regardless of verification mode, error out on mismatched special linker
// symbols.
if (SymbolName.starts_with("$ld$")) {
Ctx.emitDiag([&]() {
Ctx.Diag->Report(diag::err_header_symbol_missing)
<< getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false);
});
if (IsLinkerSymbol) {
Ctx.emitDiag(
[&]() {
Ctx.Diag->Report(diag::err_header_symbol_missing)
<< getAnnotatedName(&R, SymCtx, Loc.isValid());
},
&Loc);
updateState(Result::Invalid);
return;
}

// Missing declarations for exported symbols are hard errors on Pedantic mode.
if (Mode == VerificationMode::Pedantic) {
Ctx.emitDiag([&]() {
Ctx.Diag->Report(diag::err_header_symbol_missing)
<< getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false);
});
Ctx.emitDiag(
[&]() {
Ctx.Diag->Report(diag::err_header_symbol_missing)
<< getAnnotatedName(&R, SymCtx, Loc.isValid());
},
&Loc);
updateState(Result::Invalid);
return;
}

// Missing declarations for exported symbols are warnings on ErrorsAndWarnings
// mode.
if (Mode == VerificationMode::ErrorsAndWarnings) {
Ctx.emitDiag([&]() {
Ctx.Diag->Report(diag::warn_header_symbol_missing)
<< getAnnotatedName(&R, SymCtx, /*ValidSourceLoc=*/false);
});
Ctx.emitDiag(
[&]() {
Ctx.Diag->Report(diag::warn_header_symbol_missing)
<< getAnnotatedName(&R, SymCtx, Loc.isValid());
},
&Loc);
updateState(Result::Ignore);
return;
}
Expand Down Expand Up @@ -622,6 +645,18 @@ void DylibVerifier::visitObjCIVar(const ObjCIVarRecord &R,
visitSymbolInDylib(R, SymCtx);
}

void DylibVerifier::accumulateSrcLocForDylibSymbols() {
if (DSYMPath.empty())
return;

assert(DWARFCtx != nullptr && "Expected an initialized DWARFContext");
if (DWARFCtx->ParsedDSYM)
return;
DWARFCtx->ParsedDSYM = true;
DWARFCtx->SourceLocs =
DylibReader::accumulateSourceLocFromDSYM(DSYMPath, Ctx.Target);
}

void DylibVerifier::visitObjCInterface(const ObjCInterfaceRecord &R) {
if (R.isVerified())
return;
Expand Down Expand Up @@ -655,6 +690,8 @@ DylibVerifier::Result DylibVerifier::verifyRemainingSymbols() {
return Result::NoVerify;
assert(!Dylib.empty() && "No binary to verify against");

DWARFContext DWARFInfo;
DWARFCtx = &DWARFInfo;
Ctx.DiscoveredFirstError = false;
Ctx.PrintArch = true;
for (std::shared_ptr<RecordsSlice> Slice : Dylib) {
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/Interpreter/Value.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//===--- Interpreter.h - Incremental Compiation and Execution---*- C++ -*-===//
//===------------ Value.cpp - Definition of interpreter value -------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
Expand All @@ -22,8 +22,6 @@
#include <cstdint>
#include <utility>

using namespace clang;

namespace {

// This is internal buffer maintained by Value, used to hold temporaries.
Expand Down Expand Up @@ -61,7 +59,7 @@ class ValueStorage {
void Release() {
assert(RefCnt > 0 && "Can't release if reference count is already zero");
if (--RefCnt == 0) {
// We hace a non-trivial dtor.
// We have a non-trivial dtor.
if (Dtor && IsAlive()) {
assert(Elements && "We at least should have 1 element in Value");
size_t Stride = AllocSize / Elements;
Expand Down Expand Up @@ -97,6 +95,8 @@ class ValueStorage {
};
} // namespace

namespace clang {

static Value::Kind ConvertQualTypeToKind(const ASTContext &Ctx, QualType QT) {
if (Ctx.hasSameType(QT, Ctx.VoidTy))
return Value::K_Void;
Expand Down Expand Up @@ -265,3 +265,5 @@ void Value::print(llvm::raw_ostream &Out) const {
assert(OpaqueType != nullptr && "Can't print default Value");
Out << "Not implement yet.\n";
}

} // namespace clang
66 changes: 36 additions & 30 deletions clang/lib/Lex/ModuleMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,7 @@ ModuleMap::findOrCreateModuleForHeaderInUmbrellaDir(FileEntryRef File) {
UmbrellaModule = UmbrellaModule->Parent;

if (UmbrellaModule->InferSubmodules) {
OptionalFileEntryRef UmbrellaModuleMap =
getModuleMapFileForUniquing(UmbrellaModule);
FileID UmbrellaModuleMap = getModuleMapFileIDForUniquing(UmbrellaModule);

// Infer submodules for each of the directories we found between
// the directory of the umbrella header and the directory where
Expand Down Expand Up @@ -1021,7 +1020,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,

// If the framework has a parent path from which we're allowed to infer
// a framework module, do so.
OptionalFileEntryRef ModuleMapFile;
FileID ModuleMapFID;
if (!Parent) {
// Determine whether we're allowed to infer a module map.
bool canInfer = false;
Expand Down Expand Up @@ -1060,7 +1059,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
Attrs.IsExhaustive |= inferred->second.Attrs.IsExhaustive;
Attrs.NoUndeclaredIncludes |=
inferred->second.Attrs.NoUndeclaredIncludes;
ModuleMapFile = inferred->second.ModuleMapFile;
ModuleMapFID = inferred->second.ModuleMapFID;
}
}
}
Expand All @@ -1069,7 +1068,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
if (!canInfer)
return nullptr;
} else {
ModuleMapFile = getModuleMapFileForUniquing(Parent);
ModuleMapFID = getModuleMapFileIDForUniquing(Parent);
}

// Look for an umbrella header.
Expand All @@ -1086,7 +1085,7 @@ Module *ModuleMap::inferFrameworkModule(DirectoryEntryRef FrameworkDir,
Module *Result = new Module(ModuleName, SourceLocation(), Parent,
/*IsFramework=*/true, /*IsExplicit=*/false,
NumCreatedModules++);
InferredModuleAllowedBy[Result] = ModuleMapFile;
InferredModuleAllowedBy[Result] = ModuleMapFID;
Result->IsInferred = true;
if (!Parent) {
if (LangOpts.CurrentModule == ModuleName)
Expand Down Expand Up @@ -1307,28 +1306,34 @@ void ModuleMap::addHeader(Module *Mod, Module::Header Header,
Cb->moduleMapAddHeader(Header.Entry.getName());
}

OptionalFileEntryRef
ModuleMap::getContainingModuleMapFile(const Module *Module) const {
FileID ModuleMap::getContainingModuleMapFileID(const Module *Module) const {
if (Module->DefinitionLoc.isInvalid())
return std::nullopt;
return {};

return SourceMgr.getFileEntryRefForID(
SourceMgr.getFileID(Module->DefinitionLoc));
return SourceMgr.getFileID(Module->DefinitionLoc);
}

OptionalFileEntryRef
ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
ModuleMap::getContainingModuleMapFile(const Module *Module) const {
return SourceMgr.getFileEntryRefForID(getContainingModuleMapFileID(Module));
}

FileID ModuleMap::getModuleMapFileIDForUniquing(const Module *M) const {
if (M->IsInferred) {
assert(InferredModuleAllowedBy.count(M) && "missing inferred module map");
return InferredModuleAllowedBy.find(M)->second;
}
return getContainingModuleMapFile(M);
return getContainingModuleMapFileID(M);
}

OptionalFileEntryRef
ModuleMap::getModuleMapFileForUniquing(const Module *M) const {
return SourceMgr.getFileEntryRefForID(getModuleMapFileIDForUniquing(M));
}

void ModuleMap::setInferredModuleAllowedBy(Module *M,
OptionalFileEntryRef ModMap) {
void ModuleMap::setInferredModuleAllowedBy(Module *M, FileID ModMapFID) {
assert(M->IsInferred && "module not inferred");
InferredModuleAllowedBy[M] = ModMap;
InferredModuleAllowedBy[M] = ModMapFID;
}

std::error_code
Expand Down Expand Up @@ -1517,7 +1522,7 @@ namespace clang {
ModuleMap &Map;

/// The current module map file.
FileEntryRef ModuleMapFile;
FileID ModuleMapFID;

/// Source location of most recent parsed module declaration
SourceLocation CurrModuleDeclLoc;
Expand Down Expand Up @@ -1585,13 +1590,12 @@ namespace clang {
bool parseOptionalAttributes(Attributes &Attrs);

public:
explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
const TargetInfo *Target, DiagnosticsEngine &Diags,
ModuleMap &Map, FileEntryRef ModuleMapFile,
DirectoryEntryRef Directory, bool IsSystem)
ModuleMapParser(Lexer &L, SourceManager &SourceMgr,
const TargetInfo *Target, DiagnosticsEngine &Diags,
ModuleMap &Map, FileID ModuleMapFID,
DirectoryEntryRef Directory, bool IsSystem)
: L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),
ModuleMapFile(ModuleMapFile), Directory(Directory),
IsSystem(IsSystem) {
ModuleMapFID(ModuleMapFID), Directory(Directory), IsSystem(IsSystem) {
Tok.clear();
consumeToken();
}
Expand Down Expand Up @@ -2011,11 +2015,13 @@ void ModuleMapParser::parseModuleDecl() {
}

if (TopLevelModule &&
ModuleMapFile != Map.getContainingModuleMapFile(TopLevelModule)) {
assert(ModuleMapFile != Map.getModuleMapFileForUniquing(TopLevelModule) &&
ModuleMapFID != Map.getContainingModuleMapFileID(TopLevelModule)) {
assert(ModuleMapFID !=
Map.getModuleMapFileIDForUniquing(TopLevelModule) &&
"submodule defined in same file as 'module *' that allowed its "
"top-level module");
Map.addAdditionalModuleMapFile(TopLevelModule, ModuleMapFile);
Map.addAdditionalModuleMapFile(
TopLevelModule, *SourceMgr.getFileEntryRefForID(ModuleMapFID));
}
}

Expand Down Expand Up @@ -2120,7 +2126,8 @@ void ModuleMapParser::parseModuleDecl() {
ActiveModule->NoUndeclaredIncludes = true;
ActiveModule->Directory = Directory;

StringRef MapFileName(ModuleMapFile.getName());
StringRef MapFileName(
SourceMgr.getFileEntryRefForID(ModuleMapFID)->getName());
if (MapFileName.ends_with("module.private.modulemap") ||
MapFileName.ends_with("module_private.map")) {
ActiveModule->ModuleMapIsPrivate = true;
Expand Down Expand Up @@ -2906,7 +2913,7 @@ void ModuleMapParser::parseInferredModuleDecl(bool Framework, bool Explicit) {
// We'll be inferring framework modules for this directory.
Map.InferredDirectories[Directory].InferModules = true;
Map.InferredDirectories[Directory].Attrs = Attrs;
Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
Map.InferredDirectories[Directory].ModuleMapFID = ModuleMapFID;
// FIXME: Handle the 'framework' keyword.
}

Expand Down Expand Up @@ -3139,8 +3146,7 @@ bool ModuleMap::parseModuleMapFile(FileEntryRef File, bool IsSystem,
Buffer->getBufferStart() + (Offset ? *Offset : 0),
Buffer->getBufferEnd());
SourceLocation Start = L.getSourceLocation();
ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
IsSystem);
ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, ID, Dir, IsSystem);
bool Result = Parser.parseModuleMapFile();
ParsedModuleMap[File] = Result;

Expand Down
12 changes: 3 additions & 9 deletions clang/lib/Lex/PPLexerChange.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,16 +93,10 @@ bool Preprocessor::EnterSourceFile(FileID FID, ConstSearchDirIterator CurDir,
}

Lexer *TheLexer = new Lexer(FID, *InputFile, *this, IsFirstIncludeOfFile);
if (getPreprocessorOpts().DependencyDirectivesForFile &&
FID != PredefinesFileID) {
if (OptionalFileEntryRef File = SourceMgr.getFileEntryRefForID(FID)) {
if (std::optional<ArrayRef<dependency_directives_scan::Directive>>
DepDirectives =
getPreprocessorOpts().DependencyDirectivesForFile(*File)) {
if (DependencyDirectivesForFile && FID != PredefinesFileID)
if (OptionalFileEntryRef File = SourceMgr.getFileEntryRefForID(FID))
if (auto DepDirectives = DependencyDirectivesForFile(*File))
TheLexer->DepDirectives = *DepDirectives;
}
}
}

EnterSourceFileWithLexer(TheLexer, CurDir);
return false;
Expand Down
21 changes: 11 additions & 10 deletions clang/lib/Parse/ParseOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "clang/Parse/ParseDiagnostic.h"
#include "clang/Parse/Parser.h"
#include "clang/Parse/RAIIObjectsForParser.h"
#include "clang/Sema/SemaOpenACC.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSwitch.h"

Expand Down Expand Up @@ -777,7 +778,7 @@ bool Parser::ParseOpenACCClause(OpenACCDirectiveKind DirKind) {
SourceLocation ClauseLoc = ConsumeToken();

bool Result = ParseOpenACCClauseParams(DirKind, Kind);
getActions().ActOnOpenACCClause(Kind, ClauseLoc);
getActions().OpenACC().ActOnClause(Kind, ClauseLoc);
return Result;
}

Expand Down Expand Up @@ -1151,7 +1152,7 @@ Parser::OpenACCDirectiveParseInfo Parser::ParseOpenACCDirective() {
SourceLocation StartLoc = getCurToken().getLocation();
OpenACCDirectiveKind DirKind = ParseOpenACCDirectiveKind(*this);

getActions().ActOnOpenACCConstruct(DirKind, StartLoc);
getActions().OpenACC().ActOnConstruct(DirKind, StartLoc);

// Once we've parsed the construct/directive name, some have additional
// specifiers that need to be taken care of. Atomic has an 'atomic-clause'
Expand Down Expand Up @@ -1223,12 +1224,12 @@ Parser::DeclGroupPtrTy Parser::ParseOpenACCDirectiveDecl() {

OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();

if (getActions().ActOnStartOpenACCDeclDirective(DirInfo.DirKind,
DirInfo.StartLoc))
if (getActions().OpenACC().ActOnStartDeclDirective(DirInfo.DirKind,
DirInfo.StartLoc))
return nullptr;

// TODO OpenACC: Do whatever decl parsing is required here.
return DeclGroupPtrTy::make(getActions().ActOnEndOpenACCDeclDirective());
return DeclGroupPtrTy::make(getActions().OpenACC().ActOnEndDeclDirective());
}

// Parse OpenACC Directive on a Statement.
Expand All @@ -1239,8 +1240,8 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() {
ConsumeAnnotationToken();

OpenACCDirectiveParseInfo DirInfo = ParseOpenACCDirective();
if (getActions().ActOnStartOpenACCStmtDirective(DirInfo.DirKind,
DirInfo.StartLoc))
if (getActions().OpenACC().ActOnStartStmtDirective(DirInfo.DirKind,
DirInfo.StartLoc))
return StmtError();

StmtResult AssocStmt;
Expand All @@ -1249,10 +1250,10 @@ StmtResult Parser::ParseOpenACCDirectiveStmt() {
ParsingOpenACCDirectiveRAII DirScope(*this, /*Value=*/false);
ParseScope ACCScope(this, getOpenACCScopeFlags(DirInfo.DirKind));

AssocStmt = getActions().ActOnOpenACCAssociatedStmt(DirInfo.DirKind,
ParseStatement());
AssocStmt = getActions().OpenACC().ActOnAssociatedStmt(DirInfo.DirKind,
ParseStatement());
}

return getActions().ActOnEndOpenACCStmtDirective(
return getActions().OpenACC().ActOnEndStmtDirective(
DirInfo.DirKind, DirInfo.StartLoc, DirInfo.EndLoc, AssocStmt);
}
1 change: 1 addition & 0 deletions clang/lib/Sema/JumpDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaInternal.h"
Expand Down
4 changes: 3 additions & 1 deletion clang/lib/Sema/Sema.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaConsumer.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/SemaOpenACC.h"
#include "clang/Sema/TemplateDeduction.h"
#include "clang/Sema/TemplateInstCallback.h"
#include "clang/Sema/TypoCorrection.h"
Expand Down Expand Up @@ -196,7 +197,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
ThreadSafetyDeclCache(nullptr), LateTemplateParser(nullptr),
LateTemplateParserCleanup(nullptr), OpaqueParser(nullptr),
CurContext(nullptr), ExternalSource(nullptr), CurScope(nullptr),
Ident_super(nullptr),
Ident_super(nullptr), OpenACCPtr(std::make_unique<SemaOpenACC>(*this)),
MSPointerToMemberRepresentationMethod(
LangOpts.getMSPointerToMemberRepresentationMethod()),
MSStructPragmaOn(false), VtorDispStack(LangOpts.getVtorDispMode()),
Expand Down Expand Up @@ -653,6 +654,7 @@ ExprResult Sema::ImpCastExprToType(Expr *E, QualType Ty,
case CK_FunctionToPointerDecay:
case CK_ToVoid:
case CK_NonAtomicToAtomic:
case CK_HLSLArrayRValue:
break;
}
}
Expand Down
40 changes: 37 additions & 3 deletions clang/lib/Sema/SemaChecking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5641,12 +5641,17 @@ bool Sema::CheckHLSLBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
return true;
break;
}
case Builtin::BI__builtin_elementwise_ceil:
case Builtin::BI__builtin_elementwise_cos:
case Builtin::BI__builtin_elementwise_sin:
case Builtin::BI__builtin_elementwise_exp:
case Builtin::BI__builtin_elementwise_exp2:
case Builtin::BI__builtin_elementwise_floor:
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_roundeven:
case Builtin::BI__builtin_elementwise_sin:
case Builtin::BI__builtin_elementwise_sqrt:
case Builtin::BI__builtin_elementwise_trunc: {
if (CheckFloatOrHalfRepresentations(this, TheCall))
Expand Down Expand Up @@ -12441,6 +12446,19 @@ isArithmeticArgumentPromotion(Sema &S, const ImplicitCastExpr *ICE) {
S.Context.getFloatingTypeOrder(From, To) < 0;
}

static analyze_format_string::ArgType::MatchKind
handleFormatSignedness(analyze_format_string::ArgType::MatchKind Match,
DiagnosticsEngine &Diags, SourceLocation Loc) {
if (Match == analyze_format_string::ArgType::NoMatchSignedness) {
Match =
Diags.isIgnored(
diag::warn_format_conversion_argument_type_mismatch_signedness, Loc)
? analyze_format_string::ArgType::Match
: analyze_format_string::ArgType::NoMatch;
}
return Match;
}

bool
CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
const char *StartSpecifier,
Expand Down Expand Up @@ -12484,6 +12502,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,

ArgType::MatchKind ImplicitMatch = ArgType::NoMatch;
ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy);
ArgType::MatchKind OrigMatch = Match;

Match = handleFormatSignedness(Match, S.getDiagnostics(), E->getExprLoc());
if (Match == ArgType::Match)
return true;

Expand All @@ -12507,6 +12528,14 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
ICE->getType() == S.Context.UnsignedIntTy) {
// All further checking is done on the subexpression
ImplicitMatch = AT.matchesType(S.Context, ExprTy);
if (OrigMatch == ArgType::NoMatchSignedness &&
ImplicitMatch != ArgType::NoMatchSignedness)
// If the original match was a signedness match this match on the
// implicit cast type also need to be signedness match otherwise we
// might introduce new unexpected warnings from -Wformat-signedness.
return true;
ImplicitMatch = handleFormatSignedness(
ImplicitMatch, S.getDiagnostics(), E->getExprLoc());
if (ImplicitMatch == ArgType::Match)
return true;
}
Expand Down Expand Up @@ -12628,6 +12657,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
case ArgType::Match:
case ArgType::MatchPromotion:
case ArgType::NoMatchPromotionTypeConfusion:
case ArgType::NoMatchSignedness:
llvm_unreachable("expected non-matching");
case ArgType::NoMatchPedantic:
Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
Expand Down Expand Up @@ -12663,8 +12693,10 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
CastFix << (S.LangOpts.CPlusPlus ? ">" : ")");

SmallVector<FixItHint,4> Hints;
if (AT.matchesType(S.Context, IntendedTy) != ArgType::Match ||
ShouldNotPrintDirectly)
ArgType::MatchKind IntendedMatch = AT.matchesType(S.Context, IntendedTy);
IntendedMatch = handleFormatSignedness(IntendedMatch, S.getDiagnostics(),
E->getExprLoc());
if ((IntendedMatch != ArgType::Match) || ShouldNotPrintDirectly)
Hints.push_back(FixItHint::CreateReplacement(SpecRange, os.str()));

if (const CStyleCastExpr *CCast = dyn_cast<CStyleCastExpr>(E)) {
Expand Down Expand Up @@ -12733,6 +12765,7 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
case ArgType::Match:
case ArgType::MatchPromotion:
case ArgType::NoMatchPromotionTypeConfusion:
case ArgType::NoMatchSignedness:
llvm_unreachable("expected non-matching");
case ArgType::NoMatchPedantic:
Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
Expand Down Expand Up @@ -12944,6 +12977,7 @@ bool CheckScanfHandler::HandleScanfSpecifier(

analyze_format_string::ArgType::MatchKind Match =
AT.matchesType(S.Context, Ex->getType());
Match = handleFormatSignedness(Match, S.getDiagnostics(), Ex->getExprLoc());
bool Pedantic = Match == analyze_format_string::ArgType::NoMatchPedantic;
if (Match == analyze_format_string::ArgType::Match)
return true;
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaConcept.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1281,6 +1281,8 @@ substituteParameterMappings(Sema &S, NormalizedConstraint &N,
S, InstLocBegin,
Sema::InstantiatingTemplate::ParameterMappingSubstitution{}, Concept,
{InstLocBegin, InstLocEnd});
if (Inst.isInvalid())
return true;
if (S.SubstTemplateArguments(*Atomic.ParameterMapping, MLTAL, SubstArgs))
return true;

Expand Down Expand Up @@ -1354,6 +1356,8 @@ NormalizedConstraint::fromConstraintExpr(Sema &S, NamedDecl *D, const Expr *E) {
S, CSE->getExprLoc(),
Sema::InstantiatingTemplate::ConstraintNormalization{}, D,
CSE->getSourceRange());
if (Inst.isInvalid())
return std::nullopt;
// C++ [temp.constr.normal]p1.1
// [...]
// The normal form of an id-expression of the form C<A1, A2, ..., AN>,
Expand Down
6 changes: 4 additions & 2 deletions clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9915,7 +9915,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// FIXME: We need a better way to separate C++ standard and clang modules.
bool ImplicitInlineCXX20 = !getLangOpts().CPlusPlusModules ||
!NewFD->getOwningModule() ||
NewFD->getOwningModule()->isGlobalModule() ||
NewFD->isFromExplicitGlobalModule() ||
NewFD->getOwningModule()->isHeaderLikeModule();
bool isInline = D.getDeclSpec().isInlineSpecified();
bool isVirtual = D.getDeclSpec().isVirtualSpecified();
Expand Down Expand Up @@ -18170,7 +18170,9 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
cast_or_null<RecordDecl>(PrevDecl));
}

if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus)
// Only C23 and later allow defining new types in 'offsetof()'.
if (OOK != OOK_Outside && TUK == TUK_Definition && !getLangOpts().CPlusPlus &&
!getLangOpts().C23)
Diag(New->getLocation(), diag::ext_type_defined_in_offsetof)
<< (OOK == OOK_Macro) << New->getSourceRange();

Expand Down
1 change: 1 addition & 0 deletions clang/lib/Sema/SemaDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13589,6 +13589,7 @@ Decl *Sema::ActOnAliasDeclaration(Scope *S, AccessSpecifier AS,
Diag(UsingLoc, diag::err_alias_template_extra_headers)
<< SourceRange(TemplateParamLists[1]->getTemplateLoc(),
TemplateParamLists[TemplateParamLists.size()-1]->getRAngleLoc());
Invalid = true;
}
TemplateParameterList *TemplateParams = TemplateParamLists[0];

Expand Down
10 changes: 8 additions & 2 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,8 +658,9 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E) {
QualType T = E->getType();
assert(!T.isNull() && "r-value conversion on typeless expression?");

// lvalue-to-rvalue conversion cannot be applied to function or array types.
if (T->isFunctionType() || T->isArrayType())
// lvalue-to-rvalue conversion cannot be applied to types that decay to
// pointers (i.e. function or array types).
if (T->canDecayToPointerType())
return E;

// We don't want to throw lvalue-to-rvalue casts on top of
Expand Down Expand Up @@ -4686,6 +4687,9 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
case Type::Decayed:
T = cast<DecayedType>(Ty)->getPointeeType();
break;
case Type::ArrayParameter:
T = cast<ArrayParameterType>(Ty)->getElementType();
break;
case Type::Pointer:
T = cast<PointerType>(Ty)->getPointeeType();
break;
Expand Down Expand Up @@ -12908,6 +12912,8 @@ static ImplicitConversionKind castKindToImplicitConversionKind(CastKind CK) {
case CK_IntegralComplexToReal:
case CK_IntegralRealToComplex:
return ICK_Complex_Real;
case CK_HLSLArrayRValue:
return ICK_HLSL_Array_RValue;
}
}

Expand Down
8 changes: 8 additions & 0 deletions clang/lib/Sema/SemaExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4416,6 +4416,13 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
.get();
break;

case ICK_HLSL_Array_RValue:
FromType = Context.getArrayParameterType(FromType);
From = ImpCastExprToType(From, FromType, CK_HLSLArrayRValue, VK_PRValue,
/*BasePath=*/nullptr, CCK)
.get();
break;

case ICK_Function_To_Pointer:
FromType = Context.getPointerType(FromType);
From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay,
Expand Down Expand Up @@ -4793,6 +4800,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
case ICK_Num_Conversion_Kinds:
case ICK_C_Only_Conversion:
case ICK_Incompatible_Pointer_Conversion:
case ICK_HLSL_Array_RValue:
llvm_unreachable("Improper second standard conversion");
}

Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaInit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6269,7 +6269,10 @@ void InitializationSequence::InitializeFrom(Sema &S,
// initializer is a string literal, see 8.5.2.
// - Otherwise, if the destination type is an array, the program is
// ill-formed.
if (const ArrayType *DestAT = Context.getAsArrayType(DestType)) {
// - Except in HLSL, where non-decaying array parameters behave like
// non-array types for initialization.
if (DestType->isArrayType() && !DestType->isArrayParameterType()) {
const ArrayType *DestAT = Context.getAsArrayType(DestType);
if (Initializer && isa<VariableArrayType>(DestAT)) {
SetFailed(FK_VariableLengthArrayHasInitializer);
return;
Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Sema/SemaLookup.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3243,6 +3243,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
case Type::Pipe:
T = cast<PipeType>(T)->getElementType().getTypePtr();
continue;

// Array parameter types are treated as fundamental types.
case Type::ArrayParameter:
break;
}

if (Queue.empty())
Expand Down
33 changes: 21 additions & 12 deletions clang/lib/Sema/SemaOpenACC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,15 @@
///
//===----------------------------------------------------------------------===//

#include "clang/AST/StmtOpenACC.h"
#include "clang/Sema/SemaOpenACC.h"
#include "clang/Basic/DiagnosticSema.h"
#include "clang/Basic/OpenACCKinds.h"
#include "clang/Sema/Sema.h"

using namespace clang;

namespace {
bool diagnoseConstructAppertainment(Sema &S, OpenACCDirectiveKind K,
bool diagnoseConstructAppertainment(SemaOpenACC &S, OpenACCDirectiveKind K,
SourceLocation StartLoc, bool IsStmt) {
switch (K) {
default:
Expand All @@ -30,24 +31,32 @@ bool diagnoseConstructAppertainment(Sema &S, OpenACCDirectiveKind K,
case OpenACCDirectiveKind::Serial:
case OpenACCDirectiveKind::Kernels:
if (!IsStmt)
return S.Diag(StartLoc, diag::err_acc_construct_appertainment) << K;
return S.SemaRef.Diag(StartLoc, diag::err_acc_construct_appertainment)
<< K;
break;
}
return false;
}
} // namespace

bool Sema::ActOnOpenACCClause(OpenACCClauseKind ClauseKind,
SemaOpenACC::SemaOpenACC(Sema &S) : SemaRef(S) {}

ASTContext &SemaOpenACC::getASTContext() const { return SemaRef.Context; }
DiagnosticsEngine &SemaOpenACC::getDiagnostics() const { return SemaRef.Diags; }
const LangOptions &SemaOpenACC::getLangOpts() const { return SemaRef.LangOpts; }

bool SemaOpenACC::ActOnClause(OpenACCClauseKind ClauseKind,
SourceLocation StartLoc) {
if (ClauseKind == OpenACCClauseKind::Invalid)
return false;
// For now just diagnose that it is unsupported and leave the parsing to do
// whatever it can do. This function will eventually need to start returning
// some sort of Clause AST type, but for now just return true/false based on
// success.
return Diag(StartLoc, diag::warn_acc_clause_unimplemented) << ClauseKind;
return SemaRef.Diag(StartLoc, diag::warn_acc_clause_unimplemented)
<< ClauseKind;
}
void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K,
void SemaOpenACC::ActOnConstruct(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
switch (K) {
case OpenACCDirectiveKind::Invalid:
Expand All @@ -63,17 +72,17 @@ void Sema::ActOnOpenACCConstruct(OpenACCDirectiveKind K,
// here as these constructs do not take any arguments.
break;
default:
Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K;
SemaRef.Diag(StartLoc, diag::warn_acc_construct_unimplemented) << K;
break;
}
}

bool Sema::ActOnStartOpenACCStmtDirective(OpenACCDirectiveKind K,
bool SemaOpenACC::ActOnStartStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/true);
}

StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
StmtResult SemaOpenACC::ActOnEndStmtDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc,
SourceLocation EndLoc,
StmtResult AssocStmt) {
Expand All @@ -92,7 +101,7 @@ StmtResult Sema::ActOnEndOpenACCStmtDirective(OpenACCDirectiveKind K,
llvm_unreachable("Unhandled case in directive handling?");
}

StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
StmtResult SemaOpenACC::ActOnAssociatedStmt(OpenACCDirectiveKind K,
StmtResult AssocStmt) {
switch (K) {
default:
Expand All @@ -114,9 +123,9 @@ StmtResult Sema::ActOnOpenACCAssociatedStmt(OpenACCDirectiveKind K,
llvm_unreachable("Invalid associated statement application");
}

bool Sema::ActOnStartOpenACCDeclDirective(OpenACCDirectiveKind K,
bool SemaOpenACC::ActOnStartDeclDirective(OpenACCDirectiveKind K,
SourceLocation StartLoc) {
return diagnoseConstructAppertainment(*this, K, StartLoc, /*IsStmt=*/false);
}

DeclGroupRef Sema::ActOnEndOpenACCDeclDirective() { return DeclGroupRef{}; }
DeclGroupRef SemaOpenACC::ActOnEndDeclDirective() { return DeclGroupRef{}; }
Loading