Coverage Report

Created: 2020-02-15 09:57

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Sema/SemaAttr.cpp
Line
Count
Source (jump to first uncovered line)
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
using namespace clang;
22
23
//===----------------------------------------------------------------------===//
24
// Pragma 'pack' and 'options align'
25
//===----------------------------------------------------------------------===//
26
27
Sema::PragmaStackSentinelRAII::PragmaStackSentinelRAII(Sema &S,
28
                                                       StringRef SlotLabel,
29
                                                       bool ShouldAct)
30
2.74M
    : S(S), SlotLabel(SlotLabel), ShouldAct(ShouldAct) {
31
2.74M
  if (ShouldAct) {
32
599k
    S.VtorDispStack.SentinelAction(PSK_Push, SlotLabel);
33
599k
    S.DataSegStack.SentinelAction(PSK_Push, SlotLabel);
34
599k
    S.BSSSegStack.SentinelAction(PSK_Push, SlotLabel);
35
599k
    S.ConstSegStack.SentinelAction(PSK_Push, SlotLabel);
36
599k
    S.CodeSegStack.SentinelAction(PSK_Push, SlotLabel);
37
599k
  }
38
2.74M
}
39
40
2.74M
Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() {
41
2.74M
  if (ShouldAct) {
42
599k
    S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel);
43
599k
    S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel);
44
599k
    S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel);
45
599k
    S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel);
46
599k
    S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel);
47
599k
  }
48
2.74M
}
49
50
1.01M
void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) {
51
1.01M
  // If there is no pack value, we don't need any attributes.
52
1.01M
  if (!PackStack.CurrentValue)
53
828k
    return;
54
182k
55
182k
  // Otherwise, check to see if we need a max field alignment attribute.
56
182k
  if (unsigned Alignment = PackStack.CurrentValue) {
57
182k
    if (Alignment == Sema::kMac68kAlignmentSentinel)
58
13
      RD->addAttr(AlignMac68kAttr::CreateImplicit(Context));
59
182k
    else
60
182k
      RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context,
61
182k
                                                        Alignment * 8));
62
182k
  }
63
182k
  if (PackIncludeStack.empty())
64
340
    return;
65
182k
  // The #pragma pack affected a record in an included file,  so Clang should
66
182k
  // warn when that pragma was written in a file that included the included
67
182k
  // file.
68
182k
  
for (auto &PackedInclude : llvm::reverse(PackIncludeStack))182k
{
69
182k
    if (PackedInclude.CurrentPragmaLocation != PackStack.CurrentPragmaLocation)
70
182k
      break;
71
17
    if (PackedInclude.HasNonDefaultValue)
72
13
      PackedInclude.ShouldWarnOnInclude = true;
73
17
  }
74
182k
}
75
76
1.01M
void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) {
77
1.01M
  if (MSStructPragmaOn)
78
21
    RD->addAttr(MSStructAttr::CreateImplicit(Context));
79
1.01M
80
1.01M
  // FIXME: We should merge AddAlignmentAttributesForRecord with
81
1.01M
  // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes
82
1.01M
  // all active pragmas and applies them as attributes to class definitions.
83
1.01M
  if (VtorDispStack.CurrentValue != getLangOpts().getVtorDispMode())
84
29
    RD->addAttr(MSVtorDispAttr::CreateImplicit(
85
29
        Context, unsigned(VtorDispStack.CurrentValue)));
86
1.01M
}
87
88
template <typename Attribute>
89
static void addGslOwnerPointerAttributeIfNotExisting(ASTContext &Context,
90
9.43k
                                                     CXXRecordDecl *Record) {
91
9.43k
  if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
92
2.78k
    return;
93
6.64k
94
6.64k
  for (Decl *Redecl : Record->redecls())
95
7.28k
    Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
96
6.64k
}
SemaAttr.cpp:void addGslOwnerPointerAttributeIfNotExisting<clang::PointerAttr>(clang::ASTContext&, clang::CXXRecordDecl*)
Line
Count
Source
90
5.90k
                                                     CXXRecordDecl *Record) {
91
5.90k
  if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
92
2.78k
    return;
93
3.11k
94
3.11k
  for (Decl *Redecl : Record->redecls())
95
3.76k
    Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
96
3.11k
}
SemaAttr.cpp:void addGslOwnerPointerAttributeIfNotExisting<clang::OwnerAttr>(clang::ASTContext&, clang::CXXRecordDecl*)
Line
Count
Source
90
3.52k
                                                     CXXRecordDecl *Record) {
91
3.52k
  if (Record->hasAttr<OwnerAttr>() || Record->hasAttr<PointerAttr>())
92
0
    return;
93
3.52k
94
3.52k
  for (Decl *Redecl : Record->redecls())
95
3.52k
    Redecl->addAttr(Attribute::CreateImplicit(Context, /*DerefType=*/nullptr));
96
3.52k
}
97
98
void Sema::inferGslPointerAttribute(NamedDecl *ND,
99
2.38M
                                    CXXRecordDecl *UnderlyingRecord) {
100
2.38M
  if (!UnderlyingRecord)
101
1.89M
    return;
102
499k
103
499k
  const auto *Parent = dyn_cast<CXXRecordDecl>(ND->getDeclContext());
104
499k
  if (!Parent)
105
330k
    return;
106
169k
107
169k
  static llvm::StringSet<> Containers{
108
169k
      "array",
109
169k
      "basic_string",
110
169k
      "deque",
111
169k
      "forward_list",
112
169k
      "vector",
113
169k
      "list",
114
169k
      "map",
115
169k
      "multiset",
116
169k
      "multimap",
117
169k
      "priority_queue",
118
169k
      "queue",
119
169k
      "set",
120
169k
      "stack",
121
169k
      "unordered_set",
122
169k
      "unordered_map",
123
169k
      "unordered_multiset",
124
169k
      "unordered_multimap",
125
169k
  };
126
169k
127
169k
  static llvm::StringSet<> Iterators{"iterator", "const_iterator",
128
169k
                                     "reverse_iterator",
129
169k
                                     "const_reverse_iterator"};
130
169k
131
169k
  if (Parent->isInStdNamespace() && 
Iterators.count(ND->getName())152k
&&
132
169k
      
Containers.count(Parent->getName())6.46k
)
133
5.03k
    addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context,
134
5.03k
                                                          UnderlyingRecord);
135
169k
}
136
137
2.16M
void Sema::inferGslPointerAttribute(TypedefNameDecl *TD) {
138
2.16M
139
2.16M
  QualType Canonical = TD->getUnderlyingType().getCanonicalType();
140
2.16M
141
2.16M
  CXXRecordDecl *RD = Canonical->getAsCXXRecordDecl();
142
2.16M
  if (!RD) {
143
1.95M
    if (auto *TST =
144
61.3k
            dyn_cast<TemplateSpecializationType>(Canonical.getTypePtr())) {
145
61.3k
146
61.3k
      RD = dyn_cast_or_null<CXXRecordDecl>(
147
61.3k
          TST->getTemplateName().getAsTemplateDecl()->getTemplatedDecl());
148
61.3k
    }
149
1.95M
  }
150
2.16M
151
2.16M
  inferGslPointerAttribute(TD, RD);
152
2.16M
}
153
154
508k
void Sema::inferGslOwnerPointerAttribute(CXXRecordDecl *Record) {
155
508k
  static llvm::StringSet<> StdOwners{
156
508k
      "any",
157
508k
      "array",
158
508k
      "basic_regex",
159
508k
      "basic_string",
160
508k
      "deque",
161
508k
      "forward_list",
162
508k
      "vector",
163
508k
      "list",
164
508k
      "map",
165
508k
      "multiset",
166
508k
      "multimap",
167
508k
      "optional",
168
508k
      "priority_queue",
169
508k
      "queue",
170
508k
      "set",
171
508k
      "stack",
172
508k
      "unique_ptr",
173
508k
      "unordered_set",
174
508k
      "unordered_map",
175
508k
      "unordered_multiset",
176
508k
      "unordered_multimap",
177
508k
      "variant",
178
508k
  };
179
508k
  static llvm::StringSet<> StdPointers{
180
508k
      "basic_string_view",
181
508k
      "reference_wrapper",
182
508k
      "regex_iterator",
183
508k
  };
184
508k
185
508k
  if (!Record->getIdentifier())
186
33.9k
    return;
187
474k
188
474k
  // Handle classes that directly appear in std namespace.
189
474k
  if (Record->isInStdNamespace()) {
190
247k
    if (Record->hasAttr<OwnerAttr>() || 
Record->hasAttr<PointerAttr>()245k
)
191
2.57k
      return;
192
244k
193
244k
    if (StdOwners.count(Record->getName()))
194
3.52k
      addGslOwnerPointerAttributeIfNotExisting<OwnerAttr>(Context, Record);
195
241k
    else if (StdPointers.count(Record->getName()))
196
876
      addGslOwnerPointerAttributeIfNotExisting<PointerAttr>(Context, Record);
197
244k
198
244k
    return;
199
244k
  }
200
227k
201
227k
  // Handle nested classes that could be a gsl::Pointer.
202
227k
  inferGslPointerAttribute(Record, Record);
203
227k
}
204
205
void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind,
206
3.57k
                                   SourceLocation PragmaLoc) {
207
3.57k
  PragmaMsStackAction Action = Sema::PSK_Reset;
208
3.57k
  unsigned Alignment = 0;
209
3.57k
  switch (Kind) {
210
0
    // For all targets we support native and natural are the same.
211
0
    //
212
0
    // FIXME: This is not true on Darwin/PPC.
213
1.75k
  case POAK_Native:
214
1.75k
  case POAK_Power:
215
1.75k
  case POAK_Natural:
216
1.75k
    Action = Sema::PSK_Push_Set;
217
1.75k
    Alignment = 0;
218
1.75k
    break;
219
1.75k
220
1.75k
    // Note that '#pragma options align=packed' is not equivalent to attribute
221
1.75k
    // packed, it has a different precedence relative to attribute aligned.
222
1.75k
  case POAK_Packed:
223
9
    Action = Sema::PSK_Push_Set;
224
9
    Alignment = 1;
225
9
    break;
226
1.75k
227
1.75k
  case POAK_Mac68k:
228
7
    // Check if the target supports this.
229
7
    if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) {
230
2
      Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported);
231
2
      return;
232
2
    }
233
5
    Action = Sema::PSK_Push_Set;
234
5
    Alignment = Sema::kMac68kAlignmentSentinel;
235
5
    break;
236
5
237
1.80k
  case POAK_Reset:
238
1.80k
    // Reset just pops the top of the stack, or resets the current alignment to
239
1.80k
    // default.
240
1.80k
    Action = Sema::PSK_Pop;
241
1.80k
    if (PackStack.Stack.empty()) {
242
44
      if (PackStack.CurrentValue) {
243
43
        Action = Sema::PSK_Reset;
244
43
      } else {
245
1
        Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed)
246
1
            << "stack empty";
247
1
        return;
248
1
      }
249
1.80k
    }
250
1.80k
    break;
251
3.57k
  }
252
3.57k
253
3.57k
  PackStack.Act(PragmaLoc, Action, StringRef(), Alignment);
254
3.57k
}
255
256
void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionAction Action,
257
53
                                   PragmaClangSectionKind SecKind, StringRef SecName) {
258
53
  PragmaClangSection *CSec;
259
53
  switch (SecKind) {
260
14
    case PragmaClangSectionKind::PCSK_BSS:
261
14
      CSec = &PragmaClangBSSSection;
262
14
      break;
263
11
    case PragmaClangSectionKind::PCSK_Data:
264
11
      CSec = &PragmaClangDataSection;
265
11
      break;
266
13
    case PragmaClangSectionKind::PCSK_Rodata:
267
13
      CSec = &PragmaClangRodataSection;
268
13
      break;
269
1
    case PragmaClangSectionKind::PCSK_Relro:
270
1
      CSec = &PragmaClangRelroSection;
271
1
      break;
272
14
    case PragmaClangSectionKind::PCSK_Text:
273
14
      CSec = &PragmaClangTextSection;
274
14
      break;
275
0
    default:
276
0
      llvm_unreachable("invalid clang section kind");
277
53
  }
278
53
279
53
  if (Action == PragmaClangSectionAction::PCSA_Clear) {
280
26
    CSec->Valid = false;
281
26
    return;
282
26
  }
283
27
284
27
  CSec->Valid = true;
285
27
  CSec->SectionName = std::string(SecName);
286
27
  CSec->PragmaLocation = PragmaLoc;
287
27
}
288
289
void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action,
290
84.3k
                           StringRef SlotLabel, Expr *alignment) {
291
84.3k
  Expr *Alignment = static_cast<Expr *>(alignment);
292
84.3k
293
84.3k
  // If specified then alignment must be a "small" power of two.
294
84.3k
  unsigned AlignmentVal = 0;
295
84.3k
  if (Alignment) {
296
42.2k
    llvm::APSInt Val;
297
42.2k
298
42.2k
    // pack(0) is like pack(), which just works out since that is what
299
42.2k
    // we use 0 for in PackAttr.
300
42.2k
    if (Alignment->isTypeDependent() ||
301
42.2k
        Alignment->isValueDependent() ||
302
42.2k
        !Alignment->isIntegerConstantExpr(Val, Context) ||
303
42.2k
        !(Val == 0 || 
Val.isPowerOf2()42.2k
) ||
304
42.2k
        
Val.getZExtValue() > 1642.2k
) {
305
1
      Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment);
306
1
      return; // Ignore
307
1
    }
308
42.2k
309
42.2k
    AlignmentVal = (unsigned) Val.getZExtValue();
310
42.2k
  }
311
84.3k
  
if (84.3k
Action == Sema::PSK_Show84.3k
) {
312
40
    // Show the current alignment, making sure to show the right value
313
40
    // for the default.
314
40
    // FIXME: This should come from the target.
315
40
    AlignmentVal = PackStack.CurrentValue;
316
40
    if (AlignmentVal == 0)
317
20
      AlignmentVal = 8;
318
40
    if (AlignmentVal == Sema::kMac68kAlignmentSentinel)
319
0
      Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k";
320
40
    else
321
40
      Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal;
322
40
  }
323
84.3k
  // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack:
324
84.3k
  // "#pragma pack(pop, identifier, n) is undefined"
325
84.3k
  if (Action & Sema::PSK_Pop) {
326
20.2k
    if (Alignment && 
!SlotLabel.empty()1
)
327
0
      Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifier_and_alignment);
328
20.2k
    if (PackStack.Stack.empty())
329
12
      Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty";
330
20.2k
  }
331
84.3k
332
84.3k
  PackStack.Act(PragmaLoc, Action, SlotLabel, AlignmentVal);
333
84.3k
}
334
335
void Sema::DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind,
336
974k
                                        SourceLocation IncludeLoc) {
337
974k
  if (Kind == PragmaPackDiagnoseKind::NonDefaultStateAtInclude) {
338
487k
    SourceLocation PrevLocation = PackStack.CurrentPragmaLocation;
339
487k
    // Warn about non-default alignment at #includes (without redundant
340
487k
    // warnings for the same directive in nested includes).
341
487k
    // The warning is delayed until the end of the file to avoid warnings
342
487k
    // for files that don't have any records that are affected by the modified
343
487k
    // alignment.
344
487k
    bool HasNonDefaultValue =
345
487k
        PackStack.hasValue() &&
346
487k
        
(19
PackIncludeStack.empty()19
||
347
19
         
PackIncludeStack.back().CurrentPragmaLocation != PrevLocation9
);
348
487k
    PackIncludeStack.push_back(
349
487k
        {PackStack.CurrentValue,
350
487k
         PackStack.hasValue() ? 
PrevLocation19
:
SourceLocation()487k
,
351
487k
         HasNonDefaultValue, /*ShouldWarnOnInclude*/ false});
352
487k
    return;
353
487k
  }
354
487k
355
487k
  assert(Kind == PragmaPackDiagnoseKind::ChangedStateAtExit && "invalid kind");
356
487k
  PackIncludeState PrevPackState = PackIncludeStack.pop_back_val();
357
487k
  if (PrevPackState.ShouldWarnOnInclude) {
358
11
    // Emit the delayed non-default alignment at #include warning.
359
11
    Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include);
360
11
    Diag(PrevPackState.CurrentPragmaLocation, diag::note_pragma_pack_here);
361
11
  }
362
487k
  // Warn about modified alignment after #includes.
363
487k
  if (PrevPackState.CurrentValue != PackStack.CurrentValue) {
364
13
    Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include);
365
13
    Diag(PackStack.CurrentPragmaLocation, diag::note_pragma_pack_here);
366
13
  }
367
487k
}
368
369
51.7k
void Sema::DiagnoseUnterminatedPragmaPack() {
370
51.7k
  if (PackStack.Stack.empty())
371
51.6k
    return;
372
25
  bool IsInnermost = true;
373
32
  for (const auto &StackSlot : llvm::reverse(PackStack.Stack)) {
374
32
    Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof);
375
32
    // The user might have already reset the alignment, so suggest replacing
376
32
    // the reset with a pop.
377
32
    if (IsInnermost && 
PackStack.CurrentValue == PackStack.DefaultValue24
) {
378
5
      DiagnosticBuilder DB = Diag(PackStack.CurrentPragmaLocation,
379
5
                                  diag::note_pragma_pack_pop_instead_reset);
380
5
      SourceLocation FixItLoc = Lexer::findLocationAfterToken(
381
5
          PackStack.CurrentPragmaLocation, tok::l_paren, SourceMgr, LangOpts,
382
5
          /*SkipTrailing=*/false);
383
5
      if (FixItLoc.isValid())
384
4
        DB << FixItHint::CreateInsertion(FixItLoc, "pop");
385
5
    }
386
32
    IsInnermost = false;
387
32
  }
388
25
}
389
390
2.98k
void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) {
391
2.98k
  MSStructPragmaOn = (Kind == PMSST_ON);
392
2.98k
}
393
394
void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc,
395
56
                                PragmaMSCommentKind Kind, StringRef Arg) {
396
56
  auto *PCD = PragmaCommentDecl::Create(
397
56
      Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg);
398
56
  Context.getTranslationUnitDecl()->addDecl(PCD);
399
56
  Consumer.HandleTopLevelDecl(DeclGroupRef(PCD));
400
56
}
401
402
void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name,
403
16
                                     StringRef Value) {
404
16
  auto *PDMD = PragmaDetectMismatchDecl::Create(
405
16
      Context, Context.getTranslationUnitDecl(), Loc, Name, Value);
406
16
  Context.getTranslationUnitDecl()->addDecl(PDMD);
407
16
  Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD));
408
16
}
409
410
void Sema::ActOnPragmaMSPointersToMembers(
411
    LangOptions::PragmaMSPointersToMembersKind RepresentationMethod,
412
26
    SourceLocation PragmaLoc) {
413
26
  MSPointerToMemberRepresentationMethod = RepresentationMethod;
414
26
  ImplicitMSInheritanceAttrLoc = PragmaLoc;
415
26
}
416
417
void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action,
418
                                 SourceLocation PragmaLoc,
419
45
                                 MSVtorDispMode Mode) {
420
45
  if (Action & PSK_Pop && 
VtorDispStack.Stack.empty()20
)
421
4
    Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp"
422
4
                                                  << "stack empty";
423
45
  VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode);
424
45
}
425
426
template<typename ValueType>
427
void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation,
428
                                       PragmaMsStackAction Action,
429
                                       llvm::StringRef StackSlotLabel,
430
6.08M
                                       ValueType Value) {
431
6.08M
  if (Action == PSK_Reset) {
432
21.8k
    CurrentValue = DefaultValue;
433
21.8k
    CurrentPragmaLocation = PragmaLocation;
434
21.8k
    return;
435
21.8k
  }
436
6.06M
  if (Action & PSK_Push)
437
3.02M
    Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
438
3.02M
                       PragmaLocation);
439
3.04M
  else if (Action & PSK_Pop) {
440
3.02M
    if (!StackSlotLabel.empty()) {
441
2.99M
      // If we've got a label, try to find it and jump there.
442
2.99M
      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443
2.99M
        return x.StackSlotLabel == StackSlotLabel;
444
2.99M
      });
clang::Sema::PragmaStack<unsigned int>::Act(clang::SourceLocation, clang::Sema::PragmaMsStackAction, llvm::StringRef, unsigned int)::'lambda'(clang::Sema::PragmaStack<unsigned int>::Slot const&)::operator()(clang::Sema::PragmaStack<unsigned int>::Slot const&) const
Line
Count
Source
442
10
      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443
10
        return x.StackSlotLabel == StackSlotLabel;
444
10
      });
clang::Sema::PragmaStack<clang::MSVtorDispMode>::Act(clang::SourceLocation, clang::Sema::PragmaMsStackAction, llvm::StringRef, clang::MSVtorDispMode)::'lambda'(clang::Sema::PragmaStack<clang::MSVtorDispMode>::Slot const&)::operator()(clang::Sema::PragmaStack<clang::MSVtorDispMode>::Slot const&) const
Line
Count
Source
442
599k
      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443
599k
        return x.StackSlotLabel == StackSlotLabel;
444
599k
      });
clang::Sema::PragmaStack<clang::StringLiteral*>::Act(clang::SourceLocation, clang::Sema::PragmaMsStackAction, llvm::StringRef, clang::StringLiteral*)::'lambda'(clang::Sema::PragmaStack<clang::StringLiteral*>::Slot const&)::operator()(clang::Sema::PragmaStack<clang::StringLiteral*>::Slot const&) const
Line
Count
Source
442
2.39M
      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443
2.39M
        return x.StackSlotLabel == StackSlotLabel;
444
2.39M
      });
445
2.99M
      // If we found the label so pop from there.
446
2.99M
      if (I != Stack.rend()) {
447
2.99M
        CurrentValue = I->Value;
448
2.99M
        CurrentPragmaLocation = I->PragmaLocation;
449
2.99M
        Stack.erase(std::prev(I.base()), Stack.end());
450
2.99M
      }
451
2.99M
    } else 
if (22.0k
!Stack.empty()22.0k
) {
452
22.0k
      // We do not have a label, just pop the last entry.
453
22.0k
      CurrentValue = Stack.back().Value;
454
22.0k
      CurrentPragmaLocation = Stack.back().PragmaLocation;
455
22.0k
      Stack.pop_back();
456
22.0k
    }
457
3.02M
  }
458
6.06M
  if (Action & PSK_Set) {
459
44.0k
    CurrentValue = Value;
460
44.0k
    CurrentPragmaLocation = PragmaLocation;
461
44.0k
  }
462
6.06M
}
clang::Sema::PragmaStack<unsigned int>::Act(clang::SourceLocation, clang::Sema::PragmaMsStackAction, llvm::StringRef, unsigned int)
Line
Count
Source
430
87.8k
                                       ValueType Value) {
431
87.8k
  if (Action == PSK_Reset) {
432
21.8k
    CurrentValue = DefaultValue;
433
21.8k
    CurrentPragmaLocation = PragmaLocation;
434
21.8k
    return;
435
21.8k
  }
436
66.0k
  if (Action & PSK_Push)
437
22.0k
    Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
438
22.0k
                       PragmaLocation);
439
44.0k
  else if (Action & PSK_Pop) {
440
22.0k
    if (!StackSlotLabel.empty()) {
441
9
      // If we've got a label, try to find it and jump there.
442
9
      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443
9
        return x.StackSlotLabel == StackSlotLabel;
444
9
      });
445
9
      // If we found the label so pop from there.
446
9
      if (I != Stack.rend()) {
447
5
        CurrentValue = I->Value;
448
5
        CurrentPragmaLocation = I->PragmaLocation;
449
5
        Stack.erase(std::prev(I.base()), Stack.end());
450
5
      }
451
22.0k
    } else if (!Stack.empty()) {
452
22.0k
      // We do not have a label, just pop the last entry.
453
22.0k
      CurrentValue = Stack.back().Value;
454
22.0k
      CurrentPragmaLocation = Stack.back().PragmaLocation;
455
22.0k
      Stack.pop_back();
456
22.0k
    }
457
22.0k
  }
458
66.0k
  if (Action & PSK_Set) {
459
43.9k
    CurrentValue = Value;
460
43.9k
    CurrentPragmaLocation = PragmaLocation;
461
43.9k
  }
462
66.0k
}
clang::Sema::PragmaStack<clang::MSVtorDispMode>::Act(clang::SourceLocation, clang::Sema::PragmaMsStackAction, llvm::StringRef, clang::MSVtorDispMode)
Line
Count
Source
430
1.19M
                                       ValueType Value) {
431
1.19M
  if (Action == PSK_Reset) {
432
3
    CurrentValue = DefaultValue;
433
3
    CurrentPragmaLocation = PragmaLocation;
434
3
    return;
435
3
  }
436
1.19M
  if (Action & PSK_Push)
437
599k
    Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
438
599k
                       PragmaLocation);
439
599k
  else if (Action & PSK_Pop) {
440
599k
    if (!StackSlotLabel.empty()) {
441
599k
      // If we've got a label, try to find it and jump there.
442
599k
      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443
599k
        return x.StackSlotLabel == StackSlotLabel;
444
599k
      });
445
599k
      // If we found the label so pop from there.
446
599k
      if (I != Stack.rend()) {
447
599k
        CurrentValue = I->Value;
448
599k
        CurrentPragmaLocation = I->PragmaLocation;
449
599k
        Stack.erase(std::prev(I.base()), Stack.end());
450
599k
      }
451
599k
    } else 
if (20
!Stack.empty()20
) {
452
16
      // We do not have a label, just pop the last entry.
453
16
      CurrentValue = Stack.back().Value;
454
16
      CurrentPragmaLocation = Stack.back().PragmaLocation;
455
16
      Stack.pop_back();
456
16
    }
457
599k
  }
458
1.19M
  if (Action & PSK_Set) {
459
22
    CurrentValue = Value;
460
22
    CurrentPragmaLocation = PragmaLocation;
461
22
  }
462
1.19M
}
clang::Sema::PragmaStack<clang::StringLiteral*>::Act(clang::SourceLocation, clang::Sema::PragmaMsStackAction, llvm::StringRef, clang::StringLiteral*)
Line
Count
Source
430
4.79M
                                       ValueType Value) {
431
4.79M
  if (Action == PSK_Reset) {
432
4
    CurrentValue = DefaultValue;
433
4
    CurrentPragmaLocation = PragmaLocation;
434
4
    return;
435
4
  }
436
4.79M
  if (Action & PSK_Push)
437
2.39M
    Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation,
438
2.39M
                       PragmaLocation);
439
2.39M
  else if (Action & PSK_Pop) {
440
2.39M
    if (!StackSlotLabel.empty()) {
441
2.39M
      // If we've got a label, try to find it and jump there.
442
2.39M
      auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) {
443
2.39M
        return x.StackSlotLabel == StackSlotLabel;
444
2.39M
      });
445
2.39M
      // If we found the label so pop from there.
446
2.39M
      if (I != Stack.rend()) {
447
2.39M
        CurrentValue = I->Value;
448
2.39M
        CurrentPragmaLocation = I->PragmaLocation;
449
2.39M
        Stack.erase(std::prev(I.base()), Stack.end());
450
2.39M
      }
451
2.39M
    } else 
if (6
!Stack.empty()6
) {
452
6
      // We do not have a label, just pop the last entry.
453
6
      CurrentValue = Stack.back().Value;
454
6
      CurrentPragmaLocation = Stack.back().PragmaLocation;
455
6
      Stack.pop_back();
456
6
    }
457
2.39M
  }
458
4.79M
  if (Action & PSK_Set) {
459
44
    CurrentValue = Value;
460
44
    CurrentPragmaLocation = PragmaLocation;
461
44
  }
462
4.79M
}
463
464
bool Sema::UnifySection(StringRef SectionName,
465
                        int SectionFlags,
466
1.24k
                        DeclaratorDecl *Decl) {
467
1.24k
  auto Section = Context.SectionInfos.find(SectionName);
468
1.24k
  if (Section == Context.SectionInfos.end()) {
469
58
    Context.SectionInfos[SectionName] =
470
58
        ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags);
471
58
    return false;
472
58
  }
473
1.18k
  // A pre-declared section takes precedence w/o diagnostic.
474
1.18k
  if (Section->second.SectionFlags == SectionFlags ||
475
1.18k
      
!(Section->second.SectionFlags & ASTContext::PSF_Implicit)13
)
476
1.18k
    return false;
477
3
  auto OtherDecl = Section->second.Decl;
478
3
  Diag(Decl->getLocation(), diag::err_section_conflict)
479
3
      << Decl << OtherDecl;
480
3
  Diag(OtherDecl->getLocation(), diag::note_declared_at)
481
3
      << OtherDecl->getName();
482
3
  if (auto A = Decl->getAttr<SectionAttr>())
483
3
    if (A->isImplicit())
484
2
      Diag(A->getLocation(), diag::note_pragma_entered_here);
485
3
  if (auto A = OtherDecl->getAttr<SectionAttr>())
486
3
    if (A->isImplicit())
487
2
      Diag(A->getLocation(), diag::note_pragma_entered_here);
488
3
  return true;
489
3
}
490
491
bool Sema::UnifySection(StringRef SectionName,
492
                        int SectionFlags,
493
22
                        SourceLocation PragmaSectionLocation) {
494
22
  auto Section = Context.SectionInfos.find(SectionName);
495
22
  if (Section != Context.SectionInfos.end()) {
496
2
    if (Section->second.SectionFlags == SectionFlags)
497
0
      return false;
498
2
    if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) {
499
2
      Diag(PragmaSectionLocation, diag::err_section_conflict)
500
2
          << "this" << "a prior #pragma section";
501
2
      Diag(Section->second.PragmaSectionLocation,
502
2
           diag::note_pragma_entered_here);
503
2
      return true;
504
2
    }
505
20
  }
506
20
  Context.SectionInfos[SectionName] =
507
20
      ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags);
508
20
  return false;
509
20
}
510
511
/// Called on well formed \#pragma bss_seg().
512
void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation,
513
                            PragmaMsStackAction Action,
514
                            llvm::StringRef StackSlotLabel,
515
                            StringLiteral *SegmentName,
516
57
                            llvm::StringRef PragmaName) {
517
57
  PragmaStack<StringLiteral *> *Stack =
518
57
    llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName)
519
57
        .Case("data_seg", &DataSegStack)
520
57
        .Case("bss_seg", &BSSSegStack)
521
57
        .Case("const_seg", &ConstSegStack)
522
57
        .Case("code_seg", &CodeSegStack);
523
57
  if (Action & PSK_Pop && 
Stack->Stack.empty()7
)
524
0
    Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName
525
0
        << "stack empty";
526
57
  if (SegmentName) {
527
45
    if (!checkSectionName(SegmentName->getBeginLoc(), SegmentName->getString()))
528
1
      return;
529
44
530
44
    if (SegmentName->getString() == ".drectve" &&
531
44
        
Context.getTargetInfo().getCXXABI().isMicrosoft()4
)
532
4
      Diag(PragmaLocation, diag::warn_attribute_section_drectve) << PragmaName;
533
44
  }
534
57
535
57
  Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName);
536
56
}
537
538
/// Called on well formed \#pragma bss_seg().
539
void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation,
540
22
                                int SectionFlags, StringLiteral *SegmentName) {
541
22
  UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation);
542
22
}
543
544
void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation,
545
21
                                StringLiteral *SegmentName) {
546
21
  // There's no stack to maintain, so we just have a current section.  When we
547
21
  // see the default section, reset our current section back to null so we stop
548
21
  // tacking on unnecessary attributes.
549
21
  CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? 
nullptr1
:
SegmentName20
;
550
21
  CurInitSegLoc = PragmaLocation;
551
21
}
552
553
void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope,
554
25
                             SourceLocation PragmaLoc) {
555
25
556
25
  IdentifierInfo *Name = IdTok.getIdentifierInfo();
557
25
  LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName);
558
25
  LookupParsedName(Lookup, curScope, nullptr, true);
559
25
560
25
  if (Lookup.empty()) {
561
3
    Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var)
562
3
      << Name << SourceRange(IdTok.getLocation());
563
3
    return;
564
3
  }
565
22
566
22
  VarDecl *VD = Lookup.getAsSingle<VarDecl>();
567
22
  if (!VD) {
568
0
    Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg)
569
0
      << Name << SourceRange(IdTok.getLocation());
570
0
    return;
571
0
  }
572
22
573
22
  // Warn if this was used before being marked unused.
574
22
  if (VD->isUsed())
575
1
    Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name;
576
22
577
22
  VD->addAttr(UnusedAttr::CreateImplicit(Context, IdTok.getLocation(),
578
22
                                         AttributeCommonInfo::AS_Pragma,
579
22
                                         UnusedAttr::GNU_unused));
580
22
}
581
582
6.42M
void Sema::AddCFAuditedAttribute(Decl *D) {
583
6.42M
  IdentifierInfo *Ident;
584
6.42M
  SourceLocation Loc;
585
6.42M
  std::tie(Ident, Loc) = PP.getPragmaARCCFCodeAuditedInfo();
586
6.42M
  if (!Loc.isValid()) 
return5.81M
;
587
613k
588
613k
  // Don't add a redundant or conflicting attribute.
589
613k
  if (D->hasAttr<CFAuditedTransferAttr>() ||
590
613k
      
D->hasAttr<CFUnknownTransferAttr>()611k
)
591
1.16k
    return;
592
611k
593
611k
  AttributeCommonInfo Info(Ident, SourceRange(Loc),
594
611k
                           AttributeCommonInfo::AS_Pragma);
595
611k
  D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Info));
596
611k
}
597
598
namespace {
599
600
Optional<attr::SubjectMatchRule>
601
302
getParentAttrMatcherRule(attr::SubjectMatchRule Rule) {
602
302
  using namespace attr;
603
302
  switch (Rule) {
604
206
  default:
605
206
    return None;
606
0
#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
607
0
#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated)    \
608
96
  case Value:                                                                  \
609
96
    return Parent;
610
0
#include "clang/Basic/AttrSubMatchRulesList.inc"
611
302
  }
612
302
}
613
614
57
bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) {
615
57
  using namespace attr;
616
57
  switch (Rule) {
617
4
  default:
618
4
    return false;
619
0
#define ATTR_MATCH_RULE(Value, Spelling, IsAbstract)
620
0
#define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated)    \
621
53
  case Value:                                                                  \
622
53
    return IsNegated;
623
0
#include "clang/Basic/AttrSubMatchRulesList.inc"
624
57
  }
625
57
}
626
627
CharSourceRange replacementRangeForListElement(const Sema &S,
628
38
                                               SourceRange Range) {
629
38
  // Make sure that the ',' is removed as well.
630
38
  SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken(
631
38
      Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(),
632
38
      /*SkipTrailingWhitespaceAndNewLine=*/false);
633
38
  if (AfterCommaLoc.isValid())
634
15
    return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc);
635
23
  else
636
23
    return CharSourceRange::getTokenRange(Range);
637
38
}
638
639
std::string
640
17
attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) {
641
17
  std::string Result;
642
17
  llvm::raw_string_ostream OS(Result);
643
21
  for (const auto &I : llvm::enumerate(Rules)) {
644
21
    if (I.index())
645
4
      OS << (I.index() == Rules.size() - 1 ? ", and " : 
", "0
);
646
21
    OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'";
647
21
  }
648
17
  return OS.str();
649
17
}
650
651
} // end anonymous namespace
652
653
void Sema::ActOnPragmaAttributeAttribute(
654
    ParsedAttr &Attribute, SourceLocation PragmaLoc,
655
407
    attr::ParsedSubjectMatchRuleSet Rules) {
656
407
  Attribute.setIsPragmaClangAttribute();
657
407
  SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules;
658
407
  // Gather the subject match rules that are supported by the attribute.
659
407
  SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4>
660
407
      StrictSubjectMatchRuleSet;
661
407
  Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet);
662
407
663
407
  // Figure out which subject matching rules are valid.
664
407
  if (StrictSubjectMatchRuleSet.empty()) {
665
82
    // Check for contradicting match rules. Contradicting match rules are
666
82
    // either:
667
82
    //  - a top-level rule and one of its sub-rules. E.g. variable and
668
82
    //    variable(is_parameter).
669
82
    //  - a sub-rule and a sibling that's negated. E.g.
670
82
    //    variable(is_thread_local) and variable(unless(is_parameter))
671
82
    llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2>
672
82
        RulesToFirstSpecifiedNegatedSubRule;
673
151
    for (const auto &Rule : Rules) {
674
151
      attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
675
151
      Optional<attr::SubjectMatchRule> ParentRule =
676
151
          getParentAttrMatcherRule(MatchRule);
677
151
      if (!ParentRule)
678
103
        continue;
679
48
      auto It = Rules.find(*ParentRule);
680
48
      if (It != Rules.end()) {
681
11
        // A sub-rule contradicts a parent rule.
682
11
        Diag(Rule.second.getBegin(),
683
11
             diag::err_pragma_attribute_matcher_subrule_contradicts_rule)
684
11
            << attr::getSubjectMatchRuleSpelling(MatchRule)
685
11
            << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second
686
11
            << FixItHint::CreateRemoval(
687
11
                   replacementRangeForListElement(*this, Rule.second));
688
11
        // Keep going without removing this rule as it won't change the set of
689
11
        // declarations that receive the attribute.
690
11
        continue;
691
11
      }
692
37
      if (isNegatedAttrMatcherSubRule(MatchRule))
693
12
        RulesToFirstSpecifiedNegatedSubRule.insert(
694
12
            std::make_pair(*ParentRule, Rule));
695
37
    }
696
82
    bool IgnoreNegatedSubRules = false;
697
151
    for (const auto &Rule : Rules) {
698
151
      attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first);
699
151
      Optional<attr::SubjectMatchRule> ParentRule =
700
151
          getParentAttrMatcherRule(MatchRule);
701
151
      if (!ParentRule)
702
103
        continue;
703
48
      auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule);
704
48
      if (It != RulesToFirstSpecifiedNegatedSubRule.end() &&
705
48
          
It->second != Rule14
) {
706
6
        // Negated sub-rule contradicts another sub-rule.
707
6
        Diag(
708
6
            It->second.second.getBegin(),
709
6
            diag::
710
6
                err_pragma_attribute_matcher_negated_subrule_contradicts_subrule)
711
6
            << attr::getSubjectMatchRuleSpelling(
712
6
                   attr::SubjectMatchRule(It->second.first))
713
6
            << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second
714
6
            << FixItHint::CreateRemoval(
715
6
                   replacementRangeForListElement(*this, It->second.second));
716
6
        // Keep going but ignore all of the negated sub-rules.
717
6
        IgnoreNegatedSubRules = true;
718
6
        RulesToFirstSpecifiedNegatedSubRule.erase(It);
719
6
      }
720
48
    }
721
82
722
82
    if (!IgnoreNegatedSubRules) {
723
76
      for (const auto &Rule : Rules)
724
131
        SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
725
76
    } else {
726
20
      for (const auto &Rule : Rules) {
727
20
        if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first)))
728
14
          SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first));
729
20
      }
730
6
    }
731
82
    Rules.clear();
732
325
  } else {
733
4.11k
    for (const auto &Rule : StrictSubjectMatchRuleSet) {
734
4.11k
      if (Rules.erase(Rule.first)) {
735
616
        // Add the rule to the set of attribute receivers only if it's supported
736
616
        // in the current language mode.
737
616
        if (Rule.second)
738
610
          SubjectMatchRules.push_back(Rule.first);
739
616
      }
740
4.11k
    }
741
325
  }
742
407
743
407
  if (!Rules.empty()) {
744
17
    auto Diagnostic =
745
17
        Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers)
746
17
        << Attribute;
747
17
    SmallVector<attr::SubjectMatchRule, 2> ExtraRules;
748
21
    for (const auto &Rule : Rules) {
749
21
      ExtraRules.push_back(attr::SubjectMatchRule(Rule.first));
750
21
      Diagnostic << FixItHint::CreateRemoval(
751
21
          replacementRangeForListElement(*this, Rule.second));
752
21
    }
753
17
    Diagnostic << attrMatcherRuleListToString(ExtraRules);
754
17
  }
755
407
756
407
  if (PragmaAttributeStack.empty()) {
757
1
    Diag(PragmaLoc, diag::err_pragma_attr_attr_no_push);
758
1
    return;
759
1
  }
760
406
761
406
  PragmaAttributeStack.back().Entries.push_back(
762
406
      {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false});
763
406
}
764
765
void Sema::ActOnPragmaAttributeEmptyPush(SourceLocation PragmaLoc,
766
406
                                         const IdentifierInfo *Namespace) {
767
406
  PragmaAttributeStack.emplace_back();
768
406
  PragmaAttributeStack.back().Loc = PragmaLoc;
769
406
  PragmaAttributeStack.back().Namespace = Namespace;
770
406
}
771
772
void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc,
773
399
                                   const IdentifierInfo *Namespace) {
774
399
  if (PragmaAttributeStack.empty()) {
775
4
    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
776
4
    return;
777
4
  }
778
395
779
395
  // Dig back through the stack trying to find the most recently pushed group
780
395
  // that in Namespace. Note that this works fine if no namespace is present,
781
395
  // think of push/pops without namespaces as having an implicit "nullptr"
782
395
  // namespace.
783
399
  
for (size_t Index = PragmaAttributeStack.size(); 395
Index;) {
784
397
    --Index;
785
397
    if (PragmaAttributeStack[Index].Namespace == Namespace) {
786
393
      for (const PragmaAttributeEntry &Entry :
787
393
           PragmaAttributeStack[Index].Entries) {
788
393
        if (!Entry.IsUsed) {
789
53
          assert(Entry.Attribute && "Expected an attribute");
790
53
          Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused)
791
53
              << *Entry.Attribute;
792
53
          Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here);
793
53
        }
794
393
      }
795
393
      PragmaAttributeStack.erase(PragmaAttributeStack.begin() + Index);
796
393
      return;
797
393
    }
798
397
  }
799
395
800
395
  
if (2
Namespace2
)
801
1
    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch)
802
1
        << 0 << Namespace->getName();
803
1
  else
804
1
    Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch) << 1;
805
2
}
806
807
36.7M
void Sema::AddPragmaAttributes(Scope *S, Decl *D) {
808
36.7M
  if (PragmaAttributeStack.empty())
809
36.7M
    return;
810
147k
  
for (auto &Group : PragmaAttributeStack)37.3k
{
811
147k
    for (auto &Entry : Group.Entries) {
812
147k
      ParsedAttr *Attribute = Entry.Attribute;
813
147k
      assert(Attribute && "Expected an attribute");
814
147k
      assert(Attribute->isPragmaClangAttribute() &&
815
147k
             "expected #pragma clang attribute");
816
147k
817
147k
      // Ensure that the attribute can be applied to the given declaration.
818
147k
      bool Applies = false;
819
291k
      for (const auto &Rule : Entry.MatchRules) {
820
291k
        if (Attribute->appliesToDecl(D, Rule)) {
821
55.9k
          Applies = true;
822
55.9k
          break;
823
55.9k
        }
824
291k
      }
825
147k
      if (!Applies)
826
91.2k
        continue;
827
55.9k
      Entry.IsUsed = true;
828
55.9k
      PragmaAttributeCurrentTargetDecl = D;
829
55.9k
      ParsedAttributesView Attrs;
830
55.9k
      Attrs.addAtEnd(Attribute);
831
55.9k
      ProcessDeclAttributeList(S, D, Attrs);
832
55.9k
      PragmaAttributeCurrentTargetDecl = nullptr;
833
55.9k
    }
834
147k
  }
835
37.3k
}
836
837
22
void Sema::PrintPragmaAttributeInstantiationPoint() {
838
22
  assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration");
839
22
  Diags.Report(PragmaAttributeCurrentTargetDecl->getBeginLoc(),
840
22
               diag::note_pragma_attribute_applied_decl_here);
841
22
}
842
843
51.7k
void Sema::DiagnoseUnterminatedPragmaAttribute() {
844
51.7k
  if (PragmaAttributeStack.empty())
845
51.7k
    return;
846
3
  Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof);
847
3
}
848
849
31
void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) {
850
31
  if(On)
851
14
    OptimizeOffPragmaLocation = SourceLocation();
852
17
  else
853
17
    OptimizeOffPragmaLocation = PragmaLoc;
854
31
}
855
856
2.77M
void Sema::AddRangeBasedOptnone(FunctionDecl *FD) {
857
2.77M
  // In the future, check other pragmas if they're implemented (e.g. pragma
858
2.77M
  // optimize 0 will probably map to this functionality too).
859
2.77M
  if(OptimizeOffPragmaLocation.isValid())
860
29
    AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation);
861
2.77M
}
862
863
void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD,
864
29
                                            SourceLocation Loc) {
865
29
  // Don't add a conflicting attribute. No diagnostic is needed.
866
29
  if (FD->hasAttr<MinSizeAttr>() || 
FD->hasAttr<AlwaysInlineAttr>()26
)
867
6
    return;
868
23
869
23
  // Add attributes only if required. Optnone requires noinline as well, but if
870
23
  // either is already present then don't bother adding them.
871
23
  if (!FD->hasAttr<OptimizeNoneAttr>())
872
23
    FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc));
873
23
  if (!FD->hasAttr<NoInlineAttr>())
874
23
    FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc));
875
23
}
876
877
typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack;
878
enum : unsigned { NoVisibility = ~0U };
879
880
7.68M
void Sema::AddPushedVisibilityAttribute(Decl *D) {
881
7.68M
  if (!VisContext)
882
7.68M
    return;
883
419
884
419
  NamedDecl *ND = dyn_cast<NamedDecl>(D);
885
419
  if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue))
886
96
    return;
887
323
888
323
  VisStack *Stack = static_cast<VisStack*>(VisContext);
889
323
  unsigned rawType = Stack->back().first;
890
323
  if (rawType == NoVisibility) 
return30
;
891
293
892
293
  VisibilityAttr::VisibilityType type
893
293
    = (VisibilityAttr::VisibilityType) rawType;
894
293
  SourceLocation loc = Stack->back().second;
895
293
896
293
  D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc));
897
293
}
898
899
/// FreeVisContext - Deallocate and null out VisContext.
900
63
void Sema::FreeVisContext() {
901
63
  delete static_cast<VisStack*>(VisContext);
902
63
  VisContext = nullptr;
903
63
}
904
905
67
static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) {
906
67
  // Put visibility on stack.
907
67
  if (!S.VisContext)
908
63
    S.VisContext = new VisStack;
909
67
910
67
  VisStack *Stack = static_cast<VisStack*>(S.VisContext);
911
67
  Stack->push_back(std::make_pair(type, loc));
912
67
}
913
914
void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType,
915
89
                                 SourceLocation PragmaLoc) {
916
89
  if (VisType) {
917
46
    // Compute visibility to use.
918
46
    VisibilityAttr::VisibilityType T;
919
46
    if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) {
920
1
      Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType;
921
1
      return;
922
1
    }
923
45
    PushPragmaVisibility(*this, T, PragmaLoc);
924
45
  } else {
925
43
    PopPragmaVisibility(false, PragmaLoc);
926
43
  }
927
89
}
928
929
35
void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) {
930
35
  switch (FPC) {
931
21
  case LangOptions::FPC_On:
932
21
    FPFeatures.setAllowFPContractWithinStatement();
933
21
    break;
934
6
  case LangOptions::FPC_Fast:
935
6
    FPFeatures.setAllowFPContractAcrossStatement();
936
6
    break;
937
8
  case LangOptions::FPC_Off:
938
8
    FPFeatures.setDisallowFPContract();
939
8
    break;
940
35
  }
941
35
}
942
943
0
void Sema::setRoundingMode(LangOptions::FPRoundingModeKind FPR) {
944
0
  FPFeatures.setRoundingMode(FPR);
945
0
}
946
947
0
void Sema::setExceptionMode(LangOptions::FPExceptionModeKind FPE) {
948
0
  FPFeatures.setExceptionMode(FPE);
949
0
}
950
951
3
void Sema::ActOnPragmaFEnvAccess(LangOptions::FEnvAccessModeKind FPC) {
952
3
  switch (FPC) {
953
1
  case LangOptions::FEA_On:
954
1
    FPFeatures.setAllowFEnvAccess();
955
1
    break;
956
2
  case LangOptions::FEA_Off:
957
2
    FPFeatures.setDisallowFEnvAccess();
958
2
    break;
959
3
  }
960
3
}
961
962
963
void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr,
964
22
                                       SourceLocation Loc) {
965
22
  // Visibility calculations will consider the namespace's visibility.
966
22
  // Here we just want to note that we're in a visibility context
967
22
  // which overrides any enclosing #pragma context, but doesn't itself
968
22
  // contribute visibility.
969
22
  PushPragmaVisibility(*this, NoVisibility, Loc);
970
22
}
971
972
65
void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) {
973
65
  if (!VisContext) {
974
2
    Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
975
2
    return;
976
2
  }
977
63
978
63
  // Pop visibility from stack
979
63
  VisStack *Stack = static_cast<VisStack*>(VisContext);
980
63
981
63
  const std::pair<unsigned, SourceLocation> *Back = &Stack->back();
982
63
  bool StartsWithPragma = Back->first != NoVisibility;
983
63
  if (StartsWithPragma && 
IsNamespaceEnd41
) {
984
1
    Diag(Back->second, diag::err_pragma_push_visibility_mismatch);
985
1
    Diag(EndLoc, diag::note_surrounding_namespace_ends_here);
986
1
987
1
    // For better error recovery, eat all pushes inside the namespace.
988
1
    do {
989
1
      Stack->pop_back();
990
1
      Back = &Stack->back();
991
1
      StartsWithPragma = Back->first != NoVisibility;
992
1
    } while (StartsWithPragma);
993
62
  } else if (!StartsWithPragma && 
!IsNamespaceEnd22
) {
994
1
    Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch);
995
1
    Diag(Back->second, diag::note_surrounding_namespace_starts_here);
996
1
    return;
997
1
  }
998
62
999
62
  Stack->pop_back();
1000
62
  // To simplify the implementation, never keep around an empty stack.
1001
62
  if (Stack->empty())
1002
59
    FreeVisContext();
1003
62
}