clang: lib/Sema/DeclSpec.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
25#include
26using namespace clang;
27
28
30 assert(TemplateId && "NULL template-id annotation?");
32 "should not convert invalid template-ids to unqualified-ids");
33
38}
39
41 assert(TemplateId && "NULL template-id annotation?");
43 "should not convert invalid template-ids to unqualified-ids");
44
49}
50
53 Builder.Make(Context, TL, ColonColonLoc);
54 if (Range.getBegin().isInvalid())
56 Range.setEnd(ColonColonLoc);
57
58 assert(Range == Builder.getSourceRange() &&
59 "NestedNameSpecifierLoc range computation incorrect");
60}
61
65 Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
66
67 if (Range.getBegin().isInvalid())
68 Range.setBegin(NamespaceLoc);
69 Range.setEnd(ColonColonLoc);
70
71 assert(Range == Builder.getSourceRange() &&
72 "NestedNameSpecifierLoc range computation incorrect");
73}
74
77 Builder.MakeGlobal(Context, ColonColonLoc);
78
80
81 assert(Range == Builder.getSourceRange() &&
82 "NestedNameSpecifierLoc range computation incorrect");
83}
84
88 Builder.MakeMicrosoftSuper(Context, RD, SuperLoc, ColonColonLoc);
89
90 Range.setBegin(SuperLoc);
91 Range.setEnd(ColonColonLoc);
92
93 assert(Range == Builder.getSourceRange() &&
94 "NestedNameSpecifierLoc range computation incorrect");
95}
96
99 Builder.MakeTrivial(Context, Qualifier, R);
100 Range = R;
101}
102
106 Builder.Clear();
107 return;
108 }
109
110 Range = Other.getSourceRange();
111 Builder.Adopt(Other);
112 assert(Range == Builder.getSourceRange() &&
113 "NestedNameSpecifierLoc range computation incorrect");
114}
115
117 if (!Builder.getRepresentation())
119 return Builder.getTemporary().getLocalBeginLoc();
120}
121
124 if (!Builder.getRepresentation())
126
127 return Builder.getWithLocInContext(Context);
128}
129
130
131
133 bool isAmbiguous,
136 unsigned NumParams,
139 bool RefQualifierIsLvalueRef,
143 ESpecType,
147 unsigned NumExceptions,
148 Expr *NoexceptExpr,
151 DeclsInPrototype,
157 TrailingReturnTypeLoc,
158 DeclSpec *MethodQualifiers) {
160 "function cannot have _Atomic qualifier");
161
164 I.Loc = LocalRangeBegin;
165 I.EndLoc = LocalRangeEnd;
191
192 if (MethodQualifiers && (MethodQualifiers->getTypeQualifiers() ||
199 });
202 }
203
205
206
207 if (NumParams) {
208
209
210
211
212 if (!TheDeclarator.InlineStorageUsed &&
213 NumParams <= std::size(TheDeclarator.InlineParams)) {
217 TheDeclarator.InlineStorageUsed = true;
218 } else {
221 }
222 for (unsigned i = 0; i < NumParams; i++)
223 I.Fun.Params[i] = std::move(Params[i]);
224 }
225
226
227 switch (ESpecType) {
228 default: break;
230
231 if (NumExceptions) {
234 for (unsigned i = 0; i != NumExceptions; ++i) {
237 }
238 }
239 break;
240
245 break;
246
249 break;
250 }
251
252 if (!DeclsInPrototype.empty()) {
253 assert(ESpecType == EST_None && NumExceptions == 0 &&
254 "cannot have exception specifiers and decls in prototype");
256
258 for (size_t J = 0; J < DeclsInPrototype.size(); ++J)
260 }
261
262 return I;
263}
264
269 assert(() && "declarator given multiple names!");
270
271 BindingGroup.LSquareLoc = LSquareLoc;
272 BindingGroup.RSquareLoc = RSquareLoc;
273 BindingGroup.NumBindings = Bindings.size();
274 Range.setEnd(RSquareLoc);
275
276
278 Name.EndLocation = RSquareLoc;
279
280
284 BindingGroup.DeleteBindings = false;
285 InlineStorageUsed = true;
286 } else {
287 BindingGroup.Bindings =
289 BindingGroup.DeleteBindings = true;
290 }
292 BindingGroup.Bindings);
293 }
294}
295
297 for (unsigned i = 0, i_end = DeclTypeInfo.size(); i < i_end; ++i) {
298 switch (DeclTypeInfo[i].Kind) {
300 return true;
302 continue;
309 return false;
310 }
311 llvm_unreachable("Invalid type chunk");
312 }
313
314 switch (DS.getTypeSpecType()) {
349#define GENERIC_IMAGE_TYPE(ImgType, Id) case TST_##ImgType##_t:
350#include "clang/Basic/OpenCLImageTypes.def"
351#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) case TST_##Name:
352#include "clang/Basic/HLSLIntangibleTypes.def"
353 return false;
354
356
357
358 return false;
359
363 if (Expr *E = DS.getRepAsExpr())
364 return E->getType()->isFunctionType();
365 return false;
366
367#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) case TST_##Trait:
368#include "clang/Basic/TransformTypeTraits.def"
372 QualType QT = DS.getRepAsType().get();
374 return false;
375
376 if (const LocInfoType *LIT = dyn_cast(QT))
377 QT = LIT->getType();
378
380 return false;
381
383 }
384 }
385
386 llvm_unreachable("Invalid TypeSpecType!");
387}
388
395 getName().OperatorFunctionId.Operator));
396}
397
400 return false;
403 auto *P = dyn_cast_or_null(Fun.Params[0].Param);
404 if (P && P->isExplicitObjectParameter())
405 return true;
406 }
407 return false;
408}
409
414
416 llvm::function_ref<void(TQ, StringRef, SourceLocation)> Handle) {
417 if (TypeQualifiers & TQ_const)
418 Handle(TQ_const, "const", TQ_constLoc);
420 Handle(TQ_volatile, "volatile", TQ_volatileLoc);
422 Handle(TQ_restrict, "restrict", TQ_restrictLoc);
424 Handle(TQ_unaligned, "unaligned", TQ_unalignedLoc);
425}
426
432
434 if (!TypeSpecOwned)
435 return false;
437}
438
439
440
441
443 unsigned Res = 0;
447
450
453
455 FS_noreturn_specified || FS_forceinline_specified)
457 return Res;
458}
459
461 const char *&PrevSpec,
462 unsigned &DiagID,
463 bool IsExtension = true) {
465 if (TNew != TPrev)
466 DiagID = diag::err_invalid_decl_spec_combination;
467 else
468 DiagID = IsExtension ? diag::ext_warn_duplicate_declspec :
469 diag::warn_duplicate_declspec;
470 return true;
471}
472
474 switch (S) {
483 }
484 llvm_unreachable("Unknown typespec!");
485}
486
488 switch (S) {
493 }
494 llvm_unreachable("Unknown typespec!");
495}
496
498 switch (W) {
500 return "unspecified";
502 return "short";
504 return "long";
506 return "long long";
507 }
508 llvm_unreachable("Unknown typespec!");
509}
510
512 switch (C) {
516 }
517 llvm_unreachable("Unknown typespec!");
518}
519
521 switch (S) {
523 return "unspecified";
525 return "signed";
527 return "unsigned";
528 }
529 llvm_unreachable("Unknown typespec!");
530}
531
534 switch (T) {
564 return "type-name-pack-indexing";
573#define TRANSFORM_TYPE_TRAIT_DEF(_, Trait) \
574 case DeclSpec::TST_##Trait: \
575 return "__" #Trait;
576#include "clang/Basic/TransformTypeTraits.def"
580#define GENERIC_IMAGE_TYPE(ImgType, Id) \
581 case DeclSpec::TST_##ImgType##_t: \
582 return #ImgType "_t";
583#include "clang/Basic/OpenCLImageTypes.def"
584#define HLSL_INTANGIBLE_TYPE(Name, Id, SingletonId) \
585 case DeclSpec::TST_##Name: \
586 return #Name;
587#include "clang/Basic/HLSLIntangibleTypes.def"
589 }
590 llvm_unreachable("Unknown typespec!");
591}
592
594 switch (C) {
596 return "unspecified";
598 return "constexpr";
600 return "consteval";
602 return "constinit";
603 }
604 llvm_unreachable("Unknown ConstexprSpecKind");
605}
606
608 switch (T) {
615 }
616 llvm_unreachable("Unknown typespec!");
617}
618
620 const char *&PrevSpec,
621 unsigned &DiagID,
623
624
625
626
627
628
629
632 "cl_clang_storage_class_specifiers", S.getLangOpts())) {
633 switch (SC) {
638 DiagID = diag::err_opencl_unknown_type_specifier;
640 return true;
641 }
642 break;
645 DiagID = diag::err_opencl_unknown_type_specifier;
647 return true;
648 default:
649 break;
650 }
651 }
652
654
659 if (StorageClassSpec == SCS_auto) {
661 PrevSpec, DiagID, Policy);
662 assert( && "auto SCS -> TST recovery failed");
663 }
664 }
665
666
667
668
670 !(SCS_extern_in_linkage_spec &&
673 return BadSpecifier(SC, (SCS)StorageClassSpec, PrevSpec, DiagID);
674 }
675 StorageClassSpec = SC;
676 StorageClassSpecLoc = Loc;
677 assert((unsigned)SC == StorageClassSpec && "SCS constants overflow bitfield");
678 return false;
679}
680
682 const char *&PrevSpec,
683 unsigned &DiagID) {
685 return BadSpecifier(TSC, (TSCS)ThreadStorageClassSpec, PrevSpec, DiagID);
686
687 ThreadStorageClassSpec = TSC;
688 ThreadStorageClassSpecLoc = Loc;
689 return false;
690}
691
692
693
694
696 const char *&PrevSpec, unsigned &DiagID,
698
699
701 TSWRange.setBegin(Loc);
702
706 TypeSpecWidth = static_cast<unsigned>(W);
707
708 TSWRange.setEnd(Loc);
709 return false;
710}
711
713 const char *&PrevSpec,
714 unsigned &DiagID) {
716 return BadSpecifier(C, (TSC)TypeSpecComplex, PrevSpec, DiagID);
717 TypeSpecComplex = C;
718 TSCLoc = Loc;
719 return false;
720}
721
723 const char *&PrevSpec, unsigned &DiagID) {
726 TypeSpecSign = static_cast<unsigned>(S);
727 TSSLoc = Loc;
728 return false;
729}
730
732 const char *&PrevSpec,
733 unsigned &DiagID,
736 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Policy);
737}
738
741 const char *&PrevSpec,
742 unsigned &DiagID,
745 assert(isTypeRep(T) && "T does not store a type");
746 assert(Rep && "no type provided!");
748 return false;
751 DiagID = diag::err_invalid_decl_spec_combination;
752 return true;
753 }
754 TypeSpecType = T;
756 TSTLoc = TagKwLoc;
757 TSTNameLoc = TagNameLoc;
758 TypeSpecOwned = false;
759
761
762
766 PackIndexingExpr = LIT->getIndexExpr();
767 }
768 return false;
769}
770
772 const char *&PrevSpec,
773 unsigned &DiagID,
776 assert(isExprRep(T) && "T does not store an expr");
777 assert(Rep && "no expression provided!");
779 return false;
782 DiagID = diag::err_invalid_decl_spec_combination;
783 return true;
784 }
785 TypeSpecType = T;
787 TSTLoc = Loc;
788 TSTNameLoc = Loc;
789 TypeSpecOwned = false;
790 return false;
791}
792
794 const char *&PrevSpec,
795 unsigned &DiagID,
796 Decl *Rep, bool Owned,
798 return SetTypeSpecType(T, Loc, Loc, PrevSpec, DiagID, Rep, Owned, Policy);
799}
800
803 const char *&PrevSpec,
804 unsigned &DiagID,
805 Decl *Rep, bool Owned,
807 assert(isDeclRep(T) && "T does not store a decl");
808
809
811 return false;
814 DiagID = diag::err_invalid_decl_spec_combination;
815 return true;
816 }
817 TypeSpecType = T;
819 TSTLoc = TagKwLoc;
820 TSTNameLoc = TagNameLoc;
821 TypeSpecOwned = Owned && Rep != nullptr;
822 return false;
823}
824
829 ConstrainedAuto = true;
832}
833
835 const char *&PrevSpec,
836 unsigned &DiagID,
839 "rep required for these type-spec kinds!");
841 return false;
844 DiagID = diag::err_invalid_decl_spec_combination;
845 return true;
846 }
847 TSTLoc = Loc;
848 TSTNameLoc = Loc;
849 if (TypeAltiVecVector && (T == TST_bool) && !TypeAltiVecBool) {
850 TypeAltiVecBool = true;
851 return false;
852 }
853 TypeSpecType = T;
854 TypeSpecOwned = false;
855 return false;
856}
857
859 unsigned &DiagID) {
860
861 if (TypeSpecSat) {
862 DiagID = diag::warn_duplicate_declspec;
863 PrevSpec = "_Sat";
864 return true;
865 }
866 TypeSpecSat = true;
867 TSSatLoc = Loc;
868 return false;
869}
870
872 const char *&PrevSpec, unsigned &DiagID,
875 return false;
878 DiagID = diag::err_invalid_vector_decl_spec_combination;
879 return true;
880 }
881 TypeAltiVecVector = isAltiVecVector;
882 AltiVecLoc = Loc;
883 return false;
884}
885
887 const char *&PrevSpec, unsigned &DiagID,
890 return false;
893 DiagID = diag::err_invalid_decl_spec_combination;
894 return true;
895 }
896
897 if (isPipe) {
899 }
900 return false;
901}
902
904 const char *&PrevSpec, unsigned &DiagID,
907 return false;
908 if (!TypeAltiVecVector || TypeAltiVecPixel ||
911 DiagID = diag::err_invalid_pixel_decl_spec_combination;
912 return true;
913 }
914 TypeAltiVecPixel = isAltiVecPixel;
915 TSTLoc = Loc;
916 TSTNameLoc = Loc;
917 return false;
918}
919
921 const char *&PrevSpec, unsigned &DiagID,
924 return false;
925 if (!TypeAltiVecVector || TypeAltiVecBool ||
928 DiagID = diag::err_invalid_vector_bool_decl_spec;
929 return true;
930 }
931 TypeAltiVecBool = isAltiVecBool;
932 TSTLoc = Loc;
933 TSTNameLoc = Loc;
934 return false;
935}
936
939 TypeSpecOwned = false;
942 return false;
943}
944
946 const char *&PrevSpec, unsigned &DiagID,
948 assert(BitsExpr && "no expression provided!");
950 return false;
951
954 DiagID = diag::err_invalid_decl_spec_combination;
955 return true;
956 }
957
960 TSTLoc = KWLoc;
961 TSTNameLoc = KWLoc;
962 TypeSpecOwned = false;
963 return false;
964}
965
967 Expr *IndexingExpr) {
969 "pack indexing can only be applied to typename");
971 PackIndexingExpr = IndexingExpr;
972 this->EllipsisLoc = EllipsisLoc;
973}
974
976 unsigned &DiagID, const LangOptions &Lang) {
977
978
979
980
981 if (TypeQualifiers & T) {
982 bool IsExtension = true;
983 if (Lang.C99)
984 IsExtension = false;
985 return BadSpecifier(T, T, PrevSpec, DiagID, IsExtension);
986 }
987
989}
990
992 TypeQualifiers |= T;
993
994 switch (T) {
996 case TQ_const: TQ_constLoc = Loc; return false;
997 case TQ_restrict: TQ_restrictLoc = Loc; return false;
998 case TQ_volatile: TQ_volatileLoc = Loc; return false;
999 case TQ_unaligned: TQ_unalignedLoc = Loc; return false;
1000 case TQ_atomic: TQ_atomicLoc = Loc; return false;
1001 }
1002
1003 llvm_unreachable("Unknown type qualifier!");
1004}
1005
1007 unsigned &DiagID) {
1008
1009
1010 if (FS_inline_specified) {
1011 DiagID = diag::warn_duplicate_declspec;
1012 PrevSpec = "inline";
1013 return true;
1014 }
1015 FS_inline_specified = true;
1016 FS_inlineLoc = Loc;
1017 return false;
1018}
1019
1021 unsigned &DiagID) {
1022 if (FS_forceinline_specified) {
1023 DiagID = diag::warn_duplicate_declspec;
1024 PrevSpec = "__forceinline";
1025 return true;
1026 }
1027 FS_forceinline_specified = true;
1028 FS_forceinlineLoc = Loc;
1029 return false;
1030}
1031
1033 const char *&PrevSpec,
1034 unsigned &DiagID) {
1035
1036
1037 if (FS_virtual_specified) {
1038 DiagID = diag::warn_duplicate_declspec;
1039 PrevSpec = "virtual";
1040 return true;
1041 }
1042 FS_virtual_specified = true;
1043 FS_virtualLoc = Loc;
1044 return false;
1045}
1046
1048 const char *&PrevSpec, unsigned &DiagID,
1051
1052
1054 DiagID = (ExplicitSpec.getExpr() || FS_explicit_specifier.getExpr())
1055 ? diag::err_duplicate_declspec
1056 : diag::ext_warn_duplicate_declspec;
1057 PrevSpec = "explicit";
1058 return true;
1059 }
1060 FS_explicit_specifier = ExplicitSpec;
1061 FS_explicitLoc = Loc;
1062 FS_explicitCloseParenLoc = CloseParenLoc;
1063 return false;
1064}
1065
1067 const char *&PrevSpec,
1068 unsigned &DiagID) {
1069
1070
1071 if (FS_noreturn_specified) {
1072 DiagID = diag::warn_duplicate_declspec;
1073 PrevSpec = "_Noreturn";
1074 return true;
1075 }
1076 FS_noreturn_specified = true;
1077 FS_noreturnLoc = Loc;
1078 return false;
1079}
1080
1082 unsigned &DiagID) {
1084 PrevSpec = "friend";
1085 DiagID = diag::warn_duplicate_declspec;
1086 return true;
1087 }
1088
1089 FriendSpecifiedFirst = isEmpty();
1090 FriendLoc = Loc;
1091 return false;
1092}
1093
1095 unsigned &DiagID) {
1097 PrevSpec = "__module_private__";
1098 DiagID = diag::ext_warn_duplicate_declspec;
1099 return true;
1100 }
1101
1102 ModulePrivateLoc = Loc;
1103 return false;
1104}
1105
1108 unsigned &DiagID) {
1111 DiagID);
1112 ConstexprSpecifier = static_cast<unsigned>(ConstexprKind);
1113 ConstexprLoc = Loc;
1114 return false;
1115}
1116
1117void DeclSpec::SaveWrittenBuiltinSpecs() {
1121
1123}
1124
1125
1126
1127
1129
1130 SaveWrittenBuiltinSpecs();
1131
1132
1133
1135 return;
1136
1137
1142 TypeAltiVecVector || TypeAltiVecPixel || TypeAltiVecBool ||
1143 TypeQualifiers)) {
1144 const unsigned NumLocs = 9;
1146 TSWRange.getBegin(), TSCLoc, TSSLoc,
1147 AltiVecLoc, TQ_constLoc, TQ_restrictLoc,
1148 TQ_volatileLoc, TQ_atomicLoc, TQ_unalignedLoc};
1151 for (unsigned I = 0; I != NumLocs; ++I) {
1152 if (ExtraLocs[I].isValid()) {
1155 FirstLoc))
1156 FirstLoc = ExtraLocs[I];
1158 }
1159 }
1163 TypeAltiVecVector = TypeAltiVecPixel = TypeAltiVecBool = false;
1164 TypeQualifiers = 0;
1165 S.Diag(TSTLoc, diag::err_decltype_auto_cannot_be_combined)
1166 << Hints[0] << Hints[1] << Hints[2] << Hints[3]
1167 << Hints[4] << Hints[5] << Hints[6] << Hints[7];
1168 }
1169
1170
1171 if (TypeAltiVecVector) {
1172
1176 S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_long_decl_spec);
1177
1178
1182 S.Diag(TSTLoc, diag::err_invalid_vector_int128_decl_spec);
1183
1184
1186 S.Diag(TSCLoc, diag::err_invalid_vector_complex_decl_spec);
1187 else if (TypeAltiVecBool) {
1188
1190 S.Diag(TSSLoc, diag::err_invalid_vector_bool_decl_spec)
1192 }
1193
1194
1195
1198 TypeAltiVecPixel) {
1199 S.Diag(TSTLoc, diag::err_invalid_vector_bool_decl_spec)
1200 << (TypeAltiVecPixel ? "__pixel" :
1202 }
1203
1207 S.Diag(TSTLoc, diag::err_invalid_vector_bool_int128_decl_spec);
1208
1209
1213 S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_bool_decl_spec)
1215
1216
1217 if ((TypeSpecType == TST_char) || (TypeSpecType == TST_int) ||
1221 } else if (TypeSpecType == TST_double) {
1222
1223
1226 S.Diag(TSWRange.getBegin(),
1227 diag::err_invalid_vector_long_double_decl_spec);
1230 S.Diag(TSTLoc, diag::err_invalid_vector_double_decl_spec);
1231 } else if (TypeSpecType == TST_float) {
1232
1233
1236 S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec);
1238
1239
1240
1241
1242
1243
1244
1248 S.Diag(TSWRange.getBegin(), diag::err_invalid_vector_long_decl_spec);
1249 else
1250 S.Diag(TSWRange.getBegin(),
1251 diag::warn_vector_long_decl_spec_combination)
1253 }
1254
1255 if (TypeAltiVecPixel) {
1256
1260 TypeSpecOwned = false;
1261 }
1262 }
1263
1264 bool IsFixedPointType =
1266
1267
1270 TypeSpecType = TST_int;
1271 else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
1273 !IsFixedPointType && TypeSpecType != TST_bitint) {
1274 S.Diag(TSSLoc, diag::err_invalid_sign_spec)
1276
1278 }
1279 }
1280
1281
1284 break;
1288 TypeSpecType = TST_int;
1289 else if (!(TypeSpecType == TST_int ||
1290 (IsFixedPointType &&
1292 S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
1295 TypeSpecSat = false;
1296 TypeSpecOwned = false;
1297 }
1298 break;
1301 TypeSpecType = TST_int;
1302 else if (TypeSpecType != TST_int && TypeSpecType != TST_double &&
1303 !IsFixedPointType) {
1304 S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
1307 TypeSpecSat = false;
1308 TypeSpecOwned = false;
1309 }
1310 break;
1311 }
1312
1313
1314
1317 S.Diag(TSCLoc, diag::ext_plain_complex)
1320 " double");
1321 TypeSpecType = TST_double;
1322 } else if (TypeSpecType == TST_int || TypeSpecType == TST_char) {
1323
1325 S.Diag(TSTLoc, diag::ext_integer_complex);
1329
1330 S.Diag(TSCLoc, diag::err_invalid_complex_spec)
1333 }
1334 }
1335
1336
1337
1338
1340 switch (StorageClassSpec) {
1345 break;
1346 default:
1350 diag::err_invalid_decl_spec_combination)
1353 else
1355 diag::err_invalid_decl_spec_combination)
1358
1361 }
1364 S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination)
1367 }
1368 }
1369
1374 S.Diag(ConstexprLoc, diag::err_invalid_decl_spec_combination)
1377 }
1378
1379
1380
1381
1382
1387 TSTLoc = TSTNameLoc = StorageClassSpecLoc;
1389 }
1390
1391
1394 S.Diag(TSTLoc, diag::ext_auto_type_specifier) << 0;
1398 S.Diag(TSTLoc, diag::ext_hlsl_auto_type_specifier) << 1;
1400 StorageClassSpec == SCS_auto)
1401 S.Diag(StorageClassSpecLoc, diag::warn_auto_storage_class)
1404 S.Diag(TSTLoc, diag::warn_cxx17_compat_unicode_type);
1406 S.Diag(TSTLoc, diag::warn_cxx98_compat_unicode_type)
1407 << (TypeSpecType == TST_char16 ? "char16_t" : "char32_t");
1409 S.Diag(ConstexprLoc, diag::warn_cxx98_compat_constexpr);
1411 S.Diag(ConstexprLoc, diag::warn_cxx20_compat_consteval);
1413 S.Diag(ConstexprLoc, diag::warn_cxx20_compat_constinit);
1414
1415
1416
1421 FixItHint StorageHint, ThreadHint;
1422
1427 }
1428
1430 if (!SpecName.empty()) SpecName += " ";
1434 }
1435
1436 S.Diag(SCLoc, diag::err_friend_decl_spec)
1437 << SpecName << StorageHint << ThreadHint;
1438
1440 }
1441
1442
1443
1444
1445
1446
1447
1448
1453
1458 } else {
1462 }
1463
1464 S.Diag(SCLoc, diag::err_friend_decl_spec)
1466
1467 FS_virtual_specified = false;
1470 }
1471
1472 assert(!TypeSpecOwned || isDeclRep((TST) TypeSpecType));
1473
1474
1475
1476
1477
1478
1479}
1480
1486
1495 for (unsigned I = 0; I != 3; ++I) {
1497
1498 if (SymbolLocations[I].isValid())
1500 }
1501}
1502
1504 const char *&PrevSpec) {
1505 if (!FirstLocation.isValid())
1506 FirstLocation = Loc;
1507 LastLocation = Loc;
1508 LastSpecifier = VS;
1509
1510 if (Specifiers & VS) {
1512 return true;
1513 }
1514
1515 Specifiers |= VS;
1516
1517 switch (VS) {
1518 default: llvm_unreachable("Unknown specifier!");
1519 case VS_Override: VS_overrideLoc = Loc; break;
1522 case VS_Final: VS_finalLoc = Loc; break;
1523 case VS_Abstract: VS_abstractLoc = Loc; break;
1524 }
1525
1526 return false;
1527}
1528
1530 switch (VS) {
1531 default: llvm_unreachable("Unknown specifier");
1533 case VS_Final: return "final";
1535 case VS_Sealed: return "sealed";
1537 }
1538}
Defines the clang::ASTContext interface.
static Decl::Kind getKind(const Decl *D)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static bool BadSpecifier(T TNew, T TPrev, const char *&PrevSpec, unsigned &DiagID, bool IsExtension=true)
Definition DeclSpec.cpp:460
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the clang::LangOptions interface.
llvm::SmallVector< std::pair< const MemRegion *, SVal >, 4 > Bindings
static bool isInvalid(LocType Loc, bool *Invalid)
Defines the SourceManager interface.
Defines various enumerations that describe declaration and type specifiers.
Defines the clang::TypeLoc interface and its subclasses.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const TargetInfo & getTargetInfo() const
void takeAllFrom(AttributePool &pool)
Take the given pool's allocations and add them to this pool.
static bool isStaticOverloadedOperator(OverloadedOperatorKind OOK)
Returns true if the given operator is implicitly static in a record context.
Represents a C++ struct/union/class.
void Make(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc)
Make a nested-name-specifier of the form 'type::'.
Definition DeclSpec.cpp:51
SourceLocation getLastQualifierNameLoc() const
Retrieve the location of the name in the last qualifier in this nested name specifier.
Definition DeclSpec.cpp:116
void MakeTrivial(ASTContext &Context, NestedNameSpecifier Qualifier, SourceRange R)
Make a new nested-name-specifier from incomplete source-location information.
Definition DeclSpec.cpp:97
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc)
Turn this (empty) nested-name-specifier into the global nested-name-specifier '::'.
Definition DeclSpec.cpp:75
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
Definition DeclSpec.cpp:123
void Extend(ASTContext &Context, NamespaceBaseDecl *Namespace, SourceLocation NamespaceLoc, SourceLocation ColonColonLoc)
Extend the current nested-name-specifier by another nested-name-specifier component of the form 'name...
Definition DeclSpec.cpp:62
void MakeMicrosoftSuper(ASTContext &Context, CXXRecordDecl *RD, SourceLocation SuperLoc, SourceLocation ColonColonLoc)
Turns this (empty) nested-name-specifier into '__super' nested-name-specifier.
Definition DeclSpec.cpp:85
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
Definition DeclSpec.cpp:103
Captures information about "declaration specifiers".
bool isVirtualSpecified() const
bool setFunctionSpecExplicit(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, ExplicitSpecifier ExplicitSpec, SourceLocation CloseParenLoc)
Definition DeclSpec.cpp:1047
bool isModulePrivateSpecified() const
static const TSCS TSCS___thread
static const TST TST_typeof_unqualType
bool SetTypePipe(bool isPipe, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
Definition DeclSpec.cpp:886
static const TST TST_typename
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.
Definition DeclSpec.cpp:619
ThreadStorageClassSpecifier TSCS
static const TST TST_char8
static const TST TST_BFloat16
void ClearStorageClassSpecs()
bool SetConstexprSpec(ConstexprSpecKind ConstexprKind, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:1106
static const TSCS TSCS__Thread_local
bool SetTypeSpecWidth(TypeSpecifierWidth W, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
These methods set the specified attribute of the DeclSpec, but return true and ignore the request if ...
Definition DeclSpec.cpp:695
TST getTypeSpecType() const
SourceLocation getStorageClassSpecLoc() const
SCS getStorageClassSpec() const
bool setModulePrivateSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:1094
bool SetTypeSpecType(TST T, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
Definition DeclSpec.cpp:834
bool SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:858
void SetPackIndexingExpr(SourceLocation EllipsisLoc, Expr *Pack)
Definition DeclSpec.cpp:966
bool SetStorageClassSpecThread(TSCS TSC, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:681
bool SetBitIntType(SourceLocation KWLoc, Expr *BitWidth, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
Definition DeclSpec.cpp:945
static const TST TST_auto_type
static const TST TST_interface
static const TST TST_double
static const TST TST_typeofExpr
unsigned getTypeQualifiers() const
getTypeQualifiers - Return a set of TQs.
bool SetTypeAltiVecPixel(bool isAltiVecPixel, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
Definition DeclSpec.cpp:903
bool SetFriendSpec(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:1081
static const TST TST_union
static const TST TST_typename_pack_indexing
static const TST TST_char
static const TST TST_bool
static const TST TST_char16
SCS
storage-class-specifier
SourceLocation getExplicitSpecLoc() const
static const TST TST_unknown_anytype
void forEachCVRUQualifier(llvm::function_ref< void(TQ, StringRef, SourceLocation)> Handle)
This method calls the passed in handler on each CVRU qual being set.
Definition DeclSpec.cpp:415
bool SetTypeSpecComplex(TSC C, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:712
bool isMissingDeclaratorOk()
Checks if this DeclSpec can stand alone, without a Declarator.
Definition DeclSpec.cpp:1481
TSCS getThreadStorageClassSpec() const
bool setFunctionSpecNoreturn(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:1066
static const TST TST_accum
static const TST TST_half
ParsedAttributes & getAttributes()
SourceRange getExplicitSpecRange() const
static const TST TST_ibm128
static const TST TST_enum
bool SetTypeAltiVecBool(bool isAltiVecBool, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
Definition DeclSpec.cpp:920
AttributePool & getAttributePool() const
static const TST TST_float128
static const TST TST_decltype
static bool isDeclRep(TST T)
void Finish(Sema &S, const PrintingPolicy &Policy)
Finish - This does final analysis of the declspec, issuing diagnostics for things like "_Complex" (la...
Definition DeclSpec.cpp:1128
static const TST TST_typeof_unqualExpr
static const TST TST_class
bool hasTagDefinition() const
Definition DeclSpec.cpp:433
static const TST TST_decimal64
unsigned getParsedSpecifiers() const
Return a bitmask of which flavors of specifiers this DeclSpec includes.
Definition DeclSpec.cpp:442
bool SetTypeQual(TQ T, SourceLocation Loc)
Definition DeclSpec.cpp:991
static const TST TST_wchar
SourceLocation getTypeSpecComplexLoc() const
static const TST TST_void
static const TSCS TSCS_unspecified
static const TST TST_bitint
static const char * getSpecifierName(DeclSpec::TST T, const PrintingPolicy &Policy)
Turn a type-specifier-type into a string like "_Bool" or "union".
Definition DeclSpec.cpp:532
static const TST TST_float
static const TST TST_atomic
static const TST TST_fract
bool SetTypeSpecError()
Definition DeclSpec.cpp:937
SourceLocation getThreadStorageClassSpecLoc() const
Decl * getRepAsDecl() const
static const TST TST_float16
static const TST TST_unspecified
SourceLocation getVirtualSpecLoc() const
TypeSpecifierSign getTypeSpecSign() const
bool isEmpty() const
isEmpty - Return true if this declaration specifier is completely empty: no tokens were parsed in the...
static const TST TST_decltype_auto
static const TSCS TSCS_thread_local
static const TST TST_error
void forEachQualifier(llvm::function_ref< void(TQ, StringRef, SourceLocation)> Handle)
This method calls the passed in handler on each qual being set.
Definition DeclSpec.cpp:427
bool setFunctionSpecVirtual(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:1032
static const TST TST_decimal32
bool SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy)
Definition DeclSpec.cpp:871
TypeSpecifierWidth getTypeSpecWidth() const
static const TST TST_char32
bool setFunctionSpecInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:1006
static const TST TST_decimal128
static const TST TST_int128
FriendSpecified isFriendSpecified() const
bool hasExplicitSpecifier() const
bool setFunctionSpecForceInline(SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:1020
static const TST TST_typeofType
TemplateIdAnnotation * TemplateIdRep
bool SetTypeSpecSign(TypeSpecifierSign S, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID)
Definition DeclSpec.cpp:722
static const TST TST_auto
@ PQ_StorageClassSpecifier
ConstexprSpecKind getConstexprSpecifier() const
static const TST TST_struct
Decl - This represents one declaration (or definition), e.g.
Information about one declarator, including the parsed type information and the identifier.
bool isDeclarationOfFunction() const
Determine whether the declaration that will be produced from this declaration will be a function.
Definition DeclSpec.cpp:296
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
void SetIdentifier(const IdentifierInfo *Id, SourceLocation IdLoc)
Set the name of this declarator to be the given identifier.
bool isFunctionDeclarator() const
isFunctionDeclarator - Once this declarator is fully parsed and formed, this method returns true if t...
void setDecompositionBindings(SourceLocation LSquareLoc, MutableArrayRef< DecompositionDeclarator::Binding > Bindings, SourceLocation RSquareLoc)
Set the decomposition bindings for this declarator.
Definition DeclSpec.cpp:265
DeclaratorChunk::ParamInfo InlineParams[16]
InlineParams - This is a local array used for the first function decl chunk to avoid going to the hea...
DeclaratorContext getContext() const
bool isCtorOrDtor()
Returns true if this declares a constructor or a destructor.
Definition DeclSpec.cpp:410
UnqualifiedId & getName()
Retrieve the name specified by this declarator.
bool hasName() const
hasName - Whether this declarator has a name, which might be an identifier (accessible via getIdentif...
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
The template parameter lists that preceded the declarator.
bool isExplicitObjectMemberFunction()
Definition DeclSpec.cpp:398
bool isStaticMember()
Returns true if this declares a static member.
Definition DeclSpec.cpp:389
DecompositionDeclarator::Binding InlineBindings[16]
DeclaratorChunk::FunctionTypeInfo & getFunctionTypeInfo()
getFunctionTypeInfo - Retrieves the function type info object (looking through parentheses).
Store information needed for an explicit specifier.
const Expr * getExpr() const
This represents one expression.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
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.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
unsigned getOpenCLCompatibleVersion() const
Return the OpenCL version that kernel language is compatible with.
Holds a QualType and a TypeSourceInfo* that came out of a declarator parsing.
This represents a decl that may have a name.
Represents C++ namespaces and their aliases.
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector::".
static OpaquePtr make(QualType P)
bool isAvailableOption(llvm::StringRef Ext, const LangOptions &LO) const
bool hasAttribute(ParsedAttr::Kind K) const
void takeAllPrependingFrom(ParsedAttributes &Other)
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Sema - This implements semantic analysis and AST building for C.
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
const LangOptions & getLangOpts() const
SourceManager & getSourceManager() const
OpenCLOptions & getOpenCLOptions()
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isBeforeInTranslationUnit(SourceLocation LHS, SourceLocation RHS) const
Determines the order of 2 source locations in the translation unit.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual bool hasFeature(StringRef Feature) const
Determine whether the given target has the given feature.
Base wrapper for a particular "section" of type source info.
SourceLocation getBeginLoc() const
Get the begin source location.
bool isFunctionType() const
struct OFI OperatorFunctionId
When Kind == IK_OperatorFunctionId, the overloaded operator that we parsed.
SourceLocation EndLocation
The location of the last token that describes this unqualified-id.
void setOperatorFunctionId(SourceLocation OperatorLoc, OverloadedOperatorKind Op, SourceLocation SymbolLocations[3])
Specify that this unqualified-id was parsed as an operator-function-id.
Definition DeclSpec.cpp:1487
bool isValid() const
Determine whether this unqualified-id refers to a valid name.
void setTemplateId(TemplateIdAnnotation *TemplateId)
Specify that this unqualified-id was parsed as a template-id.
Definition DeclSpec.cpp:29
void setConstructorTemplateId(TemplateIdAnnotation *TemplateId)
Specify that this unqualified-id was parsed as a template-id that names a constructor.
Definition DeclSpec.cpp:40
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
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 const char * getSpecifierName(Specifier VS)
Definition DeclSpec.cpp:1529
bool SetSpecifier(Specifier VS, SourceLocation Loc, const char *&PrevSpec)
Definition DeclSpec.cpp:1503
Defines the clang::TargetInfo interface.
The JSON file list parser is used to communicate input to InstallAPI.
@ TST_typename_pack_indexing
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
ConstexprSpecKind
Define the kind of constexpr specifier.
@ IK_TemplateId
A template-id, e.g., f.
@ IK_ConstructorTemplateId
A constructor named via a template-id.
@ IK_ConstructorName
A constructor name.
@ IK_DestructorName
A destructor name.
@ IK_OperatorFunctionId
An overloaded operator name, e.g., operator+.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ Keyword
The name has been typo-corrected to a keyword.
TypeSpecifierWidth
Specifies the width of a type, e.g., short, long, or long long.
TypeSpecifierSign
Specifies the signedness of a type, e.g., signed or unsigned.
U cast(CodeGen::Address addr)
SmallVector< Token, 4 > CachedTokens
A set of tokens that has been cached for later parsing.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
@ Other
Other implicit parameter.
ExceptionSpecificationType
The various types of exception specifications that exist in C++11.
@ EST_DependentNoexcept
noexcept(expression), value-dependent
@ EST_Unparsed
not parsed yet
@ EST_None
no exception specification
@ EST_NoexceptFalse
noexcept(expression), evals to 'false'
@ EST_NoexceptTrue
noexcept(expression), evals to 'true'
@ EST_Dynamic
throw(T1, T2)
unsigned isVariadic
isVariadic - If this function has a prototype, and if that proto ends with ',...)',...
CachedTokens * ExceptionSpecTokens
Pointer to the cached tokens for an exception-specification that has not yet been parsed.
SourceLocation MutableLoc
The location of the 'mutable' qualifer in a lambda-declarator, if any.
UnionParsedType TrailingReturnType
If HasTrailingReturnType is true, this is the trailing return type specified.
TypeAndRange * Exceptions
Pointer to a new[]'d array of TypeAndRange objects that contain the types in the function's dynamic e...
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.
NamedDecl ** DeclsInPrototype
Pointer to a new[]'d array of declarations that need to be available for lookup inside the function b...
AttributeFactory * QualAttrFactory
AttributeFactory for the MethodQualifiers.
SourceLocation ExceptionSpecLocEnd
The end location of the exception specification, if any.
SourceLocation EllipsisLoc
When isVariadic is true, the location of the ellipsis in the source.
unsigned DeleteParams
DeleteParams - If this is true, we need to delete[] Params.
DeclSpec * MethodQualifiers
DeclSpec for the function with the qualifier related info.
unsigned NumExceptionsOrDecls
NumExceptionsOrDecls - This is the number of types in the dynamic-exception-decl, if the function has...
SourceLocation RefQualifierLoc
The location of the ref-qualifier, if any.
SourceLocation RParenLoc
The location of the right parenthesis in the source.
unsigned NumParams
NumParams - This is the number of formal parameters specified by the declarator.
unsigned HasTrailingReturnType
HasTrailingReturnType - If this is true, a trailing return type was specified.
unsigned isAmbiguous
Can this declaration be a constructor-style initializer?
unsigned hasPrototype
hasPrototype - This is true if the function had at least one typed parameter.
SourceLocation LParenLoc
The location of the left parenthesis in the source.
unsigned ExceptionSpecType
ExceptionSpecType - An ExceptionSpecificationType value.
SourceLocation ExceptionSpecLocBeg
The beginning location of the exception specification, if any.
SourceLocation TrailingReturnTypeLoc
If HasTrailingReturnType is true, this is the location of the trailing return type.
Expr * NoexceptExpr
Pointer to the expression in the noexcept-specifier of this function, if it has one.
ParamInfo - An array of paraminfo objects is allocated whenever a function declarator is parsed.
SourceLocation EndLoc
EndLoc - If valid, the place where this chunck ends.
static DeclaratorChunk getFunction(bool HasProto, bool IsAmbiguous, SourceLocation LParenLoc, ParamInfo *Params, unsigned NumParams, SourceLocation EllipsisLoc, SourceLocation RParenLoc, bool RefQualifierIsLvalueRef, SourceLocation RefQualifierLoc, SourceLocation MutableLoc, ExceptionSpecificationType ESpecType, SourceRange ESpecRange, ParsedType *Exceptions, SourceRange *ExceptionRanges, unsigned NumExceptions, Expr *NoexceptExpr, CachedTokens *ExceptionSpecTokens, ArrayRef< NamedDecl * > DeclsInPrototype, SourceLocation LocalRangeBegin, SourceLocation LocalRangeEnd, Declarator &TheDeclarator, TypeResult TrailingReturnType=TypeResult(), SourceLocation TrailingReturnTypeLoc=SourceLocation(), DeclSpec *MethodQualifiers=nullptr)
DeclaratorChunk::getFunction - Return a DeclaratorChunk for a function.
Definition DeclSpec.cpp:132
SourceLocation Loc
Loc - The place where this type was defined.
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
Describes how types, statements, expressions, and declarations should be printed.
unsigned Bool
Whether we can use 'bool' rather than '_Bool' (even if the language doesn't actually have 'bool',...
unsigned MSWChar
When true, print the built-in wchar_t type as __wchar_t.
Information about a template-id annotation token.