51#include "llvm/ADT/ArrayRef.h"
52#include "llvm/ADT/STLExtras.h"
53#include "llvm/ADT/StringExtras.h"
54#include "llvm/Support/ConvertUTF.h"
55#include "llvm/Support/SaveAndRestore.h"
72class CheckDefaultArgumentVisitor
75 const Expr *DefaultArg;
78 CheckDefaultArgumentVisitor(Sema &S,
const Expr *DefaultArg)
79 : S(S), DefaultArg(DefaultArg) {}
81 bool VisitExpr(
const Expr *Node);
82 bool VisitDeclRefExpr(
const DeclRefExpr *DRE);
83 bool VisitCXXThisExpr(
const CXXThisExpr *ThisE);
84 bool VisitLambdaExpr(
const LambdaExpr *Lambda);
85 bool VisitPseudoObjectExpr(
const PseudoObjectExpr *POE);
89bool CheckDefaultArgumentVisitor::VisitExpr(
const Expr *Node) {
90 bool IsInvalid =
false;
91 for (
const Stmt *SubStmt : Node->
children())
93 IsInvalid |= Visit(SubStmt);
100bool CheckDefaultArgumentVisitor::VisitDeclRefExpr(
const DeclRefExpr *DRE) {
101 const ValueDecl *
Decl = dyn_cast<ValueDecl>(DRE->
getDecl());
106 if (
const auto *Param = dyn_cast<ParmVarDecl>(Decl)) {
117 diag::err_param_default_argument_references_param)
119 }
else if (
auto *VD =
Decl->getPotentiallyDecomposedVarDecl()) {
134 diag::err_param_default_argument_references_local)
141bool CheckDefaultArgumentVisitor::VisitCXXThisExpr(
const CXXThisExpr *ThisE) {
146 diag::err_param_default_argument_references_this)
150bool CheckDefaultArgumentVisitor::VisitPseudoObjectExpr(
151 const PseudoObjectExpr *POE) {
155 if (
const auto *OVE = dyn_cast<OpaqueValueExpr>(E)) {
156 E = OVE->getSourceExpr();
157 assert(E &&
"pseudo-object binding without source expression?");
165bool CheckDefaultArgumentVisitor::VisitLambdaExpr(
const LambdaExpr *Lambda) {
172 for (
const LambdaCapture &LC : Lambda->
captures()) {
174 return S.
Diag(LC.getLocation(), diag::err_lambda_capture_default_arg);
177 Invalid |= Visit(D->getInit());
192 Proto = Self->ResolveExceptionSpec(CallLoc, Proto);
209 llvm_unreachable(
"should not see unresolved exception specs here");
238 "should not generate implicit declarations for dependent cases");
242 assert(EST ==
EST_Dynamic &&
"EST case not considered earlier.");
244 "Shouldn't collect exceptions when throw-all is guaranteed.");
248 if (ExceptionsSeen.insert(Self->Context.getCanonicalType(E)).second)
249 Exceptions.push_back(E);
277 if (Self->canThrow(S))
284 diag::err_typecheck_decl_incomplete_type))
303 CheckCompletedExpr(Arg, EqualLoc);
312 Param->setDefaultArg(Arg);
316 UnparsedDefaultArgInstantiationsMap::iterator InstPos
319 for (
auto &Instantiation : InstPos->second)
320 Instantiation->setUninstantiatedDefaultArg(Arg);
330 if (!param || !DefaultArg)
338 Diag(EqualLoc, diag::err_param_default_argument)
350 if (Param->isParameterPack()) {
351 Diag(EqualLoc, diag::err_param_default_argument_on_parameter_pack)
354 Param->setDefaultArg(
nullptr);
365 CheckDefaultArgumentVisitor DefaultArgChecker(*
this, DefaultArg);
366 if (DefaultArgChecker.Visit(DefaultArg))
379 Param->setUnparsedDefaultArg();
389 Param->setInvalidDecl();
394 Param->getType().getNonReferenceType());
397 Param->getType().getNonReferenceType());
399 Param->setDefaultArg(RE.
get());
414 if (MightBeFunction) {
418 MightBeFunction =
false;
421 for (
unsigned argIdx = 0, e = chunk.
Fun.
NumParams; argIdx != e;
424 if (Param->hasUnparsedDefaultArg()) {
425 std::unique_ptr<CachedTokens> Toks =
428 if (Toks->size() > 1)
430 Toks->back().getLocation());
433 Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
435 }
else if (Param->getDefaultArg()) {
436 Diag(Param->getLocation(), diag::err_param_default_argument_nonfunc)
437 << Param->getDefaultArg()->getSourceRange();
438 Param->setDefaultArg(
nullptr);
442 MightBeFunction =
false;
449 return P->hasDefaultArg() && !P->hasInheritedDefaultArg();
461 ?
New->getLexicalDeclContext()
462 :
New->getDeclContext();
466 for (; PrevForDefaultArgs;
469 PrevForDefaultArgs =
New->isLocalExternDecl()
477 !
New->isCXXClassMember()) {
514 for (
unsigned p = 0, NumParams = PrevForDefaultArgs
517 p < NumParams; ++p) {
521 bool OldParamHasDfl = OldParam ? OldParam->
hasDefaultArg() :
false;
524 if (OldParamHasDfl && NewParamHasDfl) {
525 unsigned DiagDefaultParamID =
526 diag::err_param_default_argument_redefinition;
541 DiagDefaultParamID = diag::ext_param_default_argument_redefinition;
559 for (
auto Older = PrevForDefaultArgs;
561 Older = Older->getPreviousDecl();
562 OldParam = Older->getParamDecl(p);
567 }
else if (OldParamHasDfl) {
573 !
New->getLexicalDeclContext()->isDependentContext()) {
585 }
else if (NewParamHasDfl) {
586 if (
New->getDescribedFunctionTemplate()) {
589 diag::err_param_default_argument_template_redecl)
592 diag::note_template_prev_declaration)
594 }
else if (
New->getTemplateSpecializationKind()
608 <<
New->getDeclName()
610 }
else if (
New->getDeclContext()->isDependentContext()) {
622 = dyn_cast<CXXRecordDecl>(
New->getDeclContext())) {
623 if (
Record->getDescribedClassTemplate())
632 diag::err_param_default_argument_member_template_redecl)
646 if (NewSM != OldSM) {
649 Diag(NewParam->
getLocation(), diag::err_default_arg_makes_ctor_special)
660 Diag(
New->getLocation(), diag::err_constexpr_redecl_mismatch)
670 (
New->isInlineSpecified() ||
675 Diag(
New->getLocation(), diag::err_inline_decl_follows_def) <<
New;
685 !
New->isFunctionTemplateSpecialization() &&
isVisible(Old)) {
686 Diag(
New->getLocation(), diag::err_deduction_guide_redeclared);
696 Diag(
New->getLocation(), diag::err_friend_decl_with_def_arg_redeclared);
708 if (
New->isThisDeclarationInstantiatedFromAFriendDefinition() &&
717 ? diag::warn_cxx23_placeholder_var_definition
718 : diag::ext_placeholder_var_definition);
736 if (!TemplateParamLists.empty()) {
742 Diag(TemplateParamLists.front()->getTemplateLoc(),
743 diag::err_decomp_decl_template);
749 DiagID = diag::compat_pre_cxx17_decomp_decl;
752 ? diag::compat_cxx26_decomp_decl_cond
753 : diag::compat_pre_cxx26_decomp_decl_cond;
755 DiagID = diag::compat_cxx17_decomp_decl;
776 Diag(Loc, diag::err_decomp_decl_spec) << Name;
779 auto DiagCpp20Specifier = [&](StringRef Name,
SourceLocation Loc) {
780 DiagCompat(Loc, diag_compat::decomp_decl_spec) << Name;
783 if (
auto SCS = DS.getStorageClassSpec()) {
786 DS.getStorageClassSpecLoc());
789 DS.getStorageClassSpecLoc());
791 if (
auto TSCS = DS.getThreadStorageClassSpec())
793 DS.getThreadStorageClassSpecLoc());
795 if (DS.isInlineSpecified())
796 DiagBadSpecifier(
"inline", DS.getInlineSpecLoc());
803 DS.getConstexprSpecLoc());
814 Diag(DS.getVolatileSpecLoc(),
815 diag::warn_deprecated_volatile_structured_binding);
835 ? diag::err_decomp_decl_parens
836 : diag::err_decomp_decl_type)
842 if (R->isFunctionType())
847 if (DS.isConstrainedAuto()) {
850 "No other template kind should be possible for a constrained auto");
868 assert(VarName &&
"Cannot have an unnamed binding declaration");
877 Previous.getFoundDecl()->isTemplateParameter()) {
883 if (B.EllipsisLoc.isValid()) {
885 Diag(B.EllipsisLoc, diag::err_pack_outside_template);
886 QT =
Context.getPackExpansionType(
Context.DependentTy, std::nullopt,
918 auto *Old =
Previous.getRepresentativeDecl();
919 Diag(B.NameLoc, diag::err_redefinition) << B.Name;
920 Diag(Old->getLocation(), diag::note_previous_definition);
938 bool AddToScope =
true;
947 if (
OpenMP().isInOpenMPDeclareTargetContext())
948 OpenMP().checkDeclIsAllowedInOpenMPTarget(
nullptr,
New);
958 unsigned MemberCount) {
959 auto BindingWithPackItr = llvm::find_if(
961 bool HasPack = BindingWithPackItr !=
Bindings.end();
964 IsValid =
Bindings.size() == MemberCount;
967 IsValid = MemberCount >=
Bindings.size() - 1;
970 if (IsValid && HasPack) {
972 unsigned PackSize = MemberCount -
Bindings.size() + 1;
978 for (
unsigned I = 0; I < PackSize; ++I) {
983 NestedBDs[I] = NestedBD;
1013 for (
auto *B : DD->flat_bindings()) {
1018 E = GetInit(Loc, E.
get(), I++);
1021 B->setBinding(ElemType, E.
get());
1030 const llvm::APSInt &NumElems,
1033 S,
Bindings, Src, DecompType, NumElems, ElemType,
1064 S,
Bindings, Src, DecompType, llvm::APSInt::get(2),
1068 return S.CreateBuiltinUnaryOp(Loc, I ? UO_Imag : UO_Real, Base);
1076 llvm::raw_svector_ostream OS(SS);
1088 return std::string(OS.str());
1093 auto DiagnoseMissing = [&] {
1103 return DiagnoseMissing();
1113 return DiagnoseMissing();
1114 if (Result.isAmbiguous())
1119 Result.suppressDiagnostics();
1121 S.
Diag(Loc, diag::err_std_type_trait_not_class_template) << Trait;
1122 S.
Diag(
Found->getLocation(), diag::note_declared_at);
1136 Loc, TraitTy, DiagID,
1146 assert(RD &&
"specialization of class template is not a class?");
1151static TemplateArgumentLoc
1158static TemplateArgumentLoc
1163namespace {
enum class IsTupleLike { TupleLike, NotTupleLike, Error }; }
1166 unsigned &OutSize) {
1176 return IsTupleLike::NotTupleLike;
1184 return IsTupleLike::NotTupleLike;
1193 : R(R), Args(Args) {}
1196 return S.
Diag(Loc, diag::err_decomp_decl_std_tuple_size_not_constant)
1200 } Diagnoser(R, Args);
1205 return IsTupleLike::Error;
1210 return IsTupleLike::Error;
1214 if (Size < 0 || Size >=
UINT_MAX) {
1217 S.
Diag(Loc, diag::err_decomp_decl_std_tuple_size_invalid)
1220 << StringRef(Str.data(), Str.size());
1221 return IsTupleLike::Error;
1224 OutSize = Size.getExtValue();
1225 return IsTupleLike::TupleLike;
1239 diag::err_decomp_decl_std_tuple_element_not_specialized);
1248 auto *TD = R.getAsSingle<
TypeDecl>();
1250 R.suppressDiagnostics();
1251 S.
Diag(Loc, diag::err_decomp_decl_std_tuple_element_not_specialized)
1255 S.
Diag(R.getRepresentativeDecl()->getLocation(), diag::note_declared_at);
1264struct InitializingBinding {
1266 InitializingBinding(Sema &S, BindingDecl *BD) : S(S) {
1267 Sema::CodeSynthesisContext Ctx;
1273 ~InitializingBinding() {
1282 unsigned NumElems) {
1296 bool UseMemberGet =
false;
1306 dyn_cast<FunctionTemplateDecl>(D->getUnderlyingDecl())) {
1308 if (TPL->
size() != 0 &&
1311 UseMemberGet =
true;
1319 for (
auto *B : DD->flat_bindings()) {
1320 InitializingBinding InitContext(S, B);
1343 MemberGet, &Args,
nullptr);
1381 B->getDeclName().getAsIdentifierInfo(), RefType,
1385 RefVD->setImplicit();
1387 RefVD->setInlineSpecified();
1388 RefVD->getLexicalDeclContext()->addHiddenDecl(RefVD);
1393 E =
Seq.Perform(S, Entity, Kind,
Init);
1399 RefVD->setInit(E.
get());
1408 B->setBinding(T, E.
get());
1423 return Specifier->getType()->getAsCXXRecordDecl()->hasDirectFields();
1432 ClassWithFields = RD;
1444 for (
auto &P : Paths) {
1448 BestPath->back().Base->getType())) {
1450 S.
Diag(Loc, diag::err_decomp_decl_multiple_bases_with_members)
1451 <<
false << RD << BestPath->back().Base->getType()
1452 << P.back().Base->getType();
1454 }
else if (P.Access < BestPath->
Access) {
1460 QualType BaseType = BestPath->back().Base->getType();
1462 S.
Diag(Loc, diag::err_decomp_decl_ambiguous_base)
1469 *BestPath, diag::err_decomp_decl_inaccessible_base);
1472 ClassWithFields = BaseType->getAsCXXRecordDecl();
1480 S.
Diag(Loc, diag::err_decomp_decl_multiple_bases_with_members)
1481 << (ClassWithFields == RD) << RD << ClassWithFields
1482 << Paths.
front().back().Base->getType();
1493 const auto *RD = cast_or_null<CXXRecordDecl>(BasePair.
getDecl());
1497 for (
auto *FD : RD->fields()) {
1498 if (FD->isUnnamedBitField())
1503 if (!FD->getDeclName()) {
1504 if (RD->isLambda()) {
1505 S.
Diag(Loc, diag::err_decomp_decl_lambda);
1506 S.
Diag(RD->getLocation(), diag::note_lambda_decl);
1510 if (FD->isAnonymousStructOrUnion()) {
1511 S.
Diag(Loc, diag::err_decomp_decl_anon_union_member)
1513 S.
Diag(FD->getLocation(), diag::note_declared_at);
1526 BasePair.
getAccess(), FD->getAccess())));
1535 diag::err_incomplete_type))
1541 const auto *RD = cast_or_null<CXXRecordDecl>(BasePair.
getDecl());
1548 unsigned NumFields = llvm::count_if(
1549 RD->fields(), [](
FieldDecl *FD) { return !FD->isUnnamedBitField(); });
1556 auto FlatBindings = DD->flat_bindings();
1557 assert(llvm::range_size(FlatBindings) == NumFields);
1558 auto FlatBindingsItr = FlatBindings.begin();
1564 for (
auto *FD : RD->fields()) {
1569 assert(FlatBindingsItr != FlatBindings.end());
1611 if (B->getType().isNull())
1612 B->setType(
Context.DependentTy);
1624 if (
auto *CAT =
Context.getAsConstantArrayType(DecompType)) {
1645 case IsTupleLike::Error:
1649 case IsTupleLike::TupleLike:
1654 case IsTupleLike::NotTupleLike:
1663 << DD << !RD << DecompType;
1678 assert(!T->isDependentType());
1683 T =
Context.getQualifiedType(Unqual, Quals);
1686 return static_cast<unsigned>(CAT->getSize().getZExtValue());
1688 return VT->getNumElements();
1694 case IsTupleLike::Error:
1695 return std::nullopt;
1696 case IsTupleLike::TupleLike:
1698 case IsTupleLike::NotTupleLike:
1703 if (!OrigRD || OrigRD->
isUnion())
1704 return std::nullopt;
1707 return std::nullopt;
1712 const auto *RD = cast_or_null<CXXRecordDecl>(BasePair.
getDecl());
1714 return std::nullopt;
1716 unsigned NumFields = llvm::count_if(
1717 RD->fields(), [](
FieldDecl *FD) { return !FD->isUnnamedBitField(); });
1720 return std::nullopt;
1731 "Should only be called if types are otherwise the same.");
1739 NewType = R->getPointeeType();
1758 New->setInvalidDecl();
1772 if (FTD->isMemberSpecialization())
1781 if (Param->hasDefaultArg())
1792 if (Param->hasDefaultArg() || Param->isParameterPack() ||
1796 if (Param->isInvalidDecl())
1798 else if (Param->getIdentifier())
1799 Diag(Param->getLocation(), diag::err_param_default_argument_missing_name)
1800 << Param->getIdentifier();
1802 Diag(Param->getLocation(), diag::err_param_default_argument_missing);
1809template <
typename... Ts>
1813 if (T->isDependentType())
1819 std::forward<Ts>(DiagArgs)...);
1822 return !T->isLiteralType(SemaRef.
Context);
1825 llvm_unreachable(
"unknown CheckConstexprKind");
1833 "this check is obsolete for C++23");
1836 T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
1844 SemaRef.
Diag(Loc, diag::note_constexpr_dtor_subobject)
1852 if (!Check(B.getBaseTypeLoc(), B.getType(),
nullptr))
1855 if (!Check(FD->getLocation(), FD->getType(), FD))
1866 "this check is obsolete for C++23");
1867 unsigned ArgIndex = 0;
1870 e = FT->param_type_end();
1871 i != e; ++i, ++ArgIndex) {
1873 assert(PD &&
"null in a parameter list");
1876 diag::err_constexpr_non_literal_param, ArgIndex + 1,
1889 "this check is obsolete for C++23");
1891 diag::err_constexpr_non_literal_return,
1910 default: llvm_unreachable(
"Invalid tag kind for record diagnostic!");
1938 for (
const auto &I : RD->
vbases())
1939 Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here)
1940 << I.getSourceRange();
1954 Diag(
Method->getLocation(), diag::warn_cxx17_compat_constexpr_virtual);
1960 Diag(
Method->getLocation(), diag::err_constexpr_virtual);
1967 if (WrittenVirtual !=
Method)
1969 diag::note_overridden_virtual_function);
1980 if (
auto *Dtor = dyn_cast<CXXDestructorDecl>(NewFD)) {
1985 !Dtor->getParent()->defaultedDestructorIsConstexpr()) {
2000 "CheckConstexprFunctionDefinition called on function with no body");
2015 for (
const auto *DclIt : DS->
decls()) {
2016 switch (DclIt->getKind()) {
2017 case Decl::StaticAssert:
2019 case Decl::UsingShadow:
2020 case Decl::UsingDirective:
2021 case Decl::UnresolvedUsingTypename:
2022 case Decl::UnresolvedUsingValue:
2023 case Decl::UsingEnum:
2031 case Decl::TypeAlias: {
2035 if (TN->getUnderlyingType()->isVariablyModifiedType()) {
2038 TypeLoc TL = TN->getTypeSourceInfo()->getTypeLoc();
2049 case Decl::CXXRecord:
2054 diag_compat::constexpr_type_definition)
2062 case Decl::EnumConstant:
2063 case Decl::IndirectField:
2070 case Decl::Decomposition: {
2076 if (VD->isThisDeclarationADefinition()) {
2077 if (VD->isStaticLocal()) {
2080 diag_compat::constexpr_static_var)
2087 if (SemaRef.
LangOpts.CPlusPlus23) {
2089 diag::warn_cxx20_compat_constexpr_var,
2092 SemaRef, Kind, VD->getLocation(), VD->getType(),
2093 diag::err_constexpr_local_var_non_literal_type,
2097 if (!VD->getType()->isDependentType() &&
2098 !VD->hasInit() && !VD->isCXXForRangeDecl()) {
2101 diag_compat::constexpr_local_var_no_init)
2110 SemaRef.
DiagCompat(VD->getLocation(), diag_compat::constexpr_local_var)
2118 case Decl::NamespaceAlias:
2119 case Decl::Function:
2128 SemaRef.
Diag(DS->
getBeginLoc(), diag::err_constexpr_body_invalid_stmt)
2162 if (Field->isInvalidDecl())
2165 if (Field->isUnnamedBitField())
2171 if (Field->isAnonymousStructOrUnion() &&
2172 (Field->getType()->isUnionType()
2173 ? !Field->getType()->getAsCXXRecordDecl()->hasVariantMembers()
2174 : Field->getType()->getAsCXXRecordDecl()->isEmpty()))
2177 if (!
Inits.count(Field)) {
2181 diag_compat::constexpr_ctor_missing_init);
2184 SemaRef.
Diag(Field->getLocation(),
2185 diag::note_constexpr_ctor_missing_init);
2189 }
else if (Field->isAnonymousStructOrUnion()) {
2190 const auto *RD = Field->getType()->castAsRecordDecl();
2191 for (
auto *I : RD->fields())
2194 if (!RD->isUnion() ||
Inits.count(I))
2212 case Stmt::NullStmtClass:
2216 case Stmt::DeclStmtClass:
2226 case Stmt::ReturnStmtClass:
2238 case Stmt::AttributedStmtClass:
2243 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind);
2245 case Stmt::CompoundStmtClass: {
2251 for (
auto *BodyIt : CompStmt->
body()) {
2253 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2259 case Stmt::IfStmtClass: {
2266 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2268 if (
If->getElse() &&
2270 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2275 case Stmt::WhileStmtClass:
2276 case Stmt::DoStmtClass:
2277 case Stmt::ForStmtClass:
2278 case Stmt::CXXForRangeStmtClass:
2279 case Stmt::ContinueStmtClass:
2289 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2294 case Stmt::SwitchStmtClass:
2295 case Stmt::CaseStmtClass:
2296 case Stmt::DefaultStmtClass:
2297 case Stmt::BreakStmtClass:
2305 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2310 case Stmt::LabelStmtClass:
2311 case Stmt::GotoStmtClass:
2317 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2322 case Stmt::GCCAsmStmtClass:
2323 case Stmt::MSAsmStmtClass:
2325 case Stmt::CXXTryStmtClass:
2331 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2336 case Stmt::CXXCatchStmtClass:
2341 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2393 diag_compat::constexpr_function_try_block)
2408 Cxx1yLoc, Cxx2aLoc, Cxx2bLoc, Kind))
2419 }
else if (Cxx2bLoc.
isValid()) {
2420 SemaRef.
DiagCompat(Cxx2bLoc, diag_compat::cxx23_constexpr_body_invalid_stmt)
2422 }
else if (Cxx2aLoc.
isValid()) {
2423 SemaRef.
DiagCompat(Cxx2aLoc, diag_compat::cxx20_constexpr_body_invalid_stmt)
2425 }
else if (Cxx1yLoc.
isValid()) {
2426 SemaRef.
DiagCompat(Cxx1yLoc, diag_compat::cxx14_constexpr_body_invalid_stmt)
2431 = dyn_cast<CXXConstructorDecl>(Dcl)) {
2444 diag_compat::constexpr_union_ctor_no_init);
2451 assert(RD->
getNumVBases() == 0 &&
"constexpr ctor with virtual bases");
2455 bool AnyAnonStructUnionMembers =
false;
2456 unsigned Fields = 0;
2458 E = RD->
field_end(); I != E; ++I, ++Fields) {
2459 if (I->isAnonymousStructOrUnion()) {
2460 AnyAnonStructUnionMembers =
true;
2468 if (AnyAnonStructUnionMembers ||
2478 Inits.insert(ID->chain_begin(), ID->chain_end());
2481 bool Diagnosed =
false;
2482 for (
auto *I : RD->
fields())
2489 if (ReturnStmts.empty()) {
2504 }
else if (ReturnStmts.size() > 1) {
2508 diag_compat::constexpr_body_multiple_return);
2509 for (
unsigned I = 0; I < ReturnStmts.size() - 1; ++I)
2510 SemaRef.
Diag(ReturnStmts[I],
2511 diag::note_constexpr_body_previous_return);
2539 !SemaRef.
getLangOpts().CheckConstexprFunctionBodies ||
2542 diag::ext_constexpr_function_never_constant_expr, Dcl->
getLocation());
2547 diag::ext_constexpr_function_never_constant_expr)
2550 for (
const auto &
Diag : Diags)
2566 if (SemaRef.
getLangOpts().CPlusPlus23 && !IsVoidOrDependentType)
2573 bool OK = SemaRef.
getLangOpts().CPlusPlus14 && IsVoidOrDependentType;
2575 OK ? diag::warn_cxx11_compat_constexpr_body_no_return
2576 : diag::err_constexpr_body_no_return)
2590 Diag(it->second, diag::err_immediate_function_used_before_definition)
2603 "expected an immediate function");
2604 assert(FD->
hasBody() &&
"expected the function to have a body");
2609 bool ImmediateFnIsConstructor;
2616 ShouldVisitImplicitCode =
true;
2617 ShouldVisitLambdaBody =
false;
2623 if (CurrentConstructor && CurrentInit) {
2631 SemaRef.Diag(Loc, diag::note_immediate_function_reason)
2632 << ImmediateFn << Fn << Fn->isConsteval() << IsCall
2634 << (InitializedField !=
nullptr)
2635 << (CurrentInit && !CurrentInit->
isWritten())
2636 << InitializedField << Range;
2638 bool TraverseCallExpr(
CallExpr *E)
override {
2639 if (
const auto *DR =
2641 DR && DR->isImmediateEscalating()) {
2647 if (!TraverseStmt(A))
2654 if (
const auto *ReferencedFn = dyn_cast<FunctionDecl>(E->
getDecl());
2656 Diag(E, ReferencedFn,
false);
2679 return DynamicRecursiveASTVisitor::TraverseCXXConstructorDecl(Ctr);
2682 bool TraverseType(
QualType T,
bool TraverseQualifier)
override {
2685 bool VisitBlockExpr(
BlockExpr *T)
override {
return true; }
2687 } Visitor(*
this, FD);
2688 Visitor.TraverseDecl(FD);
2699 return dyn_cast_or_null<CXXRecordDecl>(DC);
2702 return dyn_cast_or_null<CXXRecordDecl>(
CurContext);
2720 CurDecl = dyn_cast_or_null<CXXRecordDecl>(DC);
2722 CurDecl = dyn_cast_or_null<CXXRecordDecl>(
CurContext);
2741 if (BaseType->containsErrors()) {
2746 if (EllipsisLoc.
isValid() && !BaseType->containsUnexpandedParameterPack()) {
2747 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
2761 if (BaseDecl->isUnion()) {
2762 Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
2766 if (BaseType.hasQualifiers()) {
2768 BaseType.getQualifiers().getAsString(
Context.getPrintingPolicy());
2769 Diag(BaseLoc, diag::warn_qual_base_type)
2770 << Quals << llvm::count(Quals,
' ') + 1 << BaseType;
2771 Diag(BaseLoc, diag::note_base_class_specified_here) << BaseType;
2775 if (
Context.getTargetInfo().getCXXABI().isMicrosoft() ||
2776 Context.getTargetInfo().getTriple().isPS()) {
2778 if (
auto *BaseSpec =
2779 dyn_cast<ClassTemplateSpecializationDecl>(BaseDecl)) {
2788 Class->setInvalidDecl();
2792 BaseDecl = BaseDecl->getDefinition();
2793 assert(BaseDecl &&
"Base type is not incomplete, but has no definition");
2798 const auto *BaseCSA = BaseDecl->getAttr<CodeSegAttr>();
2799 const auto *DerivedCSA =
Class->getAttr<CodeSegAttr>();
2800 if ((DerivedCSA || BaseCSA) &&
2801 (!BaseCSA || !DerivedCSA ||
2802 BaseCSA->getName() != DerivedCSA->getName())) {
2803 Diag(
Class->getLocation(), diag::err_mismatched_code_seg_base);
2804 Diag(BaseDecl->getLocation(), diag::note_base_class_specified_here)
2815 if (BaseDecl->hasFlexibleArrayMember()) {
2816 Diag(BaseLoc, diag::err_base_class_has_flexible_array_member)
2817 << BaseDecl->getDeclName();
2824 if (FinalAttr *FA = BaseDecl->getAttr<FinalAttr>()) {
2825 Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
2826 << BaseDecl->getDeclName() << FA->isSpelledAsSealed();
2827 Diag(BaseDecl->getLocation(), diag::note_entity_declared_at)
2828 << BaseDecl->getDeclName() << FA->getRange();
2833 if (BaseDecl->isInvalidDecl())
2834 Class->setInvalidDecl();
2835 }
else if (BaseType->isDependentType()) {
2842 if (!
Class->isDependentContext())
2843 Class->setInvalidDecl();
2846 Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
2858 Access, TInfo, EllipsisLoc);
2875 Class->setIsParsingBaseSpecifiers();
2885 Diag(AL.getLoc(), diag::err_base_specifier_attribute)
2886 << AL << AL.isRegularKeywordAttribute() << AL.getRange();
2899 if (
Class->isUnion()) {
2900 Diag(
Class->getLocation(), diag::err_base_clause_on_union)
2910 Class->setInvalidDecl();
2927 for (
const auto &BaseSpec :
Decl->bases()) {
2928 QualType Base = Context.getCanonicalType(BaseSpec.getType())
2929 .getUnqualifiedType();
2946 std::map<QualType, CXXBaseSpecifier*, QualTypeOrdering> KnownBaseTypes;
2953 unsigned NumGoodBases = 0;
2955 for (
unsigned idx = 0; idx < Bases.size(); ++idx) {
2965 Diag(Bases[idx]->getBeginLoc(), diag::err_duplicate_base_class)
2966 << KnownBase->
getType() << Bases[idx]->getSourceRange();
2970 Context.Deallocate(Bases[idx]);
2975 KnownBase = Bases[idx];
2976 Bases[NumGoodBases++] = Bases[idx];
2981 if (Bases.size() > 1)
2985 if (
Class->isInterface() &&
2986 (!RD->isInterfaceLike() ||
2992 << RD->getSourceRange();
2995 if (RD->hasAttr<WeakAttr>())
3002 Class->setBases(Bases.data(), NumGoodBases);
3005 for (
unsigned idx = 0; idx < NumGoodBases; ++idx) {
3007 QualType BaseType = Bases[idx]->getType();
3011 if (BaseType->isDependentType())
3015 .getUnqualifiedType();
3017 if (IndirectBaseTypes.count(CanonicalBase)) {
3021 =
Class->isDerivedFrom(CanonicalBase->getAsCXXRecordDecl(), Paths);
3026 Diag(Bases[idx]->getBeginLoc(), diag::warn_inaccessible_base_class)
3028 << Bases[idx]->getSourceRange();
3030 assert(Bases[idx]->isVirtual());
3035 Context.Deallocate(Bases[idx]);
3043 if (!ClassDecl || Bases.empty())
3055 if (!
Base || !Derived)
3083 Base->getAsCXXRecordDecl(), Paths);
3089 Base->getAsCXXRecordDecl(), Paths);
3098 for (
unsigned I = Path.size(); I != 0; --I) {
3099 if (Path[I - 1].
Base->isVirtual()) {
3106 for (
unsigned I = Start, E = Path.size(); I != E; ++I)
3113 assert(BasePathArray.empty() &&
"Base path array must be empty!");
3115 return ::BuildBasePathArray(Paths.
front(), BasePathArray);
3120 unsigned InaccessibleBaseID,
3121 unsigned AmbiguousBaseConvID,
3125 bool IgnoreAccess) {
3133 if (!DerivationOkay)
3138 Path = &Paths.
front();
3145 if (PossiblePath.size() == 1) {
3146 Path = &PossiblePath;
3147 if (AmbiguousBaseConvID)
3148 Diag(Loc, diag::ext_ms_ambiguous_direct_base)
3149 <<
Base << Derived << Range;
3156 if (!IgnoreAccess) {
3175 if (AmbiguousBaseConvID) {
3185 assert(StillOkay &&
"Can only be used with a derived-to-base conversion");
3194 Diag(Loc, AmbiguousBaseConvID)
3195 << Derived <<
Base << PathDisplayStr << Range << Name;
3204 bool IgnoreAccess) {
3206 Derived,
Base, diag::err_upcast_to_inaccessible_base,
3207 diag::err_ambiguous_derived_to_base_conv, Loc, Range,
DeclarationName(),
3208 BasePath, IgnoreAccess);
3212 std::string PathDisplayStr;
3213 std::set<unsigned> DisplayedPaths;
3215 if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) {
3218 PathDisplayStr +=
"\n ";
3222 PathDisplayStr +=
" -> " + Element.Base->getType().getAsString();
3226 return PathDisplayStr;
3236 assert(Access !=
AS_none &&
"Invalid kind for syntactic access specifier!");
3265 if (!OverloadedMethods.empty()) {
3266 if (OverrideAttr *OA = D->
getAttr<OverrideAttr>()) {
3267 Diag(OA->getLocation(),
3268 diag::override_keyword_hides_virtual_member_function)
3269 <<
"override" << (OverloadedMethods.size() > 1);
3270 }
else if (FinalAttr *FA = D->
getAttr<FinalAttr>()) {
3271 Diag(FA->getLocation(),
3272 diag::override_keyword_hides_virtual_member_function)
3273 << (FA->isSpelledAsSealed() ?
"sealed" :
"final")
3274 << (OverloadedMethods.size() > 1);
3285 if (OverrideAttr *OA = D->
getAttr<OverrideAttr>()) {
3286 Diag(OA->getLocation(),
3287 diag::override_keyword_only_allowed_on_virtual_member_functions)
3291 if (FinalAttr *FA = D->
getAttr<FinalAttr>()) {
3292 Diag(FA->getLocation(),
3293 diag::override_keyword_only_allowed_on_virtual_member_functions)
3294 << (FA->isSpelledAsSealed() ?
"sealed" :
"final")
3306 if (MD->
hasAttr<OverrideAttr>() && !HasOverriddenMethods)
3307 Diag(MD->
getLocation(), diag::err_function_marked_override_not_overriding)
3321 SpellingLoc =
getSourceManager().getImmediateExpansionRange(Loc).getBegin();
3327 auto EmitDiag = [&](
unsigned DiagInconsistent,
unsigned DiagSuggest) {
3338 diag::warn_inconsistent_destructor_marked_not_override_overriding,
3339 diag::warn_suggest_destructor_marked_not_override_overriding);
3341 EmitDiag(diag::warn_inconsistent_function_marked_not_override_overriding,
3342 diag::warn_suggest_function_marked_not_override_overriding);
3348 FinalAttr *FA = Old->
getAttr<FinalAttr>();
3352 Diag(
New->getLocation(), diag::err_final_function_overridden)
3353 <<
New->getDeclName()
3354 << FA->isSpelledAsSealed();
3363 return !RD->isCompleteDefinition() ||
3364 !RD->hasTrivialDefaultConstructor() ||
3365 !RD->hasTrivialDestructor();
3369void Sema::CheckShadowInheritedFields(
const SourceLocation &Loc,
3370 DeclarationName FieldName,
3371 const CXXRecordDecl *RD,
3373 if (Diags.isIgnored(diag::warn_shadow_field, Loc))
3377 std::map<CXXRecordDecl*, NamedDecl*> Bases;
3378 auto FieldShadowed = [&](
const CXXBaseSpecifier *
Specifier,
3379 CXXBasePath &Path) {
3380 const auto Base =
Specifier->getType()->getAsCXXRecordDecl();
3382 if (Bases.find(Base) != Bases.end())
3384 for (
const auto Field :
Base->lookup(FieldName)) {
3388 assert(Bases.find(Base) == Bases.end());
3396 CXXBasePaths Paths(
true,
true,
3401 for (
const auto &P : Paths) {
3402 auto Base = P.back().Base->getType()->getAsCXXRecordDecl();
3403 auto It = Bases.find(Base);
3405 if (It == Bases.end())
3407 auto BaseField = It->second;
3408 assert(BaseField->getAccess() !=
AS_private);
3411 Diag(Loc, diag::warn_shadow_field)
3412 << FieldName << RD <<
Base << DeclIsField;
3413 Diag(BaseField->getLocation(), diag::note_shadow_field);
3419template <
typename AttrType>
3421 if (
const TagDecl *TD = T->getAsTagDecl())
3422 return TD->hasAttr<AttrType>();
3424 return TDT->getDecl()->hasAttr<AttrType>();
3467 unsigned InvalidDecl;
3468 bool ShowDeclName =
true;
3481 ShowDeclName =
false;
3486 ShowDeclName =
false;
3501 Diag(Loc, diag::err_invalid_member_in_interface)
3502 << (InvalidDecl-1) << Name;
3504 Diag(Loc, diag::err_invalid_member_in_interface)
3505 << (InvalidDecl-1) <<
"";
3531 diag::err_storageclass_invalid_for_member);
3538 !isFunc && TemplateParameterLists.empty();
3551 const char *PrevSpec;
3556 assert(!Failed &&
"Making a constexpr member const shouldn't fail");
3560 const char *PrevSpec;
3564 Context.getPrintingPolicy())) {
3566 "This is the only DeclSpec that should fail to be applied");
3570 isInstField =
false;
3581 Diag(Loc, diag::err_bad_variable_name)
3618 if (MSPropertyAttr) {
3620 BitWidth, InitStyle, AS, *MSPropertyAttr);
3623 isInstField =
false;
3626 BitWidth, InitStyle, AS);
3639 if (
Member->isInvalidDecl()) {
3644 Diag(Loc, diag::err_static_not_bitfield)
3648 Diag(Loc, diag::err_typedef_not_bitfield)
3653 Diag(Loc, diag::err_not_integral_type_bitfield)
3654 << Name << cast<ValueDecl>(
Member)->getType()
3659 Member->setInvalidDecl();
3664 NonTemplateMember = FunTmpl->getTemplatedDecl();
3666 NonTemplateMember = VarTmpl->getTemplatedDecl();
3672 if (NonTemplateMember !=
Member)
3678 if (
auto *DG = dyn_cast<CXXDeductionGuideDecl>(NonTemplateMember)) {
3679 auto *TD = DG->getDeducedTemplate();
3682 if (AS != TD->getAccess() &&
3683 TD->getDeclContext()->getRedeclContext()->Equals(
3684 DG->getDeclContext()->getRedeclContext())) {
3685 Diag(DG->getBeginLoc(), diag::err_deduction_guide_wrong_access);
3686 Diag(TD->getBeginLoc(), diag::note_deduction_guide_template_access)
3690 if (
const auto *AccessSpec = dyn_cast<AccessSpecDecl>(D))
3691 LastAccessSpec = AccessSpec;
3693 assert(LastAccessSpec &&
"differing access with no access specifier");
3694 Diag(LastAccessSpec->
getBeginLoc(), diag::note_deduction_guide_access)
3705 ? FinalAttr::Keyword_sealed
3706 : FinalAttr::Keyword_final));
3716 assert((Name || isInstField) &&
"No identifier for non-field ?");
3722 if (!
Diags.isIgnored(diag::warn_unused_private_field, FD->
getLocation()) &&
3734 class UninitializedFieldVisitor
3739 llvm::SmallPtrSetImpl<ValueDecl*> &Decls;
3742 llvm::SmallPtrSetImpl<QualType> &BaseClasses;
3757 UninitializedFieldVisitor(
Sema &S,
3758 llvm::SmallPtrSetImpl<ValueDecl*> &Decls,
3759 llvm::SmallPtrSetImpl<QualType> &BaseClasses)
3760 : Inherited(S.Context), S(S), Decls(Decls), BaseClasses(BaseClasses),
3764 bool IsInitListMemberExprInitialized(
MemberExpr *ME,
3765 bool CheckReferenceOnly) {
3767 bool ReferenceField =
false;
3772 Fields.push_back(FD);
3774 ReferenceField =
true;
3780 if (CheckReferenceOnly && !ReferenceField)
3785 auto UsedFields = llvm::drop_begin(llvm::reverse(Fields));
3786 auto UsedIter = UsedFields.begin();
3787 const auto UsedEnd = UsedFields.end();
3789 for (
const unsigned Orig : InitFieldIndex) {
3790 if (UsedIter == UsedEnd)
3792 const unsigned UsedIndex = (*UsedIter)->getFieldIndex();
3793 if (UsedIndex < Orig)
3795 if (UsedIndex > Orig)
3803 void HandleMemberExpr(MemberExpr *ME,
bool CheckReferenceOnly,
3810 MemberExpr *FieldME = ME;
3815 while (MemberExpr *SubME =
3816 dyn_cast<MemberExpr>(
Base->IgnoreParenImpCasts())) {
3821 if (FieldDecl *FD = dyn_cast<FieldDecl>(SubME->getMemberDecl()))
3826 AllPODFields =
false;
3828 Base = SubME->getBase();
3836 if (AddressOf && AllPODFields)
3841 if (ImplicitCastExpr *BaseCast = dyn_cast<ImplicitCastExpr>(Base)) {
3846 if (BaseCast->getCastKind() == CK_UncheckedDerivedToBase) {
3847 QualType T = BaseCast->getType();
3856 if (!Decls.count(FoundVD))
3861 if (InitList && !AddressOf && FoundVD == InitListFieldDecl) {
3863 if (IsInitListMemberExprInitialized(ME, CheckReferenceOnly)) {
3868 if (CheckReferenceOnly && !IsReference)
3872 unsigned diag = IsReference
3873 ? diag::warn_reference_field_is_uninit
3874 : diag::warn_field_is_uninit;
3878 diag::note_uninit_in_this_constructor)
3883 void HandleValue(Expr *E,
bool AddressOf) {
3886 if (MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
3887 HandleMemberExpr(ME,
false ,
3892 if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
3893 Visit(CO->getCond());
3894 HandleValue(CO->getTrueExpr(), AddressOf);
3895 HandleValue(CO->getFalseExpr(), AddressOf);
3899 if (BinaryConditionalOperator *BCO =
3900 dyn_cast<BinaryConditionalOperator>(E)) {
3901 Visit(BCO->getCond());
3902 HandleValue(BCO->getFalseExpr(), AddressOf);
3906 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(E)) {
3907 HandleValue(OVE->getSourceExpr(), AddressOf);
3911 if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) {
3912 switch (BO->getOpcode()) {
3917 HandleValue(BO->getLHS(), AddressOf);
3918 Visit(BO->getRHS());
3921 Visit(BO->getLHS());
3922 HandleValue(BO->getRHS(), AddressOf);
3930 void CheckInitListExpr(InitListExpr *ILE) {
3931 InitFieldIndex.push_back(0);
3932 for (
auto *Child : ILE->
children()) {
3933 if (InitListExpr *SubList = dyn_cast<InitListExpr>(Child)) {
3934 CheckInitListExpr(SubList);
3938 ++InitFieldIndex.back();
3940 InitFieldIndex.pop_back();
3943 void CheckInitializer(Expr *E,
const CXXConstructorDecl *FieldConstructor,
3944 FieldDecl *Field,
const Type *BaseClass) {
3947 for (ValueDecl* VD : DeclsToRemove)
3949 DeclsToRemove.clear();
3952 InitListExpr *ILE = dyn_cast<InitListExpr>(E);
3956 InitListFieldDecl =
Field;
3957 InitFieldIndex.clear();
3958 CheckInitListExpr(ILE);
3970 void VisitMemberExpr(MemberExpr *ME) {
3972 HandleMemberExpr(ME,
true ,
false );
3975 void VisitImplicitCastExpr(ImplicitCastExpr *E) {
3981 Inherited::VisitImplicitCastExpr(E);
3984 void VisitCXXConstructExpr(CXXConstructExpr *E) {
3986 Expr *ArgExpr = E->
getArg(0);
3987 if (InitListExpr *ILE = dyn_cast<InitListExpr>(ArgExpr))
3990 if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(ArgExpr))
3991 if (ICE->getCastKind() == CK_NoOp)
3992 ArgExpr = ICE->getSubExpr();
3993 HandleValue(ArgExpr,
false );
3996 Inherited::VisitCXXConstructExpr(E);
3999 void VisitCXXMemberCallExpr(CXXMemberCallExpr *E) {
4002 HandleValue(Callee,
false );
4008 Inherited::VisitCXXMemberCallExpr(E);
4011 void VisitCallExpr(CallExpr *E) {
4014 HandleValue(E->
getArg(0),
false);
4018 Inherited::VisitCallExpr(E);
4021 void VisitCXXOperatorCallExpr(CXXOperatorCallExpr *E) {
4025 return Inherited::VisitCXXOperatorCallExpr(E);
4029 HandleValue(Arg->IgnoreParenImpCasts(),
false );
4032 void VisitBinaryOperator(BinaryOperator *E) {
4036 if (MemberExpr *ME = dyn_cast<MemberExpr>(E->
getLHS()))
4037 if (FieldDecl *FD = dyn_cast<FieldDecl>(ME->
getMemberDecl()))
4039 DeclsToRemove.push_back(FD);
4042 HandleValue(E->
getLHS(),
false );
4047 Inherited::VisitBinaryOperator(E);
4050 void VisitUnaryOperator(UnaryOperator *E) {
4056 if (MemberExpr *ME = dyn_cast<MemberExpr>(E->
getSubExpr())) {
4057 HandleValue(ME->
getBase(),
true );
4062 Inherited::VisitUnaryOperator(E);
4072 static void DiagnoseUninitializedFields(
4073 Sema &SemaRef,
const CXXConstructorDecl *
Constructor) {
4089 llvm::SmallPtrSet<ValueDecl*, 4> UninitializedFields;
4092 for (
auto *I : RD->
decls()) {
4093 if (
auto *FD = dyn_cast<FieldDecl>(I)) {
4094 UninitializedFields.insert(FD);
4095 }
else if (
auto *IFD = dyn_cast<IndirectFieldDecl>(I)) {
4096 UninitializedFields.insert(IFD->getAnonField());
4100 llvm::SmallPtrSet<QualType, 4> UninitializedBaseClasses;
4101 for (
const auto &I : RD->
bases())
4102 UninitializedBaseClasses.insert(I.getType().getCanonicalType());
4104 if (UninitializedFields.empty() && UninitializedBaseClasses.empty())
4107 UninitializedFieldVisitor UninitializedChecker(SemaRef,
4108 UninitializedFields,
4109 UninitializedBaseClasses);
4111 for (
const auto *FieldInit :
Constructor->inits()) {
4112 if (UninitializedFields.empty() && UninitializedBaseClasses.empty())
4115 Expr *InitExpr = FieldInit->getInit();
4119 if (CXXDefaultInitExpr *
Default =
4120 dyn_cast<CXXDefaultInitExpr>(InitExpr)) {
4121 InitExpr =
Default->getExpr();
4125 UninitializedChecker.CheckInitializer(InitExpr,
Constructor,
4126 FieldInit->getAnyMember(),
4127 FieldInit->getBaseClass());
4129 UninitializedChecker.CheckInitializer(InitExpr,
nullptr,
4130 FieldInit->getAnyMember(),
4131 FieldInit->getBaseClass());
4152 if (ParamDecl->getDeclName())
4169 return ConstraintExpr;
4184 return Seq.Perform(*
this, Entity, Kind, InitExpr);
4202 "must set init style when field is created");
4239 DirectBaseSpec =
nullptr;
4240 for (
const auto &
Base : ClassDecl->
bases()) {
4244 DirectBaseSpec = &
Base;
4252 VirtualBaseSpec =
nullptr;
4253 if (!DirectBaseSpec || !DirectBaseSpec->
isVirtual()) {
4262 if (Path.back().Base->isVirtual()) {
4263 VirtualBaseSpec = Path.back().Base;
4270 return DirectBaseSpec || VirtualBaseSpec;
4284 DS, IdLoc, InitList,
4302 DS, IdLoc, List, EllipsisLoc);
4311 explicit MemInitializerValidatorCCC(
CXXRecordDecl *ClassDecl)
4312 : ClassDecl(ClassDecl) {}
4314 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
4317 return Member->getDeclContext()->getRedeclContext()->Equals(ClassDecl);
4323 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
4324 return std::make_unique<MemInitializerValidatorCCC>(*
this);
4328 CXXRecordDecl *ClassDecl;
4345 Diag(Loc, diag::err_using_placeholder_variable) << Name;
4361 for (
auto *D : ClassDecl->
lookup(MemberOrBase)) {
4363 bool IsPlaceholder = D->isPlaceholderVar(
getLangOpts());
4365 if (IsPlaceholder && D->getDeclContext() == ND->
getDeclContext())
4396 if (!ConstructorD || !
Init)
4402 = dyn_cast<CXXConstructorDecl>(ConstructorD);
4426 ClassDecl, SS, TemplateTypeTy, MemberOrBase)) {
4428 Diag(EllipsisLoc, diag::err_pack_expansion_member_init)
4438 if (TemplateTypeTy) {
4440 if (BaseType.isNull())
4457 if (R.isAmbiguous())
return true;
4460 R.suppressDiagnostics();
4463 bool NotUnknownSpecialization =
false;
4466 NotUnknownSpecialization = !
Record->hasAnyDependentBases();
4468 if (!NotUnknownSpecialization) {
4474 if (BaseType.isNull())
4477 TInfo =
Context.CreateTypeSourceInfo(BaseType);
4487 R.setLookupName(MemberOrBase);
4494 UnqualifiedBase->getCanonicalInjectedSpecializationType(
Context));
4496 for (
auto const &
Base : ClassDecl->
bases()) {
4498 Base.getType()->getAs<TemplateSpecializationType>();
4500 Context.hasSameTemplateName(BaseTemplate->getTemplateName(), TN,
4502 Diag(IdLoc, diag::ext_unqualified_base_class)
4504 BaseType =
Base.getType();
4513 MemInitializerValidatorCCC CCC(ClassDecl);
4514 if (R.empty() && BaseType.isNull() &&
4516 CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS,
4523 PDiag(diag::err_mem_init_not_member_or_class_suggest)
4524 << MemberOrBase <<
true);
4531 DirectBaseSpec, VirtualBaseSpec)) {
4536 PDiag(diag::err_mem_init_not_member_or_class_suggest)
4537 << MemberOrBase <<
false,
4550 if (!TyD && BaseType.isNull()) {
4551 Diag(IdLoc, diag::err_mem_init_not_member_or_class)
4552 << MemberOrBase <<
SourceRange(IdLoc,
Init->getSourceRange().getEnd());
4557 if (BaseType.isNull()) {
4562 if (
const auto *TD = dyn_cast<TagDecl>(TyD)) {
4568 TL.setNameLoc(IdLoc);
4569 }
else if (
auto *TN = dyn_cast<TypedefNameDecl>(TyD)) {
4575 }
else if (
auto *UD = dyn_cast<UnresolvedUsingTypenameDecl>(TyD)) {
4584 BaseType =
Context.getTypeDeclType(TyD);
4592 TInfo =
Context.getTrivialTypeSourceInfo(BaseType, IdLoc);
4602 assert((DirectMember || IndirectMember) &&
4603 "Member must be a FieldDecl or IndirectFieldDecl");
4608 if (
Member->isInvalidDecl())
4613 Args =
MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs());
4615 Args =
MultiExprArg(InitList->getInits(), InitList->getNumInits());
4623 if (
Member->getType()->isDependentType() ||
Init->isTypeDependent()) {
4628 bool InitList =
false;
4641 IdLoc,
Init->getBeginLoc(),
Init->getEndLoc())
4685 return Diag(NameLoc, diag::err_delegating_ctor)
4687 Diag(NameLoc, diag::warn_cxx98_compat_delegating_ctor);
4689 bool InitList =
true;
4693 Args =
MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs());
4704 NameLoc,
Init->getBeginLoc(),
Init->getEndLoc())
4713 "Delegating constructor with no target?");
4719 DelegationInit.
get(), InitRange.
getBegin(),
false);
4724 InitRange.
getEnd(), Args, ClassType);
4736 DelegationInit =
Init;
4750 if (!BaseType->isDependentType() && !BaseType->isRecordType())
4751 return Diag(BaseLoc, diag::err_base_init_does_not_name_class)
4765 (BaseType->isDependentType() ||
Init->isTypeDependent());
4770 if (!BaseType->containsUnexpandedParameterPack()) {
4771 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
4799 if (!DirectBaseSpec && !VirtualBaseSpec) {
4808 return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
4809 << BaseType <<
Context.getCanonicalTagType(ClassDecl)
4820 InitRange.
getEnd(), EllipsisLoc);
4827 if (DirectBaseSpec && VirtualBaseSpec)
4828 return Diag(BaseLoc, diag::err_base_init_direct_and_virtual)
4833 BaseSpec = VirtualBaseSpec;
4836 bool InitList =
true;
4840 Args =
MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs());
4880 InitRange.
getEnd(), EllipsisLoc);
4890 TargetType, ExprLoc);
4910 bool IsInheritedVirtualBase,
4914 IsInheritedVirtualBase);
4918 switch (ImplicitInitKind) {
4924 BaseInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, {});
4930 bool Moving = ImplicitInitKind ==
IIK_Move;
4932 QualType ParamType = Param->getType().getNonReferenceType();
4952 BasePath.push_back(BaseSpec);
4954 CK_UncheckedDerivedToBase,
4962 BaseInit = InitSeq.
Perform(SemaRef, InitEntity, InitKind, CopyCtorArg);
4994 if (Field->isInvalidDecl())
5000 bool Moving = ImplicitInitKind ==
IIK_Move;
5002 QualType ParamType = Param->getType().getNonReferenceType();
5005 if (Field->isZeroLengthBitField())
5008 Expr *MemberExprBase =
5021 LookupResult MemberLookup(SemaRef, Field->getDeclName(), Loc,
5059 InitSeq.Perform(SemaRef, Entity, InitKind,
MultiExprArg(&CtorArgE, 1));
5074 "Unhandled implicit init kind!");
5089 ExprResult MemberInit = InitSeq.Perform(SemaRef, InitEntity, InitKind, {});
5092 if (MemberInit.isInvalid())
5109 if (!Field->getParent()->isUnion()) {
5112 diag::err_uninitialized_member_in_ctor)
5115 << Field->getDeclName();
5116 SemaRef.
Diag(Field->getLocation(), diag::note_declared_at);
5122 diag::err_uninitialized_member_in_ctor)
5125 << Field->getDeclName();
5126 SemaRef.
Diag(Field->getLocation(), diag::note_declared_at);
5143 CXXMemberInit =
nullptr;
5148struct BaseAndFieldInfo {
5150 CXXConstructorDecl *Ctor;
5151 bool AnyErrorsInInits;
5153 llvm::DenseMap<const void *, CXXCtorInitializer*> AllBaseFields;
5154 SmallVector<CXXCtorInitializer*, 8> AllToInit;
5155 llvm::DenseMap<TagDecl*, FieldDecl*> ActiveUnionMember;
5157 BaseAndFieldInfo(Sema &S, CXXConstructorDecl *Ctor,
bool ErrorsInInits)
5158 : S(S), Ctor(Ctor), AnyErrorsInInits(ErrorsInInits) {
5170 bool isImplicitCopyOrMove()
const {
5181 llvm_unreachable(
"Invalid ImplicitInitializerKind!");
5184 bool addFieldInitializer(CXXCtorInitializer *
Init) {
5185 AllToInit.push_back(
Init);
5194 bool isInactiveUnionMember(FieldDecl *Field) {
5199 if (FieldDecl *Active =
5200 ActiveUnionMember.lookup(
Record->getCanonicalDecl()))
5201 return Active !=
Field->getCanonicalDecl();
5204 if (isImplicitCopyOrMove())
5209 if (
Field->hasInClassInitializer())
5213 if (!
Field->isAnonymousStructOrUnion())
5215 CXXRecordDecl *FieldRD =
Field->getType()->getAsCXXRecordDecl();
5222 bool isWithinInactiveUnionMember(FieldDecl *Field,
5223 IndirectFieldDecl *Indirect) {
5225 return isInactiveUnionMember(Field);
5227 for (
auto *
C : Indirect->
chain()) {
5228 FieldDecl *
Field = dyn_cast<FieldDecl>(
C);
5229 if (Field && isInactiveUnionMember(Field))
5240 if (T->isIncompleteArrayType())
5244 if (ArrayT->isZeroSize())
5247 T = ArrayT->getElementType();
5256 if (Field->isInvalidDecl())
5261 Info.AllBaseFields.lookup(Field->getCanonicalDecl()))
5262 return Info.addFieldInitializer(
Init);
5276 if (Info.isWithinInactiveUnionMember(Field, Indirect))
5279 if (Field->hasInClassInitializer() && !Info.isImplicitCopyOrMove()) {
5297 return Info.addFieldInitializer(
Init);
5307 if (Info.AnyErrorsInInits)
5318 return Info.addFieldInitializer(
Init);
5345 if (Class->isInvalidDecl())
5347 if (Class->hasIrrelevantDestructor())
5356 if (Field->isInvalidDecl())
5366 if (!FieldClassDecl)
5370 if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
5378 S.
PDiag(diag::err_access_dtor_field)
5379 << Field->getDeclName() << FieldType);
5392 bool VisitVirtualBases = !ClassDecl->
isAbstract();
5399 if (Dtor && Dtor->
isUsed())
5400 VisitVirtualBases =
false;
5406 for (
const auto &
Base : ClassDecl->
bases()) {
5407 auto *BaseClassDecl =
Base.getType()->getAsCXXRecordDecl();
5412 if (
Base.isVirtual()) {
5413 if (!VisitVirtualBases)
5415 DirectVirtualBases.insert(BaseClassDecl);
5424 S.
PDiag(diag::err_access_dtor_base)
5425 <<
Base.getType() <<
Base.getSourceRange(),
5432 if (VisitVirtualBases)
5434 &DirectVirtualBases);
5442 if (!Initializers.empty()) {
5443 Constructor->setNumCtorInitializers(Initializers.size());
5446 memcpy(baseOrMemberInitializers, Initializers.data(),
5448 Constructor->setCtorInitializers(baseOrMemberInitializers);
5458 BaseAndFieldInfo Info(*
this,
Constructor, AnyErrors);
5466 bool HadError =
false;
5469 if (
Member->isBaseInitializer())
5470 Info.AllBaseFields[
Member->getBaseClass()->getAsCanonical<RecordType>()] =
5473 Info.AllBaseFields[
Member->getAnyMember()->getCanonicalDecl()] =
Member;
5476 for (
auto *
C : F->chain()) {
5479 Info.ActiveUnionMember.insert(std::make_pair(
5484 Info.ActiveUnionMember.insert(std::make_pair(
5492 for (
auto &I : ClassDecl->
bases()) {
5494 DirectVBases.insert(&I);
5498 for (
auto &VBase : ClassDecl->
vbases()) {
5500 VBase.getType()->getAsCanonical<RecordType>())) {
5508 Diag(
Value->getSourceLocation(), diag::warn_abstract_vbase_init_ignored)
5509 << VBase.getType() << ClassDecl;
5513 Info.AllToInit.push_back(
Value);
5514 }
else if (!AnyErrors && !ClassDecl->
isAbstract()) {
5519 bool IsInheritedVirtualBase = !DirectVBases.count(&VBase);
5522 &VBase, IsInheritedVirtualBase,
5528 Info.AllToInit.push_back(CXXBaseInit);
5535 if (
Base.isVirtual())
5539 Base.getType()->getAsCanonical<RecordType>())) {
5540 Info.AllToInit.push_back(
Value);
5541 }
else if (!AnyErrors) {
5550 Info.AllToInit.push_back(CXXBaseInit);
5555 for (
auto *Mem : ClassDecl->
decls()) {
5556 if (
auto *F = dyn_cast<FieldDecl>(Mem)) {
5561 if (F->isUnnamedBitField())
5567 if (F->isAnonymousStructOrUnion() && !Info.isImplicitCopyOrMove())
5576 if (Info.isImplicitCopyOrMove())
5579 if (
auto *F = dyn_cast<IndirectFieldDecl>(Mem)) {
5580 if (F->getType()->isIncompleteArrayType()) {
5582 "Incomplete array type is not valid");
5594 unsigned NumInitializers = Info.AllToInit.size();
5595 if (NumInitializers > 0) {
5596 Constructor->setNumCtorInitializers(NumInitializers);
5599 memcpy(baseOrMemberInitializers, Info.AllToInit.data(),
5601 Constructor->setCtorInitializers(baseOrMemberInitializers);
5627 if (
const RecordType *RT = Field->getType()->getAsCanonical<RecordType>()) {
5635 IdealInits.push_back(Field->getCanonicalDecl());
5639 return Context.getCanonicalType(BaseType).getTypePtr();
5644 if (!
Member->isAnyMemberInitializer())
5647 return Member->getAnyMember()->getCanonicalDecl();
5653 if (
Previous->isAnyMemberInitializer())
5667 if (
Constructor->getDeclContext()->isDependentContext())
5672 bool ShouldCheckOrder =
false;
5674 if (!SemaRef.
Diags.
isIgnored(diag::warn_initializer_out_of_order,
5675 Init->getSourceLocation())) {
5676 ShouldCheckOrder =
true;
5680 if (!ShouldCheckOrder)
5691 for (
const auto &VBase : ClassDecl->
vbases())
5695 for (
const auto &
Base : ClassDecl->
bases()) {
5696 if (
Base.isVirtual())
5702 for (
auto *Field : ClassDecl->
fields()) {
5703 if (Field->isUnnamedBitField())
5709 unsigned NumIdealInits = IdealInitKeys.size();
5710 unsigned IdealIndex = 0;
5719 for (
unsigned InitIndex = 0; InitIndex !=
Inits.size(); ++InitIndex) {
5724 for (; IdealIndex != NumIdealInits; ++IdealIndex)
5725 if (InitKey == IdealInitKeys[IdealIndex])
5731 if (IdealIndex == NumIdealInits && InitIndex) {
5732 WarnIndexes.push_back(InitIndex);
5735 for (IdealIndex = 0; IdealIndex != NumIdealInits; ++IdealIndex)
5736 if (InitKey == IdealInitKeys[IdealIndex])
5739 assert(IdealIndex < NumIdealInits &&
5740 "initializer not found in initializer list");
5742 CorrelatedInitOrder.emplace_back(IdealIndex, InitIndex);
5745 if (WarnIndexes.empty())
5749 llvm::sort(CorrelatedInitOrder, llvm::less_first());
5755 Inits[WarnIndexes.front() - 1]->getSourceLocation(),
5756 WarnIndexes.size() == 1 ? diag::warn_initializer_out_of_order
5757 : diag::warn_some_initializers_out_of_order);
5759 for (
unsigned I = 0; I < CorrelatedInitOrder.size(); ++I) {
5760 if (CorrelatedInitOrder[I].second == I)
5766 Inits[I]->getSourceRange(),
5769 Inits[CorrelatedInitOrder[I].second]->getSourceRange()),
5775 if (WarnIndexes.size() == 1) {
5777 Inits[WarnIndexes.front()]);
5783 for (
unsigned WarnIndex : WarnIndexes) {
5786 diag::note_initializer_out_of_order);
5793bool CheckRedundantInit(Sema &S,
5794 CXXCtorInitializer *
Init,
5795 CXXCtorInitializer *&PrevInit) {
5801 if (FieldDecl *Field =
Init->getAnyMember())
5803 diag::err_multiple_mem_initialization)
5804 <<
Field->getDeclName()
5805 <<
Init->getSourceRange();
5807 const Type *BaseClass =
Init->getBaseClass();
5808 assert(BaseClass &&
"neither field nor base");
5810 diag::err_multiple_base_initialization)
5811 << QualType(BaseClass, 0)
5812 <<
Init->getSourceRange();
5820typedef std::pair<NamedDecl *, CXXCtorInitializer *> UnionEntry;
5821typedef llvm::DenseMap<RecordDecl*, UnionEntry> RedundantUnionMap;
5823bool CheckRedundantUnionInit(Sema &S,
5824 CXXCtorInitializer *
Init,
5825 RedundantUnionMap &Unions) {
5826 FieldDecl *
Field =
Init->getAnyMember();
5827 RecordDecl *Parent =
Field->getParent();
5828 NamedDecl *Child =
Field;
5832 UnionEntry &En = Unions[Parent];
5833 if (En.first && En.first != Child) {
5835 diag::err_multiple_mem_union_initialization)
5836 <<
Field->getDeclName()
5837 <<
Init->getSourceRange();
5838 S.
Diag(En.second->getSourceLocation(), diag::note_previous_initializer)
5839 << 0 << En.second->getSourceRange();
5862 if (!ConstructorDecl)
5868 = dyn_cast<CXXConstructorDecl>(ConstructorDecl);
5871 Diag(ColonLoc, diag::err_only_constructors_take_base_inits);
5878 llvm::DenseMap<const void *, CXXCtorInitializer *> Members;
5881 RedundantUnionMap MemberUnions;
5883 bool HadError =
false;
5884 for (
unsigned i = 0; i < MemInits.size(); i++) {
5888 Init->setSourceOrder(i);
5890 if (
Init->isAnyMemberInitializer()) {
5892 if (CheckRedundantInit(*
this,
Init, Members[Key]) ||
5893 CheckRedundantUnionInit(*
this,
Init, MemberUnions))
5895 }
else if (
Init->isBaseInitializer()) {
5897 if (CheckRedundantInit(*
this,
Init, Members[Key]))
5900 assert(
Init->isDelegatingInitializer());
5902 if (MemInits.size() != 1) {
5904 diag::err_delegating_initializer_alone)
5905 <<
Init->getSourceRange() << MemInits[i ? 0 : 1]->getSourceRange();
5937 for (
auto *Field : ClassDecl->
fields()) {
5946 llvm::SmallPtrSetImpl<const CXXRecordDecl *> *DirectVirtualBases) {
5948 for (
const auto &VBase : ClassDecl->
vbases()) {
5949 auto *BaseClassDecl = VBase.getType()->getAsCXXRecordDecl();
5954 if (DirectVirtualBases && DirectVirtualBases->count(BaseClassDecl))
5963 PDiag(diag::err_access_dtor_vbase)
5964 << CT << VBase.getType(),
5967 CT, VBase.getType(), diag::err_access_dtor_vbase, 0,
5981 = dyn_cast<CXXConstructorDecl>(CDtorDecl)) {
5983 !ClassDecl || ClassDecl->isInvalidDecl()) {
5995 const auto *RD =
Context.getBaseElementType(T)->getAsCXXRecordDecl();
6017 T =
Context.getBaseElementType(T);
6032 if (
Diags.isLastDiagnosticIgnored())
6042 for (
const auto &M : FinalOverriders) {
6043 for (
const auto &SO : M.second) {
6049 if (SO.second.size() != 1)
6053 if (!
Method->isPureVirtual())
6056 if (!SeenPureMethods.insert(
Method).second)
6059 Diag(
Method->getLocation(), diag::note_pure_virtual_function)
6070struct AbstractUsageInfo {
6080 void DiagnoseAbstractType() {
6089struct CheckAbstractUsage {
6090 AbstractUsageInfo &Info;
6091 const NamedDecl *Ctx;
6093 CheckAbstractUsage(AbstractUsageInfo &Info,
const NamedDecl *Ctx)
6094 : Info(Info), Ctx(Ctx) {}
6098#define ABSTRACT_TYPELOC(CLASS, PARENT)
6099#define TYPELOC(CLASS, PARENT) \
6100 case TypeLoc::CLASS: Check(TL.castAs<CLASS##TypeLoc>(), Sel); break;
6101#include "clang/AST/TypeLocNodes.def"
6107 for (
unsigned I = 0, E = TL.
getNumParams(); I != E; ++I) {
6122 for (
unsigned I = 0, E = TL.
getNumArgs(); I != E; ++I) {
6123 TemplateArgumentLoc TAL = TL.
getArgLoc(I);
6132#define CheckPolymorphic(Type) \
6133 void Check(Type TL, Sema::AbstractDiagSelID Sel) { \
6134 Visit(TL.getNextTypeLoc(), Sema::AbstractNone); \
6149 return Visit(
Next, Sel);
6157 if (T->isArrayType()) {
6161 CanQualType CT = T->getCanonicalTypeUnqualified();
6162 if (CT != Info.AbstractType)
return;
6173 Info.DiagnoseAbstractType();
6177void AbstractUsageInfo::CheckType(
const NamedDecl *D, TypeLoc TL,
6179 CheckAbstractUsage(*
this, D).Visit(TL, Sel);
6214 for (
auto *D : RD->
decls()) {
6215 if (D->isImplicit())
continue;
6218 if (
auto *FD = dyn_cast<FriendDecl>(D)) {
6219 D = FD->getFriendDecl();
6224 if (
auto *FD = dyn_cast<FunctionDecl>(D)) {
6226 }
else if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) {
6230 }
else if (
auto *FD = dyn_cast<FieldDecl>(D)) {
6233 }
else if (
auto *VD = dyn_cast<VarDecl>(D)) {
6235 }
else if (
auto *VTD = dyn_cast<VarTemplateDecl>(D)) {
6239 }
else if (
auto *RD = dyn_cast<CXXRecordDecl>(D)) {
6241 }
else if (
auto *CTD = dyn_cast<ClassTemplateDecl>(D)) {
6252 assert(ClassAttr->
getKind() == attr::DLLExport);
6262 struct MarkingClassDllexported {
6273 ~MarkingClassDllexported() {
6276 } MarkingDllexportedContext(S, Class, ClassAttr->
getLocation());
6283 if (!
Member->hasAttr<DLLExportAttr>())
6288 auto *VD = dyn_cast<VarDecl>(
Member);
6289 if (VD && VD->getStorageClass() ==
SC_Static &&
6293 auto *MD = dyn_cast<CXXMethodDecl>(
Member);
6297 if (MD->isUserProvided()) {
6307 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
6317 }
else if (MD->isExplicitlyDefaulted()) {
6326 }
else if (!MD->isTrivial() ||
6327 MD->isCopyAssignmentOperator() ||
6328 MD->isMoveAssignmentOperator()) {
6352 auto *CD = dyn_cast<CXXConstructorDecl>(
Member);
6353 if (!CD || !CD->isDefaultConstructor())
6355 auto *
Attr = CD->getAttr<DLLExportAttr>();
6361 if (!Class->isDependentContext()) {
6368 if (LastExportedDefaultCtor) {
6370 diag::err_attribute_dll_ambiguous_default_ctor)
6372 S.
Diag(CD->getLocation(), diag::note_entity_declared_at)
6373 << CD->getDeclName();
6376 LastExportedDefaultCtor = CD;
6382 bool ErrorReported =
false;
6383 auto reportIllegalClassTemplate = [&ErrorReported](
Sema &S,
6387 S.
Diag(TD->getLocation(),
6388 diag::err_cuda_device_builtin_surftex_cls_template)
6390 ErrorReported =
true;
6395 auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(Class);
6397 S.
Diag(Class->getLocation(),
6398 diag::err_cuda_device_builtin_surftex_ref_decl)
6400 S.
Diag(Class->getLocation(),
6401 diag::note_cuda_device_builtin_surftex_should_be_template_class)
6405 TD = SD->getSpecializedTemplate();
6409 unsigned N = Params->
size();
6412 reportIllegalClassTemplate(S, TD);
6414 diag::note_cuda_device_builtin_surftex_cls_should_have_n_args)
6418 reportIllegalClassTemplate(S, TD);
6420 diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg)
6424 auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Params->
getParam(1));
6425 if (!NTTP || !NTTP->getType()->isIntegralOrEnumerationType()) {
6426 reportIllegalClassTemplate(S, TD);
6428 diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg)
6436 bool ErrorReported =
false;
6437 auto reportIllegalClassTemplate = [&ErrorReported](
Sema &S,
6441 S.
Diag(TD->getLocation(),
6442 diag::err_cuda_device_builtin_surftex_cls_template)
6444 ErrorReported =
true;
6449 auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(Class);
6451 S.
Diag(Class->getLocation(),
6452 diag::err_cuda_device_builtin_surftex_ref_decl)
6454 S.
Diag(Class->getLocation(),
6455 diag::note_cuda_device_builtin_surftex_should_be_template_class)
6459 TD = SD->getSpecializedTemplate();
6463 unsigned N = Params->
size();
6466 reportIllegalClassTemplate(S, TD);
6468 diag::note_cuda_device_builtin_surftex_cls_should_have_n_args)
6472 reportIllegalClassTemplate(S, TD);
6474 diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg)
6478 auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Params->
getParam(1));
6479 if (!NTTP || !NTTP->getType()->isIntegralOrEnumerationType()) {
6480 reportIllegalClassTemplate(S, TD);
6482 diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg)
6487 auto *NTTP = dyn_cast<NonTypeTemplateParmDecl>(Params->
getParam(2));
6488 if (!NTTP || !NTTP->getType()->isIntegralOrEnumerationType()) {
6489 reportIllegalClassTemplate(S, TD);
6491 diag::note_cuda_device_builtin_surftex_cls_should_have_match_arg)
6500 if (
Method->isUserProvided())
6511 if (
Context.getTargetInfo().shouldDLLImportComdatSymbols() && !ClassAttr) {
6512 if (
auto *Spec = dyn_cast<ClassTemplatePartialSpecializationDecl>(
Class)) {
6513 if (
Attr *TemplateAttr =
6514 getDLLAttr(Spec->getSpecializedTemplate()->getTemplatedDecl())) {
6516 A->setInherited(
true);
6529 if ((
Context.getTargetInfo().getCXXABI().isMicrosoft() ||
6530 Context.getTargetInfo().getTriple().isPS()) &&
6531 (!
Class->isExternallyVisible() &&
Class->hasExternalFormalLinkage())) {
6532 Class->dropAttrs<DLLExportAttr, DLLImportAttr>();
6536 if (!
Class->isExternallyVisible()) {
6537 Diag(
Class->getLocation(), diag::err_attribute_dll_not_extern)
6538 <<
Class << ClassAttr;
6542 if (
Context.getTargetInfo().shouldDLLImportComdatSymbols() &&
6553 diag::err_attribute_dll_member_of_dll_class)
6554 << MemberAttr << ClassAttr;
6555 Diag(ClassAttr->getLocation(), diag::note_previous_attribute);
6556 Member->setInvalidDecl();
6560 if (
Class->getDescribedClassTemplate())
6565 const bool ClassExported = ClassAttr->
getKind() == attr::DLLExport;
6570 const bool PropagatedImport =
6580 !
Context.getTargetInfo().getTriple().isOSCygMing()) {
6581 if (
auto *DEA =
Class->getAttr<DLLExportAttr>()) {
6582 Class->addAttr(DLLExportOnDeclAttr::Create(
Context, DEA->getLoc()));
6583 Class->dropAttr<DLLExportAttr>();
6593 if (ClassExported) {
6596 if (
auto *S = dyn_cast<ConstructorUsingShadowDecl>(D))
6597 Shadows.push_back(S);
6620 Member->hasAttr<ExcludeFromExplicitInstantiationAttr>())
6635 if (ClassExported) {
6652 diag::warn_dllexport_inherited_ctor_unsupported)
6658 .areArgsDestroyedLeftToRightInCallee()) {
6659 bool HasCalleeCleanupParam =
false;
6661 if (P->needsDestruction(
Context)) {
6662 HasCalleeCleanupParam =
true;
6665 if (HasCalleeCleanupParam) {
6667 diag::warn_dllexport_inherited_ctor_unsupported)
6689 if (!
Context.getTargetInfo().shouldDLLImportComdatSymbols() &&
6692 if (
auto *CD = dyn_cast<CXXConstructorDecl>(MD);
6693 !CD || !CD->getInheritedConstructor())
6700 auto *Ctor = dyn_cast<CXXConstructorDecl>(MD);
6717 if (VD && PropagatedImport)
6730 bool IsInheritedCtor =
false;
6731 if (
auto *CD = dyn_cast_or_null<CXXConstructorDecl>(MD))
6732 IsInheritedCtor = (bool)CD->getInheritedConstructor();
6736 if (ClassExported) {
6748 Member->addAttr(NewAttr);
6758 "friend re-decl should not already have a DLLAttr");
6788 NewAttr->setInherited(
true);
6789 BaseTemplateSpec->
addAttr(NewAttr);
6793 if (
auto *ImportAttr = dyn_cast<DLLImportAttr>(NewAttr))
6794 ImportAttr->setPropagatedToBaseTemplate();
6815 Diag(BaseLoc, diag::warn_attribute_dll_instantiated_base_class)
6820 diag::note_template_class_explicit_specialization_was_here)
6821 << BaseTemplateSpec;
6824 diag::note_template_class_instantiation_was_here)
6825 << BaseTemplateSpec;
6831 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
6843 if (MD->isCopyAssignmentOperator())
6846 if (MD->isMoveAssignmentOperator())
6857 case OO_ExclaimEqual:
6869 case OO_GreaterEqual:
6910 llvm_unreachable(
"Invalid special member.");
6928 bool CopyCtorIsTrivial =
false, CopyCtorIsTrivialForCall =
false;
6929 bool DtorIsTrivialForCall =
false;
6940 CopyCtorIsTrivial =
true;
6942 CopyCtorIsTrivialForCall =
true;
6946 if (CD->isCopyConstructor() && !CD->isDeleted() &&
6947 !CD->isIneligibleOrNotSelected()) {
6948 if (CD->isTrivial())
6949 CopyCtorIsTrivial =
true;
6950 if (CD->isTrivialForCall())
6951 CopyCtorIsTrivialForCall =
true;
6959 DtorIsTrivialForCall =
true;
6961 if (!DD->isDeleted() && DD->isTrivialForCall())
6962 DtorIsTrivialForCall =
true;
6966 if (CopyCtorIsTrivialForCall && DtorIsTrivialForCall)
6980 uint64_t TypeSize = isAArch64 ? 128 : 64;
6992 bool HasNonDeletedCopyOrMove =
false;
6998 HasNonDeletedCopyOrMove =
true;
7005 HasNonDeletedCopyOrMove =
true;
7013 if (MD->isDeleted() || MD->isIneligibleOrNotSelected())
7016 auto *CD = dyn_cast<CXXConstructorDecl>(MD);
7017 if (CD && CD->isCopyOrMoveConstructor())
7018 HasNonDeletedCopyOrMove =
true;
7022 if (!MD->isTrivialForCall())
7026 return HasNonDeletedCopyOrMove;
7037 bool IssuedDiagnostic =
false;
7040 if (!IssuedDiagnostic) {
7042 IssuedDiagnostic =
true;
7044 S.
Diag(O->getLocation(), diag::note_overridden_virtual_function);
7047 return IssuedDiagnostic;
7054 if (
Record->isAbstract() && !
Record->isInvalidDecl()) {
7055 AbstractUsageInfo Info(*
this,
Record);
7062 if (!
Record->isInvalidDecl() && !
Record->isDependentType() &&
7063 !
Record->isAggregate() && !
Record->hasUserDeclaredConstructor() &&
7065 bool Complained =
false;
7066 for (
const auto *F :
Record->fields()) {
7067 if (F->hasInClassInitializer() || F->isUnnamedBitField())
7070 if (F->getType()->isReferenceType() ||
7071 (F->getType().isConstQualified() && F->getType()->isScalarType())) {
7073 Diag(
Record->getLocation(), diag::warn_no_constructor_for_refconst)
7078 Diag(F->getLocation(), diag::note_refconst_member_not_initialized)
7079 << F->getType()->isReferenceType()
7080 << F->getDeclName();
7085 if (
Record->getIdentifier()) {
7100 Record->hasUserDeclaredConstructor()) ||
7102 Diag(Element->getLocation(), diag::err_member_name_of_class)
7110 if (
Record->isPolymorphic() && !
Record->isDependentType()) {
7113 !
Record->hasAttr<FinalAttr>())
7115 diag::warn_non_virtual_dtor)
7119 if (
Record->isAbstract()) {
7120 if (FinalAttr *FA =
Record->getAttr<FinalAttr>()) {
7121 Diag(
Record->getLocation(), diag::warn_abstract_final_class)
7122 << FA->isSpelledAsSealed();
7128 if (!
Record->hasAttr<FinalAttr>()) {
7130 if (
const FinalAttr *FA = dtor->getAttr<FinalAttr>()) {
7131 Diag(FA->getLocation(), diag::warn_final_dtor_non_final_class)
7132 << FA->isSpelledAsSealed()
7135 (FA->isSpelledAsSealed() ?
" sealed" :
" final"));
7137 diag::note_final_dtor_non_final_class_silence)
7138 <<
Context.getCanonicalTagType(
Record) << FA->isSpelledAsSealed();
7144 if (
Record->hasAttr<TrivialABIAttr>())
7149 bool HasTrivialABI =
Record->hasAttr<TrivialABIAttr>();
7152 Record->setHasTrivialSpecialMemberForCall();
7162 auto CheckCompletedMemberFunction = [&](
CXXMethodDecl *MD) {
7173 MD->
isDeleted() ? diag::err_deleted_override
7174 : diag::err_non_deleted_override,
7176 return MD->isDeleted() != V->isDeleted();
7188 : diag::err_non_consteval_override,
7190 return MD->isConsteval() != V->isConsteval();
7199 auto CheckForDefaultedFunction = [&](
FunctionDecl *FD) ->
bool {
7200 if (!FD || FD->
isInvalidDecl() || !FD->isExplicitlyDefaulted())
7206 DefaultedSecondaryComparisons.push_back(FD);
7214 if (!
Record->isInvalidDecl() &&
7215 Record->hasAttr<VTablePointerAuthenticationAttr>())
7220 bool Incomplete = CheckForDefaultedFunction(M);
7223 if (
Record->isDependentType())
7229 if (!M->isImplicit() && !M->isUserProvided()) {
7233 Record->finishedDefaultedOrDeletedMember(M);
7234 M->setTrivialForCall(
7238 Record->setTrivialForCallFlags(M);
7247 M->isUserProvided()) {
7248 M->setTrivialForCall(HasTrivialABI);
7249 Record->setTrivialForCallFlags(M);
7252 if (!M->isInvalidDecl() && M->isExplicitlyDefaulted() &&
7253 M->hasAttr<DLLExportAttr>()) {
7259 M->dropAttr<DLLExportAttr>();
7261 if (M->hasAttr<DLLExportAttr>()) {
7267 bool EffectivelyConstexprDestructor =
true;
7272 llvm::SmallDenseSet<QualType> Visited;
7273 auto Check = [&Visited](
QualType T,
auto &&Check) ->
bool {
7274 if (!Visited.insert(T->getCanonicalTypeUnqualified()).second)
7277 T->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
7285 if (!Check(B.getType(), Check))
7288 if (!Check(FD->
getType(), Check))
7292 EffectivelyConstexprDestructor =
7300 M->isDefaulted() && M->isConstexpr() && M->size_overridden_methods() &&
7301 EffectivelyConstexprDestructor)
7305 CheckCompletedMemberFunction(M);
7314 CompleteMemberFunction(Dtor);
7316 bool HasMethodWithOverrideControl =
false,
7317 HasOverridingMethodWithoutOverrideControl =
false;
7318 for (
auto *D :
Record->decls()) {
7319 if (
auto *M = dyn_cast<CXXMethodDecl>(D)) {
7322 if (!
Record->isDependentType()) {
7328 if (M->hasAttr<OverrideAttr>()) {
7329 HasMethodWithOverrideControl =
true;
7330 }
else if (M->size_overridden_methods() > 0) {
7331 HasOverridingMethodWithoutOverrideControl =
true;
7334 if (M->isVirtualAsWritten() &&
Record->isEffectivelyFinal()) {
7335 Diag(M->getLocation(), diag::warn_unnecessary_virtual_specifier)
7342 CompleteMemberFunction(M);
7343 }
else if (
auto *F = dyn_cast<FriendDecl>(D)) {
7344 CheckForDefaultedFunction(
7345 dyn_cast_or_null<FunctionDecl>(F->getFriendDecl()));
7349 if (HasOverridingMethodWithoutOverrideControl) {
7350 bool HasInconsistentOverrideControl = HasMethodWithOverrideControl;
7351 for (
auto *M :
Record->methods())
7356 for (
FunctionDecl *FD : DefaultedSecondaryComparisons) {
7360 if (
auto *MD = dyn_cast<CXXMethodDecl>(FD))
7361 CheckCompletedMemberFunction(MD);
7382 if (
Context.getLangOpts().getLayoutCompatibility() ==
7386 Diag(
Record->getLocation(), diag::warn_cxx_ms_struct);
7392 bool ClangABICompat4 =
7393 Context.getLangOpts().getClangABICompat() <= LangOptions::ClangABI::Ver4;
7395 Context.getTargetInfo().getCallingConvKind(ClangABICompat4);
7400 if (
Record->getArgPassingRestrictions() !=
7402 Record->setArgPassingRestrictions(
7410 if (
Context.getTargetInfo().getCXXABI().areArgsDestroyedLeftToRightInCallee())
7411 Record->setParamDestroyedInCallee(
true);
7412 else if (
Record->hasNonTrivialDestructor())
7413 Record->setParamDestroyedInCallee(CanPass);
7422 if (
Record->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>())
7424 else if (
Record->hasAttr<CUDADeviceBuiltinTextureTypeAttr>())
7430 TypeAwareDecls{{OO_New, {}},
7433 {OO_Array_New, {}}};
7434 for (
auto *D :
Record->decls()) {
7441 auto CheckMismatchedTypeAwareAllocators =
7444 auto &NewDecls = TypeAwareDecls[NewKind];
7445 auto &DeleteDecls = TypeAwareDecls[DeleteKind];
7446 if (NewDecls.empty() == DeleteDecls.empty())
7449 Context.DeclarationNames.getCXXOperatorName(
7450 NewDecls.empty() ? DeleteKind : NewKind);
7452 Context.DeclarationNames.getCXXOperatorName(
7453 NewDecls.empty() ? NewKind : DeleteKind);
7455 diag::err_type_aware_allocator_missing_matching_operator)
7458 for (
auto MD : NewDecls)
7460 diag::note_unmatched_type_aware_allocator_declared)
7462 for (
auto MD : DeleteDecls)
7464 diag::note_unmatched_type_aware_allocator_declared)
7467 CheckMismatchedTypeAwareAllocators(OO_New, OO_Delete);
7468 CheckMismatchedTypeAwareAllocators(OO_Array_New, OO_Array_Delete);
7484 unsigned LHSQuals = 0;
7487 LHSQuals = FieldQuals;
7489 unsigned RHSQuals = FieldQuals;
7511 llvm::DenseMap<CXXRecordDecl *, ConstructorUsingShadowDecl *>
7517 : S(S), UseLoc(UseLoc) {
7518 bool DiagnosedMultipleConstructedBases =
false;
7524 for (
auto *D : Shadow->
redecls()) {
7525 auto *DShadow = cast<ConstructorUsingShadowDecl>(D);
7526 auto *DNominatedBase = DShadow->getNominatedBaseClass();
7527 auto *DConstructedBase = DShadow->getConstructedBaseClass();
7529 InheritedFromBases.insert(
7530 std::make_pair(DNominatedBase->getCanonicalDecl(),
7531 DShadow->getNominatedBaseClassShadowDecl()));
7532 if (DShadow->constructsVirtualBase())
7533 InheritedFromBases.insert(
7534 std::make_pair(DConstructedBase->getCanonicalDecl(),
7535 DShadow->getConstructedBaseClassShadowDecl()));
7537 assert(DNominatedBase == DConstructedBase);
7542 if (!ConstructedBase) {
7543 ConstructedBase = DConstructedBase;
7544 ConstructedBaseIntroducer = D->getIntroducer();
7545 }
else if (ConstructedBase != DConstructedBase &&
7547 if (!DiagnosedMultipleConstructedBases) {
7548 S.Diag(UseLoc, diag::err_ambiguous_inherited_constructor)
7549 << Shadow->getTargetDecl();
7550 S.Diag(ConstructedBaseIntroducer->getLocation(),
7551 diag::note_ambiguous_inherited_constructor_using)
7553 DiagnosedMultipleConstructedBases = true;
7555 S.Diag(D->getIntroducer()->getLocation(),
7556 diag::note_ambiguous_inherited_constructor_using)
7557 << DConstructedBase;
7561 if (DiagnosedMultipleConstructedBases)
7562 Shadow->setInvalidDecl();
7568 std::pair<CXXConstructorDecl *, bool>
7570 auto It = InheritedFromBases.find(
Base->getCanonicalDecl());
7571 if (It == InheritedFromBases.end())
7572 return std::make_pair(
nullptr,
false);
7576 return std::make_pair(
7577 S.findInheritingConstructor(UseLoc, Ctor, It->second),
7578 It->second->constructsVirtualBase());
7581 return std::make_pair(Ctor,
false);
7598 if (InheritedCtor) {
7601 Inherited->findConstructorForBase(ClassDecl, InheritedCtor).first;
7603 return BaseCtor->isConstexpr();
7671 if (Ctor && ClassDecl->
isUnion())
7691 for (
const auto &B : ClassDecl->
bases()) {
7692 auto *BaseClassDecl = B.getType()->getAsCXXRecordDecl();
7696 InheritedCtor, Inherited))
7709 for (
const auto *F : ClassDecl->
fields()) {
7710 if (F->isInvalidDecl())
7713 F->hasInClassInitializer())
7716 if (
const RecordType *RecordTy = BaseType->getAsCanonical<RecordType>()) {
7717 auto *FieldRecDecl =
7720 BaseType.getCVRQualifiers(),
7721 ConstArg && !F->isMutable()))
7736struct ComputingExceptionSpec {
7739 ComputingExceptionSpec(Sema &S, FunctionDecl *FD, SourceLocation Loc)
7741 Sema::CodeSynthesisContext Ctx;
7747 ~ComputingExceptionSpec() {
7753static Sema::ImplicitExceptionSpecification
7757 Sema::InheritedConstructorInfo *ICI);
7759static Sema::ImplicitExceptionSpecification
7764static Sema::ImplicitExceptionSpecification
7767 if (DFK.isSpecialMember())
7770 if (DFK.isComparison())
7772 DFK.asComparison());
7775 assert(CD->getInheritedConstructor() &&
7776 "only defaulted functions and inherited constructors have implicit "
7779 S, Loc, CD->getInheritedConstructor().getShadowDecl());
7806 auto ESI = IES.getExceptionSpec();
7824 PT.getNonReferenceType()->getAsCXXRecordDecl()) {
7845 "not an explicitly-defaulted special member");
7855 bool HadError =
false;
7868 bool ShouldDeleteForTypeMismatch =
false;
7869 unsigned ExpectedParams = 1;
7881 if (DeleteOnTypeMismatch)
7882 ShouldDeleteForTypeMismatch =
true;
7892 bool CanHaveConstParam =
false;
7902 ReturnType =
Type->getReturnType();
7907 std::nullopt, RD,
false);
7908 DeclType =
Context.getAddrSpaceQualType(
7910 QualType ExpectedReturnType =
Context.getLValueReferenceType(DeclType);
7912 if (!
Context.hasSameType(ReturnType, ExpectedReturnType)) {
7913 Diag(MD->
getLocation(), diag::err_defaulted_special_member_return_type)
7915 << ExpectedReturnType;
7921 if (DeleteOnTypeMismatch)
7922 ShouldDeleteForTypeMismatch =
true;
7939 if (!ExplicitObjectParameter.
isNull() &&
7942 Context.getCanonicalTagType(RD)))) {
7943 if (DeleteOnTypeMismatch)
7944 ShouldDeleteForTypeMismatch =
true;
7947 diag::err_defaulted_special_member_explicit_object_mismatch)
7960 bool HasConstParam =
false;
7961 if (ExpectedParams &&
ArgType->isReferenceType()) {
7967 if (DeleteOnTypeMismatch)
7968 ShouldDeleteForTypeMismatch =
true;
7971 diag::err_defaulted_special_member_volatile_param)
7977 if (HasConstParam && !CanHaveConstParam) {
7978 if (DeleteOnTypeMismatch)
7979 ShouldDeleteForTypeMismatch =
true;
7983 diag::err_defaulted_special_member_copy_const_param)
7989 diag::err_defaulted_special_member_move_const_param)
7994 }
else if (ExpectedParams) {
7998 "unexpected non-ref argument");
8032 diag::err_incorrect_defaulted_constexpr_with_vb)
8034 for (
const auto &I : RD->
vbases())
8035 Diag(I.getBeginLoc(), diag::note_constexpr_virtual_base_here);
8054 if (!
Type->hasExceptionSpec()) {
8063 Context.getFunctionType(ReturnType,
Type->getParamTypes(), EPI));
8072 if (ShouldDeleteForTypeMismatch) {
8077 Diag(DefaultLoc, diag::note_replace_equals_default_to_delete)
8081 if (ShouldDeleteForTypeMismatch && !HadError) {
8083 diag::warn_cxx17_compat_defaulted_method_type_mismatch)
8090 Diag(MD->
getLocation(), diag::err_out_of_line_default_deletes) << CSM;
8091 assert(!ShouldDeleteForTypeMismatch &&
"deleted non-first decl");
8113template<
typename Derived,
typename ResultList,
typename Result,
8115class DefaultedComparisonVisitor {
8120 DefaultedComparisonKind DCK)
8121 : S(S), RD(RD), FD(FD), DCK(DCK) {
8125 Fns.assign(Info->getUnqualifiedLookups().begin(),
8126 Info->getUnqualifiedLookups().end());
8130 ResultList visit() {
8138 case DefaultedComparisonKind::None:
8139 llvm_unreachable(
"not a defaulted comparison");
8141 case DefaultedComparisonKind::Equal:
8142 case DefaultedComparisonKind::ThreeWay:
8143 getDerived().visitSubobjects(Results, RD, ParamLvalType.
getQualifiers());
8146 case DefaultedComparisonKind::NotEqual:
8147 case DefaultedComparisonKind::Relational:
8148 Results.add(getDerived().visitExpandedSubobject(
8149 ParamLvalType, getDerived().getCompleteObject()));
8152 llvm_unreachable(
"");
8156 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
8162 bool visitSubobjects(ResultList &Results, CXXRecordDecl *
Record,
8166 for (CXXBaseSpecifier &Base :
Record->bases())
8167 if (Results.add(getDerived().visitSubobject(
8169 getDerived().getBase(&Base))))
8173 for (FieldDecl *Field :
Record->fields()) {
8176 if (
Field->isUnnamedBitField())
8179 if (
Field->isAnonymousStructOrUnion()) {
8180 if (visitSubobjects(Results,
Field->getType()->getAsCXXRecordDecl(),
8187 Qualifiers FieldQuals = Quals;
8188 if (
Field->isMutable())
8190 QualType FieldType =
8193 if (Results.add(getDerived().visitSubobject(
8194 FieldType, getDerived().getField(Field))))
8202 Result visitSubobject(QualType
Type, Subobject Subobj) {
8205 if (
auto *CAT = dyn_cast_or_null<ConstantArrayType>(AT))
8206 return getDerived().visitSubobjectArray(CAT->getElementType(),
8207 CAT->getSize(), Subobj);
8208 return getDerived().visitExpandedSubobject(
Type, Subobj);
8211 Result visitSubobjectArray(QualType
Type,
const llvm::APInt &Size,
8213 return getDerived().visitSubobject(
Type, Subobj);
8220 DefaultedComparisonKind DCK;
8221 UnresolvedSet<16> Fns;
8226struct DefaultedComparisonInfo {
8231 static DefaultedComparisonInfo deleted() {
8232 DefaultedComparisonInfo
Deleted;
8237 bool add(
const DefaultedComparisonInfo &R) {
8247struct DefaultedComparisonSubobject {
8255class DefaultedComparisonAnalyzer
8256 :
public DefaultedComparisonVisitor<DefaultedComparisonAnalyzer,
8257 DefaultedComparisonInfo,
8258 DefaultedComparisonInfo,
8259 DefaultedComparisonSubobject> {
8261 enum DiagnosticKind { NoDiagnostics, ExplainDeleted, ExplainConstexpr };
8264 DiagnosticKind Diagnose;
8267 using Base = DefaultedComparisonVisitor;
8268 using Result = DefaultedComparisonInfo;
8269 using Subobject = DefaultedComparisonSubobject;
8273 DefaultedComparisonAnalyzer(Sema &S, CXXRecordDecl *RD, FunctionDecl *FD,
8274 DefaultedComparisonKind DCK,
8275 DiagnosticKind Diagnose = NoDiagnostics)
8276 :
Base(S, RD, FD, DCK), Diagnose(Diagnose) {}
8279 if ((DCK == DefaultedComparisonKind::Equal ||
8280 DCK == DefaultedComparisonKind::ThreeWay) &&
8285 if (Diagnose == ExplainDeleted) {
8289 return Result::deleted();
8292 return Base::visit();
8296 Subobject getCompleteObject() {
8297 return Subobject{Subobject::CompleteObject, RD, FD->
getLocation()};
8300 Subobject getBase(CXXBaseSpecifier *Base) {
8301 return Subobject{Subobject::Base,
Base->getType()->getAsCXXRecordDecl(),
8302 Base->getBaseTypeLoc()};
8305 Subobject getField(FieldDecl *Field) {
8306 return Subobject{Subobject::Member,
Field,
Field->getLocation()};
8309 Result visitExpandedSubobject(QualType
Type, Subobject Subobj) {
8313 if (
Type->isReferenceType()) {
8314 if (Diagnose == ExplainDeleted) {
8315 S.
Diag(Subobj.Loc, diag::note_defaulted_comparison_reference_member)
8318 return Result::deleted();
8323 Expr *Args[] = {&Xi, &Xi};
8327 assert(OO !=
OO_None &&
"not an overloaded operator!");
8328 return visitBinaryOperator(OO, Args, Subobj);
8334 OverloadCandidateSet *SpaceshipCandidates =
nullptr) {
8338 OverloadCandidateSet CandidateSet(
8340 OverloadCandidateSet::OperatorRewriteInfo(
8342 !SpaceshipCandidates));
8347 CandidateSet.exclude(FD);
8349 if (Args[0]->
getType()->isOverloadableType())
8360 switch (CandidateSet.BestViableFunction(S, FD->
getLocation(), Best)) {
8366 if ((DCK == DefaultedComparisonKind::NotEqual ||
8367 DCK == DefaultedComparisonKind::Relational) &&
8368 !Best->RewriteKind) {
8369 if (Diagnose == ExplainDeleted) {
8370 if (Best->Function) {
8371 S.
Diag(Best->Function->getLocation(),
8372 diag::note_defaulted_comparison_not_rewritten_callee)
8375 assert(Best->Conversions.size() == 2 &&
8376 Best->Conversions[0].isUserDefined() &&
8377 "non-user-defined conversion from class to built-in "
8379 S.
Diag(Best->Conversions[0]
8380 .UserDefined.FoundConversionFunction.getDecl()
8382 diag::note_defaulted_comparison_not_rewritten_conversion)
8386 return Result::deleted();
8396 CXXRecordDecl *ArgClass = Args[0]->getType()->getAsCXXRecordDecl();
8397 if (ArgClass && Best->FoundDecl.getDecl() &&
8398 Best->FoundDecl.getDecl()->isCXXClassMember()) {
8399 QualType ObjectType = Subobj.Kind == Subobject::Member
8400 ? Args[0]->getType()
8403 ArgClass, Best->FoundDecl, ObjectType, Subobj.Loc,
8404 Diagnose == ExplainDeleted
8405 ? S.
PDiag(diag::note_defaulted_comparison_inaccessible)
8406 << FD << Subobj.Kind << Subobj.Decl
8408 return Result::deleted();
8411 bool NeedsDeducing =
8414 if (FunctionDecl *BestFD = Best->Function) {
8419 assert(!BestFD->isDeleted() &&
"wrong overload resolution result");
8421 if (Diagnose == ExplainConstexpr && !BestFD->isConstexpr()) {
8422 if (Subobj.Kind != Subobject::CompleteObject)
8423 S.
Diag(Subobj.Loc, diag::note_defaulted_comparison_not_constexpr)
8424 << Subobj.
Kind << Subobj.Decl;
8425 S.
Diag(BestFD->getLocation(),
8426 diag::note_defaulted_comparison_not_constexpr_here);
8428 return Result::deleted();
8430 R.Constexpr &= BestFD->isConstexpr();
8432 if (NeedsDeducing) {
8437 if (BestFD->getReturnType()->isUndeducedType() &&
8443 if (Diagnose == NoDiagnostics) {
8446 diag::err_defaulted_comparison_cannot_deduce_undeduced_auto)
8447 << Subobj.
Kind << Subobj.Decl;
8450 diag::note_defaulted_comparison_cannot_deduce_undeduced_auto)
8451 << Subobj.
Kind << Subobj.Decl;
8452 S.
Diag(BestFD->getLocation(),
8453 diag::note_defaulted_comparison_cannot_deduce_callee)
8454 << Subobj.
Kind << Subobj.Decl;
8456 return Result::deleted();
8459 BestFD->getCallResultType());
8461 if (Diagnose == ExplainDeleted) {
8462 S.
Diag(Subobj.Loc, diag::note_defaulted_comparison_cannot_deduce)
8463 << Subobj.
Kind << Subobj.Decl
8464 << BestFD->getCallResultType().withoutLocalFastQualifiers();
8465 S.
Diag(BestFD->getLocation(),
8466 diag::note_defaulted_comparison_cannot_deduce_callee)
8467 << Subobj.
Kind << Subobj.Decl;
8469 return Result::deleted();
8471 R.Category = Info->Kind;
8474 QualType T = Best->BuiltinParamTypes[0];
8475 assert(T == Best->BuiltinParamTypes[1] &&
8476 "builtin comparison for different types?");
8477 assert(Best->BuiltinParamTypes[2].isNull() &&
8478 "invalid builtin comparison");
8483 if (Diagnose == ExplainDeleted) {
8485 diag::note_defaulted_comparison_vector_types)
8487 S.
Diag(Subobj.Decl->getLocation(), diag::note_declared_at);
8489 return Result::deleted();
8492 if (NeedsDeducing) {
8493 std::optional<ComparisonCategoryType> Cat =
8495 assert(Cat &&
"no category for builtin comparison?");
8506 if (Diagnose == ExplainDeleted) {
8509 Kind = OO == OO_EqualEqual ? 1 : 2;
8510 CandidateSet.NoteCandidates(
8512 Subobj.Loc, S.
PDiag(diag::note_defaulted_comparison_ambiguous)
8513 << FD << Kind << Subobj.Kind << Subobj.Decl),
8516 R = Result::deleted();
8520 if (Diagnose == ExplainDeleted) {
8521 if ((DCK == DefaultedComparisonKind::NotEqual ||
8522 DCK == DefaultedComparisonKind::Relational) &&
8523 !Best->RewriteKind) {
8524 S.
Diag(Best->Function->getLocation(),
8525 diag::note_defaulted_comparison_not_rewritten_callee)
8529 diag::note_defaulted_comparison_calls_deleted)
8530 << FD << Subobj.
Kind << Subobj.Decl;
8534 R = Result::deleted();
8540 if (OO == OO_Spaceship &&
8544 if (!
R.add(visitBinaryOperator(OO_EqualEqual, Args, Subobj,
8546 R.add(visitBinaryOperator(OO_Less, Args, Subobj, &CandidateSet));
8550 if (Diagnose == ExplainDeleted) {
8551 S.
Diag(Subobj.Loc, diag::note_defaulted_comparison_no_viable_function)
8552 << FD << (OO == OO_EqualEqual || OO == OO_ExclaimEqual)
8553 << Subobj.
Kind << Subobj.Decl;
8557 if (SpaceshipCandidates) {
8558 SpaceshipCandidates->NoteCandidates(
8563 diag::note_defaulted_comparison_no_viable_function_synthesized)
8564 << (OO == OO_EqualEqual ? 0 : 1);
8567 CandidateSet.NoteCandidates(
8572 R = Result::deleted();
8581struct StmtListResult {
8582 bool IsInvalid =
false;
8583 llvm::SmallVector<Stmt*, 16> Stmts;
8586 IsInvalid |= S.isInvalid();
8589 Stmts.push_back(S.get());
8596class DefaultedComparisonSynthesizer
8597 :
public DefaultedComparisonVisitor<DefaultedComparisonSynthesizer,
8598 StmtListResult, StmtResult,
8599 std::pair<ExprResult, ExprResult>> {
8601 unsigned ArrayDepth = 0;
8604 using Base = DefaultedComparisonVisitor;
8605 using ExprPair = std::pair<ExprResult, ExprResult>;
8609 DefaultedComparisonSynthesizer(Sema &S, CXXRecordDecl *RD, FunctionDecl *FD,
8610 DefaultedComparisonKind DCK,
8611 SourceLocation BodyLoc)
8612 :
Base(S, RD, FD, DCK), Loc(BodyLoc) {}
8616 Sema::CompoundScopeRAII CompoundScope(S);
8618 StmtListResult Stmts = visit();
8619 if (Stmts.IsInvalid)
8624 case DefaultedComparisonKind::None:
8625 llvm_unreachable(
"not a defaulted comparison");
8627 case DefaultedComparisonKind::Equal: {
8636 auto OldStmts = std::move(Stmts.Stmts);
8637 Stmts.Stmts.clear();
8640 auto FinishCmp = [&] {
8641 if (Expr *Prior = CmpSoFar.
get()) {
8643 if (RetVal.
isUnset() && Stmts.Stmts.empty())
8646 else if (Stmts.add(buildIfNotCondReturnFalse(Prior)))
8652 for (Stmt *EAsStmt : llvm::reverse(OldStmts)) {
8653 Expr *E = dyn_cast<Expr>(EAsStmt);
8656 if (FinishCmp() || Stmts.add(EAsStmt))
8665 CmpSoFar = S.CreateBuiltinBinOp(Loc, BO_LAnd, E, CmpSoFar.
get());
8671 std::reverse(Stmts.Stmts.begin(), Stmts.Stmts.end());
8674 RetVal = S.ActOnCXXBoolLiteral(Loc, tok::kw_true);
8678 case DefaultedComparisonKind::ThreeWay: {
8682 ComparisonCategoryType::StrongOrdering, Loc,
8683 Sema::ComparisonCategoryUsage::DefaultedOperator);
8686 VarDecl *EqualVD = S.Context.CompCategories.getInfoForType(
StrongOrdering)
8687 .getValueInfo(ComparisonCategoryResult::Equal)
8689 RetVal = getDecl(EqualVD);
8692 RetVal = buildStaticCastToR(RetVal.
get());
8696 case DefaultedComparisonKind::NotEqual:
8697 case DefaultedComparisonKind::Relational:
8698 RetVal =
cast<Expr>(Stmts.Stmts.pop_back_val());
8705 StmtResult ReturnStmt = S.BuildReturnStmt(Loc, RetVal.
get());
8706 if (ReturnStmt.isInvalid())
8708 Stmts.Stmts.push_back(ReturnStmt.get());
8710 return S.ActOnCompoundStmt(Loc, Loc, Stmts.Stmts,
false);
8715 return S.BuildDeclarationNameExpr(
8716 CXXScopeSpec(), DeclarationNameInfo(VD->
getDeclName(), Loc), VD);
8724 ExprPair getCompleteObject() {
8727 if (
const auto *MD = dyn_cast<CXXMethodDecl>(FD);
8728 MD && MD->isImplicitObjectMemberFunction()) {
8730 LHS = S.ActOnCXXThis(Loc);
8732 LHS = S.CreateBuiltinUnaryOp(Loc, UO_Deref, LHS.
get());
8734 LHS = getParam(Param++);
8741 ExprPair getBase(CXXBaseSpecifier *Base) {
8742 ExprPair Obj = getCompleteObject();
8743 if (Obj.first.isInvalid() || Obj.second.isInvalid())
8746 const auto CastToBase = [&](Expr *E) {
8747 QualType ToType = S.Context.getQualifiedType(
8749 return S.ImpCastExprToType(E, ToType, CK_DerivedToBase,
VK_LValue, &Path);
8751 return {CastToBase(Obj.first.get()), CastToBase(Obj.second.get())};
8754 ExprPair getField(FieldDecl *Field) {
8755 ExprPair Obj = getCompleteObject();
8756 if (Obj.first.isInvalid() || Obj.second.isInvalid())
8760 DeclarationNameInfo NameInfo(
Field->getDeclName(), Loc);
8761 return {S.BuildFieldReferenceExpr(Obj.first.get(),
false, Loc,
8762 CXXScopeSpec(), Field,
Found, NameInfo),
8763 S.BuildFieldReferenceExpr(Obj.second.get(),
false, Loc,
8764 CXXScopeSpec(), Field,
Found, NameInfo)};
8771 if (
Cond.isInvalid())
8774 ExprResult NotCond = S.CreateBuiltinUnaryOp(Loc, UO_LNot,
Cond.get());
8779 assert(!
False.isInvalid() &&
"should never fail");
8781 if (ReturnFalse.isInvalid())
8784 return S.ActOnIfStmt(Loc, IfStatementKind::Ordinary, Loc,
nullptr,
8785 S.ActOnCondition(
nullptr, Loc, NotCond.
get(),
8786 Sema::ConditionKind::Boolean),
8787 Loc, ReturnFalse.get(), SourceLocation(),
nullptr);
8792 QualType SizeType = S.Context.getSizeType();
8793 Size =
Size.zextOrTrunc(S.Context.getTypeSize(SizeType));
8796 IdentifierInfo *IterationVarName =
nullptr;
8799 llvm::raw_svector_ostream
OS(Str);
8800 OS <<
"i" << ArrayDepth;
8801 IterationVarName = &S.Context.Idents.get(
OS.str());
8804 S.Context, S.CurContext, Loc, Loc, IterationVarName, SizeType,
8805 S.Context.getTrivialTypeSourceInfo(SizeType, Loc),
SC_None);
8806 llvm::APInt
Zero(S.Context.getTypeSize(SizeType), 0);
8809 Stmt *
Init =
new (S.Context) DeclStmt(DeclGroupRef(IterationVar), Loc, Loc);
8811 auto IterRef = [&] {
8813 CXXScopeSpec(), DeclarationNameInfo(IterationVarName, Loc),
8815 assert(!Ref.
isInvalid() &&
"can't reference our own variable?");
8821 Loc, BO_NE, IterRef(),
8823 assert(!
Cond.isInvalid() &&
"should never fail");
8826 ExprResult Inc = S.CreateBuiltinUnaryOp(Loc, UO_PreInc, IterRef());
8827 assert(!
Inc.isInvalid() &&
"should never fail");
8833 return S.CreateBuiltinArraySubscriptExpr(E.get(), Loc, IterRef(), Loc);
8835 Subobj.first = Index(Subobj.first);
8836 Subobj.second = Index(Subobj.second);
8843 if (Substmt.isInvalid())
8849 if (Expr *ElemCmp = dyn_cast<Expr>(Substmt.get())) {
8850 assert(DCK == DefaultedComparisonKind::Equal &&
8851 "should have non-expression statement");
8852 Substmt = buildIfNotCondReturnFalse(ElemCmp);
8853 if (Substmt.isInvalid())
8858 return S.ActOnForStmt(Loc, Loc,
Init,
8859 S.ActOnCondition(
nullptr, Loc,
Cond.get(),
8860 Sema::ConditionKind::Boolean),
8861 S.MakeFullDiscardedValueExpr(
Inc.get()), Loc,
8866 if (Obj.first.isInvalid() || Obj.second.isInvalid())
8872 if (
Type->isOverloadableType())
8873 Op = S.CreateOverloadedBinOp(Loc, Opc, Fns, Obj.first.get(),
8874 Obj.second.get(),
true,
8877 Op = S.CreateBuiltinBinOp(Loc, Opc, Obj.first.get(), Obj.second.get());
8882 case DefaultedComparisonKind::None:
8883 llvm_unreachable(
"not a defaulted comparison");
8885 case DefaultedComparisonKind::Equal:
8888 Op = S.PerformContextuallyConvertToBool(Op.
get());
8893 case DefaultedComparisonKind::ThreeWay: {
8898 Op = buildStaticCastToR(Op.
get());
8903 IdentifierInfo *Name = &S.Context.Idents.get(
"cmp");
8906 S.Context.getTrivialTypeSourceInfo(R, Loc),
SC_None);
8907 S.AddInitializerToDecl(VD, Op.
get(),
false);
8908 Stmt *InitStmt =
new (S.Context) DeclStmt(DeclGroupRef(VD), Loc, Loc);
8914 llvm::APInt ZeroVal(S.Context.getIntWidth(S.Context.IntTy), 0);
8919 Comp = S.CreateOverloadedBinOp(Loc, BO_NE, Fns, VDRef.
get(),
Zero,
true,
8922 Comp = S.CreateBuiltinBinOp(Loc, BO_NE, VDRef.
get(),
Zero);
8923 if (
Comp.isInvalid())
8925 Sema::ConditionResult
Cond = S.ActOnCondition(
8926 nullptr, Loc,
Comp.get(), Sema::ConditionKind::Boolean);
8927 if (
Cond.isInvalid())
8931 VDRef = getDecl(VD);
8934 StmtResult ReturnStmt = S.BuildReturnStmt(Loc, VDRef.
get());
8935 if (ReturnStmt.isInvalid())
8939 return S.ActOnIfStmt(Loc, IfStatementKind::Ordinary, Loc, InitStmt,
Cond,
8940 Loc, ReturnStmt.get(),
8941 SourceLocation(),
nullptr);
8944 case DefaultedComparisonKind::NotEqual:
8945 case DefaultedComparisonKind::Relational:
8950 llvm_unreachable(
"");
8956 assert(!
R->isUndeducedType() &&
"type should have been deduced already");
8961 return S.BuildCXXNamedCast(Loc, tok::kw_static_cast,
8962 S.Context.getTrivialTypeSourceInfo(R, Loc), E,
8963 SourceRange(Loc, Loc), SourceRange(Loc, Loc));
8974 Self.LookupOverloadedOperatorName(OO, S, Operators);
8987 if (Op == OO_Spaceship) {
8988 Lookup(OO_ExclaimEqual);
8990 Lookup(OO_EqualEqual);
9021 assert(!MD->isStatic() &&
"comparison function cannot be a static member");
9023 if (MD->getRefQualifier() ==
RQ_RValue) {
9024 Diag(MD->getLocation(), diag::err_ref_qualifier_comparison_operator);
9030 MD->setType(
Context.getFunctionType(FPT->getReturnType(),
9031 FPT->getParamTypes(), EPI));
9037 QualType T = MD->getFunctionObjectParameterReferenceType();
9038 if (!T.getNonReferenceType().isConstQualified() &&
9039 (MD->isImplicitObjectMemberFunction() || T->isLValueReferenceType())) {
9041 if (MD->isExplicitObjectMemberFunction()) {
9042 Loc = MD->getParamDecl(0)->getBeginLoc();
9044 MD->getParamDecl(0)->getExplicitObjectParamThisLoc());
9046 Loc = MD->getLocation();
9048 InsertLoc = Loc.getRParenLoc();
9052 if (!MD->isImplicit()) {
9053 Diag(Loc, diag::err_defaulted_comparison_non_const)
9058 if (MD->isExplicitObjectMemberFunction()) {
9059 assert(T->isLValueReferenceType());
9060 MD->getParamDecl(0)->setType(
Context.getLValueReferenceType(
9061 T.getNonReferenceType().withConst()));
9066 MD->setType(
Context.getFunctionType(FPT->getReturnType(),
9067 FPT->getParamTypes(), EPI));
9071 if (MD->isVolatile()) {
9072 Diag(MD->getLocation(), diag::err_volatile_comparison_operator);
9078 MD->setType(
Context.getFunctionType(FPT->getReturnType(),
9079 FPT->getParamTypes(), EPI));
9085 (IsMethod ? 1 : 2)) {
9089 <<
int(IsMethod) <<
int(DCK);
9095 QualType ParmTy = Param->getType();
9102 ExpectedTy =
Context.getCanonicalTagType(RD);
9104 CTy = Ref->getPointeeType();
9114 RD = CTy->getAsCXXRecordDecl();
9115 Ok &= RD !=
nullptr;
9129 <<
int(DCK) << ParmTy << RefTy <<
int(!IsMethod) << PlainTy
9130 << Param->getSourceRange();
9132 assert(!IsMethod &&
"should know expected type for method");
9134 diag::err_defaulted_comparison_param_unknown)
9135 <<
int(DCK) << ParmTy << Param->getSourceRange();
9141 Diag(FD->
getLocation(), diag::err_defaulted_comparison_param_mismatch)
9143 << ParmTy << Param->getSourceRange();
9148 assert(RD &&
"must have determined class");
9157 diag::err_defaulted_comparison_not_friend,
int(DCK),
9162 return declaresSameEntity(F->getFriendDecl(), FD);
9165 <<
int(DCK) <<
int(0) << RD;
9177 Diag(FD->
getLocation(), diag::err_defaulted_comparison_return_type_not_bool)
9187 RT->getContainedDeducedType() &&
9189 RT->getContainedAutoType()->isConstrained())) {
9191 diag::err_defaulted_comparison_deduced_return_type_not_auto)
9203 DefaultedComparisonInfo Info =
9204 DefaultedComparisonAnalyzer(*
this, RD, FD, DCK).visit();
9218 DefaultedComparisonAnalyzer(*
this, RD, FD, DCK,
9219 DefaultedComparisonAnalyzer::ExplainDeleted)
9230 diag::note_previous_declaration);
9242 DefaultedComparisonAnalyzer(*
this, RD, FD, DCK,
9243 DefaultedComparisonAnalyzer::ExplainDeleted)
9265 Context.adjustDeducedFunctionResultType(
9293 Diag(FD->
getBeginLoc(), diag::err_defaulted_comparison_constexpr_mismatch)
9295 DefaultedComparisonAnalyzer(*
this, RD, FD, DCK,
9296 DefaultedComparisonAnalyzer::ExplainConstexpr)
9317 EPI.ExceptionSpec.SourceDecl = FD;
9319 FPT->getParamTypes(), EPI));
9334 EqualEqual->setImplicit();
9349 Scope.addContextNote(UseLoc);
9356 CXXRecordDecl *RD = PT.getNonReferenceType()->getAsCXXRecordDecl();
9360 DefaultedComparisonSynthesizer(*
this, RD, FD, DCK, BodyLoc).build();
9374 L->CompletedImplicitDefinition(FD);
9381 ComputingExceptionSpec CES(S, FD, Loc);
9411 DefaultedComparisonSynthesizer(S, RD, FD, DCK, BodyLoc).build();
9412 if (!Body.isInvalid())
9433 for (
auto &Check : Overriding)
9445template<
typename Derived>
9446struct SpecialMemberVisitor {
9453 bool IsConstructor =
false, IsAssignment =
false, ConstArg =
false;
9457 : S(S), MD(MD), CSM(CSM), ICI(ICI) {
9462 IsConstructor =
true;
9466 IsAssignment =
true;
9471 llvm_unreachable(
"invalid special member kind");
9475 if (const ReferenceType *RT =
9476 MD->getNonObjectParameter(0)->getType()->getAs<ReferenceType>())
9477 ConstArg = RT->getPointeeType().isConstQualified();
9481 Derived &getDerived() {
return static_cast<Derived&
>(*this); }
9484 bool isMove()
const {
9485 return CSM == CXXSpecialMemberKind::MoveConstructor ||
9486 CSM == CXXSpecialMemberKind::MoveAssignment;
9490 Sema::SpecialMemberOverloadResult lookupIn(CXXRecordDecl *
Class,
9491 unsigned Quals,
bool IsMutable) {
9493 ConstArg && !IsMutable);
9498 Sema::SpecialMemberOverloadResult lookupInheritedCtor(CXXRecordDecl *
Class) {
9501 assert(CSM == CXXSpecialMemberKind::DefaultConstructor);
9510 typedef llvm::PointerUnion<CXXBaseSpecifier*, FieldDecl*> Subobject;
9513 static SourceLocation getSubobjectLoc(Subobject Subobj) {
9516 if (
auto *B = dyn_cast<CXXBaseSpecifier *>(Subobj))
9517 return B->getBaseTypeLoc();
9524 VisitNonVirtualBases,
9529 VisitPotentiallyConstructedBases,
9535 bool visit(BasesToVisit Bases) {
9538 if (Bases == VisitPotentiallyConstructedBases)
9539 Bases = RD->
isAbstract() ? VisitNonVirtualBases : VisitAllBases;
9541 for (
auto &B : RD->
bases())
9542 if ((Bases == VisitDirectBases || !B.isVirtual()) &&
9543 getDerived().visitBase(&B))
9546 if (Bases == VisitAllBases)
9547 for (
auto &B : RD->
vbases())
9548 if (getDerived().visitBase(&B))
9551 for (
auto *F : RD->
fields())
9552 if (!F->isInvalidDecl() && !F->isUnnamedBitField() &&
9553 getDerived().visitField(F))
9562struct SpecialMemberDeletionInfo
9563 : SpecialMemberVisitor<SpecialMemberDeletionInfo> {
9568 bool AllFieldsAreConst;
9570 SpecialMemberDeletionInfo(Sema &S, CXXMethodDecl *MD,
9572 Sema::InheritedConstructorInfo *ICI,
bool Diagnose)
9573 : SpecialMemberVisitor(S, MD, CSM, ICI), Diagnose(Diagnose),
9574 Loc(MD->getLocation()), AllFieldsAreConst(
true) {}
9579 return ICI ? CXXSpecialMemberKind::Invalid : CSM;
9582 bool shouldDeleteForVariantObjCPtrMember(FieldDecl *FD, QualType FieldType);
9584 bool shouldDeleteForVariantPtrAuthMember(
const FieldDecl *FD);
9586 bool visitBase(CXXBaseSpecifier *Base) {
return shouldDeleteForBase(Base); }
9587 bool visitField(FieldDecl *Field) {
return shouldDeleteForField(Field); }
9589 bool shouldDeleteForBase(CXXBaseSpecifier *Base);
9590 bool shouldDeleteForField(FieldDecl *FD);
9591 bool shouldDeleteForAllConstMembers();
9593 bool shouldDeleteForClassSubobject(CXXRecordDecl *
Class, Subobject Subobj,
9595 bool shouldDeleteForSubobjectCall(Subobject Subobj,
9596 Sema::SpecialMemberOverloadResult SMOR,
9597 bool IsDtorCallInCtor);
9599 bool isAccessible(Subobject Subobj, CXXMethodDecl *D);
9605bool SpecialMemberDeletionInfo::isAccessible(Subobject Subobj,
9606 CXXMethodDecl *target) {
9611 if (CXXBaseSpecifier *base = Subobj.dyn_cast<CXXBaseSpecifier*>()) {
9626bool SpecialMemberDeletionInfo::shouldDeleteForSubobjectCall(
9627 Subobject Subobj, Sema::SpecialMemberOverloadResult SMOR,
9628 bool IsDtorCallInCtor) {
9630 FieldDecl *
Field = Subobj.dyn_cast<FieldDecl*>();
9639 } DiagKind = NotSet;
9642 if (CSM == CXXSpecialMemberKind::DefaultConstructor && Field &&
9643 Field->getParent()->isUnion()) {
9653 DiagKind = !
Decl ? NoDecl : DeletedDecl;
9655 DiagKind = MultipleDecl;
9656 else if (!isAccessible(Subobj, Decl))
9657 DiagKind = InaccessibleDecl;
9658 else if (!IsDtorCallInCtor && Field &&
Field->getParent()->isUnion() &&
9659 !
Decl->isTrivial()) {
9665 if (CSM == CXXSpecialMemberKind::DefaultConstructor) {
9673 DiagKind = NonTrivialDecl;
9675 DiagKind = NonTrivialDecl;
9679 if (DiagKind == NotSet)
9685 diag::note_deleted_special_member_class_subobject)
9687 << DiagKind << IsDtorCallInCtor <<
false;
9691 diag::note_deleted_special_member_class_subobject)
9692 << getEffectiveCSM() << MD->
getParent() <<
false
9693 <<
Base->getType() << DiagKind << IsDtorCallInCtor
9697 if (DiagKind == DeletedDecl)
9707bool SpecialMemberDeletionInfo::shouldDeleteForClassSubobject(
9708 CXXRecordDecl *
Class, Subobject Subobj,
unsigned Quals) {
9709 FieldDecl *
Field = Subobj.dyn_cast<FieldDecl*>();
9710 bool IsMutable =
Field &&
Field->isMutable();
9726 if (!(CSM == CXXSpecialMemberKind::DefaultConstructor && Field &&
9727 Field->hasInClassInitializer()) &&
9728 shouldDeleteForSubobjectCall(Subobj, lookupIn(
Class, Quals, IsMutable),
9735 if (IsConstructor) {
9736 Sema::SpecialMemberOverloadResult SMOR =
9738 false,
false,
false,
false);
9739 if (shouldDeleteForSubobjectCall(Subobj, SMOR,
true))
9746bool SpecialMemberDeletionInfo::shouldDeleteForVariantObjCPtrMember(
9747 FieldDecl *FD, QualType FieldType) {
9756 if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
9762 S.
Diag(FD->
getLocation(), diag::note_deleted_special_member_class_subobject)
9763 << getEffectiveCSM() << ParentClass <<
true << FD << 4
9770bool SpecialMemberDeletionInfo::shouldDeleteForVariantPtrAuthMember(
9771 const FieldDecl *FD) {
9780 if (CSM == CXXSpecialMemberKind::DefaultConstructor ||
9781 CSM == CXXSpecialMemberKind::Destructor)
9786 S.
Diag(FD->
getLocation(), diag::note_deleted_special_member_class_subobject)
9787 << getEffectiveCSM() << ParentClass <<
true << FD << 4
9796bool SpecialMemberDeletionInfo::shouldDeleteForBase(CXXBaseSpecifier *Base) {
9797 CXXRecordDecl *BaseClass =
Base->getType()->getAsCXXRecordDecl();
9804 Sema::SpecialMemberOverloadResult SMOR = lookupInheritedCtor(BaseClass);
9805 if (
auto *BaseCtor = SMOR.
getMethod()) {
9810 if (BaseCtor->isDeleted() && Diagnose) {
9812 diag::note_deleted_special_member_class_subobject)
9813 << getEffectiveCSM() << MD->
getParent() <<
false
9814 <<
Base->getType() << 1 <<
false
9818 return BaseCtor->isDeleted();
9820 return shouldDeleteForClassSubobject(BaseClass, Base, 0);
9825bool SpecialMemberDeletionInfo::shouldDeleteForField(FieldDecl *FD) {
9829 if (inUnion() && shouldDeleteForVariantObjCPtrMember(FD, FieldType))
9832 if (inUnion() && shouldDeleteForVariantPtrAuthMember(FD))
9835 if (CSM == CXXSpecialMemberKind::DefaultConstructor) {
9840 S.
Diag(FD->
getLocation(), diag::note_deleted_default_ctor_uninit_field)
9841 << !!ICI << MD->
getParent() << FD << FieldType << 0;
9851 S.
Diag(FD->
getLocation(), diag::note_deleted_default_ctor_uninit_field)
9857 AllFieldsAreConst =
false;
9858 }
else if (CSM == CXXSpecialMemberKind::CopyConstructor) {
9863 S.
Diag(FD->
getLocation(), diag::note_deleted_copy_ctor_rvalue_reference)
9867 }
else if (IsAssignment) {
9872 << isMove() << MD->
getParent() << FD << FieldType << 0;
9887 if (!inUnion() && FieldRecord->
isUnion() &&
9889 bool AllVariantFieldsAreConst =
true;
9892 for (
auto *UI : FieldRecord->
fields()) {
9895 if (shouldDeleteForVariantObjCPtrMember(&*UI, UnionFieldType))
9898 if (shouldDeleteForVariantPtrAuthMember(&*UI))
9902 AllVariantFieldsAreConst =
false;
9905 if (UnionFieldRecord &&
9906 shouldDeleteForClassSubobject(UnionFieldRecord, UI,
9912 if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
9913 AllVariantFieldsAreConst && !FieldRecord->
field_empty()) {
9916 diag::note_deleted_default_ctor_all_const)
9927 if (shouldDeleteForClassSubobject(FieldRecord, FD,
9938bool SpecialMemberDeletionInfo::shouldDeleteForAllConstMembers() {
9941 if (CSM == CXXSpecialMemberKind::DefaultConstructor && inUnion() &&
9942 AllFieldsAreConst) {
9943 bool AnyFields =
false;
9945 if ((AnyFields = !F->isUnnamedBitField()))
9951 diag::note_deleted_default_ctor_all_const)
9997 bool DeletesOnlyMatchingCopy =
10002 (!DeletesOnlyMatchingCopy ||
10007 for (
auto *I : RD->
ctors()) {
10008 if (I->isMoveConstructor()) {
10009 UserDeclaredMove = I;
10013 assert(UserDeclaredMove);
10015 (!DeletesOnlyMatchingCopy ||
10020 for (
auto *I : RD->
methods()) {
10021 if (I->isMoveAssignmentOperator()) {
10022 UserDeclaredMove = I;
10026 assert(UserDeclaredMove);
10029 if (UserDeclaredMove) {
10031 diag::note_deleted_copy_user_declared_move)
10048 Context.DeclarationNames.getCXXOperatorName(OO_Delete);
10053 OperatorDelete, IDP,
10061 SpecialMemberDeletionInfo SMI(*
this, MD, CSM, ICI,
Diagnose);
10069 if (SMI.visit(SMI.IsAssignment ? SMI.VisitDirectBases
10070 : SMI.VisitPotentiallyConstructedBases))
10073 if (SMI.shouldDeleteForAllConstMembers())
10084 auto RealCSM = CSM;
10088 return CUDA().inferTargetForImplicitSpecialMember(RD, RealCSM, MD,
10097 assert(DFK &&
"not a defaultable function");
10104 DefaultedComparisonAnalyzer(
10106 DFK.
asComparison(), DefaultedComparisonAnalyzer::ExplainDeleted)
10127 *Selected =
nullptr;
10131 llvm_unreachable(
"not a special member");
10149 for (
auto *CI : RD->
ctors()) {
10150 if (!CI->isDefaultConstructor())
10157 *Selected = DefCtor;
10190 }
else if (!Selected) {
10198 goto NeedOverloadResolution;
10208 }
else if (!Selected) {
10213 goto NeedOverloadResolution;
10217 NeedOverloadResolution:
10246 llvm_unreachable(
"unknown special method kind");
10250 for (
auto *CI : RD->
ctors())
10251 if (!CI->isImplicit())
10258 dyn_cast<CXXConstructorDecl>(TI->getTemplatedDecl()))
10288 ConstRHS, TAH, Diagnose ? &Selected :
nullptr))
10296 S.
Diag(SubobjLoc, diag::note_nontrivial_no_def_ctor)
10299 S.
Diag(CD->getLocation(), diag::note_user_declared_ctor);
10300 }
else if (!Selected)
10301 S.
Diag(SubobjLoc, diag::note_nontrivial_no_copy)
10306 << Kind << SubType.getUnqualifiedType() << CSM;
10308 S.
Diag(SubobjLoc, diag::note_nontrivial_user_provided)
10309 << Kind << SubType.getUnqualifiedType() << CSM;
10314 S.
Diag(SubobjLoc, diag::note_nontrivial_subobject)
10315 << Kind << SubType.getUnqualifiedType() << CSM;
10331 for (
const auto *FI : RD->
fields()) {
10332 if (FI->isInvalidDecl() || FI->isUnnamedBitField())
10338 if (FI->isAnonymousStructOrUnion()) {
10340 CSM, ConstArg, TAH, Diagnose))
10350 FI->hasInClassInitializer()) {
10352 S.
Diag(FI->getLocation(), diag::note_nontrivial_default_member_init)
10363 S.
Diag(FI->getLocation(), diag::note_nontrivial_objc_ownership)
10368 bool ConstRHS = ConstArg && !FI->isMutable();
10392 "not special enough");
10396 bool ConstArg =
false;
10420 const bool ClangABICompat14 =
Context.getLangOpts().getClangABICompat() <=
10421 LangOptions::ClangABI::Ver14;
10424 ClangABICompat14)) {
10428 <<
Context.getLValueReferenceType(
10429 Context.getCanonicalTagType(RD).withConst());
10447 <<
Context.getRValueReferenceType(
Context.getCanonicalTagType(RD));
10454 llvm_unreachable(
"not a special member");
10460 diag::note_nontrivial_default_arg)
10479 for (
const auto &BI : RD->
bases())
10521 Diag(BS.
getBeginLoc(), diag::note_nontrivial_has_virtual) << RD << 1;
10526 for (
const auto *MI : RD->
methods()) {
10527 if (MI->isVirtual()) {
10529 Diag(MLoc, diag::note_nontrivial_has_virtual) << RD << 0;
10534 llvm_unreachable(
"dynamic class with no vbases and no virtual functions");
10542struct FindHiddenVirtualMethod {
10550 static bool CheckMostOverridenMethods(
10552 const llvm::SmallPtrSetImpl<const CXXMethodDecl *> &Methods) {
10556 if (CheckMostOverridenMethods(O, Methods))
10566 auto *BaseRecord = Specifier->getType()->castAsRecordDecl();
10570 bool foundSameNameMethod =
false;
10572 for (Path.
Decls = BaseRecord->lookup(Name).begin();
10577 foundSameNameMethod =
true;
10594 if (!CheckMostOverridenMethods(MD, OverridenAndUsingBaseMethods))
10595 overloadedMethods.push_back(MD);
10599 if (foundSameNameMethod)
10600 OverloadedMethods.append(overloadedMethods.begin(),
10601 overloadedMethods.end());
10602 return foundSameNameMethod;
10609 llvm::SmallPtrSetImpl<const CXXMethodDecl *>& Methods) {
10625 FindHiddenVirtualMethod FHVM;
10634 ND = shad->getTargetDecl();
10640 OverloadedMethods = FHVM.OverloadedMethods;
10645 for (
const CXXMethodDecl *overloadedMD : OverloadedMethods) {
10647 diag::note_hidden_overloaded_virtual_declared_here) << overloadedMD;
10649 Diag(overloadedMD->getLocation(), PD);
10662 if (!OverloadedMethods.empty()) {
10664 << MD << (OverloadedMethods.size() > 1);
10671 auto PrintDiagAndRemoveAttr = [&](
unsigned N) {
10674 Diag(RD.
getAttr<TrivialABIAttr>()->getLocation(),
10675 diag::ext_cannot_use_trivial_abi) << &RD;
10676 Diag(RD.
getAttr<TrivialABIAttr>()->getLocation(),
10677 diag::note_cannot_use_trivial_abi_reason) << &RD << N;
10684 PrintDiagAndRemoveAttr(1);
10688 for (
const auto &B : RD.
bases()) {
10691 if (!B.getType()->isDependentType() &&
10692 !B.getType()->getAsCXXRecordDecl()->canPassInRegisters()) {
10693 PrintDiagAndRemoveAttr(2);
10697 if (B.isVirtual()) {
10698 PrintDiagAndRemoveAttr(3);
10703 for (
const auto *FD : RD.
fields()) {
10708 PrintDiagAndRemoveAttr(4);
10714 PrintDiagAndRemoveAttr(6);
10718 if (
const auto *RT =
10720 if (!RT->isDependentType() &&
10722 ->canPassInRegisters()) {
10723 PrintDiagAndRemoveAttr(5);
10732 auto HasNonDeletedCopyOrMoveConstructor = [&]() {
10744 if (CD->isCopyOrMoveConstructor() && !CD->isDeleted())
10749 if (!HasNonDeletedCopyOrMoveConstructor()) {
10750 PrintDiagAndRemoveAttr(0);
10758 diag::err_incomplete_type_vtable_pointer_auth))
10766 assert(PrimaryBase);
10769 if (!BasePtr.getType()->getAsCXXRecordDecl()->isDynamicClass())
10771 Base = BasePtr.getType()->getAsCXXRecordDecl();
10774 if (!
Base ||
Base == PrimaryBase || !
Base->isPolymorphic())
10776 Diag(RD.
getAttr<VTablePointerAuthenticationAttr>()->getLocation(),
10777 diag::err_non_top_level_vtable_pointer_auth)
10779 PrimaryBase =
Base;
10783 Diag(RD.
getAttr<VTablePointerAuthenticationAttr>()->getLocation(),
10784 diag::err_non_polymorphic_vtable_pointer_auth)
10797 if (AL.getKind() != ParsedAttr::AT_Visibility)
10800 Diag(AL.getLoc(), diag::warn_attribute_after_definition_ignored) << AL;
10808 LBrac, RBrac, AttrList);
10830 Spaceships.clear();
10836 Spaceships.push_back(FD);
10845 if (
auto *FD = dyn_cast<FunctionDecl>(ND))
10846 if (FD->isExplicitlyDefaulted())
10847 Spaceships.push_back(FD);
10877 else if (
Context.getTargetInfo().getCXXABI().isMicrosoft() &&
10942 DefaultedSpaceships);
10943 for (
auto *FD : DefaultedSpaceships)
10950 llvm::function_ref<
Scope *()> EnterScope) {
10958 DeclContext *LookupDC = dyn_cast<DeclContext>(D);
10961 for (
unsigned i = 0; i < DD->getNumTemplateParameterLists(); ++i)
10962 ParameterLists.push_back(DD->getTemplateParameterList(i));
10966 ParameterLists.push_back(FTD->getTemplateParameters());
10967 }
else if (
VarDecl *VD = dyn_cast<VarDecl>(D)) {
10971 ParameterLists.push_back(VTD->getTemplateParameters());
10972 else if (
auto *PSD = dyn_cast<VarTemplatePartialSpecializationDecl>(D))
10973 ParameterLists.push_back(PSD->getTemplateParameters());
10975 }
else if (
TagDecl *TD = dyn_cast<TagDecl>(D)) {
10976 for (
unsigned i = 0; i < TD->getNumTemplateParameterLists(); ++i)
10977 ParameterLists.push_back(TD->getTemplateParameterList(i));
10981 ParameterLists.push_back(CTD->getTemplateParameters());
10982 else if (
auto *PSD = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
10983 ParameterLists.push_back(PSD->getTemplateParameters());
10988 unsigned Count = 0;
10989 Scope *InnermostTemplateScope =
nullptr;
10993 if (Params->size() == 0)
10996 InnermostTemplateScope = EnterScope();
10998 if (Param->getDeclName()) {
10999 InnermostTemplateScope->
AddDecl(Param);
11007 if (InnermostTemplateScope) {
11008 assert(LookupDC &&
"no enclosing DeclContext for template lookup");
11016 if (!RecordD)
return;
11023 if (!RecordD)
return;
11032 if (Param->getDeclName())
11051 if (Param->getDeclName())
11071 if (!
Method->isInvalidDecl())
11080 bool DiagOccurred =
false;
11082 [DiagID, &S, &DiagOccurred](
DeclSpec::TQ, StringRef QualName,
11089 DiagOccurred =
true;
11107 S.
Diag(PointerLoc, diag::err_invalid_ctor_dtor_decl)
11175 = dyn_cast<CXXRecordDecl>(
Constructor->getDeclContext());
11186 !
Constructor->isFunctionTemplateSpecialization()) {
11188 Constructor->getParamDecl(0)->getType()->getCanonicalTypeUnqualified();
11190 if (ParamType == ClassTy) {
11192 const char *ConstRef
11193 =
Constructor->getParamDecl(0)->getIdentifier() ?
"const &"
11195 Diag(ParamLoc, diag::err_constructor_byvalue_arg)
11217 Context.DeclarationNames.getCXXOperatorName(OO_Delete);
11220 Loc, RD,
true,
false, Name)) {
11221 Expr *ThisArg =
nullptr;
11226 if (OperatorDelete->isDestroyingOperatorDelete()) {
11227 unsigned AddressParamIndex = 0;
11228 if (OperatorDelete->isTypeAwareOperatorNewOrDelete())
11229 ++AddressParamIndex;
11231 OperatorDelete->getParamDecl(AddressParamIndex)->getType();
11238 OperatorDelete->getParamDecl(AddressParamIndex)->getLocation());
11239 assert(!
This.isInvalid() &&
"couldn't form 'this' expr in dtor?");
11242 if (
This.isInvalid()) {
11245 Diag(Loc, diag::note_implicit_delete_this_in_destructor_here);
11248 ThisArg =
This.get();
11254 Destructor->setOperatorDelete(OperatorDelete, ThisArg);
11257 Context.getTargetInfo().callGlobalDeleteInDeletingDtor(
11269 if (GlobalOperatorDelete) {
11271 Destructor->setOperatorGlobalDelete(GlobalOperatorDelete);
11275 if (
Context.getTargetInfo().emitVectorDeletingDtors(
11279 Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
11282 false, VDeleteName);
11288 Destructor->setGlobalOperatorArrayDelete(GlobalArrOperatorDelete);
11289 if (GlobalArrOperatorDelete &&
11290 Context.classNeedsVectorDeletingDestructor(RD))
11292 }
else if (!ArrOperatorDelete) {
11295 true, VDeleteName);
11297 Destructor->setOperatorArrayDelete(ArrOperatorDelete);
11298 if (ArrOperatorDelete &&
Context.classNeedsVectorDeletingDestructor(RD))
11317 << DeclaratorType << isa<TypeAliasDecl>(TT->getDecl());
11318 else if (
const TemplateSpecializationType *TST =
11319 DeclaratorType->
getAs<TemplateSpecializationType>())
11320 if (TST->isTypeAlias())
11322 << DeclaratorType << 1;
11412 if (R.getEnd().isInvalid())
11413 R.setEnd(Before.
getEnd());
11417 if (After.isInvalid())
11419 if (R.getBegin().isInvalid())
11420 R.setBegin(After.getBegin());
11421 R.setEnd(After.getEnd());
11470 unsigned NumParam = Proto->getNumParams();
11474 if (NumParam == 1) {
11476 if (
const auto *
First =
11477 dyn_cast_if_present<ParmVarDecl>(FTI.
Params[0].
Param);
11478 First &&
First->isExplicitObjectParameter())
11482 if (NumParam != 0) {
11487 }
else if (Proto->isVariadic()) {
11494 if (Proto->getReturnType() != ConvType) {
11495 bool NeedsTypedef =
false;
11499 bool PastFunctionChunk =
false;
11501 switch (Chunk.Kind) {
11503 if (!PastFunctionChunk) {
11504 if (Chunk.Fun.HasTrailingReturnType) {
11509 PastFunctionChunk =
true;
11514 NeedsTypedef =
true;
11534 After.isValid() ? After.getBegin() :
11536 auto &&DB =
Diag(Loc, diag::err_conv_function_with_complex_decl);
11537 DB << Before << After;
11539 if (!NeedsTypedef) {
11543 if (After.isInvalid() && ConvTSI) {
11551 }
else if (!Proto->getReturnType()->isDependentType()) {
11552 DB << 1 << Proto->getReturnType();
11554 DB << 2 << Proto->getReturnType();
11565 ConvType = Proto->getReturnType();
11573 ConvType =
Context.getPointerType(ConvType);
11577 ConvType =
Context.getPointerType(ConvType);
11585 R =
Context.getFunctionType(ConvType, {}, Proto->getExtProtoInfo());
11591 ? diag::warn_cxx98_compat_explicit_conversion_functions
11592 : diag::ext_explicit_conversion_functions)
11597 assert(Conversion &&
"Expected to receive a conversion function declaration");
11618 ConvType =
Context.getCanonicalType(ConvType).getUnqualifiedType();
11619 if (ConvType == ClassType)
11624 << ClassType << ConvType;
11627 << ClassType << ConvType;
11638 << ConvType->
castAs<AutoType>()->getKeyword()
11642 return ConversionTemplate;
11667 for (
unsigned Idx = 0; Idx < FTI.
NumParams; Idx++) {
11668 const auto &ParamInfo = FTI.
Params[Idx];
11669 if (!ParamInfo.Param)
11672 if (!Param->isExplicitObjectParameter())
11675 ExplicitObjectParam = Param;
11678 Diag(Param->getLocation(),
11679 diag::err_explicit_object_parameter_must_be_first)
11680 << IsLambda << Param->getSourceRange();
11683 if (!ExplicitObjectParam)
11688 diag::err_explicit_object_default_arg)
11697 diag::err_explicit_object_parameter_nonmember)
11704 diag::err_explicit_object_parameter_nonmember)
11729 !isa_and_present<CXXRecordDecl>(
11732 diag::err_explicit_object_parameter_nonmember)
11739 diag::err_explicit_object_parameter_mutable)
11747 assert(D.
isInvalidType() &&
"Explicit object parameter in non-member "
11748 "should have been diagnosed already");
11756 diag::err_explicit_object_parameter_constructor)
11766struct BadSpecifierDiagnoser {
11769 ~BadSpecifierDiagnoser() {
11773 template<
typename T>
void check(SourceLocation SpecLoc, T Spec) {
11777 return check(SpecLoc,
11780 void check(SourceLocation SpecLoc,
const char *Spec) {
11782 Diagnostic << SourceRange(SpecLoc, SpecLoc);
11783 if (!Specifiers.empty()) Specifiers +=
" ";
11784 Specifiers += Spec;
11788 Sema::SemaDiagnosticBuilder Diagnostic;
11789 std::string Specifiers;
11797 assert(GuidedTemplateDecl &&
"missing template decl for deduction guide");
11802 if (!
CurContext->getRedeclContext()->Equals(
11805 << GuidedTemplateDecl;
11811 if (DS.hasTypeSpecifier() || DS.getTypeQualifiers() ||
11812 DS.getStorageClassSpecLoc().isValid() || DS.isInlineSpecified() ||
11813 DS.isNoreturnSpecified() || DS.hasConstexprSpecifier()) {
11814 BadSpecifierDiagnoser Diagnoser(
11816 diag::err_deduction_guide_invalid_specifier);
11818 Diagnoser.check(DS.getStorageClassSpecLoc(), DS.getStorageClassSpec());
11819 DS.ClearStorageClassSpecs();
11823 Diagnoser.check(DS.getInlineSpecLoc(),
"inline");
11824 Diagnoser.check(DS.getNoreturnSpecLoc(),
"_Noreturn");
11825 Diagnoser.check(DS.getConstexprSpecLoc(),
"constexpr");
11826 DS.ClearConstexprSpec();
11828 Diagnoser.check(DS.getConstSpecLoc(),
"const");
11829 Diagnoser.check(DS.getRestrictSpecLoc(),
"__restrict");
11830 Diagnoser.check(DS.getVolatileSpecLoc(),
"volatile");
11831 Diagnoser.check(DS.getAtomicSpecLoc(),
"_Atomic");
11832 Diagnoser.check(DS.getUnalignedSpecLoc(),
"__unaligned");
11833 DS.ClearTypeQualifiers();
11835 Diagnoser.check(DS.getTypeSpecComplexLoc(), DS.getTypeSpecComplex());
11836 Diagnoser.check(DS.getTypeSpecSignLoc(), DS.getTypeSpecSign());
11837 Diagnoser.check(DS.getTypeSpecWidthLoc(), DS.getTypeSpecWidth());
11838 Diagnoser.check(DS.getTypeSpecTypeLoc(), DS.getTypeSpecType());
11839 DS.ClearTypeSpecType();
11846 bool FoundFunction =
false;
11852 diag::err_deduction_guide_with_complex_decl)
11856 if (!Chunk.Fun.hasTrailingReturnType())
11858 diag::err_deduction_guide_no_trailing_return_type);
11863 ParsedType TrailingReturnType = Chunk.Fun.getTrailingReturnType();
11866 assert(TSI &&
"deduction guide has valid type but invalid return type?");
11867 bool AcceptableReturnType =
false;
11868 bool MightInstantiateToSpecialization =
false;
11871 TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
11872 bool TemplateMatches =
Context.hasSameTemplateName(
11873 SpecifiedName, GuidedTemplate,
true);
11877 assert(
Qualifiers &&
"expected QualifiedTemplate");
11878 bool SimplyWritten =
11880 if (SimplyWritten && TemplateMatches)
11881 AcceptableReturnType =
true;
11886 MightInstantiateToSpecialization =
11890 MightInstantiateToSpecialization =
true;
11893 if (!AcceptableReturnType)
11895 diag::err_deduction_guide_bad_trailing_return_type)
11896 << GuidedTemplate << TSI->
getType()
11897 << MightInstantiateToSpecialization
11902 FoundFunction =
true;
11921 assert(*IsInline != PrevNS->
isInline());
11931 S.
Diag(Loc, diag::warn_inline_namespace_reopened_noninline)
11934 S.
Diag(Loc, diag::err_inline_namespace_mismatch);
11952 bool IsInline = InlineLoc.
isValid();
11953 bool IsInvalid =
false;
11954 bool IsStd =
false;
11955 bool AddToKnown =
false;
11966 auto DiagnoseInlineStdNS = [&]() {
11967 assert(IsInline && II->
isStr(
"std") &&
11968 CurContext->getRedeclContext()->isTranslationUnit() &&
11969 "Precondition of DiagnoseInlineStdNS not met");
11970 Diag(InlineLoc, diag::err_inline_namespace_std)
11989 R.isSingleResult() ? R.getRepresentativeDecl() :
nullptr;
11990 PrevNS = dyn_cast_or_null<NamespaceDecl>(PrevDecl);
11994 if (IsInline && II->
isStr(
"std") &&
11995 CurContext->getRedeclContext()->isTranslationUnit())
11996 DiagnoseInlineStdNS();
11997 else if (IsInline != PrevNS->
isInline())
11999 &IsInline, PrevNS);
12000 }
else if (PrevDecl) {
12002 Diag(Loc, diag::err_redefinition_different_kind)
12007 }
else if (II->
isStr(
"std") &&
12008 CurContext->getRedeclContext()->isTranslationUnit()) {
12010 DiagnoseInlineStdNS();
12015 AddToKnown = !IsInline;
12018 AddToKnown = !IsInline;
12032 if (PrevNS && IsInline != PrevNS->
isInline())
12034 &IsInline, PrevNS);
12047 if (
const VisibilityAttr *
Attr = Namespc->
getAttr<VisibilityAttr>())
12053 KnownNamespaces[Namespc] =
false;
12061 TU->setAnonymousNamespace(Namespc);
12113 return dyn_cast_or_null<NamespaceDecl>(D);
12117 NamespaceDecl *Namespc = dyn_cast_or_null<NamespaceDecl>(Dcl);
12118 assert(Namespc &&
"Invalid parameter, expected NamespaceDecl");
12121 if (Namespc->
hasAttr<VisibilityAttr>())
12124 if (DeferredExportedNamespaces.erase(Namespc))
12129 return cast_or_null<CXXRecordDecl>(
12138 return cast_or_null<NamespaceDecl>(
12144enum UnsupportedSTLSelect {
12151struct InvalidSTLDiagnoser {
12156 QualType operator()(UnsupportedSTLSelect Sel = USS_Other, StringRef Name =
"",
12157 const VarDecl *VD =
nullptr) {
12159 auto D = S.
Diag(Loc, diag::err_std_compare_type_not_supported)
12160 << TyForDiags << ((
int)Sel);
12161 if (Sel == USS_InvalidMember || Sel == USS_MissingMember) {
12162 assert(!Name.empty());
12166 if (Sel == USS_InvalidMember) {
12179 "Looking for comparison category type outside of C++.");
12194 if (Info && FullyCheckedComparisonCategories[
static_cast<unsigned>(Kind)]) {
12205 std::string NameForDiags =
"std::";
12207 Diag(Loc, diag::err_implied_comparison_category_type_not_found)
12208 << NameForDiags << (int)Usage;
12212 assert(Info->
Kind == Kind);
12223 InvalidSTLDiagnoser UnsupportedSTLError{*
this, Loc, TyForDiags(Info)};
12226 return UnsupportedSTLError(USS_NonTrivial);
12231 if (
Base->isEmpty())
12234 return UnsupportedSTLError();
12242 if (std::distance(FIt, FEnd) != 1 ||
12243 !FIt->getType()->isIntegralOrEnumerationType()) {
12244 return UnsupportedSTLError();
12254 return UnsupportedSTLError(USS_MissingMember, MemName);
12257 assert(VD &&
"should not be null!");
12264 return UnsupportedSTLError(USS_InvalidMember, MemName, VD);
12270 return UnsupportedSTLError();
12277 FullyCheckedComparisonCategories[
static_cast<unsigned>(Kind)] =
true;
12287 &
PP.getIdentifierTable().get(
"std"),
12300 const char *ClassName,
12302 const Decl **MalformedDecl) {
12310 auto ReportMatchingNameAsMalformed = [&](
NamedDecl *D) {
12311 if (!MalformedDecl)
12319 *MalformedDecl = D;
12324 if (
const TemplateSpecializationType *TST =
12326 Template = dyn_cast_or_null<ClassTemplateDecl>(
12327 TST->getTemplateName().getAsTemplateDecl());
12328 Arguments = TST->template_arguments();
12329 }
else if (
const auto *TT = SugaredType->
getAs<TagType>()) {
12331 Arguments = TT->getTemplateArgs(S.
Context);
12335 ReportMatchingNameAsMalformed(SugaredType->
getAsTagDecl());
12339 if (!*CachedDecl) {
12358 *MalformedDecl = TemplateClass;
12366 if (
Template->getCanonicalDecl() != (*CachedDecl)->getCanonicalDecl())
12371 QualType ArgType = Arguments[0].getAsType();
12377 if (S.
getLangOpts().ObjCAutoRefCount && ArgType->isObjCLifetimeType() &&
12378 !ArgType.getObjCLifetime()) {
12383 *TypeArg = ArgType;
12391 "Looking for std::initializer_list outside of C++.");
12401 const Decl **MalformedDecl) {
12403 "Looking for std::type_identity outside of C++.");
12413 const char *ClassName,
12414 bool *WasMalformed) {
12425 Result.suppressDiagnostics();
12428 S.
Diag(
Found->getLocation(), diag::err_malformed_std_class_template)
12431 *WasMalformed =
true;
12440 S.
Diag(
Template->getLocation(), diag::err_malformed_std_class_template)
12443 *WasMalformed =
true;
12458 Loc, Args,
nullptr,
12464 bool WasMalformed =
false;
12469 Diag(Loc, diag::err_implied_std_initializer_list_not_found);
12497 ArgType = RT->getPointeeType().getUnqualifiedType();
12506 case Decl::TranslationUnit:
12508 case Decl::LinkageSpec:
12518class NamespaceValidatorCCC final :
public CorrectionCandidateCallback {
12520 bool ValidateCandidate(
const TypoCorrection &candidate)
override {
12526 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
12527 return std::make_unique<NamespaceValidatorCCC>(*
this);
12536 Module *M = ND->getOwningModule();
12537 assert(M &&
"hidden namespace definition not in a module?");
12541 diag::err_module_unimported_use_header)
12546 diag::err_module_unimported_use)
12556 NamespaceValidatorCCC CCC{};
12558 S.
CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), Sc, &SS, CCC,
12566 if (isa_and_nonnull<NamespaceDecl>(Corrected.getFoundDecl()) &&
12567 Corrected.requiresImport()) {
12570 std::string CorrectedStr(Corrected.getAsString(S.
getLangOpts()));
12571 bool DroppedSpecifier =
12572 Corrected.WillReplaceSpecifier() && Ident->
getName() == CorrectedStr;
12574 S.
PDiag(diag::err_using_directive_member_suggest)
12575 << Ident << DC << DroppedSpecifier << SS.
getRange(),
12576 S.
PDiag(diag::note_namespace_defined_here));
12579 S.
PDiag(diag::err_using_directive_suggest) << Ident,
12580 S.
PDiag(diag::note_namespace_defined_here));
12582 R.addDecl(Corrected.getFoundDecl());
12593 assert(!SS.
isInvalid() &&
"Invalid CXXScopeSpec.");
12594 assert(NamespcName &&
"Invalid NamespcName.");
12595 assert(IdentLoc.
isValid() &&
"Invalid NamespceName location.");
12606 if (R.isAmbiguous())
12615 NamespcName->
isStr(
"std")) {
12616 Diag(IdentLoc, diag::ext_using_undefined_std);
12626 NamedDecl *Named = R.getRepresentativeDecl();
12628 assert(
NS &&
"expected namespace decl");
12647 CommonAncestor = CommonAncestor->
getParent();
12651 IdentLoc, Named, CommonAncestor);
12655 Diag(IdentLoc, diag::warn_using_directive_in_header);
12660 Diag(IdentLoc, diag::err_expected_namespace_name) << SS.
getRange();
12710 ? diag::warn_cxx98_compat_using_decl_constructor
12711 : diag::err_using_decl_constructor)
12728 llvm_unreachable(
"cannot parse qualified deduction guide name");
12739 ? diag::err_access_decl
12740 : diag::warn_access_decl_deprecated)
12751 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
12759 SS, TargetNameInfo, EllipsisLoc, AttrList,
12778 ? diag::err_using_enum_is_dependent
12779 : diag::err_unknown_typename)
12787 Diag(IdentLoc, diag::err_using_enum_is_dependent);
12793 Diag(IdentLoc, diag::err_using_enum_not_enum) << EnumTy;
12797 if (TSI ==
nullptr)
12798 TSI =
Context.getTrivialTypeSourceInfo(EnumTy, IdentLoc);
12819 return Context.hasSameType(TD1->getUnderlyingType(),
12820 TD2->getUnderlyingType());
12854 if (
auto *Using = dyn_cast<UsingDecl>(BUD)) {
12866 Diag(Using->getLocation(),
12867 diag::err_using_decl_nested_name_specifier_is_current_class)
12868 << Using->getQualifierLoc().getSourceRange();
12870 Using->setInvalidDecl();
12874 Diag(Using->getQualifierLoc().getBeginLoc(),
12875 diag::err_using_decl_nested_name_specifier_is_not_base_class)
12877 << Using->getQualifierLoc().getSourceRange();
12879 Using->setInvalidDecl();
12884 if (
Previous.empty())
return false;
12895 NamedDecl *NonTag =
nullptr, *Tag =
nullptr;
12896 bool FoundEquivalentDecl =
false;
12898 NamedDecl *D = Element->getUnderlyingDecl();
12905 if (
auto *RD = dyn_cast<CXXRecordDecl>(D)) {
12920 PrevShadow = Shadow;
12921 FoundEquivalentDecl =
true;
12925 FoundEquivalentDecl =
true;
12932 if (FoundEquivalentDecl)
12938 (isa_and_nonnull<UnresolvedUsingIfExistsDecl>(NonTag))) {
12939 if (!NonTag && !Tag)
12942 Diag(
Target->getLocation(), diag::note_using_decl_target);
12943 Diag((NonTag ? NonTag : Tag)->getLocation(),
12944 diag::note_using_decl_conflict);
12973 Diag(
Target->getLocation(), diag::note_using_decl_target);
12983 if (!Tag)
return false;
12986 Diag(
Target->getLocation(), diag::note_using_decl_target);
12987 Diag(Tag->getLocation(), diag::note_using_decl_conflict);
12993 if (!NonTag)
return false;
12996 Diag(
Target->getLocation(), diag::note_using_decl_target);
13006 for (
auto &B : Derived->
bases())
13007 if (B.getType()->getAsCXXRecordDecl() ==
Base)
13008 return B.isVirtual();
13009 llvm_unreachable(
"not a direct base class");
13023 if (
auto *TargetTD = dyn_cast<TemplateDecl>(
Target))
13024 NonTemplateTarget = TargetTD->getTemplatedDecl();
13029 bool IsVirtualBase =
13031 Using->getQualifier().getAsRecordDecl());
13079 bool &AnyDependentBases) {
13083 CanQualType BaseType =
Base.getType()->getCanonicalTypeUnqualified();
13084 if (CanonicalDesiredBase == BaseType)
13086 if (BaseType->isDependentType())
13087 AnyDependentBases =
true;
13093class UsingValidatorCCC final :
public CorrectionCandidateCallback {
13095 UsingValidatorCCC(
bool HasTypenameKeyword,
bool IsInstantiation,
13096 NestedNameSpecifier NNS, CXXRecordDecl *RequireMemberOf)
13097 : HasTypenameKeyword(HasTypenameKeyword),
13098 IsInstantiation(IsInstantiation), OldNNS(NNS),
13099 RequireMemberOf(RequireMemberOf) {}
13101 bool ValidateCandidate(
const TypoCorrection &Candidate)
override {
13115 if (RequireMemberOf) {
13116 auto *FoundRecord = dyn_cast<CXXRecordDecl>(ND);
13117 if (FoundRecord && FoundRecord->isInjectedClassName()) {
13131 if (
Specifier.getKind() != NestedNameSpecifier::Kind::Type ||
13137 bool AnyDependentBases =
false;
13140 AnyDependentBases) &&
13141 !AnyDependentBases)
13151 auto *FoundRecord = dyn_cast<CXXRecordDecl>(ND);
13152 if (FoundRecord && FoundRecord->isInjectedClassName())
13157 return HasTypenameKeyword || !IsInstantiation;
13159 return !HasTypenameKeyword;
13162 std::unique_ptr<CorrectionCandidateCallback> clone()
override {
13163 return std::make_unique<UsingValidatorCCC>(*
this);
13167 bool HasTypenameKeyword;
13168 bool IsInstantiation;
13169 NestedNameSpecifier OldNNS;
13170 CXXRecordDecl *RequireMemberOf;
13197 bool IsUsingIfExists) {
13198 assert(!SS.
isInvalid() &&
"Invalid CXXScopeSpec.");
13200 assert(IdentLoc.
isValid() &&
"Invalid TargetName location.");
13209 if (
auto *RD = dyn_cast<CXXRecordDecl>(
CurContext))
13210 UsingName.
setName(
Context.DeclarationNames.getCXXConstructorName(
13211 Context.getCanonicalTagType(RD)));
13222 assert(IsInstantiation &&
"no scope in non-instantiation");
13250 Diag(UsingLoc, diag::err_using_if_exists_on_ctor);
13256 if (!LookupContext || EllipsisLoc.
isValid()) {
13260 SS, NameInfo, IdentLoc))
13264 Previous.getFoundDecl()->isTemplateParameter())
13267 if (HasTypenameKeyword) {
13270 UsingLoc, TypenameLoc,
13272 IdentLoc, NameInfo.
getName(),
13276 QualifierLoc, NameInfo, EllipsisLoc);
13284 auto Build = [&](
bool Invalid) {
13287 UsingName, HasTypenameKeyword);
13294 auto BuildInvalid = [&]{
return Build(
true); };
13295 auto BuildValid = [&]{
return Build(
false); };
13298 return BuildInvalid();
13307 if (!IsInstantiation)
13308 R.setHideTags(
false);
13313 R.setBaseObjectType(
13324 if (R.empty() && IsUsingIfExists)
13342 PP.NeedsStdLibCxxWorkaroundBefore(2016'12'21) &&
13345 UsingValidatorCCC CCC(HasTypenameKeyword, IsInstantiation, SS.
getScopeRep(),
13348 CorrectTypo(R.getLookupNameInfo(), R.getLookupKind(), S, &SS, CCC,
13353 << NameInfo.
getName() << LookupContext << 0
13358 NamedDecl *ND = Corrected.getCorrectionDecl();
13360 return BuildInvalid();
13363 auto *RD = dyn_cast<CXXRecordDecl>(ND);
13369 if (Corrected.WillReplaceSpecifier()) {
13373 QualifierLoc = Builder.getWithLocInContext(
Context);
13379 UsingName.
setName(
Context.DeclarationNames.getCXXConstructorName(
13380 Context.getCanonicalTagType(CurClass)));
13392 Diag(IdentLoc, diag::err_no_member)
13394 return BuildInvalid();
13398 if (R.isAmbiguous())
13399 return BuildInvalid();
13401 if (HasTypenameKeyword) {
13405 Diag(IdentLoc, diag::err_using_typename_non_type);
13408 diag::note_using_decl_target);
13409 return BuildInvalid();
13415 if (IsInstantiation && R.getAsSingle<
TypeDecl>()) {
13416 Diag(IdentLoc, diag::err_using_dependent_value_is_type);
13417 Diag(R.getFoundDecl()->getLocation(), diag::note_using_decl_target);
13418 return BuildInvalid();
13425 Diag(IdentLoc, diag::err_using_decl_can_not_refer_to_namespace)
13430 return BuildInvalid();
13440 R.suppressDiagnostics();
13462 if (
CurContext->getRedeclContext()->isRecord()) {
13472 if (UED->getEnumDecl() == ED) {
13473 Diag(UsingLoc, diag::err_using_enum_decl_redeclaration)
13485 EnumLoc, NameLoc, EnumType);
13518 UPD->setAccess(InstantiatedFrom->
getAccess());
13524 assert(!UD->
hasTypename() &&
"expecting a constructor name");
13530 bool AnyDependentBases =
false;
13533 if (!
Base && !AnyDependentBases) {
13534 Diag(UD->
getUsingLoc(), diag::err_using_decl_constructor_not_in_direct_base)
13541 Base->setInheritConstructors();
13547 bool HasTypenameKeyword,
13560 if (!
CurContext->getRedeclContext()->isRecord()) {
13567 for (
auto *D : Prev) {
13569 bool OldCouldBeEnumerator =
13572 OldCouldBeEnumerator ? diag::err_redefinition
13573 : diag::err_redefinition_different_kind)
13574 << Prev.getLookupName();
13587 if (
const auto *UD = dyn_cast<UsingDecl>(D)) {
13588 DTypename = UD->hasTypename();
13589 DQual = UD->getQualifier();
13590 }
else if (
const auto *UD = dyn_cast<UnresolvedUsingValueDecl>(D)) {
13592 DQual = UD->getQualifier();
13593 }
else if (
const auto *UD = dyn_cast<UnresolvedUsingTypenameDecl>(D)) {
13595 DQual = UD->getQualifier();
13601 if (HasTypenameKeyword != DTypename)
continue;
13609 Diag(NameLoc, diag::err_using_decl_redeclaration) << SS.
getRange();
13623 assert(
bool(NamedContext) == (R || UD) && !(R && UD) &&
13624 "resolvable context must have exactly one set of decls");
13628 bool Cxx20Enumerator =
false;
13629 if (NamedContext) {
13638 if (
auto *ED = dyn_cast<EnumDecl>(NamedContext)) {
13642 if (EC && R && ED->isScoped())
13645 ? diag::warn_cxx17_compat_using_decl_scoped_enumerator
13646 : diag::ext_using_decl_scoped_enumerator)
13650 NamedContext = ED->getDeclContext();
13670 ? diag::warn_cxx17_compat_using_decl_class_member_enumerator
13671 : diag::err_using_decl_can_not_refer_to_class_member)
13674 if (Cxx20Enumerator)
13677 auto *RD = NamedContext
13686 }
else if (R->getAsSingle<
TypeDecl>()) {
13689 Diag(SS.
getBeginLoc(), diag::note_using_decl_class_member_workaround)
13690 << diag::MemClassWorkaround::AliasDecl
13697 Diag(InsertLoc, diag::note_using_decl_class_member_workaround)
13698 << diag::MemClassWorkaround::TypedefDecl
13703 }
else if (R->getAsSingle<
VarDecl>()) {
13713 Diag(UsingLoc, diag::note_using_decl_class_member_workaround)
13714 << diag::MemClassWorkaround::ReferenceDecl << FixIt;
13727 Diag(UsingLoc, diag::note_using_decl_class_member_workaround)
13729 ? diag::MemClassWorkaround::ConstexprVar
13730 : diag::MemClassWorkaround::ConstVar)
13739 if (!NamedContext) {
13755 ? diag::warn_cxx17_compat_using_decl_non_member_enumerator
13756 : diag::err_using_decl_nested_name_specifier_is_not_class)
13759 if (Cxx20Enumerator)
13780 if (Cxx20Enumerator) {
13781 Diag(NameLoc, diag::warn_cxx17_compat_using_decl_non_member_enumerator)
13788 diag::err_using_decl_nested_name_specifier_is_current_class)
13795 diag::err_using_decl_nested_name_specifier_is_not_base_class)
13811 if (
Type.isInvalid())
13830 TemplateParamLists.size()
13837 Previous.getFoundDecl()->isTemplateParameter()) {
13843 "name in alias declaration must be an identifier");
13866 if (TemplateParamLists.size()) {
13870 if (TemplateParamLists.size() != 1) {
13871 Diag(UsingLoc, diag::err_alias_template_extra_headers)
13872 <<
SourceRange(TemplateParamLists[1]->getTemplateLoc(),
13873 TemplateParamLists[TemplateParamLists.size()-1]->getRAngleLoc());
13890 Diag(UsingLoc, diag::err_redefinition_different_kind)
13905 OldTemplateParams =
13941 else if (OldDecl) {
13948 if (
auto *TD = dyn_cast_or_null<TagDecl>(DeclFromDeclSpec)) {
13971 if (R.isAmbiguous())
13976 Diag(IdentLoc, diag::err_expected_namespace_name) << SS.
getRange();
13980 assert(!R.isAmbiguous() && !R.empty());
14008 Diag(AliasLoc, diag::err_redefinition_different_namespace_alias)
14010 Diag(AD->getLocation(), diag::note_previous_namespace_alias)
14011 << AD->getNamespace();
14016 ? diag::err_redefinition
14017 : diag::err_redefinition_different_kind;
14018 Diag(AliasLoc, DiagID) << Alias;
14039struct SpecialMemberExceptionSpecInfo
14040 : SpecialMemberVisitor<SpecialMemberExceptionSpecInfo> {
14048 : SpecialMemberVisitor(S, MD, CSM, ICI), Loc(Loc), ExceptSpec(S) {}
14053 void visitClassSubobject(
CXXRecordDecl *Class, Subobject Subobj,
14056 void visitSubobjectCall(Subobject Subobj,
14061bool SpecialMemberExceptionSpecInfo::visitBase(CXXBaseSpecifier *Base) {
14062 auto *BaseClass =
Base->getType()->getAsCXXRecordDecl();
14066 Sema::SpecialMemberOverloadResult SMOR = lookupInheritedCtor(BaseClass);
14067 if (
auto *BaseCtor = SMOR.
getMethod()) {
14068 visitSubobjectCall(Base, BaseCtor);
14072 visitClassSubobject(BaseClass, Base, 0);
14076bool SpecialMemberExceptionSpecInfo::visitField(FieldDecl *FD) {
14077 if (CSM == CXXSpecialMemberKind::DefaultConstructor &&
14096void SpecialMemberExceptionSpecInfo::visitClassSubobject(CXXRecordDecl *
Class,
14099 FieldDecl *
Field = Subobj.dyn_cast<FieldDecl*>();
14100 bool IsMutable =
Field &&
Field->isMutable();
14101 visitSubobjectCall(Subobj, lookupIn(
Class, Quals, IsMutable));
14104void SpecialMemberExceptionSpecInfo::visitSubobjectCall(
14105 Subobject Subobj, Sema::SpecialMemberOverloadResult SMOR) {
14108 if (CXXMethodDecl *MD = SMOR.
getMethod())
14109 ExceptSpec.
CalledDecl(getSubobjectLoc(Subobj), MD);
14138 ComputingExceptionSpec CES(S, MD, Loc);
14145 SpecialMemberExceptionSpecInfo Info(S, MD, CSM, ICI, MD->
getLocation());
14147 return Info.ExceptSpec;
14154 diag::err_exception_spec_incomplete_type))
14155 return Info.ExceptSpec;
14172 Info.visit(Info.IsConstructor ? Info.VisitPotentiallyConstructedBases
14173 : Info.VisitAllBases);
14175 return Info.ExceptSpec;
14180struct DeclaringSpecialMember {
14183 Sema::ContextRAII SavedContext;
14184 bool WasAlreadyBeingDeclared;
14187 : S(S), D(RD, CSM), SavedContext(S, RD) {
14189 if (WasAlreadyBeingDeclared)
14196 Sema::CodeSynthesisContext Ctx;
14197 Ctx.Kind = Sema::CodeSynthesisContext::DeclaringSpecialMember;
14204 Ctx.PointOfInstantiation = RD->getLocation();
14206 Ctx.SpecialMember = CSM;
14207 S.pushCodeSynthesisContext(Ctx);
14210 ~DeclaringSpecialMember() {
14211 if (!WasAlreadyBeingDeclared) {
14218 bool isAlreadyBeingDeclared()
const {
14219 return WasAlreadyBeingDeclared;
14231 if (
auto *Acceptable = R.getAcceptableDecl(D))
14232 R.addDecl(Acceptable);
14234 R.suppressDiagnostics();
14240void Sema::setupImplicitSpecialMemberType(
CXXMethodDecl *SpecialMem,
14246 LangAS AS = getDefaultCXXMethodAddrSpace();
14251 auto QT = Context.getFunctionType(ResultTy, Args, EPI);
14259 Context.getTrivialTypeSourceInfo(SpecialMem->
getType());
14273 "Should not build implicit default constructor!");
14275 DeclaringSpecialMember DSM(*
this, ClassDecl,
14277 if (DSM.isAlreadyBeingDeclared())
14287 =
Context.DeclarationNames.getCXXConstructorName(ClassType);
14299 setupImplicitSpecialMemberType(DefaultCon,
Context.VoidTy, {});
14302 CUDA().inferTargetForImplicitSpecialMember(
14323 ClassDecl->
addDecl(DefaultCon);
14333 "DefineImplicitDefaultConstructor - call it for implicit default ctor");
14338 assert(ClassDecl &&
"DefineImplicitDefaultConstructor - invalid constructor");
14352 Scope.addContextNote(CurrentLocation);
14395 ->getInheritedConstructor()
14402 Context.getTrivialTypeSourceInfo(BaseCtor->
getType(), UsingLoc);
14413 false, BaseCtor, &ICI);
14430 EPI.ExceptionSpec.SourceDecl = DerivedCtor;
14436 for (
unsigned I = 0, N = FPT->
getNumParams(); I != N; ++I) {
14440 Context, DerivedCtor, UsingLoc, UsingLoc,
nullptr,
14447 ParamDecls.push_back(PD);
14452 assert(!BaseCtor->
isDeleted() &&
"should not use deleted constructor");
14455 Derived->
addDecl(DerivedCtor);
14461 return DerivedCtor;
14492 Scope.addContextNote(CurrentLocation);
14495 Constructor->getInheritedConstructor().getShadowDecl();
14497 Constructor->getInheritedConstructor().getConstructor();
14511 for (
bool VBase : {
false,
true}) {
14513 if (B.isVirtual() != VBase)
14516 auto *BaseRD = B.getType()->getAsCXXRecordDecl();
14521 if (!BaseCtor.first)
14526 InitLoc, B.getType(), BaseCtor.first, VBase, BaseCtor.second);
14528 auto *TInfo =
Context.getTrivialTypeSourceInfo(B.getType(), InitLoc);
14530 Context, TInfo, VBase, InitLoc,
Init.get(), InitLoc,
14560 DeclaringSpecialMember DSM(*
this, ClassDecl,
14562 if (DSM.isAlreadyBeingDeclared())
14572 =
Context.DeclarationNames.getCXXDestructorName(ClassType);
14587 CUDA().inferTargetForImplicitSpecialMember(
14622 !
Destructor->doesThisDeclarationHaveABody() &&
14624 "DefineImplicitDestructor - call it for implicit default dtor");
14629 assert(ClassDecl &&
"DefineImplicitDestructor - invalid destructor");
14640 Scope.addContextNote(CurrentLocation);
14667 assert(
Context.getTargetInfo().getCXXABI().isMicrosoft() &&
14668 "implicit complete dtors unneeded outside MS ABI");
14670 "complete dtor only exists for classes with vbases");
14675 Scope.addContextNote(CurrentLocation);
14683 if (
Record->isInvalidDecl()) {
14704 if (M->getParent()->getTemplateSpecializationKind() !=
14724 "adjusting dtor exception specs was introduced in c++11");
14734 if (DtorType->hasExceptionSpec())
14757 ExprBuilder(
const ExprBuilder&) =
delete;
14758 ExprBuilder &operator=(
const ExprBuilder&) =
delete;
14761 static Expr *assertNotNull(
Expr *E) {
14762 assert(E &&
"Expression construction must not fail.");
14768 virtual ~ExprBuilder() {}
14770 virtual Expr *build(Sema &S, SourceLocation Loc)
const = 0;
14773class RefBuilder:
public ExprBuilder {
14778 Expr *build(Sema &S, SourceLocation Loc)
const override {
14782 RefBuilder(VarDecl *Var, QualType VarType)
14783 : Var(Var), VarType(VarType) {}
14786class ThisBuilder:
public ExprBuilder {
14788 Expr *build(Sema &S, SourceLocation Loc)
const override {
14793class CastBuilder:
public ExprBuilder {
14794 const ExprBuilder &Builder;
14800 Expr *build(Sema &S, SourceLocation Loc)
const override {
14802 CK_UncheckedDerivedToBase, Kind,
14811class DerefBuilder:
public ExprBuilder {
14812 const ExprBuilder &Builder;
14815 Expr *build(Sema &S, SourceLocation Loc)
const override {
14816 return assertNotNull(
14820 DerefBuilder(
const ExprBuilder &Builder) : Builder(Builder) {}
14823class MemberBuilder:
public ExprBuilder {
14824 const ExprBuilder &Builder;
14828 LookupResult &MemberLookup;
14831 Expr *build(Sema &S, SourceLocation Loc)
const override {
14833 Builder.build(S, Loc),
Type, Loc, IsArrow, SS, SourceLocation(),
14834 nullptr, MemberLookup,
nullptr,
nullptr).get());
14837 MemberBuilder(
const ExprBuilder &Builder, QualType
Type,
bool IsArrow,
14838 LookupResult &MemberLookup)
14839 : Builder(Builder),
Type(
Type), IsArrow(IsArrow),
14840 MemberLookup(MemberLookup) {}
14843class MoveCastBuilder:
public ExprBuilder {
14844 const ExprBuilder &Builder;
14847 Expr *build(Sema &S, SourceLocation Loc)
const override {
14848 return assertNotNull(
CastForMoving(S, Builder.build(S, Loc)));
14851 MoveCastBuilder(
const ExprBuilder &Builder) : Builder(Builder) {}
14854class LvalueConvBuilder:
public ExprBuilder {
14855 const ExprBuilder &Builder;
14858 Expr *build(Sema &S, SourceLocation Loc)
const override {
14859 return assertNotNull(
14863 LvalueConvBuilder(
const ExprBuilder &Builder) : Builder(Builder) {}
14866class SubscriptBuilder:
public ExprBuilder {
14867 const ExprBuilder &
Base;
14868 const ExprBuilder &Index;
14871 Expr *build(Sema &S, SourceLocation Loc)
const override {
14873 Base.build(S, Loc), Loc, Index.build(S, Loc), Loc).
get());
14876 SubscriptBuilder(
const ExprBuilder &Base,
const ExprBuilder &Index)
14888 const ExprBuilder &ToB,
const ExprBuilder &FromB) {
14897 Expr *From = FromB.build(S, Loc);
14901 Expr *To = ToB.build(S, Loc);
14906 bool NeedsCollectableMemCpy =
false;
14907 if (
auto *RD = T->getBaseElementTypeUnsafe()->getAsRecordDecl())
14911 StringRef MemCpyName = NeedsCollectableMemCpy ?
14912 "__builtin_objc_memmove_collectable" :
14913 "__builtin_memcpy";
14926 assert(MemCpyRef.
isUsable() &&
"Builtin reference cannot fail");
14928 Expr *CallArgs[] = {
14932 Loc, CallArgs, Loc);
14934 assert(!
Call.isInvalid() &&
"Call to __builtin_memcpy cannot fail!");
14967 const ExprBuilder &To,
const ExprBuilder &From,
14968 bool CopyingBaseSubobject,
bool Copying,
14969 unsigned Depth = 0) {
14984 if (
auto *ClassDecl = T->getAsCXXRecordDecl()) {
14998 if (Method->isCopyAssignmentOperator() ||
14999 (!Copying && Method->isMoveAssignmentOperator()))
15018 if (CopyingBaseSubobject) {
15047 Expr *FromInst = From.build(S, Loc);
15050 Loc, FromInst, Loc);
15051 if (
Call.isInvalid())
15070 Loc, BO_Assign, To.build(S, Loc), From.build(S, Loc));
15090 llvm::raw_svector_ostream OS(Str);
15091 OS <<
"__i" << Depth;
15095 IterationVarName, SizeType,
15104 RefBuilder IterationVarRef(IterationVar, SizeType);
15105 LvalueConvBuilder IterationVarRefRVal(IterationVarRef);
15111 SubscriptBuilder FromIndexCopy(From, IterationVarRefRVal);
15112 MoveCastBuilder FromIndexMove(FromIndexCopy);
15113 const ExprBuilder *FromIndex;
15115 FromIndex = &FromIndexCopy;
15117 FromIndex = &FromIndexMove;
15119 SubscriptBuilder ToIndex(To, IterationVarRefRVal);
15124 ToIndex, *FromIndex, CopyingBaseSubobject,
15125 Copying, Depth + 1);
15127 if (
Copy.isInvalid() || !
Copy.get())
15134 S.
Context, IterationVarRefRVal.build(S, Loc),
15148 Loc, Loc, InitStmt,
15155 const ExprBuilder &To,
const ExprBuilder &From,
15156 bool CopyingBaseSubobject,
bool Copying) {
15158 if (T->isArrayType() && !T.isConstQualified() && !T.isVolatileQualified() &&
15159 T.isTriviallyCopyableType(S.
Context))
15163 CopyingBaseSubobject,
15168 if (!Result.isInvalid() && !Result.get())
15181 DeclaringSpecialMember DSM(*
this, ClassDecl,
15183 if (DSM.isAlreadyBeingDeclared())
15187 std::nullopt, ClassDecl,
15221 CUDA().inferTargetForImplicitSpecialMember(
15228 ClassLoc, ClassLoc,
15241 ++
getASTContext().NumImplicitCopyAssignmentOperatorsDeclared;
15273 for (
auto *I : RD->
ctors()) {
15274 if (I->isCopyConstructor()) {
15275 UserDeclaredOperation = I;
15279 assert(UserDeclaredOperation);
15283 for (
auto *I : RD->
methods()) {
15284 if (I->isCopyAssignmentOperator()) {
15285 UserDeclaredOperation = I;
15289 assert(UserDeclaredOperation);
15292 if (UserDeclaredOperation) {
15293 bool UDOIsUserProvided = UserDeclaredOperation->
isUserProvided();
15297 (UDOIsUserProvided && UDOIsDestructor)
15298 ? diag::warn_deprecated_copy_with_user_provided_dtor
15299 : (UDOIsUserProvided && !UDOIsDestructor)
15300 ? diag::warn_deprecated_copy_with_user_provided_copy
15301 : (!UDOIsUserProvided && UDOIsDestructor)
15302 ? diag::warn_deprecated_copy_with_dtor
15303 : diag::warn_deprecated_copy;
15305 << RD << IsCopyAssignment;
15316 "DefineImplicitCopyAssignment called for wrong function");
15334 Scope.addContextNote(CurrentLocation);
15369 RefBuilder OtherRef(
Other, OtherRefType);
15372 std::optional<ThisBuilder>
This;
15373 std::optional<DerefBuilder> DerefThis;
15374 std::optional<RefBuilder> ExplicitObject;
15375 bool IsArrow =
false;
15381 ExplicitObject.emplace(CopyAssignOperator->
getParamDecl(0), ObjectType);
15385 DerefThis.emplace(*
This);
15388 ExprBuilder &ObjectParameter =
15389 ExplicitObject ?
static_cast<ExprBuilder &
>(*ExplicitObject)
15390 :
static_cast<ExprBuilder &
>(*This);
15394 for (
auto &
Base : ClassDecl->
bases()) {
15397 QualType BaseType =
Base.getType().getUnqualifiedType();
15398 if (!BaseType->isRecordType()) {
15404 BasePath.push_back(&
Base);
15408 CastBuilder From(OtherRef,
Context.getQualifiedType(BaseType, OtherQuals),
15413 ExplicitObject ?
static_cast<ExprBuilder &
>(*ExplicitObject)
15414 :
static_cast<ExprBuilder &
>(*DerefThis),
15423 if (
Copy.isInvalid()) {
15429 Statements.push_back(
Copy.getAs<
Expr>());
15433 for (
auto *Field : ClassDecl->
fields()) {
15436 if (Field->isUnnamedBitField() || Field->getParent()->isUnion())
15439 if (Field->isInvalidDecl()) {
15445 if (Field->getType()->isReferenceType()) {
15446 Diag(ClassDecl->
getLocation(), diag::err_uninitialized_member_for_assign)
15447 <<
Context.getCanonicalTagType(ClassDecl) << 0
15448 << Field->getDeclName();
15449 Diag(Field->getLocation(), diag::note_declared_at);
15456 if (!BaseType->isRecordType() && BaseType.isConstQualified()) {
15457 Diag(ClassDecl->
getLocation(), diag::err_uninitialized_member_for_assign)
15458 <<
Context.getCanonicalTagType(ClassDecl) << 1
15459 << Field->getDeclName();
15460 Diag(Field->getLocation(), diag::note_declared_at);
15466 if (Field->isZeroLengthBitField())
15469 QualType FieldType = Field->getType().getNonReferenceType();
15472 "Incomplete array type is not valid");
15478 LookupResult MemberLookup(*
this, Field->getDeclName(), Loc,
15483 MemberBuilder From(OtherRef, OtherRefType,
false, MemberLookup);
15484 MemberBuilder To(ObjectParameter, ObjectType, IsArrow, MemberLookup);
15490 if (
Copy.isInvalid()) {
15496 Statements.push_back(
Copy.getAs<
Stmt>());
15502 (ExplicitObject ?
static_cast<ExprBuilder &
>(*ExplicitObject)
15503 :
LangOpts.HLSL ?
static_cast<ExprBuilder &
>(*This)
15504 :
static_cast<ExprBuilder &
>(*DerefThis))
15505 .build(*
this, Loc);
15510 Statements.push_back(Return.
getAs<
Stmt>());
15523 assert(!Body.
isInvalid() &&
"Compound statement creation cannot fail");
15529 L->CompletedImplicitDefinition(CopyAssignOperator);
15536 DeclaringSpecialMember DSM(*
this, ClassDecl,
15538 if (DSM.isAlreadyBeingDeclared())
15545 std::nullopt, ClassDecl,
15575 CUDA().inferTargetForImplicitSpecialMember(
15582 ClassLoc, ClassLoc,
15595 ++
getASTContext().NumImplicitMoveAssignmentOperatorsDeclared;
15618 assert(!Class->isDependentContext() &&
"should not define dependent move");
15624 if (Class->getNumVBases() == 0 || Class->hasTrivialMoveAssignment() ||
15625 Class->getNumBases() < 2)
15629 typedef llvm::DenseMap<CXXRecordDecl*, CXXBaseSpecifier*> VBaseMap;
15632 for (
auto &BI : Class->bases()) {
15633 Worklist.push_back(&BI);
15634 while (!Worklist.empty()) {
15640 if (!
Base->hasNonTrivialMoveAssignment())
15665 VBases.insert(std::make_pair(
Base->getCanonicalDecl(), &BI))
15667 if (Existing && Existing != &BI) {
15668 S.
Diag(CurrentLocation, diag::warn_vbase_moved_multiple_times)
15671 << (
Base->getCanonicalDecl() ==
15674 S.
Diag(BI.getBeginLoc(), diag::note_vbase_moved_here)
15675 << (
Base->getCanonicalDecl() ==
15676 BI.getType()->getAsCXXRecordDecl()->getCanonicalDecl())
15680 Existing =
nullptr;
15690 llvm::append_range(Worklist, llvm::make_pointer_range(
Base->bases()));
15703 "DefineImplicitMoveAssignment called for wrong function");
15733 Scope.addContextNote(CurrentLocation);
15749 RefBuilder OtherRef(
Other, OtherRefType);
15751 MoveCastBuilder MoveOther(OtherRef);
15754 std::optional<ThisBuilder>
This;
15755 std::optional<DerefBuilder> DerefThis;
15756 std::optional<RefBuilder> ExplicitObject;
15758 bool IsArrow =
false;
15763 ExplicitObject.emplace(MoveAssignOperator->
getParamDecl(0), ObjectType);
15767 DerefThis.emplace(*
This);
15770 ExprBuilder &ObjectParameter =
15771 ExplicitObject ? *ExplicitObject :
static_cast<ExprBuilder &
>(*This);
15775 for (
auto &
Base : ClassDecl->
bases()) {
15786 QualType BaseType =
Base.getType().getUnqualifiedType();
15787 if (!BaseType->isRecordType()) {
15793 BasePath.push_back(&
Base);
15797 CastBuilder From(OtherRef, BaseType,
VK_XValue, BasePath);
15802 ExplicitObject ?
static_cast<ExprBuilder &
>(*ExplicitObject)
15803 :
static_cast<ExprBuilder &
>(*DerefThis),
15812 if (Move.isInvalid()) {
15818 Statements.push_back(Move.getAs<
Expr>());
15822 for (
auto *Field : ClassDecl->
fields()) {
15825 if (Field->isUnnamedBitField() || Field->getParent()->isUnion())
15828 if (Field->isInvalidDecl()) {
15834 if (Field->getType()->isReferenceType()) {
15835 Diag(ClassDecl->
getLocation(), diag::err_uninitialized_member_for_assign)
15836 <<
Context.getCanonicalTagType(ClassDecl) << 0
15837 << Field->getDeclName();
15838 Diag(Field->getLocation(), diag::note_declared_at);
15845 if (!BaseType->isRecordType() && BaseType.isConstQualified()) {
15846 Diag(ClassDecl->
getLocation(), diag::err_uninitialized_member_for_assign)
15847 <<
Context.getCanonicalTagType(ClassDecl) << 1
15848 << Field->getDeclName();
15849 Diag(Field->getLocation(), diag::note_declared_at);
15855 if (Field->isZeroLengthBitField())
15858 QualType FieldType = Field->getType().getNonReferenceType();
15861 "Incomplete array type is not valid");
15866 LookupResult MemberLookup(*
this, Field->getDeclName(), Loc,
15870 MemberBuilder From(MoveOther, OtherRefType,
15871 false, MemberLookup);
15872 MemberBuilder To(ObjectParameter, ObjectType, IsArrow, MemberLookup);
15874 assert(!From.build(*
this, Loc)->isLValue() &&
15875 "Member reference with rvalue base must be rvalue except for reference "
15876 "members, which aren't allowed for move assignment.");
15883 if (Move.isInvalid()) {
15889 Statements.push_back(Move.getAs<
Stmt>());
15895 (ExplicitObject ?
static_cast<ExprBuilder &
>(*ExplicitObject)
15896 :
LangOpts.HLSL ?
static_cast<ExprBuilder &
>(*This)
15897 :
static_cast<ExprBuilder &
>(*DerefThis))
15898 .build(*
this, Loc);
15904 Statements.push_back(Return.
getAs<
Stmt>());
15917 assert(!Body.
isInvalid() &&
"Compound statement creation cannot fail");
15923 L->CompletedImplicitDefinition(MoveAssignOperator);
15934 DeclaringSpecialMember DSM(*
this, ClassDecl,
15936 if (DSM.isAlreadyBeingDeclared())
15940 std::nullopt, ClassDecl,
15957 =
Context.DeclarationNames.getCXXConstructorName(
15958 Context.getCanonicalType(ClassType));
15977 CUDA().inferTargetForImplicitSpecialMember(
16003 ClassDecl->
hasAttr<TrivialABIAttr>() ||
16035 "DefineImplicitCopyConstructor - call it for implicit copy ctor");
16040 assert(ClassDecl &&
"DefineImplicitCopyConstructor - invalid constructor");
16051 Scope.addContextNote(CurrentLocation);
16081 DeclaringSpecialMember DSM(*
this, ClassDecl,
16083 if (DSM.isAlreadyBeingDeclared())
16087 std::nullopt, ClassDecl,
16100 =
Context.DeclarationNames.getCXXConstructorName(
16101 Context.getCanonicalType(ClassType));
16121 CUDA().inferTargetForImplicitSpecialMember(
16128 ClassLoc, ClassLoc,
16141 ClassDecl->
hasAttr<TrivialABIAttr>() ||
16173 "DefineImplicitMoveConstructor - call it for implicit move ctor");
16178 assert(ClassDecl &&
"DefineImplicitMoveConstructor - invalid constructor");
16189 Scope.addContextNote(CurrentLocation);
16231 CallOp->getDescribedFunctionTemplate(), TemplateArgs, CurrentLocation);
16235 if (CallOp != Invoker) {
16244 if (CallOp->isInvalidDecl())
16254 if (Invoker != CallOp) {
16267 assert(FunctionRef &&
"Can't refer to __invoke function?");
16275 L->CompletedImplicitDefinition(Conv);
16276 if (Invoker != CallOp)
16277 L->CompletedImplicitDefinition(Invoker);
16305 Diag(CurrentLocation, diag::note_lambda_to_block_conv);
16314 Diag(CurrentLocation, diag::note_lambda_to_block_conv);
16320 Stmt *ReturnS = Return.
get();
16327 L->CompletedImplicitDefinition(Conv);
16334 switch (Args.size()) {
16339 if (!Args[1]->isDefaultArgument())
16344 return !Args[0]->isDefaultArgument();
16353 bool HadMultipleCandidates,
bool IsListInitialization,
16354 bool IsStdInitListInitialization,
bool RequiresZeroInit,
16356 bool Elidable =
false;
16375 Expr *SubExpr = ExprArgs[0];
16386 Elidable, ExprArgs, HadMultipleCandidates,
16387 IsListInitialization,
16388 IsStdInitListInitialization, RequiresZeroInit,
16389 ConstructKind, ParenRange);
16395 bool HadMultipleCandidates,
bool IsListInitialization,
16396 bool IsStdInitListInitialization,
bool RequiresZeroInit,
16398 if (
auto *Shadow = dyn_cast<ConstructorUsingShadowDecl>(FoundDecl)) {
16408 ConstructLoc, DeclInitType,
Constructor, Elidable, ExprArgs,
16409 HadMultipleCandidates, IsListInitialization, IsStdInitListInitialization,
16410 RequiresZeroInit, ConstructKind, ParenRange);
16418 bool HadMultipleCandidates,
bool IsListInitialization,
16419 bool IsStdInitListInitialization,
bool RequiresZeroInit,
16424 "given constructor for wrong type");
16432 HadMultipleCandidates, IsListInitialization,
16433 IsStdInitListInitialization, RequiresZeroInit,
16465 PDiag(diag::err_access_dtor_var)
16475 bool HasConstantInit =
false;
16482 diag::err_constexpr_var_requires_const_destruction) << VD;
16493 if (!VD->
hasAttr<AlwaysDestroyAttr>())
16505 bool AllowExplicit,
16506 bool IsListInitialization) {
16508 unsigned NumArgs = ArgsPtr.size();
16509 Expr **Args = ArgsPtr.data();
16515 if (NumArgs < NumParams)
16516 ConvertedArgs.reserve(NumParams);
16518 ConvertedArgs.reserve(NumArgs);
16526 CallType, AllowExplicit, IsListInitialization);
16527 ConvertedArgs.append(AllArgs.begin(), AllArgs.end());
16538 bool SeenTypedOperators =
Context.hasSeenTypeAwareOperatorNewOrDelete();
16545 if (DeallocType.
isNull())
16556 constexpr unsigned RequiredParameterCount =
16559 if (NumParams != RequiredParameterCount)
16564 if (llvm::any_of(FnDecl->
parameters().drop_front(),
16566 return ParamDecl->getType()->isDependentType();
16571 if (SpecializedTypeIdentity.
isNull())
16575 ArgTypes.reserve(NumParams);
16581 ArgTypes.push_back(SpecializedTypeIdentity);
16602 diag::err_operator_new_delete_declared_in_namespace)
16609 diag::err_operator_new_delete_declared_static)
16619 Qualifiers PtrQuals = PtrTy->getPointeeType().getQualifiers();
16622 PtrTy->getPointeeType().getUnqualifiedType(), PtrQuals)));
16629 bool *WasMalformed) {
16630 const Decl *MalformedDecl =
nullptr;
16633 nullptr, &MalformedDecl))
16636 if (!MalformedDecl)
16640 *WasMalformed =
true;
16658 SemaRef, FD,
nullptr);
16659 unsigned DestroyingDeleteIdx = IsPotentiallyTypeAware + 1;
16668 unsigned DependentParamTypeDiag,
unsigned InvalidParamTypeDiag) {
16669 auto NormalizeType = [&SemaRef](
QualType T) {
16673 if (
const auto PtrTy = T->template getAs<PointerType>())
16680 unsigned FirstNonTypeParam = 0;
16681 bool MalformedTypeIdentity =
false;
16683 SemaRef, FnDecl, &MalformedTypeIdentity);
16684 unsigned MinimumMandatoryArgumentCount = 1;
16685 unsigned SizeParameterIndex = 0;
16686 if (IsPotentiallyTypeAware) {
16690 SemaRef.
Diag(FnDecl->
getLocation(), diag::warn_ext_type_aware_allocators);
16693 SizeParameterIndex = 1;
16694 MinimumMandatoryArgumentCount =
16697 SizeParameterIndex = 2;
16698 MinimumMandatoryArgumentCount =
16701 FirstNonTypeParam = 1;
16704 bool IsPotentiallyDestroyingDelete =
16707 if (IsPotentiallyDestroyingDelete) {
16708 ++MinimumMandatoryArgumentCount;
16709 ++SizeParameterIndex;
16712 if (NumParams < MinimumMandatoryArgumentCount)
16714 diag::err_operator_new_delete_too_few_parameters)
16715 << IsPotentiallyTypeAware << IsPotentiallyDestroyingDelete
16716 << FnDecl->
getDeclName() << MinimumMandatoryArgumentCount;
16718 for (
unsigned Idx = 0; Idx < MinimumMandatoryArgumentCount; ++Idx) {
16722 diag::err_operator_new_default_arg)
16727 QualType CanResultType = NormalizeType(FnType->getReturnType());
16728 QualType CanExpectedResultType = NormalizeType(ExpectedResultType);
16729 QualType CanExpectedSizeOrAddressParamType =
16730 NormalizeType(ExpectedSizeOrAddressParamType);
16733 if (CanResultType != CanExpectedResultType) {
16736 return SemaRef.
Diag(
16738 CanResultType->isDependentType()
16739 ? diag::err_operator_new_delete_dependent_result_type
16740 : diag::err_operator_new_delete_invalid_result_type)
16747 diag::err_operator_new_delete_template_too_few_parameters)
16751 auto FallbackType) ->
bool {
16755 << IsPotentiallyTypeAware << IsPotentiallyDestroyingDelete
16761 auto ActualParamType =
16763 if (ActualParamType == CanExpectedTy)
16765 unsigned Diagnostic = ActualParamType->isDependentType()
16766 ? DependentParamTypeDiag
16767 : InvalidParamTypeDiag;
16769 << IsPotentiallyTypeAware << IsPotentiallyDestroyingDelete
16775 if (CheckType(FirstNonTypeParam, CanExpectedSizeOrAddressParamType,
"size_t"))
16782 if (!IsPotentiallyTypeAware)
16791 if (CheckType(SizeParameterIndex + 1, StdAlignValT,
"std::align_val_t"))
16795 return MalformedTypeIdentity;
16814 SizeTy, diag::err_operator_new_dependent_param_type,
16815 diag::err_operator_new_param_type);
16827 auto *MD = dyn_cast<CXXMethodDecl>(FnDecl);
16828 auto ConstructDestroyingDeleteAddressType = [&]() {
16841 SemaRef, MD,
nullptr)) {
16845 AddressParamType == ConstructDestroyingDeleteAddressType()) {
16856 diag::err_type_aware_destroying_operator_delete)
16857 << Param->getSourceRange();
16879 diag::err_operator_delete_dependent_param_type,
16880 diag::err_operator_delete_param_type))
16889 diag::err_destroying_operator_delete_not_usual);
16899 "Expected an overloaded operator declaration");
16909 if (Op == OO_Delete || Op == OO_Array_Delete)
16912 if (Op == OO_New || Op == OO_Array_New)
16922 if (
CXXMethodDecl *MethodDecl = dyn_cast<CXXMethodDecl>(FnDecl)) {
16923 if (MethodDecl->isStatic()) {
16924 if (Op == OO_Call || Op == OO_Subscript)
16927 ? diag::warn_cxx20_compat_operator_overload_static
16928 : diag::ext_operator_overload_static))
16931 return Diag(FnDecl->
getLocation(), diag::err_operator_overload_static)
16935 bool ClassOrEnumParam =
false;
16937 QualType ParamType = Param->getType().getNonReferenceType();
16940 ClassOrEnumParam =
true;
16945 if (!ClassOrEnumParam)
16947 diag::err_operator_overload_needs_class_or_enum)
16957 if (Op != OO_Call) {
16960 if (Param->hasDefaultArg()) {
16961 FirstDefaultedParam = Param;
16965 if (FirstDefaultedParam) {
16966 if (Op == OO_Subscript) {
16968 ? diag::ext_subscript_overload
16969 : diag::error_subscript_overload)
16974 diag::err_operator_overload_default_arg)
16982 {
false,
false,
false }
16983#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
16984 , { Unary, Binary, MemberOnly }
16985#include "clang/Basic/OperatorKinds.def"
16988 bool CanBeUnaryOperator = OperatorUses[Op][0];
16989 bool CanBeBinaryOperator = OperatorUses[Op][1];
16990 bool MustBeMemberOperator = OperatorUses[Op][2];
17001 if (Op != OO_Call && Op != OO_Subscript &&
17002 ((NumParams == 1 && !CanBeUnaryOperator) ||
17003 (NumParams == 2 && !CanBeBinaryOperator) || (NumParams < 1) ||
17004 (NumParams > 2))) {
17006 unsigned ErrorKind;
17007 if (CanBeUnaryOperator && CanBeBinaryOperator) {
17009 }
else if (CanBeUnaryOperator) {
17012 assert(CanBeBinaryOperator &&
17013 "All non-call overloaded operators are unary or binary!");
17016 return Diag(FnDecl->
getLocation(), diag::err_operator_overload_must_be)
17017 << FnDecl->
getDeclName() << NumParams << ErrorKind;
17020 if (Op == OO_Subscript && NumParams != 2) {
17022 ? diag::ext_subscript_overload
17023 : diag::error_subscript_overload)
17024 << FnDecl->
getDeclName() << (NumParams == 1 ? 0 : 2);
17029 if (Op != OO_Call &&
17031 return Diag(FnDecl->
getLocation(), diag::err_operator_overload_variadic)
17038 diag::err_operator_overload_must_be_member)
17052 if ((Op == OO_PlusPlus || Op == OO_MinusMinus) && NumParams == 2) {
17059 diag::err_operator_overload_post_incdec_must_be_int)
17060 << LastParam->
getType() << (Op == OO_MinusMinus);
17072 if (TemplateParams->
size() == 1) {
17074 dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->
getParam(0));
17088 if (SemaRef.
getLangOpts().CPlusPlus20 && PmDecl &&
17091 PmDecl->
getType()->
getAs<DeducedTemplateSpecializationType>()))
17093 }
else if (TemplateParams->
size() == 2) {
17095 dyn_cast<TemplateTypeParmDecl>(TemplateParams->
getParam(0));
17097 dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->
getParam(1));
17103 if (
const auto *TArgs =
17105 TArgs && TArgs->getDepth() == PmType->
getDepth() &&
17106 TArgs->getIndex() == PmType->
getIndex()) {
17109 diag::ext_string_literal_operator_template);
17116 diag::err_literal_operator_template)
17123 Diag(FnDecl->
getLocation(), diag::err_literal_operator_outside_namespace)
17132 Diag(LSD->getExternLoc(), diag::note_extern_c_begins_here);
17151 diag::err_literal_operator_template_with_params);
17161 QualType ParamType = Param->getType().getUnqualifiedType();
17179 Diag(Param->getSourceRange().getBegin(),
17180 diag::err_literal_operator_param)
17181 << ParamType <<
"'const char *'" << Param->getSourceRange();
17186 Diag(Param->getSourceRange().getBegin(), diag::err_literal_operator_param)
17187 << ParamType <<
Context.LongDoubleTy << Param->getSourceRange();
17191 Diag(Param->getSourceRange().getBegin(), diag::err_literal_operator_param)
17192 << ParamType <<
Context.UnsignedLongLongTy << Param->getSourceRange();
17196 Diag(Param->getSourceRange().getBegin(),
17197 diag::err_literal_operator_invalid_param)
17198 << ParamType << Param->getSourceRange();
17207 QualType FirstParamType = (*Param)->getType().getUnqualifiedType();
17214 Diag((*Param)->getSourceRange().getBegin(),
17215 diag::err_literal_operator_param)
17216 << FirstParamType <<
"'const char *'" << (*Param)->getSourceRange();
17223 Diag((*Param)->getSourceRange().getBegin(),
17224 diag::err_literal_operator_param)
17225 << FirstParamType <<
"'const char *'" << (*Param)->getSourceRange();
17238 Diag((*Param)->getSourceRange().getBegin(),
17239 diag::err_literal_operator_param)
17240 << FirstParamType <<
"'const char *'" << (*Param)->getSourceRange();
17248 QualType SecondParamType = (*Param)->getType().getUnqualifiedType();
17249 if (!
Context.hasSameType(SecondParamType,
Context.getSizeType())) {
17250 Diag((*Param)->getSourceRange().getBegin(),
17251 diag::err_literal_operator_param)
17252 << SecondParamType <<
Context.getSizeType()
17253 << (*Param)->getSourceRange();
17257 Diag(FnDecl->
getLocation(), diag::err_literal_operator_bad_param_count);
17266 if (Param->hasDefaultArg()) {
17267 Diag(Param->getDefaultArgRange().getBegin(),
17268 diag::err_literal_operator_default_argument)
17269 << Param->getDefaultArgRange();
17284 <<
static_cast<int>(Status)
17295 assert(Lit->
isUnevaluated() &&
"Unexpected string literal kind");
17301 else if (Lang ==
"C++")
17304 Diag(LangStr->
getExprLoc(), diag::err_language_linkage_spec_unknown)
17324 if (
getLangOpts().CPlusPlusModules && isCurrentModulePurview()) {
17325 Module *GlobalModule = PushImplicitGlobalModuleFragment(ExternLoc);
17348 PopImplicitGlobalModuleFragment();
17351 return LinkageSpec;
17375 ExDeclType =
Context.getArrayDecayedType(ExDeclType);
17377 ExDeclType =
Context.getPointerType(ExDeclType);
17384 Diag(Loc, diag::err_catch_rvalue_ref);
17389 Diag(Loc, diag::err_catch_variably_modified) << ExDeclType;
17395 unsigned DK = diag::err_catch_incomplete;
17397 BaseType = Ptr->getPointeeType();
17399 DK = diag::err_catch_incomplete_ptr;
17402 BaseType = Ref->getPointeeType();
17404 DK = diag::err_catch_incomplete_ref;
17406 if (!
Invalid && (Mode == 0 || !BaseType->isVoidType()) &&
17410 if (!
Invalid && BaseType.isWebAssemblyReferenceType()) {
17411 Diag(Loc, diag::err_wasm_reftype_tc) << 1;
17415 if (!
Invalid && Mode != 1 && BaseType->isSizelessType()) {
17416 Diag(Loc, diag::err_catch_sizeless) << (Mode == 2 ? 1 : 0) << BaseType;
17422 diag::err_abstract_type_in_decl,
17433 if (T->isObjCObjectType()) {
17434 Diag(Loc, diag::err_objc_object_catch);
17436 }
else if (T->isObjCObjectPointerType()) {
17439 Diag(Loc, diag::warn_objc_pointer_cxx_catch_fragile);
17448 if (
getLangOpts().ObjCAutoRefCount &&
ObjC().inferObjCARCLifetime(ExDecl))
17473 Expr *opaqueValue =
17523 Diag(PrevDecl->getLocation(), diag::note_previous_definition);
17525 }
else if (PrevDecl->isTemplateParameter())
17553 Expr *AssertMessageExpr,
17559 AssertMessageExpr, RParenLoc,
false);
17564 case BuiltinType::Char_S:
17565 case BuiltinType::Char_U:
17567 case BuiltinType::Char8:
17570 case BuiltinType::Char16:
17573 case BuiltinType::Char32:
17576 case BuiltinType::WChar_S:
17577 case BuiltinType::WChar_U:
17581 llvm_unreachable(
"Non-character type");
17591 char Arr[UNI_MAX_UTF8_BYTES_PER_CODE_POINT];
17594 llvm::raw_svector_ostream OS(Str);
17598 if (K == BuiltinType::Char_S || K == BuiltinType::Char_U ||
17599 K == BuiltinType::Char8 ||
Value <= 0x7F) {
17601 if (!Escaped.empty())
17604 OS << static_cast<char>(
Value);
17609 case BuiltinType::Char16:
17610 case BuiltinType::Char32:
17611 case BuiltinType::WChar_S:
17612 case BuiltinType::WChar_U: {
17613 if (llvm::ConvertCodePointToUTF8(
Value, Ptr))
17617 << llvm::format_hex_no_prefix(
Value, TyWidth / 4,
true);
17621 llvm_unreachable(
"Non-character type is passed");
17633 switch (
V.getKind()) {
17635 if (T->isBooleanType()) {
17639 int64_t BoolValue =
V.getInt().getExtValue();
17640 assert((BoolValue == 0 || BoolValue == 1) &&
17641 "Bool type, but value is not 0 or 1");
17642 llvm::raw_svector_ostream OS(Str);
17643 OS << (BoolValue ?
"true" :
"false");
17645 llvm::raw_svector_ostream OS(Str);
17650 switch (BTy->getKind()) {
17651 case BuiltinType::Char_S:
17652 case BuiltinType::Char_U:
17653 case BuiltinType::Char8:
17654 case BuiltinType::Char16:
17655 case BuiltinType::Char32:
17656 case BuiltinType::WChar_S:
17657 case BuiltinType::WChar_U: {
17658 unsigned TyWidth = Context.getIntWidth(T);
17659 assert(8 <= TyWidth && TyWidth <= 32 &&
"Unexpected integer width");
17660 uint32_t CodeUnit =
static_cast<uint32_t
>(
V.getInt().getZExtValue());
17665 << llvm::format_hex_no_prefix(CodeUnit, 2,
17667 <<
", " <<
V.getInt() <<
')';
17674 V.getInt().toString(Str);
17680 V.getFloat().toString(Str);
17684 if (
V.isNullPointer()) {
17685 llvm::raw_svector_ostream OS(Str);
17692 llvm::raw_svector_ostream OS(Str);
17694 V.getComplexFloatReal().toString(Str);
17696 V.getComplexFloatImag().toString(Str);
17701 llvm::raw_svector_ostream OS(Str);
17703 V.getComplexIntReal().toString(Str);
17705 V.getComplexIntImag().toString(Str);
17732 if (
const auto *UnaryOp = dyn_cast<UnaryOperator>(E))
17736 if (
const auto *BO = dyn_cast<BinaryOperator>(E))
17737 return (BO->isShiftOp() || BO->isAdditiveOp() || BO->isMultiplicativeOp() ||
17738 BO->isBitwiseOp());
17744 if (
const auto *Op = dyn_cast<BinaryOperator>(E);
17745 Op && Op->getOpcode() != BO_LOr) {
17746 const Expr *LHS = Op->getLHS()->IgnoreParenImpCasts();
17747 const Expr *RHS = Op->getRHS()->IgnoreParenImpCasts();
17765 for (
auto &DiagSide : DiagSides) {
17766 const Expr *Side = DiagSide.Cond;
17771 DiagSide.Result.Val, Side->
getType(), DiagSide.ValueString,
Context);
17773 if (DiagSides[0].Print && DiagSides[1].Print) {
17774 Diag(Op->getExprLoc(), diag::note_expr_evaluates_to)
17775 << DiagSides[0].ValueString << Op->getOpcodeStr()
17776 << DiagSides[1].ValueString << Op->getSourceRange();
17783template <
typename ResultType>
17787 bool ErrorOnInvalidMessage) {
17790 assert(!Message->isTypeDependent() && !Message->isValueDependent() &&
17791 "can't evaluate a dependant static assert message");
17793 if (
const auto *SL = dyn_cast<StringLiteral>(Message)) {
17794 assert(SL->isUnevaluated() &&
"expected an unevaluated string");
17795 if constexpr (std::is_same_v<APValue, ResultType>) {
17800 assert(CAT &&
"string literal isn't an array");
17804 for (
unsigned I = 0; I < SL->getLength(); I++) {
17805 Value = SL->getCodeUnit(I);
17809 Result.assign(SL->getString().begin(), SL->getString().end());
17815 QualType T = Message->getType().getNonReferenceType();
17816 auto *RD = T->getAsCXXRecordDecl();
17818 SemaRef.
Diag(Loc, diag::err_user_defined_msg_invalid) << EvalContext;
17822 auto FindMember = [&](StringRef
Member) -> std::optional<LookupResult> {
17828 if (MemberLookup.
empty())
17829 return std::nullopt;
17830 return std::move(MemberLookup);
17833 std::optional<LookupResult> SizeMember = FindMember(
"size");
17834 std::optional<LookupResult> DataMember = FindMember(
"data");
17835 if (!SizeMember || !DataMember) {
17836 SemaRef.
Diag(Loc, diag::err_user_defined_msg_missing_member_function)
17838 << ((!SizeMember && !DataMember) ? 2
17846 Message, Message->getType(), Message->getBeginLoc(),
false,
17872 SemaRef.
Diag(Loc, diag::err_user_defined_msg_invalid_mem_fn_ret_ty)
17873 << EvalContext << 0;
17883 SemaRef.
Diag(Loc, diag::err_user_defined_msg_invalid_mem_fn_ret_ty)
17884 << EvalContext << 1;
17888 if (!ErrorOnInvalidMessage &&
17889 SemaRef.
Diags.
isIgnored(diag::warn_user_defined_msg_constexpr, Loc))
17894 Status.Diag = &Notes;
17895 if (!Message->EvaluateCharRangeAsString(Result, EvaluatedSize.
get(),
17896 EvaluatedData.
get(), Ctx, Status) ||
17898 SemaRef.
Diag(Message->getBeginLoc(),
17899 ErrorOnInvalidMessage ? diag::err_user_defined_msg_constexpr
17900 : diag::warn_user_defined_msg_constexpr)
17902 for (
const auto &
Note : Notes)
17904 return !ErrorOnInvalidMessage;
17911 bool ErrorOnInvalidMessage) {
17913 ErrorOnInvalidMessage);
17918 bool ErrorOnInvalidMessage) {
17920 ErrorOnInvalidMessage);
17924 Expr *AssertExpr,
Expr *AssertMessage,
17927 assert(AssertExpr !=
nullptr &&
"Expected non-null condition");
17945 AssertExpr = FullAssertExpr.
get();
17948 Expr *BaseExpr = AssertExpr;
17960 diag::err_static_assert_expression_is_not_constant,
17966 if (!Failed && AssertMessage &&
Cond.getBoolValue()) {
17976 bool InTemplateDefinition =
17979 if (!Failed && !
Cond && !InTemplateDefinition) {
17981 llvm::raw_svector_ostream Msg(MsgBuffer);
17982 bool HasMessage = AssertMessage;
17983 if (AssertMessage) {
17991 Expr *InnerCond =
nullptr;
17992 std::string InnerCondDescription;
17993 std::tie(InnerCond, InnerCondDescription) =
17995 if (
const auto *ConceptIDExpr =
17996 dyn_cast_or_null<ConceptSpecializationExpr>(InnerCond)) {
17998 ConceptIDExpr->getSatisfaction();
18009 diag::err_static_assert_requirement_failed)
18010 << InnerCondDescription << !HasMessage << Msg.str()
18027 AssertExpr = FullAssertExpr.
get();
18031 AssertExpr, AssertMessage, RParenLoc,
18045 bool IsMemberSpecialization =
false;
18050 TagLoc, NameLoc, SS,
nullptr, TempParamLists,
true,
18051 IsMemberSpecialization,
Invalid)) {
18052 if (TemplateParams->size() > 0) {
18060 FriendLoc, TempParamLists.size() - 1,
18061 TempParamLists.data())
18065 Diag(TemplateParams->getTemplateLoc(), diag::err_template_tag_noparams)
18067 IsMemberSpecialization =
true;
18073 bool isAllExplicitSpecializations =
18075 return List->
size() == 0;
18084 if (isAllExplicitSpecializations) {
18086 bool Owned =
false;
18087 bool IsDependent =
false;
18104 NameLoc, &TSI,
true);
18110 EllipsisLoc, TempParamLists);
18116 assert(SS.
isNotEmpty() &&
"valid templated tag with no SS and no direct?");
18123 unsigned FriendDeclDepth = TempParamLists.front()->getDepth();
18126 DI && DI->first >= FriendDeclDepth) {
18127 auto *ND = dyn_cast<NamedDecl *>(
U.first);
18130 Diag(
U.second, diag::friend_template_decl_malformed_pack_expansion)
18139 Diag(NameLoc, diag::warn_template_qualified_friend_unsupported)
18151 EllipsisLoc, TempParamLists);
18153 Friend->setUnsupportedFriend(
true);
18177 Diag(FriendLoc, diag::err_friend_not_first_in_declaration);
18209 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
18214 if (!T->isElaboratedTypeSpecifier()) {
18215 if (TempParams.size()) {
18227 }
else if (
const RecordDecl *RD = T->getAsRecordDecl()) {
18232 ? diag::warn_cxx98_compat_unelaborated_friend_type
18233 : diag::ext_unelaborated_friend_type)
18238 DiagCompat(FriendLoc, diag_compat::nonclass_type_friend)
18255 if (!TempParams.empty())
18261 TSI, FriendLoc, EllipsisLoc);
18296 Diag(Loc, diag::err_unexpected_friend);
18331 Scope *DCScope = S;
18343 (FunctionContainingLocalClass =
18366 DC =
Previous.getRepresentativeDecl()->getDeclContext();
18370 DC = FunctionContainingLocalClass;
18407 if (isTemplateId) {
18422 if (!DC)
return nullptr;
18433 diag::warn_cxx98_compat_friend_is_member :
18434 diag::err_friend_is_member);
18470 if (DiagArg >= 0) {
18471 Diag(Loc, diag::err_introducing_special_friend) << DiagArg;
18482 DCScope = &FakeDCScope;
18485 bool AddToScope =
true;
18487 TemplateParams, AddToScope);
18488 if (!ND)
return nullptr;
18522 FD = FTD->getTemplatedDecl();
18544 }
else if (FunctionContainingLocalClass) {
18553 }
else if (isTemplateId) {
18567 Diag(FD->
getLocation(), diag::err_friend_decl_with_def_arg_redeclared);
18569 diag::note_previous_declaration);
18571 Diag(FD->
getLocation(), diag::err_friend_decl_with_def_arg_must_be_def);
18576 Diag(FD->
getLocation(), diag::warn_template_qualified_friend_unsupported)
18592 FunctionDecl *Fn = dyn_cast_or_null<FunctionDecl>(Dcl);
18594 Diag(DelLoc, diag::err_deleted_non_function);
18599 Fn->setWillHaveBody(
false);
18601 if (
const FunctionDecl *Prev = Fn->getPreviousDecl()) {
18605 Prev->getPreviousDecl()) &&
18606 !Prev->isDefined()) {
18607 Diag(DelLoc, diag::err_deleted_decl_not_first);
18608 Diag(Prev->getLocation().isInvalid() ? DelLoc : Prev->getLocation(),
18609 Prev->isImplicit() ? diag::note_previous_implicit_declaration
18610 : diag::note_previous_declaration);
18613 Fn->setInvalidDecl();
18621 Fn = Fn->getCanonicalDecl();
18626 Diag(Fn->getLocation(), diag::err_attribute_dll_deleted) << DLLAttr;
18627 Fn->setInvalidDecl();
18633 Diag(DelLoc, diag::err_deleted_main);
18637 Fn->setImplicitlyInline();
18638 Fn->setDeletedAsWritten(
true, Message);
18645 auto *FD = dyn_cast<FunctionDecl>(Dcl);
18647 if (
auto *FTD = dyn_cast<FunctionTemplateDecl>(Dcl)) {
18649 Diag(DefaultLoc, diag::err_defaulted_comparison_template);
18654 Diag(DefaultLoc, diag::err_default_special_members)
18665 (!FD->isDependentContext() ||
18668 Diag(DefaultLoc, diag::err_default_special_members)
18678 ? diag::warn_cxx17_compat_defaulted_comparison
18679 : diag::ext_defaulted_comparison);
18682 FD->setDefaulted();
18683 FD->setExplicitlyDefaulted();
18684 FD->setDefaultLoc(DefaultLoc);
18687 if (FD->isDependentContext())
18693 FD->setWillHaveBody(
false);
18708 if (
const FunctionDecl *Pattern = FD->getTemplateInstantiationPattern())
18737 Self.Diag(SubStmt->getBeginLoc(),
18738 diag::err_return_in_constructor_handler);
18745 for (
unsigned I = 0, E = TryBlock->
getNumHandlers(); I != E; ++I) {
18753 switch (BodyKind) {
18762 "Parsed function body should be '= delete;' or '= default;'");
18772 for (
unsigned I = 0, E = OldFT->
getNumParams(); I != E; ++I)
18776 !NewFT->getExtParameterInfo(I).isNoEscape()) {
18777 Diag(
New->getParamDecl(I)->getLocation(),
18778 diag::warn_overriding_method_missing_noescape);
18780 diag::note_overridden_marked_noescape);
18786 Diag(
New->getLocation(), diag::err_conflicting_overriding_attributes)
18793 const auto *OldCSA = Old->
getAttr<CodeSegAttr>();
18794 const auto *NewCSA =
New->getAttr<CodeSegAttr>();
18795 if ((NewCSA || OldCSA) &&
18796 (!OldCSA || !NewCSA || NewCSA->getName() != OldCSA->getName())) {
18797 Diag(
New->getLocation(), diag::err_mismatched_code_seg_override);
18803 if (
Context.hasAnyFunctionEffects()) {
18805 const auto NewFXOrig =
New->getFunctionEffects();
18807 if (OldFX != NewFXOrig) {
18811 for (
const auto &Diff : Diffs) {
18812 switch (Diff.shouldDiagnoseMethodOverride(*Old, OldFX, *
New, NewFX)) {
18816 Diag(
New->getLocation(), diag::warn_conflicting_func_effect_override)
18817 << Diff.effectName();
18822 NewFX.
insert(Diff.Old.value(), Errs);
18827 NewFT->getParamTypes(), EPI);
18828 New->setType(ModQT);
18829 if (Errs.empty()) {
18832 Diag(
New->getLocation(), diag::warn_mismatched_func_effect_override)
18833 << Diff.effectName();
18850 if (NewCC == OldCC)
18861 diag::err_conflicting_overriding_cc_attributes)
18871 if (!
New->isExplicitObjectMemberFunction())
18873 Diag(
New->getParamDecl(0)->getBeginLoc(),
18874 diag::err_explicit_object_parameter_nonmember)
18875 <<
New->getSourceRange() << 1 <<
false;
18877 New->setInvalidDecl();
18886 if (
Context.hasSameType(NewTy, OldTy) ||
18901 if (NewRT->getTypeClass() == OldRT->getTypeClass()) {
18911 diag::err_different_return_type_for_overriding_virtual_function)
18912 <<
New->getDeclName() << NewTy << OldTy
18913 <<
New->getReturnTypeSourceRange();
18920 if (!
Context.hasSameUnqualifiedType(NewClassTy, OldClassTy)) {
18929 diag::err_covariant_return_incomplete,
18930 New->getDeclName()))
18936 Diag(
New->getLocation(), diag::err_covariant_return_not_derived)
18937 <<
New->getDeclName() << NewTy << OldTy
18938 <<
New->getReturnTypeSourceRange();
18946 NewClassTy, OldClassTy,
18947 diag::err_covariant_return_inaccessible_base,
18948 diag::err_covariant_return_ambiguous_derived_to_base_conv,
18949 New->getLocation(),
New->getReturnTypeSourceRange(),
18950 New->getDeclName(),
nullptr)) {
18964 diag::err_covariant_return_type_different_qualifications)
18965 <<
New->getDeclName() << NewTy << OldTy
18966 <<
New->getReturnTypeSourceRange();
18976 diag::err_covariant_return_type_class_type_not_same_or_less_qualified)
18977 <<
New->getDeclName() << NewTy << OldTy
18978 <<
New->getReturnTypeSourceRange();
18990 Method->setRangeEnd(EndLoc);
18992 if (
Method->isVirtual() ||
Method->getParent()->isDependentContext()) {
18993 Method->setIsPureVirtual();
18997 if (!
Method->isInvalidDecl())
18998 Diag(
Method->getLocation(), diag::err_non_virtual_pure)
18999 <<
Method->getDeclName() << InitRange;
19006 else if (
auto *M = dyn_cast<CXXMethodDecl>(D))
19049 "Parser allowed 'typedef' as storage class of condition decl.");
19061 if (
auto *VD = dyn_cast<VarDecl>(Dcl))
19075 llvm::DenseMap<CXXRecordDecl *, bool>::iterator Pos =
19079 if (!Pos->second && VTable.DefinitionRequired)
19080 Pos->second =
true;
19084 VTablesUsed[VTable.Record] = VTable.DefinitionRequired;
19085 NewUses.push_back(
VTableUse(VTable.Record, VTable.Location));
19092 bool DefinitionRequired) {
19095 if (!
Class->isDynamicClass() ||
Class->isDependentContext() ||
19101 !
OpenMP().isInOpenMPDeclareTargetContext() &&
19102 !
OpenMP().isInOpenMPTargetExecutionDirective()) {
19103 if (!DefinitionRequired)
19111 std::pair<llvm::DenseMap<CXXRecordDecl *, bool>::iterator,
bool>
19117 if (DefinitionRequired && !Pos.first->second) {
19118 Pos.first->second =
true;
19128 if (
Context.getTargetInfo().getCXXABI().isMicrosoft()) {
19147 if (
Class->isLocalClass())
19162 bool DefinedAnything =
false;
19163 for (
unsigned I = 0; I !=
VTableUses.size(); ++I) {
19168 Class->getTemplateSpecializationKind();
19172 bool DefineVTable =
true;
19177 if (
Class->isInCurrentModuleUnit()) {
19178 DefineVTable =
true;
19179 }
else if (KeyFunction && !KeyFunction->
hasBody()) {
19184 DefineVTable =
false;
19189 "Instantiations don't have key functions");
19191 }
else if (!KeyFunction) {
19196 bool IsExplicitInstantiationDeclaration =
19198 for (
auto *R :
Class->redecls()) {
19202 IsExplicitInstantiationDeclaration =
true;
19204 IsExplicitInstantiationDeclaration =
false;
19209 if (IsExplicitInstantiationDeclaration) {
19210 const bool HasExcludeFromExplicitInstantiation =
19218 return method->hasAttr<ExcludeFromExplicitInstantiationAttr>();
19220 if (!HasExcludeFromExplicitInstantiation)
19221 DefineVTable =
false;
19228 if (!DefineVTable) {
19236 DefinedAnything =
true;
19245 if (
Context.getTargetInfo().getCXXABI().hasKeyFunctions() &&
19249 if (!KeyFunction || (KeyFunction->
hasBody(KeyFunctionDef) &&
19256 return DefinedAnything;
19261 for (
const auto *I : RD->
methods())
19262 if (I->isVirtual() && !I->isPureVirtual())
19268 bool ConstexprOnly) {
19272 for (
const auto &FinalOverrider : FinalOverriders) {
19273 for (
const auto &OverridingMethod : FinalOverrider.second) {
19274 assert(OverridingMethod.second.size() > 0 &&
"no final overrider");
19275 CXXMethodDecl *Overrider = OverridingMethod.second.front().Method;
19289 for (
const auto &I : RD->
bases()) {
19290 const auto *
Base = I.getType()->castAsCXXRecordDecl();
19291 if (
Base->getNumVBases() == 0)
19312 (void)
Target->hasBody(FNTarget);
19314 cast_or_null<CXXConstructorDecl>(FNTarget));
19319 *TCanonical =
Target?
Target->getCanonicalDecl() :
nullptr;
19321 if (!Current.insert(Canonical).second)
19326 Target->isInvalidDecl() ||
Valid.count(TCanonical)) {
19327 Valid.insert_range(Current);
19330 }
else if (TCanonical == Canonical ||
Invalid.count(TCanonical) ||
19331 Current.count(TCanonical)) {
19333 if (!
Invalid.count(TCanonical)) {
19335 diag::warn_delegating_ctor_cycle)
19339 if (TCanonical != Canonical)
19340 S.
Diag(
Target->getLocation(), diag::note_it_delegates_to);
19343 while (
C->getCanonicalDecl() != Canonical) {
19345 (void)
C->getTargetConstructor()->hasBody(FNTarget);
19346 assert(FNTarget &&
"Ctor cycle through bodiless function");
19350 S.
Diag(
C->getLocation(), diag::note_which_delegates_to);
19354 Invalid.insert_range(Current);
19365 for (DelegatingCtorDeclsType::iterator
19372 CI->setInvalidDecl();
19381 explicit FindCXXThisExpr(
Sema &S) : S(S) {}
19409 FindCXXThisExpr Finder(*
this);
19422 if (!Finder.TraverseStmt(
const_cast<Expr *
>(TRC.ConstraintExpr)))
19439 FindCXXThisExpr Finder(*
this);
19461 if (!Finder.TraverseType(E))
19471 FindCXXThisExpr Finder(*
this);
19474 for (
const auto *A :
Method->attrs()) {
19476 Expr *Arg =
nullptr;
19478 if (
const auto *G = dyn_cast<GuardedByAttr>(A))
19480 else if (
const auto *G = dyn_cast<PtGuardedByAttr>(A))
19482 else if (
const auto *AA = dyn_cast<AcquiredAfterAttr>(A))
19484 else if (
const auto *AB = dyn_cast<AcquiredBeforeAttr>(A))
19486 else if (
const auto *LR = dyn_cast<LockReturnedAttr>(A))
19487 Arg = LR->getArg();
19488 else if (
const auto *LE = dyn_cast<LocksExcludedAttr>(A))
19490 else if (
const auto *RC = dyn_cast<RequiresCapabilityAttr>(A))
19492 else if (
const auto *AC = dyn_cast<AcquireCapabilityAttr>(A))
19494 else if (
const auto *AC = dyn_cast<TryAcquireCapabilityAttr>(A)) {
19495 Arg = AC->getSuccessValue();
19497 }
else if (
const auto *RC = dyn_cast<ReleaseCapabilityAttr>(A))
19500 if (Arg && !Finder.TraverseStmt(Arg))
19503 for (
Expr *A : Args) {
19504 if (!Finder.TraverseStmt(A))
19518 Exceptions.clear();
19521 Exceptions.reserve(DynamicExceptions.size());
19522 for (
unsigned ei = 0, ee = DynamicExceptions.size(); ei != ee; ++ei) {
19529 if (!Unexpanded.empty()) {
19540 Exceptions.push_back(ET);
19550 "Parser should have made sure that the expression is boolean");
19570 D = FTD->getTemplatedDecl();
19580 DynamicExceptionRanges, NoexceptExpr, Exceptions,
19584 Context.adjustExceptionSpec(FD, ESI,
true);
19608 Diag(DeclStart, diag::err_anonymous_property);
19622 TInfo =
Context.getTrivialTypeSourceInfo(T, Loc);
19633 diag::err_invalid_thread)
19641 switch (
Previous.getResultKind()) {
19648 PrevDecl =
Previous.getRepresentativeDecl();
19661 PrevDecl =
nullptr;
19665 PrevDecl =
nullptr;
19676 Record->setInvalidDecl();
19698 if (!ExplicitLists.empty()) {
19699 bool IsMemberSpecialization, IsInvalid;
19703 ExplicitLists,
false, IsMemberSpecialization, IsInvalid,
19715 if (ExplicitParams && !ExplicitParams->
empty()) {
19716 Info.AutoTemplateParameterDepth = ExplicitParams->
getDepth();
19717 llvm::append_range(Info.TemplateParams, *ExplicitParams);
19718 Info.NumExplicitTemplateParams = ExplicitParams->
size();
19720 Info.AutoTemplateParameterDepth = TemplateParameterDepth;
19721 Info.NumExplicitTemplateParams = 0;
19727 if (FSI.TemplateParams.size() > FSI.NumExplicitTemplateParams) {
19728 if (FSI.NumExplicitTemplateParams != 0) {
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
static bool CheckLiteralType(EvalInfo &Info, const Expr *E, const LValue *This=nullptr)
Check that this core constant expression is of literal type, and if not, produce an appropriate diagn...
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.
llvm::MachO::Target Target
llvm::MachO::Record Record
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
Defines the clang::Preprocessor interface.
@ ForExternalRedeclaration
The lookup results will be used for redeclaration of a name with external linkage; non-visible lookup...
@ ForVisibleRedeclaration
The lookup results will be used for redeclaration of a name, if an entity by that name already exists...
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static void ProcessAPINotes(Sema &S, Decl *D, const api_notes::CommonEntityInfo &Info, VersionedInfoMetadata Metadata)
This file declares semantic analysis for CUDA constructs.
static void DiagnoseUnsatisfiedConstraint(Sema &S, ArrayRef< UnsatisfiedConstraintRecord > Records, SourceLocation Loc, bool First=true, concepts::NestedRequirement *Req=nullptr)
static LookupResult lookupMember(Sema &S, const char *Name, CXXRecordDecl *RD, SourceLocation Loc, bool &Res)
static bool findTrivialSpecialMember(Sema &S, CXXRecordDecl *RD, CXXSpecialMemberKind CSM, unsigned Quals, bool ConstRHS, TrivialABIHandling TAH, CXXMethodDecl **Selected)
Perform lookup for a special member of the specified kind, and determine whether it is trivial.
static void checkMoveAssignmentForRepeatedMove(Sema &S, CXXRecordDecl *Class, SourceLocation CurrentLocation)
Check if we're implicitly defining a move assignment operator for a class with virtual bases.
static void checkMethodTypeQualifiers(Sema &S, Declarator &D, unsigned DiagID)
static void DelegatingCycleHelper(CXXConstructorDecl *Ctor, llvm::SmallPtrSet< CXXConstructorDecl *, 4 > &Valid, llvm::SmallPtrSet< CXXConstructorDecl *, 4 > &Invalid, llvm::SmallPtrSet< CXXConstructorDecl *, 4 > &Current, Sema &S)
static bool CheckConstexprFunctionBody(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *Body, Sema::CheckConstexprKind Kind)
Check the body for the given constexpr function declaration only contains the permitted types of stat...
llvm::SmallPtrSet< QualType, 4 > IndirectBaseSet
Use small set to collect indirect bases.
static void checkCUDADeviceBuiltinSurfaceClassTemplate(Sema &S, CXXRecordDecl *Class)
static bool checkVectorDecomposition(Sema &S, ArrayRef< BindingDecl * > Bindings, ValueDecl *Src, QualType DecompType, const VectorType *VT)
static void SearchForReturnInStmt(Sema &Self, Stmt *S)
static bool checkSimpleDecomposition(Sema &S, ArrayRef< BindingDecl * > Bindings, ValueDecl *Src, QualType DecompType, const llvm::APSInt &NumElemsAPS, QualType ElemType, llvm::function_ref< ExprResult(SourceLocation, Expr *, unsigned)> GetInit)
static CXXDestructorDecl * LookupDestructorIfRelevant(Sema &S, CXXRecordDecl *Class)
static void extendRight(SourceRange &R, SourceRange After)
static void DiagnoseNamespaceInlineMismatch(Sema &S, SourceLocation KeywordLoc, SourceLocation Loc, IdentifierInfo *II, bool *IsInline, NamespaceDecl *PrevNS)
Diagnose a mismatch in 'inline' qualifiers when a namespace is reopened.
static bool IsPotentiallyTypeAwareOperatorNewOrDelete(Sema &SemaRef, const FunctionDecl *FD, bool *WasMalformed)
static bool RefersToRValueRef(Expr *MemRef)
static bool CheckConstexprCtorInitializer(Sema &SemaRef, const FunctionDecl *Dcl, FieldDecl *Field, llvm::SmallPtrSet< Decl *, 16 > &Inits, bool &Diagnosed, Sema::CheckConstexprKind Kind)
Check that the given field is initialized within a constexpr constructor.
static CanQualType RemoveAddressSpaceFromPtr(Sema &SemaRef, const PointerType *PtrTy)
static bool isVirtualDirectBase(CXXRecordDecl *Derived, CXXRecordDecl *Base)
Determine whether a direct base class is a virtual base class.
#define CheckPolymorphic(Type)
static void BuildBasePathArray(const CXXBasePath &Path, CXXCastPath &BasePathArray)
static void WriteCharValueForDiagnostic(uint32_t Value, const BuiltinType *BTy, unsigned TyWidth, SmallVectorImpl< char > &Str)
Convert character's value, interpreted as a code unit, to a string.
static void CheckAbstractClassUsage(AbstractUsageInfo &Info, FunctionDecl *FD)
Check for invalid uses of an abstract type in a function declaration.
static unsigned getRecordDiagFromTagKind(TagTypeKind Tag)
Get diagnostic select index for tag kind for record diagnostic message.
static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T, unsigned &OutSize)
static Expr * CastForMoving(Sema &SemaRef, Expr *E)
static bool IsPotentiallyDestroyingOperatorDelete(Sema &SemaRef, const FunctionDecl *FD)
static void extendLeft(SourceRange &R, SourceRange Before)
static bool specialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl, CXXSpecialMemberKind CSM, unsigned Quals, bool ConstRHS, CXXConstructorDecl *InheritedCtor=nullptr, Sema::InheritedConstructorInfo *Inherited=nullptr)
Is the special member function which would be selected to perform the specified operation on the spec...
static void diagnoseInvalidDeclaratorChunks(Sema &S, Declarator &D, unsigned Kind)
static bool canPassInRegisters(Sema &S, CXXRecordDecl *D, TargetInfo::CallingConvKind CCK)
Determine whether a type is permitted to be passed or returned in registers, per C++ [class....
static void lookupOperatorsForDefaultedComparison(Sema &Self, Scope *S, UnresolvedSetImpl &Operators, OverloadedOperatorKind Op)
Perform the unqualified lookups that might be needed to form a defaulted comparison function for the ...
static void WriteCharTypePrefix(BuiltinType::Kind BTK, llvm::raw_ostream &OS)
static bool EvaluateAsStringImpl(Sema &SemaRef, Expr *Message, ResultType &Result, ASTContext &Ctx, Sema::StringEvaluationContext EvalContext, bool ErrorOnInvalidMessage)
static void diagnoseDeprecatedCopyOperation(Sema &S, CXXMethodDecl *CopyOp)
Diagnose an implicit copy operation for a class which is odr-used, but which is deprecated because th...
static void AddMostOverridenMethods(const CXXMethodDecl *MD, llvm::SmallPtrSetImpl< const CXXMethodDecl * > &Methods)
Add the most overridden methods from MD to Methods.
static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc, const CXXRecordDecl *RD, CXXCastPath &BasePath)
Find the base class to decompose in a built-in decomposition of a class type.
static const void * GetKeyForBase(ASTContext &Context, QualType BaseType)
static QualType BuildStdClassTemplate(Sema &S, ClassTemplateDecl *CTD, QualType TypeParam, SourceLocation Loc)
static NamespaceDecl * getNamespaceDecl(NamespaceBaseDecl *D)
getNamespaceDecl - Returns the namespace a decl represents.
static Sema::ImplicitExceptionSpecification ComputeDefaultedComparisonExceptionSpec(Sema &S, SourceLocation Loc, FunctionDecl *FD, Sema::DefaultedComparisonKind DCK)
static bool isDestroyingDeleteT(QualType Type)
static StmtResult buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T, const ExprBuilder &To, const ExprBuilder &From, bool CopyingBaseSubobject, bool Copying, unsigned Depth=0)
Builds a statement that copies/moves the given entity from From to To.
static void checkCUDADeviceBuiltinTextureClassTemplate(Sema &S, CXXRecordDecl *Class)
static void AddInitializerToDiag(const Sema::SemaDiagnosticBuilder &Diag, const CXXCtorInitializer *Previous, const CXXCtorInitializer *Current)
static bool BuildImplicitBaseInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, ImplicitInitializerKind ImplicitInitKind, CXXBaseSpecifier *BaseSpec, bool IsInheritedVirtualBase, CXXCtorInitializer *&CXXBaseInit)
static bool IsUnusedPrivateField(const FieldDecl *FD)
static void NoteIndirectBases(ASTContext &Context, IndirectBaseSet &Set, const QualType &Type)
Recursively add the bases of Type. Don't add Type itself.
static bool CheckConstexprMissingReturn(Sema &SemaRef, const FunctionDecl *Dcl)
static bool CheckConstexprFunctionStmt(Sema &SemaRef, const FunctionDecl *Dcl, Stmt *S, SmallVectorImpl< SourceLocation > &ReturnStmts, SourceLocation &Cxx1yLoc, SourceLocation &Cxx2aLoc, SourceLocation &Cxx2bLoc, Sema::CheckConstexprKind Kind)
Check the provided statement is allowed in a constexpr function definition.
static bool functionDeclHasDefaultArgument(const FunctionDecl *FD)
static bool CheckConstexprParameterTypes(Sema &SemaRef, const FunctionDecl *FD, Sema::CheckConstexprKind Kind)
Check whether a function's parameter types are all literal types.
static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext)
Determine whether a using statement is in a context where it will be apply in all contexts.
static bool checkTupleLikeDecomposition(Sema &S, ArrayRef< BindingDecl * > Bindings, VarDecl *Src, QualType DecompType, unsigned NumElems)
static CXXConstructorDecl * findUserDeclaredCtor(CXXRecordDecl *RD)
static bool checkMemberDecomposition(Sema &S, ArrayRef< BindingDecl * > Bindings, ValueDecl *Src, QualType DecompType, const CXXRecordDecl *OrigRD)
static bool HasAttribute(const QualType &T)
static bool CheckOperatorNewDeclaration(Sema &SemaRef, FunctionDecl *FnDecl)
static void checkForMultipleExportedDefaultConstructors(Sema &S, CXXRecordDecl *Class)
static bool CheckOperatorNewDeleteTypes(Sema &SemaRef, FunctionDecl *FnDecl, AllocationOperatorKind OperatorKind, CanQualType ExpectedResultType, CanQualType ExpectedSizeOrAddressParamType, unsigned DependentParamTypeDiag, unsigned InvalidParamTypeDiag)
static bool checkTrivialClassMembers(Sema &S, CXXRecordDecl *RD, CXXSpecialMemberKind CSM, bool ConstArg, TrivialABIHandling TAH, bool Diagnose)
Check whether the members of a class type allow a special member to be trivial.
static TemplateArgumentLoc getTrivialTypeTemplateArgument(Sema &S, SourceLocation Loc, QualType T)
static void findImplicitlyDeclaredEqualityComparisons(ASTContext &Ctx, CXXRecordDecl *RD, llvm::SmallVectorImpl< FunctionDecl * > &Spaceships)
Find the equality comparison functions that should be implicitly declared in a given class definition...
static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl< const void * > &IdealInits)
ImplicitInitializerKind
ImplicitInitializerKind - How an implicit base or member initializer should initialize its base or me...
static bool ConvertAPValueToString(const APValue &V, QualType T, SmallVectorImpl< char > &Str, ASTContext &Context)
Convert \V to a string we can present to the user in a diagnostic \T is the type of the expression th...
static bool checkArrayDecomposition(Sema &S, ArrayRef< BindingDecl * > Bindings, ValueDecl *Src, QualType DecompType, const ConstantArrayType *CAT)
static ClassTemplateDecl * LookupStdClassTemplate(Sema &S, SourceLocation Loc, const char *ClassName, bool *WasMalformed)
static void ReferenceDllExportedMembers(Sema &S, CXXRecordDecl *Class)
static bool UsefulToPrintExpr(const Expr *E)
Some Expression types are not useful to print notes about, e.g.
static bool FindBaseInitializer(Sema &SemaRef, CXXRecordDecl *ClassDecl, QualType BaseType, const CXXBaseSpecifier *&DirectBaseSpec, const CXXBaseSpecifier *&VirtualBaseSpec)
Find the direct and/or virtual base specifiers that correspond to the given base type,...
static bool checkLiteralOperatorTemplateParameterList(Sema &SemaRef, FunctionTemplateDecl *TpDecl)
static bool ReportOverrides(Sema &S, unsigned DiagID, const CXXMethodDecl *MD, llvm::function_ref< bool(const CXXMethodDecl *)> Report)
Report an error regarding overriding, along with any relevant overridden methods.
static bool CheckBindingsCount(Sema &S, DecompositionDecl *DD, QualType DecompType, ArrayRef< BindingDecl * > Bindings, unsigned MemberCount)
static bool CheckOperatorDeleteDeclaration(Sema &SemaRef, FunctionDecl *FnDecl)
static const void * GetKeyForMember(ASTContext &Context, CXXCtorInitializer *Member)
static std::string printTemplateArgs(const PrintingPolicy &PrintingPolicy, TemplateArgumentListInfo &Args, const TemplateParameterList *Params)
static bool CheckConstexprReturnType(Sema &SemaRef, const FunctionDecl *FD, Sema::CheckConstexprKind Kind)
Check whether a function's return type is a literal type.
static void DiagnoseBaseOrMemInitializerOrder(Sema &SemaRef, const CXXConstructorDecl *Constructor, ArrayRef< CXXCtorInitializer * > Inits)
static Sema::ImplicitExceptionSpecification computeImplicitExceptionSpec(Sema &S, SourceLocation Loc, FunctionDecl *FD)
static bool isIncompleteOrZeroLengthArrayType(ASTContext &Context, QualType T)
Determine whether the given type is an incomplete or zero-lenfgth array type.
static void MarkFieldDestructorReferenced(Sema &S, SourceLocation Location, FieldDecl *Field)
TrivialSubobjectKind
The kind of subobject we are checking for triviality.
@ TSK_CompleteObject
The object is actually the complete object.
@ TSK_Field
The subobject is a non-static data member.
@ TSK_BaseClass
The subobject is a base class.
static bool hasOneRealArgument(MultiExprArg Args)
Determine whether the given list arguments contains exactly one "real" (non-default) argument.
static StmtResult buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T, const ExprBuilder &ToB, const ExprBuilder &FromB)
When generating a defaulted copy or move assignment operator, if a field should be copied with __buil...
static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg, const char *ClassName, ClassTemplateDecl **CachedDecl, const Decl **MalformedDecl)
static void DefineDefaultedFunction(Sema &S, FunctionDecl *FD, SourceLocation DefaultLoc)
static bool BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor, ImplicitInitializerKind ImplicitInitKind, FieldDecl *Field, IndirectFieldDecl *Indirect, CXXCtorInitializer *&CXXMemberInit)
static void MarkBaseDestructorsReferenced(Sema &S, SourceLocation Location, CXXRecordDecl *ClassDecl)
static bool CheckMemberDecompositionFields(Sema &S, SourceLocation Loc, const CXXRecordDecl *OrigRD, QualType DecompType, DeclAccessPair BasePair)
static bool CollectFieldInitializer(Sema &SemaRef, BaseAndFieldInfo &Info, FieldDecl *Field, IndirectFieldDecl *Indirect=nullptr)
static CXXBaseSpecifier * findDirectBaseWithType(CXXRecordDecl *Derived, QualType DesiredBase, bool &AnyDependentBases)
Find the base specifier for a base class with the given type.
static Sema::SpecialMemberOverloadResult lookupCallFromSpecialMember(Sema &S, CXXRecordDecl *Class, CXXSpecialMemberKind CSM, unsigned FieldQuals, bool ConstRHS)
Look up the special member function that would be called by a special member function for a subobject...
static bool defaultedSpecialMemberIsConstexpr(Sema &S, CXXRecordDecl *ClassDecl, CXXSpecialMemberKind CSM, bool ConstArg, CXXConstructorDecl *InheritedCtor=nullptr, Sema::InheritedConstructorInfo *Inherited=nullptr)
Determine whether the specified special member function would be constexpr if it were implicitly defi...
static bool checkTrivialSubobjectCall(Sema &S, SourceLocation SubobjLoc, QualType SubType, bool ConstRHS, CXXSpecialMemberKind CSM, TrivialSubobjectKind Kind, TrivialABIHandling TAH, bool Diagnose)
Check whether the special member selected for a given type would be trivial.
static void DiagnoseInvisibleNamespace(const TypoCorrection &Corrected, Sema &S)
static StmtResult buildSingleCopyAssign(Sema &S, SourceLocation Loc, QualType T, const ExprBuilder &To, const ExprBuilder &From, bool CopyingBaseSubobject, bool Copying)
static FunctionProtoType::ExtProtoInfo getImplicitMethodEPI(Sema &S, CXXMethodDecl *MD)
static QualType getTupleLikeElementType(Sema &S, SourceLocation Loc, unsigned I, QualType T)
static Sema::ImplicitExceptionSpecification ComputeDefaultedSpecialMemberExceptionSpec(Sema &S, SourceLocation Loc, CXXMethodDecl *MD, CXXSpecialMemberKind CSM, Sema::InheritedConstructorInfo *ICI)
static QualType getStdTrait(Sema &S, SourceLocation Loc, StringRef Trait, TemplateArgumentListInfo &Args, unsigned DiagID)
static bool checkComplexDecomposition(Sema &S, ArrayRef< BindingDecl * > Bindings, ValueDecl *Src, QualType DecompType, const ComplexType *CT)
static bool TryNamespaceTypoCorrection(Sema &S, LookupResult &R, Scope *Sc, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident)
static bool InitializationHasSideEffects(const FieldDecl &FD)
static bool CheckOperatorNewDeleteDeclarationScope(Sema &SemaRef, const FunctionDecl *FnDecl)
static bool checkArrayLikeDecomposition(Sema &S, ArrayRef< BindingDecl * > Bindings, ValueDecl *Src, QualType DecompType, const llvm::APSInt &NumElems, QualType ElemType)
static bool CheckConstexprDeclStmt(Sema &SemaRef, const FunctionDecl *Dcl, DeclStmt *DS, SourceLocation &Cxx1yLoc, Sema::CheckConstexprKind Kind)
Check the given declaration statement is legal within a constexpr function body.
static bool IsEquivalentForUsingDecl(ASTContext &Context, NamedDecl *D1, NamedDecl *D2)
Determine whether a using declaration considers the given declarations as "equivalent",...
static TemplateArgumentLoc getTrivialIntegralTemplateArgument(Sema &S, SourceLocation Loc, QualType T, uint64_t I)
static bool CheckConstexprDestructorSubobjects(Sema &SemaRef, const CXXDestructorDecl *DD, Sema::CheckConstexprKind Kind)
Determine whether a destructor cannot be constexpr due to.
static bool isProvablyNotDerivedFrom(Sema &SemaRef, CXXRecordDecl *Record, const BaseSet &Bases)
Determines if the given class is provably not derived from all of the prospective base classes.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static ExprResult CheckConvertedConstantExpression(Sema &S, Expr *From, QualType T, APValue &Value, CCEKind CCE, bool RequireInt, NamedDecl *Dest)
CheckConvertedConstantExpression - Check that the expression From is a converted constant expression ...
static TemplateDeductionResult DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams, ArrayRef< TemplateArgument > Ps, ArrayRef< TemplateArgument > As, TemplateDeductionInfo &Info, SmallVectorImpl< DeducedTemplateArgument > &Deduced, bool NumberOfArgumentsMustMatch, bool PartialOrdering, PackFold PackFold, bool *HasDeducedAnyParam)
static void collectUnexpandedParameterPacks(Sema &S, TemplateParameterList *Params, SmallVectorImpl< UnexpandedParameterPack > &Unexpanded)
static bool DiagnoseUnexpandedParameterPacks(Sema &S, TemplateTemplateParmDecl *TTP)
Check for unexpanded parameter packs within the template parameters of a template template parameter,...
static bool isInvalid(LocType Loc, bool *Invalid)
Defines various enumerations that describe declaration and type specifiers.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
std::pair< CXXConstructorDecl *, bool > findConstructorForBase(CXXRecordDecl *Base, CXXConstructorDecl *Ctor) const
Find the constructor to use for inherited construction of a base class, and whether that base class c...
InheritedConstructorInfo(Sema &S, SourceLocation UseLoc, ConstructorUsingShadowDecl *Shadow)
a trap message and trap category.
APValue - This class implements a discriminated union of [uninitialized] [APSInt] [APFloat],...
virtual bool HandleTopLevelDecl(DeclGroupRef D)
HandleTopLevelDecl - Handle the specified top-level declaration.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
DeclarationNameTable DeclarationNames
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
const LangOptions & getLangOpts() const
QualType getConstType(QualType T) const
Return the uniqued reference to the type for a const qualified type.
CallingConv getDefaultCallingConvention(bool IsVariadic, bool IsCXXMethod) const
Retrieves the default calling convention for the current context.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
ComparisonCategories CompCategories
Types and expressions required to build C++2a three-way comparisons using operator<=>,...
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
const clang::PrintingPolicy & getPrintingPolicy() const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
QualType getTypeDeclType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier, const TypeDecl *Decl) const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
QualType getPackExpansionType(QualType Pattern, UnsignedOrNone NumExpansions, bool ExpectPackInType=true) const
Form a pack expansion type with the given pattern.
static bool hasSameType(QualType T1, QualType T2)
Determine whether the given types T1 and T2 are equivalent.
llvm::APSInt MakeIntValue(uint64_t Value, QualType Type) const
Make an APSInt of the appropriate width and signedness for the given Value and integer Type.
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
An abstract interface that should be implemented by listeners that want to be notified when an AST en...
Represents an access specifier followed by colon ':'.
static AccessSpecDecl * Create(ASTContext &C, AccessSpecifier AS, DeclContext *DC, SourceLocation ASLoc, SourceLocation ColonLoc)
TypeLoc getElementLoc() const
QualType getElementType() const
Attr - This represents one attribute.
attr::Kind getKind() const
Attr * clone(ASTContext &C) const
SourceLocation getLocation() const
Represents a C++ declaration that introduces decls from somewhere else.
unsigned shadow_size() const
Return the number of shadowed declarations associated with this using declaration.
void addShadowDecl(UsingShadowDecl *S)
shadow_iterator shadow_begin() const
void removeShadowDecl(UsingShadowDecl *S)
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
static bool isCompoundAssignmentOp(Opcode Opc)
static Opcode getOverloadedOpcode(OverloadedOperatorKind OO)
Retrieve the binary opcode that corresponds to the given overloaded operator.
A binding in a decomposition declaration.
static BindingDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T)
void setBinding(QualType DeclaredType, Expr *Binding)
Set the binding for this BindingDecl, along with its declared type (which should be a possibly-cv-qua...
void setDecomposedDecl(ValueDecl *Decomposed)
Set the decomposed variable for this BindingDecl.
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Wrapper for source info for block pointers.
This class is used for builtin types like 'int'.
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
DeclContext::lookup_iterator Decls
The declarations found inside this base class subobject.
AccessSpecifier Access
The access along this inheritance path.
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
const CXXRecordDecl * getOrigin() const
Retrieve the type from which this base-paths search began.
bool isRecordingPaths() const
Whether we are recording paths.
void setRecordingPaths(bool RP)
Specify whether we should be recording paths or not.
void setOrigin(const CXXRecordDecl *Rec)
void clear()
Clear the base-paths results.
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
Represents a base class of a C++ class.
SourceLocation getBeginLoc() const LLVM_READONLY
bool isVirtual() const
Determines whether the base class is a virtual base class (or not).
QualType getType() const
Retrieves the type of the base class.
SourceRange getSourceRange() const LLVM_READONLY
Retrieves the source range that contains the entire base specifier.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
A boolean literal, per ([C++ lex.bool] Boolean literals).
CXXCatchStmt - This represents a C++ catch block.
Represents a call to a C++ constructor.
static CXXConstructExpr * Create(const ASTContext &Ctx, QualType Ty, SourceLocation Loc, CXXConstructorDecl *Ctor, bool Elidable, ArrayRef< Expr * > Args, bool HadMultipleCandidates, bool ListInitialization, bool StdInitListInitialization, bool ZeroInitialization, CXXConstructionKind ConstructKind, SourceRange ParenOrBraceRange)
Create a C++ construction expression.
Expr * getArg(unsigned Arg)
Return the specified argument.
bool isImmediateEscalating() const
CXXConstructorDecl * getConstructor() const
Get the constructor that this expression will (ultimately) call.
Represents a C++ constructor within a class.
CXXConstructorDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isMoveConstructor(unsigned &TypeQuals) const
Determine whether this constructor is a move constructor (C++11 [class.copy]p3), which can be used to...
ExplicitSpecifier getExplicitSpecifier()
init_iterator init_begin()
Retrieve an iterator to the first initializer.
CXXConstructorDecl * getTargetConstructor() const
When this constructor delegates to another, retrieve the target.
bool isCopyConstructor(unsigned &TypeQuals) const
Whether this constructor is a copy constructor (C++ [class.copy]p2, which can be used to copy the cla...
bool isDefaultConstructor() const
Whether this constructor is a default constructor (C++ [class.ctor]p5), which can be used to default-...
InheritedConstructor getInheritedConstructor() const
Get the constructor that this inheriting constructor is based on.
static CXXConstructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, ExplicitSpecifier ES, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, InheritedConstructor Inherited=InheritedConstructor(), const AssociatedConstraint &TrailingRequiresClause={})
Represents a C++ conversion function within a class.
QualType getConversionType() const
Returns the type that this conversion function is converting to.
Represents a C++ base or member initializer.
bool isWritten() const
Determine whether this initializer is explicitly written in the source code.
SourceRange getSourceRange() const LLVM_READONLY
Determine the source range covering the entire initializer.
SourceLocation getSourceLocation() const
Determine the source location of the initializer.
bool isAnyMemberInitializer() const
TypeSourceInfo * getTypeSourceInfo() const
Returns the declarator information for a base class or delegating initializer.
FieldDecl * getAnyMember() const
Represents a C++ destructor within a class.
static CXXDestructorDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool UsesFPIntrin, bool isInline, bool isImplicitlyDeclared, ConstexprSpecKind ConstexprKind, const AssociatedConstraint &TrailingRequiresClause={})
A mapping from each virtual member function to its set of final overriders.
Represents a call to an inherited base class constructor from an inheriting constructor.
Represents a call to a member function that may be written either with member call syntax (e....
CXXMethodDecl * getMethodDecl() const
Retrieve the declaration of the called method.
Represents a static or instance method of a struct/union/class.
bool isExplicitObjectMemberFunction() const
[C++2b][dcl.fct]/p7 An explicit object member function is a non-static member function with an explic...
static CXXMethodDecl * Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin, bool isInline, ConstexprSpecKind ConstexprKind, SourceLocation EndLocation, const AssociatedConstraint &TrailingRequiresClause={})
unsigned getNumExplicitParams() const
CXXMethodDecl * getMostRecentDecl()
overridden_method_range overridden_methods() const
unsigned size_overridden_methods() const
method_iterator begin_overridden_methods() const
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
bool isMoveAssignmentOperator() const
Determine whether this is a move assignment operator.
QualType getFunctionObjectParameterType() const
CXXMethodDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
The null pointer literal (C++11 [lex.nullptr])
Represents a C++ struct/union/class.
bool hasConstexprDefaultConstructor() const
Determine whether this class has a constexpr default constructor.
friend_range friends() const
bool hasTrivialMoveAssignment() const
Determine whether this class has a trivial move assignment operator (C++11 [class....
bool isTriviallyCopyable() const
Determine whether this class is considered trivially copyable per (C++11 [class]p6).
bool hasTrivialDefaultConstructor() const
Determine whether this class has a trivial default constructor (C++11 [class.ctor]p5).
bool isGenericLambda() const
Determine whether this class describes a generic lambda function object (i.e.
bool hasTrivialDestructor() const
Determine whether this class has a trivial destructor (C++ [class.dtor]p3)
bool hasUserDeclaredDestructor() const
Determine whether this class has a user-declared destructor.
bool implicitCopyConstructorHasConstParam() const
Determine whether an implicit copy constructor for this type would have a parameter with a const-qual...
bool defaultedDestructorIsDeleted() const
true if a defaulted destructor for this class would be deleted.
bool hasInheritedAssignment() const
Determine whether this class has a using-declaration that names a base class assignment operator.
bool allowConstDefaultInit() const
Determine whether declaring a const variable with this type is ok per core issue 253.
bool hasTrivialDestructorForCall() const
bool defaultedMoveConstructorIsDeleted() const
true if a defaulted move constructor for this class would be deleted.
bool isLiteral() const
Determine whether this class is a literal type.
bool hasUserDeclaredMoveAssignment() const
Determine whether this class has had a move assignment declared by the user.
bool defaultedDestructorIsConstexpr() const
Determine whether a defaulted default constructor for this class would be constexpr.
bool hasAnyDependentBases() const
Determine whether this class has any dependent base classes which are not the current instantiation.
bool isLambda() const
Determine whether this class describes a lambda function object.
bool hasTrivialMoveConstructor() const
Determine whether this class has a trivial move constructor (C++11 [class.copy]p12)
bool needsImplicitDefaultConstructor() const
Determine if we need to declare a default constructor for this class.
bool needsImplicitMoveConstructor() const
Determine whether this class should get an implicit move constructor or if any existing special membe...
bool hasUserDeclaredCopyAssignment() const
Determine whether this class has a user-declared copy assignment operator.
bool isProvablyNotDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is provably not derived from the type Base.
method_range methods() const
CXXRecordDecl * getDefinition() const
bool needsOverloadResolutionForCopyAssignment() const
Determine whether we need to eagerly declare a defaulted copy assignment operator for this class.
static AccessSpecifier MergeAccess(AccessSpecifier PathAccess, AccessSpecifier DeclAccess)
Calculates the access of a decl that is reached along a path.
bool defaultedDefaultConstructorIsConstexpr() const
Determine whether a defaulted default constructor for this class would be constexpr.
bool hasTrivialCopyConstructor() const
Determine whether this class has a trivial copy constructor (C++ [class.copy]p6, C++11 [class....
void setImplicitMoveAssignmentIsDeleted()
Set that we attempted to declare an implicit move assignment operator, but overload resolution failed...
bool hasConstexprDestructor() const
Determine whether this class has a constexpr destructor.
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
unsigned getNumBases() const
Retrieves the number of base classes of this class.
bool defaultedCopyConstructorIsDeleted() const
true if a defaulted copy constructor for this class would be deleted.
bool hasTrivialCopyConstructorForCall() const
bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths, bool LookupInDependent=false) const
Look for entities within the base classes of this C++ class, transitively searching all base class su...
bool lambdaIsDefaultConstructibleAndAssignable() const
Determine whether this lambda should have an implicit default constructor and copy and move assignmen...
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
bool hasTrivialCopyAssignment() const
Determine whether this class has a trivial copy assignment operator (C++ [class.copy]p11,...
base_class_range vbases()
base_class_iterator vbases_begin()
void setImplicitMoveConstructorIsDeleted()
Set that we attempted to declare an implicit move constructor, but overload resolution failed so we d...
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool hasVariantMembers() const
Determine whether this class has any variant members.
void setImplicitCopyConstructorIsDeleted()
Set that we attempted to declare an implicit copy constructor, but overload resolution failed so we d...
bool isDynamicClass() const
bool hasInClassInitializer() const
Whether this class has any in-class initializers for non-static data members (including those in anon...
bool needsImplicitCopyConstructor() const
Determine whether this class needs an implicit copy constructor to be lazily declared.
bool hasIrrelevantDestructor() const
Determine whether this class has a destructor which has no semantic effect.
bool hasNonTrivialCopyConstructorForCall() const
bool hasDirectFields() const
Determine whether this class has direct non-static data members.
bool hasUserDeclaredCopyConstructor() const
Determine whether this class has a user-declared copy constructor.
bool hasDefinition() const
void setImplicitCopyAssignmentIsDeleted()
Set that we attempted to declare an implicit copy assignment operator, but overload resolution failed...
bool needsImplicitDestructor() const
Determine whether this class needs an implicit destructor to be lazily declared.
ClassTemplateDecl * getDescribedClassTemplate() const
Retrieves the class template that is described by this class declaration.
void getFinalOverriders(CXXFinalOverriderMap &FinaOverriders) const
Retrieve the final overriders for each virtual member function in the class hierarchy where this clas...
bool needsOverloadResolutionForMoveConstructor() const
Determine whether we need to eagerly declare a defaulted move constructor for this class.
bool isInjectedClassName() const
Determines whether this declaration represents the injected class name.
bool needsOverloadResolutionForMoveAssignment() const
Determine whether we need to eagerly declare a move assignment operator for this class.
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
bool hasNonTrivialDestructorForCall() const
bool needsOverloadResolutionForDestructor() const
Determine whether we need to eagerly declare a destructor for this class.
bool hasInheritedConstructor() const
Determine whether this class has a using-declaration that names a user-declared base class constructo...
CXXMethodDecl * getLambdaStaticInvoker() const
Retrieve the lambda static invoker, the address of which is returned by the conversion operator,...
bool needsOverloadResolutionForCopyConstructor() const
Determine whether we need to eagerly declare a defaulted copy constructor for this class.
CXXRecordDecl * getDefinitionOrSelf() const
bool hasUserDeclaredMoveConstructor() const
Determine whether this class has had a move constructor declared by the user.
bool needsImplicitMoveAssignment() const
Determine whether this class should get an implicit move assignment operator or if any existing speci...
bool needsImplicitCopyAssignment() const
Determine whether this class needs an implicit copy assignment operator to be lazily declared.
bool hasTrivialMoveConstructorForCall() const
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
CXXRecordDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
bool isDerivedFrom(const CXXRecordDecl *Base) const
Determine whether this class is derived from the class Base.
bool implicitCopyAssignmentHasConstParam() const
Determine whether an implicit copy assignment operator for this type would have a parameter with a co...
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
bool isValid() const
A scope specifier is present, and it refers to a real scope.
void MakeTrivial(ASTContext &Context, NestedNameSpecifier Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
SourceRange getRange() const
SourceLocation getBeginLoc() const
bool isSet() const
Deprecated.
NestedNameSpecifier getScopeRep() const
Retrieve the representation of the nested-name-specifier.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
bool isEmpty() const
No scope specifier.
Represents the this expression in C++.
SourceLocation getBeginLoc() const
SourceLocation getLocation() const
CXXTryStmt - A C++ try block, including all handlers.
CXXCatchStmt * getHandler(unsigned i)
unsigned getNumHandlers() const
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
FunctionDecl * getDirectCallee()
If the callee is a FunctionDecl, return it. Otherwise return null.
bool isCallToStdMove() const
QualType withConst() const
Retrieves a version of this type with const applied.
CastKind getCastKind() const
static CharSourceRange getTokenRange(SourceRange R)
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Declaration of a class template.
CXXRecordDecl * getTemplatedDecl() const
Get the underlying class declarations of the template.
Represents a class template specialization, which refers to a class template with a given set of temp...
TemplateSpecializationKind getSpecializationKind() const
Determine the kind of specialization that this declaration represents.
ClassTemplateDecl * getSpecializedTemplate() const
Retrieve the template that this specialization specializes.
SourceLocation getPointOfInstantiation() const
Get the point of instantiation (if any), or null if none.
bool isExplicitSpecialization() const
const ComparisonCategoryInfo * lookupInfoForType(QualType Ty) const
static StringRef getCategoryString(ComparisonCategoryType Kind)
static StringRef getResultString(ComparisonCategoryResult Kind)
static std::vector< ComparisonCategoryResult > getPossibleResultsForType(ComparisonCategoryType Type)
Return the list of results which are valid for the specified comparison category type.
const CXXRecordDecl * Record
The declaration for the comparison category type from the standard library.
ComparisonCategoryType Kind
The Kind of the comparison category type.
Complex values, per C99 6.2.5p11.
QualType getElementType() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
ConstStmtVisitor - This class implements a simple visitor for Stmt subclasses.
Represents the canonical version of C arrays with a specified constant size.
llvm::APInt getSize() const
Return the constant array size as an APInt.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Represents a shadow constructor declaration introduced into a class by a C++11 using-declaration that...
const CXXRecordDecl * getParent() const
Returns the parent of this using shadow declaration, which is the class in which this is declared.
static ConstructorUsingShadowDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, UsingDecl *Using, NamedDecl *Target, bool IsVirtual)
Base class for callback objects used by Sema::CorrectTypo to check the validity of a potential typo c...
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
NamedDecl * getDecl() const
AccessSpecifier getAccess() const
The results of name lookup within a DeclContext.
DeclListNode::iterator iterator
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext,...
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool Equals(const DeclContext *DC) const
Determine whether this declaration context is equivalent to the declaration context DC.
lookup_result::iterator lookup_iterator
bool isFileContext() const
void makeDeclVisibleInContext(NamedDecl *D)
Makes a declaration visible within this context.
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
bool InEnclosingNamespaceSetOf(const DeclContext *NS) const
Test if this context is part of the enclosing namespace set of the context NS, as defined in C++0x [n...
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
bool isTranslationUnit() const
DeclContext * getRedeclContext()
getRedeclContext - Retrieve the context in which an entity conflicts with other entities of the same ...
void removeDecl(Decl *D)
Removes a declaration from this context.
void addDecl(Decl *D)
Add the declaration D into this context.
decl_iterator decls_end() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
bool isFunctionOrMethod() const
const LinkageSpecDecl * getExternCContext() const
Retrieve the nearest enclosing C linkage specification context.
bool Encloses(const DeclContext *DC) const
Determine whether this declaration context semantically encloses the declaration context DC.
Decl::Kind getDeclKind() const
DeclContext * getNonTransparentContext()
decl_iterator decls_begin() const
A reference to a declared variable, function, enum, etc.
static DeclRefExpr * Create(const ASTContext &Context, NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKWLoc, ValueDecl *D, bool RefersToEnclosingVariableOrCapture, SourceLocation NameLoc, QualType T, ExprValueKind VK, NamedDecl *FoundD=nullptr, const TemplateArgumentListInfo *TemplateArgs=nullptr, NonOdrUseReason NOUR=NOUR_None)
NonOdrUseReason isNonOdrUse() const
Is this expression a non-odr-use reference, and if so, why?
SourceLocation getBeginLoc() const
bool isImmediateEscalating() const
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool isModulePrivateSpecified() const
bool hasTypeSpecifier() const
Return true if any type-specifier has been found.
bool SetStorageClassSpec(Sema &S, SCS SC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec and return false if there was no error.
ThreadStorageClassSpecifier TSCS
Expr * getPackIndexingExpr() const
void ClearStorageClassSpecs()
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
SourceLocation getBeginLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
SourceLocation getExplicitSpecLoc() const
SourceLocation getFriendSpecLoc() const
ParsedType getRepAsType() const
TSCS getThreadStorageClassSpec() const
bool isFriendSpecifiedFirst() const
ParsedAttributes & getAttributes()
SourceLocation getEllipsisLoc() const
SourceLocation getConstSpecLoc() const
SourceRange getExplicitSpecRange() const
Expr * getRepAsExpr() const
bool isInlineSpecified() const
SourceLocation getRestrictSpecLoc() const
bool SetTypeQual(TQ T, SourceLocation Loc)
void ClearConstexprSpec()
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
SourceLocation getThreadStorageClassSpecLoc() const
SourceLocation getAtomicSpecLoc() const
SourceLocation getVirtualSpecLoc() const
SourceLocation getConstexprSpecLoc() const
SourceLocation getTypeSpecTypeLoc() const
void forEachQualifier(llvm::function_ref< void(TQ, StringRef, SourceLocation)> Handle)
This method calls the passed in handler on each qual being set.
SourceLocation getInlineSpecLoc() const
SourceLocation getUnalignedSpecLoc() const
SourceLocation getVolatileSpecLoc() const
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool hasConstexprSpecifier() const
static const TST TST_auto
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
SourceLocation getBeginLoc() const LLVM_READONLY
Decl - This represents one declaration (or definition), e.g.
Decl * getPreviousDecl()
Retrieve the previous declaration that declares the same entity as this declaration,...
bool isInStdNamespace() const
SourceLocation getEndLoc() const LLVM_READONLY
FriendObjectKind getFriendObjectKind() const
Determines whether this declaration is the object of a friend declaration and, if so,...
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
virtual bool isOutOfLine() const
Determine whether this declaration is declared out of line (outside its semantic context).
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
Kind
Lists the kind of concrete classes of Decl.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
@ FOK_Undeclared
A friend of a previously-undeclared entity.
@ FOK_None
Not a friend object.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool isTemplateParameter() const
isTemplateParameter - Determines whether this declaration is a template parameter.
DeclContext * getNonTransparentDeclContext()
Return the non transparent context.
bool isInvalidDecl() const
unsigned getIdentifierNamespace() const
bool isLocalExternDecl() const
Determine whether this is a block-scope declaration with linkage.
void setAccess(AccessSpecifier AS)
SourceLocation getLocation() const
@ IDNS_Ordinary
Ordinary names.
bool isTemplateParameterPack() const
isTemplateParameter - Determines whether this declaration is a template parameter pack.
void setLocalOwningModule(Module *M)
void setImplicit(bool I=true)
void setReferenced(bool R=true)
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
DeclContext * getDeclContext()
AccessSpecifier getAccess() const
SourceLocation getBeginLoc() const LLVM_READONLY
DeclContext * getLexicalDeclContext()
getLexicalDeclContext - The declaration context where this Decl was lexically declared (LexicalDC).
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
@ VisibleWhenImported
This declaration has an owning module, and is visible when that module is imported.
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
The name of a declaration.
IdentifierInfo * getAsIdentifierInfo() const
Retrieve the IdentifierInfo * stored in this declaration name, or null if this declaration name isn't...
bool isAnyOperatorNewOrDelete() const
std::string getAsString() const
Retrieve the human-readable string for this name.
const IdentifierInfo * getCXXLiteralIdentifier() const
If this name is the name of a literal operator, retrieve the identifier associated with it.
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
@ CXXConversionFunctionName
NameKind getNameKind() const
Determine what kind of name this is.
bool isIdentifier() const
Predicate functions for querying what type of name this is.
Represents a ValueDecl that came out of a declarator.
SourceLocation getTypeSpecStartLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
unsigned getNumTemplateParameterLists() const
void setTypeSourceInfo(TypeSourceInfo *TI)
TypeSourceInfo * getTypeSourceInfo() const
Information about one declarator, including the parsed type information and the identifier.
bool isFunctionDeclarator(unsigned &idx) const
isFunctionDeclarator - This method returns true if the declarator is a function declarator (looking t...
bool isDeclarationOfFunction() const
Determine whether the declaration that will be produced from this declaration will be a function.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
bool isFunctionDeclarationContext() const
Return true if this declaration appears in a context where a function declarator would be a function ...
SourceLocation getIdentifierLoc() const
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
SourceLocation getEndLoc() const LLVM_READONLY
type_object_range type_objects() const
Returns the range of type objects, from the identifier outwards.
bool hasGroupingParens() const
void setInvalidType(bool Val=true)
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool isRedeclaration() const
DeclaratorContext getContext() const
const DecompositionDeclarator & getDecompositionDeclarator() const
SourceLocation getBeginLoc() const LLVM_READONLY
bool isFunctionDefinition() const
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
const CXXScopeSpec & getCXXScopeSpec() const
getCXXScopeSpec - Return the C++ scope specifier (global scope or nested-name-specifier) that is part...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
void setInventedTemplateParameterList(TemplateParameterList *Invented)
Sets the template parameter list generated from the explicit template parameters along with any inven...
bool mayHaveDecompositionDeclarator() const
Return true if the context permits a C++17 decomposition declarator.
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
bool isDecompositionDeclarator() const
Return whether this declarator is a decomposition declarator.
bool isStaticMember()
Returns true if this declares a static member.
DeclSpec & getMutableDeclSpec()
getMutableDeclSpec - Return a non-const version of the DeclSpec.
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
const IdentifierInfo * getIdentifier() const
A decomposition declaration.
ArrayRef< BindingDecl * > bindings() const
A parsed C++17 decomposition declarator of the form '[' identifier-list ']'.
ArrayRef< Binding > bindings() const
SourceRange getSourceRange() const
SourceLocation getLSquareLoc() const
void setNameLoc(SourceLocation Loc)
void setElaboratedKeywordLoc(SourceLocation Loc)
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc)
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
virtual bool TraverseConstructorInitializer(MaybeConst< CXXCtorInitializer > *Init)
static EmptyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L)
RAII object that enters a new expression evaluation context.
An instance of this object exists for each enum constant that is defined.
enumerator_range enumerators() const
EvaluatedExprVisitor - This class visits 'Expr *'s.
Store information needed for an explicit specifier.
const Expr * getExpr() const
void setKind(ExplicitSpecKind Kind)
This represents one expression.
static bool isPotentialConstantExpr(const FunctionDecl *FD, SmallVectorImpl< PartialDiagnosticAt > &Diags)
isPotentialConstantExpr - Return true if this function's definition might be usable in a constant exp...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreImplicit() LLVM_READONLY
Skip past any implicit AST nodes which might surround this expression until reaching a fixed point.
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
bool EvaluateAsRValue(EvalResult &Result, const ASTContext &Ctx, bool InConstantContext=false) const
EvaluateAsRValue - Return true if this is a constant which we can fold to an rvalue using any crazy t...
bool isTemporaryObject(ASTContext &Ctx, const CXXRecordDecl *TempTy) const
Determine whether the result of this expression is a temporary object of the given class type.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
Represents difference between two FPOptions values.
Represents a member of a struct/union/class.
bool isMutable() const
Determines whether this field is mutable (C++ only).
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
bool hasInClassInitializer() const
Determine whether this member has a C++11 default member initializer.
bool isAnonymousStructOrUnion() const
Determines whether this field is a representative for an anonymous struct or union.
InClassInitStyle getInClassInitStyle() const
Get the kind of (C++11) default member initializer that this field has.
void setInClassInitializer(Expr *NewInit)
Set the C++11 in-class initializer for this member.
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
FieldDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
bool isUnnamedBitField() const
Determines whether this is an unnamed bitfield.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
static FixItHint CreateInsertionFromRange(SourceLocation InsertionLoc, CharSourceRange FromRange, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code from FromRange at a specific location.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
static FriendDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, FriendUnion Friend_, SourceLocation FriendL, SourceLocation EllipsisLoc={}, ArrayRef< TemplateParameterList * > FriendTypeTPLists={})
void setUnsupportedFriend(bool Unsupported)
static FriendTemplateDecl * Create(ASTContext &Context, DeclContext *DC, SourceLocation Loc, MutableArrayRef< TemplateParameterList * > Params, FriendUnion Friend, SourceLocation FriendLoc)
static DefaultedOrDeletedFunctionInfo * Create(ASTContext &Context, ArrayRef< DeclAccessPair > Lookups, StringLiteral *DeletedMessage=nullptr)
Represents a function declaration or definition.
static constexpr unsigned RequiredTypeAwareDeleteParameterCount
Count of mandatory parameters for type aware operator delete.
const ParmVarDecl * getParamDecl(unsigned i) const
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
ExceptionSpecificationType getExceptionSpecType() const
Gets the ExceptionSpecificationType as declared.
bool isTrivialForCall() const
ConstexprSpecKind getConstexprKind() const
DefaultedOrDeletedFunctionInfo * getDefaultedOrDeletedInfo() const
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to call this function.
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isImmediateFunction() const
void setDefaultedOrDeletedInfo(DefaultedOrDeletedFunctionInfo *Info)
SourceRange getReturnTypeSourceRange() const
Attempt to compute an informative source range covering the function return type.
bool isDestroyingOperatorDelete() const
Determine whether this is a destroying operator delete.
bool hasCXXExplicitFunctionObjectParameter() const
bool isInlined() const
Determine whether this function should be inlined, because it is either marked "inline" or "constexpr...
SourceLocation getDefaultLoc() const
QualType getReturnType() const
ArrayRef< ParmVarDecl * > parameters() const
bool isExplicitlyDefaulted() const
Whether this function is explicitly defaulted.
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
MutableArrayRef< ParmVarDecl * >::iterator param_iterator
FunctionDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
param_iterator param_begin()
const ParmVarDecl * getNonObjectParameter(unsigned I) const
bool isVariadic() const
Whether this function is variadic.
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
bool isDeleted() const
Whether this function has been deleted.
void setBodyContainsImmediateEscalatingExpressions(bool Set)
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
FunctionEffectsRef getFunctionEffects() const
bool isTemplateInstantiation() const
Determines if the given function was instantiated from a function template.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
TemplatedKind getTemplatedKind() const
What kind of templated function this is.
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
static constexpr unsigned RequiredTypeAwareNewParameterCount
Count of mandatory parameters for type aware operator new.
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
bool isExternC() const
Determines whether this function is a function with external, C linkage.
FunctionDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
bool isImmediateEscalating() const
void setIsDestroyingOperatorDelete(bool IsDestroyingDelete)
bool isTypeAwareOperatorNewOrDelete() const
Determine whether this is a type aware operator new or delete.
void setIsTypeAwareOperatorNewOrDelete(bool IsTypeAwareOperator=true)
bool isDefaulted() const
Whether this function is defaulted.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
void setConstexprKind(ConstexprSpecKind CSK)
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine what kind of template instantiation this function represents.
void setDefaulted(bool D=true)
bool isUserProvided() const
True if this method is user-declared and was not deleted or defaulted on its first declaration.
QualType getDeclaredReturnType() const
Get the declared return type, which may differ from the actual return type if the return type is dedu...
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
bool hasOneParamOrDefaultArgs() const
Determine whether this function has a single parameter, or multiple parameters where all but the firs...
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
size_t param_size() const
DeclarationNameInfo getNameInfo() const
bool hasBody(const FunctionDecl *&Definition) const
Returns true if the function has a body.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
FunctionDecl * getPreviousDecl()
Return the previous declaration of this declaration or NULL if this is the first declaration.
void setParams(ArrayRef< ParmVarDecl * > NewParamInfo)
bool willHaveBody() const
True if this function will eventually have a body, once it's fully parsed.
A mutable set of FunctionEffects and possibly conditions attached to them.
bool insert(const FunctionEffectWithCondition &NewEC, Conflicts &Errs)
SmallVector< Conflict > Conflicts
An immutable set of FunctionEffects and possibly conditions attached to them.
static FunctionParmPackExpr * Create(const ASTContext &Context, QualType T, ValueDecl *ParamPack, SourceLocation NameLoc, ArrayRef< ValueDecl * > Params)
Represents a prototype with parameter type info, e.g.
ExtParameterInfo getExtParameterInfo(unsigned I) const
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
unsigned getNumParams() const
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
const QualType * param_type_iterator
QualType getParamType(unsigned i) const
bool isVariadic() const
Whether this function prototype is variadic.
ExtProtoInfo getExtProtoInfo() const
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
ArrayRef< QualType > getParamTypes() const
ArrayRef< QualType > exceptions() const
bool hasExtParameterInfos() const
Is there any interesting extra information for any of the parameters of this function type?
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Wrapper for source info for functions.
unsigned getNumParams() const
ParmVarDecl * getParam(unsigned i) const
void setParam(unsigned i, ParmVarDecl *VD)
TypeLoc getReturnLoc() const
ExtInfo withCallingConv(CallingConv cc) const
FunctionType - C99 6.7.5.3 - Function Declarators.
CallingConv getCallConv() const
QualType getReturnType() const
One of these records is kept for each identifier that is lexed.
unsigned getLength() const
Efficiently return the length of this identifier info.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
ReservedLiteralSuffixIdStatus isReservedLiteralSuffixId() const
Determine whether this is a name reserved for future standardization or the implementation (C++ [usrl...
bool isPlaceholder() const
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
IfStmt - This represents an if/then/else.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Represents an implicitly-generated value initialization of an object of a given type.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
void setInherited(bool I)
Description of a constructor that was inherited from a base class.
ConstructorUsingShadowDecl * getShadowDecl() const
const TypeClass * getTypePtr() const
Describes an C or C++ initializer list.
unsigned getNumInits() const
const Expr * getInit(unsigned Init) const
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDefault(SourceLocation InitLoc)
Create a default initialization.
static InitializationKind CreateDirect(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a direct initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
static InitializationKind CreateDirectList(SourceLocation InitLoc)
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
Describes an entity that is being initialized.
static InitializedEntity InitializeBase(ASTContext &Context, const CXXBaseSpecifier *Base, bool IsInheritedVirtualBase, const InitializedEntity *Parent=nullptr)
Create the initialization entity for a base class subobject.
static InitializedEntity InitializeMember(FieldDecl *Member, const InitializedEntity *Parent=nullptr, bool Implicit=false)
Create the initialization entity for a member subobject.
static InitializedEntity InitializeBinding(VarDecl *Binding)
Create the initialization entity for a structured binding.
static InitializedEntity InitializeMemberFromDefaultMemberInitializer(FieldDecl *Member)
Create the initialization entity for a default member initializer.
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static InitializedEntity InitializeDelegation(QualType Type)
Create the initialization entity for a delegated constructor.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
An lvalue reference type, per C++11 [dcl.ref].
bool isInitCapture(const LambdaCapture *Capture) const
Determine whether one of this lambda's captures is an init-capture.
capture_range captures() const
Retrieve this lambda's captures.
@ Default
Use default layout rules of the target.
static StringRef getSourceText(CharSourceRange Range, const SourceManager &SM, const LangOptions &LangOpts, bool *Invalid=nullptr)
Returns a string for the source that the range encompasses.
Represents a linkage specification.
static LinkageSpecDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation ExternLoc, SourceLocation LangLoc, LinkageSpecLanguageIDs Lang, bool HasBraces)
void setRBraceLoc(SourceLocation L)
A class for iterating through a result set and possibly filtering out results.
void erase()
Erase the last element returned from this iterator.
Represents the results of name lookup.
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
void addDecl(NamedDecl *D)
Add a declaration to these results with its natural access.
bool empty() const
Return true if no decls were found.
void resolveKind()
Resolves the result kind of the lookup, possibly hiding decls.
SourceLocation getNameLoc() const
Gets the location of the identifier.
Filter makeFilter()
Create a filter for this result set.
NamedDecl * getFoundDecl() const
Fetch the unique decl found by this lookup.
bool isSingleResult() const
Determines if this names a single result which is not an unresolved value using decl.
UnresolvedSetImpl::iterator iterator
NamedDecl * getRepresentativeDecl() const
Fetches a representative decl. Useful for lazy diagnostics.
static bool isVisible(Sema &SemaRef, NamedDecl *D)
Determine whether the given declaration is visible to the program.
An instance of this class represents the declaration of a property member.
static MSPropertyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName N, QualType T, TypeSourceInfo *TInfo, SourceLocation StartL, IdentifierInfo *Getter, IdentifierInfo *Setter)
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
SourceLocation getExprLoc() const LLVM_READONLY
Wrapper for source info for member pointers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
Describes a module or submodule.
StringRef getTopLevelModuleName() const
Retrieve the name of the top-level module.
bool isExplicitGlobalModule() const
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
bool isPlaceholderVar(const LangOptions &LangOpts) const
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
void setModulePrivate()
Specify that this declaration was marked as being private to the module in which it was defined.
Represents a C++ namespace alias.
static NamespaceAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamespaceBaseDecl *Namespace)
Represents C++ namespaces and their aliases.
NamespaceDecl * getNamespace()
Represent a C++ namespace.
bool isInline() const
Returns true if this is an inline namespace declaration.
static NamespaceDecl * Create(ASTContext &C, DeclContext *DC, bool Inline, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, NamespaceDecl *PrevDecl, bool Nested)
NamespaceDecl * getAnonymousNamespace() const
Retrieve the anonymous namespace that inhabits this namespace, if any.
void setRBraceLoc(SourceLocation L)
Class that aids in the construction of nested-name-specifiers along with source-location information ...
void MakeTrivial(ASTContext &Context, NestedNameSpecifier Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
A C++ nested-name-specifier augmented with source location information.
SourceRange getSourceRange() const LLVM_READONLY
Retrieve the source range covering the entirety of this nested-name-specifier.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
NestedNameSpecifier getCanonical() const
Retrieves the "canonical" nested name specifier for a given nested name specifier.
bool containsUnexpandedParameterPack() const
Whether this nested-name-specifier contains an unexpanded parameter pack (for C++11 variadic template...
bool isDependent() const
Whether this nested name specifier refers to a dependent type or not.
const Type * getAsType() const
@ Global
The global specifier '::'. There is no stored value.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
The basic abstraction for the target Objective-C runtime.
bool isFragile() const
The inverse of isNonFragile(): does this runtime follow the set of implied behaviors for a "fragile" ...
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
@ CSK_Normal
Normal lookup.
@ CSK_Operator
C++ [over.match.oper]: Lookup of operator function candidates in a call using operator syntax.
SmallVectorImpl< OverloadCandidate >::iterator iterator
A single parameter index whose accessors require each use to make explicit the parameter index encodi...
static ParenListExpr * Create(const ASTContext &Ctx, SourceLocation LParenLoc, ArrayRef< Expr * > Exprs, SourceLocation RParenLoc)
Create a paren list.
Represents a parameter to a function.
void setDefaultArg(Expr *defarg)
void setUnparsedDefaultArg()
Specify that this parameter has an unparsed default argument.
bool hasUnparsedDefaultArg() const
Determines whether this parameter has a default argument that has not yet been parsed.
SourceRange getDefaultArgRange() const
Retrieve the source range that covers the entire default argument.
void setUninstantiatedDefaultArg(Expr *arg)
void setScopeInfo(unsigned scopeDepth, unsigned parameterIndex)
bool hasUninstantiatedDefaultArg() const
bool hasInheritedDefaultArg() const
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
Expr * getUninstantiatedDefaultArg()
bool hasDefaultArg() const
Determines whether this parameter has a default argument, either parsed or not.
void setHasInheritedDefaultArg(bool I=true)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
ParsedAttr - Represents a syntactic attribute.
IdentifierInfo * getPropertyDataSetter() const
IdentifierInfo * getPropertyDataGetter() const
static const ParsedAttributesView & none()
const ParsedAttr * getMSPropertyAttr() const
bool hasAttribute(ParsedAttr::Kind K) const
bool isAddressDiscriminated() const
Wrapper for source info for pointers.
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
IdentifierInfo * getIdentifierInfo(StringRef Name) const
Return information about the specified preprocessor identifier token.
IdentifierTable & getIdentifierTable()
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool hasAddressDiscriminatedPointerAuth() const
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
bool hasQualifiers() const
Determine whether this type has any qualifiers.
PointerAuthQualifier getPointerAuth() const
QualType getLocalUnqualifiedType() const
Return this type with all of the instance-specific qualifiers removed, but without removing any quali...
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
unsigned getLocalCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers local to this particular QualType instan...
bool isConstQualified() const
Determine whether this type is const-qualified.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool hasNonTrivialObjCLifetime() const
bool isPODType(const ASTContext &Context) const
Determine whether this is a Plain Old Data (POD) type (C++ 3.9p10).
bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
Represents a template name as written in source code.
The collection of all-type qualifiers we support.
void removeCVRQualifiers(unsigned mask)
void addAddressSpace(LangAS space)
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
@ OCL_Weak
Reading or writing from this object requires a barrier call.
void removeAddressSpace()
LangAS getAddressSpace() const
void setObjCLifetime(ObjCLifetime type)
An rvalue reference type, per C++11 [dcl.ref].
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
bool hasObjectMember() const
field_iterator field_end() const
field_range fields() const
specific_decl_iterator< FieldDecl > field_iterator
RecordDecl * getDefinitionOrSelf() const
bool isAnonymousStructOrUnion() const
Whether this is an anonymous struct or union.
field_iterator field_begin() const
RedeclarableTemplateDecl * getMostRecentDecl()
Returns the most recent (re)declaration of this declaration.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
void setPreviousDecl(decl_type *PrevDecl)
Set the previous declaration.
Base for LValueReferenceType and RValueReferenceType.
QualType getPointeeType() const
Scope - A scope is a transient data structure that is used while parsing the program.
void setEntity(DeclContext *E)
const Scope * getFnParent() const
getFnParent - Return the closest scope that is a function body.
unsigned getFlags() const
getFlags - Return the flags for this scope.
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
DeclContext * getEntity() const
Get the entity corresponding to this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
@ DeclScope
This is a scope that can contain a declaration.
void PushUsingDirective(UsingDirectiveDecl *UDir)
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
Emit a compatibility diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
A RAII object to enter scope of a compound statement.
For a defaulted function, the kind of defaulted function that it is.
DefaultedComparisonKind asComparison() const
bool isSpecialMember() const
bool isComparison() const
CXXSpecialMemberKind asSpecialMember() const
Helper class that collects exception specifications for implicitly-declared special member functions.
void CalledStmt(Stmt *S)
Integrate an invoked statement into the collected data.
void CalledExpr(Expr *E)
Integrate an invoked expression into the collected data.
void CalledDecl(SourceLocation CallLoc, const CXXMethodDecl *Method)
Integrate another called method into the collected data.
SpecialMemberOverloadResult - The overloading result for a special member function.
CXXMethodDecl * getMethod() const
RAII object to handle the state changes required to synthesize a function body.
Abstract base class used for diagnosing integer constant expression violations.
Sema - This implements semantic analysis and AST building for C.
void DefineImplicitLambdaToFunctionPointerConversion(SourceLocation CurrentLoc, CXXConversionDecl *Conv)
Define the "body" of the conversion from a lambda object to a function pointer.
QualType SubstAutoType(QualType TypeWithAuto, QualType Replacement)
Substitute Replacement for auto in TypeWithAuto.
CXXConstructorDecl * DeclareImplicitDefaultConstructor(CXXRecordDecl *ClassDecl)
Declare the implicit default constructor for the given class.
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S)
MergeCXXFunctionDecl - Merge two declarations of the same C++ function, once we already know that the...
Attr * getImplicitCodeSegOrSectionAttrForFunction(const FunctionDecl *FD, bool IsDefinition)
Returns an implicit CodeSegAttr if a __declspec(code_seg) is found on a containing class.
MemInitResult BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init, CXXRecordDecl *ClassDecl)
void CheckTypedefForVariablyModifiedType(Scope *S, TypedefNameDecl *D)
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
bool CheckSpecifiedExceptionType(QualType &T, SourceRange Range)
CheckSpecifiedExceptionType - Check if the given type is valid in an exception specification.
ExprResult BuildBlockForLambdaConversion(SourceLocation CurrentLocation, SourceLocation ConvLocation, CXXConversionDecl *Conv, Expr *Src)
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Decl * ActOnAliasDeclaration(Scope *CurScope, AccessSpecifier AS, MultiTemplateParamsArg TemplateParams, SourceLocation UsingLoc, UnqualifiedId &Name, const ParsedAttributesView &AttrList, TypeResult Type, Decl *DeclFromDeclSpec)
TemplateArgumentLoc getTrivialTemplateArgumentLoc(const TemplateArgument &Arg, QualType NTTPType, SourceLocation Loc, NamedDecl *TemplateParam=nullptr)
Allocate a TemplateArgumentLoc where all locations have been initialized to the given location.
NamedDecl * ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists, bool &AddToScope)
void DiagnoseAbstractType(const CXXRecordDecl *RD)
void HideUsingShadowDecl(Scope *S, UsingShadowDecl *Shadow)
Hides a using shadow declaration.
bool CheckUsingDeclQualifier(SourceLocation UsingLoc, bool HasTypename, const CXXScopeSpec &SS, const DeclarationNameInfo &NameInfo, SourceLocation NameLoc, const LookupResult *R=nullptr, const UsingDecl *UD=nullptr)
Checks that the given nested-name qualifier used in a using decl in the current context is appropriat...
bool CheckExplicitObjectOverride(CXXMethodDecl *New, const CXXMethodDecl *Old)
llvm::SmallPtrSet< SpecialMemberDecl, 4 > SpecialMembersBeingDeclared
The C++ special members which we are currently in the process of declaring.
void ActOnParamUnparsedDefaultArgument(Decl *param, SourceLocation EqualLoc, SourceLocation ArgLoc)
ActOnParamUnparsedDefaultArgument - We've seen a default argument for a function parameter,...
DefaultedFunctionKind getDefaultedFunctionKind(const FunctionDecl *FD)
Determine the kind of defaulting that would be done for a given function.
ExprResult BuildMemberReferenceExpr(Expr *Base, QualType BaseType, SourceLocation OpLoc, bool IsArrow, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, NamedDecl *FirstQualifierInScope, const DeclarationNameInfo &NameInfo, const TemplateArgumentListInfo *TemplateArgs, const Scope *S, ActOnMemberAccessExtraArgs *ExtraArgs=nullptr)
bool isDeclInScope(NamedDecl *D, DeclContext *Ctx, Scope *S=nullptr, bool AllowInlineNamespace=false) const
isDeclInScope - If 'Ctx' is a function/method, isDeclInScope returns true if 'D' is in Scope 'S',...
bool IsOverload(FunctionDecl *New, FunctionDecl *Old, bool UseMemberUsingDeclRules, bool ConsiderCudaAttrs=true)
ExprResult CreateBuiltinUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *InputExpr, bool IsAfterAmp=false)
void BuildBasePathArray(const CXXBasePaths &Paths, CXXCastPath &BasePath)
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old)
Merge the exception specifications of two variable declarations.
CXXSpecialMemberKind getSpecialMember(const CXXMethodDecl *MD)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupUsingDeclName
Look up all declarations in a scope with the given name, including resolved using declarations.
@ LookupLocalFriendName
Look up a friend of a local class.
@ LookupNamespaceName
Look up a namespace name within a C++ using directive or namespace alias definition,...
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
void DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc, ArrayRef< Expr * > Args)
DiagnoseSentinelCalls - This routine checks whether a call or message-send is to a declaration with t...
void DiagnoseFunctionSpecifiers(const DeclSpec &DS)
Diagnose function specifiers on a declaration of an identifier that does not identify a function.
Decl * BuildStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *AssertMessageExpr, SourceLocation RParenLoc, bool Failed)
void EvaluateImplicitExceptionSpec(SourceLocation Loc, FunctionDecl *FD)
Evaluate the implicit exception specification for a defaulted special member function.
void PrintContextStack(InstantiationContextDiagFuncRef DiagFunc)
ExplicitSpecifier ActOnExplicitBoolSpecifier(Expr *E)
ActOnExplicitBoolSpecifier - Build an ExplicitSpecifier from an expression found in an explicit(bool)...
bool DiagRedefinedPlaceholderFieldDecl(SourceLocation Loc, RecordDecl *ClassDecl, const IdentifierInfo *Name)
void ActOnFinishCXXNonNestedClass()
MemInitResult BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo, Expr *Init, CXXRecordDecl *ClassDecl, SourceLocation EllipsisLoc)
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, ImplicitDeallocationParameters, bool Diagnose=true)
void ForceDeclarationOfImplicitMembers(CXXRecordDecl *Class)
Force the declaration of any implicitly-declared members of this class.
void ActOnParamDefaultArgumentError(Decl *param, SourceLocation EqualLoc, Expr *DefaultArg)
ActOnParamDefaultArgumentError - Parsing or semantic analysis of the default argument for the paramet...
bool diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC, DeclarationName Name, SourceLocation Loc, TemplateIdAnnotation *TemplateId, bool IsMemberSpecialization)
Diagnose a declaration whose declarator-id has the given nested-name-specifier.
void DiagnoseStaticAssertDetails(const Expr *E)
Try to print more useful information about a failed static_assert with expression \E.
void DefineImplicitMoveAssignment(SourceLocation CurrentLocation, CXXMethodDecl *MethodDecl)
Defines an implicitly-declared move assignment operator.
void ActOnFinishDelayedMemberInitializers(Decl *Record)
ExprResult CreateBuiltinBinOp(SourceLocation OpLoc, BinaryOperatorKind Opc, Expr *LHSExpr, Expr *RHSExpr, bool ForFoldExpression=false)
CreateBuiltinBinOp - Creates a new built-in binary operation with operator Opc at location TokLoc.
NamedDecl * ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, TypeSourceInfo *TInfo, LookupResult &Previous, MultiTemplateParamsArg TemplateParamLists, bool &AddToScope, ArrayRef< BindingDecl * > Bindings={})
void CheckDelegatingCtorCycles()
SmallVector< CXXMethodDecl *, 4 > DelayedDllExportMemberFunctions
void CheckExplicitObjectMemberFunction(Declarator &D, DeclarationName Name, QualType R, bool IsLambda, DeclContext *DC=nullptr)
bool DiagnoseClassNameShadow(DeclContext *DC, DeclarationNameInfo Info)
DiagnoseClassNameShadow - Implement C++ [class.mem]p13: If T is the name of a class,...
AccessResult CheckFriendAccess(NamedDecl *D)
Checks access to the target of a friend declaration.
void MarkBaseAndMemberDestructorsReferenced(SourceLocation Loc, CXXRecordDecl *Record)
MarkBaseAndMemberDestructorsReferenced - Given a record decl, mark all the non-trivial destructors of...
const TranslationUnitKind TUKind
The kind of translation unit we are processing.
QualType tryBuildStdTypeIdentity(QualType Type, SourceLocation Loc)
Looks for the std::type_identity template and instantiates it with Type, or returns a null type if ty...
DeclResult ActOnCXXConditionDeclaration(Scope *S, Declarator &D)
ActOnCXXConditionDeclarationExpr - Parsed a condition declaration of a C++ if/switch/while/for statem...
void LookupOverloadedBinOp(OverloadCandidateSet &CandidateSet, OverloadedOperatorKind Op, const UnresolvedSetImpl &Fns, ArrayRef< Expr * > Args, bool RequiresADL=true)
Perform lookup for an overloaded binary operator.
DelegatingCtorDeclsType DelegatingCtorDecls
All the delegating constructors seen so far in the file, used for cycle detection at the end of the T...
bool ActOnAccessSpecifier(AccessSpecifier Access, SourceLocation ASLoc, SourceLocation ColonLoc, const ParsedAttributesView &Attrs)
ActOnAccessSpecifier - Parsed an access specifier followed by a colon.
std::unique_ptr< CXXFieldCollector > FieldCollector
FieldCollector - Collects CXXFieldDecls during parsing of C++ classes.
void AddPragmaAttributes(Scope *S, Decl *D)
Adds the attributes that have been specified using the '#pragma clang attribute push' directives to t...
TemplateDecl * AdjustDeclIfTemplate(Decl *&Decl)
AdjustDeclIfTemplate - If the given decl happens to be a template, reset the parameter D to reference...
bool isImplicitlyDeleted(FunctionDecl *FD)
Determine whether the given function is an implicitly-deleted special member function.
void CheckImplicitSpecialMemberDeclaration(Scope *S, FunctionDecl *FD)
Check a completed declaration of an implicit special member.
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
bool CompleteConstructorCall(CXXConstructorDecl *Constructor, QualType DeclInitType, MultiExprArg ArgsPtr, SourceLocation Loc, SmallVectorImpl< Expr * > &ConvertedArgs, bool AllowExplicit=false, bool IsListInitialization=false)
Given a constructor and the set of arguments provided for the constructor, convert the arguments and ...
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC)
Require that the context specified by SS be complete.
bool TemplateParameterListsAreEqual(const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New, const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain, TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc=SourceLocation())
Determine whether the given template parameter lists are equivalent.
Decl * ActOnNamespaceAliasDef(Scope *CurScope, SourceLocation NamespaceLoc, SourceLocation AliasLoc, IdentifierInfo *Alias, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *Ident)
void CheckOverrideControl(NamedDecl *D)
CheckOverrideControl - Check C++11 override control semantics.
bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, const FunctionProtoType *Proto, unsigned FirstParam, ArrayRef< Expr * > Args, SmallVectorImpl< Expr * > &AllArgs, VariadicCallType CallType=VariadicCallType::DoesNotApply, bool AllowExplicit=false, bool IsListInitialization=false)
GatherArgumentsForCall - Collector argument expressions for various form of call prototypes.
bool ShouldDeleteSpecialMember(CXXMethodDecl *MD, CXXSpecialMemberKind CSM, InheritedConstructorInfo *ICI=nullptr, bool Diagnose=false)
Determine if a special member function should have a deleted definition when it is defaulted.
DeclResult ActOnTemplatedFriendTag(Scope *S, SourceLocation FriendLoc, unsigned TagSpec, SourceLocation TagLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, SourceLocation EllipsisLoc, const ParsedAttributesView &Attr, MultiTemplateParamsArg TempParamLists)
Handle a friend tag declaration where the scope specifier was templated.
Scope * getScopeForContext(DeclContext *Ctx)
Determines the active Scope associated with the given declaration context.
CXXConstructorDecl * DeclareImplicitMoveConstructor(CXXRecordDecl *ClassDecl)
Declare the implicit move constructor for the given class.
bool ProcessAccessDeclAttributeList(AccessSpecDecl *ASDecl, const ParsedAttributesView &AttrList)
Annotation attributes are the only attributes allowed after an access specifier.
FunctionDecl * InstantiateFunctionDeclaration(FunctionTemplateDecl *FTD, const TemplateArgumentList *Args, SourceLocation Loc, CodeSynthesisContext::SynthesisKind CSC=CodeSynthesisContext::ExplicitTemplateArgumentSubstitution)
Instantiate (or find existing instantiation of) a function template with a given set of template argu...
void SetFunctionBodyKind(Decl *D, SourceLocation Loc, FnBodyKind BodyKind, StringLiteral *DeletedMessage=nullptr)
void referenceDLLExportedClassMethods()
void CheckCompleteDestructorVariant(SourceLocation CurrentLocation, CXXDestructorDecl *Dtor)
Do semantic checks to allow the complete destructor variant to be emitted when the destructor is defi...
NamedDecl * ActOnCXXMemberDeclarator(Scope *S, AccessSpecifier AS, Declarator &D, MultiTemplateParamsArg TemplateParameterLists, Expr *BitfieldWidth, const VirtSpecifiers &VS, InClassInitStyle InitStyle)
ActOnCXXMemberDeclarator - This is invoked when a C++ class member declarator is parsed.
bool CheckIfOverriddenFunctionIsMarkedFinal(const CXXMethodDecl *New, const CXXMethodDecl *Old)
CheckIfOverriddenFunctionIsMarkedFinal - Checks whether a virtual member function overrides a virtual...
NamedDecl * HandleDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParameterLists)
bool CheckOverridingFunctionAttributes(CXXMethodDecl *New, const CXXMethodDecl *Old)
TemplateParameterList * MatchTemplateParametersToScopeSpecifier(SourceLocation DeclStartLoc, SourceLocation DeclLoc, const CXXScopeSpec &SS, TemplateIdAnnotation *TemplateId, ArrayRef< TemplateParameterList * > ParamLists, bool IsFriend, bool &IsMemberSpecialization, bool &Invalid, bool SuppressDiagnostic=false)
Match the given template parameter lists to the given scope specifier, returning the template paramet...
void handleTagNumbering(const TagDecl *Tag, Scope *TagScope)
void AddImplicitlyDeclaredMembersToClass(CXXRecordDecl *ClassDecl)
AddImplicitlyDeclaredMembersToClass - Adds any implicitly-declared special functions,...
bool tryResolveExplicitSpecifier(ExplicitSpecifier &ExplicitSpec)
tryResolveExplicitSpecifier - Attempt to resolve the explict specifier.
Decl * ActOnConversionDeclarator(CXXConversionDecl *Conversion)
ActOnConversionDeclarator - Called by ActOnDeclarator to complete the declaration of the given C++ co...
bool IsCXXTriviallyRelocatableType(QualType T)
Determines if a type is trivially relocatable according to the C++26 rules.
@ Other
C++26 [dcl.fct.def.general]p1 function-body: ctor-initializer[opt] compound-statement function-try-bl...
@ Delete
deleted-function-body
QualType BuildStdInitializerList(QualType Element, SourceLocation Loc)
Looks for the std::initializer_list template and instantiates it with Element, or emits an error if i...
MemInitResult BuildMemberInitializer(ValueDecl *Member, Expr *Init, SourceLocation IdLoc)
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
FieldDecl * HandleField(Scope *S, RecordDecl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth, InClassInitStyle InitStyle, AccessSpecifier AS)
HandleField - Analyze a field of a C struct or a C++ data member.
FPOptionsOverride CurFPFeatureOverrides()
void DiagnoseHiddenVirtualMethods(CXXMethodDecl *MD)
Diagnose methods which overload virtual methods in a base class without overriding any.
UsingShadowDecl * BuildUsingShadowDecl(Scope *S, BaseUsingDecl *BUD, NamedDecl *Target, UsingShadowDecl *PrevDecl)
Builds a shadow declaration corresponding to a 'using' declaration.
ExprResult BuildCallToMemberFunction(Scope *S, Expr *MemExpr, SourceLocation LParenLoc, MultiExprArg Args, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallToMemberFunction - Build a call to a member function.
FunctionDecl * FindDeallocationFunctionForDestructor(SourceLocation StartLoc, CXXRecordDecl *RD, bool Diagnose, bool LookForGlobal, DeclarationName Name)
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
bool isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass, DeclAccessPair Found, QualType ObjectType, SourceLocation Loc, const PartialDiagnostic &Diag)
Is the given member accessible for the purposes of deciding whether to define a special member functi...
BaseResult ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange, const ParsedAttributesView &Attrs, bool Virtual, AccessSpecifier Access, ParsedType basetype, SourceLocation BaseLoc, SourceLocation EllipsisLoc)
ActOnBaseSpecifier - Parsed a base specifier.
void ActOnFinishFunctionDeclarationDeclarator(Declarator &D)
Called after parsing a function declarator belonging to a function declaration.
void ActOnParamDefaultArgument(Decl *param, SourceLocation EqualLoc, Expr *defarg)
ActOnParamDefaultArgument - Check whether the default argument provided for a function parameter is w...
void CheckConversionDeclarator(Declarator &D, QualType &R, StorageClass &SC)
CheckConversionDeclarator - Called by ActOnDeclarator to check the well-formednes of the conversion f...
bool DeduceReturnType(FunctionDecl *FD, SourceLocation Loc, bool Diagnose=true)
void ActOnFinishDelayedCXXMethodDeclaration(Scope *S, Decl *Method)
ActOnFinishDelayedCXXMethodDeclaration - We have finished processing the delayed method declaration f...
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReceiver=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
DeclarationNameInfo GetNameForDeclarator(Declarator &D)
GetNameForDeclarator - Determine the full declaration name for the given Declarator.
DiagnosticsEngine & getDiagnostics() const
void DiagnoseTypeTraitDetails(const Expr *E)
If E represents a built-in type trait, or a known standard type trait, try to print more information ...
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
bool isStdTypeIdentity(QualType Ty, QualType *TypeArgument, const Decl **MalformedDecl=nullptr)
Tests whether Ty is an instance of std::type_identity and, if it is and TypeArgument is not NULL,...
void propagateDLLAttrToBaseClassTemplate(CXXRecordDecl *Class, Attr *ClassAttr, ClassTemplateSpecializationDecl *BaseTemplateSpec, SourceLocation BaseLoc)
Perform propagation of DLL attributes from a derived class to a templated base class for MS compatibi...
bool SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMemberKind CSM, TrivialABIHandling TAH=TrivialABIHandling::IgnoreTrivialABI, bool Diagnose=false)
Determine whether a defaulted or deleted special member function is trivial, as specified in C++11 [c...
NamedDecl * ActOnFriendFunctionDecl(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParams)
void setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec, TypedefNameDecl *NewTD)
void CheckDelayedMemberExceptionSpecs()
void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param)
This is used to implement the constant expression evaluation part of the attribute enable_if extensio...
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
ASTContext & getASTContext() const
ClassTemplateDecl * StdInitializerList
The C++ "std::initializer_list" template, which is defined in <initializer_list>.
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
void CheckExplicitlyDefaultedFunction(Scope *S, FunctionDecl *MD)
bool isCurrentClassName(const IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS=nullptr)
isCurrentClassName - Determine whether the identifier II is the name of the class type currently bein...
void MarkVariableReferenced(SourceLocation Loc, VarDecl *Var)
Mark a variable referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
void checkExceptionSpecification(bool IsTopLevel, ExceptionSpecificationType EST, ArrayRef< ParsedType > DynamicExceptions, ArrayRef< SourceRange > DynamicExceptionRanges, Expr *NoexceptExpr, SmallVectorImpl< QualType > &Exceptions, FunctionProtoType::ExceptionSpecInfo &ESI)
Check the given exception-specification and update the exception specification information with the r...
SmallVector< std::pair< FunctionDecl *, FunctionDecl * >, 2 > DelayedEquivalentExceptionSpecChecks
All the function redeclarations seen during a class definition that had their exception spec checks d...
bool checkThisInStaticMemberFunctionType(CXXMethodDecl *Method)
Check whether 'this' shows up in the type of a static member function after the (naturally empty) cv-...
void PopExpressionEvaluationContext()
NamespaceDecl * getOrCreateStdNamespace()
Retrieve the special "std" namespace, which may require us to implicitly define the namespace.
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
bool isInitListConstructor(const FunctionDecl *Ctor)
Determine whether Ctor is an initializer-list constructor, as defined in [dcl.init....
void ActOnStartFunctionDeclarationDeclarator(Declarator &D, unsigned TemplateParameterDepth)
Called before parsing a function declarator belonging to a function declaration.
std::string getAmbiguousPathsDisplayString(CXXBasePaths &Paths)
Builds a string representing ambiguous paths from a specific derived class to different subobjects of...
DefaultedComparisonKind
Kinds of defaulted comparison operator functions.
@ Relational
This is an <, <=, >, or >= that should be implemented as a rewrite in terms of a <=> comparison.
@ NotEqual
This is an operator!= that should be implemented as a rewrite in terms of a == comparison.
@ ThreeWay
This is an operator<=> that should be implemented as a series of subobject comparisons.
@ None
This is not a defaultable comparison operator.
@ Equal
This is an operator== that should be implemented as a series of subobject comparisons.
OverloadKind CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &OldDecls, NamedDecl *&OldDecl, bool UseMemberUsingDeclRules)
Determine whether the given New declaration is an overload of the declarations in Old.
bool RequireLiteralType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
Ensure that the type T is a literal type.
llvm::PointerIntPair< CXXRecordDecl *, 3, CXXSpecialMemberKind > SpecialMemberDecl
void ActOnStartCXXInClassMemberInitializer()
Enter a new C++ default initializer scope.
ValueDecl * tryLookupCtorInitMemberDecl(CXXRecordDecl *ClassDecl, CXXScopeSpec &SS, ParsedType TemplateTypeTy, IdentifierInfo *MemberOrBase)
NamedDecl * BuildUsingDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, bool HasTypenameKeyword, SourceLocation TypenameLoc, CXXScopeSpec &SS, DeclarationNameInfo NameInfo, SourceLocation EllipsisLoc, const ParsedAttributesView &AttrList, bool IsInstantiation, bool IsUsingIfExists)
Builds a using declaration.
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
bool pushCodeSynthesisContext(CodeSynthesisContext Ctx)
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
void DefineImplicitMoveConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor)
DefineImplicitMoveConstructor - Checks for feasibility of defining this constructor as the move const...
@ TPL_TemplateMatch
We are matching the template parameter lists of two templates that might be redeclarations.
EnumDecl * getStdAlignValT() const
void ActOnFinishDelayedMemberDeclarations(Scope *S, Decl *Record)
LangAS getDefaultCXXMethodAddrSpace() const
Returns default addr space for method qualifiers.
LazyDeclPtr StdBadAlloc
The C++ "std::bad_alloc" class, which is defined by the C++ standard library.
QualType BuildQualifiedType(QualType T, SourceLocation Loc, Qualifiers Qs, const DeclSpec *DS=nullptr)
void PushFunctionScope()
Enter a new function scope.
void SetDeclDefaulted(Decl *dcl, SourceLocation DefaultLoc)
void DefineImplicitCopyConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor)
DefineImplicitCopyConstructor - Checks for feasibility of defining this constructor as the copy const...
FPOptions & getCurFPFeatures()
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr)
ConditionResult ActOnCondition(Scope *S, SourceLocation Loc, Expr *SubExpr, ConditionKind CK, bool MissingOK=false)
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
@ UPPC_UsingDeclaration
A using declaration.
@ UPPC_ExceptionType
The type of an exception.
@ UPPC_Initializer
An initializer.
@ UPPC_BaseType
The base type of a class type.
@ UPPC_FriendDeclaration
A friend declaration.
@ UPPC_DefaultArgument
A default argument.
@ UPPC_DeclarationType
The type of an arbitrary declaration.
@ UPPC_DataMemberType
The type of a data member.
@ UPPC_StaticAssertExpression
The expression in a static assertion.
Decl * ActOnStartNamespaceDef(Scope *S, SourceLocation InlineLoc, SourceLocation NamespaceLoc, SourceLocation IdentLoc, IdentifierInfo *Ident, SourceLocation LBrace, const ParsedAttributesView &AttrList, UsingDirectiveDecl *&UsingDecl, bool IsNested)
ActOnStartNamespaceDef - This is called at the start of a namespace definition.
const LangOptions & getLangOpts() const
void DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl, bool SupportedForCompatibility=false)
DiagnoseTemplateParameterShadow - Produce a diagnostic complaining that the template parameter 'PrevD...
TypoCorrection CorrectTypo(const DeclarationNameInfo &Typo, Sema::LookupNameKind LookupKind, Scope *S, CXXScopeSpec *SS, CorrectionCandidateCallback &CCC, CorrectTypoKind Mode, DeclContext *MemberContext=nullptr, bool EnteringContext=false, const ObjCObjectPointerType *OPT=nullptr, bool RecordFailure=true)
Try to "correct" a typo in the source code by finding visible declarations whose names are similar to...
QualType CheckComparisonCategoryType(ComparisonCategoryType Kind, SourceLocation Loc, ComparisonCategoryUsage Usage)
Lookup the specified comparison category types in the standard library, an check the VarDecls possibl...
void DiagnoseAbsenceOfOverrideControl(NamedDecl *D, bool Inconsistent)
DiagnoseAbsenceOfOverrideControl - Diagnose if 'override' keyword was not used in the declaration of ...
SmallVector< VTableUse, 16 > VTableUses
The list of vtables that are required but have not yet been materialized.
PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, Decl *D=nullptr, QualType BlockType=QualType())
Pop a function (or block or lambda or captured region) scope from the stack.
AccessResult CheckStructuredBindingMemberAccess(SourceLocation UseLoc, CXXRecordDecl *DecomposedClass, DeclAccessPair Field)
Checks implicit access to a member in a structured binding.
void EnterTemplatedContext(Scope *S, DeclContext *DC)
Enter a template parameter scope, after it's been associated with a particular DeclContext.
void ActOnBaseSpecifiers(Decl *ClassDecl, MutableArrayRef< CXXBaseSpecifier * > Bases)
ActOnBaseSpecifiers - Attach the given base specifiers to the class, after checking whether there are...
const FunctionProtoType * ResolveExceptionSpec(SourceLocation Loc, const FunctionProtoType *FPT)
void NoteTemplateLocation(const NamedDecl &Decl, std::optional< SourceRange > ParamRange={})
void DefineDefaultedComparison(SourceLocation Loc, FunctionDecl *FD, DefaultedComparisonKind DCK)
bool isEquivalentInternalLinkageDeclaration(const NamedDecl *A, const NamedDecl *B)
Determine if A and B are equivalent internal linkage declarations from different modules,...
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, QualType ObjectType, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
bool CheckConstexprFunctionDefinition(const FunctionDecl *FD, CheckConstexprKind Kind)
ExprResult BuildCallExpr(Scope *S, Expr *Fn, SourceLocation LParenLoc, MultiExprArg ArgExprs, SourceLocation RParenLoc, Expr *ExecConfig=nullptr, bool IsExecConfig=false, bool AllowRecovery=false)
BuildCallExpr - Handle a call to Fn with the specified array of arguments.
AccessResult CheckBaseClassAccess(SourceLocation AccessLoc, QualType Base, QualType Derived, const CXXBasePath &Path, unsigned DiagID, bool ForceCheck=false, bool ForceUnprivileged=false)
Checks access for a hierarchy conversion.
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
NamedDecl * getShadowedDeclaration(const TypedefNameDecl *D, const LookupResult &R)
Return the declaration shadowed by the given typedef D, or null if it doesn't shadow any declaration ...
void AddBuiltinOperatorCandidates(OverloadedOperatorKind Op, SourceLocation OpLoc, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet)
AddBuiltinOperatorCandidates - Add the appropriate built-in operator overloads to the candidate set (...
void CheckExtraCXXDefaultArguments(Declarator &D)
CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...
void CheckCompleteDecompositionDeclaration(DecompositionDecl *DD)
void checkClassLevelDLLAttribute(CXXRecordDecl *Class)
Check class-level dllimport/dllexport attribute.
const LangOptions & LangOpts
std::pair< Expr *, std::string > findFailedBooleanCondition(Expr *Cond)
Find the failed Boolean condition within a given Boolean constant expression, and describe it with a ...
void DiagnoseReturnInConstructorExceptionHandler(CXXTryStmt *TryBlock)
void MarkVirtualMembersReferenced(SourceLocation Loc, const CXXRecordDecl *RD, bool ConstexprOnly=false)
MarkVirtualMembersReferenced - Will mark all members of the given CXXRecordDecl referenced.
ExprResult CheckForImmediateInvocation(ExprResult E, FunctionDecl *Decl)
Wrap the expression in a ConstantExpr if it is a potential immediate invocation.
ExprResult TemporaryMaterializationConversion(Expr *E)
If E is a prvalue denoting an unmaterialized temporary, materialize it as an xvalue.
NamedDeclSetType UnusedPrivateFields
Set containing all declared private fields that are not used.
void DefineInheritingConstructor(SourceLocation UseLoc, CXXConstructorDecl *Constructor)
Define the specified inheriting constructor.
bool CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, LookupResult &Previous, bool IsMemberSpecialization, bool DeclIsDefn)
Perform semantic checking of a new function declaration.
CXXRecordDecl * getStdBadAlloc() const
QualType CheckDestructorDeclarator(Declarator &D, QualType R, StorageClass &SC)
CheckDestructorDeclarator - Called by ActOnDeclarator to check the well-formednes of the destructor d...
bool CheckPureMethod(CXXMethodDecl *Method, SourceRange InitRange)
Mark the given method pure.
void SetParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc)
void NoteHiddenVirtualMethods(CXXMethodDecl *MD, SmallVectorImpl< CXXMethodDecl * > &OverloadedMethods)
CXXMethodDecl * DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl)
Declare the implicit move assignment operator for the given class.
QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo &II, SourceLocation IILoc, TypeSourceInfo **TSI, bool DeducedTSTContext)
llvm::DenseMap< CXXRecordDecl *, bool > VTablesUsed
The set of classes whose vtables have been used within this translation unit, and a bit that will be ...
void CheckCXXDefaultArguments(FunctionDecl *FD)
Helpers for dealing with blocks and functions.
@ DefaultedOperator
A defaulted 'operator<=>' needed the comparison category.
SmallVector< InventedTemplateParameterInfo, 4 > InventedParameterInfos
Stack containing information needed when in C++2a an 'auto' is encountered in a function declaration ...
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)
Perform marking for a reference to an arbitrary declaration.
void ProcessDeclAttributeList(Scope *S, Decl *D, const ParsedAttributesView &AttrList, const ProcessDeclAttributeOptions &Options=ProcessDeclAttributeOptions())
ProcessDeclAttributeList - Apply all the decl attributes in the specified attribute list to the speci...
void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, bool DefinitionRequired=false)
Note that the vtable for the given class was used at the given location.
NamedDecl * BuildUsingEnumDeclaration(Scope *S, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation EnumLoc, SourceLocation NameLoc, TypeSourceInfo *EnumType, EnumDecl *ED)
TypeLoc getReturnTypeLoc(FunctionDecl *FD) const
SmallVector< std::pair< const CXXMethodDecl *, const CXXMethodDecl * >, 2 > DelayedOverridingExceptionSpecChecks
All the overriding functions seen during a class definition that had their exception spec checks dela...
llvm::DenseMap< ParmVarDecl *, SourceLocation > UnparsedDefaultArgLocs
void MarkVirtualMemberExceptionSpecsNeeded(SourceLocation Loc, const CXXRecordDecl *RD)
Mark the exception specifications of all virtual member functions in the given class as needed.
ExprResult BuildConvertedConstantExpression(Expr *From, QualType T, CCEKind CCE, NamedDecl *Dest=nullptr)
bool RequireCompleteEnumDecl(EnumDecl *D, SourceLocation L, CXXScopeSpec *SS=nullptr)
Require that the EnumDecl is completed with its enumerators defined or instantiated.
bool CheckOverloadedOperatorDeclaration(FunctionDecl *FnDecl)
CheckOverloadedOperatorDeclaration - Check whether the declaration of this overloaded operator is wel...
void MarkVirtualBaseDestructorsReferenced(SourceLocation Location, CXXRecordDecl *ClassDecl, llvm::SmallPtrSetImpl< const CXXRecordDecl * > *DirectVirtualBases=nullptr)
Mark destructors of virtual bases of this class referenced.
void ExitDeclaratorContext(Scope *S)
void PushUsingDirective(Scope *S, UsingDirectiveDecl *UDir)
void CheckConstructor(CXXConstructorDecl *Constructor)
CheckConstructor - Checks a fully-formed constructor for well-formedness, issuing any diagnostics req...
void DefineImplicitLambdaToBlockPointerConversion(SourceLocation CurrentLoc, CXXConversionDecl *Conv)
Define the "body" of the conversion from a lambda object to a block pointer.
void DefineImplicitDestructor(SourceLocation CurrentLocation, CXXDestructorDecl *Destructor)
DefineImplicitDestructor - Checks for feasibility of defining this destructor as the default destruct...
void DiagnoseNontrivial(const CXXRecordDecl *Record, CXXSpecialMemberKind CSM)
Diagnose why the specified class does not have a trivial special member of the given kind.
Decl * ActOnUsingEnumDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation EnumLoc, SourceRange TyLoc, const IdentifierInfo &II, ParsedType Ty, const CXXScopeSpec &SS)
void popCodeSynthesisContext()
CXXRecordDecl * getCurrentClass(Scope *S, const CXXScopeSpec *SS)
Get the class that is directly named by the current context.
bool EvaluateAsString(Expr *Message, APValue &Result, ASTContext &Ctx, StringEvaluationContext EvalContext, bool ErrorOnInvalidMessage)
QualType BuildReferenceType(QualType T, bool LValueRef, SourceLocation Loc, DeclarationName Entity)
Build a reference type.
ExprResult ActOnFinishTrailingRequiresClause(ExprResult ConstraintExpr)
bool checkThisInStaticMemberFunctionAttributes(CXXMethodDecl *Method)
Check whether 'this' shows up in the attributes of the given static member function.
CXXBaseSpecifier * CheckBaseSpecifier(CXXRecordDecl *Class, SourceRange SpecifierRange, bool Virtual, AccessSpecifier Access, TypeSourceInfo *TInfo, SourceLocation EllipsisLoc)
Check the validity of a C++ base class specifier.
DeclResult CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, TemplateParameterList *TemplateParams, AccessSpecifier AS, SourceLocation ModulePrivateLoc, SourceLocation FriendLoc, unsigned NumOuterTemplateParamLists, TemplateParameterList **OuterTemplateParamLists, SkipBodyInfo *SkipBody=nullptr)
UnparsedDefaultArgInstantiationsMap UnparsedDefaultArgInstantiations
A mapping from parameters with unparsed default arguments to the set of instantiations of each parame...
void DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, CXXConstructorDecl *Constructor)
DefineImplicitDefaultConstructor - Checks for feasibility of defining this constructor as the default...
std::pair< CXXRecordDecl *, SourceLocation > VTableUse
The list of classes whose vtables have been used within this translation unit, and the source locatio...
ExprResult DefaultLvalueConversion(Expr *E)
bool CheckUsingShadowDecl(BaseUsingDecl *BUD, NamedDecl *Target, const LookupResult &PreviousDecls, UsingShadowDecl *&PrevShadow)
Determines whether to create a using shadow decl for a particular decl, given the set of decls existi...
ExprResult BuildDeclarationNameExpr(const CXXScopeSpec &SS, LookupResult &R, bool NeedsADL, bool AcceptInvalidDecl=false)
bool isVisible(const NamedDecl *D)
Determine whether a declaration is visible to name lookup.
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, SourceLocation Loc, SourceRange Range, CXXCastPath *BasePath=nullptr, bool IgnoreAccess=false)
Module * getCurrentModule() const
Get the module unit whose scope we are currently within.
bool CheckDeductionGuideDeclarator(Declarator &D, QualType &R, StorageClass &SC)
Check the validity of a declarator that we parsed for a deduction-guide.
void DiagPlaceholderVariableDefinition(SourceLocation Loc)
void CheckForFunctionRedefinition(FunctionDecl *FD, const FunctionDecl *EffectiveDefinition=nullptr, SkipBodyInfo *SkipBody=nullptr)
bool DiagnoseUseOfOverloadedDecl(NamedDecl *D, SourceLocation Loc)
std::unique_ptr< RecordDeclSetTy > PureVirtualClassDiagSet
PureVirtualClassDiagSet - a set of class declarations which we have emitted a list of pure virtual fu...
void ActOnFinishInlineFunctionDef(FunctionDecl *D)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
VarDecl * BuildExceptionDeclaration(Scope *S, TypeSourceInfo *TInfo, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id)
Perform semantic analysis for the variable declaration that occurs within a C++ catch clause,...
void ActOnDocumentableDecl(Decl *D)
Should be called on all declarations that might have attached documentation comments.
ClassTemplateDecl * StdTypeIdentity
The C++ "std::type_identity" template, which is defined in <type_traits>.
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
Decl * ActOnFriendTypeDecl(Scope *S, const DeclSpec &DS, MultiTemplateParamsArg TemplateParams, SourceLocation EllipsisLoc)
Handle a friend type declaration.
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
void DefineImplicitCopyAssignment(SourceLocation CurrentLocation, CXXMethodDecl *MethodDecl)
Defines an implicitly-declared copy assignment operator.
bool CheckFunctionConstraints(const FunctionDecl *FD, ConstraintSatisfaction &Satisfaction, SourceLocation UsageLoc=SourceLocation(), bool ForOverloadResolution=false)
Check whether the given function decl's trailing requires clause is satisfied, if any.
bool SetDelegatingInitializer(CXXConstructorDecl *Constructor, CXXCtorInitializer *Initializer)
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
bool CheckLiteralOperatorDeclaration(FunctionDecl *FnDecl)
CheckLiteralOperatorDeclaration - Check whether the declaration of this literal operator function is ...
bool DefineUsedVTables()
Define all of the vtables that have been used in this translation unit and reference any virtual memb...
CXXMethodDecl * DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl)
Declare the implicit copy assignment operator for the given class.
void checkIllFormedTrivialABIStruct(CXXRecordDecl &RD)
Check that the C++ class annoated with "trivial_abi" satisfies all the conditions that are needed for...
void MarkDeclRefReferenced(DeclRefExpr *E, const Expr *Base=nullptr)
Perform reference-marking and odr-use handling for a DeclRefExpr.
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
unsigned ActOnReenterTemplateScope(Decl *Template, llvm::function_ref< Scope *()> EnterScope)
ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, NamedDecl *FoundDecl, CXXConstructorDecl *Constructor, MultiExprArg Exprs, bool HadMultipleCandidates, bool IsListInitialization, bool IsStdInitListInitialization, bool RequiresZeroInit, CXXConstructionKind ConstructKind, SourceRange ParenRange)
BuildCXXConstructExpr - Creates a complete call to a constructor, including handling of its default a...
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
FunctionDecl * SubstSpaceshipAsEqualEqual(CXXRecordDecl *RD, FunctionDecl *Spaceship)
Substitute the name and return type of a defaulted 'operator<=>' to form an implicit 'operator=='.
NamedDecl * ActOnDecompositionDeclarator(Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists)
ExprResult BuildFieldReferenceExpr(Expr *BaseExpr, bool IsArrow, SourceLocation OpLoc, const CXXScopeSpec &SS, FieldDecl *Field, DeclAccessPair FoundDecl, const DeclarationNameInfo &MemberNameInfo)
void diagnoseFunctionEffectMergeConflicts(const FunctionEffectSet::Conflicts &Errs, SourceLocation NewLoc, SourceLocation OldLoc)
void EnterDeclaratorContext(Scope *S, DeclContext *DC)
EnterDeclaratorContext - Used when we must lookup names in the context of a declarator's nested name ...
bool CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *MD, DefaultedComparisonKind DCK)
bool checkThisInStaticMemberFunctionExceptionSpec(CXXMethodDecl *Method)
Whether this' shows up in the exception specification of a static member function.
void ActOnFinishCXXInClassMemberInitializer(Decl *VarDecl, SourceLocation EqualLoc, ExprResult Init)
This is invoked after parsing an in-class initializer for a non-static C++ class member,...
llvm::FoldingSet< SpecialMemberOverloadResultEntry > SpecialMemberCache
A cache of special member function overload resolution results for C++ records.
QualType BuildPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc, bool FullySubstituted=false, ArrayRef< QualType > Expansions={})
Decl * ActOnStartLinkageSpecification(Scope *S, SourceLocation ExternLoc, Expr *LangStr, SourceLocation LBraceLoc)
ActOnStartLinkageSpecification - Parsed the beginning of a C++ linkage specification,...
void FilterUsingLookup(Scope *S, LookupResult &lookup)
Remove decls we can't actually see from a lookup being used to declare shadow using decls.
Decl * ActOnExceptionDeclarator(Scope *S, Declarator &D)
ActOnExceptionDeclarator - Parsed the exception-declarator in a C++ catch handler.
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, SourceLocation Loc)
PushNamespaceVisibilityAttr - Note that we've entered a namespace with a visibility attribute.
void ActOnDefaultCtorInitializers(Decl *CDtorDecl)
void ActOnMemInitializers(Decl *ConstructorDecl, SourceLocation ColonLoc, ArrayRef< CXXCtorInitializer * > MemInits, bool AnyErrors)
ActOnMemInitializers - Handle the member initializers for a constructor.
bool CheckTemplateDeclScope(Scope *S, TemplateParameterList *TemplateParams)
Check whether a template can be declared within this scope.
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
void ActOnCXXEnterDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXEnterDeclInitializer - Invoked when we are about to parse an initializer for the declaration ...
FunctionDecl * BuildTypeAwareUsualDelete(FunctionTemplateDecl *FnDecl, QualType AllocType, SourceLocation)
void ActOnFinishCXXMemberSpecification(Scope *S, SourceLocation RLoc, Decl *TagDecl, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
void CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl, const LookupResult &R)
Diagnose variable or built-in function shadowing.
void AdjustDestructorExceptionSpec(CXXDestructorDecl *Destructor)
Build an exception spec for destructors that don't have one.
Decl * ActOnStaticAssertDeclaration(SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *AssertMessageExpr, SourceLocation RParenLoc)
void DiagnoseUnknownAttribute(const ParsedAttr &AL)
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
bool CheckImmediateEscalatingFunctionDefinition(FunctionDecl *FD, const sema::FunctionScopeInfo *FSI)
void InstantiateDefaultCtorDefaultArgs(CXXConstructorDecl *Ctor)
In the MS ABI, we need to instantiate default arguments of dllexported default constructors along wit...
void CheckCompleteVariableDeclaration(VarDecl *VD)
ExprResult ActOnRequiresClause(ExprResult ConstraintExpr)
QualType CheckTemplateIdType(ElaboratedTypeKeyword Keyword, TemplateName Template, SourceLocation TemplateLoc, TemplateArgumentListInfo &TemplateArgs, Scope *Scope, bool ForNestedNameSpecifier)
void checkClassLevelCodeSegAttribute(CXXRecordDecl *Class)
bool isStdInitializerList(QualType Ty, QualType *Element)
Tests whether Ty is an instance of std::initializer_list and, if it is and Element is not NULL,...
RedeclarationKind forRedeclarationInCurContext() const
LazyDeclPtr StdNamespace
The C++ "std" namespace, where the standard library resides.
bool CheckUsingDeclRedeclaration(SourceLocation UsingLoc, bool HasTypenameKeyword, const CXXScopeSpec &SS, SourceLocation NameLoc, const LookupResult &Previous)
Checks that the given using declaration is not an invalid redeclaration.
void FinalizeVarWithDestructor(VarDecl *VD, CXXRecordDecl *DeclInit)
FinalizeVarWithDestructor - Prepare for calling destructor on the constructed variable.
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=AllowFoldKind::No)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
IntrusiveRefCntPtr< ExternalSemaSource > ExternalSource
Source of additional semantic information.
void ActOnFinishCXXMemberDecls()
Perform any semantic analysis which needs to be delayed until all pending class member declarations h...
llvm::SmallPtrSet< const Decl *, 4 > ParsingInitForAutoVars
ParsingInitForAutoVars - a set of declarations with auto types for which we are currently parsing the...
void NoteDeletedFunction(FunctionDecl *FD)
Emit a note explaining that this function is deleted.
ExprResult CreateBuiltinArraySubscriptExpr(Expr *Base, SourceLocation LLoc, Expr *Idx, SourceLocation RLoc)
Decl * ActOnFinishLinkageSpecification(Scope *S, Decl *LinkageSpec, SourceLocation RBraceLoc)
ActOnFinishLinkageSpecification - Complete the definition of the C++ linkage specification LinkageSpe...
bool CheckInheritingConstructorUsingDecl(UsingDecl *UD)
Additional checks for a using declaration referring to a constructor name.
@ ConstantEvaluated
The current context is "potentially evaluated" in C++11 terms, but the expression is evaluated at com...
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ Unevaluated
The current expression and its subexpressions occur within an unevaluated operand (C++11 [expr]p7),...
QualType BuildDecltypeType(Expr *E, bool AsUnevaluated=true)
If AsUnevaluated is false, E is treated as though it were an evaluated context, such as when building...
TypeSourceInfo * GetTypeForDeclarator(Declarator &D)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
void diagnoseTypo(const TypoCorrection &Correction, const PartialDiagnostic &TypoDiag, bool ErrorRecovery=true)
DeclResult ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc, CXXScopeSpec &SS, IdentifierInfo *Name, SourceLocation NameLoc, const ParsedAttributesView &Attr, AccessSpecifier AS, SourceLocation ModulePrivateLoc, MultiTemplateParamsArg TemplateParameterLists, bool &OwnedDecl, bool &IsDependent, SourceLocation ScopedEnumKWLoc, bool ScopedEnumUsesClassTag, TypeResult UnderlyingType, bool IsTypeSpecifier, bool IsTemplateParamOrArg, OffsetOfKind OOK, SkipBodyInfo *SkipBody=nullptr)
This is invoked when we see 'struct foo' or 'struct {'.
void ActOnFinishNamespaceDef(Decl *Dcl, SourceLocation RBrace)
ActOnFinishNamespaceDef - This callback is called after a namespace is exited.
MemInitResult BuildMemInitializer(Decl *ConstructorD, Scope *S, CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, ParsedType TemplateTypeTy, const DeclSpec &DS, SourceLocation IdLoc, Expr *Init, SourceLocation EllipsisLoc)
Handle a C++ member initializer.
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void actOnDelayedExceptionSpecification(Decl *D, ExceptionSpecificationType EST, SourceRange SpecificationRange, ArrayRef< ParsedType > DynamicExceptions, ArrayRef< SourceRange > DynamicExceptionRanges, Expr *NoexceptExpr)
Add an exception-specification to the given member or friend function (or function template).
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
void CheckExplicitObjectLambda(Declarator &D)
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
void NoteDeletedInheritingConstructor(CXXConstructorDecl *CD)
void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc)
PopPragmaVisibility - Pop the top element of the visibility stack; used for '#pragma GCC visibility' ...
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
void checkInitializerLifetime(const InitializedEntity &Entity, Expr *Init)
Check that the lifetime of the initializer (and its subobjects) is sufficient for initializing the en...
void CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record)
Perform semantic checks on a class definition that has been completing, introducing implicitly-declar...
void DiscardCleanupsInEvaluationContext()
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
bool CheckEquivalentExceptionSpec(FunctionDecl *Old, FunctionDecl *New)
void mergeDeclAttributes(NamedDecl *New, Decl *Old, AvailabilityMergeKind AMK=AvailabilityMergeKind::Redeclaration)
mergeDeclAttributes - Copy attributes from the Old decl to the New one.
bool isDependentScopeSpecifier(const CXXScopeSpec &SS)
SourceManager & SourceMgr
bool CheckDestructor(CXXDestructorDecl *Destructor)
CheckDestructor - Checks a fully-formed destructor definition for well-formedness,...
NamedDecl * BuildUsingPackDecl(NamedDecl *InstantiatedFrom, ArrayRef< NamedDecl * > Expansions)
MemInitResult ActOnMemInitializer(Decl *ConstructorD, Scope *S, CXXScopeSpec &SS, IdentifierInfo *MemberOrBase, ParsedType TemplateTypeTy, const DeclSpec &DS, SourceLocation IdLoc, SourceLocation LParenLoc, ArrayRef< Expr * > Args, SourceLocation RParenLoc, SourceLocation EllipsisLoc)
Handle a C++ member initializer using parentheses syntax.
void SetDeclDeleted(Decl *dcl, SourceLocation DelLoc, StringLiteral *Message=nullptr)
void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method)
ActOnStartDelayedCXXMethodDeclaration - We have completed parsing a top-level (non-nested) C++ class,...
DiagnosticsEngine & Diags
FullExprArg MakeFullDiscardedValueExpr(Expr *Arg)
TypeAwareAllocationMode ShouldUseTypeAwareOperatorNewOrDelete() const
CXXConstructorDecl * DeclareImplicitCopyConstructor(CXXRecordDecl *ClassDecl)
Declare the implicit copy constructor for the given class.
NamespaceDecl * getStdNamespace() const
llvm::SmallPtrSet< const CXXRecordDecl *, 8 > RecordDeclSetTy
void DeclareImplicitEqualityComparison(CXXRecordDecl *RD, FunctionDecl *Spaceship)
bool AttachBaseSpecifiers(CXXRecordDecl *Class, MutableArrayRef< CXXBaseSpecifier * > Bases)
Performs the actual work of attaching the given base class specifiers to a C++ class.
void ActOnCXXExitDeclInitializer(Scope *S, Decl *Dcl)
ActOnCXXExitDeclInitializer - Invoked after we are finished parsing an initializer for the declaratio...
static bool adjustContextForLocalExternDecl(DeclContext *&DC)
Adjust the DeclContext for a function or variable that might be a function-local external declaration...
SpecialMemberOverloadResult LookupSpecialMember(CXXRecordDecl *D, CXXSpecialMemberKind SM, bool ConstArg, bool VolatileArg, bool RValueThis, bool ConstThis, bool VolatileThis)
NamedDecl * ActOnTypedefNameDecl(Scope *S, DeclContext *DC, TypedefNameDecl *D, LookupResult &Previous, bool &Redeclaration)
ActOnTypedefNameDecl - Perform semantic checking for a declaration which declares a typedef-name,...
ExprResult ActOnIntegerConstant(SourceLocation Loc, int64_t Val)
ExprResult BuildCXXDefaultInitExpr(SourceLocation Loc, FieldDecl *Field)
Decl * ActOnEmptyDeclaration(Scope *S, const ParsedAttributesView &AttrList, SourceLocation SemiLoc)
Handle a C++11 empty-declaration and attribute-declaration.
friend class InitializationSequence
void diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, SourceLocation FallbackLoc, SourceLocation ConstQualLoc=SourceLocation(), SourceLocation VolatileQualLoc=SourceLocation(), SourceLocation RestrictQualLoc=SourceLocation(), SourceLocation AtomicQualLoc=SourceLocation(), SourceLocation UnalignedQualLoc=SourceLocation())
llvm::MapVector< NamedDecl *, SourceLocation > UndefinedButUsed
UndefinedInternals - all the used, undefined objects which require a definition in this translation u...
QualType CheckConstructorDeclarator(Declarator &D, QualType R, StorageClass &SC)
CheckConstructorDeclarator - Called by ActOnDeclarator to check the well-formedness of the constructo...
ExprResult ConvertParamDefaultArgument(ParmVarDecl *Param, Expr *DefaultArg, SourceLocation EqualLoc)
void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD)
ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in it, apply them to D.
void FilterLookupForScope(LookupResult &R, DeclContext *Ctx, Scope *S, bool ConsiderLinkage, bool AllowInlineNamespace)
Filters out lookup results that don't fall within the given scope as determined by isDeclInScope.
ExprResult ConvertMemberDefaultInitExpression(FieldDecl *FD, Expr *InitExpr, SourceLocation InitLoc)
bool IsInvalidSMECallConversion(QualType FromType, QualType ToType)
void checkIncorrectVTablePointerAuthenticationAttribute(CXXRecordDecl &RD)
Check that VTable Pointer authentication is only being set on the first first instantiation of the vt...
static Scope * getScopeForDeclContext(Scope *S, DeclContext *DC)
Finds the scope corresponding to the given decl context, if it happens to be an enclosing scope.
bool isUsualDeallocationFunction(const CXXMethodDecl *FD)
void DiagnoseDeletedDefaultedFunction(FunctionDecl *FD)
Produce notes explaining why a defaulted function was defined as deleted.
ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)
bool CheckOverridingFunctionExceptionSpec(const CXXMethodDecl *New, const CXXMethodDecl *Old)
CheckOverridingFunctionExceptionSpec - Checks whether the exception spec is a subset of base spec.
SmallVector< CXXRecordDecl *, 4 > DelayedDllExportClasses
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
bool CheckTemplateParameterList(TemplateParameterList *NewParams, TemplateParameterList *OldParams, TemplateParamListContext TPC, SkipBodyInfo *SkipBody=nullptr)
Checks the validity of a template parameter list, possibly considering the template parameter list fr...
bool CheckOverridingFunctionReturnType(const CXXMethodDecl *New, const CXXMethodDecl *Old)
CheckOverridingFunctionReturnType - Checks whether the return types are covariant,...
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
UnsignedOrNone GetDecompositionElementCount(QualType DecompType, SourceLocation Loc)
Decl * ActOnDeclarator(Scope *S, Declarator &D)
MSPropertyDecl * HandleMSProperty(Scope *S, RecordDecl *TagD, SourceLocation DeclStart, Declarator &D, Expr *BitfieldWidth, InClassInitStyle InitStyle, AccessSpecifier AS, const ParsedAttr &MSPropertyAttr)
HandleMSProperty - Analyze a __delcspec(property) field of a C++ class.
void UpdateExceptionSpec(FunctionDecl *FD, const FunctionProtoType::ExceptionSpecInfo &ESI)
bool CheckRedeclarationInModule(NamedDecl *New, NamedDecl *Old)
A wrapper function for checking the semantic restrictions of a redeclaration within a module.
LazyDeclPtr StdAlignValT
The C++ "std::align_val_t" enum class, which is defined by the C++ standard library.
void ActOnPureSpecifier(Decl *D, SourceLocation PureSpecLoc)
@ CheckValid
Identify whether this function satisfies the formal rules for constexpr functions in the current lanu...
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
void LoadExternalVTableUses()
Load any externally-stored vtable uses.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
Decl * ActOnUsingDirective(Scope *CurScope, SourceLocation UsingLoc, SourceLocation NamespcLoc, CXXScopeSpec &SS, SourceLocation IdentLoc, IdentifierInfo *NamespcName, const ParsedAttributesView &AttrList)
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
void HandleFunctionTypeMismatch(PartialDiagnostic &PDiag, QualType FromType, QualType ToType)
HandleFunctionTypeMismatch - Gives diagnostic information for differeing function types.
void ActOnStartTrailingRequiresClause(Scope *S, Declarator &D)
void FindHiddenVirtualMethods(CXXMethodDecl *MD, SmallVectorImpl< CXXMethodDecl * > &OverloadedMethods)
Check if a method overloads virtual methods in a base class without overriding any.
IdentifierResolver IdResolver
DeclContextLookupResult LookupConstructors(CXXRecordDecl *Class)
Look up the constructors for the given class.
void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record)
ExprResult ActOnCXXThis(SourceLocation Loc)
CXXConstructorDecl * findInheritingConstructor(SourceLocation Loc, CXXConstructorDecl *BaseCtor, ConstructorUsingShadowDecl *DerivedShadow)
Given a derived-class using shadow declaration for a constructor and the correspnding base class cons...
void warnOnReservedIdentifier(const NamedDecl *D)
bool CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD, CXXSpecialMemberKind CSM, SourceLocation DefaultLoc)
bool isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS)
Determine whether the identifier II is a typo for the name of the class type currently being defined.
Decl * ActOnUsingDeclaration(Scope *CurScope, AccessSpecifier AS, SourceLocation UsingLoc, SourceLocation TypenameLoc, CXXScopeSpec &SS, UnqualifiedId &Name, SourceLocation EllipsisLoc, const ParsedAttributesView &AttrList)
void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param)
ActOnDelayedCXXMethodParameter - We've already started a delayed C++ method declaration.
bool isAbstractType(SourceLocation Loc, QualType T)
bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param, Expr *Init=nullptr, bool SkipImmediateInvocations=true)
Instantiate or parse a C++ default argument expression as necessary.
ValueDecl * tryLookupUnambiguousFieldDecl(RecordDecl *ClassDecl, const IdentifierInfo *MemberOrBase)
ASTMutationListener * getASTMutationListener() const
bool SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors, ArrayRef< CXXCtorInitializer * > Initializers={})
void DiagnoseImmediateEscalatingReason(FunctionDecl *FD)
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
CXXDestructorDecl * DeclareImplicitDestructor(CXXRecordDecl *ClassDecl)
Declare the implicit destructor for the given class.
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
static StaticAssertDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StaticAssertLoc, Expr *AssertExpr, Expr *Message, SourceLocation RParenLoc, bool Failed)
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
StmtClass getStmtClass() const
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
static bool isValidUDSuffix(const LangOptions &LangOpts, StringRef Suffix)
Determine whether a suffix is a valid ud-suffix.
StringLiteral - This represents a string literal expression, e.g.
bool isUnevaluated() const
StringRef getString() const
Represents the declaration of a struct/union/class/enum.
bool isBeingDefined() const
Return true if this decl is currently being defined.
StringRef getKindName() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TagDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
TagKind getTagKind() const
bool isDependentType() const
Whether this declaration declares a type that is dependent, i.e., a type that somehow depends on temp...
void setElaboratedKeywordLoc(SourceLocation Loc)
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
A convenient class for passing around template argument information.
void addArgument(const TemplateArgumentLoc &Loc)
ArrayRef< TemplateArgumentLoc > arguments() const
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
TypeSourceInfo * getTypeSourceInfo() const
Represents a template argument.
@ Type
The template argument is a type.
ArgKind getKind() const
Return the kind of stored template argument.
The base class of all kinds of template declarations (e.g., class, function, etc.).
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
SourceRange getSourceRange() const LLVM_READONLY
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
unsigned getMinRequiredArguments() const
Returns the minimum number of arguments needed to form a template specialization.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
Expr * getRequiresClause()
The constraint-expression of the associated requires-clause.
SourceLocation getRAngleLoc() const
SourceLocation getLAngleLoc() const
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
SourceLocation getTemplateLoc() const
unsigned getNumArgs() const
TemplateArgumentLoc getArgLoc(unsigned i) const
Declaration of a template type parameter.
unsigned getIndex() const
Retrieve the index of the template parameter.
unsigned getDepth() const
Retrieve the depth of the template parameter.
The top declaration context.
Represents the declaration of a typedef-name via a C++11 alias-declaration.
static TypeAliasDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, TypeSourceInfo *TInfo)
void setDescribedAliasTemplate(TypeAliasTemplateDecl *TAT)
Declaration of an alias template.
static TypeAliasTemplateDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name, TemplateParameterList *Params, NamedDecl *Decl)
Create a function template node.
TypeAliasDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
Represents a declaration of a type.
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
TypeSpecTypeLoc pushTypeSpec(QualType T)
Pushes space for a typespec TypeLoc.
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
Base wrapper for a particular "section" of type source info.
QualType getType() const
Get the type for which this source info wrapper provides information.
TypeLoc getNextTypeLoc() const
Get the next TypeLoc pointed by this TypeLoc, e.g for "int*" the TypeLoc is a PointerLoc and next Typ...
T getAs() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
TypeLoc IgnoreParens() const
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
SourceRange getLocalSourceRange() const
Get the local source range.
TypeLocClass getTypeLocClass() const
SourceLocation getEndLoc() const
Get the end source location.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
SourceLocation getBeginLoc() const
Get the begin source location.
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
void setNameLoc(SourceLocation Loc)
The base class of the type hierarchy.
bool isBooleanType() const
const TemplateSpecializationType * getAsNonAliasTemplateSpecializationType() const
Look through sugar for an instance of TemplateSpecializationType which is not a type alias,...
bool isIncompleteArrayType() const
bool isUndeducedAutoType() const
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
CanQualType getCanonicalTypeUnqualified() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
bool isLValueReferenceType() const
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool containsUnexpandedParameterPack() const
Whether this type is or contains an unexpanded parameter pack, used to support C++0x variadic templat...
QualType getCanonicalTypeInternal() const
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isFunctionProtoType() const
bool isOverloadableType() const
Determines whether this is a type for which one can define an overloaded operator.
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isFunctionType() const
bool isStructureOrClassType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isUnsignedIntegerType() const
Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
Base class for declarations which introduce a typedef-name.
QualType getUnderlyingType() const
Wrapper for source info for typedefs.
Simple class containing the result of Sema::CorrectTypo.
NamedDecl * getCorrectionDecl() const
Gets the pointer to the declaration of the typo correction.
SourceRange getCorrectionRange() const
void WillReplaceSpecifier(bool ForceReplacement)
DeclClass * getCorrectionDeclAs() const
NestedNameSpecifier getCorrectionSpecifier() const
Gets the NestedNameSpecifier needed to use the typo correction.
NamedDecl * getFoundDecl() const
Get the correction declaration found by name lookup (before we looked through using shadow declaratio...
Expr * getSubExpr() const
static bool isIncrementDecrementOp(Opcode Op)
static UnaryOperator * Create(const ASTContext &C, Expr *input, Opcode opc, QualType type, ExprValueKind VK, ExprObjectKind OK, SourceLocation l, bool CanOverflow, FPOptionsOverride FPFeatures)
Represents a C++ unqualified-id that has been parsed.
UnionParsedType ConversionFunctionId
When Kind == IK_ConversionFunctionId, the type that the conversion function names.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
UnionParsedType DestructorName
When Kind == IK_DestructorName, the type referred to by the class-name.
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
UnionParsedTemplateTy TemplateName
When Kind == IK_DeductionGuideName, the parsed template-name.
const IdentifierInfo * Identifier
When Kind == IK_Identifier, the parsed identifier, or when Kind == IK_UserLiteralId,...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
TemplateIdAnnotation * TemplateId
When Kind == IK_TemplateId or IK_ConstructorTemplateId, the template-id annotation that contains the ...
static UnresolvedLookupExpr * Create(const ASTContext &Context, CXXRecordDecl *NamingClass, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool RequiresADL, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, bool KnownInstantiationDependent)
A set of unresolved declarations.
ArrayRef< DeclAccessPair > pairs() const
The iterator over UnresolvedSets.
A set of unresolved declarations.
This node is generated when a using-declaration that was annotated with attribute((using_if_exists)) ...
static UnresolvedUsingIfExistsDecl * Create(ASTContext &Ctx, DeclContext *DC, SourceLocation Loc, DeclarationName Name)
Wrapper for source info for unresolved typename using decls.
static UnresolvedUsingTypenameDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation TypenameLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation TargetNameLoc, DeclarationName TargetName, SourceLocation EllipsisLoc)
static UnresolvedUsingValueDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, SourceLocation EllipsisLoc)
Represents a C++ using-declaration.
bool hasTypename() const
Return true if the using declaration has 'typename'.
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
DeclarationNameInfo getNameInfo() const
static UsingDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingL, NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo, bool HasTypenameKeyword)
SourceLocation getUsingLoc() const
Return the source location of the 'using' keyword.
Represents C++ using-directive.
static UsingDirectiveDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingLoc, SourceLocation NamespaceLoc, NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc, NamedDecl *Nominated, DeclContext *CommonAncestor)
Represents a C++ using-enum-declaration.
static UsingEnumDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation UsingL, SourceLocation EnumL, SourceLocation NameL, TypeSourceInfo *EnumType)
static UsingPackDecl * Create(ASTContext &C, DeclContext *DC, NamedDecl *InstantiatedFrom, ArrayRef< NamedDecl * > UsingDecls)
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
static UsingShadowDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation Loc, DeclarationName Name, BaseUsingDecl *Introducer, NamedDecl *Target)
NamedDecl * getTargetDecl() const
Gets the underlying declaration which has been brought into the local scope.
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
BaseUsingDecl * getIntroducer() const
Gets the (written or instantiated) using declaration that introduced this declaration.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
void setType(QualType newType)
bool isParameterPack() const
Determine whether this value is actually a function parameter pack, init-capture pack,...
Represents a variable declaration or definition.
VarTemplateDecl * getDescribedVarTemplate() const
Retrieves the variable template that is described by this variable declaration.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
DefinitionKind isThisDeclarationADefinition(ASTContext &) const
Check whether this declaration is a definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isNoDestroy(const ASTContext &) const
Is destruction of this variable entirely suppressed?
bool isInlineSpecified() const
APValue * evaluateValue() const
Attempt to evaluate the value of the initializer attached to this declaration, and produce notes expl...
bool isStaticDataMember() const
Determines whether this is a static data member.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool evaluateDestruction(SmallVectorImpl< PartialDiagnosticAt > &Notes) const
Evaluate the destruction of this variable to determine if it constitutes constant destruction.
bool isStaticLocal() const
Returns true if a variable with function scope is a static local variable.
QualType::DestructionKind needsDestruction(const ASTContext &Ctx) const
Would the destruction of this variable have any effect, and if so, what kind?
ThreadStorageClassSpecifier getTSCSpec() const
const Expr * getInit() const
@ TLS_Dynamic
TLS with a dynamic initializer.
StorageClass getStorageClass() const
Returns the storage class as written in the source.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
void setExceptionVariable(bool EV)
Declaration of a variable template.
Represents a GCC generic vector type.
unsigned getNumElements() const
QualType getElementType() const
Represents a C++11 virt-specifier-seq.
SourceLocation getOverrideLoc() const
SourceLocation getLastLocation() const
bool isOverrideSpecified() const
SourceLocation getFinalLoc() const
bool isFinalSpecified() const
bool isFinalSpelledSealed() const
Retains information about a function, method, or block that is currently being parsed.
bool FoundImmediateEscalatingExpression
Whether we found an immediate-escalating expression.
Provides information about an attempted template argument deduction, whose success or failure was des...
Defines the clang::TargetInfo interface.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
bool Comp(InterpState &S, CodePtr OpPC)
1) Pops the value from the stack.
bool Inc(InterpState &S, CodePtr OpPC, bool CanOverflow)
1) Pops a pointer from the stack 2) Load the value from the pointer 3) Writes the value increased by ...
std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl
All declarations that can appear in a module declaration.
The JSON file list parser is used to communicate input to InstallAPI.
bool FTIHasNonVoidParameters(const DeclaratorChunk::FunctionTypeInfo &FTI)
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
@ TST_typename_pack_indexing
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ OO_None
Not an overloaded operator.
@ NUM_OVERLOADED_OPERATORS
@ NonFunction
This is not an overload because the lookup results contain a non-function.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
@ Overload
This is a legitimate overload: the existing declarations are functions or function templates with dif...
bool isa(CodeGen::Address addr)
bool isTemplateInstantiation(TemplateSpecializationKind Kind)
Determine whether this template specialization kind refers to an instantiation of an entity (as oppos...
MutableArrayRef< TemplateParameterList * > MultiTemplateParamsArg
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
@ OR_Ambiguous
Ambiguous candidates found.
@ OR_No_Viable_Function
No viable function found.
ConstexprSpecKind
Define the kind of constexpr specifier.
LinkageSpecLanguageIDs
Represents the language in a linkage specification.
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
@ NotFound
No entity found met the criteria.
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
@ Found
Name lookup found a single declaration that met the criteria.
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
LLVM_READONLY auto escapeCStyle(CharT Ch) -> StringRef
Return C-style escaped string for special characters, or an empty string if there is no such mapping.
@ Comparison
A comparison.
InClassInitStyle
In-class initialization styles for non-static data members.
@ ICIS_ListInit
Direct list-initialization.
@ ICIS_NoInit
No in-class initializer.
@ RQ_None
No ref-qualifier was provided.
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
@ OCD_AmbiguousCandidates
Requests that only tied-for-best candidates be shown.
@ OCD_AllCandidates
Requests that all candidates be shown.
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ Redeclaration
Merge availability attributes for a redeclaration, which requires an exact match.
std::pair< llvm::PointerUnion< const TemplateTypeParmType *, NamedDecl *, const TemplateSpecializationType *, const SubstBuiltinTemplatePackType * >, SourceLocation > UnexpandedParameterPack
@ If
'if' clause, allowed on all the Compute Constructs, Data Constructs, Executable Constructs,...
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
@ Delete
'delete' clause, allowed on the 'exit data' construct.
@ IK_DeductionGuideName
A deduction-guide name (a template-name)
@ IK_ImplicitSelfParam
An implicit 'self' parameter.
@ IK_TemplateId
A template-id, e.g., f<int>.
@ IK_ConstructorTemplateId
A constructor named via a template-id.
@ IK_ConstructorName
A constructor name.
@ IK_LiteralOperatorId
A user-defined literal name, e.g., operator "" _i.
@ IK_Identifier
An identifier.
@ IK_DestructorName
A destructor name.
@ IK_OperatorFunctionId
An overloaded operator name, e.g., operator+.
@ IK_ConversionFunctionId
A conversion function name, e.g., operator int.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
std::optional< ComparisonCategoryType > getComparisonCategoryForBuiltinCmp(QualType T)
Get the comparison category that should be used when comparing values of type T.
ActionResult< Decl * > DeclResult
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
ComparisonCategoryType commonComparisonType(ComparisonCategoryType A, ComparisonCategoryType B)
Determine the common comparison type, as defined in C++2a [class.spaceship]p4.
@ Dependent
Parse the block as a dependent block, which may be used in some template instantiations but not other...
ComparisonCategoryResult
An enumeration representing the possible results of a three-way comparison.
MutableArrayRef< Expr * > MultiExprArg
Language
The language for the input, used to select and validate the language standard and possible actions.
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
std::pair< unsigned, unsigned > getDepthAndIndex(const NamedDecl *ND)
Retrieve the depth and index of a template parameter.
InheritableAttr * getDLLAttr(Decl *D)
Return a DLL attribute from the declaration.
ActionResult< CXXCtorInitializer * > MemInitResult
llvm::Expected< QualType > ExpectedType
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
@ Template
We are parsing a template declaration.
ActionResult< CXXBaseSpecifier * > BaseResult
void EscapeStringForDiagnostic(StringRef Str, SmallVectorImpl< char > &OutStr)
EscapeStringForDiagnostic - Append Str to the diagnostic buffer, escaping non-printable characters an...
ReservedLiteralSuffixIdStatus
TagTypeKind
The kind of a tag type.
@ Interface
The "__interface" keyword.
@ Struct
The "struct" keyword.
@ Class
The "class" keyword.
@ Keyword
The name has been typo-corrected to a keyword.
@ Type
The name was classified as a type.
LangAS
Defines the address space values used by the address space qualifier of QualType.
@ CanPassInRegs
The argument of this type can be passed directly in registers.
@ CanNeverPassInRegs
The argument of this type cannot be passed directly in registers.
@ CannotPassInRegs
The argument of this type cannot be passed directly in registers.
@ TU_Prefix
The translation unit is a prefix to a translation unit, and is not complete.
ComparisonCategoryType
An enumeration representing the different comparison categories types.
CXXSpecialMemberKind
Kinds of C++ special members.
OverloadedOperatorKind getRewrittenOverloadedOperator(OverloadedOperatorKind Kind)
Get the other overloaded operator that the given operator can be rewritten into, if any such operator...
@ TNK_Concept_template
The name refers to a concept.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
SmallVector< CXXBaseSpecifier *, 4 > CXXCastPath
A simple array of base specifiers.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
@ ConsiderTrivialABI
The triviality of a method affected by "trivial_abi".
@ IgnoreTrivialABI
The triviality of a method unaffected by "trivial_abi".
@ Incomplete
Template argument deduction did not deduce a value for every template parameter.
@ Success
Template argument deduction was successful.
@ Inconsistent
Template argument deduction produced inconsistent deduced values for the given template parameter.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
CallingConv
CallingConv - Specifies the calling convention that a function uses.
TypeAwareAllocationMode typeAwareAllocationModeFromBool(bool IsTypeAwareAllocation)
U cast(CodeGen::Address addr)
@ StaticAssertMessageData
Call to data() in a static assert message.
@ StaticAssertMessageSize
Call to size() in a static assert message.
@ ExplicitBool
Condition in an explicit(bool) specifier.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
ElaboratedTypeKeyword
The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Enum
The "enum" keyword introduces the elaborated-type-specifier.
bool isLambdaMethod(const DeclContext *DC)
bool isExternallyVisible(Linkage L)
ActionResult< Expr * > ExprResult
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_DependentNoexcept
noexcept(expression), value-dependent
@ EST_Uninstantiated
not instantiated yet
@ EST_Unparsed
not parsed yet
@ EST_NoThrow
Microsoft __declspec(nothrow) extension.
@ EST_None
no exception specification
@ EST_MSAny
Microsoft throw(...) extension.
@ EST_BasicNoexcept
noexcept
@ EST_NoexceptFalse
noexcept(expression), evals to 'false'
@ EST_Unevaluated
not evaluated yet, for special member function
@ EST_NoexceptTrue
noexcept(expression), evals to 'true'
@ EST_Dynamic
throw(T1, T2)
ActionResult< Stmt * > StmtResult
@ NOUR_Unevaluated
This name appears in an unevaluated operand.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
Represents an element in a path from a derived class to a base class.
bool hasValidIntValue() const
True iff we've successfully evaluated the variable as a constant expression and extracted its integer...
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
SourceLocation getLoc() const
getLoc - Returns the main location of the declaration name.
DeclarationName getName() const
getName - Returns the embedded declaration name.
void setNamedTypeInfo(TypeSourceInfo *TInfo)
setNamedTypeInfo - Sets the source type info associated to the name.
void setName(DeclarationName N)
setName - Sets the embedded declaration name.
SourceLocation getBeginLoc() const
getBeginLoc - Retrieve the location of the first token.
SourceRange getSourceRange() const LLVM_READONLY
getSourceRange - The range of the declaration name.
SourceLocation getEndLoc() const LLVM_READONLY
bool containsUnexpandedParameterPack() const
Determine whether this name contains an unexpanded parameter pack.
unsigned isVariadic
isVariadic - If this function has a prototype, and if that proto ends with ',...)',...
ParamInfo * Params
Params - This is a pointer to a new[]'d array of ParamInfo objects that describe the parameters speci...
unsigned RefQualifierIsLValueRef
Whether the ref-qualifier (if any) is an lvalue reference.
DeclSpec * MethodQualifiers
DeclSpec for the function with the qualifier related info.
SourceLocation getRefQualifierLoc() const
Retrieve the location of the ref-qualifier, if any.
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
bool hasMutableQualifier() const
Determine whether this lambda-declarator contains a 'mutable' qualifier.
bool hasMethodTypeQualifiers() const
Determine whether this method has qualifiers.
void freeParams()
Reset the parameter list to having zero parameters.
bool hasRefQualifier() const
Determine whether this function declaration contains a ref-qualifier.
std::unique_ptr< CachedTokens > DefaultArgTokens
DefaultArgTokens - When the parameter's default argument cannot be parsed immediately (because it occ...
One instance of this struct is used for each type in a declarator that is parsed.
SourceRange getSourceRange() const
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
EvalResult is a struct with detailed info about an evaluated expression.
A simple structure that captures a vtable use for the purposes of the ExternalSemaSource.
Holds information about the various types of exception specification.
FunctionDecl * SourceDecl
The function whose exception specification this is, for EST_Unevaluated and EST_Uninstantiated.
ExceptionSpecificationType Type
The kind of exception specification this is.
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Expr * NoexceptExpr
Noexcept expression, if this is a computed noexcept specification.
Extra information about a function prototype.
ExceptionSpecInfo ExceptionSpec
FunctionEffectsRef FunctionEffects
RefQualifierKind RefQualifier
FunctionType::ExtInfo ExtInfo
static StringRef getTagTypeKindName(TagTypeKind Kind)
static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag)
Converts a TagTypeKind into an elaborated type keyword.
static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec)
Converts a type specifier (DeclSpec::TST) into a tag type kind.
Describes how types, statements, expressions, and declarations should be printed.
A context in which code is being synthesized (where a source location alone is not sufficient to iden...
enum clang::Sema::CodeSynthesisContext::SynthesisKind Kind
SourceLocation PointOfInstantiation
The point of instantiation or synthesis within the source code.
@ MarkingClassDllexported
We are marking a class as __dllexport.
@ InitializingStructuredBinding
We are initializing a structured binding.
@ ExceptionSpecEvaluation
We are computing the exception specification for a defaulted special member function.
@ DeclaringImplicitEqualityComparison
We are declaring an implicit 'operator==' for a defaulted 'operator<=>'.
Decl * Entity
The entity that is being synthesized.
Abstract class used to diagnose incomplete types.
virtual void diagnose(Sema &S, SourceLocation Loc, QualType T)=0
Information about a template-id annotation token.
TemplateNameKind Kind
The kind of template that Template refers to.
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
SourceLocation RAngleLoc
The location of the '>' after the template argument list.
SourceLocation LAngleLoc
The location of the '<' before the template argument list.
OpaquePtr< T > get() const