@@ -159,6 +159,76 @@ static bool TagIsRecordType(dw_tag_t tag) {
159159 }
160160}
161161
162+ // / Get the object parameter DIE if one exists, otherwise returns
163+ // / a default DWARFDIE. If \c containing_decl_ctx is not a valid
164+ // / C++ declaration context for class methods, assume no object
165+ // / parameter exists for the given \c subprogram.
166+ static DWARFDIE
167+ GetCXXObjectParameter (const DWARFDIE &subprogram,
168+ const clang::DeclContext &containing_decl_ctx) {
169+ assert (subprogram.Tag () == DW_TAG_subprogram ||
170+ subprogram.Tag () == DW_TAG_inlined_subroutine ||
171+ subprogram.Tag () == DW_TAG_subroutine_type);
172+
173+ if (!DeclKindIsCXXClass (containing_decl_ctx.getDeclKind ()))
174+ return {};
175+
176+ // FIXME: if subprogram has a explicit DW_AT_object_pointer, use it.
177+
178+ // If no DW_AT_object_pointer was specified, assume the implicit object
179+ // parameter is the first parameter to the function, is called "this" and is
180+ // artificial (which is what most compilers would generate).
181+ auto children = subprogram.children ();
182+ auto it = llvm::find_if (children, [](const DWARFDIE &child) {
183+ return child.Tag () == DW_TAG_formal_parameter;
184+ });
185+
186+ if (it == children.end ())
187+ return {};
188+
189+ DWARFDIE object_pointer = *it;
190+
191+ if (!object_pointer.GetAttributeValueAsUnsigned (DW_AT_artificial, 0 ))
192+ return {};
193+
194+ // Often times compilers omit the "this" name for the
195+ // specification DIEs, so we can't rely upon the name being in
196+ // the formal parameter DIE...
197+ if (const char *name = object_pointer.GetName ();
198+ name && ::strcmp (name, " this" ) != 0 )
199+ return {};
200+
201+ return object_pointer;
202+ }
203+
204+ // / In order to determine the CV-qualifiers for a C++ class
205+ // / method in DWARF, we have to look at the CV-qualifiers of
206+ // / the object parameter's type.
207+ static unsigned GetCXXMethodCVQuals (const DWARFDIE &subprogram,
208+ const DWARFDIE &object_parameter) {
209+ if (!subprogram || !object_parameter)
210+ return 0 ;
211+
212+ Type *this_type = subprogram.ResolveTypeUID (
213+ object_parameter.GetAttributeValueAsReferenceDIE (DW_AT_type));
214+ if (!this_type)
215+ return 0 ;
216+
217+ uint32_t encoding_mask = this_type->GetEncodingMask ();
218+
219+ // FIXME: explicit object parameters need not to be pointers
220+ if (!(encoding_mask & (1u << Type::eEncodingIsPointerUID)))
221+ return 0 ;
222+
223+ unsigned cv_quals = 0 ;
224+ if (encoding_mask & (1u << Type::eEncodingIsConstUID))
225+ cv_quals |= clang::Qualifiers::Const;
226+ if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
227+ cv_quals |= clang::Qualifiers::Volatile;
228+
229+ return cv_quals;
230+ }
231+
162232TypeSP DWARFASTParserClang::ParseTypeFromClangModule (const SymbolContext &sc,
163233 const DWARFDIE &die,
164234 Log *log) {
@@ -1188,11 +1258,8 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
11881258 const dw_tag_t tag = die.Tag ();
11891259
11901260 bool is_variadic = false ;
1191- bool is_static = false ;
11921261 bool has_template_params = false ;
11931262
1194- unsigned type_quals = 0 ;
1195-
11961263 DEBUG_PRINTF (" 0x%8.8" PRIx64 " : %s (\" %s\" )\n " , die.GetID (),
11971264 DW_TAG_value_to_name (tag), type_name_cstr);
11981265
@@ -1215,23 +1282,15 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
12151282 DWARFDIE decl_ctx_die;
12161283 clang::DeclContext *containing_decl_ctx =
12171284 GetClangDeclContextContainingDIE (die, &decl_ctx_die);
1218- const clang::Decl::Kind containing_decl_kind =
1219- containing_decl_ctx->getDeclKind ();
1220-
1221- bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
1222- // Start off static. This will be set to false in
1223- // ParseChildParameters(...) if we find a "this" parameters as the
1224- // first parameter
1225- if (is_cxx_method) {
1226- is_static = true ;
1227- }
1285+ assert (containing_decl_ctx);
12281286
12291287 if (die.HasChildren ()) {
1230- ParseChildParameters (containing_decl_ctx, die, is_static, is_variadic,
1288+ ParseChildParameters (containing_decl_ctx, die, is_variadic,
12311289 has_template_params, function_param_types,
1232- function_param_decls, type_quals );
1290+ function_param_decls);
12331291 }
12341292
1293+ bool is_cxx_method = DeclKindIsCXXClass (containing_decl_ctx->getDeclKind ());
12351294 bool ignore_containing_context = false ;
12361295 // Check for templatized class member functions. If we had any
12371296 // DW_TAG_template_type_parameter or DW_TAG_template_value_parameter
@@ -1251,12 +1310,16 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
12511310 clang::CallingConv calling_convention =
12521311 ConvertDWARFCallingConventionToClang (attrs);
12531312
1313+ const DWARFDIE object_parameter =
1314+ GetCXXObjectParameter (die, *containing_decl_ctx);
1315+
12541316 // clang_type will get the function prototype clang type after this
12551317 // call
12561318 CompilerType clang_type =
12571319 m_ast.CreateFunctionType (return_clang_type, function_param_types.data (),
12581320 function_param_types.size (), is_variadic,
1259- type_quals, calling_convention, attrs.ref_qual );
1321+ GetCXXMethodCVQuals (die, object_parameter),
1322+ calling_convention, attrs.ref_qual );
12601323
12611324 if (attrs.name ) {
12621325 bool type_handled = false ;
@@ -1267,6 +1330,8 @@ DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die,
12671330 type_handled =
12681331 ParseObjCMethod (*objc_method, die, clang_type, attrs, is_variadic);
12691332 } else if (is_cxx_method) {
1333+ // In DWARF, a C++ method is static if it has no object parameter child.
1334+ const bool is_static = !object_parameter.IsValid ();
12701335 auto [handled, type_sp] =
12711336 ParseCXXMethod (die, clang_type, attrs, decl_ctx_die, is_static,
12721337 ignore_containing_context);
@@ -2315,10 +2380,8 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
23152380
23162381ConstString
23172382DWARFASTParserClang::ConstructDemangledNameFromDWARF (const DWARFDIE &die) {
2318- bool is_static = false ;
23192383 bool is_variadic = false ;
23202384 bool has_template_params = false ;
2321- unsigned type_quals = 0 ;
23222385 std::vector<CompilerType> param_types;
23232386 std::vector<clang::ParmVarDecl *> param_decls;
23242387 StreamString sstr;
@@ -2328,9 +2391,13 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
23282391
23292392 clang::DeclContext *containing_decl_ctx =
23302393 GetClangDeclContextContainingDIE (die, nullptr );
2331- ParseChildParameters (containing_decl_ctx, die, is_static, is_variadic,
2332- has_template_params, param_types, param_decls,
2333- type_quals);
2394+ assert (containing_decl_ctx);
2395+
2396+ const unsigned cv_quals = GetCXXMethodCVQuals (
2397+ die, GetCXXObjectParameter (die, *containing_decl_ctx));
2398+
2399+ ParseChildParameters (containing_decl_ctx, die, is_variadic,
2400+ has_template_params, param_types, param_decls);
23342401 sstr << " (" ;
23352402 for (size_t i = 0 ; i < param_types.size (); i++) {
23362403 if (i > 0 )
@@ -2340,7 +2407,7 @@ DWARFASTParserClang::ConstructDemangledNameFromDWARF(const DWARFDIE &die) {
23402407 if (is_variadic)
23412408 sstr << " , ..." ;
23422409 sstr << " )" ;
2343- if (type_quals & clang::Qualifiers::Const)
2410+ if (cv_quals & clang::Qualifiers::Const)
23442411 sstr << " const" ;
23452412
23462413 return ConstString (sstr.GetString ());
@@ -3070,57 +3137,37 @@ bool DWARFASTParserClang::ParseChildMembers(
30703137 return true ;
30713138}
30723139
3073- size_t DWARFASTParserClang::ParseChildParameters (
3140+ void DWARFASTParserClang::ParseChildParameters (
30743141 clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die,
3075- bool &is_static, bool & is_variadic, bool &has_template_params,
3142+ bool &is_variadic, bool &has_template_params,
30763143 std::vector<CompilerType> &function_param_types,
3077- std::vector<clang::ParmVarDecl *> &function_param_decls,
3078- unsigned &type_quals) {
3144+ std::vector<clang::ParmVarDecl *> &function_param_decls) {
30793145 if (!parent_die)
3080- return 0 ;
3146+ return ;
30813147
3082- size_t arg_idx = 0 ;
30833148 for (DWARFDIE die : parent_die.children ()) {
30843149 const dw_tag_t tag = die.Tag ();
30853150 switch (tag) {
30863151 case DW_TAG_formal_parameter: {
3152+ if (die.GetAttributeValueAsUnsigned (DW_AT_artificial, 0 ))
3153+ continue ;
3154+
30873155 const char *name = die.GetName ();
30883156 DWARFDIE param_type_die = die.GetAttributeValueAsReferenceDIE (DW_AT_type);
30893157
3090- if (die.GetAttributeValueAsUnsigned (DW_AT_artificial, 0 )) {
3091- // In order to determine if a C++ member function is "const" we
3092- // have to look at the const-ness of "this"...
3093- if (arg_idx == 0 &&
3094- DeclKindIsCXXClass (containing_decl_ctx->getDeclKind ()) &&
3095- // Often times compilers omit the "this" name for the
3096- // specification DIEs, so we can't rely upon the name being in
3097- // the formal parameter DIE...
3098- (name == nullptr || ::strcmp (name, " this" ) == 0 )) {
3099- if (Type *this_type = die.ResolveTypeUID (param_type_die)) {
3100- uint32_t encoding_mask = this_type->GetEncodingMask ();
3101- if (encoding_mask & Type::eEncodingIsPointerUID) {
3102- is_static = false ;
3103-
3104- if (encoding_mask & (1u << Type::eEncodingIsConstUID))
3105- type_quals |= clang::Qualifiers::Const;
3106- if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
3107- type_quals |= clang::Qualifiers::Volatile;
3108- }
3109- }
3110- }
3111- } else if (Type *type = die.ResolveTypeUID (param_type_die)) {
3112- function_param_types.push_back (type->GetForwardCompilerType ());
3158+ Type *type = die.ResolveTypeUID (param_type_die);
3159+ if (!type)
3160+ break ;
31133161
3114- clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration (
3115- containing_decl_ctx, GetOwningClangModule (die), name,
3116- type->GetForwardCompilerType (), clang::StorageClass::SC_None);
3117- assert (param_var_decl);
3118- function_param_decls.push_back (param_var_decl);
3162+ function_param_types.push_back (type->GetForwardCompilerType ());
31193163
3120- m_ast.SetMetadataAsUserID (param_var_decl, die.GetID ());
3121- }
3164+ clang::ParmVarDecl *param_var_decl = m_ast.CreateParameterDeclaration (
3165+ containing_decl_ctx, GetOwningClangModule (die), name,
3166+ type->GetForwardCompilerType (), clang::StorageClass::SC_None);
3167+ assert (param_var_decl);
3168+ function_param_decls.push_back (param_var_decl);
31223169
3123- arg_idx++ ;
3170+ m_ast. SetMetadataAsUserID (param_var_decl, die. GetID ()) ;
31243171 } break ;
31253172
31263173 case DW_TAG_unspecified_parameters:
@@ -3142,7 +3189,6 @@ size_t DWARFASTParserClang::ParseChildParameters(
31423189 break ;
31433190 }
31443191 }
3145- return arg_idx;
31463192}
31473193
31483194clang::Decl *DWARFASTParserClang::GetClangDeclForDIE (const DWARFDIE &die) {
0 commit comments