summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaAttr.cpp
diff options
context:
space:
mode:
authorEli Friedman <eli.friedman@gmail.com>2010-08-05 06:57:20 +0000
committerEli Friedman <eli.friedman@gmail.com>2010-08-05 06:57:20 +0000
commit570024a8d9b4a4aa4a35f077a0a65003dc7b71fe (patch)
treeccef452e0e9e6de88bf5965f706d54ed2a416441 /clang/lib/Sema/SemaAttr.cpp
parentef7c0ffe40cd6ac9662ee074cd97daaef6d7eaa1 (diff)
downloadbcm5719-llvm-570024a8d9b4a4aa4a35f077a0a65003dc7b71fe.tar.gz
bcm5719-llvm-570024a8d9b4a4aa4a35f077a0a65003dc7b71fe.zip
Implement #pragma GCC visibility.
llvm-svn: 110315
Diffstat (limited to 'clang/lib/Sema/SemaAttr.cpp')
-rw-r--r--clang/lib/Sema/SemaAttr.cpp67
1 files changed, 67 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaAttr.cpp b/clang/lib/Sema/SemaAttr.cpp
index 13a0c59bbdb..d1e5fe64dfb 100644
--- a/clang/lib/Sema/SemaAttr.cpp
+++ b/clang/lib/Sema/SemaAttr.cpp
@@ -288,3 +288,70 @@ void Sema::ActOnPragmaUnused(const Token *Identifiers, unsigned NumIdentifiers,
VD->addAttr(::new (Context) UnusedAttr());
}
}
+
+typedef std::vector<VisibilityAttr::VisibilityTypes> VisStack;
+
+void Sema::AddPushedVisibilityAttribute(Decl *D) {
+ if (!VisContext)
+ return;
+
+ if (D->hasAttr<VisibilityAttr>())
+ return;
+
+ VisStack *Stack = static_cast<VisStack*>(VisContext);
+ VisibilityAttr::VisibilityTypes type = Stack->back();
+
+ D->addAttr(::new (Context) VisibilityAttr(type, true));
+}
+
+/// FreeVisContext - Deallocate and null out VisContext.
+void Sema::FreeVisContext() {
+ delete static_cast<VisStack*>(VisContext);
+ VisContext = 0;
+}
+
+void Sema::ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
+ SourceLocation PragmaLoc) {
+ if (IsPush) {
+ // Compute visibility to use.
+ VisibilityAttr::VisibilityTypes type;
+ if (VisType->isStr("default"))
+ type = VisibilityAttr::DefaultVisibility;
+ else if (VisType->isStr("hidden"))
+ type = VisibilityAttr::HiddenVisibility;
+ else if (VisType->isStr("internal"))
+ type = VisibilityAttr::HiddenVisibility; // FIXME
+ else if (VisType->isStr("protected"))
+ type = VisibilityAttr::ProtectedVisibility;
+ else {
+ Diag(PragmaLoc, diag::warn_attribute_unknown_visibility) <<
+ VisType->getName();
+ return;
+ }
+ PushPragmaVisibility(type);
+ } else {
+ PopPragmaVisibility();
+ }
+}
+
+void Sema::PushPragmaVisibility(VisibilityAttr::VisibilityTypes type) {
+ // Put visibility on stack.
+ if (!VisContext)
+ VisContext = new VisStack;
+
+ VisStack *Stack = static_cast<VisStack*>(VisContext);
+ Stack->push_back(type);
+}
+
+void Sema::PopPragmaVisibility() {
+ // Pop visibility from stack, if there is one on the stack.
+ if (VisContext) {
+ VisStack *Stack = static_cast<VisStack*>(VisContext);
+
+ Stack->pop_back();
+ // To simplify the implementation, never keep around an empty stack.
+ if (Stack->empty())
+ FreeVisContext();
+ }
+ // FIXME: Add diag for pop without push.
+}
OpenPOWER on IntegriCloud