diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/include/clang/Basic/TokenKinds.def | 5 | ||||
-rw-r--r-- | clang/include/clang/Parse/Parser.h | 4 | ||||
-rw-r--r-- | clang/lib/Parse/ParsePragma.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Parse/Parser.cpp | 3 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/pr11797.cpp | 8 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/pragma-visibility.cpp | 4 |
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 |