1 //===--- SemaAttr.cpp - Semantic Analysis for Attributes ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements semantic analysis for non-trivial attributes and 11 // pragmas. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/AST/ASTConsumer.h" 16 #include "clang/AST/Attr.h" 17 #include "clang/AST/Expr.h" 18 #include "clang/Basic/TargetInfo.h" 19 #include "clang/Lex/Preprocessor.h" 20 #include "clang/Sema/Lookup.h" 21 #include "clang/Sema/SemaInternal.h" 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 } 39 } 40 41 Sema::PragmaStackSentinelRAII::~PragmaStackSentinelRAII() { 42 if (ShouldAct) { 43 S.VtorDispStack.SentinelAction(PSK_Pop, SlotLabel); 44 S.DataSegStack.SentinelAction(PSK_Pop, SlotLabel); 45 S.BSSSegStack.SentinelAction(PSK_Pop, SlotLabel); 46 S.ConstSegStack.SentinelAction(PSK_Pop, SlotLabel); 47 S.CodeSegStack.SentinelAction(PSK_Pop, SlotLabel); 48 } 49 } 50 51 void Sema::AddAlignmentAttributesForRecord(RecordDecl *RD) { 52 // If there is no pack value, we don't need any attributes. 53 if (!PackStack.CurrentValue) 54 return; 55 56 // Otherwise, check to see if we need a max field alignment attribute. 57 if (unsigned Alignment = PackStack.CurrentValue) { 58 if (Alignment == Sema::kMac68kAlignmentSentinel) 59 RD->addAttr(AlignMac68kAttr::CreateImplicit(Context)); 60 else 61 RD->addAttr(MaxFieldAlignmentAttr::CreateImplicit(Context, 62 Alignment * 8)); 63 } 64 if (PackIncludeStack.empty()) 65 return; 66 // The #pragma pack affected a record in an included file, so Clang should 67 // warn when that pragma was written in a file that included the included 68 // file. 69 for (auto &PackedInclude : llvm::reverse(PackIncludeStack)) { 70 if (PackedInclude.CurrentPragmaLocation != PackStack.CurrentPragmaLocation) 71 break; 72 if (PackedInclude.HasNonDefaultValue) 73 PackedInclude.ShouldWarnOnInclude = true; 74 } 75 } 76 77 void Sema::AddMsStructLayoutForRecord(RecordDecl *RD) { 78 if (MSStructPragmaOn) 79 RD->addAttr(MSStructAttr::CreateImplicit(Context)); 80 81 // FIXME: We should merge AddAlignmentAttributesForRecord with 82 // AddMsStructLayoutForRecord into AddPragmaAttributesForRecord, which takes 83 // all active pragmas and applies them as attributes to class definitions. 84 if (VtorDispStack.CurrentValue != getLangOpts().VtorDispMode) 85 RD->addAttr( 86 MSVtorDispAttr::CreateImplicit(Context, VtorDispStack.CurrentValue)); 87 } 88 89 void Sema::ActOnPragmaOptionsAlign(PragmaOptionsAlignKind Kind, 90 SourceLocation PragmaLoc) { 91 PragmaMsStackAction Action = Sema::PSK_Reset; 92 unsigned Alignment = 0; 93 switch (Kind) { 94 // For all targets we support native and natural are the same. 95 // 96 // FIXME: This is not true on Darwin/PPC. 97 case POAK_Native: 98 case POAK_Power: 99 case POAK_Natural: 100 Action = Sema::PSK_Push_Set; 101 Alignment = 0; 102 break; 103 104 // Note that '#pragma options align=packed' is not equivalent to attribute 105 // packed, it has a different precedence relative to attribute aligned. 106 case POAK_Packed: 107 Action = Sema::PSK_Push_Set; 108 Alignment = 1; 109 break; 110 111 case POAK_Mac68k: 112 // Check if the target supports this. 113 if (!this->Context.getTargetInfo().hasAlignMac68kSupport()) { 114 Diag(PragmaLoc, diag::err_pragma_options_align_mac68k_target_unsupported); 115 return; 116 } 117 Action = Sema::PSK_Push_Set; 118 Alignment = Sema::kMac68kAlignmentSentinel; 119 break; 120 121 case POAK_Reset: 122 // Reset just pops the top of the stack, or resets the current alignment to 123 // default. 124 Action = Sema::PSK_Pop; 125 if (PackStack.Stack.empty()) { 126 if (PackStack.CurrentValue) { 127 Action = Sema::PSK_Reset; 128 } else { 129 Diag(PragmaLoc, diag::warn_pragma_options_align_reset_failed) 130 << "stack empty"; 131 return; 132 } 133 } 134 break; 135 } 136 137 PackStack.Act(PragmaLoc, Action, StringRef(), Alignment); 138 } 139 140 void Sema::ActOnPragmaClangSection(SourceLocation PragmaLoc, PragmaClangSectionAction Action, 141 PragmaClangSectionKind SecKind, StringRef SecName) { 142 PragmaClangSection *CSec; 143 switch (SecKind) { 144 case PragmaClangSectionKind::PCSK_BSS: 145 CSec = &PragmaClangBSSSection; 146 break; 147 case PragmaClangSectionKind::PCSK_Data: 148 CSec = &PragmaClangDataSection; 149 break; 150 case PragmaClangSectionKind::PCSK_Rodata: 151 CSec = &PragmaClangRodataSection; 152 break; 153 case PragmaClangSectionKind::PCSK_Text: 154 CSec = &PragmaClangTextSection; 155 break; 156 default: 157 llvm_unreachable("invalid clang section kind"); 158 } 159 160 if (Action == PragmaClangSectionAction::PCSA_Clear) { 161 CSec->Valid = false; 162 return; 163 } 164 165 CSec->Valid = true; 166 CSec->SectionName = SecName; 167 CSec->PragmaLocation = PragmaLoc; 168 } 169 170 void Sema::ActOnPragmaPack(SourceLocation PragmaLoc, PragmaMsStackAction Action, 171 StringRef SlotLabel, Expr *alignment) { 172 Expr *Alignment = static_cast<Expr *>(alignment); 173 174 // If specified then alignment must be a "small" power of two. 175 unsigned AlignmentVal = 0; 176 if (Alignment) { 177 llvm::APSInt Val; 178 179 // pack(0) is like pack(), which just works out since that is what 180 // we use 0 for in PackAttr. 181 if (Alignment->isTypeDependent() || 182 Alignment->isValueDependent() || 183 !Alignment->isIntegerConstantExpr(Val, Context) || 184 !(Val == 0 || Val.isPowerOf2()) || 185 Val.getZExtValue() > 16) { 186 Diag(PragmaLoc, diag::warn_pragma_pack_invalid_alignment); 187 return; // Ignore 188 } 189 190 AlignmentVal = (unsigned) Val.getZExtValue(); 191 } 192 if (Action == Sema::PSK_Show) { 193 // Show the current alignment, making sure to show the right value 194 // for the default. 195 // FIXME: This should come from the target. 196 AlignmentVal = PackStack.CurrentValue; 197 if (AlignmentVal == 0) 198 AlignmentVal = 8; 199 if (AlignmentVal == Sema::kMac68kAlignmentSentinel) 200 Diag(PragmaLoc, diag::warn_pragma_pack_show) << "mac68k"; 201 else 202 Diag(PragmaLoc, diag::warn_pragma_pack_show) << AlignmentVal; 203 } 204 // MSDN, C/C++ Preprocessor Reference > Pragma Directives > pack: 205 // "#pragma pack(pop, identifier, n) is undefined" 206 if (Action & Sema::PSK_Pop) { 207 if (Alignment && !SlotLabel.empty()) 208 Diag(PragmaLoc, diag::warn_pragma_pack_pop_identifer_and_alignment); 209 if (PackStack.Stack.empty()) 210 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "pack" << "stack empty"; 211 } 212 213 PackStack.Act(PragmaLoc, Action, SlotLabel, AlignmentVal); 214 } 215 216 void Sema::DiagnoseNonDefaultPragmaPack(PragmaPackDiagnoseKind Kind, 217 SourceLocation IncludeLoc) { 218 if (Kind == PragmaPackDiagnoseKind::NonDefaultStateAtInclude) { 219 SourceLocation PrevLocation = PackStack.CurrentPragmaLocation; 220 // Warn about non-default alignment at #includes (without redundant 221 // warnings for the same directive in nested includes). 222 // The warning is delayed until the end of the file to avoid warnings 223 // for files that don't have any records that are affected by the modified 224 // alignment. 225 bool HasNonDefaultValue = 226 PackStack.hasValue() && 227 (PackIncludeStack.empty() || 228 PackIncludeStack.back().CurrentPragmaLocation != PrevLocation); 229 PackIncludeStack.push_back( 230 {PackStack.CurrentValue, 231 PackStack.hasValue() ? PrevLocation : SourceLocation(), 232 HasNonDefaultValue, /*ShouldWarnOnInclude*/ false}); 233 return; 234 } 235 236 assert(Kind == PragmaPackDiagnoseKind::ChangedStateAtExit && "invalid kind"); 237 PackIncludeState PrevPackState = PackIncludeStack.pop_back_val(); 238 if (PrevPackState.ShouldWarnOnInclude) { 239 // Emit the delayed non-default alignment at #include warning. 240 Diag(IncludeLoc, diag::warn_pragma_pack_non_default_at_include); 241 Diag(PrevPackState.CurrentPragmaLocation, diag::note_pragma_pack_here); 242 } 243 // Warn about modified alignment after #includes. 244 if (PrevPackState.CurrentValue != PackStack.CurrentValue) { 245 Diag(IncludeLoc, diag::warn_pragma_pack_modified_after_include); 246 Diag(PackStack.CurrentPragmaLocation, diag::note_pragma_pack_here); 247 } 248 } 249 250 void Sema::DiagnoseUnterminatedPragmaPack() { 251 if (PackStack.Stack.empty()) 252 return; 253 bool IsInnermost = true; 254 for (const auto &StackSlot : llvm::reverse(PackStack.Stack)) { 255 Diag(StackSlot.PragmaPushLocation, diag::warn_pragma_pack_no_pop_eof); 256 // The user might have already reset the alignment, so suggest replacing 257 // the reset with a pop. 258 if (IsInnermost && PackStack.CurrentValue == PackStack.DefaultValue) { 259 DiagnosticBuilder DB = Diag(PackStack.CurrentPragmaLocation, 260 diag::note_pragma_pack_pop_instead_reset); 261 SourceLocation FixItLoc = Lexer::findLocationAfterToken( 262 PackStack.CurrentPragmaLocation, tok::l_paren, SourceMgr, LangOpts, 263 /*SkipTrailing=*/false); 264 if (FixItLoc.isValid()) 265 DB << FixItHint::CreateInsertion(FixItLoc, "pop"); 266 } 267 IsInnermost = false; 268 } 269 } 270 271 void Sema::ActOnPragmaMSStruct(PragmaMSStructKind Kind) { 272 MSStructPragmaOn = (Kind == PMSST_ON); 273 } 274 275 void Sema::ActOnPragmaMSComment(SourceLocation CommentLoc, 276 PragmaMSCommentKind Kind, StringRef Arg) { 277 auto *PCD = PragmaCommentDecl::Create( 278 Context, Context.getTranslationUnitDecl(), CommentLoc, Kind, Arg); 279 Context.getTranslationUnitDecl()->addDecl(PCD); 280 Consumer.HandleTopLevelDecl(DeclGroupRef(PCD)); 281 } 282 283 void Sema::ActOnPragmaDetectMismatch(SourceLocation Loc, StringRef Name, 284 StringRef Value) { 285 auto *PDMD = PragmaDetectMismatchDecl::Create( 286 Context, Context.getTranslationUnitDecl(), Loc, Name, Value); 287 Context.getTranslationUnitDecl()->addDecl(PDMD); 288 Consumer.HandleTopLevelDecl(DeclGroupRef(PDMD)); 289 } 290 291 void Sema::ActOnPragmaMSPointersToMembers( 292 LangOptions::PragmaMSPointersToMembersKind RepresentationMethod, 293 SourceLocation PragmaLoc) { 294 MSPointerToMemberRepresentationMethod = RepresentationMethod; 295 ImplicitMSInheritanceAttrLoc = PragmaLoc; 296 } 297 298 void Sema::ActOnPragmaMSVtorDisp(PragmaMsStackAction Action, 299 SourceLocation PragmaLoc, 300 MSVtorDispAttr::Mode Mode) { 301 if (Action & PSK_Pop && VtorDispStack.Stack.empty()) 302 Diag(PragmaLoc, diag::warn_pragma_pop_failed) << "vtordisp" 303 << "stack empty"; 304 VtorDispStack.Act(PragmaLoc, Action, StringRef(), Mode); 305 } 306 307 template<typename ValueType> 308 void Sema::PragmaStack<ValueType>::Act(SourceLocation PragmaLocation, 309 PragmaMsStackAction Action, 310 llvm::StringRef StackSlotLabel, 311 ValueType Value) { 312 if (Action == PSK_Reset) { 313 CurrentValue = DefaultValue; 314 CurrentPragmaLocation = PragmaLocation; 315 return; 316 } 317 if (Action & PSK_Push) 318 Stack.emplace_back(StackSlotLabel, CurrentValue, CurrentPragmaLocation, 319 PragmaLocation); 320 else if (Action & PSK_Pop) { 321 if (!StackSlotLabel.empty()) { 322 // If we've got a label, try to find it and jump there. 323 auto I = llvm::find_if(llvm::reverse(Stack), [&](const Slot &x) { 324 return x.StackSlotLabel == StackSlotLabel; 325 }); 326 // If we found the label so pop from there. 327 if (I != Stack.rend()) { 328 CurrentValue = I->Value; 329 CurrentPragmaLocation = I->PragmaLocation; 330 Stack.erase(std::prev(I.base()), Stack.end()); 331 } 332 } else if (!Stack.empty()) { 333 // We don't have a label, just pop the last entry. 334 CurrentValue = Stack.back().Value; 335 CurrentPragmaLocation = Stack.back().PragmaLocation; 336 Stack.pop_back(); 337 } 338 } 339 if (Action & PSK_Set) { 340 CurrentValue = Value; 341 CurrentPragmaLocation = PragmaLocation; 342 } 343 } 344 345 bool Sema::UnifySection(StringRef SectionName, 346 int SectionFlags, 347 DeclaratorDecl *Decl) { 348 auto Section = Context.SectionInfos.find(SectionName); 349 if (Section == Context.SectionInfos.end()) { 350 Context.SectionInfos[SectionName] = 351 ASTContext::SectionInfo(Decl, SourceLocation(), SectionFlags); 352 return false; 353 } 354 // A pre-declared section takes precedence w/o diagnostic. 355 if (Section->second.SectionFlags == SectionFlags || 356 !(Section->second.SectionFlags & ASTContext::PSF_Implicit)) 357 return false; 358 auto OtherDecl = Section->second.Decl; 359 Diag(Decl->getLocation(), diag::err_section_conflict) 360 << Decl << OtherDecl; 361 Diag(OtherDecl->getLocation(), diag::note_declared_at) 362 << OtherDecl->getName(); 363 if (auto A = Decl->getAttr<SectionAttr>()) 364 if (A->isImplicit()) 365 Diag(A->getLocation(), diag::note_pragma_entered_here); 366 if (auto A = OtherDecl->getAttr<SectionAttr>()) 367 if (A->isImplicit()) 368 Diag(A->getLocation(), diag::note_pragma_entered_here); 369 return true; 370 } 371 372 bool Sema::UnifySection(StringRef SectionName, 373 int SectionFlags, 374 SourceLocation PragmaSectionLocation) { 375 auto Section = Context.SectionInfos.find(SectionName); 376 if (Section != Context.SectionInfos.end()) { 377 if (Section->second.SectionFlags == SectionFlags) 378 return false; 379 if (!(Section->second.SectionFlags & ASTContext::PSF_Implicit)) { 380 Diag(PragmaSectionLocation, diag::err_section_conflict) 381 << "this" << "a prior #pragma section"; 382 Diag(Section->second.PragmaSectionLocation, 383 diag::note_pragma_entered_here); 384 return true; 385 } 386 } 387 Context.SectionInfos[SectionName] = 388 ASTContext::SectionInfo(nullptr, PragmaSectionLocation, SectionFlags); 389 return false; 390 } 391 392 /// \brief Called on well formed \#pragma bss_seg(). 393 void Sema::ActOnPragmaMSSeg(SourceLocation PragmaLocation, 394 PragmaMsStackAction Action, 395 llvm::StringRef StackSlotLabel, 396 StringLiteral *SegmentName, 397 llvm::StringRef PragmaName) { 398 PragmaStack<StringLiteral *> *Stack = 399 llvm::StringSwitch<PragmaStack<StringLiteral *> *>(PragmaName) 400 .Case("data_seg", &DataSegStack) 401 .Case("bss_seg", &BSSSegStack) 402 .Case("const_seg", &ConstSegStack) 403 .Case("code_seg", &CodeSegStack); 404 if (Action & PSK_Pop && Stack->Stack.empty()) 405 Diag(PragmaLocation, diag::warn_pragma_pop_failed) << PragmaName 406 << "stack empty"; 407 if (SegmentName && 408 !checkSectionName(SegmentName->getLocStart(), SegmentName->getString())) 409 return; 410 Stack->Act(PragmaLocation, Action, StackSlotLabel, SegmentName); 411 } 412 413 /// \brief Called on well formed \#pragma bss_seg(). 414 void Sema::ActOnPragmaMSSection(SourceLocation PragmaLocation, 415 int SectionFlags, StringLiteral *SegmentName) { 416 UnifySection(SegmentName->getString(), SectionFlags, PragmaLocation); 417 } 418 419 void Sema::ActOnPragmaMSInitSeg(SourceLocation PragmaLocation, 420 StringLiteral *SegmentName) { 421 // There's no stack to maintain, so we just have a current section. When we 422 // see the default section, reset our current section back to null so we stop 423 // tacking on unnecessary attributes. 424 CurInitSeg = SegmentName->getString() == ".CRT$XCU" ? nullptr : SegmentName; 425 CurInitSegLoc = PragmaLocation; 426 } 427 428 void Sema::ActOnPragmaUnused(const Token &IdTok, Scope *curScope, 429 SourceLocation PragmaLoc) { 430 431 IdentifierInfo *Name = IdTok.getIdentifierInfo(); 432 LookupResult Lookup(*this, Name, IdTok.getLocation(), LookupOrdinaryName); 433 LookupParsedName(Lookup, curScope, nullptr, true); 434 435 if (Lookup.empty()) { 436 Diag(PragmaLoc, diag::warn_pragma_unused_undeclared_var) 437 << Name << SourceRange(IdTok.getLocation()); 438 return; 439 } 440 441 VarDecl *VD = Lookup.getAsSingle<VarDecl>(); 442 if (!VD) { 443 Diag(PragmaLoc, diag::warn_pragma_unused_expected_var_arg) 444 << Name << SourceRange(IdTok.getLocation()); 445 return; 446 } 447 448 // Warn if this was used before being marked unused. 449 if (VD->isUsed()) 450 Diag(PragmaLoc, diag::warn_used_but_marked_unused) << Name; 451 452 VD->addAttr(UnusedAttr::CreateImplicit(Context, UnusedAttr::GNU_unused, 453 IdTok.getLocation())); 454 } 455 456 void Sema::AddCFAuditedAttribute(Decl *D) { 457 SourceLocation Loc = PP.getPragmaARCCFCodeAuditedLoc(); 458 if (!Loc.isValid()) return; 459 460 // Don't add a redundant or conflicting attribute. 461 if (D->hasAttr<CFAuditedTransferAttr>() || 462 D->hasAttr<CFUnknownTransferAttr>()) 463 return; 464 465 D->addAttr(CFAuditedTransferAttr::CreateImplicit(Context, Loc)); 466 } 467 468 namespace { 469 470 Optional<attr::SubjectMatchRule> 471 getParentAttrMatcherRule(attr::SubjectMatchRule Rule) { 472 using namespace attr; 473 switch (Rule) { 474 default: 475 return None; 476 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 477 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 478 case Value: \ 479 return Parent; 480 #include "clang/Basic/AttrSubMatchRulesList.inc" 481 } 482 } 483 484 bool isNegatedAttrMatcherSubRule(attr::SubjectMatchRule Rule) { 485 using namespace attr; 486 switch (Rule) { 487 default: 488 return false; 489 #define ATTR_MATCH_RULE(Value, Spelling, IsAbstract) 490 #define ATTR_MATCH_SUB_RULE(Value, Spelling, IsAbstract, Parent, IsNegated) \ 491 case Value: \ 492 return IsNegated; 493 #include "clang/Basic/AttrSubMatchRulesList.inc" 494 } 495 } 496 497 CharSourceRange replacementRangeForListElement(const Sema &S, 498 SourceRange Range) { 499 // Make sure that the ',' is removed as well. 500 SourceLocation AfterCommaLoc = Lexer::findLocationAfterToken( 501 Range.getEnd(), tok::comma, S.getSourceManager(), S.getLangOpts(), 502 /*SkipTrailingWhitespaceAndNewLine=*/false); 503 if (AfterCommaLoc.isValid()) 504 return CharSourceRange::getCharRange(Range.getBegin(), AfterCommaLoc); 505 else 506 return CharSourceRange::getTokenRange(Range); 507 } 508 509 std::string 510 attrMatcherRuleListToString(ArrayRef<attr::SubjectMatchRule> Rules) { 511 std::string Result; 512 llvm::raw_string_ostream OS(Result); 513 for (const auto &I : llvm::enumerate(Rules)) { 514 if (I.index()) 515 OS << (I.index() == Rules.size() - 1 ? ", and " : ", "); 516 OS << "'" << attr::getSubjectMatchRuleSpelling(I.value()) << "'"; 517 } 518 return OS.str(); 519 } 520 521 } // end anonymous namespace 522 523 void Sema::ActOnPragmaAttributePush(AttributeList &Attribute, 524 SourceLocation PragmaLoc, 525 attr::ParsedSubjectMatchRuleSet Rules) { 526 SmallVector<attr::SubjectMatchRule, 4> SubjectMatchRules; 527 // Gather the subject match rules that are supported by the attribute. 528 SmallVector<std::pair<attr::SubjectMatchRule, bool>, 4> 529 StrictSubjectMatchRuleSet; 530 Attribute.getMatchRules(LangOpts, StrictSubjectMatchRuleSet); 531 532 // Figure out which subject matching rules are valid. 533 if (StrictSubjectMatchRuleSet.empty()) { 534 // Check for contradicting match rules. Contradicting match rules are 535 // either: 536 // - a top-level rule and one of its sub-rules. E.g. variable and 537 // variable(is_parameter). 538 // - a sub-rule and a sibling that's negated. E.g. 539 // variable(is_thread_local) and variable(unless(is_parameter)) 540 llvm::SmallDenseMap<int, std::pair<int, SourceRange>, 2> 541 RulesToFirstSpecifiedNegatedSubRule; 542 for (const auto &Rule : Rules) { 543 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 544 Optional<attr::SubjectMatchRule> ParentRule = 545 getParentAttrMatcherRule(MatchRule); 546 if (!ParentRule) 547 continue; 548 auto It = Rules.find(*ParentRule); 549 if (It != Rules.end()) { 550 // A sub-rule contradicts a parent rule. 551 Diag(Rule.second.getBegin(), 552 diag::err_pragma_attribute_matcher_subrule_contradicts_rule) 553 << attr::getSubjectMatchRuleSpelling(MatchRule) 554 << attr::getSubjectMatchRuleSpelling(*ParentRule) << It->second 555 << FixItHint::CreateRemoval( 556 replacementRangeForListElement(*this, Rule.second)); 557 // Keep going without removing this rule as it won't change the set of 558 // declarations that receive the attribute. 559 continue; 560 } 561 if (isNegatedAttrMatcherSubRule(MatchRule)) 562 RulesToFirstSpecifiedNegatedSubRule.insert( 563 std::make_pair(*ParentRule, Rule)); 564 } 565 bool IgnoreNegatedSubRules = false; 566 for (const auto &Rule : Rules) { 567 attr::SubjectMatchRule MatchRule = attr::SubjectMatchRule(Rule.first); 568 Optional<attr::SubjectMatchRule> ParentRule = 569 getParentAttrMatcherRule(MatchRule); 570 if (!ParentRule) 571 continue; 572 auto It = RulesToFirstSpecifiedNegatedSubRule.find(*ParentRule); 573 if (It != RulesToFirstSpecifiedNegatedSubRule.end() && 574 It->second != Rule) { 575 // Negated sub-rule contradicts another sub-rule. 576 Diag( 577 It->second.second.getBegin(), 578 diag:: 579 err_pragma_attribute_matcher_negated_subrule_contradicts_subrule) 580 << attr::getSubjectMatchRuleSpelling( 581 attr::SubjectMatchRule(It->second.first)) 582 << attr::getSubjectMatchRuleSpelling(MatchRule) << Rule.second 583 << FixItHint::CreateRemoval( 584 replacementRangeForListElement(*this, It->second.second)); 585 // Keep going but ignore all of the negated sub-rules. 586 IgnoreNegatedSubRules = true; 587 RulesToFirstSpecifiedNegatedSubRule.erase(It); 588 } 589 } 590 591 if (!IgnoreNegatedSubRules) { 592 for (const auto &Rule : Rules) 593 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 594 } else { 595 for (const auto &Rule : Rules) { 596 if (!isNegatedAttrMatcherSubRule(attr::SubjectMatchRule(Rule.first))) 597 SubjectMatchRules.push_back(attr::SubjectMatchRule(Rule.first)); 598 } 599 } 600 Rules.clear(); 601 } else { 602 for (const auto &Rule : StrictSubjectMatchRuleSet) { 603 if (Rules.erase(Rule.first)) { 604 // Add the rule to the set of attribute receivers only if it's supported 605 // in the current language mode. 606 if (Rule.second) 607 SubjectMatchRules.push_back(Rule.first); 608 } 609 } 610 } 611 612 if (!Rules.empty()) { 613 auto Diagnostic = 614 Diag(PragmaLoc, diag::err_pragma_attribute_invalid_matchers) 615 << Attribute.getName(); 616 SmallVector<attr::SubjectMatchRule, 2> ExtraRules; 617 for (const auto &Rule : Rules) { 618 ExtraRules.push_back(attr::SubjectMatchRule(Rule.first)); 619 Diagnostic << FixItHint::CreateRemoval( 620 replacementRangeForListElement(*this, Rule.second)); 621 } 622 Diagnostic << attrMatcherRuleListToString(ExtraRules); 623 } 624 625 PragmaAttributeStack.push_back( 626 {PragmaLoc, &Attribute, std::move(SubjectMatchRules), /*IsUsed=*/false}); 627 } 628 629 void Sema::ActOnPragmaAttributePop(SourceLocation PragmaLoc) { 630 if (PragmaAttributeStack.empty()) { 631 Diag(PragmaLoc, diag::err_pragma_attribute_stack_mismatch); 632 return; 633 } 634 const PragmaAttributeEntry &Entry = PragmaAttributeStack.back(); 635 if (!Entry.IsUsed) { 636 assert(Entry.Attribute && "Expected an attribute"); 637 Diag(Entry.Attribute->getLoc(), diag::warn_pragma_attribute_unused) 638 << Entry.Attribute->getName(); 639 Diag(PragmaLoc, diag::note_pragma_attribute_region_ends_here); 640 } 641 PragmaAttributeStack.pop_back(); 642 } 643 644 void Sema::AddPragmaAttributes(Scope *S, Decl *D) { 645 if (PragmaAttributeStack.empty()) 646 return; 647 for (auto &Entry : PragmaAttributeStack) { 648 const AttributeList *Attribute = Entry.Attribute; 649 assert(Attribute && "Expected an attribute"); 650 651 // Ensure that the attribute can be applied to the given declaration. 652 bool Applies = false; 653 for (const auto &Rule : Entry.MatchRules) { 654 if (Attribute->appliesToDecl(D, Rule)) { 655 Applies = true; 656 break; 657 } 658 } 659 if (!Applies) 660 continue; 661 Entry.IsUsed = true; 662 assert(!Attribute->getNext() && "Expected just one attribute"); 663 PragmaAttributeCurrentTargetDecl = D; 664 ProcessDeclAttributeList(S, D, Attribute); 665 PragmaAttributeCurrentTargetDecl = nullptr; 666 } 667 } 668 669 void Sema::PrintPragmaAttributeInstantiationPoint() { 670 assert(PragmaAttributeCurrentTargetDecl && "Expected an active declaration"); 671 Diags.Report(PragmaAttributeCurrentTargetDecl->getLocStart(), 672 diag::note_pragma_attribute_applied_decl_here); 673 } 674 675 void Sema::DiagnoseUnterminatedPragmaAttribute() { 676 if (PragmaAttributeStack.empty()) 677 return; 678 Diag(PragmaAttributeStack.back().Loc, diag::err_pragma_attribute_no_pop_eof); 679 } 680 681 void Sema::ActOnPragmaOptimize(bool On, SourceLocation PragmaLoc) { 682 if(On) 683 OptimizeOffPragmaLocation = SourceLocation(); 684 else 685 OptimizeOffPragmaLocation = PragmaLoc; 686 } 687 688 void Sema::AddRangeBasedOptnone(FunctionDecl *FD) { 689 // In the future, check other pragmas if they're implemented (e.g. pragma 690 // optimize 0 will probably map to this functionality too). 691 if(OptimizeOffPragmaLocation.isValid()) 692 AddOptnoneAttributeIfNoConflicts(FD, OptimizeOffPragmaLocation); 693 } 694 695 void Sema::AddOptnoneAttributeIfNoConflicts(FunctionDecl *FD, 696 SourceLocation Loc) { 697 // Don't add a conflicting attribute. No diagnostic is needed. 698 if (FD->hasAttr<MinSizeAttr>() || FD->hasAttr<AlwaysInlineAttr>()) 699 return; 700 701 // Add attributes only if required. Optnone requires noinline as well, but if 702 // either is already present then don't bother adding them. 703 if (!FD->hasAttr<OptimizeNoneAttr>()) 704 FD->addAttr(OptimizeNoneAttr::CreateImplicit(Context, Loc)); 705 if (!FD->hasAttr<NoInlineAttr>()) 706 FD->addAttr(NoInlineAttr::CreateImplicit(Context, Loc)); 707 } 708 709 typedef std::vector<std::pair<unsigned, SourceLocation> > VisStack; 710 enum : unsigned { NoVisibility = ~0U }; 711 712 void Sema::AddPushedVisibilityAttribute(Decl *D) { 713 if (!VisContext) 714 return; 715 716 NamedDecl *ND = dyn_cast<NamedDecl>(D); 717 if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue)) 718 return; 719 720 VisStack *Stack = static_cast<VisStack*>(VisContext); 721 unsigned rawType = Stack->back().first; 722 if (rawType == NoVisibility) return; 723 724 VisibilityAttr::VisibilityType type 725 = (VisibilityAttr::VisibilityType) rawType; 726 SourceLocation loc = Stack->back().second; 727 728 D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc)); 729 } 730 731 /// FreeVisContext - Deallocate and null out VisContext. 732 void Sema::FreeVisContext() { 733 delete static_cast<VisStack*>(VisContext); 734 VisContext = nullptr; 735 } 736 737 static void PushPragmaVisibility(Sema &S, unsigned type, SourceLocation loc) { 738 // Put visibility on stack. 739 if (!S.VisContext) 740 S.VisContext = new VisStack; 741 742 VisStack *Stack = static_cast<VisStack*>(S.VisContext); 743 Stack->push_back(std::make_pair(type, loc)); 744 } 745 746 void Sema::ActOnPragmaVisibility(const IdentifierInfo* VisType, 747 SourceLocation PragmaLoc) { 748 if (VisType) { 749 // Compute visibility to use. 750 VisibilityAttr::VisibilityType T; 751 if (!VisibilityAttr::ConvertStrToVisibilityType(VisType->getName(), T)) { 752 Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) << VisType; 753 return; 754 } 755 PushPragmaVisibility(*this, T, PragmaLoc); 756 } else { 757 PopPragmaVisibility(false, PragmaLoc); 758 } 759 } 760 761 void Sema::ActOnPragmaFPContract(LangOptions::FPContractModeKind FPC) { 762 switch (FPC) { 763 case LangOptions::FPC_On: 764 FPFeatures.setAllowFPContractWithinStatement(); 765 break; 766 case LangOptions::FPC_Fast: 767 FPFeatures.setAllowFPContractAcrossStatement(); 768 break; 769 case LangOptions::FPC_Off: 770 FPFeatures.setDisallowFPContract(); 771 break; 772 } 773 } 774 775 void Sema::PushNamespaceVisibilityAttr(const VisibilityAttr *Attr, 776 SourceLocation Loc) { 777 // Visibility calculations will consider the namespace's visibility. 778 // Here we just want to note that we're in a visibility context 779 // which overrides any enclosing #pragma context, but doesn't itself 780 // contribute visibility. 781 PushPragmaVisibility(*this, NoVisibility, Loc); 782 } 783 784 void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) { 785 if (!VisContext) { 786 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 787 return; 788 } 789 790 // Pop visibility from stack 791 VisStack *Stack = static_cast<VisStack*>(VisContext); 792 793 const std::pair<unsigned, SourceLocation> *Back = &Stack->back(); 794 bool StartsWithPragma = Back->first != NoVisibility; 795 if (StartsWithPragma && IsNamespaceEnd) { 796 Diag(Back->second, diag::err_pragma_push_visibility_mismatch); 797 Diag(EndLoc, diag::note_surrounding_namespace_ends_here); 798 799 // For better error recovery, eat all pushes inside the namespace. 800 do { 801 Stack->pop_back(); 802 Back = &Stack->back(); 803 StartsWithPragma = Back->first != NoVisibility; 804 } while (StartsWithPragma); 805 } else if (!StartsWithPragma && !IsNamespaceEnd) { 806 Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); 807 Diag(Back->second, diag::note_surrounding_namespace_starts_here); 808 return; 809 } 810 811 Stack->pop_back(); 812 // To simplify the implementation, never keep around an empty stack. 813 if (Stack->empty()) 814 FreeVisContext(); 815 } 816