#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"
-#include "llvm/Demangle/Demangle.h"
-
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Type.h"
+#include "llvm/Demangle/Demangle.h"
#include <map>
#include <memory>
case DW_AT_export_symbols:
exports_symbols = form_value.Boolean();
break;
+ case DW_AT_rvalue_reference:
+ ref_qual = clang::RQ_RValue;
+ break;
+ case DW_AT_reference:
+ ref_qual = clang::RQ_LValue;
+ break;
}
}
}
// clang_type will get the function prototype clang type after this
// call
- CompilerType clang_type = m_ast.CreateFunctionType(
- return_clang_type, function_param_types.data(),
- function_param_types.size(), is_variadic, type_quals, calling_convention);
+ CompilerType clang_type =
+ m_ast.CreateFunctionType(return_clang_type, function_param_types.data(),
+ function_param_types.size(), is_variadic,
+ type_quals, calling_convention, attrs.ref_qual);
if (attrs.name) {
bool type_handled = false;
#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
#include "clang/AST/CharUnits.h"
+#include "clang/AST/Type.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h"
uint32_t bit_stride = 0;
uint32_t byte_stride = 0;
uint32_t encoding = 0;
+ clang::RefQualifierKind ref_qual =
+ clang::RQ_None; ///< Indicates ref-qualifier of
+ ///< C++ member function if present.
+ ///< Is RQ_None otherwise.
};
#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSERCLANG_H
return func_decl;
}
-CompilerType
-TypeSystemClang::CreateFunctionType(const CompilerType &result_type,
- const CompilerType *args, unsigned num_args,
- bool is_variadic, unsigned type_quals,
- clang::CallingConv cc) {
+CompilerType TypeSystemClang::CreateFunctionType(
+ const CompilerType &result_type, const CompilerType *args,
+ unsigned num_args, bool is_variadic, unsigned type_quals,
+ clang::CallingConv cc, clang::RefQualifierKind ref_qual) {
if (!result_type || !ClangUtil::IsClangType(result_type))
return CompilerType(); // invalid return type
proto_info.Variadic = is_variadic;
proto_info.ExceptionSpec = EST_None;
proto_info.TypeQuals = clang::Qualifiers::fromFastMask(type_quals);
- proto_info.RefQualifier = RQ_None;
+ proto_info.RefQualifier = ref_qual;
return GetType(getASTContext().getFunctionType(
ClangUtil::GetQualType(result_type), qual_type_args, proto_info));
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTFwd.h"
#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
#include "clang/Basic/TargetInfo.h"
#include "llvm/ADT/APSInt.h"
#include "llvm/ADT/SmallVector.h"
llvm::StringRef name, const CompilerType &function_Type,
clang::StorageClass storage, bool is_inline);
- CompilerType CreateFunctionType(const CompilerType &result_type,
- const CompilerType *args, unsigned num_args,
- bool is_variadic, unsigned type_quals,
- clang::CallingConv cc = clang::CC_C);
+ CompilerType
+ CreateFunctionType(const CompilerType &result_type, const CompilerType *args,
+ unsigned num_args, bool is_variadic, unsigned type_quals,
+ clang::CallingConv cc = clang::CC_C,
+ clang::RefQualifierKind ref_qual = clang::RQ_None);
clang::ParmVarDecl *
CreateParameterDeclaration(clang::DeclContext *decl_ctx,
--- /dev/null
+CXX_SOURCES := main.cpp
+
+include Makefile.rules
--- /dev/null
+"""
+Tests that C++ expression evaluation can
+disambiguate between rvalue and lvalue
+reference-qualified functions.
+"""
+
+import lldb
+from lldbsuite.test.decorators import *
+from lldbsuite.test.lldbtest import *
+from lldbsuite.test import lldbutil
+
+class TestCase(TestBase):
+
+ def test(self):
+ self.build()
+ lldbutil.run_to_source_breakpoint(self, "Break here", lldb.SBFileSpec("main.cpp"))
+
+ # const lvalue
+ self.expect_expr("const_foo.func()", result_type="uint32_t", result_value="0")
+
+ # const rvalue
+ self.expect_expr("static_cast<Foo const&&>(Foo{}).func()",
+ result_type="int64_t", result_value="1")
+
+ # non-const lvalue
+ self.expect_expr("foo.func()", result_type="uint32_t", result_value="2")
+
+ # non-const rvalue
+ self.expect_expr("Foo{}.func()", result_type="int64_t", result_value="3")
+
+ self.filecheck("target modules dump ast", __file__)
+ # CHECK: |-CXXMethodDecl {{.*}} func 'uint32_t () const &'
+ # CHECK-NEXT: | `-AsmLabelAttr {{.*}}
+ # CHECK-NEXT: |-CXXMethodDecl {{.*}} func 'int64_t () const &&'
+ # CHECK-NEXT: | `-AsmLabelAttr {{.*}}
+ # CHECK-NEXT: |-CXXMethodDecl {{.*}} func 'uint32_t () &'
+ # CHECK-NEXT: | `-AsmLabelAttr {{.*}}
+ # CHECK-NEXT: `-CXXMethodDecl {{.*}} func 'int64_t () &&'
+ # CHECK-NEXT: `-AsmLabelAttr {{.*}}
--- /dev/null
+#include <cstdint>
+#include <cstdio>
+
+struct Foo {
+ uint32_t func() const & { return 0; }
+ int64_t func() const && { return 1; }
+ uint32_t func() & { return 2; }
+ int64_t func() && { return 3; }
+};
+
+int main() {
+ Foo foo;
+ const Foo const_foo;
+ auto res = foo.func() + const_foo.func() + Foo{}.func() +
+ static_cast<Foo const &&>(Foo{}).func();
+
+ std::puts("Break here");
+ return res;
+}