-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[clang] Split up SemaDeclAttr.cpp
#93966
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 2 commits
ceb1a28
03abb6d
0d1b75c
e4d6958
b7d132f
a9b8c2c
661d3c3
b4fb775
a6da75a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,7 @@ | |
#include "clang/Basic/TemplateKinds.h" | ||
#include "clang/Basic/TypeTraits.h" | ||
#include "clang/Sema/AnalysisBasedWarnings.h" | ||
#include "clang/Sema/Attr.h" | ||
#include "clang/Sema/CleanupInfo.h" | ||
#include "clang/Sema/DeclSpec.h" | ||
#include "clang/Sema/ExternalSemaSource.h" | ||
|
@@ -171,21 +172,26 @@ class PseudoObjectExpr; | |
class QualType; | ||
class SemaAMDGPU; | ||
class SemaARM; | ||
class SemaAVR; | ||
class SemaBPF; | ||
class SemaCodeCompletion; | ||
class SemaCUDA; | ||
class SemaHLSL; | ||
class SemaHexagon; | ||
class SemaLoongArch; | ||
class SemaM68k; | ||
class SemaMIPS; | ||
class SemaMSP430; | ||
class SemaNVPTX; | ||
class SemaObjC; | ||
class SemaOpenACC; | ||
class SemaOpenCL; | ||
class SemaOpenMP; | ||
class SemaPPC; | ||
class SemaPseudoObject; | ||
class SemaRISCV; | ||
class SemaSYCL; | ||
class SemaSwift; | ||
class SemaSystemZ; | ||
class SemaWasm; | ||
class SemaX86; | ||
|
@@ -1011,6 +1017,11 @@ class Sema final : public SemaBase { | |
return *ARMPtr; | ||
} | ||
|
||
SemaAVR &AVR() { | ||
assert(AVRPtr); | ||
return *AVRPtr; | ||
} | ||
|
||
SemaBPF &BPF() { | ||
assert(BPFPtr); | ||
return *BPFPtr; | ||
|
@@ -1041,11 +1052,21 @@ class Sema final : public SemaBase { | |
return *LoongArchPtr; | ||
} | ||
|
||
SemaM68k &M68k() { | ||
assert(M68kPtr); | ||
return *M68kPtr; | ||
} | ||
|
||
SemaMIPS &MIPS() { | ||
assert(MIPSPtr); | ||
return *MIPSPtr; | ||
} | ||
|
||
SemaMSP430 &MSP430() { | ||
assert(MSP430Ptr); | ||
return *MSP430Ptr; | ||
} | ||
|
||
SemaNVPTX &NVPTX() { | ||
assert(NVPTXPtr); | ||
return *NVPTXPtr; | ||
|
@@ -1061,6 +1082,11 @@ class Sema final : public SemaBase { | |
return *OpenACCPtr; | ||
} | ||
|
||
SemaOpenCL &OpenCL() { | ||
assert(OpenCLPtr); | ||
return *OpenCLPtr; | ||
} | ||
|
||
SemaOpenMP &OpenMP() { | ||
assert(OpenMPPtr && "SemaOpenMP is dead"); | ||
return *OpenMPPtr; | ||
|
@@ -1086,6 +1112,11 @@ class Sema final : public SemaBase { | |
return *SYCLPtr; | ||
} | ||
|
||
SemaSwift &Swift() { | ||
assert(SwiftPtr); | ||
return *SwiftPtr; | ||
} | ||
|
||
SemaSystemZ &SystemZ() { | ||
assert(SystemZPtr); | ||
return *SystemZPtr; | ||
|
@@ -1133,21 +1164,26 @@ class Sema final : public SemaBase { | |
|
||
std::unique_ptr<SemaAMDGPU> AMDGPUPtr; | ||
std::unique_ptr<SemaARM> ARMPtr; | ||
std::unique_ptr<SemaAVR> AVRPtr; | ||
std::unique_ptr<SemaBPF> BPFPtr; | ||
std::unique_ptr<SemaCodeCompletion> CodeCompletionPtr; | ||
std::unique_ptr<SemaCUDA> CUDAPtr; | ||
std::unique_ptr<SemaHLSL> HLSLPtr; | ||
std::unique_ptr<SemaHexagon> HexagonPtr; | ||
std::unique_ptr<SemaLoongArch> LoongArchPtr; | ||
std::unique_ptr<SemaM68k> M68kPtr; | ||
std::unique_ptr<SemaMIPS> MIPSPtr; | ||
std::unique_ptr<SemaMSP430> MSP430Ptr; | ||
std::unique_ptr<SemaNVPTX> NVPTXPtr; | ||
std::unique_ptr<SemaObjC> ObjCPtr; | ||
std::unique_ptr<SemaOpenACC> OpenACCPtr; | ||
std::unique_ptr<SemaOpenCL> OpenCLPtr; | ||
std::unique_ptr<SemaOpenMP> OpenMPPtr; | ||
std::unique_ptr<SemaPPC> PPCPtr; | ||
std::unique_ptr<SemaPseudoObject> PseudoObjectPtr; | ||
std::unique_ptr<SemaRISCV> RISCVPtr; | ||
std::unique_ptr<SemaSYCL> SYCLPtr; | ||
std::unique_ptr<SemaSwift> SwiftPtr; | ||
std::unique_ptr<SemaSystemZ> SystemZPtr; | ||
std::unique_ptr<SemaWasm> WasmPtr; | ||
std::unique_ptr<SemaX86> X86Ptr; | ||
|
@@ -3711,8 +3747,6 @@ class Sema final : public SemaBase { | |
const AttributeCommonInfo &CI, | ||
const IdentifierInfo *Ident); | ||
MinSizeAttr *mergeMinSizeAttr(Decl *D, const AttributeCommonInfo &CI); | ||
SwiftNameAttr *mergeSwiftNameAttr(Decl *D, const SwiftNameAttr &SNA, | ||
StringRef Name); | ||
OptimizeNoneAttr *mergeOptimizeNoneAttr(Decl *D, | ||
const AttributeCommonInfo &CI); | ||
InternalLinkageAttr *mergeInternalLinkageAttr(Decl *D, const ParsedAttr &AL); | ||
|
@@ -3726,8 +3760,6 @@ class Sema final : public SemaBase { | |
const ParsedAttr &attr, CallingConv &CC, const FunctionDecl *FD = nullptr, | ||
CUDAFunctionTarget CFT = CUDAFunctionTarget::InvalidTarget); | ||
|
||
void AddParameterABIAttr(Decl *D, const AttributeCommonInfo &CI, | ||
ParameterABI ABI); | ||
bool CheckRegparmAttr(const ParsedAttr &attr, unsigned &value); | ||
|
||
/// Create an CUDALaunchBoundsAttr attribute. | ||
|
@@ -3742,20 +3774,6 @@ class Sema final : public SemaBase { | |
Expr *MaxThreads, Expr *MinBlocks, Expr *MaxBlocks); | ||
|
||
enum class RetainOwnershipKind { NS, CF, OS }; | ||
void AddXConsumedAttr(Decl *D, const AttributeCommonInfo &CI, | ||
RetainOwnershipKind K, bool IsTemplateInstantiation); | ||
|
||
bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type); | ||
|
||
/// Do a check to make sure \p Name looks like a legal argument for the | ||
/// swift_name attribute applied to decl \p D. Raise a diagnostic if the name | ||
/// is invalid for the given declaration. | ||
/// | ||
/// \p AL is used to provide caret diagnostics in case of a malformed name. | ||
/// | ||
/// \returns true if the name is a valid swift name for \p D, false otherwise. | ||
bool DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc, | ||
const ParsedAttr &AL, bool IsAsync); | ||
|
||
UuidAttr *mergeUuidAttr(Decl *D, const AttributeCommonInfo &CI, | ||
StringRef UuidAsWritten, MSGuidDecl *GuidDecl); | ||
|
@@ -3825,6 +3843,115 @@ class Sema final : public SemaBase { | |
|
||
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool); | ||
|
||
/// Diagnose mutually exclusive attributes when present on a given | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where did this section of stuff come from? At least the first 2 are attribute related and might be better in the Attr.td with a SemaRef, perhaps a few others as well. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Making functions accept reference to |
||
/// declaration. Returns true if diagnosed. | ||
template <typename AttrTy> | ||
bool checkAttrMutualExclusion(Decl *D, const ParsedAttr &AL) { | ||
if (const auto *A = D->getAttr<AttrTy>()) { | ||
Diag(AL.getLoc(), diag::err_attributes_are_not_compatible) | ||
<< AL << A | ||
<< (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute()); | ||
Diag(A->getLocation(), diag::note_conflicting_attribute); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
template <typename AttrTy> | ||
bool checkAttrMutualExclusion(Decl *D, const Attr &AL) { | ||
if (const auto *A = D->getAttr<AttrTy>()) { | ||
Diag(AL.getLocation(), diag::err_attributes_are_not_compatible) | ||
<< &AL << A | ||
<< (AL.isRegularKeywordAttribute() || A->isRegularKeywordAttribute()); | ||
Diag(A->getLocation(), diag::note_conflicting_attribute); | ||
return true; | ||
} | ||
return false; | ||
} | ||
|
||
template <typename... DiagnosticArgs> | ||
static const Sema::SemaDiagnosticBuilder & | ||
appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr) { | ||
return Bldr; | ||
} | ||
|
||
template <typename T, typename... DiagnosticArgs> | ||
static const Sema::SemaDiagnosticBuilder & | ||
appendDiagnostics(const Sema::SemaDiagnosticBuilder &Bldr, T &&ExtraArg, | ||
DiagnosticArgs &&...ExtraArgs) { | ||
return appendDiagnostics(Bldr << std::forward<T>(ExtraArg), | ||
std::forward<DiagnosticArgs>(ExtraArgs)...); | ||
} | ||
|
||
/// Add an attribute @c AttrType to declaration @c D, provided that | ||
/// @c PassesCheck is true. | ||
/// Otherwise, emit diagnostic @c DiagID, passing in all parameters | ||
/// specified in @c ExtraArgs. | ||
template <typename AttrType, typename... DiagnosticArgs> | ||
void handleSimpleAttributeOrDiagnose(Decl *D, const AttributeCommonInfo &CI, | ||
bool PassesCheck, unsigned DiagID, | ||
DiagnosticArgs &&...ExtraArgs) { | ||
if (!PassesCheck) { | ||
Sema::SemaDiagnosticBuilder DB = Diag(D->getBeginLoc(), DiagID); | ||
appendDiagnostics(DB, std::forward<DiagnosticArgs>(ExtraArgs)...); | ||
return; | ||
} | ||
handleSimpleAttribute<AttrType>(D, CI); | ||
} | ||
|
||
/// Applies the given attribute to the Decl without performing any | ||
/// additional semantic checking. | ||
template <typename AttrType> | ||
void handleSimpleAttribute(Decl *D, const AttributeCommonInfo &CI) { | ||
D->addAttr(::new (Context) AttrType(Context, CI)); | ||
} | ||
|
||
/// Check if IdxExpr is a valid parameter index for a function or | ||
/// instance method D. May output an error. | ||
/// | ||
/// \returns true if IdxExpr is a valid index. | ||
template <typename AttrInfo> | ||
bool checkFunctionOrMethodParameterIndex(const Decl *D, const AttrInfo &AI, | ||
unsigned AttrArgNum, | ||
const Expr *IdxExpr, ParamIdx &Idx, | ||
bool CanIndexImplicitThis = false) { | ||
assert(isFunctionOrMethodOrBlockForAttrSubject(D)); | ||
|
||
// In C++ the implicit 'this' function parameter also counts. | ||
// Parameters are counted from one. | ||
bool HP = hasFunctionProto(D); | ||
bool HasImplicitThisParam = isInstanceMethod(D); | ||
bool IV = HP && isFunctionOrMethodVariadic(D); | ||
unsigned NumParams = | ||
(HP ? getFunctionOrMethodNumParams(D) : 0) + HasImplicitThisParam; | ||
|
||
std::optional<llvm::APSInt> IdxInt; | ||
if (IdxExpr->isTypeDependent() || | ||
!(IdxInt = IdxExpr->getIntegerConstantExpr(Context))) { | ||
Diag(getAttrLoc(AI), diag::err_attribute_argument_n_type) | ||
<< &AI << AttrArgNum << AANT_ArgumentIntegerConstant | ||
<< IdxExpr->getSourceRange(); | ||
return false; | ||
} | ||
|
||
unsigned IdxSource = IdxInt->getLimitedValue(UINT_MAX); | ||
if (IdxSource < 1 || (!IV && IdxSource > NumParams)) { | ||
Diag(getAttrLoc(AI), diag::err_attribute_argument_out_of_bounds) | ||
<< &AI << AttrArgNum << IdxExpr->getSourceRange(); | ||
return false; | ||
} | ||
if (HasImplicitThisParam && !CanIndexImplicitThis) { | ||
if (IdxSource == 1) { | ||
Diag(getAttrLoc(AI), diag::err_attribute_invalid_implicit_this_argument) | ||
<< &AI << IdxExpr->getSourceRange(); | ||
return false; | ||
} | ||
} | ||
|
||
Idx = ParamIdx(IdxSource, D); | ||
return true; | ||
} | ||
|
||
///@} | ||
|
||
// | ||
|
Uh oh!
There was an error while loading. Please reload this page.