|
8 | 8 |
|
9 | 9 | #include "ABIInfoImpl.h"
|
10 | 10 | #include "TargetInfo.h"
|
| 11 | +#include "clang/Basic/DiagnosticFrontend.h" |
11 | 12 |
|
12 | 13 | using namespace clang;
|
13 | 14 | using namespace clang::CodeGen;
|
@@ -151,6 +152,11 @@ class AArch64TargetCodeGenInfo : public TargetCodeGenInfo {
|
151 | 152 | }
|
152 | 153 | return TargetCodeGenInfo::isScalarizableAsmOperand(CGF, Ty);
|
153 | 154 | }
|
| 155 | + |
| 156 | + void checkFunctionCallABI(CodeGenModule &CGM, SourceLocation CallLoc, |
| 157 | + const FunctionDecl *Caller, |
| 158 | + const FunctionDecl *Callee, |
| 159 | + const CallArgList &Args) const override; |
154 | 160 | };
|
155 | 161 |
|
156 | 162 | class WindowsAArch64TargetCodeGenInfo : public AArch64TargetCodeGenInfo {
|
@@ -811,6 +817,43 @@ Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
|
811 | 817 | /*allowHigherAlign*/ false);
|
812 | 818 | }
|
813 | 819 |
|
| 820 | +static bool isStreaming(const FunctionDecl *F) { |
| 821 | + if (F->hasAttr<ArmLocallyStreamingAttr>()) |
| 822 | + return true; |
| 823 | + if (const auto *T = F->getType()->getAs<FunctionProtoType>()) |
| 824 | + return T->getAArch64SMEAttributes() & FunctionType::SME_PStateSMEnabledMask; |
| 825 | + return false; |
| 826 | +} |
| 827 | + |
| 828 | +static bool isStreamingCompatible(const FunctionDecl *F) { |
| 829 | + if (const auto *T = F->getType()->getAs<FunctionProtoType>()) |
| 830 | + return T->getAArch64SMEAttributes() & |
| 831 | + FunctionType::SME_PStateSMCompatibleMask; |
| 832 | + return false; |
| 833 | +} |
| 834 | + |
| 835 | +void AArch64TargetCodeGenInfo::checkFunctionCallABI( |
| 836 | + CodeGenModule &CGM, SourceLocation CallLoc, const FunctionDecl *Caller, |
| 837 | + const FunctionDecl *Callee, const CallArgList &Args) const { |
| 838 | + if (!Caller || !Callee || !Callee->hasAttr<AlwaysInlineAttr>()) |
| 839 | + return; |
| 840 | + |
| 841 | + bool CallerIsStreaming = isStreaming(Caller); |
| 842 | + bool CalleeIsStreaming = isStreaming(Callee); |
| 843 | + bool CallerIsStreamingCompatible = isStreamingCompatible(Caller); |
| 844 | + bool CalleeIsStreamingCompatible = isStreamingCompatible(Callee); |
| 845 | + |
| 846 | + if (!CalleeIsStreamingCompatible && |
| 847 | + (CallerIsStreaming != CalleeIsStreaming || CallerIsStreamingCompatible)) |
| 848 | + CGM.getDiags().Report(CallLoc, |
| 849 | + diag::err_function_always_inline_attribute_mismatch) |
| 850 | + << Caller->getDeclName() << Callee->getDeclName() << "streaming"; |
| 851 | + if (auto *NewAttr = Callee->getAttr<ArmNewAttr>()) |
| 852 | + if (NewAttr->isNewZA()) |
| 853 | + CGM.getDiags().Report(CallLoc, diag::err_function_always_inline_new_za) |
| 854 | + << Callee->getDeclName(); |
| 855 | +} |
| 856 | + |
814 | 857 | std::unique_ptr<TargetCodeGenInfo>
|
815 | 858 | CodeGen::createAArch64TargetCodeGenInfo(CodeGenModule &CGM,
|
816 | 859 | AArch64ABIKind Kind) {
|
|
0 commit comments