forked from OSchip/llvm-project
Fix ClangASTContext::CreateParameterDeclaration to not call addDecl
Summary: The change https://reviews.llvm.org/D55575 modified ClangASTContext::CreateParameterDeclaration to call decl_ctx->addDecl(decl); this caused a regression since the existing code in DWARFASTParserClang::ParseChildParameters is called with the containing DeclContext. So when end up with cases where we are parsing a parameter for a member function and the parameter is added to the CXXRecordDecl as opposed to the CXXMethodDecl. This example is given in the regression test TestBreakpointInMemberFuncWNonPrimitiveParams.py which without this fix in a modules build leads to assert on setting a breakpoint in a member function with non primitive parameters. This scenario would be common when debugging LLDB or clang. Differential Revision: https://reviews.llvm.org/D65414 llvm-svn: 367726
This commit is contained in:
parent
d021617bf7
commit
fa5c340ea1
|
@ -395,7 +395,8 @@ public:
|
|||
clang::ParmVarDecl *CreateParameterDeclaration(clang::DeclContext *decl_ctx,
|
||||
const char *name,
|
||||
const CompilerType ¶m_type,
|
||||
int storage);
|
||||
int storage,
|
||||
bool add_decl=false);
|
||||
|
||||
void SetFunctionParameters(clang::FunctionDecl *function_decl,
|
||||
clang::ParmVarDecl **params, unsigned num_params);
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
LEVEL = ../../../make
|
||||
|
||||
CXX_SOURCES = main.cpp a.cpp
|
||||
CFLAGS_EXTRAS = $(MANDATORY_CXXMODULE_BUILD_CFLAGS)
|
||||
|
||||
include $(LEVEL)/Makefile.rules
|
|
@ -0,0 +1,26 @@
|
|||
"""
|
||||
This is a regression test for an assert that happens while setting a breakpoint.
|
||||
The root cause of the assert was attempting to add a ParmVarDecl to a CXXRecordDecl
|
||||
when it should have been added to a CXXMethodDecl.
|
||||
|
||||
We can reproduce with a module build and setting a breakpoint in a member function
|
||||
of a class with a non-primitive type as a parameter.
|
||||
"""
|
||||
|
||||
import lldb
|
||||
from lldbsuite.test.decorators import *
|
||||
from lldbsuite.test.lldbtest import *
|
||||
from lldbsuite.test import lldbutil
|
||||
|
||||
class TestBreakpointInMemberFuncWNonPrimitiveParams(TestBase):
|
||||
|
||||
mydir = TestBase.compute_mydir(__file__)
|
||||
|
||||
@add_test_categories(["gmodules"])
|
||||
def test_breakpint_in_member_func_w_non_primitie_params(self):
|
||||
self.build()
|
||||
|
||||
(self.target, self.process, _, bkpt) = lldbutil.run_to_source_breakpoint(self, '// break here',
|
||||
lldb.SBFileSpec("main.cpp", False))
|
||||
|
||||
self.runCmd("b a.cpp:11");
|
|
@ -0,0 +1,14 @@
|
|||
#include "a.h"
|
||||
|
||||
bool A::b(int x) {
|
||||
if (x)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool B::member_func_a(A a) {
|
||||
return a.b(10); // We will try and add a breakpoint here which
|
||||
// trigger an assert since we will attempt to
|
||||
// to add ParamVarDecl a to CXXRecordDecl A
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
struct A {
|
||||
bool b(int x);
|
||||
};
|
||||
|
||||
struct B {
|
||||
bool member_func_a(A a);
|
||||
};
|
|
@ -0,0 +1,15 @@
|
|||
#include "a.h"
|
||||
#include <cstdio>
|
||||
|
||||
bool foo() {
|
||||
A a1;
|
||||
B b1;
|
||||
|
||||
return b1.member_func_a(a1); // break here
|
||||
}
|
||||
|
||||
int main() {
|
||||
int x = 0;
|
||||
|
||||
return foo();
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
module A {
|
||||
header "a.h"
|
||||
}
|
|
@ -1084,7 +1084,7 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id,
|
|||
CompilerType param_type_ct(&m_clang, qt.getAsOpaquePtr());
|
||||
clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration(
|
||||
&function_decl, param_name.str().c_str(), param_type_ct,
|
||||
clang::SC_None);
|
||||
clang::SC_None, true);
|
||||
lldbassert(m_uid_to_decl.count(toOpaqueUid(param_uid)) == 0);
|
||||
|
||||
m_uid_to_decl[toOpaqueUid(param_uid)] = param;
|
||||
|
|
|
@ -940,7 +940,7 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) {
|
|||
|
||||
clang::ParmVarDecl *param = m_ast.CreateParameterDeclaration(
|
||||
decl, nullptr, arg_type->GetForwardCompilerType(),
|
||||
clang::SC_None);
|
||||
clang::SC_None, true);
|
||||
if (param)
|
||||
params.push_back(param);
|
||||
}
|
||||
|
|
|
@ -2227,7 +2227,7 @@ CompilerType ClangASTContext::CreateFunctionType(
|
|||
|
||||
ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
|
||||
clang::DeclContext *decl_ctx, const char *name,
|
||||
const CompilerType ¶m_type, int storage) {
|
||||
const CompilerType ¶m_type, int storage, bool add_decl) {
|
||||
ASTContext *ast = getASTContext();
|
||||
assert(ast != nullptr);
|
||||
auto *decl =
|
||||
|
@ -2235,7 +2235,9 @@ ParmVarDecl *ClangASTContext::CreateParameterDeclaration(
|
|||
name && name[0] ? &ast->Idents.get(name) : nullptr,
|
||||
ClangUtil::GetQualType(param_type), nullptr,
|
||||
(clang::StorageClass)storage, nullptr);
|
||||
decl_ctx->addDecl(decl);
|
||||
if (add_decl)
|
||||
decl_ctx->addDecl(decl);
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue