diff options
Diffstat (limited to 'lldb')
3 files changed, 34 insertions, 14 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py b/lldb/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py index 455704280d1..857223b5ed1 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py +++ b/lldb/packages/Python/lldbsuite/test/lang/c/modules/TestCModules.py @@ -47,6 +47,10 @@ class CModulesTestCase(TestBase): self.expect("breakpoint list -f", BREAKPOINT_HIT_ONCE, substrs=[' resolved, hit count = 1']) + # Enable logging of the imported AST. + log_file = os.path.join(self.getBuildDir(), "lldb-ast-log.txt") + self.runCmd("log enable lldb ast -f '%s'" % log_file) + self.expect( "expr -l objc++ -- @import Darwin; 3", VARIABLES_DISPLAYED_CORRECTLY, @@ -54,6 +58,8 @@ class CModulesTestCase(TestBase): "int", "3"]) + # This expr command imports __sFILE with definition + # (FILE is a typedef to __sFILE.) self.expect( "expr *fopen(\"/dev/zero\", \"w\")", VARIABLES_DISPLAYED_CORRECTLY, @@ -61,6 +67,14 @@ class CModulesTestCase(TestBase): "FILE", "_close"]) + # Check that the AST log contains exactly one definition of __sFILE. + f = open(log_file) + log_lines = f.readlines() + f.close() + os.remove(log_file) + self.assertEqual(" ".join(log_lines).count("struct __sFILE definition"), + 1) + self.expect("expr *myFile", VARIABLES_DISPLAYED_CORRECTLY, substrs=["a", "5", "b", "9"]) diff --git a/lldb/packages/Python/lldbsuite/test/lang/c/modules/main.c b/lldb/packages/Python/lldbsuite/test/lang/c/modules/main.c index 2b244bc38d0..df321a75faa 100644 --- a/lldb/packages/Python/lldbsuite/test/lang/c/modules/main.c +++ b/lldb/packages/Python/lldbsuite/test/lang/c/modules/main.c @@ -5,11 +5,11 @@ int printf(const char * __restrict format, ...); typedef struct { int a; int b; -} FILE; +} MYFILE; int main() { - FILE *myFile = malloc(sizeof(FILE)); + MYFILE *myFile = malloc(sizeof(MYFILE)); myFile->a = 5; myFile->b = 9; diff --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp index 8d29df9dde2..c5778f86bb6 100644 --- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp +++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp @@ -612,10 +612,15 @@ void ClangASTSource::FindExternalLexicalDecls( if (!original_decl_context) return; + // Indicates whether we skipped any Decls of the original DeclContext. + bool SkippedDecls = false; for (TagDecl::decl_iterator iter = original_decl_context->decls_begin(); iter != original_decl_context->decls_end(); ++iter) { Decl *decl = *iter; + // The predicate function returns true if the passed declaration kind is + // the one we are looking for. + // See clang::ExternalASTSource::FindExternalLexicalDecls() if (predicate(decl->getKind())) { if (log) { ASTDumper ast_dumper(decl); @@ -640,21 +645,22 @@ void ClangASTSource::FindExternalLexicalDecls( m_ast_importer_sp->RequireCompleteType(copied_field_type); } - - DeclContext *decl_context_non_const = - const_cast<DeclContext *>(decl_context); - - if (copied_decl->getDeclContext() != decl_context) { - if (copied_decl->getDeclContext()->containsDecl(copied_decl)) - copied_decl->getDeclContext()->removeDecl(copied_decl); - copied_decl->setDeclContext(decl_context_non_const); - } - - if (!decl_context_non_const->containsDecl(copied_decl)) - decl_context_non_const->addDeclInternal(copied_decl); + } else { + SkippedDecls = true; } } + // CopyDecl may build a lookup table which may set up ExternalLexicalStorage + // to false. However, since we skipped some of the external Decls we must + // set it back! + if (SkippedDecls) { + decl_context->setHasExternalLexicalStorage(true); + // This sets HasLazyExternalLexicalLookups to true. By setting this bit we + // ensure that the lookup table is rebuilt, which means the external source + // is consulted again when a clang::DeclContext::lookup is called. + const_cast<DeclContext *>(decl_context)->setMustBuildLookupTable(); + } + return; } |