I added a new function to DeclContext called
addDeclInternal(). This function suppresses any
calls to FindExternalVisibleDeclsByName() while
a Decl is added to a DeclContext. This behavior
is required for the ASTImporter, because in the
case of the LLDB client the ASTImporter would be
called recursively to import the visible decls,
which leads to assertions because the recursive
call is seeing partially-formed types.
I also modified the ASTImporter to use
addDeclInternal() in all places where it would
otherwise use addDecl(). This fix should not
affect the rest of Clang, passes Clang's
testsuite, and fixes several serious LLDB bugs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142634 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp
index 321e40b..a4daea2 100644
--- a/lib/AST/DeclBase.cpp
+++ b/lib/AST/DeclBase.cpp
@@ -1013,6 +1013,13 @@
ND->getDeclContext()->makeDeclVisibleInContext(ND);
}
+void DeclContext::addDeclInternal(Decl *D) {
+ addHiddenDecl(D);
+
+ if (NamedDecl *ND = dyn_cast<NamedDecl>(D))
+ ND->getDeclContext()->makeDeclVisibleInContextInternal(ND);
+}
+
/// buildLookup - Build the lookup data structure with all of the
/// declarations in DCtx (and any other contexts linked to it or
/// transparent contexts nested within it).
@@ -1026,12 +1033,12 @@
// lookup building, this is implicitly enforced by addDecl.
if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
if (D->getDeclContext() == DCtx)
- makeDeclVisibleInContextImpl(ND);
+ makeDeclVisibleInContextImpl(ND, false);
// Insert any forward-declared Objective-C interface into the lookup
// data structure.
if (ObjCClassDecl *Class = dyn_cast<ObjCClassDecl>(*D))
- makeDeclVisibleInContextImpl(Class->getForwardInterfaceDecl());
+ makeDeclVisibleInContextImpl(Class->getForwardInterfaceDecl(), false);
// If this declaration is itself a transparent declaration context or
// inline namespace, add its members (recursively).
@@ -1147,7 +1154,17 @@
return false;
}
-void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable) {
+void DeclContext::makeDeclVisibleInContext(NamedDecl *D, bool Recoverable)
+{
+ makeDeclVisibleInContextWithFlags(D, false, Recoverable);
+}
+
+void DeclContext::makeDeclVisibleInContextInternal(NamedDecl *D, bool Recoverable)
+{
+ makeDeclVisibleInContextWithFlags(D, true, Recoverable);
+}
+
+void DeclContext::makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal, bool Recoverable) {
// FIXME: This feels like a hack. Should DeclarationName support
// template-ids, or is there a better way to keep specializations
// from being visible?
@@ -1159,7 +1176,7 @@
DeclContext *PrimaryContext = getPrimaryContext();
if (PrimaryContext != this) {
- PrimaryContext->makeDeclVisibleInContext(D, Recoverable);
+ PrimaryContext->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
return;
}
@@ -1168,12 +1185,12 @@
// them so we can add the decl. Otherwise, be lazy and don't build that
// structure until someone asks for it.
if (LookupPtr || !Recoverable || hasExternalVisibleStorage())
- makeDeclVisibleInContextImpl(D);
+ makeDeclVisibleInContextImpl(D, Internal);
// If we are a transparent context or inline namespace, insert into our
// parent context, too. This operation is recursive.
if (isTransparentContext() || isInlineNamespace())
- getParent()->makeDeclVisibleInContext(D, Recoverable);
+ getParent()->makeDeclVisibleInContextWithFlags(D, Internal, Recoverable);
Decl *DCAsDecl = cast<Decl>(this);
// Notify that a decl was made visible unless it's a Tag being defined.
@@ -1182,7 +1199,7 @@
L->AddedVisibleDecl(this, D);
}
-void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D) {
+void DeclContext::makeDeclVisibleInContextImpl(NamedDecl *D, bool Internal) {
// Skip unnamed declarations.
if (!D->getDeclName())
return;
@@ -1203,10 +1220,11 @@
// with this declaration's name.
// If the lookup table contains an entry about this name it means that we
// have already checked the external source.
- if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
- if (hasExternalVisibleStorage() &&
- LookupPtr->find(D->getDeclName()) == LookupPtr->end())
- Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
+ if (!Internal)
+ if (ExternalASTSource *Source = getParentASTContext().getExternalSource())
+ if (hasExternalVisibleStorage() &&
+ LookupPtr->find(D->getDeclName()) == LookupPtr->end())
+ Source->FindExternalVisibleDeclsByName(this, D->getDeclName());
// Insert this declaration into the map.
StoredDeclsList &DeclNameEntries = (*LookupPtr)[D->getDeclName()];