[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