r180634 - [Modules] Fix an issue where the reconstructed redeclaration chain was incomplete, missing the definition from a module.
Argyrios Kyrtzidis
akyrtzi at gmail.com
Fri Apr 26 14:33:35 PDT 2013
Author: akirtzidis
Date: Fri Apr 26 16:33:35 2013
New Revision: 180634
URL: http://llvm.org/viewvc/llvm-project?rev=180634&view=rev
Log:
[Modules] Fix an issue where the reconstructed redeclaration chain was incomplete, missing the definition from a module.
-Make sure that a deserialized external decl gets added to the TU scope.
-When associating an identifier with a set of decls, use the most recent local ones,
if they exist, otherwise associating decls from modules (that came after a local one)
will lead to an incomplete reconstructed re-declaration chain.
rdar://13712705
Added:
cfe/trunk/test/Modules/redecls/
cfe/trunk/test/Modules/redecls/a.h
cfe/trunk/test/Modules/redecls/b.h
cfe/trunk/test/Modules/redecls/main.m
cfe/trunk/test/Modules/redecls/module.map
Modified:
cfe/trunk/include/clang/Serialization/ASTReader.h
cfe/trunk/lib/Serialization/ASTReader.cpp
cfe/trunk/lib/Serialization/ASTWriter.cpp
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=180634&r1=180633&r2=180634&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Fri Apr 26 16:33:35 2013
@@ -1106,6 +1106,8 @@ private:
void finishPendingActions();
+ void pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name);
+
void addPendingDeclContextInfo(Decl *D,
serialization::GlobalDeclID SemaDC,
serialization::GlobalDeclID LexicalDC) {
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=180634&r1=180633&r2=180634&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Fri Apr 26 16:33:35 2013
@@ -6005,8 +6005,8 @@ void ASTReader::InitializeSema(Sema &S)
// Makes sure any declarations that were deserialized "too early"
// still get added to the identifier's declaration chains.
for (unsigned I = 0, N = PreloadedDecls.size(); I != N; ++I) {
- NamedDecl *ND = cast<NamedDecl>(PreloadedDecls[I]->getMostRecentDecl());
- SemaObj->pushExternalDeclIntoScope(ND, PreloadedDecls[I]->getDeclName());
+ pushExternalDeclIntoScope(PreloadedDecls[I],
+ PreloadedDecls[I]->getDeclName());
}
PreloadedDecls.clear();
@@ -6420,8 +6420,7 @@ ASTReader::SetGloballyVisibleDecls(Ident
// Introduce this declaration into the translation-unit scope
// and add it to the declaration chain for this identifier, so
// that (unqualified) name lookup will find it.
- NamedDecl *ND = cast<NamedDecl>(D->getMostRecentDecl());
- SemaObj->pushExternalDeclIntoScope(ND, II);
+ pushExternalDeclIntoScope(D, II);
} else {
// Queue this declaration so that it will be added to the
// translation unit scope and identifier's declaration chain
@@ -7208,8 +7207,7 @@ void ASTReader::finishPendingActions() {
TLD != TLDEnd; ++TLD) {
IdentifierInfo *II = TLD->first;
for (unsigned I = 0, N = TLD->second.size(); I != N; ++I) {
- NamedDecl *ND = cast<NamedDecl>(TLD->second[I]->getMostRecentDecl());
- SemaObj->pushExternalDeclIntoScope(ND, II);
+ pushExternalDeclIntoScope(cast<NamedDecl>(TLD->second[I]), II);
}
}
@@ -7349,6 +7347,21 @@ void ASTReader::FinishedDeserializing()
}
}
+void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
+ D = cast<NamedDecl>(D->getMostRecentDecl());
+
+ if (SemaObj->IdResolver.tryAddTopLevelDecl(D, Name) && SemaObj->TUScope) {
+ SemaObj->TUScope->AddDecl(D);
+ } else if (SemaObj->TUScope) {
+ // Adding the decl to IdResolver may have failed because it was already in
+ // (even though it was not added in scope). If it is already in, make sure
+ // it gets in the scope as well.
+ if (std::find(SemaObj->IdResolver.begin(Name),
+ SemaObj->IdResolver.end(), D) != SemaObj->IdResolver.end())
+ SemaObj->TUScope->AddDecl(D);
+ }
+}
+
ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
StringRef isysroot, bool DisableValidation,
bool AllowASTWithCompilerErrors, bool UseGlobalIndex)
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=180634&r1=180633&r2=180634&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Fri Apr 26 16:33:35 2013
@@ -3106,7 +3106,28 @@ public:
for (SmallVector<Decl *, 16>::reverse_iterator D = Decls.rbegin(),
DEnd = Decls.rend();
D != DEnd; ++D)
- clang::io::Emit32(Out, Writer.getDeclID(*D));
+ clang::io::Emit32(Out, Writer.getDeclID(getMostRecentLocalDecl(*D)));
+ }
+
+ /// \brief Returns the most recent local decl or the given decl if there are
+ /// no local ones. The given decl is assumed to be the most recent one.
+ Decl *getMostRecentLocalDecl(Decl *Orig) {
+ // The only way a "from AST file" decl would be more recent from a local one
+ // is if it came from a module.
+ if (!PP.getLangOpts().Modules)
+ return Orig;
+
+ // Look for a local in the decl chain.
+ for (Decl *D = Orig; D; D = D->getPreviousDecl()) {
+ if (!D->isFromASTFile())
+ return D;
+ // If we come up a decl from a (chained-)PCH stop since we won't find a
+ // local one.
+ if (D->getOwningModuleID() == 0)
+ break;
+ }
+
+ return Orig;
}
};
} // end anonymous namespace
Added: cfe/trunk/test/Modules/redecls/a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecls/a.h?rev=180634&view=auto
==============================================================================
--- cfe/trunk/test/Modules/redecls/a.h (added)
+++ cfe/trunk/test/Modules/redecls/a.h Fri Apr 26 16:33:35 2013
@@ -0,0 +1,3 @@
+ at interface AA
+ at end
+ at class AA;
Added: cfe/trunk/test/Modules/redecls/b.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecls/b.h?rev=180634&view=auto
==============================================================================
--- cfe/trunk/test/Modules/redecls/b.h (added)
+++ cfe/trunk/test/Modules/redecls/b.h Fri Apr 26 16:33:35 2013
@@ -0,0 +1 @@
+ at class AA;
Added: cfe/trunk/test/Modules/redecls/main.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecls/main.m?rev=180634&view=auto
==============================================================================
--- cfe/trunk/test/Modules/redecls/main.m (added)
+++ cfe/trunk/test/Modules/redecls/main.m Fri Apr 26 16:33:35 2013
@@ -0,0 +1,27 @@
+// RUN: rm -rf %t.mcp
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=a %S/module.map -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=b %S/module.map -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t1.pch -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules %s -emit-pch -o %t2.pch -include-pch %t1.pch -fmodules-cache-path=%t.mcp
+// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -fmodules-cache-path=%t.mcp -verify
+
+#ifndef HEADER1
+#define HEADER1
+
+ at import a;
+
+#elif !defined(HEADER2)
+#define HEADER2
+
+ at class AA;
+ at import b;
+
+#else
+
+// rdar://13712705
+ at interface SS : AA
+ at end
+
+#warning parsed this
+#endif
+// expected-warning at -2{{parsed this}}
Added: cfe/trunk/test/Modules/redecls/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecls/module.map?rev=180634&view=auto
==============================================================================
--- cfe/trunk/test/Modules/redecls/module.map (added)
+++ cfe/trunk/test/Modules/redecls/module.map Fri Apr 26 16:33:35 2013
@@ -0,0 +1,2 @@
+module a { header "a.h" }
+module b { header "b.h" }
More information about the cfe-commits
mailing list