[cfe-commits] r147533 - in /cfe/trunk/lib: Sema/SemaLookup.cpp Serialization/ASTReaderDecl.cpp

Douglas Gregor dgregor at apple.com
Wed Jan 4 08:44:10 PST 2012


Author: dgregor
Date: Wed Jan  4 10:44:10 2012
New Revision: 147533

URL: http://llvm.org/viewvc/llvm-project?rev=147533&view=rev
Log:
Implement declaration merging for typedefs loaded from disjoint
modules, so long as the typedefs refer to the same underlying
type. This ensures that the typedefs end up in the same redeclaration
chain.

To test this, fix name lookup for C/Objective-C to properly deal with
multiple declarations with the same name in the same scope.

Modified:
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=147533&r1=147532&r2=147533&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Jan  4 10:44:10 2012
@@ -1179,29 +1179,28 @@
 
         // Check whether there are any other declarations with the same name
         // and in the same scope.
+        if (I != IEnd) {
+          DeclContext *DC = (*I)->getDeclContext()->getRedeclContext();
+          IdentifierResolver::iterator LastI = I;
+          for (++LastI; LastI != IEnd; ++LastI) {
+            DeclContext *LastDC 
+              = (*LastI)->getDeclContext()->getRedeclContext();
+            if (!(*LastI)->isInIdentifierNamespace(IDNS))
+              continue;
+            
+            if (!LastDC->Equals(DC))
+              break;
+            
+            if (!LastDC->isFileContext() && !S->isDeclScope(*LastI))
+              break;
+            
+            D = R.isForRedeclaration()? *LastI : getVisibleDecl(*LastI);
+            if (D)
+              R.addDecl(D);
+          }
 
-        // Figure out what scope the identifier is in.
-        while (S->getParent() &&
-               (!(S->getFlags() & Scope::DeclScope) ||
-                !S->isDeclScope(*I)))
-          S = S->getParent();
-
-        // Find the last declaration in this scope (with the same
-        // name, naturally).
-        IdentifierResolver::iterator LastI = I;
-        for (++LastI; LastI != IEnd; ++LastI) {
-          if (!S->isDeclScope(*LastI))
-            break;
-          
-          if (!(*LastI)->isInIdentifierNamespace(IDNS))
-            continue;
-          
-          D = R.isForRedeclaration()? *LastI : getVisibleDecl(*LastI);
-          if (D)
-            R.addDecl(D);
+          R.resolveKind();
         }
-
-        R.resolveKind();
         return true;
       }
   } else {

Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=147533&r1=147532&r2=147533&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Jan  4 10:44:10 2012
@@ -402,9 +402,14 @@
 }
 
 void ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
-  VisitRedeclarable(TD);
+  // Record the declaration -> global ID mapping.
+  Reader.DeclToID[TD] = ThisDeclID;
+  
+  RedeclarableResult Redecl = VisitRedeclarable(TD);
   VisitTypeDecl(TD);
-  TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));  
+  
+  TD->setTypeSourceInfo(GetTypeSourceInfo(Record, Idx));
+  mergeRedeclarable(TD, Redecl);
 }
 
 void ASTDeclReader::VisitTypedefDecl(TypedefDecl *TD) {
@@ -1668,15 +1673,22 @@
   if (X == Y)
     return true;
   
-  // Must have the same kind.
-  if (X->getKind() != Y->getKind())
-    return false;
-  
   // Must be in the same context.
   if (!X->getDeclContext()->getRedeclContext()->Equals(
          Y->getDeclContext()->getRedeclContext()))
     return false;
+
+  // Two typedefs refer to the same entity if they have the same underlying
+  // type.
+  if (TypedefNameDecl *TypedefX = dyn_cast<TypedefNameDecl>(X))
+    if (TypedefNameDecl *TypedefY = dyn_cast<TypedefNameDecl>(Y))
+      return X->getASTContext().hasSameType(TypedefX->getUnderlyingType(),
+                                            TypedefY->getUnderlyingType());
   
+  // Must have the same kind.
+  if (X->getKind() != Y->getKind())
+    return false;
+    
   // Objective-C classes and protocols with the same name always match.
   if (isa<ObjCInterfaceDecl>(X) || isa<ObjCProtocolDecl>(X))
     return true;





More information about the cfe-commits mailing list