[cfe-commits] r110315 - in /cfe/trunk: include/clang/AST/Attr.h include/clang/Basic/DiagnosticSemaKinds.td include/clang/Parse/Action.h include/clang/Parse/Parser.h lib/AST/AttrImpl.cpp lib/CodeGen/CodeGenModule.cpp lib/Frontend/PCHReaderDecl.cpp lib/Frontend/PCHWriter.cpp lib/Parse/ParsePragma.cpp lib/Parse/ParsePragma.h lib/Parse/Parser.cpp lib/Sema/Sema.cpp lib/Sema/Sema.h lib/Sema/SemaAttr.cpp lib/Sema/SemaDecl.cpp lib/Sema/SemaDeclAttr.cpp lib/Sema/SemaDeclCXX.cpp

Eli Friedman eli.friedman at gmail.com
Wed Aug 4 23:57:21 PDT 2010


Author: efriedma
Date: Thu Aug  5 01:57:20 2010
New Revision: 110315

URL: http://llvm.org/viewvc/llvm-project?rev=110315&view=rev
Log:
Implement #pragma GCC visibility.


Modified:
    cfe/trunk/include/clang/AST/Attr.h
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h
    cfe/trunk/lib/AST/AttrImpl.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
    cfe/trunk/lib/Frontend/PCHWriter.cpp
    cfe/trunk/lib/Parse/ParsePragma.cpp
    cfe/trunk/lib/Parse/ParsePragma.h
    cfe/trunk/lib/Parse/Parser.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaAttr.cpp
    cfe/trunk/lib/Sema/SemaDecl.cpp
    cfe/trunk/lib/Sema/SemaDeclAttr.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp

Modified: cfe/trunk/include/clang/AST/Attr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Attr.h?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Attr.h (original)
+++ cfe/trunk/include/clang/AST/Attr.h Thu Aug  5 01:57:20 2010
@@ -540,12 +540,15 @@
   };
 private:
   VisibilityTypes VisibilityType;
+  bool FromPragma;
 public:
-  VisibilityAttr(VisibilityTypes v) : Attr(attr::Visibility),
-                 VisibilityType(v) {}
+  VisibilityAttr(VisibilityTypes v, bool fp) : Attr(attr::Visibility),
+                 VisibilityType(v), FromPragma(fp) {}
 
   VisibilityTypes getVisibility() const { return VisibilityType; }
 
+  bool isFromPragma() const { return FromPragma; }
+
   virtual Attr *clone(ASTContext &C) const;
 
   // Implement isa/cast/dyncast/etc.

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu Aug  5 01:57:20 2010
@@ -988,7 +988,7 @@
   "transparent_union attribute ignored">;
 def warn_attribute_type_not_supported : Warning<
   "'%0' attribute argument not supported: %1">;
-def warn_attribute_unknown_visibility : Warning<"unknown visibility '%1'">;
+def warn_attribute_unknown_visibility : Warning<"unknown visibility '%0'">;
 def err_unknown_machine_mode : Error<"unknown machine mode %0">;
 def err_unsupported_machine_mode : Error<"unsupported machine mode %0">;
 def err_mode_not_primitive : Error<

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Thu Aug  5 01:57:20 2010
@@ -2734,6 +2734,14 @@
     return;
   }
 
+
+  /// ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... .
+  virtual void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
+                                     SourceLocation PragmaLoc) {
+    return;
+  }
+
+
   /// ActOnPragmaWeakID - Called on well formed #pragma weak ident.
   virtual void ActOnPragmaWeakID(IdentifierInfo* WeakName,
                                  SourceLocation PragmaLoc,

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Thu Aug  5 01:57:20 2010
@@ -110,6 +110,7 @@
   IdentifierInfo *Ident_pixel;
 
   llvm::OwningPtr<PragmaHandler> AlignHandler;
+  llvm::OwningPtr<PragmaHandler> GCCVisibilityHandler;
   llvm::OwningPtr<PragmaHandler> OptionsHandler;
   llvm::OwningPtr<PragmaHandler> PackHandler;
   llvm::OwningPtr<PragmaHandler> UnusedHandler;

Modified: cfe/trunk/lib/AST/AttrImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/AttrImpl.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/AST/AttrImpl.cpp (original)
+++ cfe/trunk/lib/AST/AttrImpl.cpp Thu Aug  5 01:57:20 2010
@@ -213,7 +213,7 @@
 }
 
 Attr *VisibilityAttr::clone(ASTContext &C) const {
-  return ::new (C) VisibilityAttr(VisibilityType);
+  return ::new (C) VisibilityAttr(VisibilityType, FromPragma);
 }
 
 Attr *OverloadableAttr::clone(ASTContext &C) const {

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Thu Aug  5 01:57:20 2010
@@ -190,9 +190,11 @@
           return LangOptions::Hidden;
   }
            
-  // This decl should have the same visibility as its parent.
+  // If this decl is contained in a class, it should have the same visibility
+  // as the parent class.
   if (const DeclContext *DC = D->getDeclContext()) 
-    return getDeclVisibilityMode(cast<Decl>(DC));
+    if (DC->isRecord())
+      return getDeclVisibilityMode(cast<Decl>(DC));
 
   return getLangOptions().getVisibilityMode();
 }

Modified: cfe/trunk/lib/Frontend/PCHReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderDecl.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderDecl.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderDecl.cpp Thu Aug  5 01:57:20 2010
@@ -1292,7 +1292,8 @@
 
     case attr::Visibility:
       New = ::new (*Context) VisibilityAttr(
-                              (VisibilityAttr::VisibilityTypes)Record[Idx++]);
+                              (VisibilityAttr::VisibilityTypes)Record[Idx++],
+                              (bool)Record[Idx++]);
       break;
 
     SIMPLE_ATTR(WarnUnusedResult);

Modified: cfe/trunk/lib/Frontend/PCHWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriter.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriter.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriter.cpp Thu Aug  5 01:57:20 2010
@@ -2106,6 +2106,7 @@
     case attr::Visibility:
       // FIXME: stable encoding
       Record.push_back(cast<VisibilityAttr>(Attr)->getVisibility());
+      Record.push_back(cast<VisibilityAttr>(Attr)->isFromPragma());
       break;
 
     case attr::WarnUnusedResult:

Modified: cfe/trunk/lib/Parse/ParsePragma.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.cpp (original)
+++ cfe/trunk/lib/Parse/ParsePragma.cpp Thu Aug  5 01:57:20 2010
@@ -18,6 +18,59 @@
 #include "clang/Parse/Parser.h"
 using namespace clang;
 
+
+// #pragma GCC visibility comes in two variants:
+//   'push' '(' [visibility] ')'
+//   'pop'
+void PragmaGCCVisibilityHandler::HandlePragma(Preprocessor &PP, Token &VisTok) {
+  SourceLocation VisLoc = VisTok.getLocation();
+
+  Token Tok;
+  PP.Lex(Tok);
+
+  const IdentifierInfo *PushPop = Tok.getIdentifierInfo();
+
+  bool IsPush;
+  const IdentifierInfo *VisType;
+  if (PushPop && PushPop->isStr("pop")) {
+    IsPush = false;
+    VisType = 0;
+  } else if (PushPop && PushPop->isStr("push")) {
+    IsPush = true;
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::l_paren)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_lparen)
+        << "visibility";
+      return;
+    }
+    PP.Lex(Tok);
+    VisType = Tok.getIdentifierInfo();
+    if (!VisType) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+        << "visibility";
+      return;
+    }
+    PP.Lex(Tok);
+    if (Tok.isNot(tok::r_paren)) {
+      PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_rparen)
+        << "visibility";
+      return;
+    }
+  } else {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_expected_identifier)
+      << "visibility";
+    return;
+  }
+  PP.Lex(Tok);
+  if (Tok.isNot(tok::eom)) {
+    PP.Diag(Tok.getLocation(), diag::warn_pragma_extra_tokens_at_eol)
+      << "visibility";
+    return;
+  }
+
+  Actions.ActOnPragmaVisibility(IsPush, VisType, VisLoc);
+}
+
 // #pragma pack(...) comes in the following delicious flavors:
 //   pack '(' [integer] ')'
 //   pack '(' 'show' ')'

Modified: cfe/trunk/lib/Parse/ParsePragma.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParsePragma.h?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParsePragma.h (original)
+++ cfe/trunk/lib/Parse/ParsePragma.h Thu Aug  5 01:57:20 2010
@@ -28,6 +28,15 @@
   virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
 };
 
+class PragmaGCCVisibilityHandler : public PragmaHandler {
+  Action &Actions;
+public:
+  explicit PragmaGCCVisibilityHandler(Action &A) : PragmaHandler("visibility"),
+                                                   Actions(A) {}
+
+  virtual void HandlePragma(Preprocessor &PP, Token &FirstToken);
+};
+
 class PragmaOptionsHandler : public PragmaHandler {
   Action &Actions;
 public:

Modified: cfe/trunk/lib/Parse/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/Parser.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/Parser.cpp (original)
+++ cfe/trunk/lib/Parse/Parser.cpp Thu Aug  5 01:57:20 2010
@@ -36,6 +36,9 @@
   AlignHandler.reset(new PragmaAlignHandler(actions));
   PP.AddPragmaHandler(AlignHandler.get());
 
+  GCCVisibilityHandler.reset(new PragmaGCCVisibilityHandler(actions));
+  PP.AddPragmaHandler("GCC", GCCVisibilityHandler.get());
+
   OptionsHandler.reset(new PragmaOptionsHandler(actions));
   PP.AddPragmaHandler(OptionsHandler.get());
 
@@ -303,6 +306,8 @@
   // Remove the pragma handlers we installed.
   PP.RemovePragmaHandler(AlignHandler.get());
   AlignHandler.reset();
+  PP.RemovePragmaHandler("GCC", GCCVisibilityHandler.get());
+  GCCVisibilityHandler.reset();
   PP.RemovePragmaHandler(OptionsHandler.get());
   OptionsHandler.reset();
   PP.RemovePragmaHandler(PackHandler.get());

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Thu Aug  5 01:57:20 2010
@@ -126,7 +126,7 @@
     LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer),
     Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()),
     ExternalSource(0), CodeCompleter(CodeCompleter), CurContext(0), 
-    PackContext(0), TopFunctionScope(0), ParsingDeclDepth(0),
+    PackContext(0), VisContext(0), TopFunctionScope(0), ParsingDeclDepth(0),
     IdResolver(pp.getLangOptions()), GlobalNewDeleteDeclared(false), 
     CompleteTranslationUnit(CompleteTranslationUnit),
     NumSFINAEErrors(0), SuppressAccessChecking(false),
@@ -147,6 +147,7 @@
 
 Sema::~Sema() {
   if (PackContext) FreePackedContext();
+  if (VisContext) FreeVisContext();
   delete TheTargetAttributesSema;
   while (!FunctionScopes.empty())
     PopFunctionOrBlockScope();

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Thu Aug  5 01:57:20 2010
@@ -285,6 +285,9 @@
   /// of 0 indicates default alignment.
   void *PackContext; // Really a "PragmaPackStack*"
 
+  /// VisContext - Manages the stack for #pragma GCC visibility.
+  void *VisContext; // Really a "PragmaVisStack*"
+
   /// \brief Stack containing information about each of the nested function,
   /// block, and method scopes that are currently active.
   llvm::SmallVector<FunctionScopeInfo *, 4> FunctionScopes;
@@ -4199,6 +4202,10 @@
                                  SourceLocation LParenLoc,
                                  SourceLocation RParenLoc);
 
+  /// ActOnPragmaVisibility - Called on well formed #pragma GCC visibility... .
+  virtual void ActOnPragmaVisibility(bool IsPush, const IdentifierInfo* VisType,
+                                     SourceLocation PragmaLoc);
+
   NamedDecl *DeclClonePragmaWeak(NamedDecl *ND, IdentifierInfo *II);
   void DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W);
 
@@ -4221,6 +4228,21 @@
   /// FreePackedContext - Deallocate and null out PackContext.
   void FreePackedContext();
 
+  /// AddPushedVisibilityAttribute - If '#pragma GCC visibility' was used,
+  /// add an appropriate visibility attribute.
+  void AddPushedVisibilityAttribute(Decl *RD);
+
+  /// PushPragmaVisibility - Push the top element of the visibility stack; used
+  ///  for '#pragma GCC visibility' and visibility attributes on namespaces.
+  void PushPragmaVisibility(VisibilityAttr::VisibilityTypes type);
+
+  /// PopPragmaVisibility - Pop the top element of the visibility stack; used
+  /// for '#pragma GCC visibility' and visibility attributes on namespaces.
+  void PopPragmaVisibility();
+
+  /// FreeVisContext - Deallocate and null out VisContext.
+  void FreeVisContext();
+
   /// AddAlignedAttr - Adds an aligned attribute to a particular declaration.
   void AddAlignedAttr(SourceLocation AttrLoc, Decl *D, Expr *E);
 

Modified: cfe/trunk/lib/Sema/SemaAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaAttr.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaAttr.cpp Thu Aug  5 01:57:20 2010
@@ -288,3 +288,70 @@
     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.
+}

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Aug  5 01:57:20 2010
@@ -2680,6 +2680,11 @@
       !NewVD->isInvalidDecl())
     RegisterLocallyScopedExternCDecl(NewVD, Previous, S);
 
+  // If there's a #pragma GCC visibility in scope, and this isn't a class
+  // member, set the visibility of this variable.
+  if (NewVD->getLinkage() == ExternalLinkage && !DC->isRecord())
+    AddPushedVisibilityAttribute(NewVD);
+
   return NewVD;
 }
 
@@ -3529,6 +3534,11 @@
     NewFD->addAttr(::new (Context) OverloadableAttr());
   }
 
+  // If there's a #pragma GCC visibility in scope, and this isn't a class
+  // member, set the visibility of this function.
+  if (NewFD->getLinkage() == ExternalLinkage && !DC->isRecord())
+    AddPushedVisibilityAttribute(NewFD);
+
   // If this is a locally-scoped extern C function, update the
   // map of such names.
   if (CurContext->isFunctionOrMethod() && NewFD->isExternC()
@@ -6367,6 +6377,11 @@
 
   if (Attr)
     ProcessDeclAttributeList(S, Record, Attr);
+
+  // If there's a #pragma GCC visibility in scope, and this isn't a subclass,
+  // set the visibility of this record.
+  if (Record && !Record->getDeclContext()->isRecord())
+    AddPushedVisibilityAttribute(Record);
 }
 
 /// \brief Determine whether the given integral value is representable within

Modified: cfe/trunk/lib/Sema/SemaDeclAttr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclAttr.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclAttr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclAttr.cpp Thu Aug  5 01:57:20 2010
@@ -847,7 +847,7 @@
     return;
   }
 
-  d->addAttr(::new (S.Context) VisibilityAttr(type));
+  d->addAttr(::new (S.Context) VisibilityAttr(type, false));
 }
 
 static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=110315&r1=110314&r2=110315&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Aug  5 01:57:20 2010
@@ -3179,6 +3179,9 @@
 
   ProcessDeclAttributeList(DeclRegionScope, Namespc, AttrList);
 
+  if (const VisibilityAttr *attr = Namespc->getAttr<VisibilityAttr>())
+    PushPragmaVisibility(attr->getVisibility());
+
   if (II) {
     // C++ [namespace.def]p2:
     // The identifier in an original-namespace-definition shall not have been
@@ -3310,6 +3313,8 @@
   assert(Namespc && "Invalid parameter, expected NamespaceDecl");
   Namespc->setRBracLoc(RBrace);
   PopDeclContext();
+  if (Namespc->hasAttr<VisibilityAttr>())
+    PopPragmaVisibility();
 }
 
 /// \brief Retrieve the special "std" namespace, which may require us to 





More information about the cfe-commits mailing list