]> granicus.if.org Git - clang/commitdiff
Implement declaration merging for variables in disjoint modules.
authorDouglas Gregor <dgregor@apple.com>
Wed, 4 Jan 2012 17:21:36 +0000 (17:21 +0000)
committerDouglas Gregor <dgregor@apple.com>
Wed, 4 Jan 2012 17:21:36 +0000 (17:21 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147535 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Serialization/ASTReaderDecl.cpp
test/Modules/Inputs/redecl-merge-left.h
test/Modules/Inputs/redecl-merge-right.h
test/Modules/redecl-merge.m

index c34243f60163ef233f4d643fb2b3713f866c0619..84f7545e6a64e3a3ffb605b2e47e9fcadbf2d72e 100644 (file)
@@ -880,8 +880,12 @@ void ASTDeclReader::VisitIndirectFieldDecl(IndirectFieldDecl *FD) {
 }
 
 void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
-  VisitRedeclarable(VD);
+  // Record the declaration -> global ID mapping.
+  Reader.DeclToID[VD] = ThisDeclID;
+  
+  RedeclarableResult Redecl = VisitRedeclarable(VD);
   VisitDeclaratorDecl(VD);
+  
   VD->VarDeclBits.SClass = (StorageClass)Record[Idx++];
   VD->VarDeclBits.SClassAsWritten = (StorageClass)Record[Idx++];
   VD->VarDeclBits.ThreadSpecified = Record[Idx++];
@@ -890,6 +894,9 @@ void ASTDeclReader::VisitVarDecl(VarDecl *VD) {
   VD->VarDeclBits.NRVOVariable = Record[Idx++];
   VD->VarDeclBits.CXXForRangeDecl = Record[Idx++];
   VD->VarDeclBits.ARCPseudoStrong = Record[Idx++];
+  
+  mergeRedeclarable(VD, Redecl);
+  
   if (uint64_t Val = Record[Idx++]) {
     VD->setInit(Reader.ReadExpr(F));
     if (Val > 1) {
@@ -1707,12 +1714,20 @@ static bool isSameEntity(NamedDecl *X, NamedDecl *Y) {
   }
   
   // Functions with the same type and linkage match.
+  // FIXME: This needs to cope with function templates, merging of 
+  //prototyped/non-prototyped functions, etc.
   if (FunctionDecl *FuncX = dyn_cast<FunctionDecl>(X)) {
     FunctionDecl *FuncY = cast<FunctionDecl>(Y);
     return (FuncX->getLinkage() == FuncY->getLinkage()) &&
       FuncX->getASTContext().hasSameType(FuncX->getType(), FuncY->getType());
   }
   
+  // Variables with the same type and linkage match.
+  if (VarDecl *VarX = dyn_cast<VarDecl>(X)) {
+    VarDecl *VarY = cast<VarDecl>(Y);
+    return (VarX->getLinkage() == VarY->getLinkage()) &&
+      VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType());
+  }
   
   // FIXME: Many other cases to implement.
   return false;
index 3eb0a735fa96b3ea6539d3612473e33f20313adf..632125ddb111a88926b77249dedd8ecaebcd585e 100644 (file)
@@ -63,6 +63,21 @@ int func0(int);
 int func1(int);
 int func2(int);
 
+
+
+
+
+
+
+
+
+
+// Spacing matters!
+extern int var1;
+extern float var2;
+
+extern double var3;
+
 #ifdef __cplusplus
 template<typename T> class Vector;
 
index 9660199c72d80ee2fa5f9a4bfce3111f1e5f6583..86a3993bc47ce36c1351c55823b45bf27a662735 100644 (file)
@@ -69,6 +69,15 @@ int func1(int);
 int func1(int);
 static int func2(int);
 
+
+
+
+// Spacing matters!
+extern int var1;
+extern int var2;
+
+static double var3;
+
 #ifdef __cplusplus
 template<typename T> class Vector { 
 public:
index b8752610fb4db468b9b6b32a662bba28a34ffc80..b41986609c0133b2da61cb0d53f09aae698f3bad 100644 (file)
@@ -72,6 +72,14 @@ void testFuncMerge(int i) {
   func2(i); // expected-error{{call to 'func2' is ambiguous}}
 }
 
+void testVarMerge(int i) {
+  var1 = i;
+  // in other files: expected-note 2{{candidate found by name lookup is 'var2'}}
+  var2 = i; // expected-error{{reference to 'var2' is ambiguous}}
+  // in other files: expected-note 2{{candidate found by name lookup is 'var3'}}
+  var3 = i; // expected-error{{reference to 'var3' is ambiguous}}
+}
+
 // Test redeclarations of entities in explicit submodules, to make
 // sure we're maintaining the declaration chains even when normal name
 // lookup can't see what we're looking for.