@@ -1864,76 +1864,114 @@ class ExtensionRange {
1864
1864
// / Pattern and Initialization expression. The pattern is always present, but
1865
1865
// / the initializer can be null if there is none.
1866
1866
class PatternBindingEntry {
1867
- Pattern *ThePattern;
1868
-
1869
- // / The location of the equal '=' token.
1870
- SourceLoc EqualLoc;
1871
-
1872
1867
enum class Flags {
1873
1868
Checked = 1 << 0 ,
1874
1869
Removed = 1 << 1 ,
1875
- Lazy = 1 << 2 ,
1870
+ Lazy = 1 << 2
1871
+ };
1872
+ llvm::PointerIntPair<Pattern *, 3 , OptionSet<Flags>> PatternAndFlags;
1873
+
1874
+ struct ExprAndEqualLoc {
1875
+ // When the initializer is removed we don't actually clear the pointer
1876
+ // because we might need to get initializer's source range. Since the
1877
+ // initializer is ASTContext-allocated it is safe.
1878
+ Expr *Node;
1879
+ // / The location of the equal '=' token.
1880
+ SourceLoc EqualLoc;
1876
1881
};
1877
1882
1878
- // When the initializer is removed we don't actually clear the pointer
1879
- // because we might need to get initializer's source range. Since the
1880
- // initializer is ASTContext-allocated it is safe.
1881
- llvm::PointerIntPair<Expr *, 3 , OptionSet<Flags>> InitAndFlags;
1883
+ union {
1884
+ // / The initializer expression and its '=' token loc.
1885
+ ExprAndEqualLoc InitExpr;
1886
+
1887
+ // / The text of the initializer expression if deserialized from a module.
1888
+ StringRef InitStringRepresentation;
1889
+ };
1882
1890
1883
1891
// / The initializer context used for this pattern binding entry.
1884
- DeclContext *InitContext = nullptr ;
1892
+ llvm::PointerIntPair< DeclContext *, 1 , bool > InitContextAndIsText ;
1885
1893
1886
1894
friend class PatternBindingInitializer ;
1887
1895
1888
1896
public:
1889
1897
PatternBindingEntry (Pattern *P, SourceLoc EqualLoc, Expr *E,
1890
1898
DeclContext *InitContext)
1891
- : ThePattern(P), EqualLoc(EqualLoc), InitAndFlags(E, {}),
1892
- InitContext (InitContext) {}
1899
+ : PatternAndFlags(P, {}), InitExpr({E, EqualLoc}),
1900
+ InitContextAndIsText ({InitContext, false }) {
1901
+ }
1893
1902
1894
- Pattern *getPattern () const { return ThePattern ; }
1895
- void setPattern (Pattern *P) { ThePattern = P ; }
1903
+ Pattern *getPattern () const { return PatternAndFlags. getPointer () ; }
1904
+ void setPattern (Pattern *P) { PatternAndFlags. setPointer (P) ; }
1896
1905
Expr *getInit () const {
1897
- return (InitAndFlags.getInt ().contains (Flags::Removed))
1898
- ? nullptr : InitAndFlags.getPointer ();
1906
+ if (PatternAndFlags.getInt ().contains (Flags::Removed) ||
1907
+ InitContextAndIsText.getInt ())
1908
+ return nullptr ;
1909
+ return InitExpr.Node ;
1899
1910
}
1900
1911
Expr *getNonLazyInit () const {
1901
1912
return isInitializerLazy () ? nullptr : getInit ();
1902
1913
}
1903
1914
SourceRange getOrigInitRange () const ;
1904
1915
void setInit (Expr *E);
1905
1916
1917
+ // / Gets the text of the initializer expression, stripping out inactive
1918
+ // / branches of any #ifs inside the expression.
1919
+ StringRef getInitStringRepresentation (SmallVectorImpl<char > &scratch) const ;
1920
+
1921
+ // / Sets the initializer string representation to the string that was
1922
+ // / deserialized from a partial module.
1923
+ void setInitStringRepresentation (StringRef str) {
1924
+ InitStringRepresentation = str;
1925
+ InitContextAndIsText.setInt (true );
1926
+ }
1927
+
1928
+ // / Whether this pattern entry can generate a string representation of its
1929
+ // / initializer expression.
1930
+ bool hasInitStringRepresentation () const ;
1931
+
1906
1932
// / Retrieve the location of the equal '=' token.
1907
- SourceLoc getEqualLoc () const { return EqualLoc; }
1933
+ SourceLoc getEqualLoc () const {
1934
+ return InitContextAndIsText.getInt () ? SourceLoc () : InitExpr.EqualLoc ;
1935
+ }
1908
1936
1909
1937
// / Set the location of the equal '=' token.
1910
- void setEqualLoc (SourceLoc equalLoc) { EqualLoc = equalLoc; }
1938
+ void setEqualLoc (SourceLoc equalLoc) {
1939
+ assert (!InitContextAndIsText.getInt () &&
1940
+ " cannot set equal loc for textual initializer" );
1941
+ InitExpr.EqualLoc = equalLoc;
1942
+ }
1911
1943
1912
1944
// / Retrieve the initializer as it was written in the source.
1913
- Expr *getInitAsWritten () const { return InitAndFlags.getPointer (); }
1945
+ Expr *getInitAsWritten () const {
1946
+ return InitContextAndIsText.getInt () ? nullptr : InitExpr.Node ;
1947
+ }
1914
1948
1915
1949
bool isInitializerChecked () const {
1916
- return InitAndFlags .getInt ().contains (Flags::Checked);
1950
+ return PatternAndFlags .getInt ().contains (Flags::Checked);
1917
1951
}
1918
1952
void setInitializerChecked () {
1919
- InitAndFlags .setInt (InitAndFlags .getInt () | Flags::Checked);
1953
+ PatternAndFlags .setInt (PatternAndFlags .getInt () | Flags::Checked);
1920
1954
}
1921
1955
1922
1956
bool isInitializerLazy () const {
1923
- return InitAndFlags .getInt ().contains (Flags::Lazy);
1957
+ return PatternAndFlags .getInt ().contains (Flags::Lazy);
1924
1958
}
1925
1959
void setInitializerLazy () {
1926
- InitAndFlags .setInt (InitAndFlags .getInt () | Flags::Lazy);
1960
+ PatternAndFlags .setInt (PatternAndFlags .getInt () | Flags::Lazy);
1927
1961
}
1928
1962
1929
1963
// Return the first variable initialized by this pattern.
1930
1964
VarDecl *getAnchoringVarDecl () const ;
1931
1965
1932
1966
// Retrieve the declaration context for the initializer.
1933
- DeclContext *getInitContext () const { return InitContext; }
1967
+ DeclContext *getInitContext () const {
1968
+ return InitContextAndIsText.getPointer ();
1969
+ }
1934
1970
1935
1971
// / Override the initializer context.
1936
- void setInitContext (DeclContext *dc) { InitContext = dc; }
1972
+ void setInitContext (DeclContext *dc) {
1973
+ InitContextAndIsText.setPointer (dc);
1974
+ }
1937
1975
1938
1976
// / Retrieve the source range covered by this pattern binding.
1939
1977
// /
@@ -2007,6 +2045,10 @@ class PatternBindingDecl final : public Decl,
2007
2045
return const_cast <PatternBindingDecl*>(this )->getMutablePatternList ();
2008
2046
}
2009
2047
2048
+ void setInitStringRepresentation (unsigned i, StringRef str) {
2049
+ getMutablePatternList ()[i].setInitStringRepresentation (str);
2050
+ }
2051
+
2010
2052
Expr *getInit (unsigned i) const {
2011
2053
return getPatternList ()[i].getInit ();
2012
2054
}
@@ -2039,7 +2081,8 @@ class PatternBindingDecl final : public Decl,
2039
2081
2040
2082
// / Return the PatternEntry (a pattern + initializer pair) for the specified
2041
2083
// / VarDecl.
2042
- PatternBindingEntry getPatternEntryForVarDecl (const VarDecl *VD) const {
2084
+ const PatternBindingEntry &getPatternEntryForVarDecl (
2085
+ const VarDecl *VD) const {
2043
2086
return getPatternList ()[getPatternEntryIndexForVarDecl (VD)];
2044
2087
}
2045
2088
@@ -2097,7 +2140,7 @@ class PatternBindingDecl final : public Decl,
2097
2140
static bool classof (const Decl *D) {
2098
2141
return D->getKind () == DeclKind::PatternBinding;
2099
2142
}
2100
-
2143
+
2101
2144
private:
2102
2145
MutableArrayRef<PatternBindingEntry> getMutablePatternList () {
2103
2146
// Pattern entries are tail allocated.
@@ -4606,6 +4649,14 @@ class VarDecl : public AbstractStorageDecl {
4606
4649
return nullptr ;
4607
4650
}
4608
4651
4652
+ // Return whether this VarDecl has an initial value, either by checking
4653
+ // if it has an initializer in its parent pattern binding or if it has
4654
+ // the @_hasInitialValue attribute.
4655
+ bool hasInitialValue () const {
4656
+ return getAttrs ().hasAttribute <HasInitialValueAttr>() ||
4657
+ getParentInitializer ();
4658
+ }
4659
+
4609
4660
VarDecl *getOverriddenDecl () const {
4610
4661
return cast_or_null<VarDecl>(AbstractStorageDecl::getOverriddenDecl ());
4611
4662
}
@@ -4687,6 +4738,13 @@ class VarDecl : public AbstractStorageDecl {
4687
4738
void setHasNonPatternBindingInit (bool V = true ) {
4688
4739
Bits.VarDecl .HasNonPatternBindingInit = V;
4689
4740
}
4741
+
4742
+ // / Determines if this var has an initializer expression that should be
4743
+ // / exposed to clients.
4744
+ // / There's a very narrow case when we would: if the decl is an instance
4745
+ // / member with an initializer expression and the parent type is
4746
+ // / @_fixed_layout and resides in a resilient module.
4747
+ bool isInitExposedToClients () const ;
4690
4748
4691
4749
// / Is this a special debugger variable?
4692
4750
bool isDebuggerVar () const { return Bits.VarDecl .IsDebuggerVar ; }
0 commit comments