summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenFunction.h
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2016-06-28 19:03:57 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2016-06-28 19:03:57 +0000
commit5179eb78210a2ad01a18c37b75048ccfe78414ac (patch)
tree194b7981ca2f1dc43a513f016c1374bf1b31aabb /clang/lib/CodeGen/CodeGenFunction.h
parenta5c7adcb38e89cd23ed3cbbc813d2da2546a9161 (diff)
downloadbcm5719-llvm-5179eb78210a2ad01a18c37b75048ccfe78414ac.tar.gz
bcm5719-llvm-5179eb78210a2ad01a18c37b75048ccfe78414ac.zip
P0136R1, DR1573, DR1645, DR1715, DR1736, DR1903, DR1941, DR1959, DR1991:
Replace inheriting constructors implementation with new approach, voted into C++ last year as a DR against C++11. Instead of synthesizing a set of derived class constructors for each inherited base class constructor, we make the constructors of the base class visible to constructor lookup in the derived class, using the normal rules for using-declarations. For constructors, UsingShadowDecl now has a ConstructorUsingShadowDecl derived class that tracks the requisite additional information. We create shadow constructors (not found by name lookup) in the derived class to model the actual initialization, and have a new expression node, CXXInheritedCtorInitExpr, to model the initialization of a base class from such a constructor. (This initialization is special because it performs real perfect forwarding of arguments.) In cases where argument forwarding is not possible (for inalloca calls, variadic calls, and calls with callee parameter cleanup), the shadow inheriting constructor is not emitted and instead we directly emit the initialization code into the caller of the inherited constructor. Note that this new model is not perfectly compatible with the old model in some corner cases. In particular: * if B inherits a private constructor from A, and C uses that constructor to construct a B, then we previously required that A befriends B and B befriends C, but the new rules require A to befriend C directly, and * if a derived class has its own constructors (and so its implicit default constructor is suppressed), it may still inherit a default constructor from a base class llvm-svn: 274049
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.h')
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 4748e6b47dc..441cee54fc1 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -1065,6 +1065,61 @@ public:
CharUnits OldCXXThisAlignment;
};
+ class InlinedInheritingConstructorScope {
+ public:
+ InlinedInheritingConstructorScope(CodeGenFunction &CGF, GlobalDecl GD)
+ : CGF(CGF), OldCurGD(CGF.CurGD), OldCurFuncDecl(CGF.CurFuncDecl),
+ OldCurCodeDecl(CGF.CurCodeDecl),
+ OldCXXABIThisDecl(CGF.CXXABIThisDecl),
+ OldCXXABIThisValue(CGF.CXXABIThisValue),
+ OldCXXThisValue(CGF.CXXThisValue),
+ OldCXXABIThisAlignment(CGF.CXXABIThisAlignment),
+ OldCXXThisAlignment(CGF.CXXThisAlignment),
+ OldReturnValue(CGF.ReturnValue), OldFnRetTy(CGF.FnRetTy),
+ OldCXXInheritedCtorInitExprArgs(
+ std::move(CGF.CXXInheritedCtorInitExprArgs)) {
+ CGF.CurGD = GD;
+ CGF.CurFuncDecl = CGF.CurCodeDecl =
+ cast<CXXConstructorDecl>(GD.getDecl());
+ CGF.CXXABIThisDecl = nullptr;
+ CGF.CXXABIThisValue = nullptr;
+ CGF.CXXThisValue = nullptr;
+ CGF.CXXABIThisAlignment = CharUnits();
+ CGF.CXXThisAlignment = CharUnits();
+ CGF.ReturnValue = Address::invalid();
+ CGF.FnRetTy = QualType();
+ CGF.CXXInheritedCtorInitExprArgs.clear();
+ }
+ ~InlinedInheritingConstructorScope() {
+ CGF.CurGD = OldCurGD;
+ CGF.CurFuncDecl = OldCurFuncDecl;
+ CGF.CurCodeDecl = OldCurCodeDecl;
+ CGF.CXXABIThisDecl = OldCXXABIThisDecl;
+ CGF.CXXABIThisValue = OldCXXABIThisValue;
+ CGF.CXXThisValue = OldCXXThisValue;
+ CGF.CXXABIThisAlignment = OldCXXABIThisAlignment;
+ CGF.CXXThisAlignment = OldCXXThisAlignment;
+ CGF.ReturnValue = OldReturnValue;
+ CGF.FnRetTy = OldFnRetTy;
+ CGF.CXXInheritedCtorInitExprArgs =
+ std::move(OldCXXInheritedCtorInitExprArgs);
+ }
+
+ private:
+ CodeGenFunction &CGF;
+ GlobalDecl OldCurGD;
+ const Decl *OldCurFuncDecl;
+ const Decl *OldCurCodeDecl;
+ ImplicitParamDecl *OldCXXABIThisDecl;
+ llvm::Value *OldCXXABIThisValue;
+ llvm::Value *OldCXXThisValue;
+ CharUnits OldCXXABIThisAlignment;
+ CharUnits OldCXXThisAlignment;
+ Address OldReturnValue;
+ QualType OldFnRetTy;
+ CallArgList OldCXXInheritedCtorInitExprArgs;
+ };
+
private:
/// CXXThisDecl - When generating code for a C++ member function,
/// this will hold the implicit 'this' declaration.
@@ -1078,6 +1133,10 @@ private:
/// this expression.
Address CXXDefaultInitExprThis = Address::invalid();
+ /// The values of function arguments to use when evaluating
+ /// CXXInheritedCtorInitExprs within this context.
+ CallArgList CXXInheritedCtorInitExprArgs;
+
/// CXXStructorImplicitParamDecl - When generating code for a constructor or
/// destructor, this will hold the implicit argument (e.g. VTT).
ImplicitParamDecl *CXXStructorImplicitParamDecl;
@@ -1301,6 +1360,8 @@ public:
const BlockByrefInfo &getBlockByrefInfo(const VarDecl *var);
+ QualType BuildFunctionArgList(GlobalDecl GD, FunctionArgList &Args);
+
void GenerateCode(GlobalDecl GD, llvm::Function *Fn,
const CGFunctionInfo &FnInfo);
/// \brief Emit code for the start of a function.
@@ -1874,10 +1935,32 @@ public:
void EmitDelegatingCXXConstructorCall(const CXXConstructorDecl *Ctor,
const FunctionArgList &Args);
+ /// Emit a call to an inheriting constructor (that is, one that invokes a
+ /// constructor inherited from a base class) by inlining its definition. This
+ /// is necessary if the ABI does not support forwarding the arguments to the
+ /// base class constructor (because they're variadic or similar).
+ void EmitInlinedInheritingCXXConstructorCall(const CXXConstructorDecl *Ctor,
+ CXXCtorType CtorType,
+ bool ForVirtualBase,
+ bool Delegating,
+ CallArgList &Args);
+
+ /// Emit a call to a constructor inherited from a base class, passing the
+ /// current constructor's arguments along unmodified (without even making
+ /// a copy).
+ void EmitInheritedCXXConstructorCall(const CXXConstructorDecl *D,
+ bool ForVirtualBase, Address This,
+ bool InheritedFromVBase,
+ const CXXInheritedCtorInitExpr *E);
+
void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
bool ForVirtualBase, bool Delegating,
Address This, const CXXConstructExpr *E);
+ void EmitCXXConstructorCall(const CXXConstructorDecl *D, CXXCtorType Type,
+ bool ForVirtualBase, bool Delegating,
+ Address This, CallArgList &Args);
+
/// Emit assumption load for all bases. Requires to be be called only on
/// most-derived class and not under construction of the object.
void EmitVTableAssumptionLoads(const CXXRecordDecl *ClassDecl, Address This);
OpenPOWER on IntegriCloud