Remove hasExternalLinkageUncached.
authorRafael Espindola <rafael.espindola@gmail.com>
Mon, 15 Apr 2013 12:49:13 +0000 (12:49 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Mon, 15 Apr 2013 12:49:13 +0000 (12:49 +0000)
It was being used correctly, but it is a very dangerous API to have around.
Instead, move the logic from the filtering to when we are deciding if we should
link two decls.

llvm-svn: 179523

clang/include/clang/AST/Decl.h
clang/include/clang/Sema/Sema.h
clang/lib/AST/Decl.cpp
clang/lib/Sema/SemaDecl.cpp
clang/lib/Sema/SemaOverload.cpp

index f0832dc..4260ab0 100644 (file)
@@ -219,10 +219,6 @@ 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 9e9fda7..67dacfc 100644 (file)
@@ -203,6 +203,17 @@ class Sema {
 
   static bool mightHaveNonExternalLinkage(const DeclaratorDecl *FD);
 
+  static bool
+  shouldLinkPossiblyHiddenDecl(const NamedDecl *Old, const NamedDecl *New) {
+    // We are about to link these. It is now safe to compute the linkage of
+    // the new decl. If the new decl has external linkage, we will
+    // link it with the hidden decl (which also has external linkage) and
+    // it will keep having external linkage. If it has internal linkage, we
+    // will not link it. Since it has no previous decls, it will remain
+    // with internal linkage.
+    return !Old->isHidden() || New->hasExternalLinkage();
+  }
+
 public:
   typedef OpaquePtr<DeclGroupRef> DeclGroupPtrTy;
   typedef OpaquePtr<TemplateName> TemplateTy;
index bf807ae..9505d29 100644 (file)
@@ -866,10 +866,6 @@ 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 9b3083a..a17e9d0 100644 (file)
@@ -1613,20 +1613,7 @@ static void filterNonConflictingPreviousDecls(ASTContext &context,
     if (!old->isHidden())
       continue;
 
-    // If either has no-external linkage, ignore the old declaration.
-    // 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())
+    if (old->getLinkage() != ExternalLinkage)
       filter.erase();
   }
 
@@ -2881,6 +2868,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous,
     return New->setInvalidDecl();
   }
 
+  if (!shouldLinkPossiblyHiddenDecl(Old, New))
+    return;
+
   // C++ [class.mem]p1:
   //   A member shall not be declared twice in the member-specification [...]
   // 
@@ -6687,8 +6677,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
     // there's no more work to do here; we'll just add the new
     // function to the scope.
     if (!AllowOverloadingOfFunction(Previous, Context)) {
-      Redeclaration = true;
-      OldDecl = Previous.getFoundDecl();
+      NamedDecl *Candidate = Previous.getFoundDecl();
+      if (shouldLinkPossiblyHiddenDecl(Candidate, NewFD)) {
+        Redeclaration = true;
+        OldDecl = Candidate;
+      }
     } else {
       switch (CheckOverload(S, NewFD, Previous, OldDecl,
                             /*NewIsUsingDecl*/ false)) {
index 22b2a4a..dec4938 100644 (file)
@@ -940,6 +940,9 @@ Sema::CheckOverload(Scope *S, FunctionDecl *New, const LookupResult &Old,
           continue;
         }
 
+        if (!shouldLinkPossiblyHiddenDecl(*I, New))
+          continue;
+
         Match = *I;
         return Ovl_Match;
       }