From: Douglas Gregor Date: Wed, 4 Jan 2012 17:21:36 +0000 (+0000) Subject: Implement declaration merging for variables in disjoint modules. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=4791fa2c3c16c51c8435706682ec0fec8647335a;p=clang Implement declaration merging for variables in disjoint modules. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@147535 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Serialization/ASTReaderDecl.cpp b/lib/Serialization/ASTReaderDecl.cpp index c34243f601..84f7545e6a 100644 --- a/lib/Serialization/ASTReaderDecl.cpp +++ b/lib/Serialization/ASTReaderDecl.cpp @@ -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(X)) { FunctionDecl *FuncY = cast(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(X)) { + VarDecl *VarY = cast(Y); + return (VarX->getLinkage() == VarY->getLinkage()) && + VarX->getASTContext().hasSameType(VarX->getType(), VarY->getType()); + } // FIXME: Many other cases to implement. return false; diff --git a/test/Modules/Inputs/redecl-merge-left.h b/test/Modules/Inputs/redecl-merge-left.h index 3eb0a735fa..632125ddb1 100644 --- a/test/Modules/Inputs/redecl-merge-left.h +++ b/test/Modules/Inputs/redecl-merge-left.h @@ -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 class Vector; diff --git a/test/Modules/Inputs/redecl-merge-right.h b/test/Modules/Inputs/redecl-merge-right.h index 9660199c72..86a3993bc4 100644 --- a/test/Modules/Inputs/redecl-merge-right.h +++ b/test/Modules/Inputs/redecl-merge-right.h @@ -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 class Vector { public: diff --git a/test/Modules/redecl-merge.m b/test/Modules/redecl-merge.m index b8752610fb..b41986609c 100644 --- a/test/Modules/redecl-merge.m +++ b/test/Modules/redecl-merge.m @@ -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.