clang 24.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 if (PragmaLocation.isValid())
858 Diag(PragmaLocation, diag::note_pragma_entered_here);
859 if (Section.PragmaSectionLocation.isValid())
860 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
861 return true;
862}
863
864bool Sema::UnifySection(StringRef SectionName,
865 int SectionFlags,
866 SourceLocation PragmaSectionLocation) {
867 auto SectionIt = Context.SectionInfos.find(SectionName);
868 if (SectionIt != Context.SectionInfos.end()) {
869 const auto &Section = SectionIt->second;
870 if (Section.SectionFlags == SectionFlags)
871 return false;
872 if (!(Section.SectionFlags & ASTContext::PSF_Implicit)) {
873 Diag(PragmaSectionLocation, diag::err_section_conflict)
874 << "this" << Section;
875 if (Section.Decl)
876 Diag(Section.Decl->getLocation(), diag::note_declared_at);
877 if (Section.PragmaSectionLocation.isValid())
878 Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
879 return true;
880 }
881 }
882 Context.SectionInfos[SectionName] =
883 ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
884 return false;
885}
886
887/// Called on well formed \#pragma bss_seg().
889 PragmaMsStackAction Action,
890 llvm::StringRef StackSlotLabel,
891 StringLiteral *SegmentName,
892 llvm::StringRef PragmaName) {
894 llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
895 .Case("data_seg", &DataSegStack)
896 .Case("bss_seg", &BSSSegStack)
897 .Case("const_seg", &ConstSegStack)
898 .Case("code_seg", &CodeSegStack);
899 if (Action & PSK_Pop && Stack->Stack.empty())
900 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
901 << "stack empty";
902 if (SegmentName) {
903 if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
904 return;
905
906 if (SegmentName->getString() == ".drectve" &&
907 Context.getTargetInfo().getCXXABI().isMicrosoft())
908 Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName;
909 }
910
911 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
912}
913
914/// Called on well formed \#pragma strict_gs_check().
916 PragmaMsStackAction Action,
917 bool Value) {
918 if (Action & PSK_Pop && StrictGuardStackCheckStack.Stack.empty())
919 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "strict_gs_check"
920 << "stack empty";
921
922 StrictGuardStackCheckStack.Act(PragmaLocation, Action, StringRef(), Value);
923}
924
925/// Called on well formed \#pragma bss_seg().
927 int SectionFlags, StringLiteral *SegmentName) {
928 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
929}
930
932 StringLiteral *SegmentName,
934 // There's no stack to maintain, so we just have a current section. When we
935 // see the default section, reset our current section back to null so we stop
936 // tacking on unnecessary attributes.
937 CurInitSeg.Segment =
938 SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
939 CurInitSeg.PragmaLocation = PragmaLocation;
940 CurInitSeg.Func = nullptr;
941
942 if (Func) {
943 DeclarationNameInfo NameInfo(Func->getIdentifierInfo(), Func->getLoc());
944 LookupResult R(*this, NameInfo, LookupOrdinaryName);
946
947 FunctionDecl *FD = R.getAsSingle<FunctionDecl>();
948 if (!FD) {
949 Diag(Func->getLoc(), diag::err_undeclared_var_use)
950 << Func->getIdentifierInfo();
951 return;
952 }
953
954 // the required type is: int __cdecl myexit (void (__cdecl *pf)(void))
955 QualType FnTy = FD->getType();
956 const auto *Proto = FnTy->getAs<FunctionProtoType>();
957 bool Valid = Proto && Proto->getReturnType()->isIntegerType() &&
958 Proto->getNumParams() == 1 &&
959 Proto->getParamType(0)->isFunctionPointerType();
960 if (!Valid) {
961 Diag(Func->getLoc(), diag::err_pragma_init_seg_bad_func_type)
962 << FD->getDeclName();
963 return;
964 }
965
966 CurInitSeg.Func = FD;
967 }
968}
969
971 SourceLocation PragmaLocation, StringRef Section,
972 const SmallVector<std::tuple<IdentifierInfo *, SourceLocation>>
973 &Functions) {
974 if (!CurContext->getRedeclContext()->isFileContext()) {
975 Diag(PragmaLocation, diag::err_pragma_expected_file_scope) << "alloc_text";
976 return;
977 }
978
979 for (auto &Function : Functions) {
980 IdentifierInfo *II;
981 SourceLocation Loc;
982 std::tie(II, Loc) = Function;
983
984 DeclarationName DN(II);
986 if (!ND) {
987 Diag(Loc, diag::err_undeclared_use) << II->getName();
988 return;
989 }
990
991 auto *FD = dyn_cast<FunctionDecl>(ND->getCanonicalDecl());
992 if (!FD) {
993 Diag(Loc, diag::err_pragma_alloc_text_not_function);
994 return;
995 }
996
997 if (getLangOpts().CPlusPlus && !FD->isInExternCContext()) {
998 Diag(Loc, diag::err_pragma_alloc_text_c_linkage);
999 return;
1000 }
1001
1002 FunctionToSectionMap[II->getName()] = std::make_tuple(Section, Loc);
1003 }
1004}
1005
1006void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
1007 SourceLocation PragmaLoc) {
1008
1009 IdentifierInfo *Name = IdTok.getIdentifierInfo();
1010 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
1011 LookupName(Lookup, curScope, /*AllowBuiltinCreation=*/true);
1012
1013 if (Lookup.empty()) {
1014 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
1015 << Name << SourceRange(IdTok.getLocation());
1016 return;
1017 }
1018
1019 VarDecl *VD = Lookup.getAsSingle<VarDecl>();
1020 if (!VD) {
1021 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
1022 << Name << SourceRange(IdTok.getLocation());
1023 return;
1024 }
1025
1026 // Warn if this was used before being marked unused.
1027 if (VD->isUsed())
1028 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
1029
1030 VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(),
1031 UnusedAttr::GNU_unused));
1032}
1033
1034namespace {
1035
1036std::optional<attr::SubjectMatchRule>
1037getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
1038 using namespace attr;
1039 switch (Rule) {
1040 default:
1041 return std::nullopt;
1042#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
1043#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
1044 case Value: \
1045 return Parent;
1046#include "clang/Basic/AttrSubMatchRulesList.inc"
1047 }
1048}
1049
1050bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
1051 using namespace attr;
1052 switch (Rule) {
1053 default:
1054 return false;
1055#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
1056#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
1057 case Value: \
1058 return IsNegated;
1059#include "clang/Basic/AttrSubMatchRulesList.inc"
1060 }
1061}
1062
1063CharSourceRange replacementRangeForListElement(const Sema &S,
1064 SourceRange Range) {
1065 // Make sure that the ',' is removed as well.
1066 SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
1067 Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
1068 /*SkipTrailingWhitespaceAndNewLine=*/false);
1069 if (AfterCommaLoc.isValid())
1070 return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
1071 else
1072 return CharSourceRange::getTokenRange(Range);
1073}
1074
1075std::string
1076attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
1077 std::string Result;
1078 llvm::raw_string_ostream OS(Result);
1079 for (const auto &I : llvm::enumerate(Rules)) {
1080 if (I.index())
1081 OS << (I.index() == Rules.size() - 1 ? ", and " : ", ");
1082 OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
1083 }
1084 return Result;
1085}
1086
1087} // end anonymous namespace
1088
1090 ParsedAttr &Attribute, SourceLocation PragmaLoc,
1092 Attribute.setIsPragmaClangAttribute();
1094 // Gather the subject match rules that are supported by the attribute.
1096 StrictSubjectMatchRuleSet;
1097 Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
1098
1099 // Figure out which subject matching rules are valid.
1100 if (StrictSubjectMatchRuleSet.empty()) {
1101 // Check for contradicting match rules. Contradicting match rules are
1102 // either:
1103 // - a top-level rule and one of its sub-rules. E.g. variable and
1104 // variable(is_parameter).
1105 // - a sub-rule and a sibling that's negated. E.g.
1106 // variable(is_thread_local) and variable(unless(is_parameter))
1107 llvm::SmallDenseMap<int, attr::ParsedSubjectMatchRuleSet::value_type, 2>
1108 RulesToFirstSpecifiedNegatedSubRule;
1109 for (const auto &Rule : Rules) {
1110 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1111 std::optional<attr::SubjectMatchRule> ParentRule =
1112 getParentAttrMatcherRule(MatchRule);
1113 if (!ParentRule)
1114 continue;
1115 auto It = Rules.find(*ParentRule);
1116 if (It != Rules.end()) {
1117 // A sub-rule contradicts a parent rule.
1118 Diag(Rule.second.getBegin(),
1119 diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
1121 << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
1123 replacementRangeForListElement(*this, Rule.second));
1124 // Keep going without removing this rule as it won't change the set of
1125 // declarations that receive the attribute.
1126 continue;
1127 }
1128 if (isNegatedAttrMatcherSubRule(MatchRule))
1129 RulesToFirstSpecifiedNegatedSubRule.insert(
1130 std::make_pair(*ParentRule, Rule));
1131 }
1132 bool IgnoreNegatedSubRules = false;
1133 for (const auto &Rule : Rules) {
1134 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1135 std::optional<attr::SubjectMatchRule> ParentRule =
1136 getParentAttrMatcherRule(MatchRule);
1137 if (!ParentRule)
1138 continue;
1139 auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
1140 if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
1141 It->second != Rule) {
1142 // Negated sub-rule contradicts another sub-rule.
1143 Diag(
1144 It->second.second.getBegin(),
1145 diag::
1146 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
1148 attr::SubjectMatchRule(It->second.first))
1149 << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
1151 replacementRangeForListElement(*this, It->second.second));
1152 // Keep going but ignore all of the negated sub-rules.
1153 IgnoreNegatedSubRules = true;
1154 RulesToFirstSpecifiedNegatedSubRule.erase(It);
1155 }
1156 }
1157
1158 if (!IgnoreNegatedSubRules) {
1159 for (const auto &Rule : Rules)
1160 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
1161 } else {
1162 for (const auto &Rule : Rules) {
1163 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
1164 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
1165 }
1166 }
1167 Rules.clear();
1168 } else {
1169 // Each rule in Rules must be a strict subset of the attribute's
1170 // SubjectMatch rules. I.e. we're allowed to use
1171 // `apply_to=variables(is_global)` on an attrubute with SubjectList<[Var]>,
1172 // but should not allow `apply_to=variables` on an attribute which has
1173 // `SubjectList<[GlobalVar]>`.
1174 for (const auto &StrictRule : StrictSubjectMatchRuleSet) {
1175 // First, check for exact match.
1176 if (Rules.erase(StrictRule.first)) {
1177 // Add the rule to the set of attribute receivers only if it's supported
1178 // in the current language mode.
1179 if (StrictRule.second)
1180 SubjectMatchRules.push_back(StrictRule.first);
1181 }
1182 }
1183 // Check remaining rules for subset matches.
1184 auto RulesToCheck = Rules;
1185 for (const auto &Rule : RulesToCheck) {
1186 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1187 if (auto ParentRule = getParentAttrMatcherRule(MatchRule)) {
1188 if (llvm::any_of(StrictSubjectMatchRuleSet,
1189 [ParentRule](const auto &StrictRule) {
1190 return StrictRule.first == *ParentRule &&
1191 StrictRule.second; // IsEnabled
1192 })) {
1193 SubjectMatchRules.push_back(MatchRule);
1194 Rules.erase(MatchRule);
1195 }
1196 }
1197 }
1198 }
1199
1200 if (!Rules.empty()) {
1201 auto Diagnostic =
1202 Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
1203 << Attribute;
1205 for (const auto &Rule : Rules) {
1206 ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
1208 replacementRangeForListElement(*this, Rule.second));
1209 }
1210 Diagnostic << attrMatcherRuleListToString(ExtraRules);
1211 }
1212
1213 if (PragmaAttributeStack.empty()) {
1214 Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push);
1215 return;
1216 }
1217
1218 PragmaAttributeStack.back().Entries.push_back(
1219 {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
1220}
1221
1223 const IdentifierInfo *Namespace) {
1224 PragmaAttributeStack.emplace_back();
1225 PragmaAttributeStack.back().Loc = PragmaLoc;
1226 PragmaAttributeStack.back().Namespace = Namespace;
1227}
1228
1230 const IdentifierInfo *Namespace) {
1231 if (PragmaAttributeStack.empty()) {
1232 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1233 return;
1234 }
1235
1236 // Dig back through the stack trying to find the most recently pushed group
1237 // that in Namespace. Note that this works fine if no namespace is present,
1238 // think of push/pops without namespaces as having an implicit "nullptr"
1239 // namespace.
1240 for (size_t Index = PragmaAttributeStack.size(); Index;) {
1241 --Index;
1242 if (PragmaAttributeStack[Index].Namespace == Namespace) {
1243 for (const PragmaAttributeEntry &Entry :
1244 PragmaAttributeStack[Index].Entries) {
1245 if (!Entry.IsUsed) {
1246 assert(Entry.Attribute && "Expected an attribute");
1247 Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
1248 << *Entry.Attribute;
1249 Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
1250 }
1251 }
1252 PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index);
1253 return;
1254 }
1255 }
1256
1257 if (Namespace)
1258 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch)
1259 << 0 << Namespace->getName();
1260 else
1261 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1262}
1263
1265 if (PragmaAttributeStack.empty())
1266 return;
1267
1268 if (const auto *P = dyn_cast<ParmVarDecl>(D))
1269 if (P->getType()->isVoidType())
1270 return;
1271
1272 for (auto &Group : PragmaAttributeStack) {
1273 for (auto &Entry : Group.Entries) {
1274 ParsedAttr *Attribute = Entry.Attribute;
1275 assert(Attribute && "Expected an attribute");
1276 assert(Attribute->isPragmaClangAttribute() &&
1277 "expected #pragma clang attribute");
1278
1279 // Ensure that the attribute can be applied to the given declaration.
1280 bool Applies = false;
1281 for (const auto &Rule : Entry.MatchRules) {
1282 if (Attribute->appliesToDecl(D, Rule)) {
1283 Applies = true;
1284 break;
1285 }
1286 }
1287 if (!Applies)
1288 continue;
1289 Entry.IsUsed = true;
1292 Attrs.addAtEnd(Attribute);
1293 ProcessDeclAttributeList(S, D, Attrs);
1295 }
1296 }
1297}
1298
1301 assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
1302 DiagFunc(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
1303 PDiag(diag::note_pragma_attribute_applied_decl_here));
1304}
1305
1307 for (auto &[Type, Num] : ExcessPrecisionNotSatisfied) {
1308 assert(LocationOfExcessPrecisionNotSatisfied.isValid() &&
1309 "expected a valid source location");
1311 diag::warn_excess_precision_not_supported)
1312 << static_cast<bool>(Num);
1313 }
1314}
1315
1317 if (PragmaAttributeStack.empty())
1318 return;
1319 Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
1320}
1321
1323 if(On)
1325 else
1326 OptimizeOffPragmaLocation = PragmaLoc;
1327}
1328
1330 if (!CurContext->getRedeclContext()->isFileContext()) {
1331 Diag(Loc, diag::err_pragma_expected_file_scope) << "optimize";
1332 return;
1333 }
1334
1335 MSPragmaOptimizeIsOn = IsOn;
1336}
1337
1339 SourceLocation Loc, const llvm::SmallVectorImpl<StringRef> &NoBuiltins) {
1340 if (!CurContext->getRedeclContext()->isFileContext()) {
1341 Diag(Loc, diag::err_pragma_expected_file_scope) << "function";
1342 return;
1343 }
1344
1345 MSFunctionNoBuiltins.insert_range(NoBuiltins);
1346}
1347
1349 // In the future, check other pragmas if they're implemented (e.g. pragma
1350 // optimize 0 will probably map to this functionality too).
1351 if(OptimizeOffPragmaLocation.isValid())
1353}
1354
1356 if (!FD->getIdentifier())
1357 return;
1358
1359 StringRef Name = FD->getName();
1360 auto It = FunctionToSectionMap.find(Name);
1361 if (It != FunctionToSectionMap.end()) {
1362 StringRef Section;
1363 SourceLocation Loc;
1364 std::tie(Section, Loc) = It->second;
1365
1366 if (!FD->hasAttr<SectionAttr>())
1367 FD->addAttr(SectionAttr::CreateImplicit(Context, Section));
1368 }
1369}
1370
1372 // Don't modify the function attributes if it's "on". "on" resets the
1373 // optimizations to the ones listed on the command line
1376}
1377
1379 SourceLocation Loc) {
1380 // Don't add a conflicting attribute. No diagnostic is needed.
1381 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
1382 return;
1383
1384 // Add attributes only if required. Optnone requires noinline as well, but if
1385 // either is already present then don't bother adding them.
1386 if (!FD->hasAttr<OptimizeNoneAttr>())
1387 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
1388 if (!FD->hasAttr<NoInlineAttr>())
1389 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
1390}
1391
1393 if (FD->isDeleted() || FD->isDefaulted())
1394 return;
1396 MSFunctionNoBuiltins.end());
1397 if (!MSFunctionNoBuiltins.empty())
1398 FD->addAttr(NoBuiltinAttr::CreateImplicit(Context, V.data(), V.size()));
1399}
1400
1402 SourceLocation NameLoc,
1403 Scope *curScope) {
1404 LookupResult Result(*this, IdentId, NameLoc, LookupOrdinaryName);
1405 LookupName(Result, curScope);
1406 if (!getLangOpts().CPlusPlus)
1407 return Result.getAsSingle<NamedDecl>();
1408 for (NamedDecl *D : Result) {
1409 if (auto *FD = dyn_cast<FunctionDecl>(D))
1410 if (FD->isExternC())
1411 return D;
1412 if (isa<VarDecl>(D))
1413 return D;
1414 }
1415 return nullptr;
1416}
1417
1419 Scope *curScope) {
1420 if (!CurContext->getRedeclContext()->isFileContext()) {
1421 Diag(NameLoc, diag::err_pragma_expected_file_scope) << "export";
1422 return;
1423 }
1424
1425 PendingPragmaInfo Info;
1426 Info.NameLoc = NameLoc;
1427 Info.Used = false;
1428
1429 NamedDecl *PrevDecl =
1430 lookupExternCFunctionOrVariable(IdentId, NameLoc, curScope);
1431 if (!PrevDecl) {
1432 PendingExportedNames[IdentId] = Info;
1433 return;
1434 }
1435
1436 if (auto *FD = dyn_cast<FunctionDecl>(PrevDecl->getCanonicalDecl())) {
1437 if (!FD->hasExternalFormalLinkage()) {
1438 Diag(NameLoc, diag::warn_pragma_not_applied) << "export" << PrevDecl;
1439 return;
1440 }
1441 if (FD->hasBody()) {
1442 Diag(NameLoc, diag::warn_pragma_not_applied_to_defined_symbol)
1443 << "export";
1444 return;
1445 }
1446 } else if (auto *VD = dyn_cast<VarDecl>(PrevDecl->getCanonicalDecl())) {
1447 if (!VD->hasExternalFormalLinkage()) {
1448 Diag(NameLoc, diag::warn_pragma_not_applied) << "export" << PrevDecl;
1449 return;
1450 }
1451 if (VD->hasDefinition() == VarDecl::Definition) {
1452 Diag(NameLoc, diag::warn_pragma_not_applied_to_defined_symbol)
1453 << "export";
1454 return;
1455 }
1456 }
1457 mergeVisibilityType(PrevDecl->getCanonicalDecl(), NameLoc,
1458 VisibilityAttr::Default);
1459}
1460
1461typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
1462enum : unsigned { NoVisibility = ~0U };
1463
1465 if (!VisContext)
1466 return;
1467
1468 NamedDecl *ND = dyn_cast<NamedDecl>(D);
1470 return;
1471
1472 VisStack *Stack = static_cast<VisStack*>(VisContext);
1473 unsigned rawType = Stack->back().first;
1474 if (rawType == NoVisibility) return;
1475
1476 VisibilityAttr::VisibilityType type
1477 = (VisibilityAttr::VisibilityType) rawType;
1478 SourceLocation loc = Stack->back().second;
1479
1480 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
1481}
1482
1484 delete static_cast<VisStack*>(VisContext);
1485 VisContext = nullptr;
1486}
1487
1488static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
1489 // Put visibility on stack.
1490 if (!S.VisContext)
1491 S.VisContext = new VisStack;
1492
1493 VisStack *Stack = static_cast<VisStack*>(S.VisContext);
1494 Stack->push_back(std::make_pair(type, loc));
1495}
1496
1498 SourceLocation PragmaLoc) {
1499 if (VisType) {
1500 // Compute visibility to use.
1501 VisibilityAttr::VisibilityType T;
1502 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
1503 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
1504 return;
1505 }
1506 PushPragmaVisibility(*this, T, PragmaLoc);
1507 } else {
1508 PopPragmaVisibility(false, PragmaLoc);
1509 }
1510}
1511
1514 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1515 switch (FPC) {
1517 NewFPFeatures.setAllowFPContractWithinStatement();
1518 break;
1521 NewFPFeatures.setAllowFPContractAcrossStatement();
1522 break;
1524 NewFPFeatures.setDisallowFPContract();
1525 break;
1526 }
1527 FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), NewFPFeatures);
1528 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1529}
1530
1532 PragmaFPKind Kind, bool IsEnabled) {
1533 if (IsEnabled) {
1534 // For value unsafe context, combining this pragma with eval method
1535 // setting is not recommended. See comment in function FixupInvocation#506.
1536 int Reason = -1;
1537 if (getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine)
1538 // Eval method set using the option 'ffp-eval-method'.
1539 Reason = 1;
1540 if (PP.getLastFPEvalPragmaLocation().isValid())
1541 // Eval method set using the '#pragma clang fp eval_method'.
1542 // We could have both an option and a pragma used to the set the eval
1543 // method. The pragma overrides the option in the command line. The Reason
1544 // of the diagnostic is overriden too.
1545 Reason = 0;
1546 if (Reason != -1)
1547 Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context)
1548 << Reason << (Kind == PFK_Reassociate ? 4 : 5);
1549 }
1550
1551 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1552 switch (Kind) {
1553 case PFK_Reassociate:
1554 NewFPFeatures.setAllowFPReassociateOverride(IsEnabled);
1555 break;
1556 case PFK_Reciprocal:
1557 NewFPFeatures.setAllowReciprocalOverride(IsEnabled);
1558 break;
1559 default:
1560 llvm_unreachable("unhandled value changing pragma fp");
1561 }
1562
1563 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1564 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1565}
1566
1567void Sema::ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode FPR) {
1568 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1569 NewFPFeatures.setConstRoundingModeOverride(FPR);
1570 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1571 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1572}
1573
1576 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1577 NewFPFeatures.setSpecifiedExceptionModeOverride(FPE);
1578 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1579 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1580}
1581
1583 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1584 if (IsEnabled) {
1585 // Verify Microsoft restriction:
1586 // You can't enable fenv_access unless precise semantics are enabled.
1587 // Precise semantics can be enabled either by the float_control
1588 // pragma, or by using the /fp:precise or /fp:strict compiler options
1589 if (!isPreciseFPEnabled())
1590 Diag(Loc, diag::err_pragma_fenv_requires_precise);
1591 }
1592 NewFPFeatures.setAllowFEnvAccessOverride(IsEnabled);
1593 NewFPFeatures.setRoundingMathOverride(IsEnabled);
1594 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1595 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1596}
1597
1600 FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1601 NewFPFeatures.setComplexRangeOverride(Range);
1602 FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1603 CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1604}
1605
1610
1611void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
1612 SourceLocation Loc) {
1613 // Visibility calculations will consider the namespace's visibility.
1614 // Here we just want to note that we're in a visibility context
1615 // which overrides any enclosing #pragma context, but doesn't itself
1616 // contribute visibility.
1618}
1619
1620void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
1621 if (!VisContext) {
1622 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1623 return;
1624 }
1625
1626 // Pop visibility from stack
1627 VisStack *Stack = static_cast<VisStack*>(VisContext);
1628
1629 const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
1630 bool StartsWithPragma = Back->first != NoVisibility;
1631 if (StartsWithPragma && IsNamespaceEnd) {
1632 Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
1633 Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
1634
1635 // For better error recovery, eat all pushes inside the namespace.
1636 do {
1637 Stack->pop_back();
1638 Back = &Stack->back();
1639 StartsWithPragma = Back->first != NoVisibility;
1640 } while (StartsWithPragma);
1641 } else if (!StartsWithPragma && !IsNamespaceEnd) {
1642 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1643 Diag(Back->second, diag::note_surrounding_namespace_starts_here);
1644 return;
1645 }
1646
1647 Stack->pop_back();
1648 // To simplify the implementation, never keep around an empty stack.
1649 if (Stack->empty())
1651}
1652
1653// 'Subject' is the entity the attribute appertains to: a Decl, a Stmt, or a
1654// QualType. Attr.td subject lists currently only accept declarations and
1655// statements, so the appertainment and mutual exclusion checks for a QualType
1656// are stubs that always succeed.
1657template <typename SubjectTy>
1658static bool checkCommonAttributeFeatures(Sema &S, SubjectTy Subject,
1659 const ParsedAttr &A,
1660 bool SkipArgCountCheck) {
1661 // Several attributes carry different semantics than the parsing requires, so
1662 // those are opted out of the common argument checks.
1663 //
1664 // We also bail on unknown and ignored attributes because those are handled
1665 // as part of the target-specific handling logic.
1667 return false;
1668 // Check whether the attribute requires specific language extensions to be
1669 // enabled.
1670 if (!A.diagnoseLangOpts(S))
1671 return true;
1672 // Check whether the attribute appertains to the given subject.
1673 if (!A.diagnoseAppertainsTo(S, Subject))
1674 return true;
1675 // Check whether the attribute is mutually exclusive with other attributes
1676 // that have already been applied to the declaration.
1677 if (!A.diagnoseMutualExclusion(S, Subject))
1678 return true;
1679 // Check whether the attribute exists in the target architecture.
1680 if (S.CheckAttrTarget(A))
1681 return true;
1682
1683 if (A.hasCustomParsing())
1684 return false;
1685
1686 if (!SkipArgCountCheck) {
1687 if (A.getMinArgs() == A.getMaxArgs()) {
1688 // If there are no optional arguments, then checking for the argument
1689 // count is trivial.
1690 if (!A.checkExactlyNumArgs(S, A.getMinArgs()))
1691 return true;
1692 } else {
1693 // There are optional arguments, so checking is slightly more involved.
1694 if (A.getMinArgs() && !A.checkAtLeastNumArgs(S, A.getMinArgs()))
1695 return true;
1696 else if (!A.hasVariadicArg() && A.getMaxArgs() &&
1697 !A.checkAtMostNumArgs(S, A.getMaxArgs()))
1698 return true;
1699 }
1700 }
1701
1702 return false;
1703}
1704
1706 bool SkipArgCountCheck) {
1707 return ::checkCommonAttributeFeatures(*this, D, A, SkipArgCountCheck);
1708}
1710 bool SkipArgCountCheck) {
1711 return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck);
1712}
1714 bool SkipArgCountCheck) {
1715 return ::checkCommonAttributeFeatures(*this, T, A, SkipArgCountCheck);
1716}
#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:245
PtrTy get() const
Definition Ownership.h:171
Attr - This represents one attribute.
Definition Attr.h:47
Represents a call to a C++ constructor.
Definition ExprCXX.h:1553
Represents a C++ constructor within a class.
Definition DeclCXX.h:2645
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2360
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:356
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Decl()=delete
bool isInStdNamespace() const
Definition DeclBase.cpp:453
T * getAttr() const
Definition DeclBase.h:582
void addAttr(Attr *A)
SourceLocation getLocation() const
Definition DeclBase.h:448
bool isUsed(bool CheckUsedAttr=true) const
Whether any (re-)declaration of the entity was used, meaning that a definition is required.
Definition DeclBase.cpp:579
DeclContext * getDeclContext()
Definition DeclBase.h:457
bool hasAttr() const
Definition DeclBase.h:586
virtual Decl * getCanonicalDecl()
Retrieves the "canonical" declaration of the given declaration.
Definition DeclBase.h:996
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:833
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
This represents one expression.
Definition Expr.h:114
bool isValueDependent() const
Determines whether the value of this expression depends on.
Definition Expr.h:179
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Definition Expr.h:196
bool isLValue() const
isLValue - True if this expression is an "l-value" according to the rules of the current language.
Definition Expr.h:286
bool EvaluateAsConstantExpr(EvalResult &Result, const ASTContext &Ctx, ConstantExprKind Kind=ConstantExprKind::Normal) const
Evaluate an expression that is required to be a constant expression.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
QualType getType() const
Definition Expr.h:146
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:129
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:103
Represents a function declaration or definition.
Definition Decl.h:2071
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2944
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3284
unsigned getBuiltinID(bool ConsiderWrapperFunctions=false) const
Returns a value indicating whether this function corresponds to a builtin function.
Definition Decl.cpp:3822
QualType getReturnType() const
Definition Decl.h:2992
bool isDeleted() const
Whether this function has been deleted.
Definition Decl.h:2679
bool isDefaulted() const
Whether this function is defaulted.
Definition Decl.h:2524
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3886
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5548
One of these records is kept for each identifier that is lexed.
StringRef getName() const
Return the actual identifier string.
A simple pair of identifier info and location.
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
Definition Expr.cpp:2109
An lvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3715
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:1437
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:276
@ VisibilityForValue
Do an LV computation for, ultimately, a non-type declaration.
Definition Decl.h:463
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:297
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:303
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:342
std::optional< Visibility > getExplicitVisibility(ExplicitVisibilityKind kind) const
If visibility was explicitly specified for this declaration, return that visibility.
Definition Decl.cpp:1316
Represents a parameter to a function.
Definition Decl.h:1832
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:631
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:848
static PragmaCommentDecl * Create(const ASTContext &C, TranslationUnitDecl *DC, SourceLocation CommentLoc, PragmaMSCommentKind CommentKind, StringRef Arg)
Definition Decl.cpp:5597
static PragmaDetectMismatchDecl * Create(const ASTContext &C, TranslationUnitDecl *DC, SourceLocation Loc, StringRef Name, StringRef Value)
Definition Decl.cpp:5620
A (possibly-)qualified type.
Definition TypeBase.h:938
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8578
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:8763
QualType getCanonicalType() const
Definition TypeBase.h:8630
Represents a struct/union/class.
Definition Decl.h:4476
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:1952
bool IsPackSet() const
Definition Sema.h:1954
bool IsAlignAttr() const
Definition Sema.h:1948
Mode getAlignMode() const
Definition Sema.h:1950
PragmaStackSentinelRAII(Sema &S, StringRef SlotLabel, bool ShouldAct)
Definition SemaAttr.cpp:29
Sema - This implements semantic analysis and AST building for C.
Definition Sema.h:862
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:9507
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:2174
llvm::function_ref< void(SourceLocation, PartialDiagnostic)> InstantiationContextDiagFuncRef
Definition Sema.h:2351
void ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode)
Called to set constant rounding mode for floating point operations.
PragmaClangSection PragmaClangRodataSection
Definition Sema.h:1874
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:8493
void inferLifetimeCaptureByAttribute(FunctionDecl *FD)
Add [[clang:lifetime_capture_by(this)]] to STL container methods.
Definition SemaAttr.cpp:318
PragmaStack< FPOptionsOverride > FpPragmaStack
Definition Sema.h:2105
PragmaStack< StringLiteral * > CodeSegStack
Definition Sema.h:2099
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:2094
void AddAlignmentAttributesForRecord(RecordDecl *RD)
AddAlignmentAttributesForRecord - Adds any needed alignment attributes to a the record decl,...
Definition SemaAttr.cpp:54
FPOptionsOverride CurFPFeatureOverrides()
Definition Sema.h:2106
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:888
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:1331
void ActOnPragmaUnused(const Token &Identifier, Scope *curScope, SourceLocation PragmaLoc)
ActOnPragmaUnused - Called on well-formed '#pragma unused'.
llvm::DenseMap< IdentifierInfo *, PendingPragmaInfo > PendingExportedNames
Definition Sema.h:2393
void ActOnPragmaMSAllocText(SourceLocation PragmaLocation, StringRef Section, const SmallVector< std::tuple< IdentifierInfo *, SourceLocation > > &Functions)
Called on well-formed #pragma alloc_text().
Definition SemaAttr.cpp:970
PragmaStack< bool > StrictGuardStackCheckStack
Definition Sema.h:2102
void ActOnPragmaAttributeAttribute(ParsedAttr &Attribute, SourceLocation PragmaLoc, attr::ParsedSubjectMatchRuleSet Rules)
PragmaStack< StringLiteral * > ConstSegStack
Definition Sema.h:2098
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:774
void ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, SourceLocation PragmaLoc)
ActOnPragmaOptionsAlign - Called on well formed #pragma options align.
Definition SemaAttr.cpp:377
InitSegPragmaState CurInitSeg
Definition Sema.h:2145
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:278
const LangOptions & getLangOpts() const
Definition Sema.h:927
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:1330
bool MSPragmaOptimizeIsOn
The "on" or "off" argument passed by #pragma optimize, that denotes whether the optimizations in the ...
Definition Sema.h:2192
SmallVector< PragmaAttributeGroup, 2 > PragmaAttributeStack
Definition Sema.h:2170
const LangOptions & LangOpts
Definition Sema.h:1329
PragmaClangSection PragmaClangRelroSection
Definition Sema.h:1875
SourceLocation ImplicitMSInheritanceAttrLoc
Source location for newly created implicit MSInheritanceAttrs.
Definition Sema.h:1864
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:2087
PragmaStack< StringLiteral * > BSSSegStack
Definition Sema.h:2097
llvm::StringMap< std::tuple< StringRef, SourceLocation > > FunctionToSectionMap
Sections used with pragma alloc_text.
Definition Sema.h:2148
llvm::SmallSetVector< StringRef, 4 > MSFunctionNoBuiltins
Set of no-builtin functions listed by #pragma function.
Definition Sema.h:2195
NamedDecl * lookupExternCFunctionOrVariable(IdentifierInfo *IdentId, SourceLocation NameLoc, Scope *curScope)
void AddPushedVisibilityAttribute(Decl *RD)
AddPushedVisibilityAttribute - If '#pragma GCC visibility' was used, add an appropriate visibility at...
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
Definition Sema.h:1471
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:2275
bool MSStructPragmaOn
Definition Sema.h:1861
SourceManager & getSourceManager() const
Definition Sema.h:932
void PrintPragmaAttributeInstantiationPoint()
Definition Sema.h:2365
void DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind, SourceLocation IncludeLoc)
Definition SemaAttr.cpp:593
PragmaClangSection PragmaClangTextSection
Definition Sema.h:1876
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:8492
PragmaClangSection PragmaClangDataSection
Definition Sema.h:1873
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:2086
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:2151
bool CheckAttrTarget(const ParsedAttr &CurrAttr)
ASTConsumer & Consumer
Definition Sema.h:1332
PragmaAlignPackDiagnoseKind
Definition Sema.h:2253
Scope * TUScope
Translation Unit Scope - useful to Objective-C actions that need to lookup file scope declarations in...
Definition Sema.h:1290
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:1334
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:1327
PragmaStack< StringLiteral * > DataSegStack
Definition Sema.h:2096
void ActOnPragmaVisibility(const IdentifierInfo *VisType, SourceLocation PragmaLoc)
ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... .
void ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, StringLiteral *SegmentName, IdentifierLoc *Func=nullptr)
Called on well-formed #pragma init_seg().
Definition SemaAttr.cpp:931
SourceLocation OptimizeOffPragmaLocation
This represents the last location of a "#pragma clang optimize off" directive if such a directive has...
Definition Sema.h:2179
LangOptions::PragmaMSPointersToMembersKind MSPointerToMemberRepresentationMethod
Controls member pointer representation format under the MS ABI.
Definition Sema.h:1859
void ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation, PragmaMsStackAction Action, bool Value)
ActOnPragmaMSStrictGuardStackCheck - Called on well formed #pragma strict_gs_check.
Definition SemaAttr.cpp:915
PragmaClangSection PragmaClangBSSSection
Definition Sema.h:1872
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:926
void inferNullableClassAttribute(CXXRecordDecl *CRD)
Add _Nullable attributes for std:: types.
Definition SemaAttr.cpp:365
PragmaMsStackAction
Definition Sema.h:1878
@ PSK_Push_Set
Definition Sema.h:1884
@ PSK_Reset
Definition Sema.h:1879
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
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:1844
SourceLocation getBeginLoc() const LLVM_READONLY
Definition Expr.h:2042
StringRef getString() const
Definition Expr.h:1912
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:225
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:1879
bool isVoidType() const
Definition TypeBase.h:9200
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:8914
bool isFunctionType() const
Definition TypeBase.h:8811
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9431
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3713
QualType getUnderlyingType() const
Definition Decl.h:3768
QualType getType() const
Definition Decl.h:725
Represents a variable declaration or definition.
Definition Decl.h:934
@ Definition
This declaration is definitely a definition.
Definition Decl.h:1326
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)
Top level wrappers for InstallAPI frontend operations.
PragmaClangSectionAction
Definition Sema.h:469
@ PFK_Reassociate
Definition PragmaKinds.h:41
@ PFK_Reciprocal
Definition PragmaKinds.h:42
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:354
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
@ AANT_ArgumentConstantExpr
PragmaOptionsAlignKind
Definition Sema.h:471
@ Result
The result type of a method or function.
Definition TypeBase.h:906
const FunctionProtoType * T
MSVtorDispMode
In the Microsoft ABI, this controls the placement of virtual displacement members used to implement v...
Definition LangOptions.h:39
PragmaClangSectionKind
pragma clang section kind
Definition Sema.h:460
@ On
Always emit colors regardless of the output stream.
PragmaMSStructKind
Definition PragmaKinds.h:24
@ PMSST_ON
Definition PragmaKinds.h:26
PragmaFloatControlKind
Definition PragmaKinds.h:29
@ PFC_NoExcept
Definition PragmaKinds.h:34
@ PFC_NoPrecise
Definition PragmaKinds.h:32
@ PFC_Pop
Definition PragmaKinds.h:36
@ PFC_Precise
Definition PragmaKinds.h:31
@ PFC_Except
Definition PragmaKinds.h:33
@ PFC_Push
Definition PragmaKinds.h:35
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
Definition Specifiers.h:139
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
Definition Expr.h:667
APValue Val
Val - This is the value the expression can be folded to.
Definition Expr.h:669
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:651
SourceLocation CurrentPragmaLocation
Definition Sema.h:2091
Information from a C++ pragma export, for a symbol that we haven't seen the declaration for yet.
Definition Sema.h:2388
This an attribute introduced by #pragma clang attribute.
Definition Sema.h:2154
SourceLocation PragmaLocation
Definition Sema.h:1869
SmallVector< Slot, 2 > Stack
Definition Sema.h:2070
void Act(SourceLocation PragmaLocation, PragmaMsStackAction Action, llvm::StringRef StackSlotLabel, ValueType Value)
Definition Sema.h:2009