From de6a39f759c1f2aa5873d1c35ef21083144fe508 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Sat, 2 Mar 2013 21:41:48 +0000 Subject: [PATCH] Process #pragma weak only after we know the linkage of the function or variable we are looking at. llvm-svn: 176414 --- clang/include/clang/Sema/Sema.h | 1 + clang/lib/Sema/SemaDecl.cpp | 2 ++ clang/lib/Sema/SemaDeclAttr.cpp | 48 +++++++++++++++++++------------------- clang/test/SemaCXX/pragma-weak.cpp | 8 +++++++ 4 files changed, 35 insertions(+), 24 deletions(-) create mode 100644 clang/test/SemaCXX/pragma-weak.cpp diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 12a787e..df74692 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2340,6 +2340,7 @@ public: // More parsing and symbol table subroutines. + void ProcessPragmaWeak(Scope *S, Decl *D); // Decl attributes - this routine is the top level dispatcher. void ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, bool NonInheritable = true, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 2416f39..c21cf03 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -4900,6 +4900,7 @@ Sema::ActOnVariableDeclarator(Scope *S, Declarator &D, DeclContext *DC, NewVD->setInvalidDecl(); } + ProcessPragmaWeak(S, NewVD); checkAttributesAfterMerging(*this, *NewVD); // If this is a locally-scoped extern C variable, update the map of @@ -6368,6 +6369,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, } } + ProcessPragmaWeak(S, NewFD); checkAttributesAfterMerging(*this, *NewFD); AddKnownFunctionAttributes(NewFD); diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 25202b1..2778d6e6 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -5087,37 +5087,37 @@ void Sema::DeclApplyPragmaWeak(Scope *S, NamedDecl *ND, WeakInfo &W) { } } -/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in -/// it, apply them to D. This is a bit tricky because PD can have attributes -/// specified in many different places, and we need to find and apply them all. -void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, - bool NonInheritable, bool Inheritable) { +void Sema::ProcessPragmaWeak(Scope *S, Decl *D) { // It's valid to "forward-declare" #pragma weak, in which case we // have to do this. - if (Inheritable) { - LoadExternalWeakUndeclaredIdentifiers(); - if (!WeakUndeclaredIdentifiers.empty()) { - NamedDecl *ND = NULL; - if (VarDecl *VD = dyn_cast(D)) - if (VD->isExternC()) - ND = VD; - if (FunctionDecl *FD = dyn_cast(D)) - if (FD->isExternC()) - ND = FD; - if (ND) { - if (IdentifierInfo *Id = ND->getIdentifier()) { - llvm::DenseMap::iterator I - = WeakUndeclaredIdentifiers.find(Id); - if (I != WeakUndeclaredIdentifiers.end()) { - WeakInfo W = I->second; - DeclApplyPragmaWeak(S, ND, W); - WeakUndeclaredIdentifiers[Id] = W; - } + LoadExternalWeakUndeclaredIdentifiers(); + if (!WeakUndeclaredIdentifiers.empty()) { + NamedDecl *ND = NULL; + if (VarDecl *VD = dyn_cast(D)) + if (VD->isExternC()) + ND = VD; + if (FunctionDecl *FD = dyn_cast(D)) + if (FD->isExternC()) + ND = FD; + if (ND) { + if (IdentifierInfo *Id = ND->getIdentifier()) { + llvm::DenseMap::iterator I + = WeakUndeclaredIdentifiers.find(Id); + if (I != WeakUndeclaredIdentifiers.end()) { + WeakInfo W = I->second; + DeclApplyPragmaWeak(S, ND, W); + WeakUndeclaredIdentifiers[Id] = W; } } } } +} +/// ProcessDeclAttributes - Given a declarator (PD) with attributes indicated in +/// it, apply them to D. This is a bit tricky because PD can have attributes +/// specified in many different places, and we need to find and apply them all. +void Sema::ProcessDeclAttributes(Scope *S, Decl *D, const Declarator &PD, + bool NonInheritable, bool Inheritable) { // Apply decl attributes from the DeclSpec if present. if (const AttributeList *Attrs = PD.getDeclSpec().getAttributes().getList()) ProcessDeclAttributeList(S, D, Attrs, NonInheritable, Inheritable); diff --git a/clang/test/SemaCXX/pragma-weak.cpp b/clang/test/SemaCXX/pragma-weak.cpp new file mode 100644 index 0000000..057cf6b --- /dev/null +++ b/clang/test/SemaCXX/pragma-weak.cpp @@ -0,0 +1,8 @@ +// RUN: %clang_cc1 %s + +#pragma weak foo +static void foo(); +extern "C" { + void foo() { + }; +} -- 2.7.4