clang 24.0.0git
Attr.h
Go to the documentation of this file.
1//===----- Attr.h --- Helper functions for attribute handling in Sema -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file provides helpers for Sema functions that handle attributes.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_SEMA_ATTR_H
14#define LLVM_CLANG_SEMA_ATTR_H
15
16#include "clang/AST/Attr.h"
17#include "clang/AST/Decl.h"
18#include "clang/AST/DeclBase.h"
19#include "clang/AST/DeclCXX.h"
20#include "clang/AST/DeclObjC.h"
21#include "clang/AST/Type.h"
22#include "clang/AST/TypeLoc.h"
27#include "clang/Sema/SemaBase.h"
28#include "llvm/Support/Casting.h"
29
30namespace clang {
31
32/// isFuncOrMethodForAttrSubject - Return true if the given decl has function
33/// type (function or function-typed variable) or an Objective-C
34/// method.
35inline bool isFuncOrMethodForAttrSubject(const Decl *D) {
36 return (D->getFunctionType() != nullptr) || llvm::isa<ObjCMethodDecl>(D);
37}
38
39/// Return true if the given decl has function type (function or
40/// function-typed variable) or an Objective-C method or a block.
42 return isFuncOrMethodForAttrSubject(D) || llvm::isa<BlockDecl>(D);
43}
44
45/// Return true if the given decl has a declarator that should have
46/// been processed by Sema::GetTypeForDeclarator.
47inline bool hasDeclarator(const Decl *D) {
48 // In some sense, TypedefDecl really *ought* to be a DeclaratorDecl.
49 return isa<DeclaratorDecl>(D) || isa<BlockDecl>(D) ||
51}
52
53/// hasFunctionProto - Return true if the given decl has a argument
54/// information. This decl should have already passed
55/// isFuncOrMethodForAttrSubject or isFunctionOrMethodOrBlockForAttrSubject.
56inline bool hasFunctionProto(const Decl *D) {
57 if (const FunctionType *FnTy = D->getFunctionType())
58 return isa<FunctionProtoType>(FnTy);
59 return isa<ObjCMethodDecl>(D) || isa<BlockDecl>(D);
60}
61
62/// getFunctionOrMethodNumParams - Return number of function or method
63/// parameters, optionally including the implicit object parameter of a C++
64/// method. It is an error to call this on a K&R function (use hasFunctionProto
65/// first).
66inline unsigned getFunctionOrMethodNumParams(const Decl *D,
67 bool IncludeThis = false) {
68 if (const FunctionType *FnTy = D->getFunctionType()) {
69 if (IncludeThis)
70 if (const auto *FD = dyn_cast<FunctionDecl>(D))
71 return FD->getNumParamsIncludingThis();
72 return cast<FunctionProtoType>(FnTy)->getNumParams();
73 }
74 if (const auto *BD = dyn_cast<BlockDecl>(D))
75 return BD->getNumParams();
76 return cast<ObjCMethodDecl>(D)->param_size();
77}
78
79/// getFunctionOrMethodParam - Return parameter declaration for the given index
80/// of the passed Decl, which must have a FunctionProtoType. When the Decl is
81/// not a FunctionDecl/ObjCMethodDecl/BlockDecl, do best effort to find
82/// underlying FunctionProtoType using the Decl's TypeSourceInfo.
84 unsigned Idx) {
85 if (const auto *FD = dyn_cast<FunctionDecl>(D))
86 return FD->getParamDecl(Idx);
87 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
88 return MD->getParamDecl(Idx);
89 if (const auto *BD = dyn_cast<BlockDecl>(D))
90 return BD->getParamDecl(Idx);
91
92 // Handle declarations that do not directly own parameters but have an
93 // underlying FunctionProtoType (e.g. function pointers).
94 const TypeSourceInfo *TSI = nullptr;
95 if (const auto *DD = dyn_cast<DeclaratorDecl>(D))
96 TSI = DD->getTypeSourceInfo();
97 else if (const auto *TD = dyn_cast<TypedefNameDecl>(D))
98 TSI = TD->getTypeSourceInfo();
99
100 if (!TSI)
101 return nullptr;
102
104
105 if (auto PTL = TL.getAsAdjusted<PointerTypeLoc>())
106 TL = PTL.getPointeeLoc();
107 else if (auto MPTL = TL.getAsAdjusted<MemberPointerTypeLoc>())
108 TL = MPTL.getPointeeLoc();
109 else if (auto RTL = TL.getAsAdjusted<ReferenceTypeLoc>())
110 TL = RTL.getPointeeLoc();
111 else if (auto BPTL = TL.getAsAdjusted<BlockPointerTypeLoc>())
112 TL = BPTL.getPointeeLoc();
113
114 if (auto FPTL = TL.getAsAdjusted<FunctionProtoTypeLoc>())
115 if (Idx < FPTL.getNumParams())
116 return FPTL.getParam(Idx);
117
118 return nullptr;
119}
120
121inline QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx) {
122 if (const FunctionType *FnTy = D->getFunctionType())
123 return cast<FunctionProtoType>(FnTy)->getParamType(Idx);
124 if (const auto *BD = dyn_cast<BlockDecl>(D))
125 return BD->getParamDecl(Idx)->getType();
126
127 return cast<ObjCMethodDecl>(D)->parameters()[Idx]->getType();
128}
129
130inline SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx) {
131 if (auto *PVD = getFunctionOrMethodParam(D, Idx))
132 return PVD->getSourceRange();
133 return SourceRange();
134}
135
137 if (const FunctionType *FnTy = D->getFunctionType())
138 return FnTy->getReturnType();
139 return cast<ObjCMethodDecl>(D)->getReturnType();
140}
141
143 if (const auto *FD = dyn_cast<FunctionDecl>(D))
144 return FD->getReturnTypeSourceRange();
145 if (const auto *MD = dyn_cast<ObjCMethodDecl>(D))
146 return MD->getReturnTypeSourceRange();
147 return SourceRange();
148}
149
150inline bool isFunctionOrMethodVariadic(const Decl *D) {
151 if (const FunctionType *FnTy = D->getFunctionType())
152 return cast<FunctionProtoType>(FnTy)->isVariadic();
153 if (const auto *BD = dyn_cast<BlockDecl>(D))
154 return BD->isVariadic();
155 return cast<ObjCMethodDecl>(D)->isVariadic();
156}
157
158inline bool isInstanceMethod(const Decl *D) {
159 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
160 return MethodDecl->isInstance();
161 return false;
162}
163
164inline bool hasImplicitObjectParameter(const Decl *D) {
165 if (const auto *MethodDecl = dyn_cast<CXXMethodDecl>(D))
166 return MethodDecl->isImplicitObjectMemberFunction();
167 return false;
168}
169
170/// Diagnose mutually exclusive attributes when present on a given
171/// declaration. Returns true if diagnosed.
172template <typename AttrTy>
174 if (const auto *A = D->getAttr<AttrTy>()) {
175 S.Diag(AL.getLoc(), diag::err_attributes_are_not_compatible)
176 << AL << A
177 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
178 S.Diag(A->getLocation(), diag::note_conflicting_attribute);
179 return true;
180 }
181 return false;
182}
183
184template <typename AttrTy>
186 if (const auto *A = D->getAttr<AttrTy>()) {
187 S.Diag(AL.getLocation(), diag::err_attributes_are_not_compatible)
188 << &AL << A
189 << (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute());
190 Diag(A->getLocation(), diag::note_conflicting_attribute);
191 return true;
192 }
193 return false;
194}
195
196template <typename... DiagnosticArgs>
197const SemaBase::SemaDiagnosticBuilder &
199 return Bldr;
200}
201
202template <typename T, typename... DiagnosticArgs>
203const SemaBase::SemaDiagnosticBuilder &
205 DiagnosticArgs &&...ExtraArgs) {
206 return appendDiagnostics(Bldr << std::forward<T>(ExtraArg),
207 std::forward<DiagnosticArgs>(ExtraArgs)...);
208}
209
210/// Applies the given attribute to the Decl without performing any
211/// additional semantic checking.
212template <typename AttrType>
214 const AttributeCommonInfo &CI) {
215 D->addAttr(::new (S.getASTContext()) AttrType(S.getASTContext(), CI));
216}
217
218/// Add an attribute @c AttrType to declaration @c D, provided that
219/// @c PassesCheck is true.
220/// Otherwise, emit diagnostic @c DiagID, passing in all parameters
221/// specified in @c ExtraArgs.
222template <typename AttrType, typename... DiagnosticArgs>
224 const AttributeCommonInfo &CI,
225 bool PassesCheck, unsigned DiagID,
226 DiagnosticArgs &&...ExtraArgs) {
227 if (!PassesCheck) {
229 appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...);
230 return;
231 }
233}
234
235} // namespace clang
236#endif // LLVM_CLANG_SEMA_ATTR_H
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Defines the clang::SourceLocation class and associated facilities.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Attr - This represents one attribute.
Definition Attr.h:47
SourceLocation getLocation() const
Definition Attr.h:100
SourceLocation getLoc() const
Wrapper for source info for block pointers.
Definition TypeLoc.h:1557
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
T * getAttr() const
Definition DeclBase.h:582
void addAttr(Attr *A)
const FunctionType * getFunctionType(bool BlocksToo=true) const
Looks through the Decl's underlying type to extract a FunctionType when possible.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition DeclBase.h:440
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4612
Wrapper for source info for member pointers.
Definition TypeLoc.h:1575
Represents a parameter to a function.
Definition Decl.h:1832
ParsedAttr - Represents a syntactic attribute.
Definition ParsedAttr.h:119
Wrapper for source info for pointers.
Definition TypeLoc.h:1544
A (possibly-)qualified type.
Definition TypeBase.h:938
A generic diagnostic builder for errors which may or may not be deferred.
Definition SemaBase.h:111
ASTContext & getASTContext() const
Definition SemaBase.cpp:9
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
A trivial tuple used to represent a source range.
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
Definition TypeLoc.h:349
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:2766
A container of type source information.
Definition TypeBase.h:8417
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
const SemaBase::SemaDiagnosticBuilder & appendDiagnostics(const SemaBase::SemaDiagnosticBuilder &Bldr)
Definition Attr.h:198
void handleSimpleAttributeOrDiagnose(SemaBase &S, Decl *D, const AttributeCommonInfo &CI, bool PassesCheck, unsigned DiagID, DiagnosticArgs &&...ExtraArgs)
Add an attribute AttrType to declaration D, provided that PassesCheck is true.
Definition Attr.h:223
bool hasDeclarator(const Decl *D)
Return true if the given decl has a declarator that should have been processed by Sema::GetTypeForDec...
Definition Attr.h:47
QualType getFunctionOrMethodResultType(const Decl *D)
Definition Attr.h:136
bool isInstanceMethod(const Decl *D)
Definition Attr.h:158
const ParmVarDecl * getFunctionOrMethodParam(const Decl *D, unsigned Idx)
getFunctionOrMethodParam - Return parameter declaration for the given index of the passed Decl,...
Definition Attr.h:83
bool checkAttrMutualExclusion(SemaBase &S, Decl *D, const ParsedAttr &AL)
Diagnose mutually exclusive attributes when present on a given declaration.
Definition Attr.h:173
SourceRange getFunctionOrMethodResultSourceRange(const Decl *D)
Definition Attr.h:142
bool isFunctionOrMethodOrBlockForAttrSubject(const Decl *D)
Return true if the given decl has function type (function or function-typed variable) or an Objective...
Definition Attr.h:41
QualType getFunctionOrMethodParamType(const Decl *D, unsigned Idx)
Definition Attr.h:121
const FunctionProtoType * T
bool isFunctionOrMethodVariadic(const Decl *D)
Definition Attr.h:150
bool isFuncOrMethodForAttrSubject(const Decl *D)
isFuncOrMethodForAttrSubject - Return true if the given decl has function type (function or function-...
Definition Attr.h:35
unsigned getFunctionOrMethodNumParams(const Decl *D, bool IncludeThis=false)
getFunctionOrMethodNumParams - Return number of function or method parameters, optionally including t...
Definition Attr.h:66
void handleSimpleAttribute(SemaBase &S, Decl *D, const AttributeCommonInfo &CI)
Applies the given attribute to the Decl without performing any additional semantic checking.
Definition Attr.h:213
bool hasImplicitObjectParameter(const Decl *D)
Definition Attr.h:164
bool hasFunctionProto(const Decl *D)
hasFunctionProto - Return true if the given decl has a argument information.
Definition Attr.h:56
U cast(CodeGen::Address addr)
Definition Address.h:327
SourceRange getFunctionOrMethodParamRange(const Decl *D, unsigned Idx)
Definition Attr.h:130