Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/Sema/SemaAttr.cpp
35233 views
1
//===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file implements semantic analysis for non-trivial attributes and
10
// pragmas.
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "clang/AST/ASTConsumer.h"
15
#include "clang/AST/Attr.h"
16
#include "clang/AST/Expr.h"
17
#include "clang/Basic/TargetInfo.h"
18
#include "clang/Lex/Preprocessor.h"
19
#include "clang/Sema/Lookup.h"
20
#include "clang/Sema/SemaInternal.h"
21
#include <optional>
22
using namespace clang;
23
24
//===----------------------------------------------------------------------===//
25
// Pragma 'pack' and 'options align'
26
//===----------------------------------------------------------------------===//
27
28
Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S,
29
StringRef SlotLabel,
30
bool ShouldAct)
31
: S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) {
32
if (ShouldAct) {
33
S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel);
34
S.DataSegStack.SentinelAction(PSK_Push, SlotLabel);
35
S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel);
36
S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel);
37
S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel);
38
S.StrictGuardStackCheckStack.SentinelAction(PSK_Push, SlotLabel);
39
}
40
}
41
42
Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() {
43
if (ShouldAct) {
44
S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel);
45
S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel);
46
S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel);
47
S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel);
48
S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel);
49
S.StrictGuardStackCheckStack.SentinelAction(PSK_Pop, SlotLabel);
50
}
51
}
52
53
void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
54
AlignPackInfo InfoVal = AlignPackStack.CurrentValue;
55
AlignPackInfo::Mode M = InfoVal.getAlignMode();
56
bool IsPackSet = InfoVal.IsPackSet();
57
bool IsXLPragma = getLangOpts().XLPragmaPack;
58
59
// If we are not under mac68k/natural alignment mode and also there is no pack
60
// value, we don't need any attributes.
61
if (!IsPackSet && M != AlignPackInfo::Mac68k && M != AlignPackInfo::Natural)
62
return;
63
64
if (M == AlignPackInfo::Mac68k && (IsXLPragma || InfoVal.IsAlignAttr())) {
65
RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
66
} else if (IsPackSet) {
67
// Check to see if we need a max field alignment attribute.
68
RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(
69
Context, InfoVal.getPackNumber() * 8));
70
}
71
72
if (IsXLPragma && M == AlignPackInfo::Natural)
73
RD->addAttr(AlignNaturalAttr::CreateImplicit(Context));
74
75
if (AlignPackIncludeStack.empty())
76
return;
77
// The #pragma align/pack affected a record in an included file, so Clang
78
// should warn when that pragma was written in a file that included the
79
// included file.
80
for (auto &AlignPackedInclude : llvm::reverse(AlignPackIncludeStack)) {
81
if (AlignPackedInclude.CurrentPragmaLocation !=
82
AlignPackStack.CurrentPragmaLocation)
83
break;
84
if (AlignPackedInclude.HasNonDefaultValue)
85
AlignPackedInclude.ShouldWarnOnInclude = true;
86
}
87
}
88
89
void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
90
if (MSStructPragmaOn)
91
RD->addAttr(MSStructAttr::CreateImplicit(Context));
92
93
// FIXME: We should merge AddAlignmentAttributesForRecord with
94
// AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
95
// all active pragmas and applies them as attributes to class definitions.
96
if (VtorDispStack.CurrentValue != getLangOpts().getVtorDispMode())
97
RD->addAttr(MSVtorDispAttr::CreateImplicit(
98
Context, unsigned(VtorDispStack.CurrentValue)));
99
}
100
101
template <typename Attribute>
102
static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context,
103
CXXRecordDecl *Record) {
104
if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
105
return;
106
107
for (Decl *Redecl : Record->redecls())
108
Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
109
}
110
111
void Sema::inferGslPointerAttribute(NamedDecl *ND,
112
CXXRecordDecl *UnderlyingRecord) {
113
if (!UnderlyingRecord)
114
return;
115
116
const auto *Parent = dyn_cast<CXXRecordDecl>(ND->getDeclContext());
117
if (!Parent)
118
return;
119
120
static const llvm::StringSet<> Containers{
121
"array",
122
"basic_string",
123
"deque",
124
"forward_list",
125
"vector",
126
"list",
127
"map",
128
"multiset",
129
"multimap",
130
"priority_queue",
131
"queue",
132
"set",
133
"stack",
134
"unordered_set",
135
"unordered_map",
136
"unordered_multiset",
137
"unordered_multimap",
138
};
139
140
static const llvm::StringSet<> Iterators{"iterator", "const_iterator",
141
"reverse_iterator",
142
"const_reverse_iterator"};
143
144
if (Parent->isInStdNamespace() && Iterators.count(ND->getName()) &&
145
Containers.count(Parent->getName()))
146
addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context,
147
UnderlyingRecord);
148
}
149
150
void Sema::inferGslPointerAttribute(TypedefNameDecl *TD) {
151
152
QualType Canonical = TD->getUnderlyingType().getCanonicalType();
153
154
CXXRecordDecl *RD = Canonical->getAsCXXRecordDecl();
155
if (!RD) {
156
if (auto *TST =
157
dyn_cast<TemplateSpecializationType>(Canonical.getTypePtr())) {
158
159
RD = dyn_cast_or_null<CXXRecordDecl>(
160
TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl());
161
}
162
}
163
164
inferGslPointerAttribute(TD, RD);
165
}
166
167
void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) {
168
static const llvm::StringSet<> StdOwners{
169
"any",
170
"array",
171
"basic_regex",
172
"basic_string",
173
"deque",
174
"forward_list",
175
"vector",
176
"list",
177
"map",
178
"multiset",
179
"multimap",
180
"optional",
181
"priority_queue",
182
"queue",
183
"set",
184
"stack",
185
"unique_ptr",
186
"unordered_set",
187
"unordered_map",
188
"unordered_multiset",
189
"unordered_multimap",
190
"variant",
191
};
192
static const llvm::StringSet<> StdPointers{
193
"basic_string_view",
194
"reference_wrapper",
195
"regex_iterator",
196
"span",
197
};
198
199
if (!Record->getIdentifier())
200
return;
201
202
// Handle classes that directly appear in std namespace.
203
if (Record->isInStdNamespace()) {
204
if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
205
return;
206
207
if (StdOwners.count(Record->getName()))
208
addGslOwnerPointerAttributeIfNotExisting<OwnerAttr>(Context, Record);
209
else if (StdPointers.count(Record->getName()))
210
addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context, Record);
211
212
return;
213
}
214
215
// Handle nested classes that could be a gsl::Pointer.
216
inferGslPointerAttribute(Record, Record);
217
}
218
219
void Sema::inferNullableClassAttribute(CXXRecordDecl *CRD) {
220
static const llvm::StringSet<> Nullable{
221
"auto_ptr", "shared_ptr", "unique_ptr", "exception_ptr",
222
"coroutine_handle", "function", "move_only_function",
223
};
224
225
if (CRD->isInStdNamespace() && Nullable.count(CRD->getName()) &&
226
!CRD->hasAttr<TypeNullableAttr>())
227
for (Decl *Redecl : CRD->redecls())
228
Redecl->addAttr(TypeNullableAttr::CreateImplicit(Context));
229
}
230
231
void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
232
SourceLocation PragmaLoc) {
233
PragmaMsStackAction Action = Sema::PSK_Reset;
234
AlignPackInfo::Mode ModeVal = AlignPackInfo::Native;
235
236
switch (Kind) {
237
// For most of the platforms we support, native and natural are the same.
238
// With XL, native is the same as power, natural means something else.
239
case POAK_Native:
240
case POAK_Power:
241
Action = Sema::PSK_Push_Set;
242
break;
243
case POAK_Natural:
244
Action = Sema::PSK_Push_Set;
245
ModeVal = AlignPackInfo::Natural;
246
break;
247
248
// Note that '#pragma options align=packed' is not equivalent to attribute
249
// packed, it has a different precedence relative to attribute aligned.
250
case POAK_Packed:
251
Action = Sema::PSK_Push_Set;
252
ModeVal = AlignPackInfo::Packed;
253
break;
254
255
case POAK_Mac68k:
256
// Check if the target supports this.
257
if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
258
Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
259
return;
260
}
261
Action = Sema::PSK_Push_Set;
262
ModeVal = AlignPackInfo::Mac68k;
263
break;
264
case POAK_Reset:
265
// Reset just pops the top of the stack, or resets the current alignment to
266
// default.
267
Action = Sema::PSK_Pop;
268
if (AlignPackStack.Stack.empty()) {
269
if (AlignPackStack.CurrentValue.getAlignMode() != AlignPackInfo::Native ||
270
AlignPackStack.CurrentValue.IsPackAttr()) {
271
Action = Sema::PSK_Reset;
272
} else {
273
Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
274
<< "stack empty";
275
return;
276
}
277
}
278
break;
279
}
280
281
AlignPackInfo Info(ModeVal, getLangOpts().XLPragmaPack);
282
283
AlignPackStack.Act(PragmaLoc, Action, StringRef(), Info);
284
}
285
286
void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc,
287
PragmaClangSectionAction Action,
288
PragmaClangSectionKind SecKind,
289
StringRef SecName) {
290
PragmaClangSection *CSec;
291
int SectionFlags = ASTContext::PSF_Read;
292
switch (SecKind) {
293
case PragmaClangSectionKind::PCSK_BSS:
294
CSec = &PragmaClangBSSSection;
295
SectionFlags |= ASTContext::PSF_Write | ASTContext::PSF_ZeroInit;
296
break;
297
case PragmaClangSectionKind::PCSK_Data:
298
CSec = &PragmaClangDataSection;
299
SectionFlags |= ASTContext::PSF_Write;
300
break;
301
case PragmaClangSectionKind::PCSK_Rodata:
302
CSec = &PragmaClangRodataSection;
303
break;
304
case PragmaClangSectionKind::PCSK_Relro:
305
CSec = &PragmaClangRelroSection;
306
break;
307
case PragmaClangSectionKind::PCSK_Text:
308
CSec = &PragmaClangTextSection;
309
SectionFlags |= ASTContext::PSF_Execute;
310
break;
311
default:
312
llvm_unreachable("invalid clang section kind");
313
}
314
315
if (Action == PragmaClangSectionAction::PCSA_Clear) {
316
CSec->Valid = false;
317
return;
318
}
319
320
if (llvm::Error E = isValidSectionSpecifier(SecName)) {
321
Diag(PragmaLoc, diag::err_pragma_section_invalid_for_target)
322
<< toString(std::move(E));
323
CSec->Valid = false;
324
return;
325
}
326
327
if (UnifySection(SecName, SectionFlags, PragmaLoc))
328
return;
329
330
CSec->Valid = true;
331
CSec->SectionName = std::string(SecName);
332
CSec->PragmaLocation = PragmaLoc;
333
}
334
335
void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action,
336
StringRef SlotLabel, Expr *alignment) {
337
bool IsXLPragma = getLangOpts().XLPragmaPack;
338
// XL pragma pack does not support identifier syntax.
339
if (IsXLPragma && !SlotLabel.empty()) {
340
Diag(PragmaLoc, diag::err_pragma_pack_identifer_not_supported);
341
return;
342
}
343
344
const AlignPackInfo CurVal = AlignPackStack.CurrentValue;
345
Expr *Alignment = static_cast<Expr *>(alignment);
346
347
// If specified then alignment must be a "small" power of two.
348
unsigned AlignmentVal = 0;
349
AlignPackInfo::Mode ModeVal = CurVal.getAlignMode();
350
351
if (Alignment) {
352
std::optional<llvm::APSInt> Val;
353
Val = Alignment->getIntegerConstantExpr(Context);
354
355
// pack(0) is like pack(), which just works out since that is what
356
// we use 0 for in PackAttr.
357
if (Alignment->isTypeDependent() || !Val ||
358
!(*Val == 0 || Val->isPowerOf2()) || Val->getZExtValue() > 16) {
359
Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
360
return; // Ignore
361
}
362
363
if (IsXLPragma && *Val == 0) {
364
// pack(0) does not work out with XL.
365
Diag(PragmaLoc, diag::err_pragma_pack_invalid_alignment);
366
return; // Ignore
367
}
368
369
AlignmentVal = (unsigned)Val->getZExtValue();
370
}
371
372
if (Action == Sema::PSK_Show) {
373
// Show the current alignment, making sure to show the right value
374
// for the default.
375
// FIXME: This should come from the target.
376
AlignmentVal = CurVal.IsPackSet() ? CurVal.getPackNumber() : 8;
377
if (ModeVal == AlignPackInfo::Mac68k &&
378
(IsXLPragma || CurVal.IsAlignAttr()))
379
Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
380
else
381
Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
382
}
383
384
// MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
385
// "#pragma pack(pop, identifier, n) is undefined"
386
if (Action & Sema::PSK_Pop) {
387
if (Alignment && !SlotLabel.empty())
388
Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifier_and_alignment);
389
if (AlignPackStack.Stack.empty()) {
390
assert(CurVal.getAlignMode() == AlignPackInfo::Native &&
391
"Empty pack stack can only be at Native alignment mode.");
392
Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty";
393
}
394
}
395
396
AlignPackInfo Info(ModeVal, AlignmentVal, IsXLPragma);
397
398
AlignPackStack.Act(PragmaLoc, Action, SlotLabel, Info);
399
}
400
401
bool Sema::ConstantFoldAttrArgs(const AttributeCommonInfo &CI,
402
MutableArrayRef<Expr *> Args) {
403
llvm::SmallVector<PartialDiagnosticAt, 8> Notes;
404
for (unsigned Idx = 0; Idx < Args.size(); Idx++) {
405
Expr *&E = Args.begin()[Idx];
406
assert(E && "error are handled before");
407
if (E->isValueDependent() || E->isTypeDependent())
408
continue;
409
410
// FIXME: Use DefaultFunctionArrayLValueConversion() in place of the logic
411
// that adds implicit casts here.
412
if (E->getType()->isArrayType())
413
E = ImpCastExprToType(E, Context.getPointerType(E->getType()),
414
clang::CK_ArrayToPointerDecay)
415
.get();
416
if (E->getType()->isFunctionType())
417
E = ImplicitCastExpr::Create(Context,
418
Context.getPointerType(E->getType()),
419
clang::CK_FunctionToPointerDecay, E, nullptr,
420
VK_PRValue, FPOptionsOverride());
421
if (E->isLValue())
422
E = ImplicitCastExpr::Create(Context, E->getType().getNonReferenceType(),
423
clang::CK_LValueToRValue, E, nullptr,
424
VK_PRValue, FPOptionsOverride());
425
426
Expr::EvalResult Eval;
427
Notes.clear();
428
Eval.Diag = &Notes;
429
430
bool Result = E->EvaluateAsConstantExpr(Eval, Context);
431
432
/// Result means the expression can be folded to a constant.
433
/// Note.empty() means the expression is a valid constant expression in the
434
/// current language mode.
435
if (!Result || !Notes.empty()) {
436
Diag(E->getBeginLoc(), diag::err_attribute_argument_n_type)
437
<< CI << (Idx + 1) << AANT_ArgumentConstantExpr;
438
for (auto &Note : Notes)
439
Diag(Note.first, Note.second);
440
return false;
441
}
442
assert(Eval.Val.hasValue());
443
E = ConstantExpr::Create(Context, E, Eval.Val);
444
}
445
446
return true;
447
}
448
449
void Sema::DiagnoseNonDefaultPragmaAlignPack(PragmaAlignPackDiagnoseKind Kind,
450
SourceLocation IncludeLoc) {
451
if (Kind == PragmaAlignPackDiagnoseKind::NonDefaultStateAtInclude) {
452
SourceLocation PrevLocation = AlignPackStack.CurrentPragmaLocation;
453
// Warn about non-default alignment at #includes (without redundant
454
// warnings for the same directive in nested includes).
455
// The warning is delayed until the end of the file to avoid warnings
456
// for files that don't have any records that are affected by the modified
457
// alignment.
458
bool HasNonDefaultValue =
459
AlignPackStack.hasValue() &&
460
(AlignPackIncludeStack.empty() ||
461
AlignPackIncludeStack.back().CurrentPragmaLocation != PrevLocation);
462
AlignPackIncludeStack.push_back(
463
{AlignPackStack.CurrentValue,
464
AlignPackStack.hasValue() ? PrevLocation : SourceLocation(),
465
HasNonDefaultValue, /*ShouldWarnOnInclude*/ false});
466
return;
467
}
468
469
assert(Kind == PragmaAlignPackDiagnoseKind::ChangedStateAtExit &&
470
"invalid kind");
471
AlignPackIncludeState PrevAlignPackState =
472
AlignPackIncludeStack.pop_back_val();
473
// FIXME: AlignPackStack may contain both #pragma align and #pragma pack
474
// information, diagnostics below might not be accurate if we have mixed
475
// pragmas.
476
if (PrevAlignPackState.ShouldWarnOnInclude) {
477
// Emit the delayed non-default alignment at #include warning.
478
Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include);
479
Diag(PrevAlignPackState.CurrentPragmaLocation, diag::note_pragma_pack_here);
480
}
481
// Warn about modified alignment after #includes.
482
if (PrevAlignPackState.CurrentValue != AlignPackStack.CurrentValue) {
483
Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include);
484
Diag(AlignPackStack.CurrentPragmaLocation, diag::note_pragma_pack_here);
485
}
486
}
487
488
void Sema::DiagnoseUnterminatedPragmaAlignPack() {
489
if (AlignPackStack.Stack.empty())
490
return;
491
bool IsInnermost = true;
492
493
// FIXME: AlignPackStack may contain both #pragma align and #pragma pack
494
// information, diagnostics below might not be accurate if we have mixed
495
// pragmas.
496
for (const auto &StackSlot : llvm::reverse(AlignPackStack.Stack)) {
497
Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof);
498
// The user might have already reset the alignment, so suggest replacing
499
// the reset with a pop.
500
if (IsInnermost &&
501
AlignPackStack.CurrentValue == AlignPackStack.DefaultValue) {
502
auto DB = Diag(AlignPackStack.CurrentPragmaLocation,
503
diag::note_pragma_pack_pop_instead_reset);
504
SourceLocation FixItLoc =
505
Lexer::findLocationAfterToken(AlignPackStack.CurrentPragmaLocation,
506
tok::l_paren, SourceMgr, LangOpts,
507
/*SkipTrailing=*/false);
508
if (FixItLoc.isValid())
509
DB << FixItHint::CreateInsertion(FixItLoc, "pop");
510
}
511
IsInnermost = false;
512
}
513
}
514
515
void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
516
MSStructPragmaOn = (Kind == PMSST_ON);
517
}
518
519
void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc,
520
PragmaMSCommentKind Kind, StringRef Arg) {
521
auto *PCD = PragmaCommentDecl::Create(
522
Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg);
523
Context.getTranslationUnitDecl()->addDecl(PCD);
524
Consumer.HandleTopLevelDecl(DeclGroupRef(PCD));
525
}
526
527
void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
528
StringRef Value) {
529
auto *PDMD = PragmaDetectMismatchDecl::Create(
530
Context, Context.getTranslationUnitDecl(), Loc, Name, Value);
531
Context.getTranslationUnitDecl()->addDecl(PDMD);
532
Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
533
}
534
535
void Sema::ActOnPragmaFPEvalMethod(SourceLocation Loc,
536
LangOptions::FPEvalMethodKind Value) {
537
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
538
switch (Value) {
539
default:
540
llvm_unreachable("invalid pragma eval_method kind");
541
case LangOptions::FEM_Source:
542
NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Source);
543
break;
544
case LangOptions::FEM_Double:
545
NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Double);
546
break;
547
case LangOptions::FEM_Extended:
548
NewFPFeatures.setFPEvalMethodOverride(LangOptions::FEM_Extended);
549
break;
550
}
551
if (getLangOpts().ApproxFunc)
552
Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 0;
553
if (getLangOpts().AllowFPReassoc)
554
Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 1;
555
if (getLangOpts().AllowRecip)
556
Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context) << 0 << 2;
557
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
558
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
559
PP.setCurrentFPEvalMethod(Loc, Value);
560
}
561
562
void Sema::ActOnPragmaFloatControl(SourceLocation Loc,
563
PragmaMsStackAction Action,
564
PragmaFloatControlKind Value) {
565
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
566
if ((Action == PSK_Push_Set || Action == PSK_Push || Action == PSK_Pop) &&
567
!CurContext->getRedeclContext()->isFileContext()) {
568
// Push and pop can only occur at file or namespace scope, or within a
569
// language linkage declaration.
570
Diag(Loc, diag::err_pragma_fc_pp_scope);
571
return;
572
}
573
switch (Value) {
574
default:
575
llvm_unreachable("invalid pragma float_control kind");
576
case PFC_Precise:
577
NewFPFeatures.setFPPreciseEnabled(true);
578
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
579
break;
580
case PFC_NoPrecise:
581
if (CurFPFeatures.getExceptionMode() == LangOptions::FPE_Strict)
582
Diag(Loc, diag::err_pragma_fc_noprecise_requires_noexcept);
583
else if (CurFPFeatures.getAllowFEnvAccess())
584
Diag(Loc, diag::err_pragma_fc_noprecise_requires_nofenv);
585
else
586
NewFPFeatures.setFPPreciseEnabled(false);
587
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
588
break;
589
case PFC_Except:
590
if (!isPreciseFPEnabled())
591
Diag(Loc, diag::err_pragma_fc_except_requires_precise);
592
else
593
NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Strict);
594
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
595
break;
596
case PFC_NoExcept:
597
NewFPFeatures.setSpecifiedExceptionModeOverride(LangOptions::FPE_Ignore);
598
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
599
break;
600
case PFC_Push:
601
FpPragmaStack.Act(Loc, Sema::PSK_Push_Set, StringRef(), NewFPFeatures);
602
break;
603
case PFC_Pop:
604
if (FpPragmaStack.Stack.empty()) {
605
Diag(Loc, diag::warn_pragma_pop_failed) << "float_control"
606
<< "stack empty";
607
return;
608
}
609
FpPragmaStack.Act(Loc, Action, StringRef(), NewFPFeatures);
610
NewFPFeatures = FpPragmaStack.CurrentValue;
611
break;
612
}
613
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
614
}
615
616
void Sema::ActOnPragmaMSPointersToMembers(
617
LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
618
SourceLocation PragmaLoc) {
619
MSPointerToMemberRepresentationMethod = RepresentationMethod;
620
ImplicitMSInheritanceAttrLoc = PragmaLoc;
621
}
622
623
void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,
624
SourceLocation PragmaLoc,
625
MSVtorDispMode Mode) {
626
if (Action & PSK_Pop && VtorDispStack.Stack.empty())
627
Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
628
<< "stack empty";
629
VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode);
630
}
631
632
template <>
633
void Sema::PragmaStack<Sema::AlignPackInfo>::Act(SourceLocation PragmaLocation,
634
PragmaMsStackAction Action,
635
llvm::StringRef StackSlotLabel,
636
AlignPackInfo Value) {
637
if (Action == PSK_Reset) {
638
CurrentValue = DefaultValue;
639
CurrentPragmaLocation = PragmaLocation;
640
return;
641
}
642
if (Action & PSK_Push)
643
Stack.emplace_back(Slot(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
644
PragmaLocation));
645
else if (Action & PSK_Pop) {
646
if (!StackSlotLabel.empty()) {
647
// If we've got a label, try to find it and jump there.
648
auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
649
return x.StackSlotLabel == StackSlotLabel;
650
});
651
// We found the label, so pop from there.
652
if (I != Stack.rend()) {
653
CurrentValue = I->Value;
654
CurrentPragmaLocation = I->PragmaLocation;
655
Stack.erase(std::prev(I.base()), Stack.end());
656
}
657
} else if (Value.IsXLStack() && Value.IsAlignAttr() &&
658
CurrentValue.IsPackAttr()) {
659
// XL '#pragma align(reset)' would pop the stack until
660
// a current in effect pragma align is popped.
661
auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
662
return x.Value.IsAlignAttr();
663
});
664
// If we found pragma align so pop from there.
665
if (I != Stack.rend()) {
666
Stack.erase(std::prev(I.base()), Stack.end());
667
if (Stack.empty()) {
668
CurrentValue = DefaultValue;
669
CurrentPragmaLocation = PragmaLocation;
670
} else {
671
CurrentValue = Stack.back().Value;
672
CurrentPragmaLocation = Stack.back().PragmaLocation;
673
Stack.pop_back();
674
}
675
}
676
} else if (!Stack.empty()) {
677
// xl '#pragma align' sets the baseline, and `#pragma pack` cannot pop
678
// over the baseline.
679
if (Value.IsXLStack() && Value.IsPackAttr() && CurrentValue.IsAlignAttr())
680
return;
681
682
// We don't have a label, just pop the last entry.
683
CurrentValue = Stack.back().Value;
684
CurrentPragmaLocation = Stack.back().PragmaLocation;
685
Stack.pop_back();
686
}
687
}
688
if (Action & PSK_Set) {
689
CurrentValue = Value;
690
CurrentPragmaLocation = PragmaLocation;
691
}
692
}
693
694
bool Sema::UnifySection(StringRef SectionName, int SectionFlags,
695
NamedDecl *Decl) {
696
SourceLocation PragmaLocation;
697
if (auto A = Decl->getAttr<SectionAttr>())
698
if (A->isImplicit())
699
PragmaLocation = A->getLocation();
700
auto SectionIt = Context.SectionInfos.find(SectionName);
701
if (SectionIt == Context.SectionInfos.end()) {
702
Context.SectionInfos[SectionName] =
703
ASTContext::SectionInfo(Decl, PragmaLocation, SectionFlags);
704
return false;
705
}
706
// A pre-declared section takes precedence w/o diagnostic.
707
const auto &Section = SectionIt->second;
708
if (Section.SectionFlags == SectionFlags ||
709
((SectionFlags & ASTContext::PSF_Implicit) &&
710
!(Section.SectionFlags & ASTContext::PSF_Implicit)))
711
return false;
712
Diag(Decl->getLocation(), diag::err_section_conflict) << Decl << Section;
713
if (Section.Decl)
714
Diag(Section.Decl->getLocation(), diag::note_declared_at)
715
<< Section.Decl->getName();
716
if (PragmaLocation.isValid())
717
Diag(PragmaLocation, diag::note_pragma_entered_here);
718
if (Section.PragmaSectionLocation.isValid())
719
Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
720
return true;
721
}
722
723
bool Sema::UnifySection(StringRef SectionName,
724
int SectionFlags,
725
SourceLocation PragmaSectionLocation) {
726
auto SectionIt = Context.SectionInfos.find(SectionName);
727
if (SectionIt != Context.SectionInfos.end()) {
728
const auto &Section = SectionIt->second;
729
if (Section.SectionFlags == SectionFlags)
730
return false;
731
if (!(Section.SectionFlags & ASTContext::PSF_Implicit)) {
732
Diag(PragmaSectionLocation, diag::err_section_conflict)
733
<< "this" << Section;
734
if (Section.Decl)
735
Diag(Section.Decl->getLocation(), diag::note_declared_at)
736
<< Section.Decl->getName();
737
if (Section.PragmaSectionLocation.isValid())
738
Diag(Section.PragmaSectionLocation, diag::note_pragma_entered_here);
739
return true;
740
}
741
}
742
Context.SectionInfos[SectionName] =
743
ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
744
return false;
745
}
746
747
/// Called on well formed \#pragma bss_seg().
748
void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
749
PragmaMsStackAction Action,
750
llvm::StringRef StackSlotLabel,
751
StringLiteral *SegmentName,
752
llvm::StringRef PragmaName) {
753
PragmaStack<StringLiteral *> *Stack =
754
llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
755
.Case("data_seg", &DataSegStack)
756
.Case("bss_seg", &BSSSegStack)
757
.Case("const_seg", &ConstSegStack)
758
.Case("code_seg", &CodeSegStack);
759
if (Action & PSK_Pop && Stack->Stack.empty())
760
Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
761
<< "stack empty";
762
if (SegmentName) {
763
if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
764
return;
765
766
if (SegmentName->getString() == ".drectve" &&
767
Context.getTargetInfo().getCXXABI().isMicrosoft())
768
Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName;
769
}
770
771
Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
772
}
773
774
/// Called on well formed \#pragma strict_gs_check().
775
void Sema::ActOnPragmaMSStrictGuardStackCheck(SourceLocation PragmaLocation,
776
PragmaMsStackAction Action,
777
bool Value) {
778
if (Action & PSK_Pop && StrictGuardStackCheckStack.Stack.empty())
779
Diag(PragmaLocation, diag::warn_pragma_pop_failed) << "strict_gs_check"
780
<< "stack empty";
781
782
StrictGuardStackCheckStack.Act(PragmaLocation, Action, StringRef(), Value);
783
}
784
785
/// Called on well formed \#pragma bss_seg().
786
void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
787
int SectionFlags, StringLiteral *SegmentName) {
788
UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
789
}
790
791
void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
792
StringLiteral *SegmentName) {
793
// There's no stack to maintain, so we just have a current section. When we
794
// see the default section, reset our current section back to null so we stop
795
// tacking on unnecessary attributes.
796
CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName;
797
CurInitSegLoc = PragmaLocation;
798
}
799
800
void Sema::ActOnPragmaMSAllocText(
801
SourceLocation PragmaLocation, StringRef Section,
802
const SmallVector<std::tuple<IdentifierInfo *, SourceLocation>>
803
&Functions) {
804
if (!CurContext->getRedeclContext()->isFileContext()) {
805
Diag(PragmaLocation, diag::err_pragma_expected_file_scope) << "alloc_text";
806
return;
807
}
808
809
for (auto &Function : Functions) {
810
IdentifierInfo *II;
811
SourceLocation Loc;
812
std::tie(II, Loc) = Function;
813
814
DeclarationName DN(II);
815
NamedDecl *ND = LookupSingleName(TUScope, DN, Loc, LookupOrdinaryName);
816
if (!ND) {
817
Diag(Loc, diag::err_undeclared_use) << II->getName();
818
return;
819
}
820
821
auto *FD = dyn_cast<FunctionDecl>(ND->getCanonicalDecl());
822
if (!FD) {
823
Diag(Loc, diag::err_pragma_alloc_text_not_function);
824
return;
825
}
826
827
if (getLangOpts().CPlusPlus && !FD->isInExternCContext()) {
828
Diag(Loc, diag::err_pragma_alloc_text_c_linkage);
829
return;
830
}
831
832
FunctionToSectionMap[II->getName()] = std::make_tuple(Section, Loc);
833
}
834
}
835
836
void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
837
SourceLocation PragmaLoc) {
838
839
IdentifierInfo *Name = IdTok.getIdentifierInfo();
840
LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
841
LookupName(Lookup, curScope, /*AllowBuiltinCreation=*/true);
842
843
if (Lookup.empty()) {
844
Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
845
<< Name << SourceRange(IdTok.getLocation());
846
return;
847
}
848
849
VarDecl *VD = Lookup.getAsSingle<VarDecl>();
850
if (!VD) {
851
Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
852
<< Name << SourceRange(IdTok.getLocation());
853
return;
854
}
855
856
// Warn if this was used before being marked unused.
857
if (VD->isUsed())
858
Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
859
860
VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(),
861
UnusedAttr::GNU_unused));
862
}
863
864
namespace {
865
866
std::optional<attr::SubjectMatchRule>
867
getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
868
using namespace attr;
869
switch (Rule) {
870
default:
871
return std::nullopt;
872
#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
873
#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
874
case Value: \
875
return Parent;
876
#include "clang/Basic/AttrSubMatchRulesList.inc"
877
}
878
}
879
880
bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
881
using namespace attr;
882
switch (Rule) {
883
default:
884
return false;
885
#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
886
#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \
887
case Value: \
888
return IsNegated;
889
#include "clang/Basic/AttrSubMatchRulesList.inc"
890
}
891
}
892
893
CharSourceRange replacementRangeForListElement(const Sema &S,
894
SourceRange Range) {
895
// Make sure that the ',' is removed as well.
896
SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
897
Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
898
/*SkipTrailingWhitespaceAndNewLine=*/false);
899
if (AfterCommaLoc.isValid())
900
return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
901
else
902
return CharSourceRange::getTokenRange(Range);
903
}
904
905
std::string
906
attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
907
std::string Result;
908
llvm::raw_string_ostream OS(Result);
909
for (const auto &I : llvm::enumerate(Rules)) {
910
if (I.index())
911
OS << (I.index() == Rules.size() - 1 ? ", and " : ", ");
912
OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
913
}
914
return Result;
915
}
916
917
} // end anonymous namespace
918
919
void Sema::ActOnPragmaAttributeAttribute(
920
ParsedAttr &Attribute, SourceLocation PragmaLoc,
921
attr::ParsedSubjectMatchRuleSet Rules) {
922
Attribute.setIsPragmaClangAttribute();
923
SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
924
// Gather the subject match rules that are supported by the attribute.
925
SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4>
926
StrictSubjectMatchRuleSet;
927
Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
928
929
// Figure out which subject matching rules are valid.
930
if (StrictSubjectMatchRuleSet.empty()) {
931
// Check for contradicting match rules. Contradicting match rules are
932
// either:
933
// - a top-level rule and one of its sub-rules. E.g. variable and
934
// variable(is_parameter).
935
// - a sub-rule and a sibling that's negated. E.g.
936
// variable(is_thread_local) and variable(unless(is_parameter))
937
llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2>
938
RulesToFirstSpecifiedNegatedSubRule;
939
for (const auto &Rule : Rules) {
940
attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
941
std::optional<attr::SubjectMatchRule> ParentRule =
942
getParentAttrMatcherRule(MatchRule);
943
if (!ParentRule)
944
continue;
945
auto It = Rules.find(*ParentRule);
946
if (It != Rules.end()) {
947
// A sub-rule contradicts a parent rule.
948
Diag(Rule.second.getBegin(),
949
diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
950
<< attr::getSubjectMatchRuleSpelling(MatchRule)
951
<< attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
952
<< FixItHint::CreateRemoval(
953
replacementRangeForListElement(*this, Rule.second));
954
// Keep going without removing this rule as it won't change the set of
955
// declarations that receive the attribute.
956
continue;
957
}
958
if (isNegatedAttrMatcherSubRule(MatchRule))
959
RulesToFirstSpecifiedNegatedSubRule.insert(
960
std::make_pair(*ParentRule, Rule));
961
}
962
bool IgnoreNegatedSubRules = false;
963
for (const auto &Rule : Rules) {
964
attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
965
std::optional<attr::SubjectMatchRule> ParentRule =
966
getParentAttrMatcherRule(MatchRule);
967
if (!ParentRule)
968
continue;
969
auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
970
if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
971
It->second != Rule) {
972
// Negated sub-rule contradicts another sub-rule.
973
Diag(
974
It->second.second.getBegin(),
975
diag::
976
err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
977
<< attr::getSubjectMatchRuleSpelling(
978
attr::SubjectMatchRule(It->second.first))
979
<< attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
980
<< FixItHint::CreateRemoval(
981
replacementRangeForListElement(*this, It->second.second));
982
// Keep going but ignore all of the negated sub-rules.
983
IgnoreNegatedSubRules = true;
984
RulesToFirstSpecifiedNegatedSubRule.erase(It);
985
}
986
}
987
988
if (!IgnoreNegatedSubRules) {
989
for (const auto &Rule : Rules)
990
SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
991
} else {
992
for (const auto &Rule : Rules) {
993
if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
994
SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
995
}
996
}
997
Rules.clear();
998
} else {
999
// Each rule in Rules must be a strict subset of the attribute's
1000
// SubjectMatch rules. I.e. we're allowed to use
1001
// `apply_to=variables(is_global)` on an attrubute with SubjectList<[Var]>,
1002
// but should not allow `apply_to=variables` on an attribute which has
1003
// `SubjectList<[GlobalVar]>`.
1004
for (const auto &StrictRule : StrictSubjectMatchRuleSet) {
1005
// First, check for exact match.
1006
if (Rules.erase(StrictRule.first)) {
1007
// Add the rule to the set of attribute receivers only if it's supported
1008
// in the current language mode.
1009
if (StrictRule.second)
1010
SubjectMatchRules.push_back(StrictRule.first);
1011
}
1012
}
1013
// Check remaining rules for subset matches.
1014
auto RulesToCheck = Rules;
1015
for (const auto &Rule : RulesToCheck) {
1016
attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
1017
if (auto ParentRule = getParentAttrMatcherRule(MatchRule)) {
1018
if (llvm::any_of(StrictSubjectMatchRuleSet,
1019
[ParentRule](const auto &StrictRule) {
1020
return StrictRule.first == *ParentRule &&
1021
StrictRule.second; // IsEnabled
1022
})) {
1023
SubjectMatchRules.push_back(MatchRule);
1024
Rules.erase(MatchRule);
1025
}
1026
}
1027
}
1028
}
1029
1030
if (!Rules.empty()) {
1031
auto Diagnostic =
1032
Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
1033
<< Attribute;
1034
SmallVector<attr::SubjectMatchRule, 2> ExtraRules;
1035
for (const auto &Rule : Rules) {
1036
ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
1037
Diagnostic << FixItHint::CreateRemoval(
1038
replacementRangeForListElement(*this, Rule.second));
1039
}
1040
Diagnostic << attrMatcherRuleListToString(ExtraRules);
1041
}
1042
1043
if (PragmaAttributeStack.empty()) {
1044
Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push);
1045
return;
1046
}
1047
1048
PragmaAttributeStack.back().Entries.push_back(
1049
{PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
1050
}
1051
1052
void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc,
1053
const IdentifierInfo *Namespace) {
1054
PragmaAttributeStack.emplace_back();
1055
PragmaAttributeStack.back().Loc = PragmaLoc;
1056
PragmaAttributeStack.back().Namespace = Namespace;
1057
}
1058
1059
void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc,
1060
const IdentifierInfo *Namespace) {
1061
if (PragmaAttributeStack.empty()) {
1062
Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1063
return;
1064
}
1065
1066
// Dig back through the stack trying to find the most recently pushed group
1067
// that in Namespace. Note that this works fine if no namespace is present,
1068
// think of push/pops without namespaces as having an implicit "nullptr"
1069
// namespace.
1070
for (size_t Index = PragmaAttributeStack.size(); Index;) {
1071
--Index;
1072
if (PragmaAttributeStack[Index].Namespace == Namespace) {
1073
for (const PragmaAttributeEntry &Entry :
1074
PragmaAttributeStack[Index].Entries) {
1075
if (!Entry.IsUsed) {
1076
assert(Entry.Attribute && "Expected an attribute");
1077
Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
1078
<< *Entry.Attribute;
1079
Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
1080
}
1081
}
1082
PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index);
1083
return;
1084
}
1085
}
1086
1087
if (Namespace)
1088
Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch)
1089
<< 0 << Namespace->getName();
1090
else
1091
Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
1092
}
1093
1094
void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
1095
if (PragmaAttributeStack.empty())
1096
return;
1097
for (auto &Group : PragmaAttributeStack) {
1098
for (auto &Entry : Group.Entries) {
1099
ParsedAttr *Attribute = Entry.Attribute;
1100
assert(Attribute && "Expected an attribute");
1101
assert(Attribute->isPragmaClangAttribute() &&
1102
"expected #pragma clang attribute");
1103
1104
// Ensure that the attribute can be applied to the given declaration.
1105
bool Applies = false;
1106
for (const auto &Rule : Entry.MatchRules) {
1107
if (Attribute->appliesToDecl(D, Rule)) {
1108
Applies = true;
1109
break;
1110
}
1111
}
1112
if (!Applies)
1113
continue;
1114
Entry.IsUsed = true;
1115
PragmaAttributeCurrentTargetDecl = D;
1116
ParsedAttributesView Attrs;
1117
Attrs.addAtEnd(Attribute);
1118
ProcessDeclAttributeList(S, D, Attrs);
1119
PragmaAttributeCurrentTargetDecl = nullptr;
1120
}
1121
}
1122
}
1123
1124
void Sema::PrintPragmaAttributeInstantiationPoint() {
1125
assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
1126
Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
1127
diag::note_pragma_attribute_applied_decl_here);
1128
}
1129
1130
void Sema::DiagnoseUnterminatedPragmaAttribute() {
1131
if (PragmaAttributeStack.empty())
1132
return;
1133
Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
1134
}
1135
1136
void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
1137
if(On)
1138
OptimizeOffPragmaLocation = SourceLocation();
1139
else
1140
OptimizeOffPragmaLocation = PragmaLoc;
1141
}
1142
1143
void Sema::ActOnPragmaMSOptimize(SourceLocation Loc, bool IsOn) {
1144
if (!CurContext->getRedeclContext()->isFileContext()) {
1145
Diag(Loc, diag::err_pragma_expected_file_scope) << "optimize";
1146
return;
1147
}
1148
1149
MSPragmaOptimizeIsOn = IsOn;
1150
}
1151
1152
void Sema::ActOnPragmaMSFunction(
1153
SourceLocation Loc, const llvm::SmallVectorImpl<StringRef> &NoBuiltins) {
1154
if (!CurContext->getRedeclContext()->isFileContext()) {
1155
Diag(Loc, diag::err_pragma_expected_file_scope) << "function";
1156
return;
1157
}
1158
1159
MSFunctionNoBuiltins.insert(NoBuiltins.begin(), NoBuiltins.end());
1160
}
1161
1162
void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
1163
// In the future, check other pragmas if they're implemented (e.g. pragma
1164
// optimize 0 will probably map to this functionality too).
1165
if(OptimizeOffPragmaLocation.isValid())
1166
AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
1167
}
1168
1169
void Sema::AddSectionMSAllocText(FunctionDecl *FD) {
1170
if (!FD->getIdentifier())
1171
return;
1172
1173
StringRef Name = FD->getName();
1174
auto It = FunctionToSectionMap.find(Name);
1175
if (It != FunctionToSectionMap.end()) {
1176
StringRef Section;
1177
SourceLocation Loc;
1178
std::tie(Section, Loc) = It->second;
1179
1180
if (!FD->hasAttr<SectionAttr>())
1181
FD->addAttr(SectionAttr::CreateImplicit(Context, Section));
1182
}
1183
}
1184
1185
void Sema::ModifyFnAttributesMSPragmaOptimize(FunctionDecl *FD) {
1186
// Don't modify the function attributes if it's "on". "on" resets the
1187
// optimizations to the ones listed on the command line
1188
if (!MSPragmaOptimizeIsOn)
1189
AddOptnoneAttributeIfNoConflicts(FD, FD->getBeginLoc());
1190
}
1191
1192
void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD,
1193
SourceLocation Loc) {
1194
// Don't add a conflicting attribute. No diagnostic is needed.
1195
if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>())
1196
return;
1197
1198
// Add attributes only if required. Optnone requires noinline as well, but if
1199
// either is already present then don't bother adding them.
1200
if (!FD->hasAttr<OptimizeNoneAttr>())
1201
FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
1202
if (!FD->hasAttr<NoInlineAttr>())
1203
FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
1204
}
1205
1206
void Sema::AddImplicitMSFunctionNoBuiltinAttr(FunctionDecl *FD) {
1207
SmallVector<StringRef> V(MSFunctionNoBuiltins.begin(),
1208
MSFunctionNoBuiltins.end());
1209
if (!MSFunctionNoBuiltins.empty())
1210
FD->addAttr(NoBuiltinAttr::CreateImplicit(Context, V.data(), V.size()));
1211
}
1212
1213
typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
1214
enum : unsigned { NoVisibility = ~0U };
1215
1216
void Sema::AddPushedVisibilityAttribute(Decl *D) {
1217
if (!VisContext)
1218
return;
1219
1220
NamedDecl *ND = dyn_cast<NamedDecl>(D);
1221
if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue))
1222
return;
1223
1224
VisStack *Stack = static_cast<VisStack*>(VisContext);
1225
unsigned rawType = Stack->back().first;
1226
if (rawType == NoVisibility) return;
1227
1228
VisibilityAttr::VisibilityType type
1229
= (VisibilityAttr::VisibilityType) rawType;
1230
SourceLocation loc = Stack->back().second;
1231
1232
D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
1233
}
1234
1235
void Sema::FreeVisContext() {
1236
delete static_cast<VisStack*>(VisContext);
1237
VisContext = nullptr;
1238
}
1239
1240
static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
1241
// Put visibility on stack.
1242
if (!S.VisContext)
1243
S.VisContext = new VisStack;
1244
1245
VisStack *Stack = static_cast<VisStack*>(S.VisContext);
1246
Stack->push_back(std::make_pair(type, loc));
1247
}
1248
1249
void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
1250
SourceLocation PragmaLoc) {
1251
if (VisType) {
1252
// Compute visibility to use.
1253
VisibilityAttr::VisibilityType T;
1254
if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
1255
Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
1256
return;
1257
}
1258
PushPragmaVisibility(*this, T, PragmaLoc);
1259
} else {
1260
PopPragmaVisibility(false, PragmaLoc);
1261
}
1262
}
1263
1264
void Sema::ActOnPragmaFPContract(SourceLocation Loc,
1265
LangOptions::FPModeKind FPC) {
1266
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1267
switch (FPC) {
1268
case LangOptions::FPM_On:
1269
NewFPFeatures.setAllowFPContractWithinStatement();
1270
break;
1271
case LangOptions::FPM_Fast:
1272
NewFPFeatures.setAllowFPContractAcrossStatement();
1273
break;
1274
case LangOptions::FPM_Off:
1275
NewFPFeatures.setDisallowFPContract();
1276
break;
1277
case LangOptions::FPM_FastHonorPragmas:
1278
llvm_unreachable("Should not happen");
1279
}
1280
FpPragmaStack.Act(Loc, Sema::PSK_Set, StringRef(), NewFPFeatures);
1281
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1282
}
1283
1284
void Sema::ActOnPragmaFPValueChangingOption(SourceLocation Loc,
1285
PragmaFPKind Kind, bool IsEnabled) {
1286
if (IsEnabled) {
1287
// For value unsafe context, combining this pragma with eval method
1288
// setting is not recommended. See comment in function FixupInvocation#506.
1289
int Reason = -1;
1290
if (getLangOpts().getFPEvalMethod() != LangOptions::FEM_UnsetOnCommandLine)
1291
// Eval method set using the option 'ffp-eval-method'.
1292
Reason = 1;
1293
if (PP.getLastFPEvalPragmaLocation().isValid())
1294
// Eval method set using the '#pragma clang fp eval_method'.
1295
// We could have both an option and a pragma used to the set the eval
1296
// method. The pragma overrides the option in the command line. The Reason
1297
// of the diagnostic is overriden too.
1298
Reason = 0;
1299
if (Reason != -1)
1300
Diag(Loc, diag::err_setting_eval_method_used_in_unsafe_context)
1301
<< Reason << (Kind == PFK_Reassociate ? 4 : 5);
1302
}
1303
1304
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1305
switch (Kind) {
1306
case PFK_Reassociate:
1307
NewFPFeatures.setAllowFPReassociateOverride(IsEnabled);
1308
break;
1309
case PFK_Reciprocal:
1310
NewFPFeatures.setAllowReciprocalOverride(IsEnabled);
1311
break;
1312
default:
1313
llvm_unreachable("unhandled value changing pragma fp");
1314
}
1315
1316
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1317
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1318
}
1319
1320
void Sema::ActOnPragmaFEnvRound(SourceLocation Loc, llvm::RoundingMode FPR) {
1321
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1322
NewFPFeatures.setConstRoundingModeOverride(FPR);
1323
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1324
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1325
}
1326
1327
void Sema::setExceptionMode(SourceLocation Loc,
1328
LangOptions::FPExceptionModeKind FPE) {
1329
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1330
NewFPFeatures.setSpecifiedExceptionModeOverride(FPE);
1331
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1332
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1333
}
1334
1335
void Sema::ActOnPragmaFEnvAccess(SourceLocation Loc, bool IsEnabled) {
1336
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1337
if (IsEnabled) {
1338
// Verify Microsoft restriction:
1339
// You can't enable fenv_access unless precise semantics are enabled.
1340
// Precise semantics can be enabled either by the float_control
1341
// pragma, or by using the /fp:precise or /fp:strict compiler options
1342
if (!isPreciseFPEnabled())
1343
Diag(Loc, diag::err_pragma_fenv_requires_precise);
1344
}
1345
NewFPFeatures.setAllowFEnvAccessOverride(IsEnabled);
1346
NewFPFeatures.setRoundingMathOverride(IsEnabled);
1347
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1348
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1349
}
1350
1351
void Sema::ActOnPragmaCXLimitedRange(SourceLocation Loc,
1352
LangOptions::ComplexRangeKind Range) {
1353
FPOptionsOverride NewFPFeatures = CurFPFeatureOverrides();
1354
NewFPFeatures.setComplexRangeOverride(Range);
1355
FpPragmaStack.Act(Loc, PSK_Set, StringRef(), NewFPFeatures);
1356
CurFPFeatures = NewFPFeatures.applyOverrides(getLangOpts());
1357
}
1358
1359
void Sema::ActOnPragmaFPExceptions(SourceLocation Loc,
1360
LangOptions::FPExceptionModeKind FPE) {
1361
setExceptionMode(Loc, FPE);
1362
}
1363
1364
void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
1365
SourceLocation Loc) {
1366
// Visibility calculations will consider the namespace's visibility.
1367
// Here we just want to note that we're in a visibility context
1368
// which overrides any enclosing #pragma context, but doesn't itself
1369
// contribute visibility.
1370
PushPragmaVisibility(*this, NoVisibility, Loc);
1371
}
1372
1373
void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
1374
if (!VisContext) {
1375
Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1376
return;
1377
}
1378
1379
// Pop visibility from stack
1380
VisStack *Stack = static_cast<VisStack*>(VisContext);
1381
1382
const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
1383
bool StartsWithPragma = Back->first != NoVisibility;
1384
if (StartsWithPragma && IsNamespaceEnd) {
1385
Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
1386
Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
1387
1388
// For better error recovery, eat all pushes inside the namespace.
1389
do {
1390
Stack->pop_back();
1391
Back = &Stack->back();
1392
StartsWithPragma = Back->first != NoVisibility;
1393
} while (StartsWithPragma);
1394
} else if (!StartsWithPragma && !IsNamespaceEnd) {
1395
Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
1396
Diag(Back->second, diag::note_surrounding_namespace_starts_here);
1397
return;
1398
}
1399
1400
Stack->pop_back();
1401
// To simplify the implementation, never keep around an empty stack.
1402
if (Stack->empty())
1403
FreeVisContext();
1404
}
1405
1406
template <typename Ty>
1407
static bool checkCommonAttributeFeatures(Sema &S, const Ty *Node,
1408
const ParsedAttr &A,
1409
bool SkipArgCountCheck) {
1410
// Several attributes carry different semantics than the parsing requires, so
1411
// those are opted out of the common argument checks.
1412
//
1413
// We also bail on unknown and ignored attributes because those are handled
1414
// as part of the target-specific handling logic.
1415
if (A.getKind() == ParsedAttr::UnknownAttribute)
1416
return false;
1417
// Check whether the attribute requires specific language extensions to be
1418
// enabled.
1419
if (!A.diagnoseLangOpts(S))
1420
return true;
1421
// Check whether the attribute appertains to the given subject.
1422
if (!A.diagnoseAppertainsTo(S, Node))
1423
return true;
1424
// Check whether the attribute is mutually exclusive with other attributes
1425
// that have already been applied to the declaration.
1426
if (!A.diagnoseMutualExclusion(S, Node))
1427
return true;
1428
// Check whether the attribute exists in the target architecture.
1429
if (S.CheckAttrTarget(A))
1430
return true;
1431
1432
if (A.hasCustomParsing())
1433
return false;
1434
1435
if (!SkipArgCountCheck) {
1436
if (A.getMinArgs() == A.getMaxArgs()) {
1437
// If there are no optional arguments, then checking for the argument
1438
// count is trivial.
1439
if (!A.checkExactlyNumArgs(S, A.getMinArgs()))
1440
return true;
1441
} else {
1442
// There are optional arguments, so checking is slightly more involved.
1443
if (A.getMinArgs() && !A.checkAtLeastNumArgs(S, A.getMinArgs()))
1444
return true;
1445
else if (!A.hasVariadicArg() && A.getMaxArgs() &&
1446
!A.checkAtMostNumArgs(S, A.getMaxArgs()))
1447
return true;
1448
}
1449
}
1450
1451
return false;
1452
}
1453
1454
bool Sema::checkCommonAttributeFeatures(const Decl *D, const ParsedAttr &A,
1455
bool SkipArgCountCheck) {
1456
return ::checkCommonAttributeFeatures(*this, D, A, SkipArgCountCheck);
1457
}
1458
bool Sema::checkCommonAttributeFeatures(const Stmt *S, const ParsedAttr &A,
1459
bool SkipArgCountCheck) {
1460
return ::checkCommonAttributeFeatures(*this, S, A, SkipArgCountCheck);
1461
}
1462
1463