clang 22.0.0git
SemaAttr.cpp
Go to the documentation of this file.
1//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements semantic analysis for non-trivial attributes and
10// pragmas.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CheckExprLifetime.h"
16#include "clang/AST/Attr.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/Expr.h"
21#include "clang/Sema/Lookup.h"
22#include <optional>
23using namespace clang;
24
25//===----------------------------------------------------------------------===//
26// Pragma 'pack' and 'options align'
27//===----------------------------------------------------------------------===//
28
30 StringRef SlotLabel,
31 bool ShouldAct)
32 : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) {
33 if (ShouldAct) {
34 S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel);
35 S.DataSegStack.SentinelAction(PSK_Push, SlotLabel);
36 S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel);
37 S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel);
38 S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel);
39 S.StrictGuardStackCheckStack.SentinelAction(PSK_Push, SlotLabel);
40 }
41}
42
44 if (ShouldAct) {
45 S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel);
46 S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel);
47 S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel);
48 S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel);
49 S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel);
50 S.StrictGuardStackCheckStack.SentinelAction(PSK_Pop, SlotLabel);
51 }
52}
53
55 AlignPackInfo InfoVal = AlignPackStack.CurrentValue;
57 bool IsPackSet = InfoVal.IsPackSet();
58 bool IsXLPragma = getLangOpts().XLPragmaPack;
59
60 // If we are not under mac68k/natural alignment mode and also there is no pack
61 // value, we don't need any attributes.
62 if (!IsPackSet && M != AlignPackInfo::Mac68k && M != AlignPackInfo::Natural)
63 return;
64
65 if (M == AlignPackInfo::Mac68k && (IsXLPragma || InfoVal.IsAlignAttr())) {
66 RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
67 } else if (IsPackSet) {
68 // Check to see if we need a max field alignment attribute.
69 RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(
70 Context, InfoVal.getPackNumber() * 8));
71 }
72
73 if (IsXLPragma && M == AlignPackInfo::Natural)
74 RD->addAttr(AlignNaturalAttr::CreateImplicit(Context));
75
76 if (AlignPackIncludeStack.empty())
77 return;
78 // The #pragma align/pack affected a record in an included file, so Clang
79 // should warn when that pragma was written in a file that included the
80 // included file.
81 for (auto &AlignPackedInclude : llvm::reverse(AlignPackIncludeStack)) {
82 if (AlignPackedInclude.CurrentPragmaLocation !=
83 AlignPackStack.CurrentPragmaLocation)
84 break;
85 if (AlignPackedInclude.HasNonDefaultValue)
86 AlignPackedInclude.ShouldWarnOnInclude = true;
87 }
88}
89
92 RD->addAttr(MSStructAttr::CreateImplicit(Context));
93
94 // FIXME: We should merge AddAlignmentAttributesForRecord with
95 // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
96 // all active pragmas and applies them as attributes to class definitions.
97 if (VtorDispStack.CurrentValue != getLangOpts().getVtorDispMode())
98 RD->addAttr(MSVtorDispAttr::CreateImplicit(
99 Context, unsigned(VtorDispStack.CurrentValue)));
100}
101
102template <typename Attribute>
105 if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
106 return;
107
108 for (Decl *Redecl : Record->redecls())
109 Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
110}
111
113 CXXRecordDecl *UnderlyingRecord) {
114 if (!UnderlyingRecord)
115 return;
116
117 const auto *Parent = dyn_cast<CXXRecordDecl>(ND->getDeclContext());
118 if (!Parent)
119 return;
120
121 static const llvm::StringSet<> Containers{
122 "array",
123 "basic_string",
124 "deque",
125 "forward_list",
126 "vector",
127 "list",
128 "map",
129 "multiset",
130 "multimap",
131 "priority_queue",
132 "queue",
133 "set",
134 "stack",
135 "unordered_set",
136 "unordered_map",
137 "unordered_multiset",
138 "unordered_multimap",
139 };
140
141 static const llvm::StringSet<> Iterators{"iterator", "const_iterator",
142 "reverse_iterator",
143 "const_reverse_iterator"};
144
145 if (Parent->isInStdNamespace() && Iterators.count(ND->getName()) &&
146 Containers.count(Parent->getName()))
148 UnderlyingRecord);
149}
150
152
153 QualType Canonical = TD->getUnderlyingType().getCanonicalType();
154
155 CXXRecordDecl *RD = Canonical->getAsCXXRecordDecl();
156 if (!RD) {
157 if (auto *TST =
158 dyn_cast<TemplateSpecializationType>(Canonical.getTypePtr())) {
159
160 if (const auto *TD = TST->getTemplateName().getAsTemplateDecl())
161 RD = dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl());
162 }
163 }
164
166}
167
169 static const llvm::StringSet<> StdOwners{
170 "any",
171 "array",
172 "basic_regex",
173 "basic_string",
174 "deque",
175 "forward_list",
176 "vector",
177 "list",
178 "map",
179 "multiset",
180 "multimap",
181 "optional",
182 "priority_queue",
183 "queue",
184 "set",
185 "stack",
186 "unique_ptr",
187 "unordered_set",
188 "unordered_map",
189 "unordered_multiset",
190 "unordered_multimap",
191 "variant",
192 };
193 static const llvm::StringSet<> StdPointers{
194 "basic_string_view",
195 "reference_wrapper",
196 "regex_iterator",
197 "span",
198 };
199
200 if (!Record->getIdentifier())
201 return;
202
203 // Handle classes that directly appear in std namespace.
204 if (Record->isInStdNamespace()) {
205 if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
206 return;
207
208 if (StdOwners.count(Record->getName()))
210 else if (StdPointers.count(Record->getName()))
212
213 return;
214 }
215
216 // Handle nested classes that could be a gsl::Pointer.
218}
219
221 if (FD->getNumParams() == 0)
222 return;
223 // Skip void returning functions (except constructors). This can occur in
224 // cases like 'as_const'.
226 return;
227
228 if (unsigned BuiltinID = FD->getBuiltinID()) {
229 // Add lifetime attribute to std::move, std::fowrard et al.
230 switch (BuiltinID) {
231 case Builtin::BIaddressof:
232 case Builtin::BI__addressof:
233 case Builtin::BI__builtin_addressof:
234 case Builtin::BIas_const:
235 case Builtin::BIforward:
236 case Builtin::BIforward_like:
237 case Builtin::BImove:
238 case Builtin::BImove_if_noexcept:
239 if (ParmVarDecl *P = FD->getParamDecl(0u);
240 !P->hasAttr<LifetimeBoundAttr>())
241 P->addAttr(
242 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation()));
243 break;
244 default:
245 break;
246 }
247 return;
248 }
249 if (auto *CMD = dyn_cast<CXXMethodDecl>(FD)) {
250 const auto *CRD = CMD->getParent();
251 if (!CRD->isInStdNamespace() || !CRD->getIdentifier())
252 return;
253
254 if (isa<CXXConstructorDecl>(CMD)) {
255 auto *Param = CMD->getParamDecl(0);
256 if (Param->hasAttr<LifetimeBoundAttr>())
257 return;
258 if (CRD->getName() == "basic_string_view" &&
259 Param->getType()->isPointerType()) {
260 // construct from a char array pointed by a pointer.
261 // basic_string_view(const CharT* s);
262 // basic_string_view(const CharT* s, size_type count);
263 Param->addAttr(
264 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation()));
265 } else if (CRD->getName() == "span") {
266 // construct from a reference of array.
267 // span(std::type_identity_t<element_type> (&arr)[N]);
268 const auto *LRT = Param->getType()->getAs<LValueReferenceType>();
269 if (LRT && LRT->getPointeeType().IgnoreParens()->isArrayType())
270 Param->addAttr(
271 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation()));
272 }
273 }
274 }
275}
276
278 auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD);
279 if (!MD || !MD->getParent()->isInStdNamespace())
280 return;
281 auto Annotate = [this](const FunctionDecl *MD) {
282 // Do not infer if any parameter is explicitly annotated.
283 for (ParmVarDecl *PVD : MD->parameters())
284 if (PVD->hasAttr<LifetimeCaptureByAttr>())
285 return;
286 for (ParmVarDecl *PVD : MD->parameters()) {
287 // Methods in standard containers that capture values typically accept
288 // reference-type parameters, e.g., `void push_back(const T& value)`.
289 // We only apply the lifetime_capture_by attribute to parameters of
290 // pointer-like reference types (`const T&`, `T&&`).
291 if (PVD->getType()->isReferenceType() &&
292 sema::isGLSPointerType(PVD->getType().getNonReferenceType())) {
293 int CaptureByThis[] = {LifetimeCaptureByAttr::This};
294 PVD->addAttr(
295 LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1));
296 }
297 }
298 };
299
300 if (!MD->getIdentifier()) {
301 static const llvm::StringSet<> MapLikeContainer{
302 "map",
303 "multimap",
304 "unordered_map",
305 "unordered_multimap",
306 };
307 // Infer for the map's operator []:
308 // std::map<string_view, ...> m;
309 // m[ReturnString(..)] = ...; // !dangling references in m.
310 if (MD->getOverloadedOperator() == OO_Subscript &&
311 MapLikeContainer.contains(MD->getParent()->getName()))
312 Annotate(MD);
313 return;
314 }
315 static const llvm::StringSet<> CapturingMethods{
316 "insert", "insert_or_assign", "push", "push_front", "push_back"};
317 if (!CapturingMethods.contains(MD->getName()))
318 return;
319 Annotate(MD);
320}
321
323 static const llvm::StringSet<> Nullable{
324 "auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr",
325 "coroutine_handle", "function", "move_only_function",
326 };
327
328 if (CRD->isInStdNamespace() && Nullable.count(CRD->getName()) &&
329 !CRD->hasAttr<TypeNullableAttr>())
330 for (Decl *Redecl : CRD->redecls())
331 Redecl->addAttr(TypeNullableAttr::CreateImplicit(Context));
332}
333
335 SourceLocation PragmaLoc) {
338
339 switch (Kind) {
340 // For most of the platforms we support, native and natural are the same.
341 // With XL, native is the same as power, natural means something else.
344 Action = Sema::PSK_Push_Set;
345 break;
347 Action = Sema::PSK_Push_Set;
348 ModeVal = AlignPackInfo::Natural;
349 break;
350
351 // Note that '#pragma options align=packed' is not equivalent to attribute
352 // packed, it has a different precedence relative to attribute aligned.
354 Action = Sema::PSK_Push_Set;
355 ModeVal = AlignPackInfo::Packed;
356 break;
357
359 // Check if the target supports this.
360 if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
361 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
362 return;
363 }
364 Action = Sema::PSK_Push_Set;
365 ModeVal = AlignPackInfo::Mac68k;
366 break;
368 // Reset just pops the top of the stack, or resets the current alignment to
369 // default.
370 Action = Sema::PSK_Pop;
371 if (AlignPackStack.Stack.empty()) {
372 if (AlignPackStack.CurrentValue.getAlignMode() != AlignPackInfo::Native ||
373 AlignPackStack.CurrentValue.IsPackAttr()) {
374 Action = Sema::PSK_Reset;
375 } else {
376 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
377 << "stack empty";
378 return;
379 }
380 }
381 break;
382 }
383
384 AlignPackInfo Info(ModeVal, getLangOpts().XLPragmaPack);
385
386 AlignPackStack.Act(PragmaLoc, Action, StringRef(), Info);
387}
388
392 StringRef SecName) {
393 PragmaClangSection *CSec;
394 int SectionFlags = ASTContext::PSF_Read;
395 switch (SecKind) {
397 CSec = &PragmaClangBSSSection;
399 break;
402 SectionFlags |= ASTContext::PSF_Write;
403 break;
406 break;
409 break;
412 SectionFlags |= ASTContext::PSF_Execute;
413 break;
414 default:
415 llvm_unreachable("invalid clang section kind");
416 }
417
418 if (Action == PragmaClangSectionAction::Clear) {
419 CSec->Valid = false;
420 return;
421 }
422
423 if (llvm::Error E = isValidSectionSpecifier(SecName)) {
424 Diag(PragmaLoc, diag::err_pragma_section_invalid_for_target)
425 << toString(std::move(E));
426 CSec->Valid = false;
427 return;
428 }
429
430 if (UnifySection(SecName, SectionFlags, PragmaLoc))
431 return;
432
433 CSec->Valid = true;
434 CSec->SectionName = std::string(SecName);
435 CSec->PragmaLocation = PragmaLoc;
436}
437
439 StringRef SlotLabel, Expr *Alignment) {
440 bool IsXLPragma = getLangOpts().XLPragmaPack;
441 // XL pragma pack does not support identifier syntax.
442 if (IsXLPragma && !SlotLabel.empty()) {
443 Diag(PragmaLoc, diag::err_pragma_pack_identifer_not_supported);
444 return;
445 }
446
447 const AlignPackInfo CurVal = AlignPackStack.CurrentValue;
448
449 // If specified then alignment must be a "small" power of two.
450 unsigned AlignmentVal = 0;
451 AlignPackInfo::Mode ModeVal = CurVal.getAlignMode();
452
453 if (Alignment) {
454 std::optional<llvm::APSInt> Val;
455 Val = Alignment->getIntegerConstantExpr(Context);
456
457 // pack(0) is like pack(), which just works out since that is what
458 // we use 0 for in PackAttr.
459 if (Alignment->isTypeDependent() || !Val ||
460 !(*Val == 0 || Val->isPowerOf2()) || Val->getZExtValue() > 16) {
461 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
462 return; // Ignore
463 }
464
465 if (IsXLPragma && *Val == 0) {
466 // pack(0) does not work out with XL.
467 Diag(PragmaLoc, diag::err_pragma_pack_invalid_alignment);
468 return; // Ignore
469 }
470
471 AlignmentVal = (unsigned)Val->getZExtValue();
472 }
473
474 if (Action == Sema::PSK_Show) {
475 // Show the current alignment, making sure to show the right value
476 // for the default.
477 // FIXME: This should come from the target.
478 AlignmentVal = CurVal.IsPackSet() ? CurVal.getPackNumber() : 8;
479 if (ModeVal == AlignPackInfo::Mac68k &&
480 (IsXLPragma || CurVal.IsAlignAttr()))
481 Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
482 else
483 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
484 }
485
486 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
487 // "#pragma pack(pop, identifier, n) is undefined"
488 if (Action & Sema::PSK_Pop) {
489 if (Alignment && !SlotLabel.empty())
490 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifier_and_alignment);
491 if (AlignPackStack.Stack.empty()) {
492 assert(CurVal.getAlignMode() == AlignPackInfo::Native &&
493 "Empty pack stack can only be at Native alignment mode.");
494 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty";
495 }
496 }
497
498 AlignPackInfo Info(ModeVal, AlignmentVal, IsXLPragma);
499
500 AlignPackStack.Act(PragmaLoc, Action, SlotLabel, Info);
501}
502
506 for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
507 Expr *&E = Args.begin()[Idx];
508 assert(E && "error are handled before");
509 if (E->isValueDependent() || E->isTypeDependent())
510 continue;
511
512 // FIXME: Use DefaultFunctionArrayLValueConversion() in place of the logic
513 // that adds implicit casts here.
514 if (E->getType()->isArrayType())
515 E = ImpCastExprToType(E, Context.getPointerType(E->getType()),
516 clang::CK_ArrayToPointerDecay)
517 .get();
518 if (E->getType()->isFunctionType())
520 Context.getPointerType(E->getType()),
521 clang::CK_FunctionToPointerDecay, E, nullptr,
523 if (E->isLValue())
525 clang::CK_LValueToRValue, E, nullptr,
527
528 Expr::EvalResult Eval;
529 Notes.clear();
530 Eval.Diag = &Notes;
531
532 bool Result = E->EvaluateAsConstantExpr(Eval, Context);
533
534 /// Result means the expression can be folded to a constant.
535 /// Note.empty() means the expression is a valid constant expression in the
536 /// current language mode.
537 if (!Result || !Notes.empty()) {
538 Diag(E->getBeginLoc(), diag::err_attribute_argument_n_type)
539 << CI << (Idx + 1) << AANT_ArgumentConstantExpr;
540 for (auto &Note : Notes)
541 Diag(Note.first, Note.second);
542 return false;
543 }
544 E = ConstantExpr::Create(Context, E, Eval.Val);
545 }
546
547 return true;
548}
549
551 SourceLocation IncludeLoc) {
553 SourceLocation PrevLocation = AlignPackStack.CurrentPragmaLocation;
554 // Warn about non-default alignment at #includes (without redundant
555 // warnings for the same directive in nested includes).
556 // The warning is delayed until the end of the file to avoid warnings
557 // for files that don't have any records that are affected by the modified
558 // alignment.
559 bool HasNonDefaultValue =
560 AlignPackStack.hasValue() &&
561 (AlignPackIncludeStack.empty() ||
562 AlignPackIncludeStack.back().CurrentPragmaLocation != PrevLocation);
563 AlignPackIncludeStack.push_back(
564 {AlignPackStack.CurrentValue,
565 AlignPackStack.hasValue() ? PrevLocation : SourceLocation(),
566 HasNonDefaultValue, /*ShouldWarnOnInclude*/ false});
567 return;
568 }
569
571 "invalid kind");
572 AlignPackIncludeState PrevAlignPackState =
573 AlignPackIncludeStack.pop_back_val();
574 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack
575 // information, diagnostics below might not be accurate if we have mixed
576 // pragmas.
577 if (PrevAlignPackState.ShouldWarnOnInclude) {
578 // Emit the delayed non-default alignment at #include warning.
579 Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include);
580 Diag(PrevAlignPackState.CurrentPragmaLocation, diag::note_pragma_pack_here);
581 }
582 // Warn about modified alignment after #includes.
583 if (PrevAlignPackState.CurrentValue != AlignPackStack.CurrentValue) {
584 Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include);
585 Diag(AlignPackStack.CurrentPragmaLocation, diag::note_pragma_pack_here);
586 }
587}
588
590 if (AlignPackStack.Stack.empty())
591 return;
592 bool IsInnermost = true;
593
594 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack
595 // information, diagnostics below might not be accurate if we have mixed
596 // pragmas.
597 for (const auto &StackSlot : llvm::reverse(AlignPackStack.Stack)) {
598 Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof);
599 // The user might have already reset the alignment, so suggest replacing
600 // the reset with a pop.
601 if (IsInnermost &&
602 AlignPackStack.CurrentValue == AlignPackStack.DefaultValue) {
603 auto DB = Diag(AlignPackStack.CurrentPragmaLocation,
604 diag::note_pragma_pack_pop_instead_reset);
605 SourceLocation FixItLoc =
606 Lexer::findLocationAfterToken(AlignPackStack.CurrentPragmaLocation,
607 tok::l_paren, SourceMgr, LangOpts,
608 /*SkipTrailing=*/false);
609 if (FixItLoc.isValid())
610 DB << FixItHint::CreateInsertion(FixItLoc, "pop");
611 }
612 IsInnermost = false;
613 }
614}
615
619
621 PragmaMSCommentKind Kind, StringRef Arg) {
622 auto *PCD = PragmaCommentDecl::Create(
623 Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg);
624 Context.getTranslationUnitDecl()->addDecl(PCD);
625 Consumer.HandleTopLevelDecl(DeclGroupRef(PCD));
626}
627
629 StringRef Value) {
631 Context, Context.getTranslationUnitDecl(), Loc, Name, Value);
632 Context.getTranslationUnitDecl()->addDecl(PDMD);
633 Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
634}
635
639 switch (Value) {
640 default:
641 llvm_unreachable("invalid pragma eval_method kind");
643 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Source);
644 break;
646 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Double);
647 break;
649 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Extended);
650 break;
651 }
652 if (getLangOpts().ApproxFunc)
653 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 0;
654 if (getLangOpts().AllowFPReassoc)
655 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 1;
656 if (getLangOpts().AllowRecip)
657 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 2;
658 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
659 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
660 PP.setCurrentFPEvalMethod(Loc, Value);
661}
662
664 PragmaMsStackAction Action,
667 if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) &&
668 !CurContext->getRedeclContext()->isFileContext()) {
669 // Push and pop can only occur at file or namespace scope, or within a
670 // language linkage declaration.
671 Diag(Loc, diag::err_pragma_fc_pp_scope);
672 return;
673 }
674 switch (Value) {
675 default:
676 llvm_unreachable("invalid pragma float_control kind");
677 case PFC_Precise:
678 NewFPFeatures.setFPPreciseEnabled(true);
679 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
680 break;
681 case PFC_NoPrecise:
682 if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict)
683 Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept);
684 else if (CurFPFeatures.getAllowFEnvAccess())
685 Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv);
686 else
687 NewFPFeatures.setFPPreciseEnabled(false);
688 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
689 break;
690 case PFC_Except:
691 if (!isPreciseFPEnabled())
692 Diag(Loc, diag::err_pragma_fc_except_requires_precise);
693 else
694 NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Strict);
695 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
696 break;
697 case PFC_NoExcept:
698 NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Ignore);
699 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
700 break;
701 case PFC_Push:
702 FpPragmaStack.Act(Loc, Sema::PSK_Push_Set, StringRef(), NewFPFeatures);
703 break;
704 case PFC_Pop:
705 if (FpPragmaStack.Stack.empty()) {
706 Diag(Loc, diag::warn_pragma_pop_failed) << "float_control"
707 << "stack empty";
708 return;
709 }
710 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
711 NewFPFeatures = FpPragmaStack.CurrentValue;
712 break;
713 }
714 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
715}
716
723
725 SourceLocation PragmaLoc,
726 MSVtorDispMode Mode) {
727 if (Action & PSK_Pop && VtorDispStack.Stack.empty())
728 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
729 << "stack empty";
730 VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode);
731}
732
733template <>
735 PragmaMsStackAction Action,
736 llvm::StringRef StackSlotLabel,
737 AlignPackInfo Value) {
738 if (Action == PSK_Reset) {
739 CurrentValue = DefaultValue;
740 CurrentPragmaLocation = PragmaLocation;
741 return;
742 }
743 if (Action & PSK_Push)
744 Stack.emplace_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
745 PragmaLocation));
746 else if (Action & PSK_Pop) {
747 if (!StackSlotLabel.empty()) {
748 // If we've got a label, try to find it and jump there.
749 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
750 return x.StackSlotLabel == StackSlotLabel;
751 });
752 // We found the label, so pop from there.
753 if (I != Stack.rend()) {
754 CurrentValue = I->Value;
755 CurrentPragmaLocation = I->PragmaLocation;
756 Stack.erase(std::prev(I.base()), Stack.end());
757 }
758 } else if (Value.IsXLStack() && Value.IsAlignAttr() &&
759 CurrentValue.IsPackAttr()) {
760 // XL '#pragma align(reset)' would pop the stack until
761 // a current in effect pragma align is popped.
762 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
763 return x.Value.IsAlignAttr();
764 });
765 // If we found pragma align so pop from there.
766 if (I != Stack.rend()) {
767 Stack.erase(std::prev(I.base()), Stack.end());
768 if (Stack.empty()) {
769 CurrentValue = DefaultValue;
770 CurrentPragmaLocation = PragmaLocation;
771 } else {
772 CurrentValue = Stack.back().Value;
773 CurrentPragmaLocation = Stack.back().PragmaLocation;
774 Stack.pop_back();
775 }
776 }
777 } else if (!Stack.empty()) {
778 // xl '#pragma align' sets the baseline, and `#pragma pack` cannot pop
779 // over the baseline.
780 if (Value.IsXLStack() && Value.IsPackAttr() && CurrentValue.IsAlignAttr())
781 return;
782
783 // We don't have a label, just pop the last entry.
784 CurrentValue = Stack.back().Value;
785 CurrentPragmaLocation = Stack.back().PragmaLocation;
786 Stack.pop_back();
787 }
788 }
789 if (Action & PSK_Set) {
790 CurrentValue = Value;
791 CurrentPragmaLocation = PragmaLocation;
792 }
793}
794
795bool Sema::UnifySection(StringRef SectionName, int SectionFlags,
796 NamedDecl *Decl) {
797 SourceLocation PragmaLocation;
798 if (auto A = Decl->getAttr<SectionAttr>())
799 if (A->isImplicit())
800 PragmaLocation = A->getLocation();
801 auto [SectionIt, Inserted] = Context.SectionInfos.try_emplace(
802 SectionName, Decl, PragmaLocation, SectionFlags);
803 if (Inserted)
804 return false;
805 // A pre-declared section takes precedence w/o diagnostic.
806 const auto &Section = SectionIt->second;
807 if (Section.SectionFlags == SectionFlags ||
808 ((SectionFlags & ASTContext::PSF_Implicit) &&
809 !(Section.SectionFlags & ASTContext::PSF_Implicit)))
810 return false;
811 Diag(Decl->getLocation(), diag::err_section_conflict) << Decl << Section;
812 if (Section.Decl)
813 Diag(Section.Decl->getLocation(), diag::note_declared_at)
814 << Section.Decl->getName();
815 if (PragmaLocation.isValid())
816 Diag(PragmaLocation, diag::note_pragma_entered_here);
817 if (Section.PragmaSectionLocation.isValid())
818 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
819 return true;
820}
821
822bool Sema::UnifySection(StringRef SectionName,
823 int SectionFlags,
824 SourceLocation PragmaSectionLocation) {
825 auto SectionIt = Context.SectionInfos.find(SectionName);
826 if (SectionIt != Context.SectionInfos.end()) {
827 const auto &Section = SectionIt->second;
828 if (Section.SectionFlags == SectionFlags)
829 return false;
830 if (!(Section.SectionFlags & ASTContext::PSF_Implicit)) {
831 Diag(PragmaSectionLocation, diag::err_section_conflict)
832 << "this" << Section;
833 if (Section.Decl)
834 Diag(Section.Decl->getLocation(), diag::note_declared_at)
835 << Section.Decl->getName();
836 if (Section.PragmaSectionLocation.isValid())
837 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
838 return true;
839 }
840 }
841 Context.SectionInfos[SectionName] =
842 ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
843 return false;
844}
845
846/// Called on well formed \#pragma bss_seg().
848 PragmaMsStackAction Action,
849 llvm::StringRef StackSlotLabel,
850 StringLiteral *SegmentName,
851 llvm::StringRef PragmaName) {
853 llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
854 .Case("data_seg", &DataSegStack)
855 .Case("bss_seg", &BSSSegStack)
856 .Case("const_seg", &ConstSegStack)
857 .Case("code_seg", &CodeSegStack);
858 if (Action & PSK_Pop && Stack->Stack.empty())
859 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
860 << "stack empty";
861 if (SegmentName) {
862 if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
863 return;
864
865 if (SegmentName->getString() == ".drectve" &&
866 Context.getTargetInfo().getCXXABI().isMicrosoft())
867 Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName;
868 }
869
870 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
871}
872
873/// Called on well formed \#pragma strict_gs_check().
875 PragmaMsStackAction Action,
876 bool Value) {
877 if (Action & PSK_Pop && StrictGuardStackCheckStack.Stack.empty())
878 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "strict_gs_check"
879 << "stack empty";
880
881 StrictGuardStackCheckStack.Act(PragmaLocation, Action, StringRef(), Value);
882}
883
884/// Called on well formed \#pragma bss_seg().
886 int SectionFlags, StringLiteral *SegmentName) {
887 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
888}
889
891 StringLiteral *SegmentName) {
892 // There's no stack to maintain, so we just have a current section. When we
893 // see the default section, reset our current section back to null so we stop
894 // tacking on unnecessary attributes.
895 CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
896 CurInitSegLoc = PragmaLocation;
897}
898
900 SourceLocation PragmaLocation, StringRef Section,
901 const SmallVector<std::tuple<IdentifierInfo *, SourceLocation>>
902 &Functions) {
903 if (!CurContext->getRedeclContext()->isFileContext()) {
904 Diag(PragmaLocation, diag::err_pragma_expected_file_scope) << "alloc_text";
905 return;
906 }
907
908 for (auto &Function : Functions) {
909 IdentifierInfo *II;
910 SourceLocation Loc;
911 std::tie(II, Loc) = Function;
912
913 DeclarationName DN(II);
915 if (!ND) {
916 Diag(Loc, diag::err_undeclared_use) << II->getName();
917 return;
918 }
919
920 auto *FD = dyn_cast<FunctionDecl>(ND->getCanonicalDecl());
921 if (!FD) {
922 Diag(Loc, diag::err_pragma_alloc_text_not_function);
923 return;
924 }
925
926 if (getLangOpts().CPlusPlus && !FD->isInExternCContext()) {
927 Diag(Loc, diag::err_pragma_alloc_text_c_linkage);
928 return;
929 }
930
931 FunctionToSectionMap[II->getName()] = std::make_tuple(Section, Loc);
932 }
933}
934
935void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
936 SourceLocation PragmaLoc) {
937
938 IdentifierInfo *Name = IdTok.getIdentifierInfo();
939 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
940 LookupName(Lookup, curScope, /*AllowBuiltinCreation=*/true);
941
942 if (Lookup.empty()) {
943 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
944 << Name << SourceRange(IdTok.getLocation());
945 return;
946 }
947
948 VarDecl *VD = Lookup.getAsSingle<VarDecl>();
949 if (!VD) {
950 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
951 << Name << SourceRange(IdTok.getLocation());
952 return;
953 }
954
955 // Warn if this was used before being marked unused.
956 if (VD->isUsed())
957 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
958
959 VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(),
960 UnusedAttr::GNU_unused));
961}
962
963namespace {
964
965std::optional<attr::SubjectMatchRule>
966getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
967 using namespace attr;
968 switch (Rule) {
969 default:
970 return std::nullopt;
971#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
972#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
973 case Value: \
974 return Parent;
975#include "clang/Basic/AttrSubMatchRulesList.inc"
976 }
977}
978
979bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
980 using namespace attr;
981 switch (Rule) {
982 default:
983 return false;
984#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
985#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
986 case Value: \
987 return IsNegated;
988#include "clang/Basic/AttrSubMatchRulesList.inc"
989 }
990}
991
992CharSourceRange replacementRangeForListElement(const Sema &S,
993 SourceRange Range) {
994 // Make sure that the ',' is removed as well.
995 SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
996 Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
997 /*SkipTrailingWhitespaceAndNewLine=*/false);
998 if (AfterCommaLoc.isValid())
999 return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
1000 else
1001 return CharSourceRange::getTokenRange(Range);
1002}
1003
1004std::string
1005attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
1006 std::string Result;
1007 llvm::raw_string_ostream OS(Result);
1008 for (const auto &I : llvm::enumerate(Rules)) {
1009 if (I.index())
1010 OS << (I.index() == Rules.size() - 1 ? ", and " : ", ");
1011 OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
1012 }
1013 return Result;
1014}
1015
1016} // end anonymous namespace
1017
1019 ParsedAttr &Attribute, SourceLocation PragmaLoc,
1021 Attribute.setIsPragmaClangAttribute();
1023 // Gather the subject match rules that are supported by the attribute.
1025 StrictSubjectMatchRuleSet;
1026 Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
1027
1028 // Figure out which subject matching rules are valid.
1029 if (StrictSubjectMatchRuleSet.empty()) {
1030 // Check for contradicting match rules. Contradicting match rules are
1031 // either:
1032 // - a top-level rule and one of its sub-rules. E.g. variable and
1033 // variable(is_parameter).
1034 // - a sub-rule and a sibling that's negated. E.g.
1035 // variable(is_thread_local) and variable(unless(is_parameter))
1036 llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2>
1037 RulesToFirstSpecifiedNegatedSubRule;
1038 for (const auto &Rule : Rules) {
1039 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1040 std::optional<attr::SubjectMatchRule> ParentRule =
1041 getParentAttrMatcherRule(MatchRule);
1042 if (!ParentRule)
1043 continue;
1044 auto It = Rules.find(*ParentRule);
1045 if (It != Rules.end()) {
1046 // A sub-rule contradicts a parent rule.
1047 Diag(Rule.second.getBegin(),
1048 diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
1050 << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
1052 replacementRangeForListElement(*this, Rule.second));
1053 // Keep going without removing this rule as it won't change the set of
1054 // declarations that receive the attribute.
1055 continue;
1056 }
1057 if (isNegatedAttrMatcherSubRule(MatchRule))
1058 RulesToFirstSpecifiedNegatedSubRule.insert(
1059 std::make_pair(*ParentRule, Rule));
1060 }
1061 bool IgnoreNegatedSubRules = false;
1062 for (const auto &Rule : Rules) {
1063 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1064 std::optional<attr::SubjectMatchRule> ParentRule =
1065 getParentAttrMatcherRule(MatchRule);
1066 if (!ParentRule)
1067 continue;
1068 auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
1069 if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
1070 It->second != Rule) {
1071 // Negated sub-rule contradicts another sub-rule.
1072 Diag(
1073 It->second.second.getBegin(),
1074 diag::
1075 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
1077 attr::SubjectMatchRule(It->second.first))
1078 << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
1080 replacementRangeForListElement(*this, It->second.second));
1081 // Keep going but ignore all of the negated sub-rules.
1082 IgnoreNegatedSubRules = true;
1083 RulesToFirstSpecifiedNegatedSubRule.erase(It);
1084 }
1085 }
1086
1087 if (!IgnoreNegatedSubRules) {
1088 for (const auto &Rule : Rules)
1089 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
1090 } else {
1091 for (const auto &Rule : Rules) {
1092 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
1093 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
1094 }
1095 }
1096 Rules.clear();
1097 } else {
1098 // Each rule in Rules must be a strict subset of the attribute's
1099 // SubjectMatch rules. I.e. we're allowed to use
1100 // `apply_to=variables(is_global)` on an attrubute with SubjectList<[Var]>,
1101 // but should not allow `apply_to=variables` on an attribute which has
1102 // `SubjectList<[GlobalVar]>`.
1103 for (const auto &StrictRule : StrictSubjectMatchRuleSet) {
1104 // First, check for exact match.
1105 if (Rules.erase(StrictRule.first)) {
1106 // Add the rule to the set of attribute receivers only if it's supported
1107 // in the current language mode.
1108 if (StrictRule.second)
1109 SubjectMatchRules.push_back(StrictRule.first);
1110 }
1111 }
1112 // Check remaining rules for subset matches.
1113 auto RulesToCheck = Rules;
1114 for (const auto &Rule : RulesToCheck) {
1115 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1116 if (auto ParentRule = getParentAttrMatcherRule(MatchRule)) {
1117 if (llvm::any_of(StrictSubjectMatchRuleSet,
1118 [ParentRule](const auto &StrictRule) {
1119 return StrictRule.first == *ParentRule &&
1120 StrictRule.second; // IsEnabled
1121 })) {
1122 SubjectMatchRules.push_back(MatchRule);
1123 Rules.erase(MatchRule);
1124 }
1125 }
1126 }
1127 }
1128
1129 if (!Rules.empty()) {
1130 auto Diagnostic =
1131 Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
1132 << Attribute;
1134 for (const auto &Rule : Rules) {
1135 ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
1137 replacementRangeForListElement(*this, Rule.second));
1138 }
1139 Diagnostic << attrMatcherRuleListToString(ExtraRules);
1140 }
1141
1142 if (PragmaAttributeStack.empty()) {
1143 Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push);
1144 return;
1145 }
1146
1147 PragmaAttributeStack.back().Entries.push_back(
1148 {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
1149}
1150
1152 const IdentifierInfo *Namespace) {
1153 PragmaAttributeStack.emplace_back();
1154 PragmaAttributeStack.back().Loc = PragmaLoc;
1155 PragmaAttributeStack.back().Namespace = Namespace;
1156}
1157
1159 const IdentifierInfo *Namespace) {
1160 if (PragmaAttributeStack.empty()) {
1161 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1162 return;
1163 }
1164
1165 // Dig back through the stack trying to find the most recently pushed group
1166 // that in Namespace. Note that this works fine if no namespace is present,
1167 // think of push/pops without namespaces as having an implicit "nullptr"
1168 // namespace.
1169 for (size_t Index = PragmaAttributeStack.size(); Index;) {
1170 --Index;
1171 if (PragmaAttributeStack[Index].Namespace == Namespace) {
1172 for (const PragmaAttributeEntry &Entry :
1173 PragmaAttributeStack[Index].Entries) {
1174 if (!Entry.IsUsed) {
1175 assert(Entry.Attribute && "Expected an attribute");
1176 Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
1177 << *Entry.Attribute;
1178 Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
1179 }
1180 }
1181 PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index);
1182 return;
1183 }
1184 }
1185
1186 if (Namespace)
1187 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch)
1188 << 0 << Namespace->getName();
1189 else
1190 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1191}
1192
1194 if (PragmaAttributeStack.empty())
1195 return;
1196
1197 if (const auto *P = dyn_cast<ParmVarDecl>(D))
1198 if (P->getType()->isVoidType())
1199 return;
1200
1201 for (auto &Group : PragmaAttributeStack) {
1202 for (auto &Entry : Group.Entries) {
1203 ParsedAttr *Attribute = Entry.Attribute;
1204 assert(Attribute && "Expected an attribute");
1205 assert(Attribute->isPragmaClangAttribute() &&
1206 "expected #pragma clang attribute");
1207
1208 // Ensure that the attribute can be applied to the given declaration.
1209 bool Applies = false;
1210 for (const auto &Rule : Entry.MatchRules) {
1211 if (Attribute->appliesToDecl(D, Rule)) {
1212 Applies = true;
1213 break;
1214 }
1215 }
1216 if (!Applies)
1217 continue;
1218 Entry.IsUsed = true;
1221 Attrs.addAtEnd(Attribute);
1222 ProcessDeclAttributeList(S, D, Attrs);
1224 }
1225 }
1226}
1227
1230 assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
1231 DiagFunc(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
1232 PDiag(diag::note_pragma_attribute_applied_decl_here));
1233}
1234
1236 for (auto &[Type, Num] : ExcessPrecisionNotSatisfied) {
1237 assert(LocationOfExcessPrecisionNotSatisfied.isValid() &&
1238 "expected a valid source location");
1240 diag::warn_excess_precision_not_supported)
1241 << static_cast<bool>(Num);
1242 }
1243}
1244
1246 if (PragmaAttributeStack.empty())
1247 return;
1248 Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
1249}
1250
1252 if(On)
1254 else
1255 OptimizeOffPragmaLocation = PragmaLoc;
1256}
1257
1259 if (!CurContext->getRedeclContext()->isFileContext()) {
1260 Diag(Loc, diag::err_pragma_expected_file_scope) << "optimize";
1261 return;
1262 }
1263
1264 MSPragmaOptimizeIsOn = IsOn;
1265}
1266
1268 SourceLocation Loc, const llvm::SmallVectorImpl<StringRef> &NoBuiltins) {
1269 if (!CurContext->getRedeclContext()->isFileContext()) {
1270 Diag(Loc, diag::err_pragma_expected_file_scope) << "function";
1271 return;
1272 }
1273
1274 MSFunctionNoBuiltins.insert_range(NoBuiltins);
1275}
1276
1278 // In the future, check other pragmas if they're implemented (e.g. pragma
1279 // optimize 0 will probably map to this functionality too).
1280 if(OptimizeOffPragmaLocation.isValid())
1282}
1283
1285 if (!FD->getIdentifier())
1286 return;
1287
1288 StringRef Name = FD->getName();
1289 auto It = FunctionToSectionMap.find(Name);
1290 if (It != FunctionToSectionMap.end()) {
1291 StringRef Section;
1292 SourceLocation Loc;
1293 std::tie(Section, Loc) = It->second;
1294
1295 if (!FD->hasAttr<SectionAttr>())
1296 FD->addAttr(SectionAttr::CreateImplicit(Context, Section));
1297 }
1298}
1299
1301 // Don't modify the function attributes if it's "on". "on" resets the
1302 // optimizations to the ones listed on the command line
1305}
1306
1308 SourceLocation Loc) {
1309 // Don't add a conflicting attribute. No diagnostic is needed.
1310 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
1311 return;
1312
1313 // Add attributes only if required. Optnone requires noinline as well, but if
1314 // either is already present then don't bother adding them.
1315 if (!FD->hasAttr<OptimizeNoneAttr>())
1316 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
1317 if (!FD->hasAttr<NoInlineAttr>())
1318 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
1319}
1320
1322 if (FD->isDeleted() || FD->isDefaulted())
1323 return;
1325 MSFunctionNoBuiltins.end());
1326 if (!MSFunctionNoBuiltins.empty())
1327 FD->addAttr(NoBuiltinAttr::CreateImplicit(Context, V.data(), V.size()));
1328}
1329
1330typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
1331enum : unsigned { NoVisibility = ~0U };
1332
1334 if (!VisContext)
1335 return;
1336
1337 NamedDecl *ND = dyn_cast<NamedDecl>(D);
1339 return;
1340
1341 VisStack *Stack = static_cast<VisStack*>(VisContext);
1342 unsigned rawType = Stack->back().first;
1343 if (rawType == NoVisibility) return;
1344
1345 VisibilityAttr::VisibilityType type
1346 = (VisibilityAttr::VisibilityType) rawType;
1347 SourceLocation loc = Stack->back().second;
1348
1349 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
1350}
1351
1353 delete static_cast<VisStack*>(VisContext);
1354 VisContext = nullptr;
1355}
1356
1357static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
1358 // Put visibility on stack.
1359 if (!S.VisContext)
1360 S.VisContext = new VisStack;
1361
1362 VisStack *Stack = static_cast<VisStack*>(S.VisContext);
1363 Stack->push_back(std::make_pair(type, loc));
1364}
1365
1367 SourceLocation PragmaLoc) {
1368 if (VisType) {
1369 // Compute visibility to use.
1370 VisibilityAttr::VisibilityType T;
1371 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
1372 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
1373 return;
1374 }
1375 PushPragmaVisibility(*this, T, PragmaLoc);
1376 } else {
1377 PopPragmaVisibility(false, PragmaLoc);
1378 }
1379}
1380
1383 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1384 switch (FPC) {
1386 NewFPFeatures.setAllowFPContractWithinStatement();
1387 break;
1390 NewFPFeatures.setAllowFPContractAcrossStatement();
1391 break;
1393 NewFPFeatures.setDisallowFPContract();
1394 break;
1395 }
1396 FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), NewFPFeatures);
1397 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1398}
1399
1401 PragmaFPKind Kind, bool IsEnabled) {
1402 if (IsEnabled) {
1403 // For value unsafe context, combining this pragma with eval method
1404 // setting is not recommended. See comment in function FixupInvocation#506.
1405 int Reason = -1;
1406 if (getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine)
1407 // Eval method set using the option 'ffp-eval-method'.
1408 Reason = 1;
1409 if (PP.getLastFPEvalPragmaLocation().isValid())
1410 // Eval method set using the '#pragma clang fp eval_method'.
1411 // We could have both an option and a pragma used to the set the eval
1412 // method. The pragma overrides the option in the command line. The Reason
1413 // of the diagnostic is overriden too.
1414 Reason = 0;
1415 if (Reason != -1)
1416 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context)
1417 << Reason << (Kind == PFK_Reassociate ? 4 : 5);
1418 }
1419
1420 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1421 switch (Kind) {
1422 case PFK_Reassociate:
1423 NewFPFeatures.setAllowFPReassociateOverride(IsEnabled);
1424 break;
1425 case PFK_Reciprocal:
1426 NewFPFeatures.setAllowReciprocalOverride(IsEnabled);
1427 break;
1428 default:
1429 llvm_unreachable("unhandled value changing pragma fp");
1430 }
1431
1432 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1433 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1434}
1435
1436void Sema::ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode FPR) {
1437 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1438 NewFPFeatures.setConstRoundingModeOverride(FPR);
1439 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1440 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1441}
1442
1445 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1446 NewFPFeatures.setSpecifiedExceptionModeOverride(FPE);
1447 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1448 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1449}
1450
1452 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1453 if (IsEnabled) {
1454 // Verify Microsoft restriction:
1455 // You can't enable fenv_access unless precise semantics are enabled.
1456 // Precise semantics can be enabled either by the float_control
1457 // pragma, or by using the /fp:precise or /fp:strict compiler options
1458 if (!isPreciseFPEnabled())
1459 Diag(Loc, diag::err_pragma_fenv_requires_precise);
1460 }
1461 NewFPFeatures.setAllowFEnvAccessOverride(IsEnabled);
1462 NewFPFeatures.setRoundingMathOverride(IsEnabled);
1463 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1464 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1465}
1466
1469 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1470 NewFPFeatures.setComplexRangeOverride(Range);
1471 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1472 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1473}
1474
1479
1480void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
1481 SourceLocation Loc) {
1482 // Visibility calculations will consider the namespace's visibility.
1483 // Here we just want to note that we're in a visibility context
1484 // which overrides any enclosing #pragma context, but doesn't itself
1485 // contribute visibility.
1487}
1488
1489void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
1490 if (!VisContext) {
1491 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1492 return;
1493 }
1494
1495 // Pop visibility from stack
1496 VisStack *Stack = static_cast<VisStack*>(VisContext);
1497
1498 const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
1499 bool StartsWithPragma = Back->first != NoVisibility;
1500 if (StartsWithPragma && IsNamespaceEnd) {
1501 Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
1502 Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
1503
1504 // For better error recovery, eat all pushes inside the namespace.
1505 do {
1506 Stack->pop_back();
1507 Back = &Stack->back();
1508 StartsWithPragma = Back->first != NoVisibility;
1509 } while (StartsWithPragma);
1510 } else if (!StartsWithPragma && !IsNamespaceEnd) {
1511 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1512 Diag(Back->second, diag::note_surrounding_namespace_starts_here);
1513 return;
1514 }
1515
1516 Stack->pop_back();
1517 // To simplify the implementation, never keep around an empty stack.
1518 if (Stack->empty())
1520}
1521
1522template <typename Ty>
1523static bool checkCommonAttributeFeatures(Sema &S, const Ty *Node,
1524 const ParsedAttr &A,
1525 bool SkipArgCountCheck) {
1526 // Several attributes carry different semantics than the parsing requires, so
1527 // those are opted out of the common argument checks.
1528 //
1529 // We also bail on unknown and ignored attributes because those are handled
1530 // as part of the target-specific handling logic.
1532 return false;
1533 // Check whether the attribute requires specific language extensions to be
1534 // enabled.
1535 if (!A.diagnoseLangOpts(S))
1536 return true;
1537 // Check whether the attribute appertains to the given subject.
1538 if (!A.diagnoseAppertainsTo(S, Node))
1539 return true;
1540 // Check whether the attribute is mutually exclusive with other attributes
1541 // that have already been applied to the declaration.
1542 if (!A.diagnoseMutualExclusion(S, Node))
1543 return true;
1544 // Check whether the attribute exists in the target architecture.
1545 if (S.CheckAttrTarget(A))
1546 return true;
1547
1548 if (A.hasCustomParsing())
1549 return false;
1550
1551 if (!SkipArgCountCheck) {
1552 if (A.getMinArgs() == A.getMaxArgs()) {
1553 // If there are no optional arguments, then checking for the argument
1554 // count is trivial.
1555 if (!A.checkExactlyNumArgs(S, A.getMinArgs()))
1556 return true;
1557 } else {
1558 // There are optional arguments, so checking is slightly more involved.
1559 if (A.getMinArgs() && !A.checkAtLeastNumArgs(S, A.getMinArgs()))
1560 return true;
1561 else if (!A.hasVariadicArg() && A.getMaxArgs() &&
1562 !A.checkAtMostNumArgs(S, A.getMaxArgs()))
1563 return true;
1564 }
1565 }
1566
1567 return false;
1568}
1569
1571 bool SkipArgCountCheck) {
1572 return ::checkCommonAttributeFeatures(*this, D, A, SkipArgCountCheck);
1573}
1575 bool SkipArgCountCheck) {
1576 return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck);
1577}
#define V(N, I)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
llvm::MachO::Record Record
Definition MachO.h:31
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
std::vector< std::pair< unsigned, SourceLocation > > VisStack
static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc)
@ NoVisibility
static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context, CXXRecordDecl *Record)
Definition SemaAttr.cpp:103
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:188
PtrTy get() const
Definition Ownership.h:171
Attr - This represents one attribute.
Definition Attr.h:44
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
static CharSourceRange getCharRange(SourceRange R)
static CharSourceRange getTokenRange(SourceRange R)
static ConstantExpr * Create(const ASTContext &Context, Expr *E, const APValue &Result)
Definition Expr.cpp:346
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Decl()=delete
bool isInStdNamespace() const
Definition DeclBase.cpp:427
T * getAttr() const
Definition DeclBase.h:573
void addAttr(Attr *A)
SourceLocation getLocation() const
Definition DeclBase.h:439
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
Definition DeclBase.cpp:553
DeclContext * getDeclContext()
Definition DeclBase.h:448
bool hasAttr() const
Definition DeclBase.h:577
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:978
The name of a declaration.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:830
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
This represents one expression.
Definition Expr.h:112
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:177
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:194
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition Expr.h:284
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
QualType getType() const
Definition Expr.h:144
Represents difference between two FPOptions values.
void setAllowFPContractAcrossStatement()
void setFPPreciseEnabled(bool Value)
void setAllowFPContractWithinStatement()
FPOptions applyOverrides(FPOptions Base)
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition Diagnostic.h:128
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.
Definition Diagnostic.h:102
Represents a function declaration or definition.
Definition Decl.h:1999
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2794
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3703
QualType getReturnType() const
Definition Decl.h:2842
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2539
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2384
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3767
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition Expr.cpp:2068
An lvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3615
FPEvalMethodKind
Possible float expression evaluation method choices.
@ FEM_Extended
Use extended type for fp arithmetic.
@ FEM_Double
Use the type double for fp arithmetic.
@ FEM_UnsetOnCommandLine
Used only for FE option processing; this is only used to indicate that the user did not specify an ex...
@ FEM_Source
Use the declared type for fp arithmetic.
ComplexRangeKind
Controls the various implementations for complex multiplication and.
FPExceptionModeKind
Possible floating point exception behavior.
@ FPE_Strict
Strictly preserve the floating-point exception semantics.
@ FPE_Ignore
Assume that floating-point exceptions are masked.
static SourceLocation findLocationAfterToken(SourceLocation loc, tok::TokenKind TKind, const SourceManager &SM, const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine)
Checks that the given token is the first token that occurs after the given location (this excludes co...
Definition Lexer.cpp:1377
Represents the results of name lookup.
Definition Lookup.h:147
DeclClass * getAsSingle() const
Definition Lookup.h:558
bool empty() const
Return true if no decls were found.
Definition Lookup.h:362
This represents a decl that may have a name.
Definition Decl.h:273
@ VisibilityForValue
Do an LV computation for, ultimately, a non-type declaration.
Definition Decl.h:460
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:294
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:300
std::optional< Visibility > getExplicitVisibility(ExplicitVisibilityKind kind) const
If visibility was explicitly specified for this declaration, return that visibility.
Definition Decl.cpp:1313
Represents a parameter to a function.
Definition Decl.h:1789
ParsedAttr - Represents a syntactic attribute.
Definition ParsedAttr.h:119
bool hasCustomParsing() const
bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const
unsigned getMinArgs() const
bool checkExactlyNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has exactly as many args as Num.
bool hasVariadicArg() const
bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const
bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const
bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at least as many args as Num.
unsigned getMaxArgs() const
bool isPragmaClangAttribute() const
True if the attribute is specified using 'pragma clang attribute'.
Definition ParsedAttr.h:363
AttributeCommonInfo::Kind getKind() const
Definition ParsedAttr.h:610
void getMatchRules(const LangOptions &LangOpts, SmallVectorImpl< std::pair< attr::SubjectMatchRule, bool > > &MatchRules) const
bool diagnoseLangOpts(class Sema &S) const
void setIsPragmaClangAttribute()
Definition ParsedAttr.h:365
bool checkAtMostNumArgs(class Sema &S, unsigned Num) const
Check if the attribute has at most as many args as Num.
void addAtEnd(ParsedAttr *newAttr)
Definition ParsedAttr.h:827
static PragmaCommentDecl * Create(const ASTContext &C, TranslationUnitDecl *DC, SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg)
Definition Decl.cpp:5374
static PragmaDetectMismatchDecl * Create(const ASTContext &C, TranslationUnitDecl *DC, SourceLocation Loc, StringRef Name, StringRef Value)
Definition Decl.cpp:5397
A (possibly-)qualified type.
Definition TypeBase.h:937
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8285
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
Definition TypeBase.h:8470
QualType getCanonicalType() const
Definition TypeBase.h:8337
Represents a struct/union/class.
Definition Decl.h:4309
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
Definition SemaBase.cpp:61
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition SemaBase.cpp:33
unsigned getPackNumber() const
Definition Sema.h:1895
bool IsPackSet() const
Definition Sema.h:1897
bool IsAlignAttr() const
Definition Sema.h:1891
Mode getAlignMode() const
Definition Sema.h:1893
PragmaStackSentinelRAII(Sema &S, StringRef SlotLabel, bool ShouldAct)
Definition SemaAttr.cpp:29
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:854
void ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn)
pragma optimize("[optimization-list]", on | off).
bool ConstantFoldAttrArgs(const AttributeCommonInfo &CI, MutableArrayRef< Expr * > Args)
ConstantFoldAttrArgs - Folds attribute arguments into ConstantExprs (unless they are value dependent ...
Definition SemaAttr.cpp:503
void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, const IdentifierInfo *Namespace)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9291
void ActOnPragmaAttributePop(SourceLocation PragmaLoc, const IdentifierInfo *Namespace)
Called on well-formed '#pragma clang attribute pop'.
void ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, StringRef Value)
ActOnPragmaDetectMismatch - Call on well-formed #pragma detect_mismatch.
Definition SemaAttr.cpp:628
const Decl * PragmaAttributeCurrentTargetDecl
The declaration that is currently receiving an attribute from the pragma attribute stack.
Definition Sema.h:2110
llvm::function_ref< void(SourceLocation, PartialDiagnostic)> InstantiationContextDiagFuncRef
Definition Sema.h:2285
void ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode)
Called to set constant rounding mode for floating point operations.
PragmaClangSection PragmaClangRodataSection
Definition Sema.h:1817
bool checkSectionName(SourceLocation LiteralLoc, StringRef Str)
void AddPragmaAttributes(Scope *S, Decl *D)
Adds the attributes that have been specified using the '#pragma clang attribute push' directives to t...
bool checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A, bool SkipArgCountCheck=false)
Handles semantic checking for features that are common to all attributes, such as checking whether a ...
void AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, SourceLocation Loc)
Adds the 'optnone' attribute to the function declaration if there are no conflicts; Loc represents th...
SourceLocation LocationOfExcessPrecisionNotSatisfied
Definition Sema.h:8284
void inferLifetimeCaptureByAttribute(FunctionDecl *FD)
Add [[clang:lifetime_capture_by(this)]] to STL container methods.
Definition SemaAttr.cpp:277
PragmaStack< FPOptionsOverride > FpPragmaStack
Definition Sema.h:2048
PragmaStack< StringLiteral * > CodeSegStack
Definition Sema.h:2042
void AddRangeBasedOptnone(FunctionDecl *FD)
Only called on function definitions; if there is a pragma in scope with the effect of a range-based o...
void ActOnPragmaMSComment(SourceLocation CommentLoc, PragmaMSCommentKind Kind, StringRef Arg)
ActOnPragmaMSComment - Called on well formed #pragma comment(kind, "arg").
Definition SemaAttr.cpp:620
SmallVector< AlignPackIncludeState, 8 > AlignPackIncludeStack
Definition Sema.h:2037
void AddAlignmentAttributesForRecord(RecordDecl *RD)
AddAlignmentAttributesForRecord - Adds any needed alignment attributes to a the record decl,...
Definition SemaAttr.cpp:54
FPOptionsOverride CurFPFeatureOverrides()
Definition Sema.h:2049
void ActOnPragmaMSSeg(SourceLocation PragmaLocation, PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, StringLiteral *SegmentName, llvm::StringRef PragmaName)
Called on well formed #pragma bss_seg/data_seg/const_seg/code_seg.
Definition SemaAttr.cpp:847
NamedDecl * LookupSingleName(Scope *S, DeclarationName Name, SourceLocation Loc, LookupNameKind NameKind, RedeclarationKind Redecl=RedeclarationKind::NotForRedeclaration)
Look up a name, looking for a single declaration.
void ActOnPragmaFloatControl(SourceLocation Loc, PragmaMsStackAction Action, PragmaFloatControlKind Value)
ActOnPragmaFloatControl - Call on well-formed #pragma float_control.
Definition SemaAttr.cpp:663
void ActOnPragmaMSPointersToMembers(LangOptions::PragmaMSPointersToMembersKind Kind, SourceLocation PragmaLoc)
ActOnPragmaMSPointersToMembers - called on well formed #pragma pointers_to_members(representation met...
Definition SemaAttr.cpp:717
void DiagnosePrecisionLossInComplexDivision()
ASTContext & Context
Definition Sema.h:1283
void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, SourceLocation PragmaLoc)
ActOnPragmaUnused - Called on well-formed '#pragma unused'.
Definition SemaAttr.cpp:935
void ActOnPragmaMSAllocText(SourceLocation PragmaLocation, StringRef Section, const SmallVector< std::tuple< IdentifierInfo *, SourceLocation > > &Functions)
Called on well-formed #pragma alloc_text().
Definition SemaAttr.cpp:899
PragmaStack< bool > StrictGuardStackCheckStack
Definition Sema.h:2045
void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute, SourceLocation PragmaLoc, attr::ParsedSubjectMatchRuleSet Rules)
PragmaStack< StringLiteral * > ConstSegStack
Definition Sema.h:2041
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.
Definition Sema.cpp:756
void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, SourceLocation PragmaLoc)
ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
Definition SemaAttr.cpp:334
void ActOnPragmaCXLimitedRange(SourceLocation Loc, LangOptions::ComplexRangeKind Range)
ActOnPragmaCXLimitedRange - Called on well formed #pragma STDC CX_LIMITED_RANGE.
void ActOnPragmaFPExceptions(SourceLocation Loc, LangOptions::FPExceptionModeKind)
Called on well formed '#pragma clang fp' that has option 'exceptions'.
void inferGslPointerAttribute(NamedDecl *ND, CXXRecordDecl *UnderlyingRecord)
Add gsl::Pointer attribute to std::container::iterator.
Definition SemaAttr.cpp:112
void ActOnPragmaFPEvalMethod(SourceLocation Loc, LangOptions::FPEvalMethodKind Value)
Definition SemaAttr.cpp:636
void ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionAction Action, PragmaClangSectionKind SecKind, StringRef SecName)
ActOnPragmaClangSection - Called on well formed #pragma clang section.
Definition SemaAttr.cpp:389
bool UnifySection(StringRef SectionName, int SectionFlags, NamedDecl *TheDecl)
Definition SemaAttr.cpp:795
void setExceptionMode(SourceLocation Loc, LangOptions::FPExceptionModeKind)
Called to set exception behavior for floating point operations.
void inferGslOwnerPointerAttribute(CXXRecordDecl *Record)
Add [[gsl::Owner]] and [[gsl::Pointer]] attributes for std:: types.
Definition SemaAttr.cpp:168
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr)
Definition Sema.cpp:272
const LangOptions & getLangOpts() const
Definition Sema.h:918
SourceLocation CurInitSegLoc
Definition Sema.h:2081
void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, SourceLocation PragmaLoc, MSVtorDispMode Value)
Called on well formed #pragma vtordisp().
Definition SemaAttr.cpp:724
void inferLifetimeBoundAttribute(FunctionDecl *FD)
Add [[clang:lifetimebound]] attr for std:: functions and methods.
Definition SemaAttr.cpp:220
Preprocessor & PP
Definition Sema.h:1282
bool MSPragmaOptimizeIsOn
The "on" or "off" argument passed by #pragma optimize, that denotes whether the optimizations in the ...
Definition Sema.h:2128
SmallVector< PragmaAttributeGroup, 2 > PragmaAttributeStack
Definition Sema.h:2106
const LangOptions & LangOpts
Definition Sema.h:1281
PragmaClangSection PragmaClangRelroSection
Definition Sema.h:1818
SourceLocation ImplicitMSInheritanceAttrLoc
Source location for newly created implicit MSInheritanceAttrs.
Definition Sema.h:1807
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 AddImplicitMSFunctionNoBuiltinAttr(FunctionDecl *FD)
Only called on function definitions; if there is a pragma in scope with the effect of a range-based n...
PragmaStack< AlignPackInfo > AlignPackStack
Definition Sema.h:2030
PragmaStack< StringLiteral * > BSSSegStack
Definition Sema.h:2040
llvm::StringMap< std::tuple< StringRef, SourceLocation > > FunctionToSectionMap
Sections used with pragma alloc_text.
Definition Sema.h:2084
llvm::SmallSetVector< StringRef, 4 > MSFunctionNoBuiltins
Set of no-builtin functions listed by #pragma function.
Definition Sema.h:2131
void AddPushedVisibilityAttribute(Decl *RD)
AddPushedVisibilityAttribute - If '#pragma GCC visibility' was used, add an appropriate visibility at...
StringLiteral * CurInitSeg
Last section used with pragma init_seg.
Definition Sema.h:2080
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1418
void ActOnPragmaMSFunction(SourceLocation Loc, const llvm::SmallVectorImpl< StringRef > &NoBuiltins)
Call on well formed #pragma function.
void ActOnPragmaMSStruct(PragmaMSStructKind Kind)
ActOnPragmaMSStruct - Called on well formed #pragma ms_struct [on|off].
Definition SemaAttr.cpp:616
bool isPreciseFPEnabled()
Are precise floating point semantics currently enabled?
Definition Sema.h:2211
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, StringLiteral *SegmentName)
Called on well-formed #pragma init_seg().
Definition SemaAttr.cpp:890
bool MSStructPragmaOn
Definition Sema.h:1804
SourceManager & getSourceManager() const
Definition Sema.h:923
void PrintPragmaAttributeInstantiationPoint()
Definition Sema.h:2299
void DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind, SourceLocation IncludeLoc)
Definition SemaAttr.cpp:550
PragmaClangSection PragmaClangTextSection
Definition Sema.h:1819
void ActOnPragmaFPValueChangingOption(SourceLocation Loc, PragmaFPKind Kind, bool IsEnabled)
Called on well formed #pragma clang fp reassociate or #pragma clang fp reciprocal.
std::vector< std::pair< QualType, unsigned > > ExcessPrecisionNotSatisfied
Definition Sema.h:8283
PragmaClangSection PragmaClangDataSection
Definition Sema.h:1816
llvm::Error isValidSectionSpecifier(StringRef Str)
Used to implement to perform semantic checking on attribute((section("foo"))) specifiers.
void PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, SourceLocation Loc)
PushNamespaceVisibilityAttr - Note that we've entered a namespace with a visibility attribute.
PragmaStack< MSVtorDispMode > VtorDispStack
Whether to insert vtordisps prior to virtual bases in the Microsoft C++ ABI.
Definition Sema.h:2029
void AddMsStructLayoutForRecord(RecordDecl *RD)
AddMsStructLayoutForRecord - Adds ms_struct layout attribute to record.
Definition SemaAttr.cpp:90
void * VisContext
VisContext - Manages the stack for #pragma GCC visibility.
Definition Sema.h:2087
bool CheckAttrTarget(const ParsedAttr &CurrAttr)
ASTConsumer & Consumer
Definition Sema.h:1284
PragmaAlignPackDiagnoseKind
Definition Sema.h:2189
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition Sema.h:1246
void DiagnoseUnterminatedPragmaAttribute()
void FreeVisContext()
FreeVisContext - Deallocate and null out VisContext.
void ModifyFnAttributesMSPragmaOptimize(FunctionDecl *FD)
Only called on function definitions; if there is a MSVC pragma optimize in scope, consider changing t...
void PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc)
PopPragmaVisibility - Pop the top element of the visibility stack; used for '#pragma GCC visibility' ...
SourceManager & SourceMgr
Definition Sema.h:1286
void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, StringRef SlotLabel, Expr *Alignment)
ActOnPragmaPack - Called on well formed #pragma pack(...).
Definition SemaAttr.cpp:438
void DiagnoseUnterminatedPragmaAlignPack()
Definition SemaAttr.cpp:589
FPOptions CurFPFeatures
Definition Sema.h:1279
PragmaStack< StringLiteral * > DataSegStack
Definition Sema.h:2039
void ActOnPragmaVisibility(const IdentifierInfo *VisType, SourceLocation PragmaLoc)
ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... .
SourceLocation OptimizeOffPragmaLocation
This represents the last location of a "#pragma clang optimize off" directive if such a directive has...
Definition Sema.h:2115
LangOptions::PragmaMSPointersToMembersKind MSPointerToMemberRepresentationMethod
Controls member pointer representation format under the MS ABI.
Definition Sema.h:1802
void ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation, PragmaMsStackAction Action, bool Value)
ActOnPragmaMSStrictGuardStackCheck - Called on well formed #pragma strict_gs_check.
Definition SemaAttr.cpp:874
PragmaClangSection PragmaClangBSSSection
Definition Sema.h:1815
void ActOnPragmaFPContract(SourceLocation Loc, LangOptions::FPModeKind FPC)
ActOnPragmaFPContract - Called on well formed #pragma {STDC,OPENCL} FP_CONTRACT and #pragma clang fp ...
void ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc)
Called on well formed #pragma clang optimize.
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
void ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled)
ActOnPragmaFenvAccess - Called on well formed #pragma STDC FENV_ACCESS.
void AddSectionMSAllocText(FunctionDecl *FD)
Only called on function definitions; if there is a #pragma alloc_text that decides which code section...
void ActOnPragmaMSSection(SourceLocation PragmaLocation, int SectionFlags, StringLiteral *SegmentName)
Called on well formed #pragma section().
Definition SemaAttr.cpp:885
void inferNullableClassAttribute(CXXRecordDecl *CRD)
Add _Nullable attributes for std:: types.
Definition SemaAttr.cpp:322
PragmaMsStackAction
Definition Sema.h:1821
@ PSK_Push_Set
Definition Sema.h:1827
@ PSK_Reset
Definition Sema.h:1822
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition Stmt.h:85
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:346
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1799
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:1973
StringRef getString() const
Definition Expr.h:1867
redecl_range redecls() const
Returns an iterator range for all the redeclarations of the same decl.
Token - This structure provides full information about a lexed token.
Definition Token.h:36
IdentifierInfo * getIdentifierInfo() const
Definition Token.h:189
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition Token.h:134
The base class of the type hierarchy.
Definition TypeBase.h:1833
bool isVoidType() const
Definition TypeBase.h:8878
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
Definition Type.h:26
bool isArrayType() const
Definition TypeBase.h:8621
bool isFunctionType() const
Definition TypeBase.h:8518
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3559
QualType getUnderlyingType() const
Definition Decl.h:3614
Represents a variable declaration or definition.
Definition Decl.h:925
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Attr > attr
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
SubjectMatchRule
A list of all the recognized kinds of attributes.
const char * getSubjectMatchRuleSpelling(SubjectMatchRule Rule)
llvm::DenseMap< int, SourceRange > ParsedSubjectMatchRuleSet
bool isGLSPointerType(QualType QT)
The JSON file list parser is used to communicate input to InstallAPI.
PragmaClangSectionAction
Definition Sema.h:473
@ PFK_Reassociate
Definition PragmaKinds.h:40
@ PFK_Reciprocal
Definition PragmaKinds.h:41
bool isa(CodeGen::Address addr)
Definition Address.h:330
@ CPlusPlus
PragmaMSCommentKind
Definition PragmaKinds.h:14
@ Nullable
Values of this type can be null.
Definition Specifiers.h:352
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ AANT_ArgumentConstantExpr
PragmaOptionsAlignKind
Definition Sema.h:475
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const FunctionProtoType * T
MSVtorDispMode
In the Microsoft ABI, this controls the placement of virtual displacement members used to implement v...
Definition LangOptions.h:37
PragmaClangSectionKind
pragma clang section kind
Definition Sema.h:464
PragmaMSStructKind
Definition PragmaKinds.h:23
@ PMSST_ON
Definition PragmaKinds.h:25
PragmaFloatControlKind
Definition PragmaKinds.h:28
@ PFC_NoExcept
Definition PragmaKinds.h:33
@ PFC_NoPrecise
Definition PragmaKinds.h:31
@ PFC_Pop
Definition PragmaKinds.h:35
@ PFC_Precise
Definition PragmaKinds.h:30
@ PFC_Except
Definition PragmaKinds.h:32
@ PFC_Push
Definition PragmaKinds.h:34
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:135
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:645
APValue Val
Val - This is the value the expression can be folded to.
Definition Expr.h:647
SmallVectorImpl< PartialDiagnosticAt > * Diag
Diag - If this is non-null, it will be filled in with a stack of notes indicating why evaluation fail...
Definition Expr.h:633
SourceLocation CurrentPragmaLocation
Definition Sema.h:2034
This an attribute introduced by #pragma clang attribute.
Definition Sema.h:2090
SourceLocation PragmaLocation
Definition Sema.h:1812
SmallVector< Slot, 2 > Stack
Definition Sema.h:2013
void Act(SourceLocation PragmaLocation, PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, ValueType Value)
Definition Sema.h:1952