summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/TokenKinds.def5
-rw-r--r--clang/include/clang/Parse/Parser.h4
-rw-r--r--clang/lib/Parse/ParsePragma.cpp17
-rw-r--r--clang/lib/Parse/Parser.cpp3
-rw-r--r--clang/test/CodeGenCXX/pr11797.cpp8
-rw-r--r--clang/test/CodeGenCXX/pragma-visibility.cpp4
6 files changed, 36 insertions, 5 deletions
diff --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index cac07337305..5c9708bc712 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -568,6 +568,11 @@ ANNOTATION(decltype) // annotation for a decltype expression,
// one 'pragma_unused' annotation token followed by the argument token.
ANNOTATION(pragma_unused)
+// Annotation for #pragma GCC visibility...
+// The lexer produces these so that they only take effect when the parser
+// handles them.
+ANNOTATION(pragma_vis)
+
#undef ANNOTATION
#undef TESTING_KEYWORD
#undef OBJC2_AT_KEYWORD
diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h
index 07f39603f00..ca71047fe44 100644
--- a/clang/include/clang/Parse/Parser.h
+++ b/clang/include/clang/Parse/Parser.h
@@ -410,6 +410,10 @@ private:
/// \brief Handle the annotation token produced for #pragma unused(...)
void HandlePragmaUnused();
+ /// \brief Handle the annotation token produced for
+ /// #pragma GCC visibility...
+ void HandlePragmaVisibility();
+
/// GetLookAheadToken - This peeks ahead N tokens and returns that token
/// without consuming any tokens. LookAhead(0) returns 'Tok', LookAhead(1)
/// returns the token after Tok, etc.
diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
index 2fe2f3bdf3c..f47b32f513b 100644
--- a/clang/lib/Parse/ParsePragma.cpp
+++ b/clang/lib/Parse/ParsePragma.cpp
@@ -29,6 +29,14 @@ void Parser::HandlePragmaUnused() {
ConsumeToken(); // The argument token.
}
+void Parser::HandlePragmaVisibility() {
+ assert(Tok.is(tok::annot_pragma_vis));
+ const IdentifierInfo *VisType =
+ static_cast<IdentifierInfo *>(Tok.getAnnotationValue());
+ SourceLocation VisLoc = ConsumeToken();
+ Actions.ActOnPragmaVisibility(VisType, VisLoc);
+}
+
// #pragma GCC visibility comes in two variants:
// 'push' '(' [visibility] ')'
// 'pop'
@@ -77,7 +85,14 @@ void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP,
return;
}
- Actions.ActOnPragmaVisibility(VisType, VisLoc);
+ Token *Toks = new Token[1];
+ Toks[0].startToken();
+ Toks[0].setKind(tok::annot_pragma_vis);
+ Toks[0].setLocation(VisLoc);
+ Toks[0].setAnnotationValue(
+ const_cast<void*>(static_cast<const void*>(VisType)));
+ PP.EnterTokenStream(Toks, 1, /*DisableMacroExpansion=*/true,
+ /*OwnsTokens=*/true);
}
// #pragma pack(...) comes in the following delicious flavors:
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 45b4a745838..7f7fdf7c448 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -543,6 +543,9 @@ Parser::ParseExternalDeclaration(ParsedAttributesWithRange &attrs,
Decl *SingleDecl = 0;
switch (Tok.getKind()) {
+ case tok::annot_pragma_vis:
+ HandlePragmaVisibility();
+ return DeclGroupPtrTy();
case tok::semi:
Diag(Tok, getLang().CPlusPlus0x ?
diag::warn_cxx98_compat_top_level_semi : diag::ext_top_level_semi)
diff --git a/clang/test/CodeGenCXX/pr11797.cpp b/clang/test/CodeGenCXX/pr11797.cpp
new file mode 100644
index 00000000000..05221acc84f
--- /dev/null
+++ b/clang/test/CodeGenCXX/pr11797.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s -fvisibility hidden -emit-llvm -o - | FileCheck %s
+
+namespace std __attribute__ ((__visibility__ ("default"))) {}
+#pragma GCC visibility push(default)
+void foo() {
+}
+#pragma GCC visibility pop
+// CHECK: define void @_Z3foov()
diff --git a/clang/test/CodeGenCXX/pragma-visibility.cpp b/clang/test/CodeGenCXX/pragma-visibility.cpp
index 2dc8bcc74fa..97f8cc8bb85 100644
--- a/clang/test/CodeGenCXX/pragma-visibility.cpp
+++ b/clang/test/CodeGenCXX/pragma-visibility.cpp
@@ -55,8 +55,6 @@ namespace n __attribute((visibility("default"))) {
#pragma GCC visibility pop
namespace n __attribute((visibility("default"))) {
- extern int foofoo; // FIXME: Shouldn't be necessary, but otherwise the pragma
- // gets to Sema before the namespace!
#pragma GCC visibility push(hidden)
void g() {}
// CHECK: define hidden void @_ZN1n1gEv
@@ -66,8 +64,6 @@ namespace n __attribute((visibility("default"))) {
// We used to test this, but it's insane, so unless it happens in
// headers, we should not support it.
namespace n __attribute((visibility("hidden"))) {
- extern int foofoo; // FIXME: Shouldn't be necessary, but otherwise the pragma
- // gets to Sema before the namespace!
#pragma GCC visibility pop
void h() {}
// CHECK disabled: define void @_ZN1n1hEv
OpenPOWER on IntegriCloud