@@ -29,6 +29,7 @@ namespace clang {
29
29
30
30
class ClassTemplateDecl ;
31
31
class ClassTemplateSpecializationDecl ;
32
+ class ConstructorUsingShadowDecl ;
32
33
class CXXBasePath ;
33
34
class CXXBasePaths ;
34
35
class CXXConstructorDecl ;
@@ -1298,7 +1299,7 @@ class CXXRecordDecl : public RecordDecl {
1298
1299
}
1299
1300
1300
1301
// / \brief Determine whether this class has a using-declaration that names
1301
- // / a base class constructor.
1302
+ // / a user-declared base class constructor.
1302
1303
bool hasInheritedConstructor () const {
1303
1304
return data ().HasInheritedConstructor ;
1304
1305
}
@@ -2153,6 +2154,23 @@ class CXXCtorInitializer final
2153
2154
friend TrailingObjects;
2154
2155
};
2155
2156
2157
+ // / Description of a constructor that was inherited from a base class.
2158
+ class InheritedConstructor {
2159
+ ConstructorUsingShadowDecl *Shadow;
2160
+ CXXConstructorDecl *BaseCtor;
2161
+
2162
+ public:
2163
+ InheritedConstructor () : Shadow(), BaseCtor() {}
2164
+ InheritedConstructor (ConstructorUsingShadowDecl *Shadow,
2165
+ CXXConstructorDecl *BaseCtor)
2166
+ : Shadow(Shadow), BaseCtor(BaseCtor) {}
2167
+
2168
+ explicit operator bool () const { return Shadow; }
2169
+
2170
+ ConstructorUsingShadowDecl *getShadowDecl () const { return Shadow; }
2171
+ CXXConstructorDecl *getConstructor () const { return BaseCtor; }
2172
+ };
2173
+
2156
2174
// / \brief Represents a C++ constructor within a class.
2157
2175
// /
2158
2176
// / For example:
@@ -2163,41 +2181,51 @@ class CXXCtorInitializer final
2163
2181
// / explicit X(int); // represented by a CXXConstructorDecl.
2164
2182
// / };
2165
2183
// / \endcode
2166
- class CXXConstructorDecl : public CXXMethodDecl {
2184
+ class CXXConstructorDecl final
2185
+ : public CXXMethodDecl,
2186
+ private llvm::TrailingObjects<CXXConstructorDecl, InheritedConstructor> {
2167
2187
void anchor () override ;
2168
2188
2169
2189
// / \name Support for base and member initializers.
2170
2190
// / \{
2171
2191
// / \brief The arguments used to initialize the base or member.
2172
2192
LazyCXXCtorInitializersPtr CtorInitializers;
2173
- unsigned NumCtorInitializers : 31 ;
2193
+ unsigned NumCtorInitializers : 30 ;
2174
2194
// / \}
2175
2195
2176
2196
// / \brief Whether this constructor declaration has the \c explicit keyword
2177
2197
// / specified.
2178
2198
unsigned IsExplicitSpecified : 1 ;
2179
2199
2200
+ // / \brief Whether this constructor declaration is an implicitly-declared
2201
+ // / inheriting constructor.
2202
+ unsigned IsInheritingConstructor : 1 ;
2203
+
2180
2204
CXXConstructorDecl (ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc,
2181
2205
const DeclarationNameInfo &NameInfo,
2182
2206
QualType T, TypeSourceInfo *TInfo,
2183
2207
bool isExplicitSpecified, bool isInline,
2184
- bool isImplicitlyDeclared, bool isConstexpr)
2208
+ bool isImplicitlyDeclared, bool isConstexpr,
2209
+ InheritedConstructor Inherited)
2185
2210
: CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo,
2186
2211
SC_None, isInline, isConstexpr, SourceLocation()),
2187
2212
CtorInitializers (nullptr ), NumCtorInitializers(0 ),
2188
- IsExplicitSpecified(isExplicitSpecified) {
2213
+ IsExplicitSpecified(isExplicitSpecified),
2214
+ IsInheritingConstructor((bool )Inherited) {
2189
2215
setImplicit (isImplicitlyDeclared);
2216
+ if (Inherited)
2217
+ *getTrailingObjects<InheritedConstructor>() = Inherited;
2190
2218
}
2191
2219
2192
2220
public:
2193
- static CXXConstructorDecl *CreateDeserialized (ASTContext &C, unsigned ID);
2194
- static CXXConstructorDecl * Create (ASTContext &C, CXXRecordDecl *RD,
2195
- SourceLocation StartLoc,
2196
- const DeclarationNameInfo &NameInfo ,
2197
- QualType T, TypeSourceInfo *TInfo,
2198
- bool isExplicit ,
2199
- bool isInline, bool isImplicitlyDeclared ,
2200
- bool isConstexpr );
2221
+ static CXXConstructorDecl *CreateDeserialized (ASTContext &C, unsigned ID,
2222
+ bool InheritsConstructor);
2223
+ static CXXConstructorDecl *
2224
+ Create (ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc ,
2225
+ const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo,
2226
+ bool isExplicit, bool isInline, bool isImplicitlyDeclared ,
2227
+ bool isConstexpr ,
2228
+ InheritedConstructor Inherited = InheritedConstructor() );
2201
2229
2202
2230
// / \brief Determine whether this constructor declaration has the
2203
2231
// / \c explicit keyword specified.
@@ -2344,11 +2372,15 @@ class CXXConstructorDecl : public CXXMethodDecl {
2344
2372
// / an object.
2345
2373
bool isSpecializationCopyingObject () const ;
2346
2374
2347
- // / \brief Get the constructor that this inheriting constructor is based on.
2348
- const CXXConstructorDecl *getInheritedConstructor () const ;
2375
+ // / \brief Determine whether this is an implicit constructor synthesized to
2376
+ // / model a call to a constructor inherited from a base class.
2377
+ bool isInheritingConstructor () const { return IsInheritingConstructor; }
2349
2378
2350
- // / \brief Set the constructor that this inheriting constructor is based on.
2351
- void setInheritedConstructor (const CXXConstructorDecl *BaseCtor);
2379
+ // / \brief Get the constructor that this inheriting constructor is based on.
2380
+ InheritedConstructor getInheritedConstructor () const {
2381
+ return IsInheritingConstructor ? *getTrailingObjects<InheritedConstructor>()
2382
+ : InheritedConstructor ();
2383
+ }
2352
2384
2353
2385
CXXConstructorDecl *getCanonicalDecl () override {
2354
2386
return cast<CXXConstructorDecl>(FunctionDecl::getCanonicalDecl ());
@@ -2363,6 +2395,7 @@ class CXXConstructorDecl : public CXXMethodDecl {
2363
2395
2364
2396
friend class ASTDeclReader ;
2365
2397
friend class ASTDeclWriter ;
2398
+ friend TrailingObjects;
2366
2399
};
2367
2400
2368
2401
// / \brief Represents a C++ destructor within a class.
@@ -2807,18 +2840,6 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
2807
2840
NamedDecl *UsingOrNextShadow;
2808
2841
friend class UsingDecl ;
2809
2842
2810
- UsingShadowDecl (ASTContext &C, DeclContext *DC, SourceLocation Loc,
2811
- UsingDecl *Using, NamedDecl *Target)
2812
- : NamedDecl(UsingShadow, DC, Loc, DeclarationName()),
2813
- redeclarable_base (C), Underlying(Target),
2814
- UsingOrNextShadow(reinterpret_cast <NamedDecl *>(Using)) {
2815
- if (Target) {
2816
- setDeclName (Target->getDeclName ());
2817
- IdentifierNamespace = Target->getIdentifierNamespace ();
2818
- }
2819
- setImplicit ();
2820
- }
2821
-
2822
2843
typedef Redeclarable<UsingShadowDecl> redeclarable_base;
2823
2844
UsingShadowDecl *getNextRedeclarationImpl () override {
2824
2845
return getNextRedeclaration ();
@@ -2830,11 +2851,16 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
2830
2851
return getMostRecentDecl ();
2831
2852
}
2832
2853
2854
+ protected:
2855
+ UsingShadowDecl (Kind K, ASTContext &C, DeclContext *DC, SourceLocation Loc,
2856
+ UsingDecl *Using, NamedDecl *Target);
2857
+ UsingShadowDecl (Kind K, ASTContext &C, EmptyShell);
2858
+
2833
2859
public:
2834
2860
static UsingShadowDecl *Create (ASTContext &C, DeclContext *DC,
2835
2861
SourceLocation Loc, UsingDecl *Using,
2836
2862
NamedDecl *Target) {
2837
- return new (C, DC) UsingShadowDecl (C, DC, Loc, Using, Target);
2863
+ return new (C, DC) UsingShadowDecl (UsingShadow, C, DC, Loc, Using, Target);
2838
2864
}
2839
2865
2840
2866
static UsingShadowDecl *CreateDeserialized (ASTContext &C, unsigned ID);
@@ -2846,6 +2872,7 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
2846
2872
using redeclarable_base::redecls;
2847
2873
using redeclarable_base::getPreviousDecl;
2848
2874
using redeclarable_base::getMostRecentDecl;
2875
+ using redeclarable_base::isFirstDecl;
2849
2876
2850
2877
UsingShadowDecl *getCanonicalDecl () override {
2851
2878
return getFirstDecl ();
@@ -2876,7 +2903,125 @@ class UsingShadowDecl : public NamedDecl, public Redeclarable<UsingShadowDecl> {
2876
2903
}
2877
2904
2878
2905
static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
2879
- static bool classofKind (Kind K) { return K == Decl::UsingShadow; }
2906
+ static bool classofKind (Kind K) {
2907
+ return K == Decl::UsingShadow || K == Decl::ConstructorUsingShadow;
2908
+ }
2909
+
2910
+ friend class ASTDeclReader ;
2911
+ friend class ASTDeclWriter ;
2912
+ };
2913
+
2914
+ // / \brief Represents a shadow constructor declaration introduced into a
2915
+ // / class by a C++11 using-declaration that names a constructor.
2916
+ // /
2917
+ // / For example:
2918
+ // / \code
2919
+ // / struct Base { Base(int); };
2920
+ // / struct Derived {
2921
+ // / using Base::Base; // creates a UsingDecl and a ConstructorUsingShadowDecl
2922
+ // / };
2923
+ // / \endcode
2924
+ class ConstructorUsingShadowDecl final : public UsingShadowDecl {
2925
+ void anchor () override ;
2926
+
2927
+ // / \brief If this constructor using declaration inherted the constructor
2928
+ // / from an indirect base class, this is the ConstructorUsingShadowDecl
2929
+ // / in the named direct base class from which the declaration was inherited.
2930
+ ConstructorUsingShadowDecl *NominatedBaseClassShadowDecl;
2931
+
2932
+ // / \brief If this constructor using declaration inherted the constructor
2933
+ // / from an indirect base class, this is the ConstructorUsingShadowDecl
2934
+ // / that will be used to construct the unique direct or virtual base class
2935
+ // / that receives the constructor arguments.
2936
+ ConstructorUsingShadowDecl *ConstructedBaseClassShadowDecl;
2937
+
2938
+ // / \brief \c true if the constructor ultimately named by this using shadow
2939
+ // / declaration is within a virtual base class subobject of the class that
2940
+ // / contains this declaration.
2941
+ unsigned IsVirtual : 1 ;
2942
+
2943
+ ConstructorUsingShadowDecl (ASTContext &C, DeclContext *DC, SourceLocation Loc,
2944
+ UsingDecl *Using, NamedDecl *Target,
2945
+ bool TargetInVirtualBase)
2946
+ : UsingShadowDecl(ConstructorUsingShadow, C, DC, Loc, Using,
2947
+ Target->getUnderlyingDecl ()),
2948
+ NominatedBaseClassShadowDecl(
2949
+ dyn_cast<ConstructorUsingShadowDecl>(Target)),
2950
+ ConstructedBaseClassShadowDecl(NominatedBaseClassShadowDecl),
2951
+ IsVirtual(TargetInVirtualBase) {
2952
+ // If we found a constructor for a non-virtual base class, but it chains to
2953
+ // a constructor for a virtual base, we should directly call the virtual
2954
+ // base constructor instead.
2955
+ // FIXME: This logic belongs in Sema.
2956
+ if (!TargetInVirtualBase && NominatedBaseClassShadowDecl &&
2957
+ NominatedBaseClassShadowDecl->constructsVirtualBase ()) {
2958
+ ConstructedBaseClassShadowDecl =
2959
+ NominatedBaseClassShadowDecl->ConstructedBaseClassShadowDecl ;
2960
+ IsVirtual = true ;
2961
+ }
2962
+ }
2963
+ ConstructorUsingShadowDecl (ASTContext &C, EmptyShell Empty)
2964
+ : UsingShadowDecl(ConstructorUsingShadow, C, Empty) {}
2965
+
2966
+ public:
2967
+ static ConstructorUsingShadowDecl *Create (ASTContext &C, DeclContext *DC,
2968
+ SourceLocation Loc,
2969
+ UsingDecl *Using, NamedDecl *Target,
2970
+ bool IsVirtual);
2971
+ static ConstructorUsingShadowDecl *CreateDeserialized (ASTContext &C,
2972
+ unsigned ID);
2973
+
2974
+ // / Returns the parent of this using shadow declaration, which
2975
+ // / is the class in which this is declared.
2976
+ // @{
2977
+ const CXXRecordDecl *getParent () const {
2978
+ return cast<CXXRecordDecl>(getDeclContext ());
2979
+ }
2980
+ CXXRecordDecl *getParent () {
2981
+ return cast<CXXRecordDecl>(getDeclContext ());
2982
+ }
2983
+ // @}
2984
+
2985
+ // / \brief Get the inheriting constructor declaration for the direct base
2986
+ // / class from which this using shadow declaration was inherited, if there is
2987
+ // / one. This can be different for each redeclaration of the same shadow decl.
2988
+ ConstructorUsingShadowDecl *getNominatedBaseClassShadowDecl () const {
2989
+ return NominatedBaseClassShadowDecl;
2990
+ }
2991
+
2992
+ // / \brief Get the inheriting constructor declaration for the base class
2993
+ // / for which we don't have an explicit initializer, if there is one.
2994
+ ConstructorUsingShadowDecl *getConstructedBaseClassShadowDecl () const {
2995
+ return ConstructedBaseClassShadowDecl;
2996
+ }
2997
+
2998
+ // / \brief Get the base class that was named in the using declaration. This
2999
+ // / can be different for each redeclaration of this same shadow decl.
3000
+ CXXRecordDecl *getNominatedBaseClass () const ;
3001
+
3002
+ // / \brief Get the base class whose constructor or constructor shadow
3003
+ // / declaration is passed the constructor arguments.
3004
+ CXXRecordDecl *getConstructedBaseClass () const {
3005
+ return cast<CXXRecordDecl>((ConstructedBaseClassShadowDecl
3006
+ ? ConstructedBaseClassShadowDecl
3007
+ : getTargetDecl ())
3008
+ ->getDeclContext ());
3009
+ }
3010
+
3011
+ // / \brief Returns \c true if the constructed base class is a virtual base
3012
+ // / class subobject of this declaration's class.
3013
+ bool constructsVirtualBase () const {
3014
+ return IsVirtual;
3015
+ }
3016
+
3017
+ // / \brief Get the constructor or constructor template in the derived class
3018
+ // / correspnding to this using shadow declaration, if it has been implicitly
3019
+ // / declared already.
3020
+ CXXConstructorDecl *getConstructor () const ;
3021
+ void setConstructor (NamedDecl *Ctor);
3022
+
3023
+ static bool classof (const Decl *D) { return classofKind (D->getKind ()); }
3024
+ static bool classofKind (Kind K) { return K == ConstructorUsingShadow; }
2880
3025
2881
3026
friend class ASTDeclReader ;
2882
3027
friend class ASTDeclWriter ;
0 commit comments