summaryrefslogtreecommitdiffstats
path: root/clang/lib/Serialization/ASTWriter.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2015-10-13 00:23:25 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2015-10-13 00:23:25 +0000
commitf983f7f6270275543ce0f873b65ce5838c40da1b (patch)
treef1f8bef16b9b6100ceecb04d9e028f869d865e12 /clang/lib/Serialization/ASTWriter.cpp
parentf03f3cc18cccbd7167540539bd9bece1d1ccccaf (diff)
downloadbcm5719-llvm-f983f7f6270275543ce0f873b65ce5838c40da1b.tar.gz
bcm5719-llvm-f983f7f6270275543ce0f873b65ce5838c40da1b.zip
[modules] Fix merging of __va_list_tag's implicit special member functions.
We model predefined declarations as not being from AST files, but in most ways they act as if they come from some implicit prebuilt module file imported before all others. Therefore, if we see an update to the predefined 'struct __va_list_tag' declaration (and we've already loaded any modules), it needs a corresponding update record, even though it didn't technically come from an AST file. llvm-svn: 250134
Diffstat (limited to 'clang/lib/Serialization/ASTWriter.cpp')
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp37
1 files changed, 31 insertions, 6 deletions
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 95c1620fcbb..331fa385905 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -5630,27 +5630,52 @@ void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
}
}
+static bool isImportedDeclContext(ASTReader *Chain, const Decl *D) {
+ if (D->isFromASTFile())
+ return true;
+
+ // If we've not loaded any modules, this can't be imported.
+ if (!Chain || !Chain->getModuleManager().size())
+ return false;
+
+ // The predefined __va_list_tag struct is imported if we imported any decls.
+ // FIXME: This is a gross hack.
+ return D == D->getASTContext().getVaListTagDecl();
+}
+
void ASTWriter::AddedVisibleDecl(const DeclContext *DC, const Decl *D) {
// TU and namespaces are handled elsewhere.
if (isa<TranslationUnitDecl>(DC) || isa<NamespaceDecl>(DC))
return;
- if (!(!D->isFromASTFile() && cast<Decl>(DC)->isFromASTFile()))
- return; // Not a source decl added to a DeclContext from PCH.
+ // We're only interested in cases where a local declaration is added to an
+ // imported context.
+ if (D->isFromASTFile() || !isImportedDeclContext(Chain, cast<Decl>(DC)))
+ return;
assert(DC == DC->getPrimaryContext() && "added to non-primary context");
assert(!getDefinitiveDeclContext(DC) && "DeclContext not definitive!");
assert(!WritingAST && "Already writing the AST!");
- UpdatedDeclContexts.insert(DC);
+ if (UpdatedDeclContexts.insert(DC) && !cast<Decl>(DC)->isFromASTFile()) {
+ // We're adding a visible declaration to a predefined decl context. Ensure
+ // that we write out all of its lookup results so we don't get a nasty
+ // surprise when we try to emit its lookup table.
+ for (auto *Child : DC->decls())
+ UpdatingVisibleDecls.push_back(Child);
+ }
UpdatingVisibleDecls.push_back(D);
}
void ASTWriter::AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {
assert(D->isImplicit());
- if (!(!D->isFromASTFile() && RD->isFromASTFile()))
- return; // Not a source member added to a class from PCH.
+
+ // We're only interested in cases where a local declaration is added to an
+ // imported context.
+ if (D->isFromASTFile() || !isImportedDeclContext(Chain, RD))
+ return;
+
if (!isa<CXXMethodDecl>(D))
- return; // We are interested in lazily declared implicit methods.
+ return;
// A decl coming from PCH was modified.
assert(RD->isCompleteDefinition());
OpenPOWER on IntegriCloud