| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| //===----- Attr.h --- Helper functions for attribute handling in Sema -----===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file provides helpers for Sema functions that handle attributes. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_ATTR_H | ||
| #define LLVM_CLANG_SEMA_ATTR_H | ||
|
|
||
| #include "clang/AST/Decl.h" | ||
| #include "clang/AST/DeclObjC.h" | ||
| #include "llvm/Support/Casting.h" | ||
|
|
||
| namespace clang { | ||
|
|
||
| /// isFuncOrMethodForAttrSubject - Return true if the given decl has function | ||
| /// type (function or function-typed variable) or an Objective-C | ||
| /// method. | ||
| inline bool isFuncOrMethodForAttrSubject(const Decl *D) { | ||
| return (D->getFunctionType() != nullptr) || llvm::isa<ObjCMethodDecl>(D); | ||
| } | ||
|
|
||
| /// Return true if the given decl has function type (function or | ||
| /// function-typed variable) or an Objective-C method or a block. | ||
| inline bool isFunctionOrMethodOrBlockForAttrSubject(const Decl *D) { | ||
| return isFuncOrMethodForAttrSubject(D) || llvm::isa<BlockDecl>(D); | ||
| } | ||
|
|
||
| } // namespace clang | ||
| #endif // LLVM_CLANG_SEMA_ATTR_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| //===----- SemaAMDGPU.h --- AMDGPU target-specific routines ---*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to AMDGPU. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMAAMDGPU_H | ||
| #define LLVM_CLANG_SEMA_SEMAAMDGPU_H | ||
|
|
||
| #include "clang/AST/Attr.h" | ||
| #include "clang/AST/DeclBase.h" | ||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Basic/AttributeCommonInfo.h" | ||
| #include "clang/Sema/ParsedAttr.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaAMDGPU : public SemaBase { | ||
| public: | ||
| SemaAMDGPU(Sema &S); | ||
|
|
||
| bool CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); | ||
|
|
||
| /// Create an AMDGPUWavesPerEUAttr attribute. | ||
| AMDGPUFlatWorkGroupSizeAttr * | ||
| CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, Expr *Min, | ||
| Expr *Max); | ||
|
|
||
| /// addAMDGPUFlatWorkGroupSizeAttr - Adds an amdgpu_flat_work_group_size | ||
| /// attribute to a particular declaration. | ||
| void addAMDGPUFlatWorkGroupSizeAttr(Decl *D, const AttributeCommonInfo &CI, | ||
| Expr *Min, Expr *Max); | ||
|
|
||
| /// Create an AMDGPUWavesPerEUAttr attribute. | ||
| AMDGPUWavesPerEUAttr * | ||
| CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, Expr *Min, | ||
| Expr *Max); | ||
|
|
||
| /// addAMDGPUWavePersEUAttr - Adds an amdgpu_waves_per_eu attribute to a | ||
| /// particular declaration. | ||
| void addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, | ||
| Expr *Min, Expr *Max); | ||
|
|
||
| /// Create an AMDGPUMaxNumWorkGroupsAttr attribute. | ||
| AMDGPUMaxNumWorkGroupsAttr * | ||
| CreateAMDGPUMaxNumWorkGroupsAttr(const AttributeCommonInfo &CI, Expr *XExpr, | ||
| Expr *YExpr, Expr *ZExpr); | ||
|
|
||
| /// addAMDGPUMaxNumWorkGroupsAttr - Adds an amdgpu_max_num_work_groups | ||
| /// attribute to a particular declaration. | ||
| void addAMDGPUMaxNumWorkGroupsAttr(Decl *D, const AttributeCommonInfo &CI, | ||
| Expr *XExpr, Expr *YExpr, Expr *ZExpr); | ||
|
|
||
| void handleAMDGPUWavesPerEUAttr(Decl *D, const ParsedAttr &AL); | ||
| void handleAMDGPUNumSGPRAttr(Decl *D, const ParsedAttr &AL); | ||
| void handleAMDGPUNumVGPRAttr(Decl *D, const ParsedAttr &AL); | ||
| void handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, const ParsedAttr &AL); | ||
| void handleAMDGPUFlatWorkGroupSizeAttr(Decl *D, const ParsedAttr &AL); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMAAMDGPU_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,63 @@ | ||
| //===----- SemaARM.h ------- ARM target-specific routines -----*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to ARM. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMAARM_H | ||
| #define LLVM_CLANG_SEMA_SEMAARM_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
| #include "llvm/ADT/SmallVector.h" | ||
| #include <tuple> | ||
|
|
||
| namespace clang { | ||
|
|
||
| class SemaARM : public SemaBase { | ||
| public: | ||
| SemaARM(Sema &S); | ||
|
|
||
| enum ArmStreamingType { | ||
| ArmNonStreaming, | ||
| ArmStreaming, | ||
| ArmStreamingCompatible, | ||
| ArmStreamingOrSVE2p1 | ||
| }; | ||
|
|
||
| bool CheckARMBuiltinExclusiveCall(unsigned BuiltinID, CallExpr *TheCall, | ||
| unsigned MaxWidth); | ||
| bool CheckNeonBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
| bool CheckMVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); | ||
| bool CheckSVEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); | ||
| bool | ||
| ParseSVEImmChecks(CallExpr *TheCall, | ||
| llvm::SmallVector<std::tuple<int, int, int>, 3> &ImmChecks); | ||
| bool CheckSMEBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); | ||
| bool CheckCDEBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
| bool CheckARMCoprocessorImmediate(const TargetInfo &TI, const Expr *CoprocArg, | ||
| bool WantCDE); | ||
| bool CheckARMBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
|
|
||
| bool CheckAArch64BuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
| bool BuiltinARMSpecialReg(unsigned BuiltinID, CallExpr *TheCall, int ArgNum, | ||
| unsigned ExpectedFieldNum, bool AllowName); | ||
| bool BuiltinARMMemoryTaggingCall(unsigned BuiltinID, CallExpr *TheCall); | ||
| }; | ||
|
|
||
| SemaARM::ArmStreamingType getArmStreamingFnType(const FunctionDecl *FD); | ||
|
|
||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMAARM_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===----- SemaBPF.h ------- BPF target-specific routines -----*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to BPF. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMABPF_H | ||
| #define LLVM_CLANG_SEMA_SEMABPF_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaBPF : public SemaBase { | ||
| public: | ||
| SemaBPF(Sema &S); | ||
|
|
||
| bool CheckBPFBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMABPF_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| //===----- SemaHexagon.h -- Hexagon target-specific routines --*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to Hexagon. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMAHEXAGON_H | ||
| #define LLVM_CLANG_SEMA_SEMAHEXAGON_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaHexagon : public SemaBase { | ||
| public: | ||
| SemaHexagon(Sema &S); | ||
|
|
||
| bool CheckHexagonBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); | ||
| bool CheckHexagonBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMAHEXAGON_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| //===-- SemaLoongArch.h -- LoongArch target-specific routines --*- C++ -*--===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to LoongArch. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMALOONGARCH_H | ||
| #define LLVM_CLANG_SEMA_SEMALOONGARCH_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaLoongArch : public SemaBase { | ||
| public: | ||
| SemaLoongArch(Sema &S); | ||
|
|
||
| bool CheckLoongArchBuiltinFunctionCall(const TargetInfo &TI, | ||
| unsigned BuiltinID, CallExpr *TheCall); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMALOONGARCH_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| //===----- SemaMIPS.h ------ MIPS target-specific routines ----*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to MIPS. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMAMIPS_H | ||
| #define LLVM_CLANG_SEMA_SEMAMIPS_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaMIPS : public SemaBase { | ||
| public: | ||
| SemaMIPS(Sema &S); | ||
|
|
||
| bool CheckMipsBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
| bool CheckMipsBuiltinCpu(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
| bool CheckMipsBuiltinArgument(unsigned BuiltinID, CallExpr *TheCall); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMAMIPS_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| //===----- SemaNVPTX.h ----- NVPTX target-specific routines ---*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to NVPTX. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMANVPTX_H | ||
| #define LLVM_CLANG_SEMA_SEMANVPTX_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaNVPTX : public SemaBase { | ||
| public: | ||
| SemaNVPTX(Sema &S); | ||
|
|
||
| bool CheckNVPTXBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMANVPTX_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| //===----- SemaPPC.h ------- PPC target-specific routines -----*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to PowerPC. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMAPPC_H | ||
| #define LLVM_CLANG_SEMA_SEMAPPC_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/AST/Type.h" | ||
| #include "clang/Basic/SourceLocation.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaPPC : public SemaBase { | ||
| public: | ||
| SemaPPC(Sema &S); | ||
|
|
||
| bool CheckPPCBuiltinFunctionCall(const TargetInfo &TI, unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
| // 16 byte ByVal alignment not due to a vector member is not honoured by XL | ||
| // on AIX. Emit a warning here that users are generating binary incompatible | ||
| // code to be safe. | ||
| // Here we try to get information about the alignment of the struct member | ||
| // from the struct passed to the caller function. We only warn when the struct | ||
| // is passed byval, hence the series of checks and early returns if we are a | ||
| // not passing a struct byval. | ||
| void checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg); | ||
|
|
||
| /// BuiltinPPCMMACall - Check the call to a PPC MMA builtin for validity. | ||
| /// Emit an error and return true on failure; return false on success. | ||
| /// TypeStr is a string containing the type descriptor of the value returned | ||
| /// by the builtin and the descriptors of the expected type of the arguments. | ||
| bool BuiltinPPCMMACall(CallExpr *TheCall, unsigned BuiltinID, | ||
| const char *TypeDesc); | ||
|
|
||
| bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc); | ||
|
|
||
| // Customized Sema Checking for VSX builtins that have the following | ||
| // signature: vector [...] builtinName(vector [...], vector [...], const int); | ||
| // Which takes the same type of vectors (any legal vector type) for the first | ||
| // two arguments and takes compile time constant for the third argument. | ||
| // Example builtins are : | ||
| // vector double vec_xxpermdi(vector double, vector double, int); | ||
| // vector short vec_xxsldwi(vector short, vector short, int); | ||
| bool BuiltinVSX(CallExpr *TheCall); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMAPPC_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| //===----- SemaSystemZ.h -- SystemZ target-specific routines --*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to SystemZ. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMASYSTEMZ_H | ||
| #define LLVM_CLANG_SEMA_SEMASYSTEMZ_H | ||
|
|
||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaSystemZ : public SemaBase { | ||
| public: | ||
| SemaSystemZ(Sema &S); | ||
|
|
||
| bool CheckSystemZBuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMASYSTEMZ_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| //===----- SemaWasm.h ------ Wasm target-specific routines ----*- C++ -*---===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| /// \file | ||
| /// This file declares semantic analysis functions specific to Wasm. | ||
| /// | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #ifndef LLVM_CLANG_SEMA_SEMAWASM_H | ||
| #define LLVM_CLANG_SEMA_SEMAWASM_H | ||
|
|
||
| #include "clang/AST/Attr.h" | ||
| #include "clang/AST/DeclBase.h" | ||
| #include "clang/AST/Expr.h" | ||
| #include "clang/Basic/TargetInfo.h" | ||
| #include "clang/Sema/ParsedAttr.h" | ||
| #include "clang/Sema/SemaBase.h" | ||
|
|
||
| namespace clang { | ||
| class SemaWasm : public SemaBase { | ||
| public: | ||
| SemaWasm(Sema &S); | ||
|
|
||
| bool CheckWebAssemblyBuiltinFunctionCall(const TargetInfo &TI, | ||
| unsigned BuiltinID, | ||
| CallExpr *TheCall); | ||
|
|
||
| bool BuiltinWasmRefNullExtern(CallExpr *TheCall); | ||
| bool BuiltinWasmRefNullFunc(CallExpr *TheCall); | ||
| bool BuiltinWasmTableGet(CallExpr *TheCall); | ||
| bool BuiltinWasmTableSet(CallExpr *TheCall); | ||
| bool BuiltinWasmTableSize(CallExpr *TheCall); | ||
| bool BuiltinWasmTableGrow(CallExpr *TheCall); | ||
| bool BuiltinWasmTableFill(CallExpr *TheCall); | ||
| bool BuiltinWasmTableCopy(CallExpr *TheCall); | ||
|
|
||
| WebAssemblyImportNameAttr * | ||
| mergeImportNameAttr(Decl *D, const WebAssemblyImportNameAttr &AL); | ||
| WebAssemblyImportModuleAttr * | ||
| mergeImportModuleAttr(Decl *D, const WebAssemblyImportModuleAttr &AL); | ||
|
|
||
| void handleWebAssemblyExportNameAttr(Decl *D, const ParsedAttr &AL); | ||
| void handleWebAssemblyImportModuleAttr(Decl *D, const ParsedAttr &AL); | ||
| void handleWebAssemblyImportNameAttr(Decl *D, const ParsedAttr &AL); | ||
| }; | ||
| } // namespace clang | ||
|
|
||
| #endif // LLVM_CLANG_SEMA_SEMAWASM_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,311 @@ | ||
| //===------ SemaAMDGPU.cpp ------- AMDGPU target-specific routines --------===// | ||
| // | ||
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| // See https://llvm.org/LICENSE.txt for license information. | ||
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // This file implements semantic analysis functions specific to AMDGPU. | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| #include "clang/Sema/SemaAMDGPU.h" | ||
| #include "clang/Basic/DiagnosticSema.h" | ||
| #include "clang/Basic/TargetBuiltins.h" | ||
| #include "clang/Sema/Ownership.h" | ||
| #include "clang/Sema/Sema.h" | ||
| #include "llvm/Support/AtomicOrdering.h" | ||
| #include <cstdint> | ||
|
|
||
| namespace clang { | ||
|
|
||
| SemaAMDGPU::SemaAMDGPU(Sema &S) : SemaBase(S) {} | ||
|
|
||
| bool SemaAMDGPU::CheckAMDGCNBuiltinFunctionCall(unsigned BuiltinID, | ||
| CallExpr *TheCall) { | ||
| // position of memory order and scope arguments in the builtin | ||
| unsigned OrderIndex, ScopeIndex; | ||
| switch (BuiltinID) { | ||
| case AMDGPU::BI__builtin_amdgcn_global_load_lds: { | ||
| constexpr const int SizeIdx = 2; | ||
| llvm::APSInt Size; | ||
| Expr *ArgExpr = TheCall->getArg(SizeIdx); | ||
| ExprResult R = SemaRef.VerifyIntegerConstantExpression(ArgExpr, &Size); | ||
| if (R.isInvalid()) | ||
| return true; | ||
| switch (Size.getSExtValue()) { | ||
| case 1: | ||
| case 2: | ||
| case 4: | ||
| return false; | ||
| default: | ||
| Diag(ArgExpr->getExprLoc(), | ||
| diag::err_amdgcn_global_load_lds_size_invalid_value) | ||
| << ArgExpr->getSourceRange(); | ||
| Diag(ArgExpr->getExprLoc(), | ||
| diag::note_amdgcn_global_load_lds_size_valid_value) | ||
| << ArgExpr->getSourceRange(); | ||
| return true; | ||
| } | ||
| } | ||
| case AMDGPU::BI__builtin_amdgcn_get_fpenv: | ||
| case AMDGPU::BI__builtin_amdgcn_set_fpenv: | ||
| return false; | ||
| case AMDGPU::BI__builtin_amdgcn_atomic_inc32: | ||
| case AMDGPU::BI__builtin_amdgcn_atomic_inc64: | ||
| case AMDGPU::BI__builtin_amdgcn_atomic_dec32: | ||
| case AMDGPU::BI__builtin_amdgcn_atomic_dec64: | ||
| OrderIndex = 2; | ||
| ScopeIndex = 3; | ||
| break; | ||
| case AMDGPU::BI__builtin_amdgcn_fence: | ||
| OrderIndex = 0; | ||
| ScopeIndex = 1; | ||
| break; | ||
| default: | ||
| return false; | ||
| } | ||
|
|
||
| ExprResult Arg = TheCall->getArg(OrderIndex); | ||
| auto ArgExpr = Arg.get(); | ||
| Expr::EvalResult ArgResult; | ||
|
|
||
| if (!ArgExpr->EvaluateAsInt(ArgResult, getASTContext())) | ||
| return Diag(ArgExpr->getExprLoc(), diag::err_typecheck_expect_int) | ||
| << ArgExpr->getType(); | ||
| auto Ord = ArgResult.Val.getInt().getZExtValue(); | ||
|
|
||
| // Check validity of memory ordering as per C11 / C++11's memody model. | ||
| // Only fence needs check. Atomic dec/inc allow all memory orders. | ||
| if (!llvm::isValidAtomicOrderingCABI(Ord)) | ||
| return Diag(ArgExpr->getBeginLoc(), | ||
| diag::warn_atomic_op_has_invalid_memory_order) | ||
| << 0 << ArgExpr->getSourceRange(); | ||
| switch (static_cast<llvm::AtomicOrderingCABI>(Ord)) { | ||
| case llvm::AtomicOrderingCABI::relaxed: | ||
| case llvm::AtomicOrderingCABI::consume: | ||
| if (BuiltinID == AMDGPU::BI__builtin_amdgcn_fence) | ||
| return Diag(ArgExpr->getBeginLoc(), | ||
| diag::warn_atomic_op_has_invalid_memory_order) | ||
| << 0 << ArgExpr->getSourceRange(); | ||
| break; | ||
| case llvm::AtomicOrderingCABI::acquire: | ||
| case llvm::AtomicOrderingCABI::release: | ||
| case llvm::AtomicOrderingCABI::acq_rel: | ||
| case llvm::AtomicOrderingCABI::seq_cst: | ||
| break; | ||
| } | ||
|
|
||
| Arg = TheCall->getArg(ScopeIndex); | ||
| ArgExpr = Arg.get(); | ||
| Expr::EvalResult ArgResult1; | ||
| // Check that sync scope is a constant literal | ||
| if (!ArgExpr->EvaluateAsConstantExpr(ArgResult1, getASTContext())) | ||
| return Diag(ArgExpr->getExprLoc(), diag::err_expr_not_string_literal) | ||
| << ArgExpr->getType(); | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| static bool | ||
| checkAMDGPUFlatWorkGroupSizeArguments(Sema &S, Expr *MinExpr, Expr *MaxExpr, | ||
| const AMDGPUFlatWorkGroupSizeAttr &Attr) { | ||
| // Accept template arguments for now as they depend on something else. | ||
| // We'll get to check them when they eventually get instantiated. | ||
| if (MinExpr->isValueDependent() || MaxExpr->isValueDependent()) | ||
| return false; | ||
|
|
||
| uint32_t Min = 0; | ||
| if (!S.checkUInt32Argument(Attr, MinExpr, Min, 0)) | ||
| return true; | ||
|
|
||
| uint32_t Max = 0; | ||
| if (!S.checkUInt32Argument(Attr, MaxExpr, Max, 1)) | ||
| return true; | ||
|
|
||
| if (Min == 0 && Max != 0) { | ||
| S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) | ||
| << &Attr << 0; | ||
| return true; | ||
| } | ||
| if (Min > Max) { | ||
| S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) | ||
| << &Attr << 1; | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| AMDGPUFlatWorkGroupSizeAttr * | ||
| SemaAMDGPU::CreateAMDGPUFlatWorkGroupSizeAttr(const AttributeCommonInfo &CI, | ||
| Expr *MinExpr, Expr *MaxExpr) { | ||
| ASTContext &Context = getASTContext(); | ||
| AMDGPUFlatWorkGroupSizeAttr TmpAttr(Context, CI, MinExpr, MaxExpr); | ||
|
|
||
| if (checkAMDGPUFlatWorkGroupSizeArguments(SemaRef, MinExpr, MaxExpr, TmpAttr)) | ||
| return nullptr; | ||
| return ::new (Context) | ||
| AMDGPUFlatWorkGroupSizeAttr(Context, CI, MinExpr, MaxExpr); | ||
| } | ||
|
|
||
| void SemaAMDGPU::addAMDGPUFlatWorkGroupSizeAttr(Decl *D, | ||
| const AttributeCommonInfo &CI, | ||
| Expr *MinExpr, Expr *MaxExpr) { | ||
| if (auto *Attr = CreateAMDGPUFlatWorkGroupSizeAttr(CI, MinExpr, MaxExpr)) | ||
| D->addAttr(Attr); | ||
| } | ||
|
|
||
| void SemaAMDGPU::handleAMDGPUFlatWorkGroupSizeAttr(Decl *D, | ||
| const ParsedAttr &AL) { | ||
| Expr *MinExpr = AL.getArgAsExpr(0); | ||
| Expr *MaxExpr = AL.getArgAsExpr(1); | ||
|
|
||
| addAMDGPUFlatWorkGroupSizeAttr(D, AL, MinExpr, MaxExpr); | ||
| } | ||
|
|
||
| static bool checkAMDGPUWavesPerEUArguments(Sema &S, Expr *MinExpr, | ||
| Expr *MaxExpr, | ||
| const AMDGPUWavesPerEUAttr &Attr) { | ||
| if (S.DiagnoseUnexpandedParameterPack(MinExpr) || | ||
| (MaxExpr && S.DiagnoseUnexpandedParameterPack(MaxExpr))) | ||
| return true; | ||
|
|
||
| // Accept template arguments for now as they depend on something else. | ||
| // We'll get to check them when they eventually get instantiated. | ||
| if (MinExpr->isValueDependent() || (MaxExpr && MaxExpr->isValueDependent())) | ||
| return false; | ||
|
|
||
| uint32_t Min = 0; | ||
| if (!S.checkUInt32Argument(Attr, MinExpr, Min, 0)) | ||
| return true; | ||
|
|
||
| uint32_t Max = 0; | ||
| if (MaxExpr && !S.checkUInt32Argument(Attr, MaxExpr, Max, 1)) | ||
| return true; | ||
|
|
||
| if (Min == 0 && Max != 0) { | ||
| S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) | ||
| << &Attr << 0; | ||
| return true; | ||
| } | ||
| if (Max != 0 && Min > Max) { | ||
| S.Diag(Attr.getLocation(), diag::err_attribute_argument_invalid) | ||
| << &Attr << 1; | ||
| return true; | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| AMDGPUWavesPerEUAttr * | ||
| SemaAMDGPU::CreateAMDGPUWavesPerEUAttr(const AttributeCommonInfo &CI, | ||
| Expr *MinExpr, Expr *MaxExpr) { | ||
| ASTContext &Context = getASTContext(); | ||
| AMDGPUWavesPerEUAttr TmpAttr(Context, CI, MinExpr, MaxExpr); | ||
|
|
||
| if (checkAMDGPUWavesPerEUArguments(SemaRef, MinExpr, MaxExpr, TmpAttr)) | ||
| return nullptr; | ||
|
|
||
| return ::new (Context) AMDGPUWavesPerEUAttr(Context, CI, MinExpr, MaxExpr); | ||
| } | ||
|
|
||
| void SemaAMDGPU::addAMDGPUWavesPerEUAttr(Decl *D, const AttributeCommonInfo &CI, | ||
| Expr *MinExpr, Expr *MaxExpr) { | ||
| if (auto *Attr = CreateAMDGPUWavesPerEUAttr(CI, MinExpr, MaxExpr)) | ||
| D->addAttr(Attr); | ||
| } | ||
|
|
||
| void SemaAMDGPU::handleAMDGPUWavesPerEUAttr(Decl *D, const ParsedAttr &AL) { | ||
| if (!AL.checkAtLeastNumArgs(SemaRef, 1) || !AL.checkAtMostNumArgs(SemaRef, 2)) | ||
| return; | ||
|
|
||
| Expr *MinExpr = AL.getArgAsExpr(0); | ||
| Expr *MaxExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr; | ||
|
|
||
| addAMDGPUWavesPerEUAttr(D, AL, MinExpr, MaxExpr); | ||
| } | ||
|
|
||
| void SemaAMDGPU::handleAMDGPUNumSGPRAttr(Decl *D, const ParsedAttr &AL) { | ||
| uint32_t NumSGPR = 0; | ||
| Expr *NumSGPRExpr = AL.getArgAsExpr(0); | ||
| if (!SemaRef.checkUInt32Argument(AL, NumSGPRExpr, NumSGPR)) | ||
| return; | ||
|
|
||
| D->addAttr(::new (getASTContext()) | ||
| AMDGPUNumSGPRAttr(getASTContext(), AL, NumSGPR)); | ||
| } | ||
|
|
||
| void SemaAMDGPU::handleAMDGPUNumVGPRAttr(Decl *D, const ParsedAttr &AL) { | ||
| uint32_t NumVGPR = 0; | ||
| Expr *NumVGPRExpr = AL.getArgAsExpr(0); | ||
| if (!SemaRef.checkUInt32Argument(AL, NumVGPRExpr, NumVGPR)) | ||
| return; | ||
|
|
||
| D->addAttr(::new (getASTContext()) | ||
| AMDGPUNumVGPRAttr(getASTContext(), AL, NumVGPR)); | ||
| } | ||
|
|
||
| static bool | ||
| checkAMDGPUMaxNumWorkGroupsArguments(Sema &S, Expr *XExpr, Expr *YExpr, | ||
| Expr *ZExpr, | ||
| const AMDGPUMaxNumWorkGroupsAttr &Attr) { | ||
| if (S.DiagnoseUnexpandedParameterPack(XExpr) || | ||
| (YExpr && S.DiagnoseUnexpandedParameterPack(YExpr)) || | ||
| (ZExpr && S.DiagnoseUnexpandedParameterPack(ZExpr))) | ||
| return true; | ||
|
|
||
| // Accept template arguments for now as they depend on something else. | ||
| // We'll get to check them when they eventually get instantiated. | ||
| if (XExpr->isValueDependent() || (YExpr && YExpr->isValueDependent()) || | ||
| (ZExpr && ZExpr->isValueDependent())) | ||
| return false; | ||
|
|
||
| uint32_t NumWG = 0; | ||
| Expr *Exprs[3] = {XExpr, YExpr, ZExpr}; | ||
| for (int i = 0; i < 3; i++) { | ||
| if (Exprs[i]) { | ||
| if (!S.checkUInt32Argument(Attr, Exprs[i], NumWG, i, | ||
| /*StrictlyUnsigned=*/true)) | ||
| return true; | ||
| if (NumWG == 0) { | ||
| S.Diag(Attr.getLoc(), diag::err_attribute_argument_is_zero) | ||
| << &Attr << Exprs[i]->getSourceRange(); | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| AMDGPUMaxNumWorkGroupsAttr *SemaAMDGPU::CreateAMDGPUMaxNumWorkGroupsAttr( | ||
| const AttributeCommonInfo &CI, Expr *XExpr, Expr *YExpr, Expr *ZExpr) { | ||
| ASTContext &Context = getASTContext(); | ||
| AMDGPUMaxNumWorkGroupsAttr TmpAttr(Context, CI, XExpr, YExpr, ZExpr); | ||
|
|
||
| if (checkAMDGPUMaxNumWorkGroupsArguments(SemaRef, XExpr, YExpr, ZExpr, | ||
| TmpAttr)) | ||
| return nullptr; | ||
|
|
||
| return ::new (Context) | ||
| AMDGPUMaxNumWorkGroupsAttr(Context, CI, XExpr, YExpr, ZExpr); | ||
| } | ||
|
|
||
| void SemaAMDGPU::addAMDGPUMaxNumWorkGroupsAttr(Decl *D, | ||
| const AttributeCommonInfo &CI, | ||
| Expr *XExpr, Expr *YExpr, | ||
| Expr *ZExpr) { | ||
| if (auto *Attr = CreateAMDGPUMaxNumWorkGroupsAttr(CI, XExpr, YExpr, ZExpr)) | ||
| D->addAttr(Attr); | ||
| } | ||
|
|
||
| void SemaAMDGPU::handleAMDGPUMaxNumWorkGroupsAttr(Decl *D, | ||
| const ParsedAttr &AL) { | ||
| Expr *YExpr = (AL.getNumArgs() > 1) ? AL.getArgAsExpr(1) : nullptr; | ||
| Expr *ZExpr = (AL.getNumArgs() > 2) ? AL.getArgAsExpr(2) : nullptr; | ||
| addAMDGPUMaxNumWorkGroupsAttr(D, AL, AL.getArgAsExpr(0), YExpr, ZExpr); | ||
| } | ||
|
|
||
| } // namespace clang |