aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-03-02 21:41:48 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-03-02 21:41:48 +0000
commit65611bf036dab4e2ba90b1316b1b21b276dde185 (patch)
tree919309cba58c6cbbb6341037ffee58de1fd96bb1
parentb88d9480e04039188c39e49367cb13d64e644cf8 (diff)
Process #pragma weak only after we know the linkage of the function or variable
we are looking at. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176414 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang/Sema/Sema.h1
-rw-r--r--lib/Sema/SemaDecl.cpp2
-rw-r--r--lib/Sema/SemaDeclAttr.cpp48
-rw-r--r--test/SemaCXX/pragma-weak.cpp8
4 files changed, 35 insertions, 24 deletions
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 12a787e329..df746928c8 100644
--- a/include/clang/Sema/Sema.h
+++ b/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/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2416f39442..c21cf03844 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/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/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 25202b1b3c..2778d6e648 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/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<VarDecl>(D))
- if (VD->isExternC())
- ND = VD;
- if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
- if (FD->isExternC())
- ND = FD;
- if (ND) {
- if (IdentifierInfo *Id = ND->getIdentifier()) {
- llvm::DenseMap<IdentifierInfo*,WeakInfo>::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<VarDecl>(D))
+ if (VD->isExternC())
+ ND = VD;
+ if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+ if (FD->isExternC())
+ ND = FD;
+ if (ND) {
+ if (IdentifierInfo *Id = ND->getIdentifier()) {
+ llvm::DenseMap<IdentifierInfo*,WeakInfo>::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/test/SemaCXX/pragma-weak.cpp b/test/SemaCXX/pragma-weak.cpp
new file mode 100644
index 0000000000..057cf6b463
--- /dev/null
+++ b/test/SemaCXX/pragma-weak.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 %s
+
+#pragma weak foo
+static void foo();
+extern "C" {
+ void foo() {
+ };
+}