void Sema::PopPragmaVisibility(bool IsNamespaceEnd, SourceLocation EndLoc) { if (!VisContext) { Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); return; } // Pop visibility from stack VisStack *Stack = static_cast<VisStack*>(VisContext); const std::pair<unsigned, SourceLocation> *Back = &Stack->back(); bool StartsWithPragma = Back->first != NoVisibility; if (StartsWithPragma && IsNamespaceEnd) { Diag(Back->second, diag::err_pragma_push_visibility_mismatch); Diag(EndLoc, diag::note_surrounding_namespace_ends_here); // For better error recovery, eat all pushes inside the namespace. do { Stack->pop_back(); Back = &Stack->back(); StartsWithPragma = Back->first != NoVisibility; } while (StartsWithPragma); } else if (!StartsWithPragma && !IsNamespaceEnd) { Diag(EndLoc, diag::err_pragma_pop_visibility_mismatch); Diag(Back->second, diag::note_surrounding_namespace_starts_here); return; } Stack->pop_back(); // To simplify the implementation, never keep around an empty stack. if (Stack->empty()) FreeVisContext(); }
void Sema::AddPushedVisibilityAttribute(Decl *D) { if (!VisContext) return; if (D->hasAttr<VisibilityAttr>()) return; VisStack *Stack = static_cast<VisStack*>(VisContext); unsigned rawType = Stack->back().first; if (rawType == NoVisibility) return; VisibilityAttr::VisibilityType type = (VisibilityAttr::VisibilityType) rawType; SourceLocation loc = Stack->back().second; D->addAttr(::new (Context) VisibilityAttr(loc, Context, type)); }
void Sema::AddPushedVisibilityAttribute(Decl *D) { if (!VisContext) return; NamedDecl *ND = dyn_cast<NamedDecl>(D); if (ND && ND->getExplicitVisibility(NamedDecl::VisibilityForValue)) return; VisStack *Stack = static_cast<VisStack*>(VisContext); unsigned rawType = Stack->back().first; if (rawType == NoVisibility) return; VisibilityAttr::VisibilityType type = (VisibilityAttr::VisibilityType) rawType; SourceLocation loc = Stack->back().second; D->addAttr(VisibilityAttr::CreateImplicit(Context, type, loc)); }