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