]> granicus.if.org Git - clang/commitdiff
Add hasExternalLinkageUncached back with the test that Richard provided, but
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 4 Apr 2013 04:40:17 +0000 (04:40 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 4 Apr 2013 04:40:17 +0000 (04:40 +0000)
keep the call at the current location.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178741 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Decl.h
lib/AST/Decl.cpp
lib/Sema/SemaDecl.cpp
test/Modules/Inputs/linkage-merge-bar.h [new file with mode: 0644]
test/Modules/Inputs/linkage-merge-foo.h [new file with mode: 0644]
test/Modules/Inputs/module.map
test/Modules/linkage-merge.cpp [new file with mode: 0644]

index 0294b9fde8af5177898312e365ff0b3599cb6546..7927279ddd6d4276de665db93b9f780ccca71507 100644 (file)
@@ -219,6 +219,10 @@ public:
     return getLinkage() == ExternalLinkage;
   }
 
+  /// \brief True if this decl has external linkage. Don't cache the linkage,
+  /// because we are not finished setting up the redecl chain for the decl.
+  bool hasExternalLinkageUncached() const;
+
   /// \brief Determines the visibility of this entity.
   Visibility getVisibility() const {
     return getLinkageAndVisibility().getVisibility();
index 9505d299ab1debfc7990d2bcd1a465b141f38069..bf807aeb1d690de662c2c3b34f69e2ace42dcd94 100644 (file)
@@ -866,6 +866,10 @@ bool NamedDecl::isLinkageValid() const {
     Linkage(CachedLinkage);
 }
 
+bool NamedDecl::hasExternalLinkageUncached() const {
+  return getLVForDecl(this, LVForExplicitValue).getLinkage() == ExternalLinkage;
+}
+
 Linkage NamedDecl::getLinkage() const {
   if (HasCachedLinkage)
     return Linkage(CachedLinkage);
index 0ad539ef17268ab357db571abe6d20bad7bab89e..436fca35cbc83d9be44487be1d7c65b1bafc3e8e 100644 (file)
@@ -1614,7 +1614,19 @@ static void filterNonConflictingPreviousDecls(ASTContext &context,
       continue;
 
     // If either has no-external linkage, ignore the old declaration.
-    if (old->getLinkage() != ExternalLinkage || !decl->hasExternalLinkage())
+    // If this declaration would have external linkage if it were the first
+    // declaration of this name, then it may in fact be a redeclaration of
+    // some hidden declaration, so include those too. We don't need to worry
+    // about some previous visible declaration giving this declaration external
+    // linkage, because in that case, we'll mark this declaration as a redecl
+    // of the visible decl, and that decl will already be a redecl of the
+    // hidden declaration if that's appropriate.
+    //
+    // Don't cache this linkage computation, because it's not yet correct: we
+    // may later give this declaration a previous declaration which changes
+    // its linkage.
+    if (old->getLinkage() != ExternalLinkage ||
+        !decl->hasExternalLinkageUncached())
       filter.erase();
   }
 
diff --git a/test/Modules/Inputs/linkage-merge-bar.h b/test/Modules/Inputs/linkage-merge-bar.h
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/Modules/Inputs/linkage-merge-foo.h b/test/Modules/Inputs/linkage-merge-foo.h
new file mode 100644 (file)
index 0000000..7ed7775
--- /dev/null
@@ -0,0 +1 @@
+int f();
index 595e5d88468a96d71837e5402af17e4f0a7777e2..d20521f9c7649e2398ef641ec63334de209d6967 100644 (file)
@@ -199,3 +199,13 @@ module builtin {
     header "builtin_sub.h"
   }
 }
+
+module linkage_merge {
+  explicit module foo {
+    header "linkage-merge-foo.h"
+  }
+  explicit module bar {
+    header "linkage-merge-bar.h"
+  }
+
+}
diff --git a/test/Modules/linkage-merge.cpp b/test/Modules/linkage-merge.cpp
new file mode 100644 (file)
index 0000000..dafb009
--- /dev/null
@@ -0,0 +1,7 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs %s
+
+#include "linkage-merge-bar.h"
+
+static int f(int);
+int f(int);