diff options
Diffstat (limited to 'lib/AST/DeclBase.cpp')
-rw-r--r-- | lib/AST/DeclBase.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 843e907dea..3758ca1065 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -337,6 +337,38 @@ void Decl::dropAttrs() { getASTContext().eraseDeclAttrs(this); } +void Decl::addAttr(Attr *A) { + if (NamedDecl *ND = dyn_cast<NamedDecl>(this)) + if (VisibilityAttr *Visibility = dyn_cast<VisibilityAttr>(A)) { + bool ClearVisibility = true; + if (VarDecl *VD = dyn_cast<VarDecl>(this)) { + if (VD->getPreviousDeclaration()) { + VisibilityAttr *PrevVisibility + = VD->getPreviousDeclaration()->getAttr<VisibilityAttr>(); + if (PrevVisibility && + PrevVisibility->getVisibility() == Visibility->getVisibility()) + ClearVisibility = false; + } + } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(this)) { + if (FD->getPreviousDeclaration()) { + VisibilityAttr *PrevVisibility + = FD->getPreviousDeclaration()->getAttr<VisibilityAttr>(); + if (PrevVisibility && + PrevVisibility->getVisibility() == Visibility->getVisibility()) + ClearVisibility = false; + } + } + + if (ClearVisibility) + ND->ClearLinkageAndVisibilityCache(); + } + + if (hasAttrs()) + getAttrs().push_back(A); + else + setAttrs(AttrVec(1, A)); +} + const AttrVec &Decl::getAttrs() const { assert(HasAttrs && "No attrs to get!"); return getASTContext().getDeclAttrs(this); |