File indexing completed on 2026-05-10 08:36:59
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_SEMA_ATTR_H
0014 #define LLVM_CLANG_SEMA_ATTR_H
0015
0016 #include "clang/AST/Attr.h"
0017 #include "clang/AST/Decl.h"
0018 #include "clang/AST/DeclBase.h"
0019 #include "clang/AST/DeclCXX.h"
0020 #include "clang/AST/DeclObjC.h"
0021 #include "clang/AST/Type.h"
0022 #include "clang/Basic/AttributeCommonInfo.h"
0023 #include "clang/Basic/DiagnosticSema.h"
0024 #include "clang/Basic/SourceLocation.h"
0025 #include "clang/Sema/ParsedAttr.h"
0026 #include "clang/Sema/SemaBase.h"
0027 #include "llvm/Support/Casting.h"
0028
0029 namespace clang {
0030
0031
0032
0033
0034 inline bool isFuncOrMethodForAttrSubject(const Decl *D) {
0035 return (D->getFunctionType() != nullptr) || llvm::isa<ObjCMethodDecl>(D);
0036 }
0037
0038
0039
0040 inline bool isFunctionOrMethodOrBlockForAttrSubject(const Decl *D) {
0041 return isFuncOrMethodForAttrSubject(D) || llvm::isa<BlockDecl>(D);
0042 }
0043
0044
0045
0046 inline bool hasDeclarator(const Decl *D) {
0047
0048 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) ||
0049 isa<TypedefNameDecl>(D) || isa<ObjCPropertyDecl>(D);
0050 }
0051
0052
0053
0054
0055 inline bool hasFunctionProto(const Decl *D) {
0056 if (const FunctionType *FnTy = D->getFunctionType())
0057 return isa<FunctionProtoType>(FnTy);
0058 return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
0059 }
0060
0061
0062
0063
0064 inline unsigned getFunctionOrMethodNumParams(const Decl *D) {
0065 if (const FunctionType *FnTy = D->getFunctionType())
0066 return cast<FunctionProtoType>(FnTy)->getNumParams();
0067 if (const auto *BD = dyn_cast<BlockDecl>(D))
0068 return BD->getNumParams();
0069 return cast<ObjCMethodDecl>(D)->param_size();
0070 }
0071
0072 inline const ParmVarDecl *getFunctionOrMethodParam(const Decl *D,
0073 unsigned Idx) {
0074 if (const auto *FD = dyn_cast<FunctionDecl>(D))
0075 return FD->getParamDecl(Idx);
0076 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
0077 return MD->getParamDecl(Idx);
0078 if (const auto *BD = dyn_cast<BlockDecl>(D))
0079 return BD->getParamDecl(Idx);
0080 return nullptr;
0081 }
0082
0083 inline QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
0084 if (const FunctionType *FnTy = D->getFunctionType())
0085 return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
0086 if (const auto *BD = dyn_cast<BlockDecl>(D))
0087 return BD->getParamDecl(Idx)->getType();
0088
0089 return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
0090 }
0091
0092 inline SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
0093 if (auto *PVD = getFunctionOrMethodParam(D, Idx))
0094 return PVD->getSourceRange();
0095 return SourceRange();
0096 }
0097
0098 inline QualType getFunctionOrMethodResultType(const Decl *D) {
0099 if (const FunctionType *FnTy = D->getFunctionType())
0100 return FnTy->getReturnType();
0101 return cast<ObjCMethodDecl>(D)->getReturnType();
0102 }
0103
0104 inline SourceRange getFunctionOrMethodResultSourceRange(const Decl *D) {
0105 if (const auto *FD = dyn_cast<FunctionDecl>(D))
0106 return FD->getReturnTypeSourceRange();
0107 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
0108 return MD->getReturnTypeSourceRange();
0109 return SourceRange();
0110 }
0111
0112 inline bool isFunctionOrMethodVariadic(const Decl *D) {
0113 if (const FunctionType *FnTy = D->getFunctionType())
0114 return cast<FunctionProtoType>(FnTy)->isVariadic();
0115 if (const auto *BD = dyn_cast<BlockDecl>(D))
0116 return BD->isVariadic();
0117 return cast<ObjCMethodDecl>(D)->isVariadic();
0118 }
0119
0120 inline bool isInstanceMethod(const Decl *D) {
0121 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
0122 return MethodDecl->isInstance();
0123 return false;
0124 }
0125
0126
0127
0128 template <typename AttrTy>
0129 bool checkAttrMutualExclusion(SemaBase &S, Decl *D, const ParsedAttr &AL) {
0130 if (const auto *A = D->getAttr<AttrTy>()) {
0131 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
0132 << AL << A
0133 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
0134 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
0135 return true;
0136 }
0137 return false;
0138 }
0139
0140 template <typename AttrTy>
0141 bool checkAttrMutualExclusion(SemaBase &S, Decl *D, const Attr &AL) {
0142 if (const auto *A = D->getAttr<AttrTy>()) {
0143 S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible)
0144 << &AL << A
0145 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
0146 Diag(A->getLocation(), diag::note_conflicting_attribute);
0147 return true;
0148 }
0149 return false;
0150 }
0151
0152 template <typename... DiagnosticArgs>
0153 const SemaBase::SemaDiagnosticBuilder &
0154 appendDiagnostics(const SemaBase::SemaDiagnosticBuilder &Bldr) {
0155 return Bldr;
0156 }
0157
0158 template <typename T, typename... DiagnosticArgs>
0159 const SemaBase::SemaDiagnosticBuilder &
0160 appendDiagnostics(const SemaBase::SemaDiagnosticBuilder &Bldr, T &&ExtraArg,
0161 DiagnosticArgs &&...ExtraArgs) {
0162 return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
0163 std::forward<DiagnosticArgs>(ExtraArgs)...);
0164 }
0165
0166
0167
0168 template <typename AttrType>
0169 void handleSimpleAttribute(SemaBase &S, Decl *D,
0170 const AttributeCommonInfo &CI) {
0171 D->addAttr(::new (S.getASTContext()) AttrType(S.getASTContext(), CI));
0172 }
0173
0174
0175
0176
0177
0178 template <typename AttrType, typename... DiagnosticArgs>
0179 void handleSimpleAttributeOrDiagnose(SemaBase &S, Decl *D,
0180 const AttributeCommonInfo &CI,
0181 bool PassesCheck, unsigned DiagID,
0182 DiagnosticArgs &&...ExtraArgs) {
0183 if (!PassesCheck) {
0184 SemaBase::SemaDiagnosticBuilder DB = S.Diag(D->getBeginLoc(), DiagID);
0185 appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
0186 return;
0187 }
0188 handleSimpleAttribute<AttrType>(S, D, CI);
0189 }
0190
0191 }
0192 #endif