clang 23.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
15#include "clang/AST/Attr.h"
16#include "clang/AST/DeclCXX.h"
17#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 "flat_map",
140 "flat_set",
141 };
142
143 static const llvm::StringSet<> Iterators{"iterator", "const_iterator",
144 "reverse_iterator",
145 "const_reverse_iterator"};
146
147 if (Parent->isInStdNamespace() && Iterators.count(ND->getName()) &&
148 Containers.count(Parent->getName()))
150 UnderlyingRecord);
151}
152
154
155 QualType Canonical = TD->getUnderlyingType().getCanonicalType();
156
157 CXXRecordDecl *RD = Canonical->getAsCXXRecordDecl();
158 if (!RD) {
159 if (auto *TST =
160 dyn_cast<TemplateSpecializationType>(Canonical.getTypePtr())) {
161
162 if (const auto *TD = TST->getTemplateName().getAsTemplateDecl())
163 RD = dyn_cast_or_null<CXXRecordDecl>(TD->getTemplatedDecl());
164 }
165 }
166
168}
169
171 static const llvm::StringSet<> StdOwners{
172 "any",
173 "array",
174 "basic_regex",
175 "basic_string",
176 "deque",
177 "forward_list",
178 "vector",
179 "list",
180 "map",
181 "multiset",
182 "multimap",
183 "optional",
184 "priority_queue",
185 "queue",
186 "set",
187 "stack",
188 "unique_ptr",
189 "unordered_set",
190 "unordered_map",
191 "unordered_multiset",
192 "unordered_multimap",
193 "variant",
194 "flat_map",
195 "flat_set",
196 };
197 static const llvm::StringSet<> StdPointers{
198 "basic_string_view",
199 "reference_wrapper",
200 "regex_iterator",
201 "span",
202 };
203
204 if (!Record->getIdentifier())
205 return;
206
207 // Handle classes that directly appear in std namespace.
208 if (Record->isInStdNamespace()) {
209 if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
210 return;
211
212 if (StdOwners.count(Record->getName()))
214 else if (StdPointers.count(Record->getName()))
216
217 return;
218 }
219
220 // Handle nested classes that could be a gsl::Pointer.
222}
223
224// This uses recursion and is only safe for small Stmt (e.g., the body of
225// std::make_unique). Do not use this for other Stmt without addressing the
226// potential for stack exhaustion.
227static const CXXNewExpr *findCXXNewExpr(const Stmt *S) {
228 if (!S)
229 return nullptr;
230 if (const auto *E = dyn_cast<CXXNewExpr>(S))
231 return E;
232 for (const Stmt *Child : S->children())
233 if (const CXXNewExpr *E = findCXXNewExpr(Child))
234 return E;
235 return nullptr;
236}
237
239 if (FD->getNumParams() == 0)
240 return;
241 // Skip void returning functions (except constructors). This can occur in
242 // cases like 'as_const'.
244 return;
245
246 if (unsigned BuiltinID = FD->getBuiltinID()) {
247 // Add lifetime attribute to std::move, std::fowrard et al.
248 switch (BuiltinID) {
249 case Builtin::BIaddressof:
250 case Builtin::BI__addressof:
251 case Builtin::BI__builtin_addressof:
252 case Builtin::BIas_const:
253 case Builtin::BIforward:
254 case Builtin::BIforward_like:
255 case Builtin::BImove:
256 case Builtin::BImove_if_noexcept:
257 if (ParmVarDecl *P = FD->getParamDecl(0u);
258 !P->hasAttr<LifetimeBoundAttr>())
259 P->addAttr(
260 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation()));
261 break;
262 default:
263 break;
264 }
265 return;
266 }
267
268 // Handle std::make_unique to propagate lifetimebound attributes from the
269 // constructed type's constructor to make_unique's parameters by looking
270 // into its body.
271 if (FD->getDeclName().isIdentifier() && FD->getName() == "make_unique") {
272 const FunctionDecl *BodyDecl = nullptr;
273 if (FD->getBody(BodyDecl))
274 if (const CXXNewExpr *NewExpr = findCXXNewExpr(BodyDecl->getBody()))
275 if (const CXXConstructExpr *ConstructExpr = NewExpr->getConstructExpr())
276 if (const CXXConstructorDecl *Ctor = ConstructExpr->getConstructor())
277 for (unsigned I = 0; I < Ctor->getNumParams(); ++I)
278 // Only infer lifetimebound for references. For pointers and
279 // views, the forwarding reference in make_unique would
280 // incorrectly track the lifetime of the local pointer variable
281 // itself, rather than the data it points to.
282 if (I < FD->getNumParams() &&
283 Ctor->getParamDecl(I)->hasAttr<LifetimeBoundAttr>() &&
284 Ctor->getParamDecl(I)->getType()->isReferenceType())
285 FD->getParamDecl(I)->addAttr(LifetimeBoundAttr::CreateImplicit(
286 Context, FD->getLocation()));
287 return;
288 }
289
290 if (auto *CMD = dyn_cast<CXXMethodDecl>(FD)) {
291 const auto *CRD = CMD->getParent();
292 if (!CRD->isInStdNamespace() || !CRD->getIdentifier())
293 return;
294
295 if (isa<CXXConstructorDecl>(CMD)) {
296 auto *Param = CMD->getParamDecl(0);
297 if (Param->hasAttr<LifetimeBoundAttr>())
298 return;
299 if (CRD->getName() == "basic_string_view" &&
300 Param->getType()->isPointerType()) {
301 // construct from a char array pointed by a pointer.
302 // basic_string_view(const CharT* s);
303 // basic_string_view(const CharT* s, size_type count);
304 Param->addAttr(
305 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation()));
306 } else if (CRD->getName() == "span") {
307 // construct from a reference of array.
308 // span(std::type_identity_t<element_type> (&arr)[N]);
309 const auto *LRT = Param->getType()->getAs<LValueReferenceType>();
310 if (LRT && LRT->getPointeeType().IgnoreParens()->isArrayType())
311 Param->addAttr(
312 LifetimeBoundAttr::CreateImplicit(Context, FD->getLocation()));
313 }
314 }
315 }
316}
317
319 auto *MD = dyn_cast_if_present<CXXMethodDecl>(FD);
320 if (!MD || !MD->getParent()->isInStdNamespace())
321 return;
322 auto Annotate = [this](const FunctionDecl *MD) {
323 // Do not infer if any parameter is explicitly annotated.
324 for (ParmVarDecl *PVD : MD->parameters())
325 if (PVD->hasAttr<LifetimeCaptureByAttr>())
326 return;
327 for (ParmVarDecl *PVD : MD->parameters()) {
328 // Methods in standard containers that capture values typically accept
329 // reference-type parameters, e.g., `void push_back(const T& value)`.
330 // We only apply the lifetime_capture_by attribute to parameters of
331 // pointer-like reference types (`const T&`, `T&&`).
332 if (PVD->getType()->isReferenceType() &&
333 lifetimes::isGslPointerType(PVD->getType().getNonReferenceType())) {
334 int CaptureByThis[] = {LifetimeCaptureByAttr::This};
335 PVD->addAttr(
336 LifetimeCaptureByAttr::CreateImplicit(Context, CaptureByThis, 1));
337 }
338 }
339 };
340
341 if (!MD->getIdentifier()) {
342 static const llvm::StringSet<> MapLikeContainer{
343 "map",
344 "multimap",
345 "unordered_map",
346 "unordered_multimap",
347 };
348 // Infer for the map's operator []:
349 // std::map<string_view, ...> m;
350 // m[ReturnString(..)] = ...; // !dangling references in m.
351 if (MD->getOverloadedOperator() == OO_Subscript &&
352 MapLikeContainer.contains(MD->getParent()->getName()))
353 Annotate(MD);
354 return;
355 }
356 static const llvm::StringSet<> CapturingMethods{
357 "insert", "insert_or_assign", "push", "push_front", "push_back"};
358 if (!CapturingMethods.contains(MD->getName()))
359 return;
360 if (MD->getName() == "insert" && MD->getParent()->getName() == "basic_string")
361 return;
362 Annotate(MD);
363}
364
366 static const llvm::StringSet<> Nullable{
367 "auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr",
368 "coroutine_handle", "function", "move_only_function",
369 };
370
371 if (CRD->isInStdNamespace() && Nullable.count(CRD->getName()) &&
372 !CRD->hasAttr<TypeNullableAttr>())
373 for (Decl *Redecl : CRD->redecls())
374 Redecl->addAttr(TypeNullableAttr::CreateImplicit(Context));
375}
376
378 SourceLocation PragmaLoc) {
381
382 switch (Kind) {
383 // For most of the platforms we support, native and natural are the same.
384 // With XL, native is the same as power, natural means something else.
387 Action = Sema::PSK_Push_Set;
388 break;
390 Action = Sema::PSK_Push_Set;
391 ModeVal = AlignPackInfo::Natural;
392 break;
393
394 // Note that '#pragma options align=packed' is not equivalent to attribute
395 // packed, it has a different precedence relative to attribute aligned.
397 Action = Sema::PSK_Push_Set;
398 ModeVal = AlignPackInfo::Packed;
399 break;
400
402 // Check if the target supports this.
403 if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
404 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
405 return;
406 }
407 Action = Sema::PSK_Push_Set;
408 ModeVal = AlignPackInfo::Mac68k;
409 break;
411 // Reset just pops the top of the stack, or resets the current alignment to
412 // default.
413 Action = Sema::PSK_Pop;
414 if (AlignPackStack.Stack.empty()) {
415 if (AlignPackStack.CurrentValue.getAlignMode() != AlignPackInfo::Native ||
416 AlignPackStack.CurrentValue.IsPackAttr()) {
417 Action = Sema::PSK_Reset;
418 } else {
419 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
420 << "stack empty";
421 return;
422 }
423 }
424 break;
425 }
426
427 AlignPackInfo Info(ModeVal, getLangOpts().XLPragmaPack);
428
429 AlignPackStack.Act(PragmaLoc, Action, StringRef(), Info);
430}
431
435 StringRef SecName) {
436 PragmaClangSection *CSec;
437 int SectionFlags = ASTContext::PSF_Read;
438 switch (SecKind) {
440 CSec = &PragmaClangBSSSection;
442 break;
445 SectionFlags |= ASTContext::PSF_Write;
446 break;
449 break;
452 break;
455 SectionFlags |= ASTContext::PSF_Execute;
456 break;
457 default:
458 llvm_unreachable("invalid clang section kind");
459 }
460
461 if (Action == PragmaClangSectionAction::Clear) {
462 CSec->Valid = false;
463 return;
464 }
465
466 if (llvm::Error E = isValidSectionSpecifier(SecName)) {
467 Diag(PragmaLoc, diag::err_pragma_section_invalid_for_target)
468 << toString(std::move(E));
469 CSec->Valid = false;
470 return;
471 }
472
473 if (UnifySection(SecName, SectionFlags, PragmaLoc))
474 return;
475
476 CSec->Valid = true;
477 CSec->SectionName = std::string(SecName);
478 CSec->PragmaLocation = PragmaLoc;
479}
480
482 StringRef SlotLabel, Expr *Alignment) {
483 bool IsXLPragma = getLangOpts().XLPragmaPack;
484 // XL pragma pack does not support identifier syntax.
485 if (IsXLPragma && !SlotLabel.empty()) {
486 Diag(PragmaLoc, diag::err_pragma_pack_identifer_not_supported);
487 return;
488 }
489
490 const AlignPackInfo CurVal = AlignPackStack.CurrentValue;
491
492 // If specified then alignment must be a "small" power of two.
493 unsigned AlignmentVal = 0;
494 AlignPackInfo::Mode ModeVal = CurVal.getAlignMode();
495
496 if (Alignment) {
497 std::optional<llvm::APSInt> Val;
498 Val = Alignment->getIntegerConstantExpr(Context);
499
500 // pack(0) is like pack(), which just works out since that is what
501 // we use 0 for in PackAttr.
502 if (Alignment->isTypeDependent() || !Val ||
503 !(*Val == 0 || Val->isPowerOf2()) || Val->getZExtValue() > 16) {
504 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
505 return; // Ignore
506 }
507
508 if (IsXLPragma && *Val == 0) {
509 // pack(0) does not work out with XL.
510 Diag(PragmaLoc, diag::err_pragma_pack_invalid_alignment);
511 return; // Ignore
512 }
513
514 AlignmentVal = (unsigned)Val->getZExtValue();
515 }
516
517 if (Action == Sema::PSK_Show) {
518 // Show the current alignment, making sure to show the right value
519 // for the default.
520 // FIXME: This should come from the target.
521 AlignmentVal = CurVal.IsPackSet() ? CurVal.getPackNumber() : 8;
522 if (ModeVal == AlignPackInfo::Mac68k &&
523 (IsXLPragma || CurVal.IsAlignAttr()))
524 Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
525 else
526 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
527 }
528
529 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
530 // "#pragma pack(pop, identifier, n) is undefined"
531 if (Action & Sema::PSK_Pop) {
532 if (Alignment && !SlotLabel.empty())
533 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifier_and_alignment);
534 if (AlignPackStack.Stack.empty()) {
535 assert(CurVal.getAlignMode() == AlignPackInfo::Native &&
536 "Empty pack stack can only be at Native alignment mode.");
537 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty";
538 }
539 }
540
541 AlignPackInfo Info(ModeVal, AlignmentVal, IsXLPragma);
542
543 AlignPackStack.Act(PragmaLoc, Action, SlotLabel, Info);
544}
545
549 for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
550 Expr *&E = Args.begin()[Idx];
551 assert(E && "error are handled before");
552 if (E->isValueDependent() || E->isTypeDependent())
553 continue;
554
555 // FIXME: Use DefaultFunctionArrayLValueConversion() in place of the logic
556 // that adds implicit casts here.
557 if (E->getType()->isArrayType())
558 E = ImpCastExprToType(E, Context.getPointerType(E->getType()),
559 clang::CK_ArrayToPointerDecay)
560 .get();
561 if (E->getType()->isFunctionType())
563 Context.getPointerType(E->getType()),
564 clang::CK_FunctionToPointerDecay, E, nullptr,
566 if (E->isLValue())
568 clang::CK_LValueToRValue, E, nullptr,
570
571 Expr::EvalResult Eval;
572 Notes.clear();
573 Eval.Diag = &Notes;
574
575 bool Result = E->EvaluateAsConstantExpr(Eval, Context);
576
577 /// Result means the expression can be folded to a constant.
578 /// Note.empty() means the expression is a valid constant expression in the
579 /// current language mode.
580 if (!Result || !Notes.empty()) {
581 Diag(E->getBeginLoc(), diag::err_attribute_argument_n_type)
582 << CI << (Idx + 1) << AANT_ArgumentConstantExpr;
583 for (auto &Note : Notes)
584 Diag(Note.first, Note.second);
585 return false;
586 }
587 E = ConstantExpr::Create(Context, E, Eval.Val);
588 }
589
590 return true;
591}
592
594 SourceLocation IncludeLoc) {
596 SourceLocation PrevLocation = AlignPackStack.CurrentPragmaLocation;
597 // Warn about non-default alignment at #includes (without redundant
598 // warnings for the same directive in nested includes).
599 // The warning is delayed until the end of the file to avoid warnings
600 // for files that don't have any records that are affected by the modified
601 // alignment.
602 bool HasNonDefaultValue =
603 AlignPackStack.hasValue() &&
604 (AlignPackIncludeStack.empty() ||
605 AlignPackIncludeStack.back().CurrentPragmaLocation != PrevLocation);
606 AlignPackIncludeStack.push_back(
607 {AlignPackStack.CurrentValue,
608 AlignPackStack.hasValue() ? PrevLocation : SourceLocation(),
609 HasNonDefaultValue, /*ShouldWarnOnInclude*/ false});
610 return;
611 }
612
614 "invalid kind");
615 AlignPackIncludeState PrevAlignPackState =
616 AlignPackIncludeStack.pop_back_val();
617 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack
618 // information, diagnostics below might not be accurate if we have mixed
619 // pragmas.
620 if (PrevAlignPackState.ShouldWarnOnInclude) {
621 // Emit the delayed non-default alignment at #include warning.
622 Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include);
623 Diag(PrevAlignPackState.CurrentPragmaLocation, diag::note_pragma_pack_here);
624 }
625 // Warn about modified alignment after #includes.
626 if (PrevAlignPackState.CurrentValue != AlignPackStack.CurrentValue) {
627 Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include);
628 Diag(AlignPackStack.CurrentPragmaLocation, diag::note_pragma_pack_here);
629 }
630}
631
633 if (AlignPackStack.Stack.empty())
634 return;
635 bool IsInnermost = true;
636
637 // FIXME: AlignPackStack may contain both #pragma align and #pragma pack
638 // information, diagnostics below might not be accurate if we have mixed
639 // pragmas.
640 for (const auto &StackSlot : llvm::reverse(AlignPackStack.Stack)) {
641 Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof);
642 // The user might have already reset the alignment, so suggest replacing
643 // the reset with a pop.
644 if (IsInnermost &&
645 AlignPackStack.CurrentValue == AlignPackStack.DefaultValue) {
646 auto DB = Diag(AlignPackStack.CurrentPragmaLocation,
647 diag::note_pragma_pack_pop_instead_reset);
648 SourceLocation FixItLoc =
649 Lexer::findLocationAfterToken(AlignPackStack.CurrentPragmaLocation,
650 tok::l_paren, SourceMgr, LangOpts,
651 /*SkipTrailing=*/false);
652 if (FixItLoc.isValid())
653 DB << FixItHint::CreateInsertion(FixItLoc, "pop");
654 }
655 IsInnermost = false;
656 }
657}
658
662
664 PragmaMSCommentKind Kind, StringRef Arg) {
665 auto *PCD = PragmaCommentDecl::Create(
666 Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg);
667 Context.getTranslationUnitDecl()->addDecl(PCD);
668 Consumer.HandleTopLevelDecl(DeclGroupRef(PCD));
669}
670
672 StringRef Value) {
674 Context, Context.getTranslationUnitDecl(), Loc, Name, Value);
675 Context.getTranslationUnitDecl()->addDecl(PDMD);
676 Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
677}
678
682 switch (Value) {
683 default:
684 llvm_unreachable("invalid pragma eval_method kind");
686 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Source);
687 break;
689 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Double);
690 break;
692 NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Extended);
693 break;
694 }
695 if (getLangOpts().ApproxFunc)
696 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 0;
697 if (getLangOpts().AllowFPReassoc)
698 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 1;
699 if (getLangOpts().AllowRecip)
700 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 2;
701 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
702 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
703 PP.setCurrentFPEvalMethod(Loc, Value);
704}
705
707 PragmaMsStackAction Action,
710 if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) &&
711 !CurContext->getRedeclContext()->isFileContext()) {
712 // Push and pop can only occur at file or namespace scope, or within a
713 // language linkage declaration.
714 Diag(Loc, diag::err_pragma_fc_pp_scope);
715 return;
716 }
717 switch (Value) {
718 default:
719 llvm_unreachable("invalid pragma float_control kind");
720 case PFC_Precise:
721 NewFPFeatures.setFPPreciseEnabled(true);
722 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
723 break;
724 case PFC_NoPrecise:
725 if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict)
726 Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept);
727 else if (CurFPFeatures.getAllowFEnvAccess())
728 Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv);
729 else
730 NewFPFeatures.setFPPreciseEnabled(false);
731 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
732 break;
733 case PFC_Except:
734 if (!isPreciseFPEnabled())
735 Diag(Loc, diag::err_pragma_fc_except_requires_precise);
736 else
737 NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Strict);
738 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
739 break;
740 case PFC_NoExcept:
741 NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Ignore);
742 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
743 break;
744 case PFC_Push:
745 FpPragmaStack.Act(Loc, Sema::PSK_Push_Set, StringRef(), NewFPFeatures);
746 break;
747 case PFC_Pop:
748 if (FpPragmaStack.Stack.empty()) {
749 Diag(Loc, diag::warn_pragma_pop_failed) << "float_control"
750 << "stack empty";
751 return;
752 }
753 FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
754 NewFPFeatures = FpPragmaStack.CurrentValue;
755 break;
756 }
757 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
758}
759
766
768 SourceLocation PragmaLoc,
769 MSVtorDispMode Mode) {
770 if (Action & PSK_Pop && VtorDispStack.Stack.empty())
771 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
772 << "stack empty";
773 VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode);
774}
775
776template <>
778 PragmaMsStackAction Action,
779 llvm::StringRef StackSlotLabel,
780 AlignPackInfo Value) {
781 if (Action == PSK_Reset) {
782 CurrentValue = DefaultValue;
783 CurrentPragmaLocation = PragmaLocation;
784 return;
785 }
786 if (Action & PSK_Push)
787 Stack.emplace_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
788 PragmaLocation));
789 else if (Action & PSK_Pop) {
790 if (!StackSlotLabel.empty()) {
791 // If we've got a label, try to find it and jump there.
792 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
793 return x.StackSlotLabel == StackSlotLabel;
794 });
795 // We found the label, so pop from there.
796 if (I != Stack.rend()) {
797 CurrentValue = I->Value;
798 CurrentPragmaLocation = I->PragmaLocation;
799 Stack.erase(std::prev(I.base()), Stack.end());
800 }
801 } else if (Value.IsXLStack() && Value.IsAlignAttr() &&
802 CurrentValue.IsPackAttr()) {
803 // XL '#pragma align(reset)' would pop the stack until
804 // a current in effect pragma align is popped.
805 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
806 return x.Value.IsAlignAttr();
807 });
808 // If we found pragma align so pop from there.
809 if (I != Stack.rend()) {
810 Stack.erase(std::prev(I.base()), Stack.end());
811 if (Stack.empty()) {
812 CurrentValue = DefaultValue;
813 CurrentPragmaLocation = PragmaLocation;
814 } else {
815 CurrentValue = Stack.back().Value;
816 CurrentPragmaLocation = Stack.back().PragmaLocation;
817 Stack.pop_back();
818 }
819 }
820 } else if (!Stack.empty()) {
821 // xl '#pragma align' sets the baseline, and `#pragma pack` cannot pop
822 // over the baseline.
823 if (Value.IsXLStack() && Value.IsPackAttr() && CurrentValue.IsAlignAttr())
824 return;
825
826 // We don't have a label, just pop the last entry.
827 CurrentValue = Stack.back().Value;
828 CurrentPragmaLocation = Stack.back().PragmaLocation;
829 Stack.pop_back();
830 }
831 }
832 if (Action & PSK_Set) {
833 CurrentValue = Value;
834 CurrentPragmaLocation = PragmaLocation;
835 }
836}
837
838bool Sema::UnifySection(StringRef SectionName, int SectionFlags,
839 NamedDecl *Decl) {
840 SourceLocation PragmaLocation;
841 if (auto A = Decl->getAttr<SectionAttr>())
842 if (A->isImplicit())
843 PragmaLocation = A->getLocation();
844 auto [SectionIt, Inserted] = Context.SectionInfos.try_emplace(
845 SectionName, Decl, PragmaLocation, SectionFlags);
846 if (Inserted)
847 return false;
848 // A pre-declared section takes precedence w/o diagnostic.
849 const auto &Section = SectionIt->second;
850 if (Section.SectionFlags == SectionFlags ||
851 ((SectionFlags & ASTContext::PSF_Implicit) &&
852 !(Section.SectionFlags & ASTContext::PSF_Implicit)))
853 return false;
854 Diag(Decl->getLocation(), diag::err_section_conflict) << Decl << Section;
855 if (Section.Decl)
856 Diag(Section.Decl->getLocation(), diag::note_declared_at)
857 << Section.Decl->getName();
858 if (PragmaLocation.isValid())
859 Diag(PragmaLocation, diag::note_pragma_entered_here);
860 if (Section.PragmaSectionLocation.isValid())
861 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
862 return true;
863}
864
865bool Sema::UnifySection(StringRef SectionName,
866 int SectionFlags,
867 SourceLocation PragmaSectionLocation) {
868 auto SectionIt = Context.SectionInfos.find(SectionName);
869 if (SectionIt != Context.SectionInfos.end()) {
870 const auto &Section = SectionIt->second;
871 if (Section.SectionFlags == SectionFlags)
872 return false;
873 if (!(Section.SectionFlags & ASTContext::PSF_Implicit)) {
874 Diag(PragmaSectionLocation, diag::err_section_conflict)
875 << "this" << Section;
876 if (Section.Decl)
877 Diag(Section.Decl->getLocation(), diag::note_declared_at)
878 << Section.Decl->getName();
879 if (Section.PragmaSectionLocation.isValid())
880 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
881 return true;
882 }
883 }
884 Context.SectionInfos[SectionName] =
885 ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
886 return false;
887}
888
889/// Called on well formed \#pragma bss_seg().
891 PragmaMsStackAction Action,
892 llvm::StringRef StackSlotLabel,
893 StringLiteral *SegmentName,
894 llvm::StringRef PragmaName) {
896 llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
897 .Case("data_seg", &DataSegStack)
898 .Case("bss_seg", &BSSSegStack)
899 .Case("const_seg", &ConstSegStack)
900 .Case("code_seg", &CodeSegStack);
901 if (Action & PSK_Pop && Stack->Stack.empty())
902 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
903 << "stack empty";
904 if (SegmentName) {
905 if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
906 return;
907
908 if (SegmentName->getString() == ".drectve" &&
909 Context.getTargetInfo().getCXXABI().isMicrosoft())
910 Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName;
911 }
912
913 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
914}
915
916/// Called on well formed \#pragma strict_gs_check().
918 PragmaMsStackAction Action,
919 bool Value) {
920 if (Action & PSK_Pop && StrictGuardStackCheckStack.Stack.empty())
921 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "strict_gs_check"
922 << "stack empty";
923
924 StrictGuardStackCheckStack.Act(PragmaLocation, Action, StringRef(), Value);
925}
926
927/// Called on well formed \#pragma bss_seg().
929 int SectionFlags, StringLiteral *SegmentName) {
930 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
931}
932
934 StringLiteral *SegmentName) {
935 // There's no stack to maintain, so we just have a current section. When we
936 // see the default section, reset our current section back to null so we stop
937 // tacking on unnecessary attributes.
938 CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
939 CurInitSegLoc = PragmaLocation;
940}
941
943 SourceLocation PragmaLocation, StringRef Section,
944 const SmallVector<std::tuple<IdentifierInfo *, SourceLocation>>
945 &Functions) {
946 if (!CurContext->getRedeclContext()->isFileContext()) {
947 Diag(PragmaLocation, diag::err_pragma_expected_file_scope) << "alloc_text";
948 return;
949 }
950
951 for (auto &Function : Functions) {
952 IdentifierInfo *II;
953 SourceLocation Loc;
954 std::tie(II, Loc) = Function;
955
956 DeclarationName DN(II);
958 if (!ND) {
959 Diag(Loc, diag::err_undeclared_use) << II->getName();
960 return;
961 }
962
963 auto *FD = dyn_cast<FunctionDecl>(ND->getCanonicalDecl());
964 if (!FD) {
965 Diag(Loc, diag::err_pragma_alloc_text_not_function);
966 return;
967 }
968
969 if (getLangOpts().CPlusPlus && !FD->isInExternCContext()) {
970 Diag(Loc, diag::err_pragma_alloc_text_c_linkage);
971 return;
972 }
973
974 FunctionToSectionMap[II->getName()] = std::make_tuple(Section, Loc);
975 }
976}
977
978void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
979 SourceLocation PragmaLoc) {
980
981 IdentifierInfo *Name = IdTok.getIdentifierInfo();
982 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
983 LookupName(Lookup, curScope, /*AllowBuiltinCreation=*/true);
984
985 if (Lookup.empty()) {
986 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
987 << Name << SourceRange(IdTok.getLocation());
988 return;
989 }
990
991 VarDecl *VD = Lookup.getAsSingle<VarDecl>();
992 if (!VD) {
993 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
994 << Name << SourceRange(IdTok.getLocation());
995 return;
996 }
997
998 // Warn if this was used before being marked unused.
999 if (VD->isUsed())
1000 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
1001
1002 VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(),
1003 UnusedAttr::GNU_unused));
1004}
1005
1006namespace {
1007
1008std::optional<attr::SubjectMatchRule>
1009getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
1010 using namespace attr;
1011 switch (Rule) {
1012 default:
1013 return std::nullopt;
1014#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
1015#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
1016 case Value: \
1017 return Parent;
1018#include "clang/Basic/AttrSubMatchRulesList.inc"
1019 }
1020}
1021
1022bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
1023 using namespace attr;
1024 switch (Rule) {
1025 default:
1026 return false;
1027#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
1028#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
1029 case Value: \
1030 return IsNegated;
1031#include "clang/Basic/AttrSubMatchRulesList.inc"
1032 }
1033}
1034
1035CharSourceRange replacementRangeForListElement(const Sema &S,
1036 SourceRange Range) {
1037 // Make sure that the ',' is removed as well.
1038 SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
1039 Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
1040 /*SkipTrailingWhitespaceAndNewLine=*/false);
1041 if (AfterCommaLoc.isValid())
1042 return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
1043 else
1044 return CharSourceRange::getTokenRange(Range);
1045}
1046
1047std::string
1048attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
1049 std::string Result;
1050 llvm::raw_string_ostream OS(Result);
1051 for (const auto &I : llvm::enumerate(Rules)) {
1052 if (I.index())
1053 OS << (I.index() == Rules.size() - 1 ? ", and " : ", ");
1054 OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
1055 }
1056 return Result;
1057}
1058
1059} // end anonymous namespace
1060
1062 ParsedAttr &Attribute, SourceLocation PragmaLoc,
1064 Attribute.setIsPragmaClangAttribute();
1066 // Gather the subject match rules that are supported by the attribute.
1068 StrictSubjectMatchRuleSet;
1069 Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
1070
1071 // Figure out which subject matching rules are valid.
1072 if (StrictSubjectMatchRuleSet.empty()) {
1073 // Check for contradicting match rules. Contradicting match rules are
1074 // either:
1075 // - a top-level rule and one of its sub-rules. E.g. variable and
1076 // variable(is_parameter).
1077 // - a sub-rule and a sibling that's negated. E.g.
1078 // variable(is_thread_local) and variable(unless(is_parameter))
1079 llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2>
1080 RulesToFirstSpecifiedNegatedSubRule;
1081 for (const auto &Rule : Rules) {
1082 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1083 std::optional<attr::SubjectMatchRule> ParentRule =
1084 getParentAttrMatcherRule(MatchRule);
1085 if (!ParentRule)
1086 continue;
1087 auto It = Rules.find(*ParentRule);
1088 if (It != Rules.end()) {
1089 // A sub-rule contradicts a parent rule.
1090 Diag(Rule.second.getBegin(),
1091 diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
1093 << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
1095 replacementRangeForListElement(*this, Rule.second));
1096 // Keep going without removing this rule as it won't change the set of
1097 // declarations that receive the attribute.
1098 continue;
1099 }
1100 if (isNegatedAttrMatcherSubRule(MatchRule))
1101 RulesToFirstSpecifiedNegatedSubRule.insert(
1102 std::make_pair(*ParentRule, Rule));
1103 }
1104 bool IgnoreNegatedSubRules = false;
1105 for (const auto &Rule : Rules) {
1106 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1107 std::optional<attr::SubjectMatchRule> ParentRule =
1108 getParentAttrMatcherRule(MatchRule);
1109 if (!ParentRule)
1110 continue;
1111 auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
1112 if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
1113 It->second != Rule) {
1114 // Negated sub-rule contradicts another sub-rule.
1115 Diag(
1116 It->second.second.getBegin(),
1117 diag::
1118 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
1120 attr::SubjectMatchRule(It->second.first))
1121 << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
1123 replacementRangeForListElement(*this, It->second.second));
1124 // Keep going but ignore all of the negated sub-rules.
1125 IgnoreNegatedSubRules = true;
1126 RulesToFirstSpecifiedNegatedSubRule.erase(It);
1127 }
1128 }
1129
1130 if (!IgnoreNegatedSubRules) {
1131 for (const auto &Rule : Rules)
1132 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
1133 } else {
1134 for (const auto &Rule : Rules) {
1135 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
1136 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
1137 }
1138 }
1139 Rules.clear();
1140 } else {
1141 // Each rule in Rules must be a strict subset of the attribute's
1142 // SubjectMatch rules. I.e. we're allowed to use
1143 // `apply_to=variables(is_global)` on an attrubute with SubjectList<[Var]>,
1144 // but should not allow `apply_to=variables` on an attribute which has
1145 // `SubjectList<[GlobalVar]>`.
1146 for (const auto &StrictRule : StrictSubjectMatchRuleSet) {
1147 // First, check for exact match.
1148 if (Rules.erase(StrictRule.first)) {
1149 // Add the rule to the set of attribute receivers only if it's supported
1150 // in the current language mode.
1151 if (StrictRule.second)
1152 SubjectMatchRules.push_back(StrictRule.first);
1153 }
1154 }
1155 // Check remaining rules for subset matches.
1156 auto RulesToCheck = Rules;
1157 for (const auto &Rule : RulesToCheck) {
1158 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1159 if (auto ParentRule = getParentAttrMatcherRule(MatchRule)) {
1160 if (llvm::any_of(StrictSubjectMatchRuleSet,
1161 [ParentRule](const auto &StrictRule) {
1162 return StrictRule.first == *ParentRule &&
1163 StrictRule.second; // IsEnabled
1164 })) {
1165 SubjectMatchRules.push_back(MatchRule);
1166 Rules.erase(MatchRule);
1167 }
1168 }
1169 }
1170 }
1171
1172 if (!Rules.empty()) {
1173 auto Diagnostic =
1174 Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
1175 << Attribute;
1177 for (const auto &Rule : Rules) {
1178 ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
1180 replacementRangeForListElement(*this, Rule.second));
1181 }
1182 Diagnostic << attrMatcherRuleListToString(ExtraRules);
1183 }
1184
1185 if (PragmaAttributeStack.empty()) {
1186 Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push);
1187 return;
1188 }
1189
1190 PragmaAttributeStack.back().Entries.push_back(
1191 {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
1192}
1193
1195 const IdentifierInfo *Namespace) {
1196 PragmaAttributeStack.emplace_back();
1197 PragmaAttributeStack.back().Loc = PragmaLoc;
1198 PragmaAttributeStack.back().Namespace = Namespace;
1199}
1200
1202 const IdentifierInfo *Namespace) {
1203 if (PragmaAttributeStack.empty()) {
1204 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1205 return;
1206 }
1207
1208 // Dig back through the stack trying to find the most recently pushed group
1209 // that in Namespace. Note that this works fine if no namespace is present,
1210 // think of push/pops without namespaces as having an implicit "nullptr"
1211 // namespace.
1212 for (size_t Index = PragmaAttributeStack.size(); Index;) {
1213 --Index;
1214 if (PragmaAttributeStack[Index].Namespace == Namespace) {
1215 for (const PragmaAttributeEntry &Entry :
1216 PragmaAttributeStack[Index].Entries) {
1217 if (!Entry.IsUsed) {
1218 assert(Entry.Attribute && "Expected an attribute");
1219 Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
1220 << *Entry.Attribute;
1221 Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
1222 }
1223 }
1224 PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index);
1225 return;
1226 }
1227 }
1228
1229 if (Namespace)
1230 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch)
1231 << 0 << Namespace->getName();
1232 else
1233 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1234}
1235
1237 if (PragmaAttributeStack.empty())
1238 return;
1239
1240 if (const auto *P = dyn_cast<ParmVarDecl>(D))
1241 if (P->getType()->isVoidType())
1242 return;
1243
1244 for (auto &Group : PragmaAttributeStack) {
1245 for (auto &Entry : Group.Entries) {
1246 ParsedAttr *Attribute = Entry.Attribute;
1247 assert(Attribute && "Expected an attribute");
1248 assert(Attribute->isPragmaClangAttribute() &&
1249 "expected #pragma clang attribute");
1250
1251 // Ensure that the attribute can be applied to the given declaration.
1252 bool Applies = false;
1253 for (const auto &Rule : Entry.MatchRules) {
1254 if (Attribute->appliesToDecl(D, Rule)) {
1255 Applies = true;
1256 break;
1257 }
1258 }
1259 if (!Applies)
1260 continue;
1261 Entry.IsUsed = true;
1264 Attrs.addAtEnd(Attribute);
1265 ProcessDeclAttributeList(S, D, Attrs);
1267 }
1268 }
1269}
1270
1273 assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
1274 DiagFunc(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
1275 PDiag(diag::note_pragma_attribute_applied_decl_here));
1276}
1277
1279 for (auto &[Type, Num] : ExcessPrecisionNotSatisfied) {
1280 assert(LocationOfExcessPrecisionNotSatisfied.isValid() &&
1281 "expected a valid source location");
1283 diag::warn_excess_precision_not_supported)
1284 << static_cast<bool>(Num);
1285 }
1286}
1287
1289 if (PragmaAttributeStack.empty())
1290 return;
1291 Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
1292}
1293
1295 if(On)
1297 else
1298 OptimizeOffPragmaLocation = PragmaLoc;
1299}
1300
1302 if (!CurContext->getRedeclContext()->isFileContext()) {
1303 Diag(Loc, diag::err_pragma_expected_file_scope) << "optimize";
1304 return;
1305 }
1306
1307 MSPragmaOptimizeIsOn = IsOn;
1308}
1309
1311 SourceLocation Loc, const llvm::SmallVectorImpl<StringRef> &NoBuiltins) {
1312 if (!CurContext->getRedeclContext()->isFileContext()) {
1313 Diag(Loc, diag::err_pragma_expected_file_scope) << "function";
1314 return;
1315 }
1316
1317 MSFunctionNoBuiltins.insert_range(NoBuiltins);
1318}
1319
1321 // In the future, check other pragmas if they're implemented (e.g. pragma
1322 // optimize 0 will probably map to this functionality too).
1323 if(OptimizeOffPragmaLocation.isValid())
1325}
1326
1328 if (!FD->getIdentifier())
1329 return;
1330
1331 StringRef Name = FD->getName();
1332 auto It = FunctionToSectionMap.find(Name);
1333 if (It != FunctionToSectionMap.end()) {
1334 StringRef Section;
1335 SourceLocation Loc;
1336 std::tie(Section, Loc) = It->second;
1337
1338 if (!FD->hasAttr<SectionAttr>())
1339 FD->addAttr(SectionAttr::CreateImplicit(Context, Section));
1340 }
1341}
1342
1344 // Don't modify the function attributes if it's "on". "on" resets the
1345 // optimizations to the ones listed on the command line
1348}
1349
1351 SourceLocation Loc) {
1352 // Don't add a conflicting attribute. No diagnostic is needed.
1353 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
1354 return;
1355
1356 // Add attributes only if required. Optnone requires noinline as well, but if
1357 // either is already present then don't bother adding them.
1358 if (!FD->hasAttr<OptimizeNoneAttr>())
1359 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
1360 if (!FD->hasAttr<NoInlineAttr>())
1361 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
1362}
1363
1365 if (FD->isDeleted() || FD->isDefaulted())
1366 return;
1368 MSFunctionNoBuiltins.end());
1369 if (!MSFunctionNoBuiltins.empty())
1370 FD->addAttr(NoBuiltinAttr::CreateImplicit(Context, V.data(), V.size()));
1371}
1372
1374 SourceLocation NameLoc,
1375 Scope *curScope) {
1376 LookupResult Result(*this, IdentId, NameLoc, LookupOrdinaryName);
1377 LookupName(Result, curScope);
1378 if (!getLangOpts().CPlusPlus)
1379 return Result.getAsSingle<NamedDecl>();
1380 for (NamedDecl *D : Result) {
1381 if (auto *FD = dyn_cast<FunctionDecl>(D))
1382 if (FD->isExternC())
1383 return D;
1384 if (isa<VarDecl>(D))
1385 return D;
1386 }
1387 return nullptr;
1388}
1389
1391 Scope *curScope) {
1392 if (!CurContext->getRedeclContext()->isFileContext()) {
1393 Diag(NameLoc, diag::err_pragma_expected_file_scope) << "export";
1394 return;
1395 }
1396
1397 PendingPragmaInfo Info;
1398 Info.NameLoc = NameLoc;
1399 Info.Used = false;
1400
1401 NamedDecl *PrevDecl =
1402 lookupExternCFunctionOrVariable(IdentId, NameLoc, curScope);
1403 if (!PrevDecl) {
1404 PendingExportedNames[IdentId] = Info;
1405 return;
1406 }
1407
1408 if (auto *FD = dyn_cast<FunctionDecl>(PrevDecl->getCanonicalDecl())) {
1409 if (!FD->hasExternalFormalLinkage()) {
1410 Diag(NameLoc, diag::warn_pragma_not_applied) << "export" << PrevDecl;
1411 return;
1412 }
1413 if (FD->hasBody()) {
1414 Diag(NameLoc, diag::warn_pragma_not_applied_to_defined_symbol)
1415 << "export";
1416 return;
1417 }
1418 } else if (auto *VD = dyn_cast<VarDecl>(PrevDecl->getCanonicalDecl())) {
1419 if (!VD->hasExternalFormalLinkage()) {
1420 Diag(NameLoc, diag::warn_pragma_not_applied) << "export" << PrevDecl;
1421 return;
1422 }
1423 if (VD->hasDefinition() == VarDecl::Definition) {
1424 Diag(NameLoc, diag::warn_pragma_not_applied_to_defined_symbol)
1425 << "export";
1426 return;
1427 }
1428 }
1429 mergeVisibilityType(PrevDecl->getCanonicalDecl(), NameLoc,
1430 VisibilityAttr::Default);
1431}
1432
1433typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
1434enum : unsigned { NoVisibility = ~0U };
1435
1437 if (!VisContext)
1438 return;
1439
1440 NamedDecl *ND = dyn_cast<NamedDecl>(D);
1442 return;
1443
1444 VisStack *Stack = static_cast<VisStack*>(VisContext);
1445 unsigned rawType = Stack->back().first;
1446 if (rawType == NoVisibility) return;
1447
1448 VisibilityAttr::VisibilityType type
1449 = (VisibilityAttr::VisibilityType) rawType;
1450 SourceLocation loc = Stack->back().second;
1451
1452 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
1453}
1454
1456 delete static_cast<VisStack*>(VisContext);
1457 VisContext = nullptr;
1458}
1459
1460static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
1461 // Put visibility on stack.
1462 if (!S.VisContext)
1463 S.VisContext = new VisStack;
1464
1465 VisStack *Stack = static_cast<VisStack*>(S.VisContext);
1466 Stack->push_back(std::make_pair(type, loc));
1467}
1468
1470 SourceLocation PragmaLoc) {
1471 if (VisType) {
1472 // Compute visibility to use.
1473 VisibilityAttr::VisibilityType T;
1474 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
1475 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
1476 return;
1477 }
1478 PushPragmaVisibility(*this, T, PragmaLoc);
1479 } else {
1480 PopPragmaVisibility(false, PragmaLoc);
1481 }
1482}
1483
1486 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1487 switch (FPC) {
1489 NewFPFeatures.setAllowFPContractWithinStatement();
1490 break;
1493 NewFPFeatures.setAllowFPContractAcrossStatement();
1494 break;
1496 NewFPFeatures.setDisallowFPContract();
1497 break;
1498 }
1499 FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), NewFPFeatures);
1500 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1501}
1502
1504 PragmaFPKind Kind, bool IsEnabled) {
1505 if (IsEnabled) {
1506 // For value unsafe context, combining this pragma with eval method
1507 // setting is not recommended. See comment in function FixupInvocation#506.
1508 int Reason = -1;
1509 if (getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine)
1510 // Eval method set using the option 'ffp-eval-method'.
1511 Reason = 1;
1512 if (PP.getLastFPEvalPragmaLocation().isValid())
1513 // Eval method set using the '#pragma clang fp eval_method'.
1514 // We could have both an option and a pragma used to the set the eval
1515 // method. The pragma overrides the option in the command line. The Reason
1516 // of the diagnostic is overriden too.
1517 Reason = 0;
1518 if (Reason != -1)
1519 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context)
1520 << Reason << (Kind == PFK_Reassociate ? 4 : 5);
1521 }
1522
1523 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1524 switch (Kind) {
1525 case PFK_Reassociate:
1526 NewFPFeatures.setAllowFPReassociateOverride(IsEnabled);
1527 break;
1528 case PFK_Reciprocal:
1529 NewFPFeatures.setAllowReciprocalOverride(IsEnabled);
1530 break;
1531 default:
1532 llvm_unreachable("unhandled value changing pragma fp");
1533 }
1534
1535 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1536 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1537}
1538
1539void Sema::ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode FPR) {
1540 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1541 NewFPFeatures.setConstRoundingModeOverride(FPR);
1542 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1543 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1544}
1545
1548 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1549 NewFPFeatures.setSpecifiedExceptionModeOverride(FPE);
1550 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1551 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1552}
1553
1555 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1556 if (IsEnabled) {
1557 // Verify Microsoft restriction:
1558 // You can't enable fenv_access unless precise semantics are enabled.
1559 // Precise semantics can be enabled either by the float_control
1560 // pragma, or by using the /fp:precise or /fp:strict compiler options
1561 if (!isPreciseFPEnabled())
1562 Diag(Loc, diag::err_pragma_fenv_requires_precise);
1563 }
1564 NewFPFeatures.setAllowFEnvAccessOverride(IsEnabled);
1565 NewFPFeatures.setRoundingMathOverride(IsEnabled);
1566 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1567 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1568}
1569
1572 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1573 NewFPFeatures.setComplexRangeOverride(Range);
1574 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1575 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1576}
1577
1582
1583void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
1584 SourceLocation Loc) {
1585 // Visibility calculations will consider the namespace's visibility.
1586 // Here we just want to note that we're in a visibility context
1587 // which overrides any enclosing #pragma context, but doesn't itself
1588 // contribute visibility.
1590}
1591
1592void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
1593 if (!VisContext) {
1594 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1595 return;
1596 }
1597
1598 // Pop visibility from stack
1599 VisStack *Stack = static_cast<VisStack*>(VisContext);
1600
1601 const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
1602 bool StartsWithPragma = Back->first != NoVisibility;
1603 if (StartsWithPragma && IsNamespaceEnd) {
1604 Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
1605 Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
1606
1607 // For better error recovery, eat all pushes inside the namespace.
1608 do {
1609 Stack->pop_back();
1610 Back = &Stack->back();
1611 StartsWithPragma = Back->first != NoVisibility;
1612 } while (StartsWithPragma);
1613 } else if (!StartsWithPragma && !IsNamespaceEnd) {
1614 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1615 Diag(Back->second, diag::note_surrounding_namespace_starts_here);
1616 return;
1617 }
1618
1619 Stack->pop_back();
1620 // To simplify the implementation, never keep around an empty stack.
1621 if (Stack->empty())
1623}
1624
1625template <typename Ty>
1626static bool checkCommonAttributeFeatures(Sema &S, const Ty *Node,
1627 const ParsedAttr &A,
1628 bool SkipArgCountCheck) {
1629 // Several attributes carry different semantics than the parsing requires, so
1630 // those are opted out of the common argument checks.
1631 //
1632 // We also bail on unknown and ignored attributes because those are handled
1633 // as part of the target-specific handling logic.
1635 return false;
1636 // Check whether the attribute requires specific language extensions to be
1637 // enabled.
1638 if (!A.diagnoseLangOpts(S))
1639 return true;
1640 // Check whether the attribute appertains to the given subject.
1641 if (!A.diagnoseAppertainsTo(S, Node))
1642 return true;
1643 // Check whether the attribute is mutually exclusive with other attributes
1644 // that have already been applied to the declaration.
1645 if (!A.diagnoseMutualExclusion(S, Node))
1646 return true;
1647 // Check whether the attribute exists in the target architecture.
1648 if (S.CheckAttrTarget(A))
1649 return true;
1650
1651 if (A.hasCustomParsing())
1652 return false;
1653
1654 if (!SkipArgCountCheck) {
1655 if (A.getMinArgs() == A.getMaxArgs()) {
1656 // If there are no optional arguments, then checking for the argument
1657 // count is trivial.
1658 if (!A.checkExactlyNumArgs(S, A.getMinArgs()))
1659 return true;
1660 } else {
1661 // There are optional arguments, so checking is slightly more involved.
1662 if (A.getMinArgs() && !A.checkAtLeastNumArgs(S, A.getMinArgs()))
1663 return true;
1664 else if (!A.hasVariadicArg() && A.getMaxArgs() &&
1665 !A.checkAtMostNumArgs(S, A.getMaxArgs()))
1666 return true;
1667 }
1668 }
1669
1670 return false;
1671}
1672
1674 bool SkipArgCountCheck) {
1675 return ::checkCommonAttributeFeatures(*this, D, A, SkipArgCountCheck);
1676}
1678 bool SkipArgCountCheck) {
1679 return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck);
1680}
#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
static const CXXNewExpr * findCXXNewExpr(const Stmt *S)
Definition SemaAttr.cpp:227
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:226
PtrTy get() const
Definition Ownership.h:171
Attr - This represents one attribute.
Definition Attr.h:46
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
Represents a C++ constructor within a class.
Definition DeclCXX.h:2624
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
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:350
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Decl()=delete
bool isInStdNamespace() const
Definition DeclBase.cpp:450
T * getAttr() const
Definition DeclBase.h:581
void addAttr(Attr *A)
SourceLocation getLocation() const
Definition DeclBase.h:447
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
Definition DeclBase.cpp:576
DeclContext * getDeclContext()
Definition DeclBase.h:456
bool hasAttr() const
Definition DeclBase.h:585
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:991
The name of a declaration.
bool isIdentifier() const
Predicate functions for querying what type of name this is.
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Decl.h:831
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 setFPPreciseEnabled(bool Value)
FPOptions applyOverrides(FPOptions Base)
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
Definition Diagnostic.h:130
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:104
Represents a function declaration or definition.
Definition Decl.h:2015
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2812
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3281
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3764
QualType getReturnType() const
Definition Decl.h:2860
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2555
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2400
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3828
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:2073
An lvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3667
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:1409
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:274
@ VisibilityForValue
Do an LV computation for, ultimately, a non-type declaration.
Definition Decl.h:461
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:295
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:301
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:340
std::optional< Visibility > getExplicitVisibility(ExplicitVisibilityKind kind) const
If visibility was explicitly specified for this declaration, return that visibility.
Definition Decl.cpp:1314
Represents a parameter to a function.
Definition Decl.h:1805
ParsedAttr - Represents a syntactic attribute.
Definition ParsedAttr.h:119
bool hasCustomParsing() 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
AttributeCommonInfo::Kind getKind() const
Definition ParsedAttr.h:610
bool diagnoseLangOpts(class Sema &S) const
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:5504
static PragmaDetectMismatchDecl * Create(const ASTContext &C, TranslationUnitDecl *DC, SourceLocation Loc, StringRef Name, StringRef Value)
Definition Decl.cpp:5527
A (possibly-)qualified type.
Definition TypeBase.h:937
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8431
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:8616
QualType getCanonicalType() const
Definition TypeBase.h:8483
Represents a struct/union/class.
Definition Decl.h:4342
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
Definition SemaBase.cpp:33
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
Definition SemaBase.cpp:61
unsigned getPackNumber() const
Definition Sema.h:1923
bool IsPackSet() const
Definition Sema.h:1925
bool IsAlignAttr() const
Definition Sema.h:1919
Mode getAlignMode() const
Definition Sema.h:1921
PragmaStackSentinelRAII(Sema &S, StringRef SlotLabel, bool ShouldAct)
Definition SemaAttr.cpp:29
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:868
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:546
void ActOnPragmaExport(IdentifierInfo *IdentId, SourceLocation ExportNameLoc, Scope *curScope)
ActonPragmaExport - called on well-formed '#pragma export'.
void ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc, const IdentifierInfo *Namespace)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
Definition Sema.h:9415
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:671
const Decl * PragmaAttributeCurrentTargetDecl
The declaration that is currently receiving an attribute from the pragma attribute stack.
Definition Sema.h:2141
llvm::function_ref< void(SourceLocation, PartialDiagnostic)> InstantiationContextDiagFuncRef
Definition Sema.h:2316
void ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode)
Called to set constant rounding mode for floating point operations.
PragmaClangSection PragmaClangRodataSection
Definition Sema.h:1845
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:8415
void inferLifetimeCaptureByAttribute(FunctionDecl *FD)
Add [[clang:lifetime_capture_by(this)]] to STL container methods.
Definition SemaAttr.cpp:318
PragmaStack< FPOptionsOverride > FpPragmaStack
Definition Sema.h:2076
PragmaStack< StringLiteral * > CodeSegStack
Definition Sema.h:2070
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:663
SmallVector< AlignPackIncludeState, 8 > AlignPackIncludeStack
Definition Sema.h:2065
void AddAlignmentAttributesForRecord(RecordDecl *RD)
AddAlignmentAttributesForRecord - Adds any needed alignment attributes to a the record decl,...
Definition SemaAttr.cpp:54
FPOptionsOverride CurFPFeatureOverrides()
Definition Sema.h:2077
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:890
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:706
void ActOnPragmaMSPointersToMembers(LangOptions::PragmaMSPointersToMembersKind Kind, SourceLocation PragmaLoc)
ActOnPragmaMSPointersToMembers - called on well formed #pragma pointers_to_members(representation met...
Definition SemaAttr.cpp:760
void DiagnosePrecisionLossInComplexDivision()
ASTContext & Context
Definition Sema.h:1308
void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, SourceLocation PragmaLoc)
ActOnPragmaUnused - Called on well-formed '#pragma unused'.
Definition SemaAttr.cpp:978
llvm::DenseMap< IdentifierInfo *, PendingPragmaInfo > PendingExportedNames
Definition Sema.h:2358
void ActOnPragmaMSAllocText(SourceLocation PragmaLocation, StringRef Section, const SmallVector< std::tuple< IdentifierInfo *, SourceLocation > > &Functions)
Called on well-formed #pragma alloc_text().
Definition SemaAttr.cpp:942
PragmaStack< bool > StrictGuardStackCheckStack
Definition Sema.h:2073
void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute, SourceLocation PragmaLoc, attr::ParsedSubjectMatchRuleSet Rules)
PragmaStack< StringLiteral * > ConstSegStack
Definition Sema.h:2069
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:762
void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, SourceLocation PragmaLoc)
ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
Definition SemaAttr.cpp:377
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 mergeVisibilityType(Decl *D, SourceLocation Loc, VisibilityAttr::VisibilityType Type)
void ActOnPragmaFPEvalMethod(SourceLocation Loc, LangOptions::FPEvalMethodKind Value)
Definition SemaAttr.cpp:679
void ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionAction Action, PragmaClangSectionKind SecKind, StringRef SecName)
ActOnPragmaClangSection - Called on well formed #pragma clang section.
Definition SemaAttr.cpp:432
bool UnifySection(StringRef SectionName, int SectionFlags, NamedDecl *TheDecl)
Definition SemaAttr.cpp:838
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:170
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr)
Definition Sema.cpp:273
const LangOptions & getLangOpts() const
Definition Sema.h:932
SourceLocation CurInitSegLoc
Definition Sema.h:2112
void ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, SourceLocation PragmaLoc, MSVtorDispMode Value)
Called on well formed #pragma vtordisp().
Definition SemaAttr.cpp:767
void inferLifetimeBoundAttribute(FunctionDecl *FD)
Add [[clang:lifetimebound]] attr for std:: functions and methods.
Definition SemaAttr.cpp:238
Preprocessor & PP
Definition Sema.h:1307
bool MSPragmaOptimizeIsOn
The "on" or "off" argument passed by #pragma optimize, that denotes whether the optimizations in the ...
Definition Sema.h:2159
SmallVector< PragmaAttributeGroup, 2 > PragmaAttributeStack
Definition Sema.h:2137
const LangOptions & LangOpts
Definition Sema.h:1306
PragmaClangSection PragmaClangRelroSection
Definition Sema.h:1846
SourceLocation ImplicitMSInheritanceAttrLoc
Source location for newly created implicit MSInheritanceAttrs.
Definition Sema.h:1835
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:2058
PragmaStack< StringLiteral * > BSSSegStack
Definition Sema.h:2068
llvm::StringMap< std::tuple< StringRef, SourceLocation > > FunctionToSectionMap
Sections used with pragma alloc_text.
Definition Sema.h:2115
llvm::SmallSetVector< StringRef, 4 > MSFunctionNoBuiltins
Set of no-builtin functions listed by #pragma function.
Definition Sema.h:2162
NamedDecl * lookupExternCFunctionOrVariable(IdentifierInfo *IdentId, SourceLocation NameLoc, Scope *curScope)
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:2111
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1446
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:659
bool isPreciseFPEnabled()
Are precise floating point semantics currently enabled?
Definition Sema.h:2242
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, StringLiteral *SegmentName)
Called on well-formed #pragma init_seg().
Definition SemaAttr.cpp:933
bool MSStructPragmaOn
Definition Sema.h:1832
SourceManager & getSourceManager() const
Definition Sema.h:937
void PrintPragmaAttributeInstantiationPoint()
Definition Sema.h:2330
void DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind, SourceLocation IncludeLoc)
Definition SemaAttr.cpp:593
PragmaClangSection PragmaClangTextSection
Definition Sema.h:1847
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:8414
PragmaClangSection PragmaClangDataSection
Definition Sema.h:1844
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:2057
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:2118
bool CheckAttrTarget(const ParsedAttr &CurrAttr)
ASTConsumer & Consumer
Definition Sema.h:1309
PragmaAlignPackDiagnoseKind
Definition Sema.h:2220
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition Sema.h:1267
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:1311
void ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, StringRef SlotLabel, Expr *Alignment)
ActOnPragmaPack - Called on well formed #pragma pack(...).
Definition SemaAttr.cpp:481
void DiagnoseUnterminatedPragmaAlignPack()
Definition SemaAttr.cpp:632
FPOptions CurFPFeatures
Definition Sema.h:1304
PragmaStack< StringLiteral * > DataSegStack
Definition Sema.h:2067
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:2146
LangOptions::PragmaMSPointersToMembersKind MSPointerToMemberRepresentationMethod
Controls member pointer representation format under the MS ABI.
Definition Sema.h:1830
void ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation, PragmaMsStackAction Action, bool Value)
ActOnPragmaMSStrictGuardStackCheck - Called on well formed #pragma strict_gs_check.
Definition SemaAttr.cpp:917
PragmaClangSection PragmaClangBSSSection
Definition Sema.h:1843
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:928
void inferNullableClassAttribute(CXXRecordDecl *CRD)
Add _Nullable attributes for std:: types.
Definition SemaAttr.cpp:365
PragmaMsStackAction
Definition Sema.h:1849
@ PSK_Push_Set
Definition Sema.h:1855
@ PSK_Reset
Definition Sema.h:1850
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:86
child_range children()
Definition Stmt.cpp:304
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Stmt.cpp:355
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1802
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:1976
StringRef getString() const
Definition Expr.h:1870
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:197
SourceLocation getLocation() const
Return a source location identifier for the specified offset in the current file.
Definition Token.h:142
The base class of the type hierarchy.
Definition TypeBase.h:1866
bool isVoidType() const
Definition TypeBase.h:9034
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:8767
bool isFunctionType() const
Definition TypeBase.h:8664
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3577
QualType getUnderlyingType() const
Definition Decl.h:3632
Represents a variable declaration or definition.
Definition Decl.h:926
@ Definition
This declaration is definitely a definition.
Definition Decl.h:1316
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 isGslPointerType(QualType QT)
The JSON file list parser is used to communicate input to InstallAPI.
PragmaClangSectionAction
Definition Sema.h:476
@ 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:353
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ AANT_ArgumentConstantExpr
PragmaOptionsAlignKind
Definition Sema.h:478
@ Result
The result type of a method or function.
Definition TypeBase.h:905
MSVtorDispMode
In the Microsoft ABI, this controls the placement of virtual displacement members used to implement v...
Definition LangOptions.h:38
PragmaClangSectionKind
pragma clang section kind
Definition Sema.h:467
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:136
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:648
APValue Val
Val - This is the value the expression can be folded to.
Definition Expr.h:650
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:636
SourceLocation CurrentPragmaLocation
Definition Sema.h:2062
Information from a C++ pragma export, for a symbol that we haven't seen the declaration for yet.
Definition Sema.h:2353
This an attribute introduced by #pragma clang attribute.
Definition Sema.h:2121
SourceLocation PragmaLocation
Definition Sema.h:1840
SmallVector< Slot, 2 > Stack
Definition Sema.h:2041
void Act(SourceLocation PragmaLocation, PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, ValueType Value)
Definition Sema.h:1980