Push record return type classification into CGCXXABI
In the Microsoft C++ ABI, instance methods always return records
indirectly via the second hidden parameter. This was implemented in
X86_32ABIInfo, but not WinX86_64ABIInfo.
Rather than exposing a handful of boolean methods in the CGCXXABI
interface, we can expose a single method that applies C++ ABI return
value classification rules.
llvm-svn: 208733
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index bd56b73..1b05b93 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -39,10 +39,7 @@
bool HasThisReturn(GlobalDecl GD) const override;
- bool isReturnTypeIndirect(const CXXRecordDecl *RD) const override {
- // Structures that are not C++03 PODs are always indirect.
- return !RD->isPOD();
- }
+ bool classifyReturnType(CGFunctionInfo &FI) const override;
RecordArgABI getRecordArgABI(const CXXRecordDecl *RD) const override;
@@ -459,6 +456,27 @@
return isa<CXXConstructorDecl>(GD.getDecl());
}
+bool MicrosoftCXXABI::classifyReturnType(CGFunctionInfo &FI) const {
+ const CXXRecordDecl *RD = FI.getReturnType()->getAsCXXRecordDecl();
+ if (!RD)
+ return false;
+
+ if (FI.isInstanceMethod()) {
+ // If it's an instance method, aggregates are always returned indirectly via
+ // the second parameter.
+ FI.getReturnInfo() = ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ FI.getReturnInfo().setSRetAfterThis(FI.isInstanceMethod());
+ return true;
+ } else if (!RD->isPOD()) {
+ // If it's a free function, non-POD types are returned indirectly.
+ FI.getReturnInfo() = ABIArgInfo::getIndirect(0, /*ByVal=*/false);
+ return true;
+ }
+
+ // Otherwise, use the C ABI rules.
+ return false;
+}
+
void MicrosoftCXXABI::BuildConstructorSignature(
const CXXConstructorDecl *Ctor, CXXCtorType Type, CanQualType &ResTy,
SmallVectorImpl<CanQualType> &ArgTys) {