[PATCH] D48661: [Fixed Point Arithmetic] Fixed Point Constant

2018-08-06 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

Just a nit but could you please add new-lines to your commit messages.
Also the 3 bools in FixedPointSemantics are a little bit wasteful.


Repository:
  rL LLVM

https://reviews.llvm.org/D48661



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48661: [Fixed Point Arithmetic] Fixed Point Constant

2018-08-06 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

And using the name Sema is a bad idea IMHO since this has a totally different 
meaning in clang.


Repository:
  rL LLVM

https://reviews.llvm.org/D48661



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50261: [AST] Remove unnecessary indirections in DeclarationNameTable

2018-08-06 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

Yes it would be nice indeed. IIRC it is only needed for
QualType in one of the moved class.

This patch is especially nice since it both cleanup the code and
speed up clang :)


Repository:
  rL LLVM

https://reviews.llvm.org/D50261



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D48661: [Fixed Point Arithmetic] Fixed Point Constant

2018-08-06 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

Added some comments inline. 
However I have not looked at the logic too closely and
have not looked at the tests at all.




Comment at: cfe/trunk/include/clang/AST/ASTContext.h:1966
   unsigned char getFixedPointIBits(QualType Ty) const;
+  FixedPointSemantics getFixedPointSemantics(QualType Ty) const;
+  APFixedPoint getFixedPointMax(QualType Ty) const;

could you add some comments for these functions ?
What are they doing ?



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:24
+
+class ASTContext;
+class QualType;

This should be removed if unused. It is very strange to have
something basic like a fixed point type depending on ASTContext...



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:31
+/// When HasUnsignedPadding is true and this type is signed, the first bit
+/// in the value this represents is treaded as padding.
+class FixedPointSemantics {

s/treaded/treated



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:54
+  return Width - Scale;
+  }
+

Do you really need the branch here?
Why not just return
`Width - Scale - (IsSigned || (!IsSigned && HasUnsignedPadding))`

Also doc



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:62
+  bool HasUnsignedPadding;
+};
+

My point is that you have two unsigned and then 3 bools.
This means that your class has now sizeof == 3*sizeof(unsigned)
This is annoying on 64 bits archs since pretty much everything
in clang is aligned to 8 bytes (because of pointer alignment requirements)
Just stuff your bits into Width or Scale. Moreover I think that
you could just use a single unsigned to store all of this.

For example you could here use a bit-field like so: 
unsigned Width : 15; (or any other appropriate split with Scale)
unsigned Scale : 14; (or any other appropriate split with Width)
unsigned IsSigned : 1;
unsigned IsSaturated : 1;
unsigned HasUnsignedPadding : 1;

Now I do not now if this matters or not in this case but it seems
to me that this is easy to do.



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:85
+  Sema) {}
+
+   llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); 
}

same comment about "sema"



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:99
+  }
+
+  APFixedPoint shl(unsigned Amt) const {

Maybe a bit more documentation here...

Also use /// for comments explaining something to an user:
eg:

/// Create a new Frob blablabla
Frob makeFrobinator()

so that doxygen picks up these comments.

Use // for comments which are internal only
eg:

...
// TODO this is broken because blablabla
...



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:110
+  }
+
+  // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.

doc



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:120
+  bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; 
}
+  bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; 
}
+  bool operator>=(const APFixedPoint &Other) const {

does this fit into 80 cols ?



Comment at: cfe/trunk/include/clang/Basic/FixedPoint.h:130
+  static APFixedPoint getMin(const FixedPointSemantics &Sema);
+
+private:

doc



Comment at: cfe/trunk/lib/AST/ASTContext.cpp:10439
+FixedPointSemantics ASTContext::getFixedPointSemantics(QualType Ty) const {
+  assert(Ty->isFixedPointType());
+  bool isSigned = Ty->isSignedFixedPointType();

assert( ... && "Ty is not a fixed point type!")



Comment at: cfe/trunk/lib/AST/ASTContext.cpp:10448
+APFixedPoint ASTContext::getFixedPointMax(QualType Ty) const {
+  assert(Ty->isFixedPointType());
+  return APFixedPoint::getMax(getFixedPointSemantics(Ty));

same



Comment at: cfe/trunk/lib/AST/ASTContext.cpp:10453
+APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const {
+  assert(Ty->isFixedPointType());
+  return APFixedPoint::getMin(getFixedPointSemantics(Ty));

same



Comment at: cfe/trunk/lib/Basic/FixedPoint.cpp:15
+
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/FixedPoint.h"

Basic depends on ASTContext ? huh



Comment at: cfe/trunk/lib/Basic/FixedPoint.cpp:98
+  }
+
+  return 0;

Would this work: do a test for equality and return 0 if true,
then it seems to me that you can drop every `else if`.
Also maybe use the above trick to remove some branches.


Repository:
  rL LLVM

https://reviews.llvm.org/D48661



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-

[PATCH] D48661: [Fixed Point Arithmetic] Fixed Point Constant

2018-08-07 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

Just to provide a bit of additional context:

My comment about fsyntax-only is not specific to fsyntax-only.
This is just an handy way to benchmark the frontend without noise
from LLVM. It is important to keep all frequently used structures small
(within reason) even if this result in a little bit of additional work to 
pack/unpack
(again, within reason) since the front-end is not doing a lot of computations
but is doing a lot of memory accesses.

On my machine when I do an fsyntax-only on all of Boost
~25% of the cycles are spent with execution stalled because of
a cache miss.

Now this basic fixed point type will potentially ends up in
the Type/Stmt/Decl hierarchy -> it *must* be small.

For another example of what not to do see APSInt which
stores a single bool, thus wasting 8 bytes on 64 bits archs
just for this single bit. I actually have a patch stuffing it into APInt
but have not bothered to upstream it since in this case it do not
really matter for clang.


Repository:
  rL LLVM

https://reviews.llvm.org/D48661



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50532: Fix a wrong type bug in ParsedAttr::TypeTagForDatatypeData

2018-08-09 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: erichkeane.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

This patch fixes a wrong type bug inside `ParsedAttr::TypeTagForDatatypeData`.
The details to the best of my knowledge are as follow. The incredible thing
is that everything works out just fine by chance due to a sequence of lucky
coincidences in the layout of various types.

The struct `ParsedAttr::TypeTagForDatatypeData` contains among other things
a `ParsedType *MatchingCType`, where `ParsedType` is just `OpaquePtr`.

However the member `MatchingCType` is initialized in the constructor for
type_tag_for_datatype attribute as follows:

`new (&ExtraData.MatchingCType) ParsedType(matchingCType);`

This results in the `ParsedType` being constructed in the location of the
`ParsedType *` Later `ParsedAttr::getMatchingCType` do `return
*getTypeTagForDatatypeDataSlot().MatchingCType;` which instead of
dereferencing the `ParsedType *` will dereference the `QualType` inside
the `ParsedType`. Now this `QualType` in this case contains no qualifiers
and therefore is a valid `Type *`. Therefore `getMatchingCType` returns a
`Type` or at least the stuff that is in the first `sizeof(void*)` bytes of it,
But it turns out that `Type` inherits from `ExtQualsCommonBase` and that the
first member of `ExtQualsCommonBase` is a `const Type *const BaseType`. This
`Type *` in this case points to the original `Type` pointed to by the
`QualType` and so everything works fine even though all the types were wrong.

This bug was only found because I changed the layout of `Type`,
which obviously broke all of this long chain of improbable events.


Repository:
  rC Clang

https://reviews.llvm.org/D50532

Files:
  include/clang/Sema/ParsedAttr.h


Index: include/clang/Sema/ParsedAttr.h
===
--- include/clang/Sema/ParsedAttr.h
+++ include/clang/Sema/ParsedAttr.h
@@ -199,7 +199,7 @@
 
 public:
   struct TypeTagForDatatypeData {
-ParsedType *MatchingCType;
+ParsedType MatchingCType;
 unsigned LayoutCompatible : 1;
 unsigned MustBeNull : 1;
   };
@@ -487,7 +487,7 @@
   const ParsedType &getMatchingCType() const {
 assert(getKind() == AT_TypeTagForDatatype &&
"Not a type_tag_for_datatype attribute");
-return *getTypeTagForDatatypeDataSlot().MatchingCType;
+return getTypeTagForDatatypeDataSlot().MatchingCType;
   }
 
   bool getLayoutCompatible() const {


Index: include/clang/Sema/ParsedAttr.h
===
--- include/clang/Sema/ParsedAttr.h
+++ include/clang/Sema/ParsedAttr.h
@@ -199,7 +199,7 @@
 
 public:
   struct TypeTagForDatatypeData {
-ParsedType *MatchingCType;
+ParsedType MatchingCType;
 unsigned LayoutCompatible : 1;
 unsigned MustBeNull : 1;
   };
@@ -487,7 +487,7 @@
   const ParsedType &getMatchingCType() const {
 assert(getKind() == AT_TypeTagForDatatype &&
"Not a type_tag_for_datatype attribute");
-return *getTypeTagForDatatypeDataSlot().MatchingCType;
+return getTypeTagForDatatypeDataSlot().MatchingCType;
   }
 
   bool getLayoutCompatible() const {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50531: [NFC] Convert ParsedAttr to use llvm::TrailingObjects

2018-08-09 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

Some inline comments. Since you already committed it I don't think it
is worth bothering with them.




Comment at: cfe/trunk/include/clang/Sema/ParsedAttr.h:124
+  detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData>;
+
+  size_t numTrailingObjects(OverloadToken) const { return NumArgs; }

I think you can do something like `friend TrailingObjects;`
like most (every ?) other users of `TrailingObjects` do. It relies on the
injected class name if I am not mistaken.



Comment at: cfe/trunk/include/clang/Sema/ParsedAttr.h:366
   ParsedAttr &operator=(const ParsedAttr &) = delete;
   ~ParsedAttr() = delete;
 

And maybe it would be nice to delete explicitly the move
ctor/assignment op too (my turn to make this remark :) ).
They are already not declared I think so it do not really matter.


Repository:
  rL LLVM

https://reviews.llvm.org/D50531



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: erichkeane, rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

The current static_assert only checks that ObjCObjectTypeBitfields
fits into an unsigned. However it turns out that FunctionTypeBitfields
do not currently fits into an unsigned. Therefore the anonymous
union containing the bit-fields always use 8 bytes instead of 4.

This patch remove the lone misguided static_assert and systematically
check the size of each bit-field.


Repository:
  rC Clang

https://reviews.llvm.org/D50630

Files:
  include/clang/AST/Type.h


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1557,8 +1557,6 @@
 unsigned IsKindOf : 1;
   };
 
-  static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
-
   class ReferenceTypeBitfields {
 friend class ReferenceType;
 
@@ -1637,6 +1635,27 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+
+static_assert(sizeof(TypeBitfields) <= 4,
+  "TypeBitfields is larger than 4 bytes!");
+static_assert(sizeof(ArrayTypeBitfields) <= 8,
+  "ArrayTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AttributedTypeBitfields) <= 8,
+  "AttributedTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AutoTypeBitfields) <= 8,
+  "AutoTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(BuiltinTypeBitfields) <= 8,
+  "BuiltinTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(FunctionTypeBitfields) <= 8,
+  "FunctionTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ObjCObjectTypeBitfields) <= 8,
+  "ObjCObjectTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ReferenceTypeBitfields) <= 8,
+  "ReferenceTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(TypeWithKeywordBitfields) <= 8,
+  "TypeWithKeywordBitfields is larger than 8 bytes!");
+static_assert(sizeof(VectorTypeBitfields) <= 8,
+  "VectorTypeBitfields is larger than 8 bytes!");
   };
 
 private:


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1557,8 +1557,6 @@
 unsigned IsKindOf : 1;
   };
 
-  static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
-
   class ReferenceTypeBitfields {
 friend class ReferenceType;
 
@@ -1637,6 +1635,27 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+
+static_assert(sizeof(TypeBitfields) <= 4,
+  "TypeBitfields is larger than 4 bytes!");
+static_assert(sizeof(ArrayTypeBitfields) <= 8,
+  "ArrayTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AttributedTypeBitfields) <= 8,
+  "AttributedTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AutoTypeBitfields) <= 8,
+  "AutoTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(BuiltinTypeBitfields) <= 8,
+  "BuiltinTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(FunctionTypeBitfields) <= 8,
+  "FunctionTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ObjCObjectTypeBitfields) <= 8,
+  "ObjCObjectTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ReferenceTypeBitfields) <= 8,
+  "ReferenceTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(TypeWithKeywordBitfields) <= 8,
+  "TypeWithKeywordBitfields is larger than 8 bytes!");
+static_assert(sizeof(VectorTypeBitfields) <= 8,
+  "VectorTypeBitfields is larger than 8 bytes!");
   };
 
 private:
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50631: [AST] Stuff more data into FunctionTypeBitfields

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: erichkeane, rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Since FunctionTypeBitfields is already > 32 bits wide we might
as well stuff the remaining bits from FunctionProtoType into it.

The patch is very mechanical, but changes the maximum number of
parameters from 2^15-1 to 2^12-1 to fit into FunctionTypeBitfields.
This seems still large enough, and in any case according to the
annex B of the C++ standard we only need to be able to accept
256 parameters.

Also the member `unsigned RefQualifier : 2;` is moved in 
FunctionTypeBitfields. This is intentional and done to avoid
the unsigned boundary.


Repository:
  rC Clang

https://reviews.llvm.org/D50631

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp

Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2844,24 +2844,23 @@
 FunctionProtoType::FunctionProtoType(QualType result, ArrayRef params,
  QualType canonical,
  const ExtProtoInfo &epi)
-: FunctionType(FunctionProto, result, canonical,
-   result->isDependentType(),
+: FunctionType(FunctionProto, result, canonical, result->isDependentType(),
result->isInstantiationDependentType(),
result->isVariablyModifiedType(),
-   result->containsUnexpandedParameterPack(), epi.ExtInfo),
-  NumParams(params.size()),
-  NumExceptions(epi.ExceptionSpec.Exceptions.size()),
-  ExceptionSpecType(epi.ExceptionSpec.Type),
-  HasExtParameterInfos(epi.ExtParameterInfos != nullptr),
-  Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn) {
-  assert(NumParams == params.size() && "function has too many parameters");
-
+   result->containsUnexpandedParameterPack(), epi.ExtInfo) {
   FunctionTypeBits.TypeQuals = epi.TypeQuals;
   FunctionTypeBits.RefQualifier = epi.RefQualifier;
+  FunctionTypeBits.NumParams = params.size();
+  assert(getNumParams() == params.size() && "function w. too many parameters!");
+  FunctionTypeBits.NumExceptions = epi.ExceptionSpec.Exceptions.size();
+  FunctionTypeBits.ExceptionSpecType = epi.ExceptionSpec.Type;
+  FunctionTypeBits.HasExtParameterInfos = !!epi.ExtParameterInfos;
+  FunctionTypeBits.Variadic = epi.Variadic;
+  FunctionTypeBits.HasTrailingReturn = epi.HasTrailingReturn;
 
   // Fill in the trailing argument array.
   auto *argSlot = reinterpret_cast(this+1);
-  for (unsigned i = 0; i != NumParams; ++i) {
+  for (unsigned i = 0, N = getNumParams(); i != N; ++i) {
 if (params[i]->isDependentType())
   setDependent();
 else if (params[i]->isInstantiationDependentType())
@@ -2875,7 +2874,7 @@
 
   if (getExceptionSpecType() == EST_Dynamic) {
 // Fill in the exception array.
-QualType *exnSlot = argSlot + NumParams;
+QualType *exnSlot = argSlot + getNumParams();
 unsigned I = 0;
 for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) {
   // Note that, before C++17, a dependent exception specification does
@@ -2895,7 +2894,7 @@
epi.ExceptionSpec.NoexceptExpr->isValueDependent());
 
 // Store the noexcept expression and context.
-auto **noexSlot = reinterpret_cast(argSlot + NumParams);
+auto **noexSlot = reinterpret_cast(argSlot + getNumParams());
 *noexSlot = epi.ExceptionSpec.NoexceptExpr;
 
 if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() ||
@@ -2907,15 +2906,15 @@
   } else if (getExceptionSpecType() == EST_Uninstantiated) {
 // Store the function decl from which we will resolve our
 // exception specification.
-auto **slot = reinterpret_cast(argSlot + NumParams);
+auto **slot = reinterpret_cast(argSlot + getNumParams());
 slot[0] = epi.ExceptionSpec.SourceDecl;
 slot[1] = epi.ExceptionSpec.SourceTemplate;
 // This exception specification doesn't make the type dependent, because
 // it's not instantiated as part of instantiating the type.
   } else if (getExceptionSpecType() == EST_Unevaluated) {
 // Store the function decl from which we will resolve our
 // exception specification.
-auto **slot = reinterpret_cast(argSlot + NumParams);
+auto **slot = reinterpret_cast(argSlot + getNumParams());
 slot[0] = epi.ExceptionSpec.SourceDecl;
   }
 
@@ -2935,7 +2934,7 @@
   if (epi.ExtParameterInfos) {
 auto *extParamInfos =
   const_cast(getExtParameterInfosBuffer());
-for (unsigned i = 0; i != NumParams; ++i)
+for (unsigned i = 0, N = getNumParams(); i != N; ++i)
   extParamInfos[i] = epi.ExtParameterInfos[i];
   }
 }
@@ -2981,7 +2980,7 @@
   case EST_Dynamic:
 // A dynamic exception specification is throwing unless every exception
 // type is an (unexpanded) pack expansion type.
-for (unsigned I = 0, N = NumExceptions; I != N; ++I)
+for (unsig

[PATCH] D50631: [AST] Stuff more data into FunctionTypeBitfields

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: include/clang/AST/Type.h:1530
+/// The number of types in the exception spec, if any.
+unsigned NumExceptions : 9;
+

erichkeane wrote:
> IMO (and @rsmith should respond here instead), if we were looking to steal 
> bits from anywhere, this would be it.  Exception-specifications that use 
> types ares are deprecated in the language and I'm not sure anyone ever used 
> them anyway.
Yes this seems a good idea. We could steal 2 bits (or more) from
here to restore the 14 bits in NumParams. I can't imagine that
someone will miss not being able to specify > 512 types
in an exception specification.



Comment at: lib/AST/Type.cpp:2863
   auto *argSlot = reinterpret_cast(this+1);
-  for (unsigned i = 0; i != NumParams; ++i) {
+  for (unsigned i = 0, N = getNumParams(); i != N; ++i) {
 if (params[i]->isDependentType())

erichkeane wrote:
> I would be unbelievably surprised if this change is worth-while.  I can't see 
> a situation where this getNumParams call doesn't get inlined.
It was just for consistency with the other changes,
but perhaps it do not belongs to this patch.


Repository:
  rC Clang

https://reviews.llvm.org/D50631



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno marked an inline comment as done.
riccibruno added inline comments.



Comment at: include/clang/AST/Type.h:1639
+
+static_assert(sizeof(TypeBitfields) <= 4,
+  "TypeBitfields is larger than 4 bytes!");

erichkeane wrote:
> I don't really see value in ensuring that TypeBitfields is <= 4 bytes, it 
> seems to me that all we care about is the union size, so just <=8 is fine.
I originally did this in the hope to provide more information
to someone who trigger one of the various static_assert.

But you are completely right that we only care about <= 8 bytes

Will update the diff with this change.


Repository:
  rC Clang

https://reviews.llvm.org/D50630



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 160368.
riccibruno marked an inline comment as done.

Repository:
  rC Clang

https://reviews.llvm.org/D50630

Files:
  include/clang/AST/Type.h


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1557,8 +1557,6 @@
 unsigned IsKindOf : 1;
   };
 
-  static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
-
   class ReferenceTypeBitfields {
 friend class ReferenceType;
 
@@ -1637,6 +1635,27 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+
+static_assert(sizeof(TypeBitfields) <= 8,
+  "TypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ArrayTypeBitfields) <= 8,
+  "ArrayTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AttributedTypeBitfields) <= 8,
+  "AttributedTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AutoTypeBitfields) <= 8,
+  "AutoTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(BuiltinTypeBitfields) <= 8,
+  "BuiltinTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(FunctionTypeBitfields) <= 8,
+  "FunctionTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ObjCObjectTypeBitfields) <= 8,
+  "ObjCObjectTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ReferenceTypeBitfields) <= 8,
+  "ReferenceTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(TypeWithKeywordBitfields) <= 8,
+  "TypeWithKeywordBitfields is larger than 8 bytes!");
+static_assert(sizeof(VectorTypeBitfields) <= 8,
+  "VectorTypeBitfields is larger than 8 bytes!");
   };
 
 private:


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1557,8 +1557,6 @@
 unsigned IsKindOf : 1;
   };
 
-  static_assert(NumTypeBits + 7 + 6 + 1 <= 32, "Does not fit in an unsigned");
-
   class ReferenceTypeBitfields {
 friend class ReferenceType;
 
@@ -1637,6 +1635,27 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+
+static_assert(sizeof(TypeBitfields) <= 8,
+  "TypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ArrayTypeBitfields) <= 8,
+  "ArrayTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AttributedTypeBitfields) <= 8,
+  "AttributedTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(AutoTypeBitfields) <= 8,
+  "AutoTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(BuiltinTypeBitfields) <= 8,
+  "BuiltinTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(FunctionTypeBitfields) <= 8,
+  "FunctionTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ObjCObjectTypeBitfields) <= 8,
+  "ObjCObjectTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(ReferenceTypeBitfields) <= 8,
+  "ReferenceTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(TypeWithKeywordBitfields) <= 8,
+  "TypeWithKeywordBitfields is larger than 8 bytes!");
+static_assert(sizeof(VectorTypeBitfields) <= 8,
+  "VectorTypeBitfields is larger than 8 bytes!");
   };
 
 private:
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50631: [AST] Stuff more data into FunctionTypeBitfields

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 160369.
riccibruno marked 5 inline comments as done.
riccibruno edited the summary of this revision.
riccibruno added a comment.

Bumped the number of bits for parameters from 12 to 14,
stealing from NumExceptions. This means that now (unless
limited by something else in clang) the maximum number
of types in a dynamic exception spec is 127, and the
maximum number of function parameters is 16383.


Repository:
  rC Clang

https://reviews.llvm.org/D50631

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp

Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2844,24 +2844,23 @@
 FunctionProtoType::FunctionProtoType(QualType result, ArrayRef params,
  QualType canonical,
  const ExtProtoInfo &epi)
-: FunctionType(FunctionProto, result, canonical,
-   result->isDependentType(),
+: FunctionType(FunctionProto, result, canonical, result->isDependentType(),
result->isInstantiationDependentType(),
result->isVariablyModifiedType(),
-   result->containsUnexpandedParameterPack(), epi.ExtInfo),
-  NumParams(params.size()),
-  NumExceptions(epi.ExceptionSpec.Exceptions.size()),
-  ExceptionSpecType(epi.ExceptionSpec.Type),
-  HasExtParameterInfos(epi.ExtParameterInfos != nullptr),
-  Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn) {
-  assert(NumParams == params.size() && "function has too many parameters");
-
+   result->containsUnexpandedParameterPack(), epi.ExtInfo) {
   FunctionTypeBits.TypeQuals = epi.TypeQuals;
   FunctionTypeBits.RefQualifier = epi.RefQualifier;
+  FunctionTypeBits.NumParams = params.size();
+  assert(getNumParams() == params.size() && "function w. too many parameters!");
+  FunctionTypeBits.NumExceptions = epi.ExceptionSpec.Exceptions.size();
+  FunctionTypeBits.ExceptionSpecType = epi.ExceptionSpec.Type;
+  FunctionTypeBits.HasExtParameterInfos = !!epi.ExtParameterInfos;
+  FunctionTypeBits.Variadic = epi.Variadic;
+  FunctionTypeBits.HasTrailingReturn = epi.HasTrailingReturn;
 
   // Fill in the trailing argument array.
   auto *argSlot = reinterpret_cast(this+1);
-  for (unsigned i = 0; i != NumParams; ++i) {
+  for (unsigned i = 0; i != getNumParams(); ++i) {
 if (params[i]->isDependentType())
   setDependent();
 else if (params[i]->isInstantiationDependentType())
@@ -2875,7 +2874,7 @@
 
   if (getExceptionSpecType() == EST_Dynamic) {
 // Fill in the exception array.
-QualType *exnSlot = argSlot + NumParams;
+QualType *exnSlot = argSlot + getNumParams();
 unsigned I = 0;
 for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) {
   // Note that, before C++17, a dependent exception specification does
@@ -2895,7 +2894,7 @@
epi.ExceptionSpec.NoexceptExpr->isValueDependent());
 
 // Store the noexcept expression and context.
-auto **noexSlot = reinterpret_cast(argSlot + NumParams);
+auto **noexSlot = reinterpret_cast(argSlot + getNumParams());
 *noexSlot = epi.ExceptionSpec.NoexceptExpr;
 
 if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() ||
@@ -2907,15 +2906,15 @@
   } else if (getExceptionSpecType() == EST_Uninstantiated) {
 // Store the function decl from which we will resolve our
 // exception specification.
-auto **slot = reinterpret_cast(argSlot + NumParams);
+auto **slot = reinterpret_cast(argSlot + getNumParams());
 slot[0] = epi.ExceptionSpec.SourceDecl;
 slot[1] = epi.ExceptionSpec.SourceTemplate;
 // This exception specification doesn't make the type dependent, because
 // it's not instantiated as part of instantiating the type.
   } else if (getExceptionSpecType() == EST_Unevaluated) {
 // Store the function decl from which we will resolve our
 // exception specification.
-auto **slot = reinterpret_cast(argSlot + NumParams);
+auto **slot = reinterpret_cast(argSlot + getNumParams());
 slot[0] = epi.ExceptionSpec.SourceDecl;
   }
 
@@ -2935,7 +2934,7 @@
   if (epi.ExtParameterInfos) {
 auto *extParamInfos =
   const_cast(getExtParameterInfosBuffer());
-for (unsigned i = 0; i != NumParams; ++i)
+for (unsigned i = 0; i != getNumParams(); ++i)
   extParamInfos[i] = epi.ExtParameterInfos[i];
   }
 }
@@ -2981,7 +2980,7 @@
   case EST_Dynamic:
 // A dynamic exception specification is throwing unless every exception
 // type is an (unexpanded) pack expansion type.
-for (unsigned I = 0, N = NumExceptions; I != N; ++I)
+for (unsigned I = 0; I != getNumExceptions(); ++I)
   if (!getExceptionType(I)->getAs())
 return CT_Can;
 return CT_Dependent;
@@ -3056,7 +3055,8 @@
 
 void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
 const ASTContext &Ctx) {
-  P

[PATCH] D50643: [AST] Pack the bits of TemplateSpecializationType into Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: erichkeane.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Type has enough space for two members of
TemplateSpecializationType. Mechanical patch.


Repository:
  rC Clang

https://reviews.llvm.org/D50643

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp

Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -3335,8 +3335,10 @@
  Canon.isNull()? true : Canon->isDependentType(),
  Canon.isNull()? true : Canon->isInstantiationDependentType(),
  false,
- T.containsUnexpandedParameterPack()),
-Template(T), NumArgs(Args.size()), TypeAlias(!AliasedType.isNull()) {
+ T.containsUnexpandedParameterPack()), Template(T) {
+  TemplateSpecializationTypeBits.NumArgs = Args.size();
+  TemplateSpecializationTypeBits.TypeAlias = !AliasedType.isNull();
+
   assert(!T.getAsDependentTemplateName() &&
  "Use DependentTemplateSpecializationType for dependent template-name");
   assert((T.getKind() == TemplateName::Template ||
@@ -3365,7 +3367,7 @@
   }
 
   // Store the aliased type if this is a type alias template specialization.
-  if (TypeAlias) {
+  if (isTypeAlias()) {
 auto *Begin = reinterpret_cast(this + 1);
 *reinterpret_cast(Begin + getNumArgs()) = AliasedType;
   }
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1624,6 +1624,20 @@
 unsigned Keyword : 2;
   };
 
+  class TemplateSpecializationTypeBitfields {
+friend class TemplateSpecializationType;
+
+unsigned : NumTypeBits;
+
+/// Whether this template specialization type is a substituted type alias.
+unsigned TypeAlias : 1;
+
+/// The number of template arguments named in this class template
+/// specialization. Intentionally not a bitfield since we have
+/// plenty of space left.
+unsigned NumArgs;
+  };
+
   union {
 TypeBitfields TypeBits;
 ArrayTypeBitfields ArrayTypeBits;
@@ -1635,6 +1649,7 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
   "TypeBitfields is larger than 8 bytes!");
@@ -1656,6 +1671,9 @@
   "TypeWithKeywordBitfields is larger than 8 bytes!");
 static_assert(sizeof(VectorTypeBitfields) <= 8,
   "VectorTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
+  "TemplateSpecializationTypeBitfields is larger"
+  " than 8 bytes!");
   };
 
 private:
@@ -4673,13 +4691,6 @@
   /// replacement must, recursively, be one of these).
   TemplateName Template;
 
-  /// The number of template arguments named in this class template
-  /// specialization.
-  unsigned NumArgs : 31;
-
-  /// Whether this template specialization type is a substituted type alias.
-  unsigned TypeAlias : 1;
-
   TemplateSpecializationType(TemplateName T,
  ArrayRef Args,
  QualType Canon,
@@ -4714,7 +4725,7 @@
   ///   typedef A type; // not a type alias
   /// };
   /// \endcode
-  bool isTypeAlias() const { return TypeAlias; }
+  bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; }
 
   /// Get the aliased type, if this is a specialization of a type alias
   /// template.
@@ -4737,14 +4748,16 @@
   }
 
   /// Retrieve the number of template arguments.
-  unsigned getNumArgs() const { return NumArgs; }
+  unsigned getNumArgs() const {
+return TemplateSpecializationTypeBits.NumArgs;
+  }
 
   /// Retrieve a specific template argument as a type.
   /// \pre \c isArgType(Arg)
   const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
 
   ArrayRef template_arguments() const {
-return {getArgs(), NumArgs};
+return {getArgs(), getNumArgs()};
   }
 
   bool isSugared() const {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50643: [AST] Pack the bits of TemplateSpecializationType into Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

All of these bitfields (ab)use are already UB I think...
I don't see what is special in this case...


Repository:
  rC Clang

https://reviews.llvm.org/D50643



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50643: [AST] Pack the bits of TemplateSpecializationType into Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

I don't like these bit-field abuses too much but this is
used all over the place in clang and so if this breaks so
many things are going to break.


Repository:
  rC Clang

https://reviews.llvm.org/D50643



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

@rjmccall

I would argue that we should make these bit-fields take 8 bytes for the 
following reasons:

1. On 64 bits archs, this is free since we have already 8 bytes of padding here.
2. On 32 bits archs, this a priori increase the size of each Type by 4 bytes. 
However, types are aligned to 16 bytes because of the fast CVR qualifiers. 
Doing an fsyntax-only on all of Boost with -print-stats I get that by far the 
most commonly used Types have size 40 or 48 (on a 64 bits arch). That is 5 or 6 
pointers. This would be 20 or 24 bytes on 32 bits archs if we assume that every 
member of the most commonly used types are pointers and that we shrink the 
bitfields to 32 bits. But since Types are aligned to 16 bytes we do not gain 
anything.


Repository:
  rC Clang

https://reviews.llvm.org/D50630



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

Also I don't understand to comment about the bit-fields of FunctionType fitting 
in the padding of Type:

If we have something like

  struct Base {
void *p1;
void *p2;
unsigned x;
  };
  
  struct Der : Base {
unsigned x;
  };

Then on my machine (64 bit linux) I get that

  sizeof(Base) == 24
  sizeof(Der) == 32

and not `sizeof(Der) == sizeof(Base)` like if the unsigned of `Der` was fitting 
into the padding of `Base`.


Repository:
  rC Clang

https://reviews.llvm.org/D50630



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type

2018-08-13 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

In https://reviews.llvm.org/D50630#1197930, @rjmccall wrote:

> In https://reviews.llvm.org/D50630#1197795, @riccibruno wrote:
>
> > @rjmccall
> >
> > I would argue that we should make these bit-fields take 8 bytes for the 
> > following reasons:
> >
> > 1. On 64 bits archs, this is free since we have already a little less than 
> > 8 bytes of padding here, assuming Type keep its 18 bits.
>
>
> First, `Type` is not 16-byte aligned as far as the compiler is concerned; it 
> is merely
>  dynamically aligned to a 16-byte boundary when allocated.  You actually 
> verified this
>  when you did your experiment of printing out the sizes of various `Type` 
> subclasses,
>  because the value of `sizeof` is always rounded up to the alignment, meaning 
> that a
>  size of 40 would not be legal if `Type` were actually 16-byte-aligned.
>
> Because `Type` is only 4/8-byte aligned, its only tail padding is what's 
> needed to
>  fill up a pointer after these bit-fields, which is supposed to be 4 bytes 
> but is
>  instead apparently 0 bytes because we overflowed one of the bit-fields.
>
> Not officially aligning `Type` to 16 bytes is fairly important for memory 
> efficiency
>  even on 64-bit hosts because many of our types use tail-allocated storage, 
> which
>  naturally starts at `sizeof(T)` bytes from the address point; if we formally 
> aligned
>  `Type` subclasses to 16 bytes, we'd often waste a pointer of that storage.


Right,

> Second, tail padding of base classes is not necessarily wasted under the 
> Itanium C++ ABI.
>  Itanium will start placing sub-objects in the tail-padding of the last 
> non-empty base class
>  as long as that base is POD under the rules of C++03; `Type` is not POD 
> because it has a
>  user-provided constructor.

I just realized that something like this was happening when playing with 
various classes on godbolt.
I should go read the Itanium spec ! However as you say the condition for this 
happening are
not necessarily satisfied and moreover other ABIs might not do this packing 
(but you almost
certainly are more familiar with this than me)

> Looking at `Type.h`, we don't seem to be taking advantage of this as much as 
> I thought,
>  at least in the `Type` hierarchy (maybe we do in the `Stmt` or `Decl` 
> hierarchies).  We
>  have a lot of subclasses that have 32 bits of miscellaneous storage but 
> either (1) don't
>  order their fields correctly to allow subclasses to fit in or (2) also 
> subclass `FoldingSetNode`,
>  which breaks up the optimization.
> 
> Since we do care primarily about 64-bit hosts, I'm leaning towards agreeing 
> that we should
>  just accept that we have 64 bits of storage here, 46 of which are available 
> to subclasses.
>  If you're interested in optimizing this, it would be nice if you could go 
> through all the
>  subclasses looking for 32-bit chunks that could be profitably moved up into 
> `Type`.
> 
>> 2. On 32 bits archs, this a priori increase the size of each Type by 4 
>> bytes. However, types are aligned to 16 bytes because of the fast CVR 
>> qualifiers. Doing an fsyntax-only on all of Boost with -print-stats I get 
>> that by far the most commonly used Types have size 40 or 48 (on a 64 bits 
>> arch). That is 5 or 6 pointers. This would be 20 or 24 bytes on 32 bits 
>> archs if we assume that every member of the most commonly used types are 
>> pointers and that we shrink the bitfields to 32 bits. But since Types are 
>> aligned to 16 bytes we do not gain anything.
> 
> Types aren't the only thing allocated in the ASTContext, so allocating a 
> 16-byte-aligned
>  chunk with a non-multiple-of-16 size doesn't mean that any difference 
> between the size
>  and the next 16-byte boundary is necessarily wasted.  But you're probably 
> right that the
>  difference between `Type` being 12 and 16 bytes is probably not a big deal.
> 
> John.

I actually did exactly this. My approach was to extend what is already done,
that is add nested classes SomethingBitfields in Type and add an instance of
each to the anonymous union. The classes which I have found so far benefiting
from this are FunctionProtoType, TemplateSpecializationType, PackExpansionType,
DependentTemplateSpecializationType and SubstTemplateTypeParmPackType.

For example the patch dealing with TemplateSpecializationType is
here https://reviews.llvm.org/D50643.


Repository:
  rC Clang

https://reviews.llvm.org/D50630



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50630: [AST] Update/correct the static_asserts for the bit-fields in Type

2018-08-14 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

I actually have patches for TemplateSpecializationType, PackExpansionType,
DependentTemplateSpecializationType and SubstTemplateTypeParmPackType which move
the unsigned to the bit-fields in Type. The same could be done for the others I 
suppose.
This assume that the bit-fields of Type have 64 bits available though.

An other one is in ElaboratedType: the member "TagDecl *OwnedTagDecl" is very
commonly null (IIRC only non-null for about 600 of the 66k ElaboratedTypes when
parsing all of Boost). Therefore we can simply put it in a trailing object
and stash a bit in the bit-fields of Type indicating when this pointer is null.

Bruno


Repository:
  rC Clang

https://reviews.llvm.org/D50630



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50711: [AST] Pack the unsigned of PackExpansionType into Type

2018-08-14 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: rsmith, rjmccall, erichkeane.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

The bit-fields of Type have enough space for
the `unsigned NumExpansions` of PackExpansionType


Repository:
  rC Clang

https://reviews.llvm.org/D50711

Files:
  include/clang/AST/Type.h


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1638,6 +1638,21 @@
 unsigned NumArgs;
   };
 
+  class PackExpansionTypeBitfields {
+friend class PackExpansionType;
+
+unsigned : NumTypeBits;
+
+/// The number of expansions that this pack expansion will
+/// generate when substituted (+1).
+///
+/// This field will only have a non-zero value when some of the parameter
+/// packs that occur within the pattern have been substituted but others
+/// have not. Intentionally not a bitfield since we have plenty
+/// of space left.
+unsigned NumExpansions;
+  };
+
   union {
 TypeBitfields TypeBits;
 ArrayTypeBitfields ArrayTypeBits;
@@ -1650,6 +1665,7 @@
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+PackExpansionTypeBitfields PackExpansionTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
   "TypeBitfields is larger than 8 bytes!");
@@ -1674,6 +1690,8 @@
 static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
   "TemplateSpecializationTypeBitfields is larger"
   " than 8 bytes!");
+static_assert(sizeof(PackExpansionTypeBitfields) <= 8,
+  "PackExpansionTypeBitfields is larger than 8 bytes");
   };
 
 private:
@@ -5189,22 +5207,16 @@
   /// The pattern of the pack expansion.
   QualType Pattern;
 
-  /// The number of expansions that this pack expansion will
-  /// generate when substituted (+1), or indicates that
-  ///
-  /// This field will only have a non-zero value when some of the parameter
-  /// packs that occur within the pattern have been substituted but others have
-  /// not.
-  unsigned NumExpansions;
-
   PackExpansionType(QualType Pattern, QualType Canon,
 Optional NumExpansions)
   : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
  /*InstantiationDependent=*/true,
  /*VariablyModified=*/Pattern->isVariablyModifiedType(),
  /*ContainsUnexpandedParameterPack=*/false),
-Pattern(Pattern),
-NumExpansions(NumExpansions ? *NumExpansions + 1 : 0) {}
+Pattern(Pattern) {
+PackExpansionTypeBits.NumExpansions =
+NumExpansions ? *NumExpansions + 1 : 0;
+  }
 
 public:
   /// Retrieve the pattern of this pack expansion, which is the
@@ -5215,9 +5227,8 @@
   /// Retrieve the number of expansions that this pack expansion will
   /// generate, if known.
   Optional getNumExpansions() const {
-if (NumExpansions)
-  return NumExpansions - 1;
-
+if (PackExpansionTypeBits.NumExpansions)
+  return PackExpansionTypeBits.NumExpansions - 1;
 return None;
   }
 


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1638,6 +1638,21 @@
 unsigned NumArgs;
   };
 
+  class PackExpansionTypeBitfields {
+friend class PackExpansionType;
+
+unsigned : NumTypeBits;
+
+/// The number of expansions that this pack expansion will
+/// generate when substituted (+1).
+///
+/// This field will only have a non-zero value when some of the parameter
+/// packs that occur within the pattern have been substituted but others
+/// have not. Intentionally not a bitfield since we have plenty
+/// of space left.
+unsigned NumExpansions;
+  };
+
   union {
 TypeBitfields TypeBits;
 ArrayTypeBitfields ArrayTypeBits;
@@ -1650,6 +1665,7 @@
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+PackExpansionTypeBitfields PackExpansionTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
   "TypeBitfields is larger than 8 bytes!");
@@ -1674,6 +1690,8 @@
 static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
   "TemplateSpecializationTypeBitfields is larger"
   " than 8 bytes!");
+static_assert(sizeof(PackExpansionTypeBitfields) <= 8,
+  "PackExpansionTypeBitfields is larger than 8 bytes");
   };
 
 private:
@@ -5189,22 +5207,16 @@
   /// The pattern of the pack expansion.
   QualType Pattern;
 
-  /// The number of expansions that this pack expansion will
-  /// generate when substituted (+1), or indicates that
-  ///
-  /// This field wil

[PATCH] D50712: [AST] Pack the unsigned of DependentTemplateSpecializationType into Type

2018-08-14 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: rsmith, rjmccall, erichkeane.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

The bit-fields of `Type` have enough space for the member
`unsigned NumArgs` of DependentTemplateSpecializationType


Repository:
  rC Clang

https://reviews.llvm.org/D50712

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp

Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2604,7 +2604,8 @@
   : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true,
 /*VariablyModified=*/false,
 NNS && NNS->containsUnexpandedParameterPack()),
-NNS(NNS), Name(Name), NumArgs(Args.size()) {
+NNS(NNS), Name(Name) {
+  DependentTemplateSpecializationTypeBits.NumArgs = Args.size();
   assert((!NNS || NNS->isDependent()) &&
  "DependentTemplateSpecializatonType requires dependent qualifier");
   TemplateArgument *ArgBuffer = getArgBuffer();
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1589,6 +1589,8 @@
 unsigned Keyword : 8;
   };
 
+  enum { NumTypeWithKeywordBits = 8 };
+
   class VectorTypeBitfields {
 friend class VectorType;
 friend class DependentVectorType;
@@ -1638,6 +1640,18 @@
 unsigned NumArgs;
   };
 
+  class DependentTemplateSpecializationTypeBitfields {
+friend class DependentTemplateSpecializationType;
+
+unsigned : NumTypeBits;
+unsigned : NumTypeWithKeywordBits;
+
+/// The number of template arguments named in this class template
+/// specialization. Intentionally not a bitfield since we have plenty
+/// of space left.
+unsigned NumArgs;
+  };
+
   class PackExpansionTypeBitfields {
 friend class PackExpansionType;
 
@@ -1665,6 +1679,8 @@
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+DependentTemplateSpecializationTypeBitfields
+  DependentTemplateSpecializationTypeBits;
 PackExpansionTypeBitfields PackExpansionTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
@@ -1690,6 +1706,9 @@
 static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
   "TemplateSpecializationTypeBitfields is larger"
   " than 8 bytes!");
+static_assert(sizeof(DependentTemplateSpecializationTypeBitfields) <= 8,
+  "DependentTemplateSpecializationTypeBitfields is larger"
+  " than 8 bytes!");
 static_assert(sizeof(PackExpansionTypeBitfields) <= 8,
   "PackExpansionTypeBitfields is larger than 8 bytes");
   };
@@ -5119,10 +5138,6 @@
   /// The identifier of the template.
   const IdentifierInfo *Name;
 
-  /// The number of template arguments named in this class template
-  /// specialization.
-  unsigned NumArgs;
-
   DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
   NestedNameSpecifier *NNS,
   const IdentifierInfo *Name,
@@ -5147,12 +5162,14 @@
   }
 
   /// Retrieve the number of template arguments.
-  unsigned getNumArgs() const { return NumArgs; }
+  unsigned getNumArgs() const {
+return DependentTemplateSpecializationTypeBits.NumArgs;
+  }
 
   const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
 
   ArrayRef template_arguments() const {
-return {getArgs(), NumArgs};
+return {getArgs(), getNumArgs()};
   }
 
   using iterator = const TemplateArgument *;
@@ -5164,7 +5181,7 @@
   QualType desugar() const { return QualType(this, 0); }
 
   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
-Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), NumArgs});
+Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()});
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50713: [AST] Pack the unsigned of SubstTemplateTypeParmPackType into Type

2018-08-14 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: rsmith, rjmccall, erichkeane.
riccibruno added a project: clang.
Herald added a reviewer: javed.absar.
Herald added subscribers: cfe-commits, chrib, kristof.beyls.

The bit-fields of `Type` have enough space for the member
`unsigned NumArgs` of SubstTemplateTypeParmPackType.


Repository:
  rC Clang

https://reviews.llvm.org/D50713

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp


Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -3285,11 +3285,12 @@
   QualType Canon,
   const TemplateArgument &ArgPack)
 : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true),
-  Replaced(Param),
-  Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {}
+  Replaced(Param), Arguments(ArgPack.pack_begin()) {
+  SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size();
+}
 
 TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
-  return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
+  return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs()));
 }
 
 void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1626,6 +1626,16 @@
 unsigned Keyword : 2;
   };
 
+  class SubstTemplateTypeParmPackTypeBitfields {
+friend class SubstTemplateTypeParmPackType;
+
+unsigned : NumTypeBits;
+
+/// The number of template arguments in \c Arguments.
+/// Intentionally not a bitfield since we have plenty of space left.
+unsigned NumArgs;
+  };
+
   class TemplateSpecializationTypeBitfields {
 friend class TemplateSpecializationType;
 
@@ -1678,6 +1688,7 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
 DependentTemplateSpecializationTypeBitfields
   DependentTemplateSpecializationTypeBits;
@@ -1703,6 +1714,9 @@
   "TypeWithKeywordBitfields is larger than 8 bytes!");
 static_assert(sizeof(VectorTypeBitfields) <= 8,
   "VectorTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8,
+  "SubstTemplateTypeParmPackTypeBitfields is larger"
+  " than 8 bytes!");
 static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
   "TemplateSpecializationTypeBitfields is larger"
   " than 8 bytes!");
@@ -4543,9 +4557,6 @@
   /// parameter pack is instantiated with.
   const TemplateArgument *Arguments;
 
-  /// The number of template arguments in \c Arguments.
-  unsigned NumArguments;
-
   SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
 QualType Canon,
 const TemplateArgument &ArgPack);
@@ -4558,6 +4569,10 @@
 return Replaced;
   }
 
+  unsigned getNumArgs() const {
+return SubstTemplateTypeParmPackTypeBits.NumArgs;
+  }
+
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 


Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -3285,11 +3285,12 @@
   QualType Canon,
   const TemplateArgument &ArgPack)
 : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true),
-  Replaced(Param),
-  Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {}
+  Replaced(Param), Arguments(ArgPack.pack_begin()) {
+  SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size();
+}
 
 TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
-  return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
+  return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs()));
 }
 
 void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1626,6 +1626,16 @@
 unsigned Keyword : 2;
   };
 
+  class SubstTemplateTypeParmPackTypeBitfields {
+friend class SubstTemplateTypeParmPackType;
+
+unsigned : NumTypeBits;
+
+/// The number of template arguments in \c Arguments.
+/// Intentionally not a bitfield since we have plenty of space left.
+unsigned NumArgs;
+  };
+
   class TemplateSpecializationTypeBitfields {
 friend class Template

[PATCH] D50715: [AST] Store the OwnedTagDecl as a trailing object in ElaboratedType.

2018-08-14 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: rsmith, rjmccall, erichkeane.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

The `TagDecl *OwnedTagDecl` in `ElaboratedType` is quite commonly
null (at least when parsing all of Boost, it is non-null for only about 600
of the 66k `ElaboratedType`). Therefore we can save a pointer in the
common case by storing it as a trailing object, and storing a bit in the
bit-fields of Type indicating when pointer is null.


Repository:
  rC Clang

https://reviews.llvm.org/D50715

Files:
  include/clang/AST/Type.h
  lib/AST/ASTContext.cpp

Index: lib/AST/ASTContext.cpp
===
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -4133,8 +4133,10 @@
 (void)CheckT;
   }
 
-  T = new (*this, TypeAlignment)
-  ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
+  void *Mem = Allocate(ElaboratedType::totalSizeToAlloc(!!OwnedTagDecl),
+   TypeAlignment);
+  T = new (Mem) ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
+
   Types.push_back(T);
   ElaboratedTypes.InsertNode(T, InsertPos);
   return QualType(T, 0);
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -45,6 +45,7 @@
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
 #include "llvm/Support/type_traits.h"
+#include "llvm/Support/TrailingObjects.h"
 #include 
 #include 
 #include 
@@ -1591,6 +1592,16 @@
 
   enum { NumTypeWithKeywordBits = 8 };
 
+  class ElaboratedTypeBitfields {
+friend class ElaboratedType;
+
+unsigned : NumTypeBits;
+unsigned : NumTypeWithKeywordBits;
+
+/// Whether the ElaboratedType has a trailing OwnedTagDecl.
+unsigned HasOwnedTagDecl : 1;
+  };
+
   class VectorTypeBitfields {
 friend class VectorType;
 friend class DependentVectorType;
@@ -1687,6 +1698,7 @@
 ObjCObjectTypeBitfields ObjCObjectTypeBits;
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
+ElaboratedTypeBitfields ElaboratedTypeBits;
 VectorTypeBitfields VectorTypeBits;
 SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
@@ -1712,6 +1724,8 @@
   "ReferenceTypeBitfields is larger than 8 bytes!");
 static_assert(sizeof(TypeWithKeywordBitfields) <= 8,
   "TypeWithKeywordBitfields is larger than 8 bytes!");
+static_assert(sizeof(ElaboratedTypeBitfields) <= 8,
+  "ElaboratedTypeBitfields is larger than 8 bytes!");
 static_assert(sizeof(VectorTypeBitfields) <= 8,
   "VectorTypeBitfields is larger than 8 bytes!");
 static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8,
@@ -5015,35 +5029,42 @@
 /// source code, including tag keywords and any nested-name-specifiers.
 /// The type itself is always "sugar", used to express what was written
 /// in the source code but containing no additional semantic information.
-class ElaboratedType : public TypeWithKeyword, public llvm::FoldingSetNode {
+class ElaboratedType final
+: public TypeWithKeyword,
+  public llvm::FoldingSetNode,
+  private llvm::TrailingObjects {
   friend class ASTContext; // ASTContext creates these
+  friend TrailingObjects;
 
   /// The nested name specifier containing the qualifier.
   NestedNameSpecifier *NNS;
 
   /// The type that this qualified name refers to.
   QualType NamedType;
 
-  /// The (re)declaration of this tag type owned by this occurrence, or nullptr
-  /// if none.
-  TagDecl *OwnedTagDecl;
+  /// The (re)declaration of this tag type owned by this occurrence is stored
+  /// as a trailing object if there is one. Use getOwnedTagDecl to obtain
+  /// it, or obtain a null pointer if there is none.
 
   ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
  QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
-: TypeWithKeyword(Keyword, Elaborated, CanonType,
-  NamedType->isDependentType(),
-  NamedType->isInstantiationDependentType(),
-  NamedType->isVariablyModifiedType(),
-  NamedType->containsUnexpandedParameterPack()),
-  NNS(NNS), NamedType(NamedType), OwnedTagDecl(OwnedTagDecl) {
+  : TypeWithKeyword(Keyword, Elaborated, CanonType,
+NamedType->isDependentType(),
+NamedType->isInstantiationDependentType(),
+NamedType->isVariablyModifiedType(),
+NamedType->containsUnexpandedParameterPack()),
+NNS(NNS), NamedType(NamedType) {
+ElaboratedTypeBits.HasOwnedTagDecl = false;
+if (OwnedTagDecl) {
+  ElaboratedTypeBits.HasOwn

[PATCH] D50713: [AST] Pack the unsigned of SubstTemplateTypeParmPackType into Type

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: include/clang/AST/Type.h:1634
+
+/// The number of template arguments in \c Arguments.
+/// Intentionally not a bitfield since we have plenty of space left.

erichkeane wrote:
> I would love it if we commented what a reasonable number for this is.  
> Additionally, we should probably make it 64 - NumTypeBits or something, to 
> ensure that if NumTypeBits gets too large that we don't blow 64 bits here as 
> well as communicate that it isn't necessary to keep this 32 bits.
The reason I did not do something like this is that
there is a penalty to access bit-fields due to the various
shifts and masks. IIRC I was actually able to measure it after
I went over each of these classes and only kept bit-fields
when strictly necessary. (however it is hard to be sure
since it was close to the noise of my measurement, and the
difference could be from totally unrelated sources).
In any case it is quite small (maybe ~0.1% in total, not just
from this single case) and IMHO not worth systematically
bothering about it but in this case why pay the penalty if
we can avoid it.

If `NumTypeBits` gets too large then this will be detected by the
the static_asserts and the person who did the modification will
have to convert `NumArgs` to a bit-field. In any case this will at least
also blow up `FunctionTypeBitfields`, `VectorTypeBitfields`,
`AttributedTypeBitfields`, `SubstTemplateTypeParmPackTypeBitfields`,
`TemplateSpecializationTypeBitfields`,
`DependentTemplateSpecializationTypeBitfields`,
and `PackExpansionTypeBitfields`.

Also I do not think that doing
`unsigned NumArgs : 64 - NumTypeBits;` will work because
since `NumTypeBits == 18` this will be
`unsigned NumArgs : 46;` and this will not pack nicely.

Given how many things will not work when `NumTypeBits > 32`
It seems to be that it is not worth converting it to a bit-field.
However a comment indicating how many bits are actually needed
would definitely be a good addition IMO. On this point I have
absolutely no idea and probably @rsmith should comment on this.


Repository:
  rC Clang

https://reviews.llvm.org/D50713



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50631: [AST] Stuff more data into FunctionTypeBitfields

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

@rsmith Could you comment on whether limiting the number of types
in a dynamic exception specification to 127 is acceptable ? I had
to steal two bits from `NumExceptions` to make all the fields fit.
If this is a bad idea then a possibility would be to put
`NumExceptions` in a trailing object.


Repository:
  rC Clang

https://reviews.llvm.org/D50631



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50713: [AST] Pack the unsigned of SubstTemplateTypeParmPackType into Type

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

The thing is that I have no idea what is the minimum number
of bits required. It was originally an unsigned but I suspect that
32 bits are not needed. Looking at [implimits] I see

  Template arguments in a template declaration [1 024].
  Recursively nested template instantiations, including substitution during 
template argument deduc-
  tion (17.8.2) [1 024].

But 1024 seems to be too small and easily exceeded by a doing a bit
of template meta-programming.


Repository:
  rC Clang

https://reviews.llvm.org/D50713



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50713: [AST] Pack the unsigned of SubstTemplateTypeParmPackType into Type

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

This comment seems fine. I will also add a similar comment to
`TemplateSpecializationTypeBitfields`, 
`DependentTemplateSpecializationTypeBitfields`
and `PackExpansionTypeBitfields` since they all 3 have a similar `unsigned`.


Repository:
  rC Clang

https://reviews.llvm.org/D50713



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50713: [AST] Pack the unsigned of SubstTemplateTypeParmPackType into Type

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 160795.
riccibruno added a comment.

updated the comment in SubstTemplateTypeParmPackTypeBitfields


Repository:
  rC Clang

https://reviews.llvm.org/D50713

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp


Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -3285,11 +3285,12 @@
   QualType Canon,
   const TemplateArgument &ArgPack)
 : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true),
-  Replaced(Param),
-  Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {}
+  Replaced(Param), Arguments(ArgPack.pack_begin()) {
+  SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size();
+}
 
 TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
-  return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
+  return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs()));
 }
 
 void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1626,6 +1626,21 @@
 unsigned Keyword : 2;
   };
 
+  class SubstTemplateTypeParmPackTypeBitfields {
+friend class SubstTemplateTypeParmPackType;
+
+unsigned : NumTypeBits;
+
+/// The number of template arguments in \c Arguments, which is
+/// expected to be able to hold at least 1024 according to [implimits].
+/// However as this limit is somewhat easy to hit with template
+/// metaprogramming we'd prefer to keep it as large as possible.
+/// At the moment it has been left as a non-bitfield since this type
+/// safely fits in 64 bits as an unsigned, so there is no reason to
+/// introduce the performance impact of a bitfield.
+unsigned NumArgs;
+  };
+
   class TemplateSpecializationTypeBitfields {
 friend class TemplateSpecializationType;
 
@@ -1690,6 +1705,7 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
 DependentTemplateSpecializationTypeBitfields
   DependentTemplateSpecializationTypeBits;
@@ -1715,6 +1731,9 @@
   "TypeWithKeywordBitfields is larger than 8 bytes!");
 static_assert(sizeof(VectorTypeBitfields) <= 8,
   "VectorTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8,
+  "SubstTemplateTypeParmPackTypeBitfields is larger"
+  " than 8 bytes!");
 static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
   "TemplateSpecializationTypeBitfields is larger"
   " than 8 bytes!");
@@ -4555,9 +4574,6 @@
   /// parameter pack is instantiated with.
   const TemplateArgument *Arguments;
 
-  /// The number of template arguments in \c Arguments.
-  unsigned NumArguments;
-
   SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param,
 QualType Canon,
 const TemplateArgument &ArgPack);
@@ -4570,6 +4586,10 @@
 return Replaced;
   }
 
+  unsigned getNumArgs() const {
+return SubstTemplateTypeParmPackTypeBits.NumArgs;
+  }
+
   bool isSugared() const { return false; }
   QualType desugar() const { return QualType(this, 0); }
 


Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -3285,11 +3285,12 @@
   QualType Canon,
   const TemplateArgument &ArgPack)
 : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true),
-  Replaced(Param),
-  Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {}
+  Replaced(Param), Arguments(ArgPack.pack_begin()) {
+  SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size();
+}
 
 TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const {
-  return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments));
+  return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs()));
 }
 
 void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1626,6 +1626,21 @@
 unsigned Keyword : 2;
   };
 
+  class SubstTemplateTypeParmPackTypeBitfields {
+friend class SubstTemplateTypeParmPackType;
+
+unsigned : NumTypeBits;
+
+/// The number of template arguments in \c Arguments, which is
+/// exp

[PATCH] D50712: [AST] Pack the unsigned of DependentTemplateSpecializationType into Type

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 160800.
riccibruno added a comment.

updated the comment in DependentTemplateSpecializationTypeBitfields


Repository:
  rC Clang

https://reviews.llvm.org/D50712

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp

Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2604,7 +2604,8 @@
   : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true,
 /*VariablyModified=*/false,
 NNS && NNS->containsUnexpandedParameterPack()),
-NNS(NNS), Name(Name), NumArgs(Args.size()) {
+NNS(NNS), Name(Name) {
+  DependentTemplateSpecializationTypeBits.NumArgs = Args.size();
   assert((!NNS || NNS->isDependent()) &&
  "DependentTemplateSpecializatonType requires dependent qualifier");
   TemplateArgument *ArgBuffer = getArgBuffer();
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1589,6 +1589,8 @@
 unsigned Keyword : 8;
   };
 
+  enum { NumTypeWithKeywordBits = 8 };
+
   class VectorTypeBitfields {
 friend class VectorType;
 friend class DependentVectorType;
@@ -1642,6 +1644,22 @@
 unsigned NumArgs;
   };
 
+  class DependentTemplateSpecializationTypeBitfields {
+friend class DependentTemplateSpecializationType;
+
+unsigned : NumTypeBits;
+unsigned : NumTypeWithKeywordBits;
+
+/// The number of template arguments named in this class template
+/// specialization, which is expected to be able to hold at least 1024
+/// according to [implimits]. However, as this limit is somewhat easy to
+/// hit with template metaprogramming we'd prefer to keep it as large
+/// as possible. At the moment it has been left as a non-bitfield since
+/// this type safely fits in 64 bits as an unsigned, so there is no reason
+/// to introduce the performance impact of a bitfield.
+unsigned NumArgs;
+  };
+
   class PackExpansionTypeBitfields {
 friend class PackExpansionType;
 
@@ -1673,6 +1691,8 @@
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+DependentTemplateSpecializationTypeBitfields
+  DependentTemplateSpecializationTypeBits;
 PackExpansionTypeBitfields PackExpansionTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
@@ -1698,6 +1718,9 @@
 static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
   "TemplateSpecializationTypeBitfields is larger"
   " than 8 bytes!");
+static_assert(sizeof(DependentTemplateSpecializationTypeBitfields) <= 8,
+  "DependentTemplateSpecializationTypeBitfields is larger"
+  " than 8 bytes!");
 static_assert(sizeof(PackExpansionTypeBitfields) <= 8,
   "PackExpansionTypeBitfields is larger than 8 bytes");
   };
@@ -5127,10 +5150,6 @@
   /// The identifier of the template.
   const IdentifierInfo *Name;
 
-  /// The number of template arguments named in this class template
-  /// specialization.
-  unsigned NumArgs;
-
   DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
   NestedNameSpecifier *NNS,
   const IdentifierInfo *Name,
@@ -5155,12 +5174,14 @@
   }
 
   /// Retrieve the number of template arguments.
-  unsigned getNumArgs() const { return NumArgs; }
+  unsigned getNumArgs() const {
+return DependentTemplateSpecializationTypeBits.NumArgs;
+  }
 
   const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
 
   ArrayRef template_arguments() const {
-return {getArgs(), NumArgs};
+return {getArgs(), getNumArgs()};
   }
 
   using iterator = const TemplateArgument *;
@@ -5172,7 +5193,7 @@
   QualType desugar() const { return QualType(this, 0); }
 
   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
-Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), NumArgs});
+Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()});
   }
 
   static void Profile(llvm::FoldingSetNodeID &ID,
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50711: [AST] Pack the unsigned of PackExpansionType into Type

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 160804.
riccibruno added a comment.

update the comment in PackExpansionTypeBitfields


Repository:
  rC Clang

https://reviews.llvm.org/D50711

Files:
  include/clang/AST/Type.h


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1642,6 +1642,25 @@
 unsigned NumArgs;
   };
 
+  class PackExpansionTypeBitfields {
+friend class PackExpansionType;
+
+unsigned : NumTypeBits;
+
+/// The number of expansions that this pack expansion will
+/// generate when substituted (+1), which is expected to be able to
+/// hold at least 1024 according to [implimits]. However, as this limit
+/// is somewhat easy to hit with template metaprogramming we'd prefer to
+/// keep it as large as possible. At the moment it has been left as a
+/// non-bitfield since this type safely fits in 64 bits as an unsigned, so
+/// there is no reason to introduce the performance impact of a bitfield.
+///
+/// This field will only have a non-zero value when some of the parameter
+/// packs that occur within the pattern have been substituted but others
+/// have not.
+unsigned NumExpansions;
+  };
+
   union {
 TypeBitfields TypeBits;
 ArrayTypeBitfields ArrayTypeBits;
@@ -1654,6 +1673,7 @@
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+PackExpansionTypeBitfields PackExpansionTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
   "TypeBitfields is larger than 8 bytes!");
@@ -1678,6 +1698,8 @@
 static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
   "TemplateSpecializationTypeBitfields is larger"
   " than 8 bytes!");
+static_assert(sizeof(PackExpansionTypeBitfields) <= 8,
+  "PackExpansionTypeBitfields is larger than 8 bytes");
   };
 
 private:
@@ -5193,22 +5215,16 @@
   /// The pattern of the pack expansion.
   QualType Pattern;
 
-  /// The number of expansions that this pack expansion will
-  /// generate when substituted (+1), or indicates that
-  ///
-  /// This field will only have a non-zero value when some of the parameter
-  /// packs that occur within the pattern have been substituted but others have
-  /// not.
-  unsigned NumExpansions;
-
   PackExpansionType(QualType Pattern, QualType Canon,
 Optional NumExpansions)
   : Type(PackExpansion, Canon, /*Dependent=*/Pattern->isDependentType(),
  /*InstantiationDependent=*/true,
  /*VariablyModified=*/Pattern->isVariablyModifiedType(),
  /*ContainsUnexpandedParameterPack=*/false),
-Pattern(Pattern),
-NumExpansions(NumExpansions ? *NumExpansions + 1 : 0) {}
+Pattern(Pattern) {
+PackExpansionTypeBits.NumExpansions =
+NumExpansions ? *NumExpansions + 1 : 0;
+  }
 
 public:
   /// Retrieve the pattern of this pack expansion, which is the
@@ -5219,9 +5235,8 @@
   /// Retrieve the number of expansions that this pack expansion will
   /// generate, if known.
   Optional getNumExpansions() const {
-if (NumExpansions)
-  return NumExpansions - 1;
-
+if (PackExpansionTypeBits.NumExpansions)
+  return PackExpansionTypeBits.NumExpansions - 1;
 return None;
   }
 


Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1642,6 +1642,25 @@
 unsigned NumArgs;
   };
 
+  class PackExpansionTypeBitfields {
+friend class PackExpansionType;
+
+unsigned : NumTypeBits;
+
+/// The number of expansions that this pack expansion will
+/// generate when substituted (+1), which is expected to be able to
+/// hold at least 1024 according to [implimits]. However, as this limit
+/// is somewhat easy to hit with template metaprogramming we'd prefer to
+/// keep it as large as possible. At the moment it has been left as a
+/// non-bitfield since this type safely fits in 64 bits as an unsigned, so
+/// there is no reason to introduce the performance impact of a bitfield.
+///
+/// This field will only have a non-zero value when some of the parameter
+/// packs that occur within the pattern have been substituted but others
+/// have not.
+unsigned NumExpansions;
+  };
+
   union {
 TypeBitfields TypeBits;
 ArrayTypeBitfields ArrayTypeBits;
@@ -1654,6 +1673,7 @@
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
 TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+PackExpansionTypeBitfields PackExpansionTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
   "TypeBitfields is larger than 8 bytes!");
@@ -1678,6 +1698,8 @@
   

[PATCH] D50643: [AST] Pack the bits of TemplateSpecializationType into Type

2018-08-15 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 160805.
riccibruno added a comment.

update the comment in TemplateSpecializationTypeBitfields


Repository:
  rC Clang

https://reviews.llvm.org/D50643

Files:
  include/clang/AST/Type.h
  lib/AST/Type.cpp

Index: lib/AST/Type.cpp
===
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -3335,8 +3335,10 @@
  Canon.isNull()? true : Canon->isDependentType(),
  Canon.isNull()? true : Canon->isInstantiationDependentType(),
  false,
- T.containsUnexpandedParameterPack()),
-Template(T), NumArgs(Args.size()), TypeAlias(!AliasedType.isNull()) {
+ T.containsUnexpandedParameterPack()), Template(T) {
+  TemplateSpecializationTypeBits.NumArgs = Args.size();
+  TemplateSpecializationTypeBits.TypeAlias = !AliasedType.isNull();
+
   assert(!T.getAsDependentTemplateName() &&
  "Use DependentTemplateSpecializationType for dependent template-name");
   assert((T.getKind() == TemplateName::Template ||
@@ -3365,7 +3367,7 @@
   }
 
   // Store the aliased type if this is a type alias template specialization.
-  if (TypeAlias) {
+  if (isTypeAlias()) {
 auto *Begin = reinterpret_cast(this + 1);
 *reinterpret_cast(Begin + getNumArgs()) = AliasedType;
   }
Index: include/clang/AST/Type.h
===
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1624,6 +1624,24 @@
 unsigned Keyword : 2;
   };
 
+  class TemplateSpecializationTypeBitfields {
+friend class TemplateSpecializationType;
+
+unsigned : NumTypeBits;
+
+/// Whether this template specialization type is a substituted type alias.
+unsigned TypeAlias : 1;
+
+/// The number of template arguments named in this class template
+/// specialization, which is expected to be able to hold at least 1024
+/// according to [implimits]. However, as this limit is somewhat easy to
+/// hit with template metaprogramming we'd prefer to keep it as large
+/// as possible. At the moment it has been left as a non-bitfield since
+/// this type safely fits in 64 bits as an unsigned, so there is no reason
+/// to introduce the performance impact of a bitfield.
+unsigned NumArgs;
+  };
+
   union {
 TypeBitfields TypeBits;
 ArrayTypeBitfields ArrayTypeBits;
@@ -1635,6 +1653,7 @@
 ReferenceTypeBitfields ReferenceTypeBits;
 TypeWithKeywordBitfields TypeWithKeywordBits;
 VectorTypeBitfields VectorTypeBits;
+TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
 
 static_assert(sizeof(TypeBitfields) <= 8,
   "TypeBitfields is larger than 8 bytes!");
@@ -1656,6 +1675,9 @@
   "TypeWithKeywordBitfields is larger than 8 bytes!");
 static_assert(sizeof(VectorTypeBitfields) <= 8,
   "VectorTypeBitfields is larger than 8 bytes!");
+static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
+  "TemplateSpecializationTypeBitfields is larger"
+  " than 8 bytes!");
   };
 
 private:
@@ -4673,13 +4695,6 @@
   /// replacement must, recursively, be one of these).
   TemplateName Template;
 
-  /// The number of template arguments named in this class template
-  /// specialization.
-  unsigned NumArgs : 31;
-
-  /// Whether this template specialization type is a substituted type alias.
-  unsigned TypeAlias : 1;
-
   TemplateSpecializationType(TemplateName T,
  ArrayRef Args,
  QualType Canon,
@@ -4714,7 +4729,7 @@
   ///   typedef A type; // not a type alias
   /// };
   /// \endcode
-  bool isTypeAlias() const { return TypeAlias; }
+  bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; }
 
   /// Get the aliased type, if this is a specialization of a type alias
   /// template.
@@ -4737,14 +4752,16 @@
   }
 
   /// Retrieve the number of template arguments.
-  unsigned getNumArgs() const { return NumArgs; }
+  unsigned getNumArgs() const {
+return TemplateSpecializationTypeBits.NumArgs;
+  }
 
   /// Retrieve a specific template argument as a type.
   /// \pre \c isArgType(Arg)
   const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
 
   ArrayRef template_arguments() const {
-return {getArgs(), NumArgs};
+return {getArgs(), getNumArgs()};
   }
 
   bool isSugared() const {
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50631: [AST] Stuff more data into FunctionTypeBitfields

2018-08-16 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno planned changes to this revision.
riccibruno added a comment.

I Will put `NumExceptions` in a trailing object. However it seems
that `FunctionProtoType` can be substantially cleaned up by converting
it to use `llvm::TrailingObjects` instead of manually doing the 
casts+arithmetic.

Therefore I plan to first convert `FunctionProtoType` to use 
`llvm::TrailingObjects`
and then resubmit this patch with the appropriate modifications.


Repository:
  rC Clang

https://reviews.llvm.org/D50631



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49302: [AST] Various micro-optimizations in CXXInheritance

2018-07-20 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

@bkramer Thanks for the review! Can you commit it for my since I can not do it 
myself?


Repository:
  rC Clang

https://reviews.llvm.org/D49302



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49728: diff space

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
Herald added a subscriber: cfe-commits.

Repository:
  rC Clang

https://reviews.llvm.org/D49728

Files:
  stat


Index: stat
===
--- stat
+++ stat
@@ -66,54 +66,54 @@
 665/34195 implicit move assignment operators created
 2361/34634 implicit destructors created
 
-Number of memory regions: 1157
-Bytes used: 269495762
-Bytes allocated: 278396928
-Bytes wasted: 8901166 (includes alignment, etc)
+Number of memory regions: 1155
+Bytes used: 266684298
+Bytes allocated: 274202624
+Bytes wasted: 7518326 (includes alignment, etc)
 
 *** Decl Stats:
   700826 decls total.
 10595 AccessSpec decls, 40 each (423800 bytes)
 1 Empty decls, 32 each (32 bytes)
 1 ExternCContext decls, 64 each (64 bytes)
 1470 Friend decls, 56 each (82320 bytes)
-596 LinkageSpec decls, 80 each (47680 bytes)
+596 LinkageSpec decls, 72 each (42912 bytes)
 7 Label decls, 72 each (504 bytes)
 12955 Namespace decls, 104 each (1347320 bytes)
 65 NamespaceAlias decls, 88 each (5720 bytes)
-1 ObjCInterface decls, 128 each (128 bytes)
+1 ObjCInterface decls, 120 each (120 bytes)
 1 BuiltinTemplate decls, 64 each (64 bytes)
 12009 ClassTemplate decls, 80 each (960720 bytes)
 27783 FunctionTemplate decls, 80 each (640 bytes)
 860 TypeAliasTemplate decls, 80 each (68800 bytes)
 54 VarTemplate decls, 80 each (4320 bytes)
 299 TemplateTemplateParm decls, 80 each (23920 bytes)
-1064 Enum decls, 152 each (161728 bytes)
-68731 CXXRecord decls, 152 each (10447112 bytes)
-36165 ClassTemplateSpecialization decls, 192 each (6943680 bytes)
-8002 ClassTemplatePartialSpecialization decls, 216 each (1728432 bytes)
+1064 Enum decls, 144 each (153216 bytes)
+68731 CXXRecord decls, 136 each (9347416 bytes)
+36165 ClassTemplateSpecialization decls, 176 each (6365040 bytes)
+8002 ClassTemplatePartialSpecialization decls, 200 each (1600400 bytes)
 113359 TemplateTypeParm decls, 64 each (7254976 bytes)
 3598 TypeAlias decls, 88 each (316624 bytes)
 56547 Typedef decls, 80 each (4523760 bytes)
 5350 Using decls, 80 each (428000 bytes)
 162 UsingDirective decls, 80 each (12960 bytes)
 21727 UsingShadow decls, 72 each (1564344 bytes)
 47 ConstructorUsingShadow decls, 96 each (4512 bytes)
 9592 Field decls, 72 each (690624 bytes)
-18388 Function decls, 160 each (2942080 bytes)
-58759 CXXMethod decls, 160 each (9401440 bytes)
-21149 CXXConstructor decls, 176 each (374 bytes)
-527 CXXConversion decls, 160 each (84320 bytes)
-4004 CXXDestructor decls, 176 each (704704 bytes)
+18388 Function decls, 152 each (2794976 bytes)
+58759 CXXMethod decls, 152 each (8931368 bytes)
+21149 CXXConstructor decls, 160 each (3383840 bytes)
+527 CXXConversion decls, 152 each (80104 bytes)
+4004 CXXDestructor decls, 168 each (672672 bytes)
 10172 NonTypeTemplateParm decls, 88 each (895136 bytes)
 25370 Var decls, 96 each (2435520 bytes)
 166183 ParmVar decls, 96 each (15953568 bytes)
 39 VarTemplateSpecialization decls, 544 each (21216 bytes)
 2769 EnumConstant decls, 72 each (199368 bytes)
 786 IndirectField decls, 64 each (50304 bytes)
 101 UnresolvedUsingValue decls, 80 each (8080 bytes)
 1538 StaticAssert decls, 56 each (86128 bytes)
-Total bytes = 75768872
+Total bytes = 72957408
 
 *** Stmt/Expr Stats:
   1210411 stmts/exprs total.


Index: stat
===
--- stat
+++ stat
@@ -66,54 +66,54 @@
 665/34195 implicit move assignment operators created
 2361/34634 implicit destructors created
 
-Number of memory regions: 1157
-Bytes used: 269495762
-Bytes allocated: 278396928
-Bytes wasted: 8901166 (includes alignment, etc)
+Number of memory regions: 1155
+Bytes used: 266684298
+Bytes allocated: 274202624
+Bytes wasted: 7518326 (includes alignment, etc)
 
 *** Decl Stats:
   700826 decls total.
 10595 AccessSpec decls, 40 each (423800 bytes)
 1 Empty decls, 32 each (32 bytes)
 1 ExternCContext decls, 64 each (64 bytes)
 1470 Friend decls, 56 each (82320 bytes)
-596 LinkageSpec decls, 80 each (47680 bytes)
+596 LinkageSpec decls, 72 each (42912 bytes)
 7 Label decls, 72 each (504 bytes)
 12955 Namespace decls, 104 each (1347320 bytes)
 65 NamespaceAlias decls, 88 each (5720 bytes)
-1 ObjCInterface decls, 128 each (128 bytes)
+1 ObjCInterface decls, 120 each (120 bytes)
 1 BuiltinTemplate decls, 64 each (64 bytes)
 12009 ClassTemplate decls, 80 each (960720 bytes)
 27783 FunctionTemplate decls, 80 each (640 bytes)
 860 TypeAliasTemplate decls, 80 each (68800 bytes)
 54 VarTemplate decls, 80 each (4320 bytes)
 299 TemplateTemplateParm decls, 80 each (23920 bytes)
-1064 Enum decls, 152 each (161728 bytes)
-68731 CXXRecord decls, 152 each (10447112 bytes)
-36165

[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

DeclContext has a little less than 8 bytes free due to the alignment
requirements on 64 bits archs. This set of patches moves the
bit-fields from classes deriving from DeclContext into DeclContext.

On 32 bits archs this increases the size of DeclContext by 4 bytes
but this is balanced by an equal or larger reduction in the size
of the classes deriving from it.

On 64 bits archs the size of DeclContext stays the same but
all the classes deriving from it shrink by 8/16 bytes.
(-print-stats diff here https://reviews.llvm.org/D49728)
When doing an -fsyntax-only on all of Boost this result
in a 3.6% reduction in the size of all Decls and
a 1% reduction in the run time due to the lower cache
miss rate.

This first patch introduces the anonymous union in DeclContext
and all the *DeclBitfields classes holding the bit-fields, and moves
the bits from TagDecl, EnumDecl and RecordDecl into DeclContext.


Repository:
  rC Clang

https://reviews.llvm.org/D49729

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1273,7 +1273,7 @@
 
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  if (D->IsCompleteDefinition)
+  if (D->isCompleteDefinition())
 Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 
   Code = serialization::DECL_CXX_RECORD;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,8 @@
 
 bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
-  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage;
+  return Result.hasExternalDecls() &&
+ DC->hasNeedToReconcileExternalVisibleStorage();
 }
 
 bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
@@ -3975,8 +3976,8 @@
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl &LookupTable) {
-  assert(!ConstDC->HasLazyLocalLexicalLookups &&
- !ConstDC->HasLazyExternalLexicalLookups &&
+  assert(!ConstDC->hasLazyLocalLexicalLookups() &&
+ !ConstDC->hasLazyExternalLexicalLookups() &&
  "must call buildLookups first");
 
   // FIXME: We need to build the lookups table, which is logically const.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,13 +742,13 @@
   ED->setPromotionType(Record.readType());
   ED->setNumPositiveBits(Record.readInt());
   ED->setNumNegativeBits(Record.readInt());
-  ED->IsScoped = Record.readInt();
-  ED->IsScopedUsingClassTag = Record.readInt();
-  ED->IsFixed = Record.readInt();
+  ED->setScoped(Record.readInt());
+  ED->setScopedUsingClassTag(Record.readInt());
+  ED->setFixed(Record.readInt());
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->IsCompleteDefinition &&
+  if (ED->isCompleteDefinition() &&
   Reader.getContext().getLangOpts().Modules &&
   Reader.getContext().getLangOpts().CPlusPlus) {
 EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
@@ -764,7 +764,7 @@
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->IsCompleteDefinition = false;
+  ED->setCompleteDefinition(false);
   Reader.mergeDefinitionVisibility(OldDef, ED);
 } else {
   OldDef = ED;
@@ -1739,7 +1739,7 @@
 Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
 DD.Definition));
 Reader.PendingDefinitions.erase(MergeDD.Definition);
-MergeDD.Definition->IsCompleteDefinition = false;
+MergeDD.Definition->setCompleteDefinition(false);
 Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
 assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
"already loaded pending lookups for merged definition");
@@ -1879,7 +1879,7 @@
   }
 
   // Mark this declaration as being a definition.
-  D->IsCompleteDefinition = true;
+  D->setCompleteDefinition(true);
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that

[PATCH] D49732: [AST][2/4] Move the bit-fields from FunctionDecl and CXXConstructorDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

This patch follows https://reviews.llvm.org/D49729
and moves the bits from FunctionDecl and CXXConstructorDecl
into DeclContext.


Repository:
  rC Clang

https://reviews.llvm.org/D49732

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  lib/AST/Decl.cpp
  lib/AST/DeclCXX.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -528,25 +528,25 @@
   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
   // after everything else is written.
   
-  Record.push_back((int)D->SClass); // FIXME: stable encoding
-  Record.push_back(D->IsInline);
-  Record.push_back(D->IsInlineSpecified);
-  Record.push_back(D->IsExplicitSpecified);
-  Record.push_back(D->IsVirtualAsWritten);
-  Record.push_back(D->IsPure);
-  Record.push_back(D->HasInheritedPrototype);
-  Record.push_back(D->HasWrittenPrototype);
-  Record.push_back(D->IsDeleted);
-  Record.push_back(D->IsTrivial);
-  Record.push_back(D->IsTrivialForCall);
-  Record.push_back(D->IsDefaulted);
-  Record.push_back(D->IsExplicitlyDefaulted);
-  Record.push_back(D->HasImplicitReturnZero);
-  Record.push_back(D->IsConstexpr);
-  Record.push_back(D->UsesSEHTry);
-  Record.push_back(D->HasSkippedBody);
-  Record.push_back(D->IsMultiVersion);
-  Record.push_back(D->IsLateTemplateParsed);
+  Record.push_back(static_cast(D->getStorageClass())); // FIXME: stable encoding
+  Record.push_back(D->isInlineSpecified());
+  Record.push_back(D->isInlined());
+  Record.push_back(D->isExplicitSpecified());
+  Record.push_back(D->isVirtualAsWritten());
+  Record.push_back(D->isPure());
+  Record.push_back(D->hasInheritedPrototype());
+  Record.push_back(D->hasWrittenPrototype());
+  Record.push_back(D->isDeletedImpl());
+  Record.push_back(D->isTrivial());
+  Record.push_back(D->isTrivialForCall());
+  Record.push_back(D->isDefaulted());
+  Record.push_back(D->isExplicitlyDefaulted());
+  Record.push_back(D->hasImplicitReturnZero());
+  Record.push_back(D->isConstexpr());
+  Record.push_back(D->usesSEHTry());
+  Record.push_back(D->hasSkippedBody());
+  Record.push_back(D->isMultiVersionImpl());
+  Record.push_back(D->isLateTemplateParsed());
   Record.push_back(D->getLinkageInternal());
   Record.AddSourceLocation(D->getLocEnd());
 
@@ -626,7 +626,7 @@
 
 void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
   VisitFunctionDecl(D);
-  Record.push_back(D->IsCopyDeductionCandidate);
+  Record.push_back(D->isCopyDeductionCandidate());
   Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
 }
 
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -506,8 +506,8 @@
   if (Record.readInt())
 Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
   if (auto *CD = dyn_cast(FD)) {
-CD->NumCtorInitializers = Record.readInt();
-if (CD->NumCtorInitializers)
+CD->setNumCtorInitializers(Record.readInt());
+if (CD->getNumCtorInitializers())
   CD->CtorInitializers = ReadGlobalOffset();
   }
   // Store the offset of the body so we can lazily load it later.
@@ -850,30 +850,31 @@
   // FunctionDecl's body is handled last at ASTDeclReader::Visit,
   // after everything else is read.
 
-  FD->SClass = (StorageClass)Record.readInt();
-  FD->IsInline = Record.readInt();
-  FD->IsInlineSpecified = Record.readInt();
-  FD->IsExplicitSpecified = Record.readInt();
-  FD->IsVirtualAsWritten = Record.readInt();
-  FD->IsPure = Record.readInt();
-  FD->HasInheritedPrototype = Record.readInt();
-  FD->HasWrittenPrototype = Record.readInt();
-  FD->IsDeleted = Record.readInt();
-  FD->IsTrivial = Record.readInt();
-  FD->IsTrivialForCall = Record.readInt();
-  FD->IsDefaulted = Record.readInt();
-  FD->IsExplicitlyDefaulted = Record.readInt();
-  FD->HasImplicitReturnZero = Record.readInt();
-  FD->IsConstexpr = Record.readInt();
-  FD->UsesSEHTry = Record.readInt();
-  FD->HasSkippedBody = Record.readInt();
-  FD->IsMultiVersion = Record.readInt();
-  FD->IsLateTemplateParsed = Record.readInt();
-  FD->setCachedLinkage(Linkage(Record.readInt()));
+  FD->setStorageClass(static_cast(Record.readInt()));
+  FD->setInlineSpecified(Record.readInt());
+  FD->setImplicitlyInline(Record.readInt());
+  FD->setExplicitSpecified(Record.readInt());
+  FD->setVirtualAsWritten(Record.readInt());
+  FD->setPureImpl(Record.readInt());
+  FD->setHasInheritedPrototype(Record.readInt());
+  FD->setHasWrittenPrototype(Record.readInt());
+  FD->setDeletedAsWritten(Record.readInt());
+  FD->setTrivial(Record.readInt());
+  FD->setTrivialForCall(Record.readInt());
+  FD->setDefaulted(Record.readInt(

[PATCH] D49733: [AST][3/4] Move the bit-fields from BlockDecl, LinkageSpecDecl and OMPDeclareReductionDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

This patch follows https://reviews.llvm.org/D49729
and https://reviews.llvm.org/D49732,

Move the bits from BlockDecl, LinkageSpecDecl and
OMPDeclareReductionDecl into DeclContext.


Repository:
  rC Clang

https://reviews.llvm.org/D49733

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/DeclOpenMP.h
  lib/AST/Decl.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclOpenMP.cpp

Index: lib/AST/DeclOpenMP.cpp
===
--- lib/AST/DeclOpenMP.cpp
+++ lib/AST/DeclOpenMP.cpp
@@ -57,6 +57,14 @@
 // OMPDeclareReductionDecl Implementation.
 //===--===//
 
+OMPDeclareReductionDecl::OMPDeclareReductionDecl(Kind DK, DeclContext *DC,
+  SourceLocation L, DeclarationName Name, QualType Ty,
+  OMPDeclareReductionDecl *PrevDeclInScope)
+  : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK),
+Combiner(nullptr), PrevDeclInScope(PrevDeclInScope) {
+  setInitializer(nullptr, CallInit);
+}
+
 void OMPDeclareReductionDecl::anchor() {}
 
 OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create(
Index: lib/AST/DeclCXX.cpp
===
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -2467,6 +2467,14 @@
  getConversionType()->isBlockPointerType();
 }
 
+LinkageSpecDecl::LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
+  SourceLocation LangLoc, LanguageIDs lang, bool HasBraces)
+  : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
+ExternLoc(ExternLoc), RBraceLoc(SourceLocation()) {
+  setLanguage(lang);
+  setBracesImpl(HasBraces);
+}
+
 void LinkageSpecDecl::anchor() {}
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
Index: lib/AST/Decl.cpp
===
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -4204,6 +4204,15 @@
 // BlockDecl Implementation
 //===--===//
 
+BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+  : Decl(Block, DC, CaretLoc), DeclContext(Block) {
+  setIsVariadic(false);
+  setCapturesCXXThis(false);
+  setBlockMissingReturnType(true);
+  setIsConversionFromLambda(false);
+  setDoesNotEscape(false);
+}
+
 void BlockDecl::setParams(ArrayRef NewParamInfo) {
   assert(!ParamInfo && "Already has param info!");
 
@@ -4217,7 +4226,7 @@
 
 void BlockDecl::setCaptures(ASTContext &Context, ArrayRef Captures,
 bool CapturesCXXThis) {
-  this->CapturesCXXThis = CapturesCXXThis;
+  this->setCapturesCXXThis(CapturesCXXThis);
   this->NumCaptures = Captures.size();
 
   if (Captures.empty()) {
Index: include/clang/AST/DeclOpenMP.h
===
--- include/clang/AST/DeclOpenMP.h
+++ include/clang/AST/DeclOpenMP.h
@@ -100,6 +100,8 @@
 ///
 /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
 class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
+  // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
+  // to save some space. Use the provided accessors to access it.
 public:
   enum InitKind {
 CallInit,   // Initialized by function call.
@@ -113,8 +115,6 @@
   Expr *Combiner;
   /// Initializer for declare reduction construct.
   Expr *Initializer;
-  /// Kind of initializer - function call or omp_priv initializtion.
-  InitKind InitializerKind = CallInit;
 
   /// Reference to the previous declare reduction construct in the same
   /// scope with the same name. Required for proper templates instantiation if
@@ -125,10 +125,7 @@
 
   OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
   DeclarationName Name, QualType Ty,
-  OMPDeclareReductionDecl *PrevDeclInScope)
-  : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
-Initializer(nullptr), InitializerKind(CallInit),
-PrevDeclInScope(PrevDeclInScope) {}
+  OMPDeclareReductionDecl *PrevDeclInScope);
 
   void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
 PrevDeclInScope = Prev;
@@ -154,11 +151,13 @@
   Expr *getInitializer() { return Initializer; }
   const Expr *getInitializer() const { return Initializer; }
   /// Get initializer kind.
-  InitKind getInitializerKind() const { return InitializerKind; }
+  InitKind getInitializerKind() const {
+return static_cast(OMPDeclareReductionDeclBits.InitializerKind);
+  }
   /// Set initializer expression for the declare reduction construct.
   void setInitializer(Expr *E, InitKind IK) {
 Initializer = E;
-InitializerKind = IK;
+OMPDeclareReductionDeclBits.Initiali

[PATCH] D49734: [AST][4/4] Move the bit-fields from ObjCMethodDecl and ObjCContainerDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

This patch follows https://reviews.llvm.org/D49729,
https://reviews.llvm.org/D49732 and
https://reviews.llvm.org/D49733.

Move the bits from ObjCMethodDecl and ObjCContainerDecl
into DeclContext.


Repository:
  rC Clang

https://reviews.llvm.org/D49734

Files:
  include/clang/AST/DeclObjC.h
  lib/AST/DeclObjC.cpp
  lib/Sema/SemaDeclObjC.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -646,12 +646,12 @@
   Record.push_back(D->isVariadic());
   Record.push_back(D->isPropertyAccessor());
   Record.push_back(D->isDefined());
-  Record.push_back(D->IsOverriding);
-  Record.push_back(D->HasSkippedBody);
+  Record.push_back(D->isOverriding());
+  Record.push_back(D->hasSkippedBody());
 
-  Record.push_back(D->IsRedeclaration);
-  Record.push_back(D->HasRedeclaration);
-  if (D->HasRedeclaration) {
+  Record.push_back(D->isRedeclaration());
+  Record.push_back(D->hasRedeclaration());
+  if (D->hasRedeclaration()) {
 assert(Context.getObjCMethodRedeclaration(D));
 Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
   }
@@ -668,7 +668,7 @@
   for (const auto *P : D->parameters())
 Record.AddDeclRef(P);
 
-  Record.push_back(D->SelLocsKind);
+  Record.push_back(D->getSelLocsKind());
   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
   SourceLocation *SelLocs = D->getStoredSelLocs();
   Record.push_back(NumStoredSelLocs);
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1002,18 +1002,18 @@
   MD->setVariadic(Record.readInt());
   MD->setPropertyAccessor(Record.readInt());
   MD->setDefined(Record.readInt());
-  MD->IsOverriding = Record.readInt();
-  MD->HasSkippedBody = Record.readInt();
+  MD->setOverriding(Record.readInt());
+  MD->setHasSkippedBody(Record.readInt());
 
-  MD->IsRedeclaration = Record.readInt();
-  MD->HasRedeclaration = Record.readInt();
-  if (MD->HasRedeclaration)
+  MD->setIsRedeclaration(Record.readInt());
+  MD->setHasRedeclaration(Record.readInt());
+  if (MD->hasRedeclaration())
 Reader.getContext().setObjCMethodRedeclaration(MD,
ReadDeclAs());
 
   MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record.readInt());
   MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record.readInt());
-  MD->SetRelatedResultType(Record.readInt());
+  MD->setRelatedResultType(Record.readInt());
   MD->setReturnType(Record.readType());
   MD->setReturnTypeSourceInfo(GetTypeSourceInfo());
   MD->DeclEndLoc = ReadSourceLocation();
@@ -1023,7 +1023,7 @@
   for (unsigned I = 0; I != NumParams; ++I)
 Params.push_back(ReadDeclAs());
 
-  MD->SelLocsKind = Record.readInt();
+  MD->setSelLocsKind((SelectorLocationsKind)Record.readInt());
   unsigned NumStoredSelLocs = Record.readInt();
   SmallVector SelLocs;
   SelLocs.reserve(NumStoredSelLocs);
Index: lib/Sema/SemaDeclObjC.cpp
===
--- lib/Sema/SemaDeclObjC.cpp
+++ lib/Sema/SemaDeclObjC.cpp
@@ -4333,7 +4333,7 @@
 
 // Propagate down the 'related result type' bit from overridden methods.
 if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
-  ObjCMethod->SetRelatedResultType();
+  ObjCMethod->setRelatedResultType();
 
 // Then merge the declarations.
 mergeObjCMethodDecls(ObjCMethod, overridden);
@@ -4712,7 +4712,7 @@
 
 if (InferRelatedResultType &&
 !ObjCMethod->getReturnType()->isObjCIndependentClassType())
-  ObjCMethod->SetRelatedResultType();
+  ObjCMethod->setRelatedResultType();
   }
 
   if (MethodDefinition &&
Index: lib/AST/DeclObjC.cpp
===
--- lib/AST/DeclObjC.cpp
+++ lib/AST/DeclObjC.cpp
@@ -65,6 +65,13 @@
 // ObjCInterfaceDecl
 //===--===//
 
+ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,
+IdentifierInfo *Id, SourceLocation nameLoc,
+SourceLocation atStartLoc)
+  : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
+  setAtStartLoc(atStartLoc);
+}
+
 void ObjCContainerDecl::anchor() {}
 
 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
@@ -769,6 +776,42 @@
 // ObjCMethodDecl
 //===--===//
 
+ObjCMethodDecl::ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
+ Selector SelInfo, QualType T, TypeSourceInfo *ReturnTInfo,
+ DeclContext *contextDecl, boo

[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

added some inline comments




Comment at: include/clang/AST/DeclBase.h:1662
+  enum { NumBlockDeclBits = 5 };
 
   /// Pointer to the data structure used to lookup declarations

uint64_t is used here because we will always store more than 32 bits
but less than 64 bits in these SomethingDeclBitfields.



Comment at: include/clang/AST/DeclBase.h:1959
-  void makeDeclVisibleInContextInternal(NamedDecl *D);
-
   StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;

This declaration has no corresponding definition and is unused.
Therefore I removed it but if this is more appropriate for another
patch I will do the necessary changes.


Repository:
  rC Clang

https://reviews.llvm.org/D49729



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157052.
bricci added a comment.

updated some some comments in DeclContext


Repository:
  rC Clang

https://reviews.llvm.org/D49729

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1273,7 +1273,7 @@
 
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  if (D->IsCompleteDefinition)
+  if (D->isCompleteDefinition())
 Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 
   Code = serialization::DECL_CXX_RECORD;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,8 @@
 
 bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
-  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage;
+  return Result.hasExternalDecls() &&
+ DC->hasNeedToReconcileExternalVisibleStorage();
 }
 
 bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
@@ -3975,8 +3976,8 @@
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl &LookupTable) {
-  assert(!ConstDC->HasLazyLocalLexicalLookups &&
- !ConstDC->HasLazyExternalLexicalLookups &&
+  assert(!ConstDC->hasLazyLocalLexicalLookups() &&
+ !ConstDC->hasLazyExternalLexicalLookups() &&
  "must call buildLookups first");
 
   // FIXME: We need to build the lookups table, which is logically const.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,13 +742,13 @@
   ED->setPromotionType(Record.readType());
   ED->setNumPositiveBits(Record.readInt());
   ED->setNumNegativeBits(Record.readInt());
-  ED->IsScoped = Record.readInt();
-  ED->IsScopedUsingClassTag = Record.readInt();
-  ED->IsFixed = Record.readInt();
+  ED->setScoped(Record.readInt());
+  ED->setScopedUsingClassTag(Record.readInt());
+  ED->setFixed(Record.readInt());
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->IsCompleteDefinition &&
+  if (ED->isCompleteDefinition() &&
   Reader.getContext().getLangOpts().Modules &&
   Reader.getContext().getLangOpts().CPlusPlus) {
 EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
@@ -764,7 +764,7 @@
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->IsCompleteDefinition = false;
+  ED->setCompleteDefinition(false);
   Reader.mergeDefinitionVisibility(OldDef, ED);
 } else {
   OldDef = ED;
@@ -1739,7 +1739,7 @@
 Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
 DD.Definition));
 Reader.PendingDefinitions.erase(MergeDD.Definition);
-MergeDD.Definition->IsCompleteDefinition = false;
+MergeDD.Definition->setCompleteDefinition(false);
 Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
 assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
"already loaded pending lookups for merged definition");
@@ -1879,7 +1879,7 @@
   }
 
   // Mark this declaration as being a definition.
-  D->IsCompleteDefinition = true;
+  D->setCompleteDefinition(true);
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that we need to propagate the
@@ -1941,7 +1941,7 @@
   // compute it.
   if (WasDefinition) {
 DeclID KeyFn = ReadDeclID();
-if (KeyFn && D->IsCompleteDefinition)
+if (KeyFn && D->isCompleteDefinition())
   // FIXME: This is wrong for the ARM ABI, where some other module may have
   // made this function no longer be a key function. We need an update
   // record or similar for that case.
@@ -3071,7 +3071,7 @@
 // we load the update record.
 if (!DD) {
   DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
-  RD->IsCompleteDefinition = true;
+  RD->setCompleteDefinition(true);
   RD->DefinitionData = DD;
   RD->getCanonicalDecl()->DefinitionData = DD;
 
Index: lib/AST/DeclTemplate.cpp
===
--- lib/AST/DeclTemplate.cpp
+++ lib/AST/DeclTemplate.cpp
@@ -71

[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci marked an inline comment as done.
bricci added a comment.

remove the inline comment about uint64_t.


Repository:
  rC Clang

https://reviews.llvm.org/D49729



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-24 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157063.
bricci added a comment.

- removed some unrelated change
- add a comment about why uint64_t instead of unsigned


Repository:
  rC Clang

https://reviews.llvm.org/D49729

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1273,7 +1273,7 @@
 
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  if (D->IsCompleteDefinition)
+  if (D->isCompleteDefinition())
 Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 
   Code = serialization::DECL_CXX_RECORD;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,8 @@
 
 bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
-  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage;
+  return Result.hasExternalDecls() &&
+ DC->hasNeedToReconcileExternalVisibleStorage();
 }
 
 bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
@@ -3975,8 +3976,8 @@
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl &LookupTable) {
-  assert(!ConstDC->HasLazyLocalLexicalLookups &&
- !ConstDC->HasLazyExternalLexicalLookups &&
+  assert(!ConstDC->hasLazyLocalLexicalLookups() &&
+ !ConstDC->hasLazyExternalLexicalLookups() &&
  "must call buildLookups first");
 
   // FIXME: We need to build the lookups table, which is logically const.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,13 +742,13 @@
   ED->setPromotionType(Record.readType());
   ED->setNumPositiveBits(Record.readInt());
   ED->setNumNegativeBits(Record.readInt());
-  ED->IsScoped = Record.readInt();
-  ED->IsScopedUsingClassTag = Record.readInt();
-  ED->IsFixed = Record.readInt();
+  ED->setScoped(Record.readInt());
+  ED->setScopedUsingClassTag(Record.readInt());
+  ED->setFixed(Record.readInt());
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->IsCompleteDefinition &&
+  if (ED->isCompleteDefinition() &&
   Reader.getContext().getLangOpts().Modules &&
   Reader.getContext().getLangOpts().CPlusPlus) {
 EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
@@ -764,7 +764,7 @@
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->IsCompleteDefinition = false;
+  ED->setCompleteDefinition(false);
   Reader.mergeDefinitionVisibility(OldDef, ED);
 } else {
   OldDef = ED;
@@ -1739,7 +1739,7 @@
 Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
 DD.Definition));
 Reader.PendingDefinitions.erase(MergeDD.Definition);
-MergeDD.Definition->IsCompleteDefinition = false;
+MergeDD.Definition->setCompleteDefinition(false);
 Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
 assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
"already loaded pending lookups for merged definition");
@@ -1879,7 +1879,7 @@
   }
 
   // Mark this declaration as being a definition.
-  D->IsCompleteDefinition = true;
+  D->setCompleteDefinition(true);
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that we need to propagate the
@@ -1941,7 +1941,7 @@
   // compute it.
   if (WasDefinition) {
 DeclID KeyFn = ReadDeclID();
-if (KeyFn && D->IsCompleteDefinition)
+if (KeyFn && D->isCompleteDefinition())
   // FIXME: This is wrong for the ARM ABI, where some other module may have
   // made this function no longer be a key function. We need an update
   // record or similar for that case.
@@ -3071,7 +3071,7 @@
 // we load the update record.
 if (!DD) {
   DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
-  RD->IsCompleteDefinition = true;
+  RD->setCompleteDefinition(true);
   RD->DefinitionData = DD;
   RD->getCanonicalDecl()->DefinitionData = DD;
 
Index: lib/AST/DeclTemplate.cpp
===
--- lib/AST/DeclTem

[PATCH] D49790: [AST] Small doc update for DeclContext

2018-07-25 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

Factored out from https://reviews.llvm.org/D49729
following @erichkeane comments.

- Add missing classes in the list of classes deriving directly from DeclContext.
- Move the friend declarations together and add a comment for why they are 
required. Also remove a friend declaration which is not needed.


Repository:
  rC Clang

https://reviews.llvm.org/D49790

Files:
  include/clang/AST/DeclBase.h


Index: include/clang/AST/DeclBase.h
===
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -1250,16 +1250,25 @@
 /// that directly derive from DeclContext are mentioned, not their subclasses):
 ///
 ///   TranslationUnitDecl
+///   ExternCContext
 ///   NamespaceDecl
-///   FunctionDecl
 ///   TagDecl
+///   OMPDeclareReductionDecl
+///   FunctionDecl
 ///   ObjCMethodDecl
 ///   ObjCContainerDecl
 ///   LinkageSpecDecl
 ///   ExportDecl
 ///   BlockDecl
-///   OMPDeclareReductionDecl
+///   CapturedDecl
 class DeclContext {
+  /// For makeDeclVisibleInContextImpl
+  friend class ASTDeclReader;
+  /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap
+  friend class ExternalASTSource;
+  /// For CreateStoredDeclsMap
+  friend class DependentDiagnostic;
+
   // We use uint64_t in the bit-fields below since some bit-fields
   // cross the unsigned boundary and this breaks the packing.
 
@@ -1709,10 +1718,6 @@
   "BlockDeclBitfields is larger than 8 bytes!");
   };
 
-  friend class ASTDeclReader;
-  friend class ASTWriter;
-  friend class ExternalASTSource;
-
   /// FirstDecl - The first declaration stored within this declaration
   /// context.
   mutable Decl *FirstDecl = nullptr;
@@ -2391,8 +2396,6 @@
 DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
   }
 
-  friend class DependentDiagnostic;
-
   void reconcileExternalVisibleStorage() const;
   bool LoadLexicalDeclsFromExternalStorage() const;
 


Index: include/clang/AST/DeclBase.h
===
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -1250,16 +1250,25 @@
 /// that directly derive from DeclContext are mentioned, not their subclasses):
 ///
 ///   TranslationUnitDecl
+///   ExternCContext
 ///   NamespaceDecl
-///   FunctionDecl
 ///   TagDecl
+///   OMPDeclareReductionDecl
+///   FunctionDecl
 ///   ObjCMethodDecl
 ///   ObjCContainerDecl
 ///   LinkageSpecDecl
 ///   ExportDecl
 ///   BlockDecl
-///   OMPDeclareReductionDecl
+///   CapturedDecl
 class DeclContext {
+  /// For makeDeclVisibleInContextImpl
+  friend class ASTDeclReader;
+  /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap
+  friend class ExternalASTSource;
+  /// For CreateStoredDeclsMap
+  friend class DependentDiagnostic;
+
   // We use uint64_t in the bit-fields below since some bit-fields
   // cross the unsigned boundary and this breaks the packing.
 
@@ -1709,10 +1718,6 @@
   "BlockDeclBitfields is larger than 8 bytes!");
   };
 
-  friend class ASTDeclReader;
-  friend class ASTWriter;
-  friend class ExternalASTSource;
-
   /// FirstDecl - The first declaration stored within this declaration
   /// context.
   mutable Decl *FirstDecl = nullptr;
@@ -2391,8 +2396,6 @@
 DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
   }
 
-  friend class DependentDiagnostic;
-
   void reconcileExternalVisibleStorage() const;
   bool LoadLexicalDeclsFromExternalStorage() const;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-25 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157231.
bricci marked 10 inline comments as done.
bricci added a comment.

address @erichkeane comments:

- ran clang-format on changed parts
- made the setters setNumPositiveBits, setNumPositiveBits, setScoped, 
setScopedUsingClassTag and setFixed in EnumDecl private.
- made the setters setBeingDefined and setBeingDefined in TagDecl protected
- moved the static_asserts to the anonymous union
- factored out the doc update of DeclBase. This is now 
https://reviews.llvm.org/D49790
- various typos


Repository:
  rC Clang

https://reviews.llvm.org/D49729

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1273,7 +1273,7 @@
 
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  if (D->IsCompleteDefinition)
+  if (D->isCompleteDefinition())
 Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 
   Code = serialization::DECL_CXX_RECORD;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,8 @@
 
 bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
-  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage;
+  return Result.hasExternalDecls() &&
+ DC->hasNeedToReconcileExternalVisibleStorage();
 }
 
 bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
@@ -3975,8 +3976,8 @@
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl &LookupTable) {
-  assert(!ConstDC->HasLazyLocalLexicalLookups &&
- !ConstDC->HasLazyExternalLexicalLookups &&
+  assert(!ConstDC->hasLazyLocalLexicalLookups() &&
+ !ConstDC->hasLazyExternalLexicalLookups() &&
  "must call buildLookups first");
 
   // FIXME: We need to build the lookups table, which is logically const.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,13 +742,13 @@
   ED->setPromotionType(Record.readType());
   ED->setNumPositiveBits(Record.readInt());
   ED->setNumNegativeBits(Record.readInt());
-  ED->IsScoped = Record.readInt();
-  ED->IsScopedUsingClassTag = Record.readInt();
-  ED->IsFixed = Record.readInt();
+  ED->setScoped(Record.readInt());
+  ED->setScopedUsingClassTag(Record.readInt());
+  ED->setFixed(Record.readInt());
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->IsCompleteDefinition &&
+  if (ED->isCompleteDefinition() &&
   Reader.getContext().getLangOpts().Modules &&
   Reader.getContext().getLangOpts().CPlusPlus) {
 EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
@@ -764,7 +764,7 @@
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->IsCompleteDefinition = false;
+  ED->setCompleteDefinition(false);
   Reader.mergeDefinitionVisibility(OldDef, ED);
 } else {
   OldDef = ED;
@@ -1739,7 +1739,7 @@
 Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
 DD.Definition));
 Reader.PendingDefinitions.erase(MergeDD.Definition);
-MergeDD.Definition->IsCompleteDefinition = false;
+MergeDD.Definition->setCompleteDefinition(false);
 Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
 assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
"already loaded pending lookups for merged definition");
@@ -1879,7 +1879,7 @@
   }
 
   // Mark this declaration as being a definition.
-  D->IsCompleteDefinition = true;
+  D->setCompleteDefinition(true);
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that we need to propagate the
@@ -1941,7 +1941,7 @@
   // compute it.
   if (WasDefinition) {
 DeclID KeyFn = ReadDeclID();
-if (KeyFn && D->IsCompleteDefinition)
+if (KeyFn && D->isCompleteDefinition())
   // FIXME: This is wrong for the ARM ABI, where some other module may have
   // made this function no longer be a key function. We need an update
   // record or similar for that case.
@@ -3071,7 +3071,7 @@
 // we load the update record.
 

[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-25 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

It might be better to wait just after the upcoming release branch in any case
since even though it is all NFC this causes a bit of churn.


Repository:
  rC Clang

https://reviews.llvm.org/D49729



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-25 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157288.
bricci added a comment.

- clang-format on the changes in the .cpp files


Repository:
  rC Clang

https://reviews.llvm.org/D49729

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1273,7 +1273,7 @@
 
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  if (D->IsCompleteDefinition)
+  if (D->isCompleteDefinition())
 Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 
   Code = serialization::DECL_CXX_RECORD;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,8 @@
 
 bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
-  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage;
+  return Result.hasExternalDecls() &&
+ DC->hasNeedToReconcileExternalVisibleStorage();
 }
 
 bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
@@ -3975,8 +3976,8 @@
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl &LookupTable) {
-  assert(!ConstDC->HasLazyLocalLexicalLookups &&
- !ConstDC->HasLazyExternalLexicalLookups &&
+  assert(!ConstDC->hasLazyLocalLexicalLookups() &&
+ !ConstDC->hasLazyExternalLexicalLookups() &&
  "must call buildLookups first");
 
   // FIXME: We need to build the lookups table, which is logically const.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,13 +742,13 @@
   ED->setPromotionType(Record.readType());
   ED->setNumPositiveBits(Record.readInt());
   ED->setNumNegativeBits(Record.readInt());
-  ED->IsScoped = Record.readInt();
-  ED->IsScopedUsingClassTag = Record.readInt();
-  ED->IsFixed = Record.readInt();
+  ED->setScoped(Record.readInt());
+  ED->setScopedUsingClassTag(Record.readInt());
+  ED->setFixed(Record.readInt());
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->IsCompleteDefinition &&
+  if (ED->isCompleteDefinition() &&
   Reader.getContext().getLangOpts().Modules &&
   Reader.getContext().getLangOpts().CPlusPlus) {
 EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
@@ -764,7 +764,7 @@
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->IsCompleteDefinition = false;
+  ED->setCompleteDefinition(false);
   Reader.mergeDefinitionVisibility(OldDef, ED);
 } else {
   OldDef = ED;
@@ -1739,7 +1739,7 @@
 Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
 DD.Definition));
 Reader.PendingDefinitions.erase(MergeDD.Definition);
-MergeDD.Definition->IsCompleteDefinition = false;
+MergeDD.Definition->setCompleteDefinition(false);
 Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
 assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
"already loaded pending lookups for merged definition");
@@ -1879,7 +1879,7 @@
   }
 
   // Mark this declaration as being a definition.
-  D->IsCompleteDefinition = true;
+  D->setCompleteDefinition(true);
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that we need to propagate the
@@ -1941,7 +1941,7 @@
   // compute it.
   if (WasDefinition) {
 DeclID KeyFn = ReadDeclID();
-if (KeyFn && D->IsCompleteDefinition)
+if (KeyFn && D->isCompleteDefinition())
   // FIXME: This is wrong for the ARM ABI, where some other module may have
   // made this function no longer be a key function. We need an update
   // record or similar for that case.
@@ -3071,7 +3071,7 @@
 // we load the update record.
 if (!DD) {
   DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
-  RD->IsCompleteDefinition = true;
+  RD->setCompleteDefinition(true);
   RD->DefinitionData = DD;
   RD->getCanonicalDecl()->DefinitionData = DD;
 
Index: lib/AST/DeclTemplate.cpp
===
--- lib/AST/DeclTemplate.cpp
+++ lib/AST/DeclTemplate.cpp

[PATCH] D49733: [AST][3/4] Move the bit-fields from BlockDecl, LinkageSpecDecl and OMPDeclareReductionDecl into DeclContext

2018-07-25 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157291.
bricci marked an inline comment as done.
bricci added a comment.

- clang-format on the changes
- removed the unnecessary hasBracesImpl and setBracesImpl


Repository:
  rC Clang

https://reviews.llvm.org/D49733

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/DeclOpenMP.h
  lib/AST/Decl.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclOpenMP.cpp

Index: lib/AST/DeclOpenMP.cpp
===
--- lib/AST/DeclOpenMP.cpp
+++ lib/AST/DeclOpenMP.cpp
@@ -57,6 +57,14 @@
 // OMPDeclareReductionDecl Implementation.
 //===--===//
 
+OMPDeclareReductionDecl::OMPDeclareReductionDecl(
+Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+QualType Ty, OMPDeclareReductionDecl *PrevDeclInScope)
+: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
+  PrevDeclInScope(PrevDeclInScope) {
+  setInitializer(nullptr, CallInit);
+}
+
 void OMPDeclareReductionDecl::anchor() {}
 
 OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create(
Index: lib/AST/DeclCXX.cpp
===
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -2466,6 +2466,15 @@
  getConversionType()->isBlockPointerType();
 }
 
+LinkageSpecDecl::LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
+ SourceLocation LangLoc, LanguageIDs lang,
+ bool HasBraces)
+: Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
+  ExternLoc(ExternLoc), RBraceLoc(SourceLocation()) {
+  setLanguage(lang);
+  LinkageSpecDeclBits.HasBraces = HasBraces;
+}
+
 void LinkageSpecDecl::anchor() {}
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
Index: lib/AST/Decl.cpp
===
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -4205,6 +4205,15 @@
 // BlockDecl Implementation
 //===--===//
 
+BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+: Decl(Block, DC, CaretLoc), DeclContext(Block) {
+  setIsVariadic(false);
+  setCapturesCXXThis(false);
+  setBlockMissingReturnType(true);
+  setIsConversionFromLambda(false);
+  setDoesNotEscape(false);
+}
+
 void BlockDecl::setParams(ArrayRef NewParamInfo) {
   assert(!ParamInfo && "Already has param info!");
 
@@ -4218,7 +4227,7 @@
 
 void BlockDecl::setCaptures(ASTContext &Context, ArrayRef Captures,
 bool CapturesCXXThis) {
-  this->CapturesCXXThis = CapturesCXXThis;
+  this->setCapturesCXXThis(CapturesCXXThis);
   this->NumCaptures = Captures.size();
 
   if (Captures.empty()) {
Index: include/clang/AST/DeclOpenMP.h
===
--- include/clang/AST/DeclOpenMP.h
+++ include/clang/AST/DeclOpenMP.h
@@ -100,6 +100,8 @@
 ///
 /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
 class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
+  // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
+  // to save some space. Use the provided accessors to access it.
 public:
   enum InitKind {
 CallInit,   // Initialized by function call.
@@ -113,8 +115,6 @@
   Expr *Combiner;
   /// Initializer for declare reduction construct.
   Expr *Initializer;
-  /// Kind of initializer - function call or omp_priv initializtion.
-  InitKind InitializerKind = CallInit;
 
   /// Reference to the previous declare reduction construct in the same
   /// scope with the same name. Required for proper templates instantiation if
@@ -125,10 +125,7 @@
 
   OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
   DeclarationName Name, QualType Ty,
-  OMPDeclareReductionDecl *PrevDeclInScope)
-  : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
-Initializer(nullptr), InitializerKind(CallInit),
-PrevDeclInScope(PrevDeclInScope) {}
+  OMPDeclareReductionDecl *PrevDeclInScope);
 
   void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
 PrevDeclInScope = Prev;
@@ -154,11 +151,13 @@
   Expr *getInitializer() { return Initializer; }
   const Expr *getInitializer() const { return Initializer; }
   /// Get initializer kind.
-  InitKind getInitializerKind() const { return InitializerKind; }
+  InitKind getInitializerKind() const {
+return static_cast(OMPDeclareReductionDeclBits.InitializerKind);
+  }
   /// Set initializer expression for the declare reduction construct.
   void setInitializer(Expr *E, InitKind IK) {
 Initializer = E;
-InitializerKind = IK;
+OMPDeclareReductionDeclBits.InitializerKind = IK;
   }
 
   /// Get reference to previous declare reduction

[PATCH] D49732: [AST][2/4] Move the bit-fields from FunctionDecl and CXXConstructorDecl into DeclContext

2018-07-25 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157289.
bricci marked 2 inline comments as done.
bricci added a comment.

- ran clang-format on the changes
- removed the unnecessary setPureImpl, isMultiVersionImpl and 
setMultiVersionImpl. However unfortunately I think that isDeletedImpl has to 
stay because ASTDeclWriter::VisitFunctionDecl need to access this bit but we do 
not want to make ASTDeclWriter a friend of FunctionDeclBitfields just for this. 
FWIW I have renamed it to isDeletedBit...


Repository:
  rC Clang

https://reviews.llvm.org/D49732

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  lib/AST/Decl.cpp
  lib/AST/DeclCXX.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -528,25 +528,25 @@
   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
   // after everything else is written.
   
-  Record.push_back((int)D->SClass); // FIXME: stable encoding
-  Record.push_back(D->IsInline);
-  Record.push_back(D->IsInlineSpecified);
-  Record.push_back(D->IsExplicitSpecified);
-  Record.push_back(D->IsVirtualAsWritten);
-  Record.push_back(D->IsPure);
-  Record.push_back(D->HasInheritedPrototype);
-  Record.push_back(D->HasWrittenPrototype);
-  Record.push_back(D->IsDeleted);
-  Record.push_back(D->IsTrivial);
-  Record.push_back(D->IsTrivialForCall);
-  Record.push_back(D->IsDefaulted);
-  Record.push_back(D->IsExplicitlyDefaulted);
-  Record.push_back(D->HasImplicitReturnZero);
-  Record.push_back(D->IsConstexpr);
-  Record.push_back(D->UsesSEHTry);
-  Record.push_back(D->HasSkippedBody);
-  Record.push_back(D->IsMultiVersion);
-  Record.push_back(D->IsLateTemplateParsed);
+  Record.push_back(static_cast(D->getStorageClass())); // FIXME: stable encoding
+  Record.push_back(D->isInlineSpecified());
+  Record.push_back(D->isInlined());
+  Record.push_back(D->isExplicitSpecified());
+  Record.push_back(D->isVirtualAsWritten());
+  Record.push_back(D->isPure());
+  Record.push_back(D->hasInheritedPrototype());
+  Record.push_back(D->hasWrittenPrototype());
+  Record.push_back(D->isDeletedBit());
+  Record.push_back(D->isTrivial());
+  Record.push_back(D->isTrivialForCall());
+  Record.push_back(D->isDefaulted());
+  Record.push_back(D->isExplicitlyDefaulted());
+  Record.push_back(D->hasImplicitReturnZero());
+  Record.push_back(D->isConstexpr());
+  Record.push_back(D->usesSEHTry());
+  Record.push_back(D->hasSkippedBody());
+  Record.push_back(D->isMultiVersion());
+  Record.push_back(D->isLateTemplateParsed());
   Record.push_back(D->getLinkageInternal());
   Record.AddSourceLocation(D->getLocEnd());
 
@@ -626,7 +626,7 @@
 
 void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
   VisitFunctionDecl(D);
-  Record.push_back(D->IsCopyDeductionCandidate);
+  Record.push_back(D->isCopyDeductionCandidate());
   Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
 }
 
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -506,8 +506,8 @@
   if (Record.readInt())
 Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
   if (auto *CD = dyn_cast(FD)) {
-CD->NumCtorInitializers = Record.readInt();
-if (CD->NumCtorInitializers)
+CD->setNumCtorInitializers(Record.readInt());
+if (CD->getNumCtorInitializers())
   CD->CtorInitializers = ReadGlobalOffset();
   }
   // Store the offset of the body so we can lazily load it later.
@@ -850,30 +850,31 @@
   // FunctionDecl's body is handled last at ASTDeclReader::Visit,
   // after everything else is read.
 
-  FD->SClass = (StorageClass)Record.readInt();
-  FD->IsInline = Record.readInt();
-  FD->IsInlineSpecified = Record.readInt();
-  FD->IsExplicitSpecified = Record.readInt();
-  FD->IsVirtualAsWritten = Record.readInt();
-  FD->IsPure = Record.readInt();
-  FD->HasInheritedPrototype = Record.readInt();
-  FD->HasWrittenPrototype = Record.readInt();
-  FD->IsDeleted = Record.readInt();
-  FD->IsTrivial = Record.readInt();
-  FD->IsTrivialForCall = Record.readInt();
-  FD->IsDefaulted = Record.readInt();
-  FD->IsExplicitlyDefaulted = Record.readInt();
-  FD->HasImplicitReturnZero = Record.readInt();
-  FD->IsConstexpr = Record.readInt();
-  FD->UsesSEHTry = Record.readInt();
-  FD->HasSkippedBody = Record.readInt();
-  FD->IsMultiVersion = Record.readInt();
-  FD->IsLateTemplateParsed = Record.readInt();
-  FD->setCachedLinkage(Linkage(Record.readInt()));
+  FD->setStorageClass(static_cast(Record.readInt()));
+  FD->setInlineSpecified(Record.readInt());
+  FD->setImplicitlyInline(Record.readInt());
+  FD->setExplicitSpecified(Record.readInt());
+  FD->setVirtualAsWritten(Record.readInt());
+  FD->setPure(Record.readInt());
+  FD->setHa

[PATCH] D49734: [AST][4/4] Move the bit-fields from ObjCMethodDecl and ObjCContainerDecl into DeclContext

2018-07-25 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157293.
bricci marked an inline comment as done.
bricci added a comment.

- clang-format on the changes
- remove the unnecessary getFamilyImpl and setFamilyImpl


Repository:
  rC Clang

https://reviews.llvm.org/D49734

Files:
  include/clang/AST/DeclObjC.h
  lib/AST/DeclObjC.cpp
  lib/Sema/SemaDeclObjC.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -646,12 +646,12 @@
   Record.push_back(D->isVariadic());
   Record.push_back(D->isPropertyAccessor());
   Record.push_back(D->isDefined());
-  Record.push_back(D->IsOverriding);
-  Record.push_back(D->HasSkippedBody);
+  Record.push_back(D->isOverriding());
+  Record.push_back(D->hasSkippedBody());
 
-  Record.push_back(D->IsRedeclaration);
-  Record.push_back(D->HasRedeclaration);
-  if (D->HasRedeclaration) {
+  Record.push_back(D->isRedeclaration());
+  Record.push_back(D->hasRedeclaration());
+  if (D->hasRedeclaration()) {
 assert(Context.getObjCMethodRedeclaration(D));
 Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
   }
@@ -668,7 +668,7 @@
   for (const auto *P : D->parameters())
 Record.AddDeclRef(P);
 
-  Record.push_back(D->SelLocsKind);
+  Record.push_back(D->getSelLocsKind());
   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
   SourceLocation *SelLocs = D->getStoredSelLocs();
   Record.push_back(NumStoredSelLocs);
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1002,18 +1002,18 @@
   MD->setVariadic(Record.readInt());
   MD->setPropertyAccessor(Record.readInt());
   MD->setDefined(Record.readInt());
-  MD->IsOverriding = Record.readInt();
-  MD->HasSkippedBody = Record.readInt();
+  MD->setOverriding(Record.readInt());
+  MD->setHasSkippedBody(Record.readInt());
 
-  MD->IsRedeclaration = Record.readInt();
-  MD->HasRedeclaration = Record.readInt();
-  if (MD->HasRedeclaration)
+  MD->setIsRedeclaration(Record.readInt());
+  MD->setHasRedeclaration(Record.readInt());
+  if (MD->hasRedeclaration())
 Reader.getContext().setObjCMethodRedeclaration(MD,
ReadDeclAs());
 
   MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record.readInt());
   MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record.readInt());
-  MD->SetRelatedResultType(Record.readInt());
+  MD->setRelatedResultType(Record.readInt());
   MD->setReturnType(Record.readType());
   MD->setReturnTypeSourceInfo(GetTypeSourceInfo());
   MD->DeclEndLoc = ReadSourceLocation();
@@ -1023,7 +1023,7 @@
   for (unsigned I = 0; I != NumParams; ++I)
 Params.push_back(ReadDeclAs());
 
-  MD->SelLocsKind = Record.readInt();
+  MD->setSelLocsKind((SelectorLocationsKind)Record.readInt());
   unsigned NumStoredSelLocs = Record.readInt();
   SmallVector SelLocs;
   SelLocs.reserve(NumStoredSelLocs);
Index: lib/Sema/SemaDeclObjC.cpp
===
--- lib/Sema/SemaDeclObjC.cpp
+++ lib/Sema/SemaDeclObjC.cpp
@@ -4333,7 +4333,7 @@
 
 // Propagate down the 'related result type' bit from overridden methods.
 if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
-  ObjCMethod->SetRelatedResultType();
+  ObjCMethod->setRelatedResultType();
 
 // Then merge the declarations.
 mergeObjCMethodDecls(ObjCMethod, overridden);
@@ -4712,7 +4712,7 @@
 
 if (InferRelatedResultType &&
 !ObjCMethod->getReturnType()->isObjCIndependentClassType())
-  ObjCMethod->SetRelatedResultType();
+  ObjCMethod->setRelatedResultType();
   }
 
   if (MethodDefinition &&
Index: lib/AST/DeclObjC.cpp
===
--- lib/AST/DeclObjC.cpp
+++ lib/AST/DeclObjC.cpp
@@ -65,6 +65,13 @@
 // ObjCInterfaceDecl
 //===--===//
 
+ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,
+ IdentifierInfo *Id, SourceLocation nameLoc,
+ SourceLocation atStartLoc)
+: NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
+  setAtStartLoc(atStartLoc);
+}
+
 void ObjCContainerDecl::anchor() {}
 
 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
@@ -769,6 +776,44 @@
 // ObjCMethodDecl
 //===--===//
 
+ObjCMethodDecl::ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
+   Selector SelInfo, QualType T,
+   TypeSourceInfo *ReturnTInfo,
+   DeclContext *contextDecl, bool isInst

[PATCH] D49790: [AST] Small doc update for DeclContext

2018-07-26 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157505.
bricci edited the summary of this revision.
bricci added a comment.

Re-added the "friend class ASTWriter" after making
hasNeedToReconcileExternalVisibleStorage, hasLazyLocalLexicalLookups
and hasLazyExternalLexicalLookups in DeclContext private.

This match the original situation where 
HasNeedToReconcileExternalVisibleStorage,
HasLazyLocalLexicalLookups and HasLazyLocalLexicalLookups in DeclContext
were private. This now depends on https://reviews.llvm.org/D49729


Repository:
  rC Clang

https://reviews.llvm.org/D49790

Files:
  include/clang/AST/DeclBase.h


Index: include/clang/AST/DeclBase.h
===
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -1250,16 +1250,29 @@
 /// that directly derive from DeclContext are mentioned, not their subclasses):
 ///
 ///   TranslationUnitDecl
+///   ExternCContext
 ///   NamespaceDecl
-///   FunctionDecl
 ///   TagDecl
+///   OMPDeclareReductionDecl
+///   FunctionDecl
 ///   ObjCMethodDecl
 ///   ObjCContainerDecl
 ///   LinkageSpecDecl
 ///   ExportDecl
 ///   BlockDecl
-///   OMPDeclareReductionDecl
+///   CapturedDecl
 class DeclContext {
+  /// For makeDeclVisibleInContextImpl
+  friend class ASTDeclReader;
+  /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap,
+  /// hasNeedToReconcileExternalVisibleStorage
+  friend class ExternalASTSource;
+  /// For CreateStoredDeclsMap
+  friend class DependentDiagnostic;
+  /// For hasNeedToReconcileExternalVisibleStorage,
+  /// hasLazyLocalLexicalLookups, hasLazyExternalLexicalLookups
+  friend class ASTWriter;
+
   // We use uint64_t in the bit-fields below since some bit-fields
   // cross the unsigned boundary and this breaks the packing.
 
@@ -1716,10 +1729,6 @@
   "BlockDeclBitfields is larger than 8 bytes!");
   };
 
-  friend class ASTDeclReader;
-  friend class ASTWriter;
-  friend class ExternalASTSource;
-
   /// FirstDecl - The first declaration stored within this declaration
   /// context.
   mutable Decl *FirstDecl = nullptr;
@@ -2398,8 +2407,6 @@
 DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
   }
 
-  friend class DependentDiagnostic;
-
   void reconcileExternalVisibleStorage() const;
   bool LoadLexicalDeclsFromExternalStorage() const;
 


Index: include/clang/AST/DeclBase.h
===
--- include/clang/AST/DeclBase.h
+++ include/clang/AST/DeclBase.h
@@ -1250,16 +1250,29 @@
 /// that directly derive from DeclContext are mentioned, not their subclasses):
 ///
 ///   TranslationUnitDecl
+///   ExternCContext
 ///   NamespaceDecl
-///   FunctionDecl
 ///   TagDecl
+///   OMPDeclareReductionDecl
+///   FunctionDecl
 ///   ObjCMethodDecl
 ///   ObjCContainerDecl
 ///   LinkageSpecDecl
 ///   ExportDecl
 ///   BlockDecl
-///   OMPDeclareReductionDecl
+///   CapturedDecl
 class DeclContext {
+  /// For makeDeclVisibleInContextImpl
+  friend class ASTDeclReader;
+  /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap,
+  /// hasNeedToReconcileExternalVisibleStorage
+  friend class ExternalASTSource;
+  /// For CreateStoredDeclsMap
+  friend class DependentDiagnostic;
+  /// For hasNeedToReconcileExternalVisibleStorage,
+  /// hasLazyLocalLexicalLookups, hasLazyExternalLexicalLookups
+  friend class ASTWriter;
+
   // We use uint64_t in the bit-fields below since some bit-fields
   // cross the unsigned boundary and this breaks the packing.
 
@@ -1716,10 +1729,6 @@
   "BlockDeclBitfields is larger than 8 bytes!");
   };
 
-  friend class ASTDeclReader;
-  friend class ASTWriter;
-  friend class ExternalASTSource;
-
   /// FirstDecl - The first declaration stored within this declaration
   /// context.
   mutable Decl *FirstDecl = nullptr;
@@ -2398,8 +2407,6 @@
 DeclContextBits.HasLazyExternalLexicalLookups = HasLELL;
   }
 
-  friend class DependentDiagnostic;
-
   void reconcileExternalVisibleStorage() const;
   bool LoadLexicalDeclsFromExternalStorage() const;
 
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-07-26 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 157522.
bricci marked 2 inline comments as done.
bricci added a comment.

- Re-based: r337978 [ODRHash] Support hashing enums added an ODRHash to 
EnumDecl which conflicts with these changes. The corresponding flag HasODRHash 
has been put into EnumDeclBitfields.
- The ugly IntegerType = (const Type *)nullptr; has been cleaned to IntegerType 
= nullptr; I guess the intent was to disambiguate between the two possible 
operator= but there is a special case for nullptr so this is not needed since 
const Type * is the first element of the pair.
- Made hasNeedToReconcileExternalVisibleStorage, hasLazyLocalLexicalLookups and 
hasLazyExternalLexicalLookups private. This match what was originally the case 
with the private bit-fields. This also requires making ASTWriter a friend of 
DeclContext (as was the case before).
- Fixed some comments in EnumDecl.


Repository:
  rC Clang

https://reviews.llvm.org/D49729

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1275,7 +1275,7 @@
 
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  if (D->IsCompleteDefinition)
+  if (D->isCompleteDefinition())
 Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 
   Code = serialization::DECL_CXX_RECORD;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,8 @@
 
 bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
-  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage;
+  return Result.hasExternalDecls() &&
+ DC->hasNeedToReconcileExternalVisibleStorage();
 }
 
 bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
@@ -3975,8 +3976,8 @@
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl &LookupTable) {
-  assert(!ConstDC->HasLazyLocalLexicalLookups &&
- !ConstDC->HasLazyExternalLexicalLookups &&
+  assert(!ConstDC->hasLazyLocalLexicalLookups() &&
+ !ConstDC->hasLazyExternalLexicalLookups() &&
  "must call buildLookups first");
 
   // FIXME: We need to build the lookups table, which is logically const.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,16 +742,16 @@
   ED->setPromotionType(Record.readType());
   ED->setNumPositiveBits(Record.readInt());
   ED->setNumNegativeBits(Record.readInt());
-  ED->IsScoped = Record.readInt();
-  ED->IsScopedUsingClassTag = Record.readInt();
-  ED->IsFixed = Record.readInt();
+  ED->setScoped(Record.readInt());
+  ED->setScopedUsingClassTag(Record.readInt());
+  ED->setFixed(Record.readInt());
 
-  ED->HasODRHash = true;
+  ED->setHasODRHash(true);
   ED->ODRHash = Record.readInt();
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->IsCompleteDefinition &&
+  if (ED->isCompleteDefinition() &&
   Reader.getContext().getLangOpts().Modules &&
   Reader.getContext().getLangOpts().CPlusPlus) {
 EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
@@ -767,7 +767,7 @@
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->IsCompleteDefinition = false;
+  ED->setCompleteDefinition(false);
   Reader.mergeDefinitionVisibility(OldDef, ED);
   if (OldDef->getODRHash() != ED->getODRHash())
 Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
@@ -1744,7 +1744,7 @@
 Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
 DD.Definition));
 Reader.PendingDefinitions.erase(MergeDD.Definition);
-MergeDD.Definition->IsCompleteDefinition = false;
+MergeDD.Definition->setCompleteDefinition(false);
 Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
 assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
"already loaded pending lookups for merged definition");
@@ -1884,7 +1884,7 @@
   }
 
   // Mark this declaration as being a definition.
-  D->IsCompleteDefinition = true;
+  D->setCompleteDefinition(true);
 
   // If this is not the first declaration or is an update record

[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-08-01 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 158498.
bricci added a comment.

rebased after the great whitespace trimming


Repository:
  rC Clang

https://reviews.llvm.org/D49729

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclBase.h
  lib/AST/Decl.cpp
  lib/AST/DeclBase.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclTemplate.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriter.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1275,7 +1275,7 @@
 
   // Store (what we currently believe to be) the key function to avoid
   // deserializing every method so we can compute it.
-  if (D->IsCompleteDefinition)
+  if (D->isCompleteDefinition())
 Record.AddDeclRef(Context.getCurrentKeyFunction(D));
 
   Code = serialization::DECL_CXX_RECORD;
Index: lib/Serialization/ASTWriter.cpp
===
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -3960,7 +3960,8 @@
 
 bool ASTWriter::isLookupResultExternal(StoredDeclsList &Result,
DeclContext *DC) {
-  return Result.hasExternalDecls() && DC->NeedToReconcileExternalVisibleStorage;
+  return Result.hasExternalDecls() &&
+ DC->hasNeedToReconcileExternalVisibleStorage();
 }
 
 bool ASTWriter::isLookupResultEntirelyExternal(StoredDeclsList &Result,
@@ -3975,8 +3976,8 @@
 void
 ASTWriter::GenerateNameLookupTable(const DeclContext *ConstDC,
llvm::SmallVectorImpl &LookupTable) {
-  assert(!ConstDC->HasLazyLocalLexicalLookups &&
- !ConstDC->HasLazyExternalLexicalLookups &&
+  assert(!ConstDC->hasLazyLocalLexicalLookups() &&
+ !ConstDC->hasLazyExternalLexicalLookups() &&
  "must call buildLookups first");
 
   // FIXME: We need to build the lookups table, which is logically const.
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -742,16 +742,16 @@
   ED->setPromotionType(Record.readType());
   ED->setNumPositiveBits(Record.readInt());
   ED->setNumNegativeBits(Record.readInt());
-  ED->IsScoped = Record.readInt();
-  ED->IsScopedUsingClassTag = Record.readInt();
-  ED->IsFixed = Record.readInt();
+  ED->setScoped(Record.readInt());
+  ED->setScopedUsingClassTag(Record.readInt());
+  ED->setFixed(Record.readInt());
 
-  ED->HasODRHash = true;
+  ED->setHasODRHash(true);
   ED->ODRHash = Record.readInt();
 
   // If this is a definition subject to the ODR, and we already have a
   // definition, merge this one into it.
-  if (ED->IsCompleteDefinition &&
+  if (ED->isCompleteDefinition() &&
   Reader.getContext().getLangOpts().Modules &&
   Reader.getContext().getLangOpts().CPlusPlus) {
 EnumDecl *&OldDef = Reader.EnumDefinitions[ED->getCanonicalDecl()];
@@ -767,7 +767,7 @@
 }
 if (OldDef) {
   Reader.MergedDeclContexts.insert(std::make_pair(ED, OldDef));
-  ED->IsCompleteDefinition = false;
+  ED->setCompleteDefinition(false);
   Reader.mergeDefinitionVisibility(OldDef, ED);
   if (OldDef->getODRHash() != ED->getODRHash())
 Reader.PendingEnumOdrMergeFailures[OldDef].push_back(ED);
@@ -1744,7 +1744,7 @@
 Reader.MergedDeclContexts.insert(std::make_pair(MergeDD.Definition,
 DD.Definition));
 Reader.PendingDefinitions.erase(MergeDD.Definition);
-MergeDD.Definition->IsCompleteDefinition = false;
+MergeDD.Definition->setCompleteDefinition(false);
 Reader.mergeDefinitionVisibility(DD.Definition, MergeDD.Definition);
 assert(Reader.Lookups.find(MergeDD.Definition) == Reader.Lookups.end() &&
"already loaded pending lookups for merged definition");
@@ -1884,7 +1884,7 @@
   }
 
   // Mark this declaration as being a definition.
-  D->IsCompleteDefinition = true;
+  D->setCompleteDefinition(true);
 
   // If this is not the first declaration or is an update record, we can have
   // other redeclarations already. Make a note that we need to propagate the
@@ -1946,7 +1946,7 @@
   // compute it.
   if (WasDefinition) {
 DeclID KeyFn = ReadDeclID();
-if (KeyFn && D->IsCompleteDefinition)
+if (KeyFn && D->isCompleteDefinition())
   // FIXME: This is wrong for the ARM ABI, where some other module may have
   // made this function no longer be a key function. We need an update
   // record or similar for that case.
@@ -3076,7 +3076,7 @@
 // we load the update record.
 if (!DD) {
   DD = new (Reader.getContext()) struct CXXRecordDecl::DefinitionData(RD);
-  RD->IsCompleteDefinition = true;
+  RD->setCompleteDefinition(true);
   RD->DefinitionData = DD;
   RD->getCanonicalDecl()->Definiti

[PATCH] D49734: [AST][4/4] Move the bit-fields from ObjCMethodDecl and ObjCContainerDecl into DeclContext

2018-08-01 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 158499.
bricci added a comment.

rebased after the great whitespace trimming


Repository:
  rC Clang

https://reviews.llvm.org/D49734

Files:
  include/clang/AST/DeclObjC.h
  lib/AST/DeclObjC.cpp
  lib/Sema/SemaDeclObjC.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -647,12 +647,12 @@
   Record.push_back(D->isVariadic());
   Record.push_back(D->isPropertyAccessor());
   Record.push_back(D->isDefined());
-  Record.push_back(D->IsOverriding);
-  Record.push_back(D->HasSkippedBody);
+  Record.push_back(D->isOverriding());
+  Record.push_back(D->hasSkippedBody());
 
-  Record.push_back(D->IsRedeclaration);
-  Record.push_back(D->HasRedeclaration);
-  if (D->HasRedeclaration) {
+  Record.push_back(D->isRedeclaration());
+  Record.push_back(D->hasRedeclaration());
+  if (D->hasRedeclaration()) {
 assert(Context.getObjCMethodRedeclaration(D));
 Record.AddDeclRef(Context.getObjCMethodRedeclaration(D));
   }
@@ -669,7 +669,7 @@
   for (const auto *P : D->parameters())
 Record.AddDeclRef(P);
 
-  Record.push_back(D->SelLocsKind);
+  Record.push_back(D->getSelLocsKind());
   unsigned NumStoredSelLocs = D->getNumStoredSelLocs();
   SourceLocation *SelLocs = D->getStoredSelLocs();
   Record.push_back(NumStoredSelLocs);
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -1007,18 +1007,18 @@
   MD->setVariadic(Record.readInt());
   MD->setPropertyAccessor(Record.readInt());
   MD->setDefined(Record.readInt());
-  MD->IsOverriding = Record.readInt();
-  MD->HasSkippedBody = Record.readInt();
+  MD->setOverriding(Record.readInt());
+  MD->setHasSkippedBody(Record.readInt());
 
-  MD->IsRedeclaration = Record.readInt();
-  MD->HasRedeclaration = Record.readInt();
-  if (MD->HasRedeclaration)
+  MD->setIsRedeclaration(Record.readInt());
+  MD->setHasRedeclaration(Record.readInt());
+  if (MD->hasRedeclaration())
 Reader.getContext().setObjCMethodRedeclaration(MD,
ReadDeclAs());
 
   MD->setDeclImplementation((ObjCMethodDecl::ImplementationControl)Record.readInt());
   MD->setObjCDeclQualifier((Decl::ObjCDeclQualifier)Record.readInt());
-  MD->SetRelatedResultType(Record.readInt());
+  MD->setRelatedResultType(Record.readInt());
   MD->setReturnType(Record.readType());
   MD->setReturnTypeSourceInfo(GetTypeSourceInfo());
   MD->DeclEndLoc = ReadSourceLocation();
@@ -1028,7 +1028,7 @@
   for (unsigned I = 0; I != NumParams; ++I)
 Params.push_back(ReadDeclAs());
 
-  MD->SelLocsKind = Record.readInt();
+  MD->setSelLocsKind((SelectorLocationsKind)Record.readInt());
   unsigned NumStoredSelLocs = Record.readInt();
   SmallVector SelLocs;
   SelLocs.reserve(NumStoredSelLocs);
Index: lib/Sema/SemaDeclObjC.cpp
===
--- lib/Sema/SemaDeclObjC.cpp
+++ lib/Sema/SemaDeclObjC.cpp
@@ -4351,7 +4351,7 @@
 
 // Propagate down the 'related result type' bit from overridden methods.
 if (RTC != Sema::RTC_Incompatible && overridden->hasRelatedResultType())
-  ObjCMethod->SetRelatedResultType();
+  ObjCMethod->setRelatedResultType();
 
 // Then merge the declarations.
 mergeObjCMethodDecls(ObjCMethod, overridden);
@@ -4746,7 +4746,7 @@
 
 if (InferRelatedResultType &&
 !ObjCMethod->getReturnType()->isObjCIndependentClassType())
-  ObjCMethod->SetRelatedResultType();
+  ObjCMethod->setRelatedResultType();
   }
 
   if (MethodDefinition &&
Index: lib/AST/DeclObjC.cpp
===
--- lib/AST/DeclObjC.cpp
+++ lib/AST/DeclObjC.cpp
@@ -65,6 +65,13 @@
 // ObjCInterfaceDecl
 //===--===//
 
+ObjCContainerDecl::ObjCContainerDecl(Kind DK, DeclContext *DC,
+ IdentifierInfo *Id, SourceLocation nameLoc,
+ SourceLocation atStartLoc)
+: NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK) {
+  setAtStartLoc(atStartLoc);
+}
+
 void ObjCContainerDecl::anchor() {}
 
 /// getIvarDecl - This method looks up an ivar in this ContextDecl.
@@ -769,6 +776,44 @@
 // ObjCMethodDecl
 //===--===//
 
+ObjCMethodDecl::ObjCMethodDecl(SourceLocation beginLoc, SourceLocation endLoc,
+   Selector SelInfo, QualType T,
+   TypeSourceInfo *ReturnTInfo,
+   DeclContext *contextDecl, bool isInstance,
+   bool isVariadic, bool isPropertyAccessor,
+   

[PATCH] D49733: [AST][3/4] Move the bit-fields from BlockDecl, LinkageSpecDecl and OMPDeclareReductionDecl into DeclContext

2018-08-01 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 158500.
bricci added a comment.

rebased after the great whitespace trimming


Repository:
  rC Clang

https://reviews.llvm.org/D49733

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  include/clang/AST/DeclOpenMP.h
  lib/AST/Decl.cpp
  lib/AST/DeclCXX.cpp
  lib/AST/DeclOpenMP.cpp

Index: lib/AST/DeclOpenMP.cpp
===
--- lib/AST/DeclOpenMP.cpp
+++ lib/AST/DeclOpenMP.cpp
@@ -57,6 +57,14 @@
 // OMPDeclareReductionDecl Implementation.
 //===--===//
 
+OMPDeclareReductionDecl::OMPDeclareReductionDecl(
+Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name,
+QualType Ty, OMPDeclareReductionDecl *PrevDeclInScope)
+: ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
+  PrevDeclInScope(PrevDeclInScope) {
+  setInitializer(nullptr, CallInit);
+}
+
 void OMPDeclareReductionDecl::anchor() {}
 
 OMPDeclareReductionDecl *OMPDeclareReductionDecl::Create(
Index: lib/AST/DeclCXX.cpp
===
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -2466,6 +2466,15 @@
  getConversionType()->isBlockPointerType();
 }
 
+LinkageSpecDecl::LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc,
+ SourceLocation LangLoc, LanguageIDs lang,
+ bool HasBraces)
+: Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec),
+  ExternLoc(ExternLoc), RBraceLoc(SourceLocation()) {
+  setLanguage(lang);
+  LinkageSpecDeclBits.HasBraces = HasBraces;
+}
+
 void LinkageSpecDecl::anchor() {}
 
 LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C,
Index: lib/AST/Decl.cpp
===
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -4215,6 +4215,15 @@
 // BlockDecl Implementation
 //===--===//
 
+BlockDecl::BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+: Decl(Block, DC, CaretLoc), DeclContext(Block) {
+  setIsVariadic(false);
+  setCapturesCXXThis(false);
+  setBlockMissingReturnType(true);
+  setIsConversionFromLambda(false);
+  setDoesNotEscape(false);
+}
+
 void BlockDecl::setParams(ArrayRef NewParamInfo) {
   assert(!ParamInfo && "Already has param info!");
 
@@ -4228,7 +4237,7 @@
 
 void BlockDecl::setCaptures(ASTContext &Context, ArrayRef Captures,
 bool CapturesCXXThis) {
-  this->CapturesCXXThis = CapturesCXXThis;
+  this->setCapturesCXXThis(CapturesCXXThis);
   this->NumCaptures = Captures.size();
 
   if (Captures.empty()) {
Index: include/clang/AST/DeclOpenMP.h
===
--- include/clang/AST/DeclOpenMP.h
+++ include/clang/AST/DeclOpenMP.h
@@ -100,6 +100,8 @@
 ///
 /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer.
 class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
+  // This class stores some data in DeclContext::OMPDeclareReductionDeclBits
+  // to save some space. Use the provided accessors to access it.
 public:
   enum InitKind {
 CallInit,   // Initialized by function call.
@@ -113,8 +115,6 @@
   Expr *Combiner;
   /// Initializer for declare reduction construct.
   Expr *Initializer;
-  /// Kind of initializer - function call or omp_priv initializtion.
-  InitKind InitializerKind = CallInit;
 
   /// Reference to the previous declare reduction construct in the same
   /// scope with the same name. Required for proper templates instantiation if
@@ -125,10 +125,7 @@
 
   OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L,
   DeclarationName Name, QualType Ty,
-  OMPDeclareReductionDecl *PrevDeclInScope)
-  : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr),
-Initializer(nullptr), InitializerKind(CallInit),
-PrevDeclInScope(PrevDeclInScope) {}
+  OMPDeclareReductionDecl *PrevDeclInScope);
 
   void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) {
 PrevDeclInScope = Prev;
@@ -154,11 +151,13 @@
   Expr *getInitializer() { return Initializer; }
   const Expr *getInitializer() const { return Initializer; }
   /// Get initializer kind.
-  InitKind getInitializerKind() const { return InitializerKind; }
+  InitKind getInitializerKind() const {
+return static_cast(OMPDeclareReductionDeclBits.InitializerKind);
+  }
   /// Set initializer expression for the declare reduction construct.
   void setInitializer(Expr *E, InitKind IK) {
 Initializer = E;
-InitializerKind = IK;
+OMPDeclareReductionDeclBits.InitializerKind = IK;
   }
 
   /// Get reference to previous declare reduction construct in the same
Index: include/clang/AST/DeclCXX.h
===

[PATCH] D49732: [AST][2/4] Move the bit-fields from FunctionDecl and CXXConstructorDecl into DeclContext

2018-08-01 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 158501.
bricci added a comment.

rebased after the great whitespace trimming


Repository:
  rC Clang

https://reviews.llvm.org/D49732

Files:
  include/clang/AST/Decl.h
  include/clang/AST/DeclCXX.h
  lib/AST/Decl.cpp
  lib/AST/DeclCXX.cpp
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp

Index: lib/Serialization/ASTWriterDecl.cpp
===
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -529,26 +529,25 @@
 
   // FunctionDecl's body is handled last at ASTWriterDecl::Visit,
   // after everything else is written.
-
-  Record.push_back((int)D->SClass); // FIXME: stable encoding
-  Record.push_back(D->IsInline);
-  Record.push_back(D->IsInlineSpecified);
-  Record.push_back(D->IsExplicitSpecified);
-  Record.push_back(D->IsVirtualAsWritten);
-  Record.push_back(D->IsPure);
-  Record.push_back(D->HasInheritedPrototype);
-  Record.push_back(D->HasWrittenPrototype);
-  Record.push_back(D->IsDeleted);
-  Record.push_back(D->IsTrivial);
-  Record.push_back(D->IsTrivialForCall);
-  Record.push_back(D->IsDefaulted);
-  Record.push_back(D->IsExplicitlyDefaulted);
-  Record.push_back(D->HasImplicitReturnZero);
-  Record.push_back(D->IsConstexpr);
-  Record.push_back(D->UsesSEHTry);
-  Record.push_back(D->HasSkippedBody);
-  Record.push_back(D->IsMultiVersion);
-  Record.push_back(D->IsLateTemplateParsed);
+  Record.push_back(static_cast(D->getStorageClass())); // FIXME: stable encoding
+  Record.push_back(D->isInlineSpecified());
+  Record.push_back(D->isInlined());
+  Record.push_back(D->isExplicitSpecified());
+  Record.push_back(D->isVirtualAsWritten());
+  Record.push_back(D->isPure());
+  Record.push_back(D->hasInheritedPrototype());
+  Record.push_back(D->hasWrittenPrototype());
+  Record.push_back(D->isDeletedBit());
+  Record.push_back(D->isTrivial());
+  Record.push_back(D->isTrivialForCall());
+  Record.push_back(D->isDefaulted());
+  Record.push_back(D->isExplicitlyDefaulted());
+  Record.push_back(D->hasImplicitReturnZero());
+  Record.push_back(D->isConstexpr());
+  Record.push_back(D->usesSEHTry());
+  Record.push_back(D->hasSkippedBody());
+  Record.push_back(D->isMultiVersion());
+  Record.push_back(D->isLateTemplateParsed());
   Record.push_back(D->getLinkageInternal());
   Record.AddSourceLocation(D->getLocEnd());
 
@@ -628,7 +627,7 @@
 
 void ASTDeclWriter::VisitCXXDeductionGuideDecl(CXXDeductionGuideDecl *D) {
   VisitFunctionDecl(D);
-  Record.push_back(D->IsCopyDeductionCandidate);
+  Record.push_back(D->isCopyDeductionCandidate());
   Code = serialization::DECL_CXX_DEDUCTION_GUIDE;
 }
 
Index: lib/Serialization/ASTReaderDecl.cpp
===
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -506,8 +506,8 @@
   if (Record.readInt())
 Reader.DefinitionSource[FD] = Loc.F->Kind == ModuleKind::MK_MainFile;
   if (auto *CD = dyn_cast(FD)) {
-CD->NumCtorInitializers = Record.readInt();
-if (CD->NumCtorInitializers)
+CD->setNumCtorInitializers(Record.readInt());
+if (CD->getNumCtorInitializers())
   CD->CtorInitializers = ReadGlobalOffset();
   }
   // Store the offset of the body so we can lazily load it later.
@@ -855,30 +855,31 @@
   // FunctionDecl's body is handled last at ASTDeclReader::Visit,
   // after everything else is read.
 
-  FD->SClass = (StorageClass)Record.readInt();
-  FD->IsInline = Record.readInt();
-  FD->IsInlineSpecified = Record.readInt();
-  FD->IsExplicitSpecified = Record.readInt();
-  FD->IsVirtualAsWritten = Record.readInt();
-  FD->IsPure = Record.readInt();
-  FD->HasInheritedPrototype = Record.readInt();
-  FD->HasWrittenPrototype = Record.readInt();
-  FD->IsDeleted = Record.readInt();
-  FD->IsTrivial = Record.readInt();
-  FD->IsTrivialForCall = Record.readInt();
-  FD->IsDefaulted = Record.readInt();
-  FD->IsExplicitlyDefaulted = Record.readInt();
-  FD->HasImplicitReturnZero = Record.readInt();
-  FD->IsConstexpr = Record.readInt();
-  FD->UsesSEHTry = Record.readInt();
-  FD->HasSkippedBody = Record.readInt();
-  FD->IsMultiVersion = Record.readInt();
-  FD->IsLateTemplateParsed = Record.readInt();
-  FD->setCachedLinkage(Linkage(Record.readInt()));
+  FD->setStorageClass(static_cast(Record.readInt()));
+  FD->setInlineSpecified(Record.readInt());
+  FD->setImplicitlyInline(Record.readInt());
+  FD->setExplicitSpecified(Record.readInt());
+  FD->setVirtualAsWritten(Record.readInt());
+  FD->setPure(Record.readInt());
+  FD->setHasInheritedPrototype(Record.readInt());
+  FD->setHasWrittenPrototype(Record.readInt());
+  FD->setDeletedAsWritten(Record.readInt());
+  FD->setTrivial(Record.readInt());
+  FD->setTrivialForCall(Record.readInt());
+  FD->setDefaulted(Record.readInt());
+  FD->setExplicitlyDefaulted(Record.readInt());
+  FD->setHasImplicitReturnZero(Record.readInt());
+  FD->setConstexpr(Re

[PATCH] D49729: [AST][1/4] Move the bit-fields from TagDecl, EnumDecl and RecordDecl into DeclContext

2018-08-01 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

@erichkeane do you have any additional comments regarding this set of patches ?
I retested them on top of trunk and did not find any problem.


Repository:
  rC Clang

https://reviews.llvm.org/D49729



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50163: [AST] Remove the static_assert check in ObjCMethodDecl::ObjCMethodDecl

2018-08-01 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

This check was introduced by r338641
but this broke some builds. For now remove it.


Repository:
  rC Clang

https://reviews.llvm.org/D50163

Files:
  lib/AST/DeclObjC.cpp


Index: lib/AST/DeclObjC.cpp
===
--- lib/AST/DeclObjC.cpp
+++ lib/AST/DeclObjC.cpp
@@ -787,13 +787,6 @@
 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
   DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),
   DeclEndLoc(endLoc) {
-  // See the comment in ObjCMethodFamilyBitfields about
-  // ObjCMethodFamilyBitWidth for why we check this.
-  static_assert(
-  static_cast(ObjCMethodDeclBits.ObjCMethodFamilyBitWidth) ==
-  static_cast(ObjCMethodFamilyBitWidth),
-  "ObjCMethodDeclBitfields::ObjCMethodFamilyBitWidth and "
-  "ObjCMethodFamilyBitWidth do not match!");
 
   // Initialized the bits stored in DeclContext.
   ObjCMethodDeclBits.Family =


Index: lib/AST/DeclObjC.cpp
===
--- lib/AST/DeclObjC.cpp
+++ lib/AST/DeclObjC.cpp
@@ -787,13 +787,6 @@
 : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo),
   DeclContext(ObjCMethod), MethodDeclType(T), ReturnTInfo(ReturnTInfo),
   DeclEndLoc(endLoc) {
-  // See the comment in ObjCMethodFamilyBitfields about
-  // ObjCMethodFamilyBitWidth for why we check this.
-  static_assert(
-  static_cast(ObjCMethodDeclBits.ObjCMethodFamilyBitWidth) ==
-  static_cast(ObjCMethodFamilyBitWidth),
-  "ObjCMethodDeclBitfields::ObjCMethodFamilyBitWidth and "
-  "ObjCMethodFamilyBitWidth do not match!");
 
   // Initialized the bits stored in DeclContext.
   ObjCMethodDeclBits.Family =
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50163: [AST] Remove the static_assert check in ObjCMethodDecl::ObjCMethodDecl

2018-08-02 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

The static_assert itself cannot be in the bitfield since the whole point is to 
avoid including Basic/IdentifierTable.h just for this.

I originally put the static_assert in ObjCMethodDecl and everything worked fine 
when tested with GCC but I then saw just
after you committed it that it broke some builds. Therefore for the moment I 
just removed it (and had to beg someone on IRC to commit it )

However  I think that we can simply add it to the definition of the class 
ObjCMethodDecl with a comment both in the bitfield
and in ObjCMethodDecl which explains why we checks this. The problem was not 
the location of the static_assert, but the fact that
even though the member ObjCMethodDeclBits is protected the nested class 
ObjCMethodDeclBitfields is private. However I think tha
we can just use something like

`static_assert(decltype(ObjCMethodDeclBits)::ObjCMethodFamilyBitWidth == 
ObjCMethodFamilyBitWidth, "blablabla")`


Repository:
  rC Clang

https://reviews.llvm.org/D50163



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50261: [AST] Remove unnecessary indirections in DeclarationNameTable

2018-08-03 Thread Bruno Ricci via Phabricator via cfe-commits
bricci created this revision.
bricci added reviewers: erichkeane, rsmith, rnk.
bricci added a project: clang.
Herald added a subscriber: cfe-commits.

DeclarationNameTable currently hold 3 void * to
FoldingSet, FoldingSet
and FoldingSet.

CXXSpecialName,  CXXLiteralOperatorIdName and
CXXDeductionGuideNameExtra are private classes holding extra
information about a "special" declaration name and are in the 
DeclarationName.cpp
The original intent seems to have been to keep these class private and only 
expose
DeclarationNameExtra and DeclarationName (the code dates from 2008 and
has not been significantly changed since).

However this make the code less straightforward than necessary because of
the need to have void* in DeclarationNameTable (with 1 of 3 comments wrong)
and to manually allocate/deallocate the FoldingSets.

Moreover removing the extra indirections reduce the run-time of an fsyntax-only 
on
all of Boost by 2.3% which is not totally unexpected given how frequently this
data structure is used.

Comments:

- For now I just moved the classes which were in DeclarationName.cpp to 
DeclarationName.h. We could find a way to hide them if desired, eg by stuffing 
them into a namespace detail or something...
- This requires including Type.h...


Repository:
  rC Clang

https://reviews.llvm.org/D50261

Files:
  include/clang/AST/DeclarationName.h
  lib/AST/DeclarationName.cpp

Index: lib/AST/DeclarationName.cpp
===
--- lib/AST/DeclarationName.cpp
+++ lib/AST/DeclarationName.cpp
@@ -39,74 +39,6 @@
 
 using namespace clang;
 
-namespace clang {
-
-/// CXXSpecialName - Records the type associated with one of the
-/// "special" kinds of declaration names in C++, e.g., constructors,
-/// destructors, and conversion functions.
-class CXXSpecialName
-  : public DeclarationNameExtra, public llvm::FoldingSetNode {
-public:
-  /// Type - The type associated with this declaration name.
-  QualType Type;
-
-  /// FETokenInfo - Extra information associated with this declaration
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-
-  void Profile(llvm::FoldingSetNodeID &ID) {
-ID.AddInteger(ExtraKindOrNumArgs);
-ID.AddPointer(Type.getAsOpaquePtr());
-  }
-};
-
-/// Contains extra information for the name of a C++ deduction guide.
-class CXXDeductionGuideNameExtra : public DeclarationNameExtra,
-   public llvm::FoldingSetNode {
-public:
-  /// The template named by the deduction guide.
-  TemplateDecl *Template;
-
-  /// FETokenInfo - Extra information associated with this operator
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-
-  void Profile(llvm::FoldingSetNodeID &ID) {
-ID.AddPointer(Template);
-  }
-};
-
-/// CXXOperatorIdName - Contains extra information for the name of an
-/// overloaded operator in C++, such as "operator+.
-class CXXOperatorIdName : public DeclarationNameExtra {
-public:
-  /// FETokenInfo - Extra information associated with this operator
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-};
-
-/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
-/// name.
-///
-/// This identifier is stored here rather than directly in DeclarationName so as
-/// to allow Objective-C selectors, which are about a million times more common,
-/// to consume minimal memory.
-class CXXLiteralOperatorIdName
-  : public DeclarationNameExtra, public llvm::FoldingSetNode {
-public:
-  IdentifierInfo *ID;
-
-  /// FETokenInfo - Extra information associated with this operator
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-
-  void Profile(llvm::FoldingSetNodeID &FSID) {
-FSID.AddPointer(ID);
-  }
-};
-
-} // namespace clang
-
 static int compareInt(unsigned A, unsigned B) {
   return (A < B ? -1 : (A > B ? 1 : 0));
 }
@@ -436,10 +368,6 @@
 }
 
 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
-  CXXSpecialNamesImpl = new llvm::FoldingSet;
-  CXXLiteralOperatorNames = new llvm::FoldingSet;
-  CXXDeductionGuideNames = new llvm::FoldingSet;
-
   // Initialize the overloaded operator names.
   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
@@ -449,21 +377,6 @@
   }
 }
 
-DeclarationNameTable::~DeclarationNameTable() {
-  auto *SpecialNames =
-  static_cast *>(CXXSpecialNamesImpl);
-  auto *LiteralNames =
-  static_cast *>(
-  CXXLiteralOperatorNames);
-  auto *DeductionGuideNames =
-  static_cast *>(
-  CXXDeductionGuideNames);
-
-  delete SpecialNames;
-  delete LiteralNames;
-  delete DeductionGuideNames;
-}
-
 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
   return getCXXSpecialName(DeclarationName::CXXConstructorName,
Ty.getUnqualifiedType());
@@ -478,23 +391,19 @@
 DeclarationNameTable::getCXXDeductionGu

[PATCH] D50261: [AST] Remove unnecessary indirections in DeclarationNameTable

2018-08-03 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

It seems to me that the increased size of DeclarationNameTable is irrelevant 
since it is
only used as a member in ASTContext and never copied nor moved from. Also,
at least for C++ it seems to me that this structure is never "rarely used" 
since it is
used for every overloaded op/ctor/dtor (but I admit that I am not familiar with 
Sema)

I will do a comparison of the build time this evening. If this is a problem we 
can try to
find a way to avoid the QualType in CXXSpecialName (which is the reason why we 
need
Type.h) by replacing it by uintptr_t and doing some casts.


Repository:
  rC Clang

https://reviews.llvm.org/D50261



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50261: [AST] Remove unnecessary indirections in DeclarationNameTable

2018-08-03 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

Additionally I have taken a quick look at the headers which includes 
DeclarationName.h
and it seems that most of them already include Type.h (with the exception of 
DeclBase.h)

If so then the build time shouldn't change much but I will report if there is 
any significient difference.


Repository:
  rC Clang

https://reviews.llvm.org/D50261



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D50261: [AST] Remove unnecessary indirections in DeclarationNameTable

2018-08-03 Thread Bruno Ricci via Phabricator via cfe-commits
bricci updated this revision to Diff 159044.
bricci marked an inline comment as done.
bricci added a comment.

Added the deleted move ctors. (I think that they were already not declared 
because
of the user-provided copy ctor/assignment)

Will report the result about the build time but this will take some time :)


Repository:
  rC Clang

https://reviews.llvm.org/D50261

Files:
  include/clang/AST/DeclarationName.h
  lib/AST/DeclarationName.cpp

Index: lib/AST/DeclarationName.cpp
===
--- lib/AST/DeclarationName.cpp
+++ lib/AST/DeclarationName.cpp
@@ -39,74 +39,6 @@
 
 using namespace clang;
 
-namespace clang {
-
-/// CXXSpecialName - Records the type associated with one of the
-/// "special" kinds of declaration names in C++, e.g., constructors,
-/// destructors, and conversion functions.
-class CXXSpecialName
-  : public DeclarationNameExtra, public llvm::FoldingSetNode {
-public:
-  /// Type - The type associated with this declaration name.
-  QualType Type;
-
-  /// FETokenInfo - Extra information associated with this declaration
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-
-  void Profile(llvm::FoldingSetNodeID &ID) {
-ID.AddInteger(ExtraKindOrNumArgs);
-ID.AddPointer(Type.getAsOpaquePtr());
-  }
-};
-
-/// Contains extra information for the name of a C++ deduction guide.
-class CXXDeductionGuideNameExtra : public DeclarationNameExtra,
-   public llvm::FoldingSetNode {
-public:
-  /// The template named by the deduction guide.
-  TemplateDecl *Template;
-
-  /// FETokenInfo - Extra information associated with this operator
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-
-  void Profile(llvm::FoldingSetNodeID &ID) {
-ID.AddPointer(Template);
-  }
-};
-
-/// CXXOperatorIdName - Contains extra information for the name of an
-/// overloaded operator in C++, such as "operator+.
-class CXXOperatorIdName : public DeclarationNameExtra {
-public:
-  /// FETokenInfo - Extra information associated with this operator
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-};
-
-/// CXXLiteralOperatorName - Contains the actual identifier that makes up the
-/// name.
-///
-/// This identifier is stored here rather than directly in DeclarationName so as
-/// to allow Objective-C selectors, which are about a million times more common,
-/// to consume minimal memory.
-class CXXLiteralOperatorIdName
-  : public DeclarationNameExtra, public llvm::FoldingSetNode {
-public:
-  IdentifierInfo *ID;
-
-  /// FETokenInfo - Extra information associated with this operator
-  /// name that can be used by the front end.
-  void *FETokenInfo;
-
-  void Profile(llvm::FoldingSetNodeID &FSID) {
-FSID.AddPointer(ID);
-  }
-};
-
-} // namespace clang
-
 static int compareInt(unsigned A, unsigned B) {
   return (A < B ? -1 : (A > B ? 1 : 0));
 }
@@ -436,10 +368,6 @@
 }
 
 DeclarationNameTable::DeclarationNameTable(const ASTContext &C) : Ctx(C) {
-  CXXSpecialNamesImpl = new llvm::FoldingSet;
-  CXXLiteralOperatorNames = new llvm::FoldingSet;
-  CXXDeductionGuideNames = new llvm::FoldingSet;
-
   // Initialize the overloaded operator names.
   CXXOperatorNames = new (Ctx) CXXOperatorIdName[NUM_OVERLOADED_OPERATORS];
   for (unsigned Op = 0; Op < NUM_OVERLOADED_OPERATORS; ++Op) {
@@ -449,21 +377,6 @@
   }
 }
 
-DeclarationNameTable::~DeclarationNameTable() {
-  auto *SpecialNames =
-  static_cast *>(CXXSpecialNamesImpl);
-  auto *LiteralNames =
-  static_cast *>(
-  CXXLiteralOperatorNames);
-  auto *DeductionGuideNames =
-  static_cast *>(
-  CXXDeductionGuideNames);
-
-  delete SpecialNames;
-  delete LiteralNames;
-  delete DeductionGuideNames;
-}
-
 DeclarationName DeclarationNameTable::getCXXConstructorName(CanQualType Ty) {
   return getCXXSpecialName(DeclarationName::CXXConstructorName,
Ty.getUnqualifiedType());
@@ -478,23 +391,19 @@
 DeclarationNameTable::getCXXDeductionGuideName(TemplateDecl *Template) {
   Template = cast(Template->getCanonicalDecl());
 
-  auto *DeductionGuideNames =
-  static_cast *>(
-  CXXDeductionGuideNames);
-
   llvm::FoldingSetNodeID ID;
   ID.AddPointer(Template);
 
   void *InsertPos = nullptr;
-  if (auto *Name = DeductionGuideNames->FindNodeOrInsertPos(ID, InsertPos))
+  if (auto *Name = CXXDeductionGuideNames.FindNodeOrInsertPos(ID, InsertPos))
 return DeclarationName(Name);
 
   auto *Name = new (Ctx) CXXDeductionGuideNameExtra;
   Name->ExtraKindOrNumArgs = DeclarationNameExtra::CXXDeductionGuide;
   Name->Template = Template;
   Name->FETokenInfo = nullptr;
 
-  DeductionGuideNames->InsertNode(Name, InsertPos);
+  CXXDeductionGuideNames.InsertNode(Name, InsertPos);
   return DeclarationName(Name);
 }
 
@@ -509,8 +418,6 @@
   assert(Kind >= DeclarationName::CXXConstructorName &&
  Kind <= DeclarationName::CXXConversionFunctionName &&
  "Ki

[PATCH] D50261: [AST] Remove unnecessary indirections in DeclarationNameTable

2018-08-04 Thread Bruno Ricci via Phabricator via cfe-commits
bricci added a comment.

I did both a clean build and an incremental build with and without this patch 
and was not able to see any
meaningful difference in the build time. Suspiciously the build time *with* the 
patch in both cases is a little
less (~0.1% ) than without the patch but this is well within the noise. At 
least I was not able to observe
a significant increase in the build time.


Repository:
  rC Clang

https://reviews.llvm.org/D50261



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53604: [AST] Widen the bit-fields of Stmt to 8 bytes

2018-10-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Although some classes are using the tail padding of Stmt, most of
them are not. In particular the expression classes are not using it
since there is Expr in between, and Expr contains a single pointer.

This patch widen the bit-fields to Stmt to 8 bytes and move some
data from NullStmt, CompoundStmt, LabelStmt, AttributedStmt, SwitchStmt,
WhileStmt, DoStmt, ForStmt, GotoStmt, ContinueStmt, BreakStmt
and ReturnStmt to the newly available space.

In itself this patch do not achieve much but I plan to go through each of
the classes in the statement/expression hierarchy and use this newly
available space. A quick estimation gives me that this should shrink the
size of the statement/expression hierarchy by >10% when parsing all of Boost.


Repository:
  rC Clang

https://reviews.llvm.org/D53604

Files:
  include/clang/AST/Stmt.h
  lib/AST/Stmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp

Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -73,7 +73,7 @@
 void ASTStmtWriter::VisitNullStmt(NullStmt *S) {
   VisitStmt(S);
   Record.AddSourceLocation(S->getSemiLoc());
-  Record.push_back(S->HasLeadingEmptyMacro);
+  Record.push_back(S->NullStmtBits.HasLeadingEmptyMacro);
   Code = serialization::STMT_NULL;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -154,7 +154,7 @@
 void ASTStmtReader::VisitNullStmt(NullStmt *S) {
   VisitStmt(S);
   S->setSemiLoc(ReadSourceLocation());
-  S->HasLeadingEmptyMacro = Record.readInt();
+  S->NullStmtBits.HasLeadingEmptyMacro = Record.readInt();
 }
 
 void ASTStmtReader::VisitCompoundStmt(CompoundStmt *S) {
@@ -164,7 +164,7 @@
   while (NumStmts--)
 Stmts.push_back(Record.readSubStmt());
   S->setStmts(Stmts);
-  S->LBraceLoc = ReadSourceLocation();
+  S->CompoundStmtBits.LBraceLoc = ReadSourceLocation();
   S->RBraceLoc = ReadSourceLocation();
 }
 
@@ -199,15 +199,18 @@
 
 void ASTStmtReader::VisitAttributedStmt(AttributedStmt *S) {
   VisitStmt(S);
+  // NumAttrs in AttributedStmt is set when creating an empty
+  // AttributedStmt in AttributedStmt::CreateEmpty, since it is needed
+  // to allocate the right amount of space for the trailing Attr *.
   uint64_t NumAttrs = Record.readInt();
   AttrVec Attrs;
   Record.readAttributes(Attrs);
   (void)NumAttrs;
-  assert(NumAttrs == S->NumAttrs);
+  assert(NumAttrs == S->AttributedStmtBits.NumAttrs);
   assert(NumAttrs == Attrs.size());
   std::copy(Attrs.begin(), Attrs.end(), S->getAttrArrayPtr());
   S->SubStmt = Record.readSubStmt();
-  S->AttrLoc = ReadSourceLocation();
+  S->AttributedStmtBits.AttrLoc = ReadSourceLocation();
 }
 
 void ASTStmtReader::VisitIfStmt(IfStmt *S) {
Index: lib/AST/Stmt.cpp
===
--- lib/AST/Stmt.cpp
+++ lib/AST/Stmt.cpp
@@ -311,9 +311,10 @@
 
 CompoundStmt::CompoundStmt(ArrayRef Stmts, SourceLocation LB,
SourceLocation RB)
-: Stmt(CompoundStmtClass), LBraceLoc(LB), RBraceLoc(RB) {
+: Stmt(CompoundStmtClass), RBraceLoc(RB) {
   CompoundStmtBits.NumStmts = Stmts.size();
   setStmts(Stmts);
+  CompoundStmtBits.LBraceLoc = LB;
 }
 
 void CompoundStmt::setStmts(ArrayRef Stmts) {
@@ -836,13 +837,14 @@
 ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
  Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
  SourceLocation RP)
-  : Stmt(ForStmtClass), ForLoc(FL), LParenLoc(LP), RParenLoc(RP)
+  : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
 {
   SubExprs[INIT] = Init;
   setConditionVariable(C, condVar);
   SubExprs[COND] = Cond;
   SubExprs[INC] = Inc;
   SubExprs[BODY] = Body;
+  ForStmtBits.ForLoc = FL;
 }
 
 VarDecl *ForStmt::getConditionVariable() const {
@@ -871,6 +873,7 @@
   SubExprs[INIT] = init;
   SubExprs[COND] = cond;
   SubExprs[BODY] = nullptr;
+  SwitchStmtBits.SwitchLoc = SourceLocation{};
 }
 
 VarDecl *SwitchStmt::getConditionVariable() const {
@@ -904,7 +907,7 @@
   setConditionVariable(C, Var);
   SubExprs[COND] = cond;
   SubExprs[BODY] = body;
-  WhileLoc = WL;
+  WhileStmtBits.WhileLoc = WL;
 }
 
 VarDecl *WhileStmt::getConditionVariable() const {
Index: include/clang/AST/Stmt.h
===
--- include/clang/AST/Stmt.h
+++ include/clang/AST/Stmt.h
@@ -89,20 +89,65 @@
 llvm_unreachable("Stmts cannot be released with regular 'delete'.");
   }
 
+  //===--- Statement bitfields classes ---===//
+
   class StmtBitfields {
 friend class Stmt;
 
 /// The statement class.
 unsigne

[PATCH] D53605: [AST] Pack PredefinedExpr

2018-10-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.
riccibruno added a dependency: D53604: [AST] Widen the bit-fields of Stmt to 8 
bytes.

This patch does 3 things:

1. Move PredefinedExpr below StringLiteral so that it can use its definition.
2. Move the location and the IdentType into the newly available space of the 
bit-fields of Stmt.
3. Only store the function name when needed.


Repository:
  rC Clang

https://reviews.llvm.org/D53605

Files:
  include/clang/AST/Expr.h
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Expr.cpp
  lib/Sema/SemaExpr.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp

Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -388,9 +388,13 @@
 
 void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
   VisitExpr(E);
-  Record.AddSourceLocation(E->getLocation());
+
+  bool HasFunctionName = !!E->getFunctionName();
+  Record.push_back(HasFunctionName);
   Record.push_back(E->getIdentType()); // FIXME: stable encoding
-  Record.AddStmt(E->getFunctionName());
+  Record.AddSourceLocation(E->getLocation());
+  if (HasFunctionName)
+Record.AddStmt(E->getFunctionName());
   Code = serialization::EXPR_PREDEFINED;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -496,9 +496,12 @@
 
 void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
   VisitExpr(E);
+  bool HasFunctionName = Record.readInt();
+  E->PredefinedExprBits.HasFnName = HasFunctionName;
+  E->PredefinedExprBits.Type = Record.readInt();
   E->setLocation(ReadSourceLocation());
-  E->Type = (PredefinedExpr::IdentType)Record.readInt();
-  E->FnName = cast_or_null(Record.readSubExpr());
+  if (HasFunctionName)
+E->setFunctionName(cast(Record.readSubExpr()));
 }
 
 void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
@@ -2334,12 +2337,14 @@
   break;
 
 case STMT_CAPTURED:
-  S = CapturedStmt::CreateDeserialized(Context,
-   Record[ASTStmtReader::NumStmtFields]);
+  S = CapturedStmt::CreateDeserialized(
+  Context, Record[ASTStmtReader::NumStmtFields]);
   break;
 
 case EXPR_PREDEFINED:
-  S = new (Context) PredefinedExpr(Empty);
+  S = PredefinedExpr::CreateEmpty(
+  Context,
+  /*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]);
   break;
 
 case EXPR_DECL_REF:
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -3083,7 +3083,7 @@
 }
   }
 
-  return new (Context) PredefinedExpr(Loc, ResTy, IT, SL);
+  return PredefinedExpr::Create(Context, Loc, ResTy, IT, SL);
 }
 
 ExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, tok::TokenKind Kind) {
Index: lib/AST/Expr.cpp
===
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -463,11 +463,36 @@
 : Expr(PredefinedExprClass, FNTy, VK_LValue, OK_Ordinary,
FNTy->isDependentType(), FNTy->isDependentType(),
FNTy->isInstantiationDependentType(),
-   /*ContainsUnexpandedParameterPack=*/false),
-  Loc(L), Type(IT), FnName(SL) {}
-
-StringLiteral *PredefinedExpr::getFunctionName() {
-  return cast_or_null(FnName);
+   /*ContainsUnexpandedParameterPack=*/false) {
+  PredefinedExprBits.Type = IT;
+  assert((getIdentType() == IT) &&
+ "IdentType do not fit in PredefinedExprBitfields!");
+  bool HasFunctionName = !!SL;
+  PredefinedExprBits.HasFnName = HasFunctionName;
+  PredefinedExprBits.Loc = L;
+  if (HasFunctionName)
+setFunctionName(SL);
+}
+
+PredefinedExpr::PredefinedExpr(EmptyShell Empty, bool HasFunctionName)
+: Expr(PredefinedExprClass, Empty) {
+  PredefinedExprBits.HasFnName = HasFunctionName;
+}
+
+PredefinedExpr *PredefinedExpr::Create(const ASTContext &Ctx, SourceLocation L,
+   QualType FNTy, IdentType IT,
+   StringLiteral *SL) {
+  bool HasFunctionName = !!SL;
+  void *Mem = Ctx.Allocate(totalSizeToAlloc(HasFunctionName),
+   alignof(PredefinedExpr));
+  return new (Mem) PredefinedExpr(L, FNTy, IT, SL);
+}
+
+PredefinedExpr *PredefinedExpr::CreateEmpty(const ASTContext &Ctx,
+bool HasFunctionName) {
+  void *Mem = Ctx.Allocate(totalSizeToAlloc(HasFunctionName),
+   alignof(PredefinedExpr));
+  return new (Mem) PredefinedExpr(EmptyShell(), HasFunctionName);
 }
 
 StringRef PredefinedExpr::getIdentTypeName(PredefinedExpr::IdentType IT) {
I

[PATCH] D53607: [AST] Only store the needed data in IfStmt.

2018-10-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added subscribers: cfe-commits, javed.absar.
riccibruno added a dependency: D53605: [AST] Pack PredefinedExpr.

Only store the needed data in `IfStmt`. The various `Stmt *` are put in
a trailing array with the commonly used `Stmt *` first (like the condition
and the then statement) and the less commonly used `Stmt *` last.
This cuts the size of `IfStmt` by up to 3 pointers + 1 `SourceLocation`.

One point which must be discussed is that this changes the order of the
children. This is strictly speaking not needed (we could just compute the
appropriate index into the trailing array) but this allows the common data
to be at a constant offset into the trailing array. This saves us from doing
bit manipulations and arithmetic each time the commonly used data is accessed.

I believe the C API is unaffected since it do not rely on calling `children` on 
`IfStmt`.
This also makes modifying an `IfStmt` after creation harder since the necessary
storage might not exist.


Repository:
  rC Clang

https://reviews.llvm.org/D53607

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Analysis/BodyFarm.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/if-stmt/test.cpp
  test/Misc/ast-dump-invalid.cpp

Index: test/Misc/ast-dump-invalid.cpp
===
--- test/Misc/ast-dump-invalid.cpp
+++ test/Misc/ast-dump-invalid.cpp
@@ -33,8 +33,6 @@
 // CHECK-NEXT:   |-ParmVarDecl
 // CHECK-NEXT:   `-CompoundStmt
 // CHECK-NEXT: `-IfStmt {{.*}} 
-// CHECK-NEXT:   |-<<>>
-// CHECK-NEXT:   |-<<>>
 // CHECK-NEXT:   |-OpaqueValueExpr {{.*}} <> 'bool'
 // CHECK-NEXT:   |-ReturnStmt {{.*}} 
 // CHECK-NEXT:   | `-IntegerLiteral {{.*}}  'int' 4
@@ -50,15 +48,15 @@
 { return 45; }
 }
 // CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl
-// CHECK-NEXT: |-CXXRecordDecl {{.*}}  line:46:8 struct Str definition
+// CHECK-NEXT: |-CXXRecordDecl {{.*}}  line:44:8 struct Str definition
 // CHECK:  | |-CXXRecordDecl {{.*}}  col:8 implicit struct Str
-// CHECK-NEXT: | `-CXXMethodDecl {{.*}}  col:11 invalid foo1 'double (double, int)'
+// CHECK-NEXT: | `-CXXMethodDecl {{.*}}  col:11 invalid foo1 'double (double, int)'
 // CHECK-NEXT: |   |-ParmVarDecl {{.*}}  col:22 'double'
 // CHECK-NEXT: |   `-ParmVarDecl {{.*}} > col:36 invalid 'int'
-// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}}  line:49:13 invalid foo1 'double (double, int)'
+// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}}  line:47:13 invalid foo1 'double (double, int)'
 // CHECK-NEXT:   |-ParmVarDecl {{.*}}  col:24 'double'
 // CHECK-NEXT:   |-ParmVarDecl {{.*}} > col:38 invalid 'int'
-// CHECK-NEXT:   `-CompoundStmt {{.*}} 
+// CHECK-NEXT:   `-CompoundStmt {{.*}} 
 // CHECK-NEXT: `-ReturnStmt {{.*}} 
 // CHECK-NEXT:   `-ImplicitCastExpr {{.*}}  'double' 
 // CHECK-NEXT: `-IntegerLiteral {{.*}}  'int' 45
Index: test/Import/if-stmt/test.cpp
===
--- test/Import/if-stmt/test.cpp
+++ test/Import/if-stmt/test.cpp
@@ -1,41 +1,30 @@
 // RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: DeclStmt
-// CHECK-NEXT: VarDecl
-// CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: ImplicitCastExpr
 // CHECK-NEXT: ImplicitCastExpr
 // CHECK-NEXT: DeclRefExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
-
-// CHECK: IfStmt
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
-// CHECK-NEXT: <>
+// CHECK-NEXT: IntegerLiteral
+
+// CHECK: IfStmt
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
+// CHECK-NEXT: DeclStmt
+// CHECK-NEXT: VarDecl
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
 // CHECK-NEXT: ReturnStmt
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: ReturnStmt
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -128,14 +128,29 @@
 
 void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
   VisitStmt(S);
+
+  bool HasElse = !!S->getElse();
+  bool HasVar = !!S->getConditionVariableDeclStmt();
+  bool HasInit = !!S->getInit();
+
   Record.push_back(S->isConstexpr());
-  Record.AddStmt(S->getInit());
-  Record.AddDeclRef(S->getConditionVariable());
+  Record.push_back(HasElse);
+  Record.push_back(HasVar);
+  Record.push_back(HasInit);
+
   Record.AddStmt(S->getCond());
   

[PATCH] D53609: [AST] Don't store data for GNU range case statement if not needed.

2018-10-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Don't store the data for case statements of the form `LHS ... RHS` if not 
needed.
This cuts the size of `CaseStmt` by 1 pointer + 1 `SourceLocation` in
the common case.

Also use the newly available space in the bit-fields of `Stmt` to store the
keyword location of `SwitchCase` and move the small accessor
`SwitchCase::getSubStmt` to the header.


Repository:
  rC Clang

https://reviews.llvm.org/D53609

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/switch-stmt/test.cpp
  test/Misc/ast-dump-color.cpp

Index: test/Misc/ast-dump-color.cpp
===
--- test/Misc/ast-dump-color.cpp
+++ test/Misc/ast-dump-color.cpp
@@ -51,13 +51,11 @@
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]|   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -7,10 +7,8 @@
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
@@ -22,11 +20,9 @@
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -96,10 +96,13 @@
 
 void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
+  Record.push_back(S->caseStmtIsGNURange());
   Record.AddStmt(S->getLHS());
-  Record.AddStmt(S->getRHS());
   Record.AddStmt(S->getSubStmt());
-  Record.AddSourceLocation(S->getEllipsisLoc());
+  if (S->caseStmtIsGNURange()) {
+Record.AddStmt(S->getRHS());
+Record.AddSourceLocation(S->getEllipsisLoc());
+  }
   Code = serialization::STMT_CASE;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -177,10 +177,13 @@
 
 void ASTStmtReader::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
+  bool CaseStmtIsGNURange = Record.readInt();
   S->setLHS(Record.readSubExpr());
-  S->setRHS(Record.readSubExpr());
   S->setSubStmt(Record.readSubStmt());
-  S->setEllipsisLoc(ReadSourceLocation());
+  if (CaseStmtIsGNURange) {
+S->setRHS(Record.readS

[PATCH] D53610: [AST] Check that GNU range case statements are correctly imported.

2018-10-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

The test for case statements did not cover GNU range case statements.


Repository:
  rC Clang

https://reviews.llvm.org/D53610

Files:
  test/Import/switch-stmt/Inputs/F.cpp
  test/Import/switch-stmt/test.cpp


Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -10,6 +10,13 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: DeclStmt
@@ -24,6 +31,10 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
+// CHECK-NEXT: IntegerLiteral
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: <>
Index: test/Import/switch-stmt/Inputs/F.cpp
===
--- test/Import/switch-stmt/Inputs/F.cpp
+++ test/Import/switch-stmt/Inputs/F.cpp
@@ -3,12 +3,17 @@
   case 1:
   case 2:
 break;
+  case 3 ... 4:
+  case 5 ... 5:
+break;
   }
   switch (int varname; 1) {
   case 1:
 break;
   case 2:
 break;
+  case 3 ... 5:
+break;
   }
   switch (1)
   default:


Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -10,6 +10,13 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: DeclStmt
@@ -24,6 +31,10 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
+// CHECK-NEXT: IntegerLiteral
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: <>
Index: test/Import/switch-stmt/Inputs/F.cpp
===
--- test/Import/switch-stmt/Inputs/F.cpp
+++ test/Import/switch-stmt/Inputs/F.cpp
@@ -3,12 +3,17 @@
   case 1:
   case 2:
 break;
+  case 3 ... 4:
+  case 5 ... 5:
+break;
   }
   switch (int varname; 1) {
   case 1:
 break;
   case 2:
 break;
+  case 3 ... 5:
+break;
   }
   switch (1)
   default:
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53607: [AST] Only store the needed data in IfStmt.

2018-10-24 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

To add on the issue of changing the order of the children. The more I think 
about
it the less it seems to be a good idea. Every test passes but I strongly suspect
that a lot of code subtly rely on this.


Repository:
  rC Clang

https://reviews.llvm.org/D53607



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53607: [AST] Only store the needed data in IfStmt.

2018-10-25 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171121.
riccibruno edited the summary of this revision.
riccibruno added a comment.

Reworked so that the order of the children is kept the same.


Repository:
  rC Clang

https://reviews.llvm.org/D53607

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Analysis/BodyFarm.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/if-stmt/test.cpp
  test/Misc/ast-dump-invalid.cpp

Index: test/Misc/ast-dump-invalid.cpp
===
--- test/Misc/ast-dump-invalid.cpp
+++ test/Misc/ast-dump-invalid.cpp
@@ -33,8 +33,6 @@
 // CHECK-NEXT:   |-ParmVarDecl
 // CHECK-NEXT:   `-CompoundStmt
 // CHECK-NEXT: `-IfStmt {{.*}} 
-// CHECK-NEXT:   |-<<>>
-// CHECK-NEXT:   |-<<>>
 // CHECK-NEXT:   |-OpaqueValueExpr {{.*}} <> 'bool'
 // CHECK-NEXT:   |-ReturnStmt {{.*}} 
 // CHECK-NEXT:   | `-IntegerLiteral {{.*}}  'int' 4
@@ -50,15 +48,15 @@
 { return 45; }
 }
 // CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl
-// CHECK-NEXT: |-CXXRecordDecl {{.*}}  line:46:8 struct Str definition
+// CHECK-NEXT: |-CXXRecordDecl {{.*}}  line:44:8 struct Str definition
 // CHECK:  | |-CXXRecordDecl {{.*}}  col:8 implicit struct Str
-// CHECK-NEXT: | `-CXXMethodDecl {{.*}}  col:11 invalid foo1 'double (double, int)'
+// CHECK-NEXT: | `-CXXMethodDecl {{.*}}  col:11 invalid foo1 'double (double, int)'
 // CHECK-NEXT: |   |-ParmVarDecl {{.*}}  col:22 'double'
 // CHECK-NEXT: |   `-ParmVarDecl {{.*}} > col:36 invalid 'int'
-// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}}  line:49:13 invalid foo1 'double (double, int)'
+// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}}  line:47:13 invalid foo1 'double (double, int)'
 // CHECK-NEXT:   |-ParmVarDecl {{.*}}  col:24 'double'
 // CHECK-NEXT:   |-ParmVarDecl {{.*}} > col:38 invalid 'int'
-// CHECK-NEXT:   `-CompoundStmt {{.*}} 
+// CHECK-NEXT:   `-CompoundStmt {{.*}} 
 // CHECK-NEXT: `-ReturnStmt {{.*}} 
 // CHECK-NEXT:   `-ImplicitCastExpr {{.*}}  'double' 
 // CHECK-NEXT: `-IntegerLiteral {{.*}}  'int' 45
Index: test/Import/if-stmt/test.cpp
===
--- test/Import/if-stmt/test.cpp
+++ test/Import/if-stmt/test.cpp
@@ -1,41 +1,30 @@
 // RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: ImplicitCastExpr
 // CHECK-NEXT: ImplicitCastExpr
 // CHECK-NEXT: DeclRefExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
 
 // CHECK: IfStmt
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
 // CHECK-NEXT: ReturnStmt
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: ReturnStmt
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -128,14 +128,29 @@
 
 void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
   VisitStmt(S);
+
+  bool HasElse = !!S->getElse();
+  bool HasVar = !!S->getConditionVariableDeclStmt();
+  bool HasInit = !!S->getInit();
+
   Record.push_back(S->isConstexpr());
-  Record.AddStmt(S->getInit());
-  Record.AddDeclRef(S->getConditionVariable());
+  Record.push_back(HasElse);
+  Record.push_back(HasVar);
+  Record.push_back(HasInit);
+
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getThen());
-  Record.AddStmt(S->getElse());
+  if (HasElse)
+Record.AddStmt(S->getElse());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+  if (HasInit)
+Record.AddStmt(S->getInit());
+
   Record.AddSourceLocation(S->getIfLoc());
-  Record.AddSourceLocation(S->getElseLoc());
+  if (HasElse)
+Record.AddSourceLocation(S->getElseLoc());
+
   Code = serialization::STMT_IF;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -215,14 +215,24 @@
 
 void ASTStmtReader::VisitIfStmt(IfStmt *S) {
   VisitStmt(S);
+
   S->setConstexpr(Record.readInt());
-  S->setInit(Record.readSubStmt());
-  S->setConditionVariable(Record.getContext(), ReadDeclAs());
+  bool HasElse = Record.readInt();
+  bool HasVar = Record.readInt();
+  bool HasInit = Record.readInt();
+
   S->setCond(Record.readSubExpr());
   S->set

[PATCH] D53609: [AST] Don't store data for GNU range case statement if not needed.

2018-10-25 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171124.
riccibruno added a comment.

Reworked so that the order of the children is kept the same.


Repository:
  rC Clang

https://reviews.llvm.org/D53609

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/switch-stmt/test.cpp
  test/Misc/ast-dump-color.cpp

Index: test/Misc/ast-dump-color.cpp
===
--- test/Misc/ast-dump-color.cpp
+++ test/Misc/ast-dump-color.cpp
@@ -51,13 +51,11 @@
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]|   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -7,10 +7,8 @@
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
@@ -22,11 +20,9 @@
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -96,10 +96,13 @@
 
 void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
+  Record.push_back(S->caseStmtIsGNURange());
   Record.AddStmt(S->getLHS());
-  Record.AddStmt(S->getRHS());
   Record.AddStmt(S->getSubStmt());
-  Record.AddSourceLocation(S->getEllipsisLoc());
+  if (S->caseStmtIsGNURange()) {
+Record.AddStmt(S->getRHS());
+Record.AddSourceLocation(S->getEllipsisLoc());
+  }
   Code = serialization::STMT_CASE;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -177,10 +177,13 @@
 
 void ASTStmtReader::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
+  bool CaseStmtIsGNURange = Record.readInt();
   S->setLHS(Record.readSubExpr());
-  S->setRHS(Record.readSubExpr());
   S->setSubStmt(Record.readSubStmt());
-  S->setEllipsisLoc(ReadSourceLocation());
+  if (CaseStmtIsGNURange) {
+S->setRHS(Record.readSubExpr());
+S->setEllipsisLoc(ReadSourceLocation());
+  }
 }
 
 void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) {
@@ -2277,7 +2280,9 @@
   break;
 
 case STMT_CASE:
-  S = new (Context) CaseStmt(Empty);
+  S = CaseStmt::CreateEmpty(
+  Context,
+  /*CaseStmtIsGNURange*/ Record[ASTStmtReader::NumStmtFields + 3]);
   

[PATCH] D53610: [AST] Check that GNU range case statements are correctly imported.

2018-10-25 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171125.
riccibruno added a comment.

rebased


Repository:
  rC Clang

https://reviews.llvm.org/D53610

Files:
  test/Import/switch-stmt/Inputs/F.cpp
  test/Import/switch-stmt/test.cpp


Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -10,6 +10,13 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: DeclStmt
@@ -24,6 +31,10 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: <>
Index: test/Import/switch-stmt/Inputs/F.cpp
===
--- test/Import/switch-stmt/Inputs/F.cpp
+++ test/Import/switch-stmt/Inputs/F.cpp
@@ -3,12 +3,17 @@
   case 1:
   case 2:
 break;
+  case 3 ... 4:
+  case 5 ... 5:
+break;
   }
   switch (int varname; 1) {
   case 1:
 break;
   case 2:
 break;
+  case 3 ... 5:
+break;
   }
   switch (1)
   default:


Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -10,6 +10,13 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: DeclStmt
@@ -24,6 +31,10 @@
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: BreakStmt
+// CHECK-NEXT: CaseStmt
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: IntegerLiteral
+// CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
 // CHECK-NEXT: <>
Index: test/Import/switch-stmt/Inputs/F.cpp
===
--- test/Import/switch-stmt/Inputs/F.cpp
+++ test/Import/switch-stmt/Inputs/F.cpp
@@ -3,12 +3,17 @@
   case 1:
   case 2:
 break;
+  case 3 ... 4:
+  case 5 ... 5:
+break;
   }
   switch (int varname; 1) {
   case 1:
 break;
   case 2:
 break;
+  case 3 ... 5:
+break;
   }
   switch (1)
   default:
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D53714: [AST] Only store the needed data in SwitchStmt.

2018-10-25 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Don't store the data for the init statement and condition variable
if not needed. This cuts the size of `SwitchStmt` by up to 2 pointers.
The order of the children is kept the same.

Also use the newly available space in the bit-fields of `Stmt`
to store the bit representing whether all enum have been covered
instead of using a `PointerIntPair`.


Repository:
  rC Clang

https://reviews.llvm.org/D53714

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/switch-stmt/test.cpp
  test/Misc/ast-dump-color.cpp

Index: test/Misc/ast-dump-color.cpp
===
--- test/Misc/ast-dump-color.cpp
+++ test/Misc/ast-dump-color.cpp
@@ -46,7 +46,6 @@
 //CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]> [[Yellow]]line:9:6[[RESET]][[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void ()'[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[Blue:.\[0;34m]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -1,8 +1,6 @@
 // RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
 
 // CHECK: SwitchStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
@@ -22,7 +20,6 @@
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-SAME: varname
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
@@ -37,15 +34,11 @@
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: DefaultStmt
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: NullStmt
 
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -159,12 +159,22 @@
 
 void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
   VisitStmt(S);
-  Record.AddStmt(S->getInit());
-  Record.AddDeclRef(S->getConditionVariable());
+
+  bool HasInit = !!S->getInit();
+  bool HasVar = !!S->getConditionVariableDeclStmt();
+  Record.push_back(HasInit);
+  Record.push_back(HasVar);
+  Record.push_back(S->isAllEnumCasesCovered());
+
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getBody());
+  if (HasInit)
+Record.AddStmt(S->getInit());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+
   Record.AddSourceLocation(S->getSwitchLoc());
-  Record.push_back(S->isAllEnumCasesCovered());
+
   for (SwitchCase *SC = S->getSwitchCaseList(); SC;
SC = SC->getNextSwitchCase())
 Record.push_back(Writer.RecordSwitchCaseID(SC));
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -240,13 +240,21 @@
 
 void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
   VisitStmt(S);
-  S->setInit(Record.readSubStmt());
-  S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
+  bool HasInit = Record.readInt();
+  bool HasVar = Record.readInt();
+  bool AllEnumCasesCovered = Record.readInt();
+  if (AllEnumCasesCovered)
+S->setAllEnumCasesCovered();
+
   S->setCond(Record.readSubExpr());
   S->setBody(Record.readSubStmt());
+  if (HasInit)
+S->setInit(Record.readSubStmt());
+  if (HasVar)
+S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
   S->setS

[PATCH] D53715: [AST] Only store the needed data in WhileStmt.

2018-10-25 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Don't store the data for the condition variable if not needed.
This cuts the size of `WhileStmt` by up to a pointer.
The order of the children is kept the same.


Repository:
  rC Clang

https://reviews.llvm.org/D53715

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/while-stmt/test.cpp

Index: test/Import/while-stmt/test.cpp
===
--- test/Import/while-stmt/test.cpp
+++ test/Import/while-stmt/test.cpp
@@ -1,12 +1,10 @@
 // RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
 
 // CHECK: WhileStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: NullStmt
 
 // CHECK: WhileStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: CompoundStmt
 
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -183,9 +183,15 @@
 
 void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
   VisitStmt(S);
-  Record.AddDeclRef(S->getConditionVariable());
+
+  bool HasVar = !!S->getConditionVariableDeclStmt();
+  Record.push_back(HasVar);
+
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getBody());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+
   Record.AddSourceLocation(S->getWhileLoc());
   Code = serialization::STMT_WHILE;
 }
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -270,10 +270,14 @@
 
 void ASTStmtReader::VisitWhileStmt(WhileStmt *S) {
   VisitStmt(S);
-  S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
+  bool HasVar = Record.readInt();
 
   S->setCond(Record.readSubExpr());
   S->setBody(Record.readSubStmt());
+  if (HasVar)
+S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
   S->setWhileLoc(ReadSourceLocation());
 }
 
@@ -2323,7 +2327,9 @@
   break;
 
 case STMT_WHILE:
-  S = new (Context) WhileStmt(Empty);
+  S = WhileStmt::CreateEmpty(
+  Context,
+  /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 0]);
   break;
 
 case STMT_DO:
Index: lib/Sema/SemaStmt.cpp
===
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -1305,8 +1305,8 @@
   if (isa(Body))
 getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return new (Context)
-  WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc);
+  return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body,
+   WhileLoc);
 }
 
 StmtResult
Index: lib/AST/Stmt.cpp
===
--- lib/AST/Stmt.cpp
+++ lib/AST/Stmt.cpp
@@ -978,32 +978,60 @@
   DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
 }
 
-WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
- SourceLocation WL)
-  : Stmt(WhileStmtClass) {
-  setConditionVariable(C, Var);
-  SubExprs[COND] = cond;
-  SubExprs[BODY] = body;
-  WhileStmtBits.WhileLoc = WL;
+WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
+ Stmt *Body, SourceLocation WL)
+: Stmt(WhileStmtClass) {
+  bool HasVar = !!Var;
+  WhileStmtBits.HasVar = HasVar;
+
+  setCond(Cond);
+  setBody(Body);
+  if (HasVar)
+setConditionVariable(Ctx, Var);
+
+  setWhileLoc(WL);
 }
 
-VarDecl *WhileStmt::getConditionVariable() const {
-  if (!SubExprs[VAR])
-return nullptr;
+WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)
+: Stmt(WhileStmtClass, Empty) {
+  WhileStmtBits.HasVar = HasVar;
+}
+
+WhileStmt *WhileStmt::Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
+ Stmt *Body, SourceLocation WL) {
+  bool HasVar = !!Var;
+  void *Mem =
+  Ctx.Allocate(totalSizeToAlloc(NumMandatoryStmtPtr + HasVar),
+   alignof(WhileStmt));
+  return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL);
+}
 
-  auto *DS = cast(SubExprs[VAR]);
+WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) {
+  void *Mem =
+  Ctx.Allocate(totalSizeToAlloc(NumMandatoryStmtPtr + HasVar),
+   alignof(WhileStmt));
+  return new (Mem) WhileStmt(EmptyShell(), HasVar);
+}
+
+VarDecl *WhileStmt::getConditionVariable() {
+  auto *DS = getConditionVariableDeclStmt();
+  if (!DS)
+return nullptr;
   return cast(DS->getSingleDecl());
 }
 
-void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
+void WhileStmt::setCo

[PATCH] D53716: [AST] Only store data for the NRVO candidate in ReturnStmt if needed.

2018-10-25 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added subscribers: cfe-commits, javed.absar.

Only store the NRVO candidate if needed in `ReturnStmt`.
A good chuck of all of the `ReturnStmt` have no NRVO candidate.
For all of them this saves one pointer.

This has no impact on `children()`.


Repository:
  rC Clang

https://reviews.llvm.org/D53716

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Analysis/BodyFarm.cpp
  lib/CodeGen/CGObjC.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp

Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -249,9 +249,15 @@
 
 void ASTStmtWriter::VisitReturnStmt(ReturnStmt *S) {
   VisitStmt(S);
+
+  bool HasNRVOCandidate = !!S->getNRVOCandidate();
+  Record.push_back(HasNRVOCandidate);
+
   Record.AddStmt(S->getRetValue());
+  if (HasNRVOCandidate)
+Record.AddDeclRef(S->getNRVOCandidate());
+
   Record.AddSourceLocation(S->getReturnLoc());
-  Record.AddDeclRef(S->getNRVOCandidate());
   Code = serialization::STMT_RETURN;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -328,9 +328,14 @@
 
 void ASTStmtReader::VisitReturnStmt(ReturnStmt *S) {
   VisitStmt(S);
+
+  bool HasNRVOCandidate = Record.readInt();
+
   S->setRetValue(Record.readSubExpr());
+  if (HasNRVOCandidate)
+S->setNRVOCandidate(ReadDeclAs());
+
   S->setReturnLoc(ReadSourceLocation());
-  S->setNRVOCandidate(ReadDeclAs());
 }
 
 void ASTStmtReader::VisitDeclStmt(DeclStmt *S) {
@@ -2357,7 +2362,8 @@
   break;
 
 case STMT_RETURN:
-  S = new (Context) ReturnStmt(Empty);
+  S = ReturnStmt::CreateEmpty(
+  Context, /* HasNRVOCandidate=*/Record[ASTStmtReader::NumStmtFields]);
   break;
 
 case STMT_DECL:
Index: lib/Sema/SemaStmt.cpp
===
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -3220,7 +3220,8 @@
 return StmtError();
   RetValExp = ER.get();
 }
-return new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);
+return ReturnStmt::Create(Context, ReturnLoc, RetValExp,
+  /* NRVOCandidate=*/nullptr);
   }
 
   if (HasDeducedReturnType) {
@@ -3346,8 +3347,8 @@
   return StmtError();
 RetValExp = ER.get();
   }
-  ReturnStmt *Result = new (Context) ReturnStmt(ReturnLoc, RetValExp,
-NRVOCandidate);
+  auto *Result =
+  ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate);
 
   // If we need to check for the named return value optimization,
   // or if we need to infer the return type,
@@ -3576,7 +3577,8 @@
 return StmtError();
   RetValExp = ER.get();
 }
-return new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);
+return ReturnStmt::Create(Context, ReturnLoc, RetValExp,
+  /* NRVOCandidate=*/nullptr);
   }
 
   // FIXME: Add a flag to the ScopeInfo to indicate whether we're performing
@@ -3671,7 +3673,7 @@
   }
 }
 
-Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, nullptr);
+Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp, nullptr);
   } else if (!RetValExp && !HasDependentReturnType) {
 FunctionDecl *FD = getCurFunctionDecl();
 
@@ -3693,7 +3695,8 @@
 else
   Diag(ReturnLoc, DiagID) << getCurMethodDecl()->getDeclName() << 1/*meth*/;
 
-Result = new (Context) ReturnStmt(ReturnLoc);
+Result = ReturnStmt::Create(Context, ReturnLoc, /* RetExpr=*/nullptr,
+/* NRVOCandidate=*/nullptr);
   } else {
 assert(RetValExp || HasDependentReturnType);
 const VarDecl *NRVOCandidate = nullptr;
@@ -3746,7 +3749,7 @@
 return StmtError();
   RetValExp = ER.get();
 }
-Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, NRVOCandidate);
+Result = ReturnStmt::Create(Context, ReturnLoc, RetValExp, NRVOCandidate);
   }
 
   // If we need to check for the named return value optimization, save the
Index: lib/CodeGen/CGObjC.cpp
===
--- lib/CodeGen/CGObjC.cpp
+++ lib/CodeGen/CGObjC.cpp
@@ -883,9 +883,10 @@
   // If there's a non-trivial 'get' expression, we just have to emit that.
   if (!hasTrivialGetExpr(propImpl)) {
 if (!AtomicHelperFn) {
-  ReturnStmt ret(SourceLocation(), propImpl->getGetterCXXConstructor(),
- /*nrvo*/ nullptr);
-  EmitReturnStmt(ret);
+  auto *ret = ReturnStmt::Create(getContext(), SourceLocation(),
+ propImpl->getGetterCXXConstructor(),
+

[PATCH] D53717: [AST] Only store the needed data in ForStmt.

2018-10-25 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added a reviewer: rjmccall.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.
riccibruno added a dependency: D53716: [AST] Only store data for the NRVO 
candidate in ReturnStmt if needed..

Don't store the init statement and condition variable if not needed.
This cuts the size of `ForStmt` by up to 2 pointers, and 1 pointer in
the common case. The condition and increment are stored unconditionally
since for statements without a condition and increment are quite uncommon.
The order of the children is kept the same.


Repository:
  rC Clang

https://reviews.llvm.org/D53717

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/for-stmt/test.cpp

Index: test/Import/for-stmt/test.cpp
===
--- test/Import/for-stmt/test.cpp
+++ test/Import/for-stmt/test.cpp
@@ -3,21 +3,17 @@
 // CHECK: ForStmt
 // CHECK-NEXT: <>
 // CHECK-NEXT: <>
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: NullStmt
 
 // CHECK: ForStmt
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: <>
 // CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: ContinueStmt
 
 // CHECK: ForStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: CXXBoolLiteralExpr
@@ -32,7 +28,6 @@
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 
 // CHECK-NEXT: BinaryOperator
 // CHECK-NEXT: ImplicitCastExpr
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -208,11 +208,20 @@
 
 void ASTStmtWriter::VisitForStmt(ForStmt *S) {
   VisitStmt(S);
-  Record.AddStmt(S->getInit());
+
+  bool HasInit = !!S->getInit();
+  bool HasVar = !!S->getConditionVariableDeclStmt();
+  Record.push_back(HasInit);
+  Record.push_back(HasVar);
+
   Record.AddStmt(S->getCond());
-  Record.AddDeclRef(S->getConditionVariable());
   Record.AddStmt(S->getInc());
   Record.AddStmt(S->getBody());
+  if (HasInit)
+Record.AddStmt(S->getInit());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+
   Record.AddSourceLocation(S->getForLoc());
   Record.AddSourceLocation(S->getLParenLoc());
   Record.AddSourceLocation(S->getRParenLoc());
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -292,11 +292,18 @@
 
 void ASTStmtReader::VisitForStmt(ForStmt *S) {
   VisitStmt(S);
-  S->setInit(Record.readSubStmt());
+
+  bool HasInit = Record.readInt();
+  bool HasVar = Record.readInt();
+
   S->setCond(Record.readSubExpr());
-  S->setConditionVariable(Record.getContext(), ReadDeclAs());
   S->setInc(Record.readSubExpr());
   S->setBody(Record.readSubStmt());
+  if (HasInit)
+S->setInit(Record.readSubStmt());
+  if (HasVar)
+S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
   S->setForLoc(ReadSourceLocation());
   S->setLParenLoc(ReadSourceLocation());
   S->setRParenLoc(ReadSourceLocation());
@@ -2342,7 +2349,10 @@
   break;
 
 case STMT_FOR:
-  S = new (Context) ForStmt(Empty);
+  S = ForStmt::CreateEmpty(
+  Context,
+  /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 0],
+  /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1]);
   break;
 
 case STMT_GOTO:
Index: lib/Sema/SemaStmt.cpp
===
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -1780,9 +1780,9 @@
   if (isa(Body))
 getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return new (Context)
-  ForStmt(Context, First, Second.get().second, Second.get().first, Third,
-  Body, ForLoc, LParenLoc, RParenLoc);
+  return ForStmt::Create(Context, First, Second.get().second,
+ Second.get().first, Third, Body, ForLoc, LParenLoc,
+ RParenLoc);
 }
 
 /// In an Objective C collection iteration statement:
Index: lib/AST/Stmt.cpp
===
--- lib/AST/Stmt.cpp
+++ lib/AST/Stmt.cpp
@@ -881,36 +881,70 @@
   return isa(getCond());
 }
 
-ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
- Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
- SourceLocation RP)
-  : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
-{
-  SubExprs[INIT] = Init;
-  setConditionVariable(C, condVar);
-  SubExprs[COND] = Cond;
-  SubExprs[INC] = Inc;
-  SubExprs[BODY] = Body;
-  ForStmtBits.ForLoc = FL;
-}
-
-VarDecl *ForStmt::getConditionVariable() const {
-  if (!SubExpr

[PATCH] D53717: [AST] Only store the needed data in ForStmt.

2018-10-26 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

In https://reviews.llvm.org/D53717#1276388, @rsmith wrote:

> In https://reviews.llvm.org/D53717#1276245, @rsmith wrote:
>
> > Do you have evidence that this complexity is worthwhile? (I wouldn't 
> > imagine we have very many `ForStmt`s per translation unit, so saving 16 
> > bytes for each of them seems unlikely to matter.)
>
>
> Strikes me that some data would be useful here, to help prioritize. Here's a 
> histogram of occurrence counts for a libc++ module:
>
>   Count# Bits b/Rec   % Abv  Record Kind
>   43731   5471391 125.1   87.46  EXPR_DECL_REF
>   35751822273  23.0  DECL_OMP_DECLARE_REDUCTION
>   29734   3431612 115.4  TYPE_TEMPLATE_SPECIALIZATION
>   25750   7472591 290.2   55.89  DECL_PARM_VAR
>   14986651081  43.4   98.81  EXPR_IMPLICIT_CAST
>   14847   1620549 109.1  EXPR_CALL
>   13153   1968371 149.7  TYPE_FUNCTION_PROTO
>   12605   3797017 301.2  100.00  DECL_CONTEXT_LEXICAL
>   12515715141  57.1  TYPE_TEMPLATE_TYPE_PARM
>   12480   2608644 209.0  DECL_TEMPLATE_TYPE_PARM
>   10571   1200811 113.6  EXPR_BINARY_OPERATOR
>   10300955610  92.8  STMT_COMPOUND
>   10254   9421030 918.8   17.66  DECL_CXX_METHOD
>   10220   2252926 220.4  EXPR_CXX_DEPENDENT_SCOPE_MEMBER
>   10083231909  23.0  STMT_NULL_PTR
>9731   5196865 534.1  EXPR_CXX_UNRESOLVED_LOOKUP
>8015580911  72.5   87.16  EXPR_INTEGER_LITERAL
>7935   3298497 415.7  EXPR_CXX_DEPENDENT_SCOPE_DECL_REF
>7934   3379054 425.9  DECL_CXX_RECORD
>7790946360 121.5  EXPR_CXX_THIS
>7508350806  46.7  LOCAL_REDECLARATIONS
>7155   1239819 173.3  EXPR_MEMBER
>6754   1264508 187.2  EXPR_CXX_OPERATOR_CALL
>6607   5819360 880.8  100.00  DECL_CONTEXT_VISIBLE
>6461736861 114.0  EXPR_UNARY_OPERATOR
>6117284391  46.5  TYPE_LVALUE_REFERENCE
>6081372753  61.3  STMT_RETURN
>6066   1964810 323.9   99.64  DECL_TYPEDEF
>5659249455  44.1  TYPE_RECORD
>5252   4884856 930.1  DECL_CLASS_TEMPLATE_SPECIALIZATION
>5196313722  60.4  TYPE_SUBST_TEMPLATE_TYPE_PARM
>5189532009 102.5  TYPE_DEPENDENT_NAME
>5083   2145083 422.01.65  DECL_VAR
>4886296440  60.7  TYPE_TYPEDEF
>4340473950 109.2  STMT_DECL
>4314   4078644 945.4  DECL_FUNCTION
>4150   1436618 346.2  DECL_FUNCTION_TEMPLATE
>3686343246  93.1  TYPE_ELABORATED
>3629144649  39.9  TYPE_POINTER
>3435   2907387 846.4  DECL_CXX_CONSTRUCTOR
>3341896701 268.4  DECL_CXX_BASE_SPECIFIERS
>2847376713 132.3  EXPR_PAREN
>2684271156 101.0  EXPR_CXX_BOOL_LITERAL
>2651208771  78.8  STMT_IF
>2053550511 268.1  EXPR_CXX_UNRESOLVED_CONSTRUCT
>1938268044 138.3  DECL_ACCESS_SPEC
>1725472401 273.9  DECL_NON_TYPE_TEMPLATE_PARM
>1647224673 136.4  EXPR_PAREN_LIST
>1610 64624  40.1  TYPE_RVALUE_REFERENCE
>1542380997 247.1   48.57  DECL_FIELD
>1446392676 271.6  EXPR_CXX_UNRESOLVED_MEMBER
>1411283553 201.0  DECL_USING_SHADOW
>1411 87833  62.2  TYPE_INJECTED_CLASS_NAME
>1339164195 122.6  EXPR_SUBST_NON_TYPE_TEMPLATE_PARM
>1226311278 253.9  DECL_CXX_CTOR_INITIALIZERS
>1110215604 194.2  EXPR_SIZEOF_PACK
>1054476456 452.0  DECL_CLASS_TEMPLATE
> 987112161 113.6  EXPR_CXX_MEMBER_CALL
> 943195005 206.8  EXPR_CXX_CONSTRUCT
> 941271069 288.1  EXPR_CXX_STATIC_CAST
> 879171231 194.8  EXPR_TYPE_TRAIT
> 771 40707  52.8  TYPE_PACK_EXPANSION
> 727106103 145.9  DECL_IMPORT
> 696146286 210.2  DECL_FRIEND
> 678136788 201.8  EXPR_CSTYLE_CAST
> 664 70292 105.9  EXPR_ARRAY_SUBSCRIPT
> 628 67550 107.6  EXPR_PACK_EXPANSION
> 601 84473 140.6  EXPR_COMPOUND_ASSIGN_OPERATOR
> 564 71760 127.2  STMT_FOR
> 557 57643 103.5  EXPR_CXX_NULL_PTR_LITERAL
> 545350959 644.0  DECL_CXX_DESTRUCTOR
> 5238679471659.6  
> DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION
> 495120219 242.9  DECL_USING
> 476 87196 183.2  EXPR_SIZEOF_ALIGN_OF
> 447292917 655.3  EXPR_STRING_LITERAL
> 434 32634  75.2  100.

[PATCH] D53605: [AST] Refactor PredefinedExpr

2018-10-26 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171326.
riccibruno marked 4 inline comments as done.
riccibruno retitled this revision from "[AST] Pack PredefinedExpr" to "[AST] 
Refactor PredefinedExpr".
riccibruno edited the summary of this revision.
riccibruno added a comment.

Address rjmcall's comments. In particular use "Kind" instead of "Type" and 
propagate
the change to the users. Change the title to "[AST] Refactor PredefinedExpr" 
since this
patch is doing various changes to `PredefinedExpr`.


Repository:
  rC Clang

https://reviews.llvm.org/D53605

Files:
  include/clang/AST/Expr.h
  include/clang/AST/Stmt.h
  include/clang/AST/StmtDataCollectors.td
  include/clang/Sema/Sema.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Expr.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaTemplateInstantiate.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp

Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -388,9 +388,13 @@
 
 void ASTStmtWriter::VisitPredefinedExpr(PredefinedExpr *E) {
   VisitExpr(E);
+
+  bool HasFunctionName = E->getFunctionName() != nullptr;
+  Record.push_back(HasFunctionName);
+  Record.push_back(E->getIdentKind()); // FIXME: stable encoding
   Record.AddSourceLocation(E->getLocation());
-  Record.push_back(E->getIdentType()); // FIXME: stable encoding
-  Record.AddStmt(E->getFunctionName());
+  if (HasFunctionName)
+Record.AddStmt(E->getFunctionName());
   Code = serialization::EXPR_PREDEFINED;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -496,9 +496,12 @@
 
 void ASTStmtReader::VisitPredefinedExpr(PredefinedExpr *E) {
   VisitExpr(E);
+  bool HasFunctionName = Record.readInt();
+  E->PredefinedExprBits.HasFunctionName = HasFunctionName;
+  E->PredefinedExprBits.Kind = Record.readInt();
   E->setLocation(ReadSourceLocation());
-  E->Type = (PredefinedExpr::IdentType)Record.readInt();
-  E->FnName = cast_or_null(Record.readSubExpr());
+  if (HasFunctionName)
+E->setFunctionName(cast(Record.readSubExpr()));
 }
 
 void ASTStmtReader::VisitDeclRefExpr(DeclRefExpr *E) {
@@ -2334,12 +2337,14 @@
   break;
 
 case STMT_CAPTURED:
-  S = CapturedStmt::CreateDeserialized(Context,
-   Record[ASTStmtReader::NumStmtFields]);
+  S = CapturedStmt::CreateDeserialized(
+  Context, Record[ASTStmtReader::NumStmtFields]);
   break;
 
 case EXPR_PREDEFINED:
-  S = new (Context) PredefinedExpr(Empty);
+  S = PredefinedExpr::CreateEmpty(
+  Context,
+  /*HasFunctionName*/ Record[ASTStmtReader::NumExprFields]);
   break;
 
 case EXPR_DECL_REF:
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -2096,8 +2096,8 @@
   /// By default, performs semantic analysis to build the new expression.
   /// Subclasses may override this routine to provide different behavior.
   ExprResult RebuildPredefinedExpr(SourceLocation Loc,
-   PredefinedExpr::IdentType IT) {
-return getSema().BuildPredefinedExpr(Loc, IT);
+   PredefinedExpr::IdentKind IK) {
+return getSema().BuildPredefinedExpr(Loc, IK);
   }
 
   /// Build a new expression that references a declaration.
@@ -8921,7 +8921,7 @@
 return E;
 
   return getDerived().RebuildPredefinedExpr(E->getLocation(),
-E->getIdentType());
+E->getIdentKind());
 }
 
 template
Index: lib/Sema/SemaTemplateInstantiate.cpp
===
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -1167,7 +1167,7 @@
   if (!E->isTypeDependent())
 return E;
 
-  return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentType());
+  return getSema().BuildPredefinedExpr(E->getLocation(), E->getIdentKind());
 }
 
 ExprResult
Index: lib/Sema/SemaExpr.cpp
===
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -3036,7 +3036,7 @@
 }
 
 ExprResult Sema::BuildPredefinedExpr(SourceLocation Loc,
- PredefinedExpr::IdentType IT) {
+ PredefinedExpr::IdentKind IK) {
   // Pick the current block, lambda, captured statement or function.
   Decl *currentDecl = nullptr;
   if (const BlockScopeInfo *BSI = getCurBlock())
@@ -3060,11 +3060,11 @@
   els

[PATCH] D53607: [AST] Only store the needed data in IfStmt.

2018-10-26 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171332.
riccibruno added a reviewer: rsmith.
riccibruno added a comment.

Add a flag to the output of -ast-dump indicating
which sub-statement `IfStmt` is storing. This removes
the ambiguity in the output of -ast-dump and addresses
rsmith's comment in https://reviews.llvm.org/D53717.


Repository:
  rC Clang

https://reviews.llvm.org/D53607

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Analysis/BodyFarm.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/if-stmt/test.cpp
  test/Misc/ast-dump-invalid.cpp

Index: test/Misc/ast-dump-invalid.cpp
===
--- test/Misc/ast-dump-invalid.cpp
+++ test/Misc/ast-dump-invalid.cpp
@@ -33,8 +33,6 @@
 // CHECK-NEXT:   |-ParmVarDecl
 // CHECK-NEXT:   `-CompoundStmt
 // CHECK-NEXT: `-IfStmt {{.*}} 
-// CHECK-NEXT:   |-<<>>
-// CHECK-NEXT:   |-<<>>
 // CHECK-NEXT:   |-OpaqueValueExpr {{.*}} <> 'bool'
 // CHECK-NEXT:   |-ReturnStmt {{.*}} 
 // CHECK-NEXT:   | `-IntegerLiteral {{.*}}  'int' 4
@@ -50,15 +48,15 @@
 { return 45; }
 }
 // CHECK: NamespaceDecl {{.*}} <{{.*}}> {{.*}} TestInvalidFunctionDecl
-// CHECK-NEXT: |-CXXRecordDecl {{.*}}  line:46:8 struct Str definition
+// CHECK-NEXT: |-CXXRecordDecl {{.*}}  line:44:8 struct Str definition
 // CHECK:  | |-CXXRecordDecl {{.*}}  col:8 implicit struct Str
-// CHECK-NEXT: | `-CXXMethodDecl {{.*}}  col:11 invalid foo1 'double (double, int)'
+// CHECK-NEXT: | `-CXXMethodDecl {{.*}}  col:11 invalid foo1 'double (double, int)'
 // CHECK-NEXT: |   |-ParmVarDecl {{.*}}  col:22 'double'
 // CHECK-NEXT: |   `-ParmVarDecl {{.*}} > col:36 invalid 'int'
-// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}}  line:49:13 invalid foo1 'double (double, int)'
+// CHECK-NEXT: `-CXXMethodDecl {{.*}} parent {{.*}}  line:47:13 invalid foo1 'double (double, int)'
 // CHECK-NEXT:   |-ParmVarDecl {{.*}}  col:24 'double'
 // CHECK-NEXT:   |-ParmVarDecl {{.*}} > col:38 invalid 'int'
-// CHECK-NEXT:   `-CompoundStmt {{.*}} 
+// CHECK-NEXT:   `-CompoundStmt {{.*}} 
 // CHECK-NEXT: `-ReturnStmt {{.*}} 
 // CHECK-NEXT:   `-ImplicitCastExpr {{.*}}  'double' 
 // CHECK-NEXT: `-IntegerLiteral {{.*}}  'int' 45
Index: test/Import/if-stmt/test.cpp
===
--- test/Import/if-stmt/test.cpp
+++ test/Import/if-stmt/test.cpp
@@ -1,41 +1,30 @@
 // RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: ImplicitCastExpr
 // CHECK-NEXT: ImplicitCastExpr
 // CHECK-NEXT: DeclRefExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
 
 // CHECK: IfStmt
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
-// CHECK-NEXT: <>
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: ReturnStmt
 // CHECK-NEXT: ReturnStmt
 
 // CHECK: IfStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: ReturnStmt
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -128,14 +128,29 @@
 
 void ASTStmtWriter::VisitIfStmt(IfStmt *S) {
   VisitStmt(S);
+
+  bool HasElse = S->getElse() != nullptr;
+  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
+  bool HasInit = S->getInit() != nullptr;
+
   Record.push_back(S->isConstexpr());
-  Record.AddStmt(S->getInit());
-  Record.AddDeclRef(S->getConditionVariable());
+  Record.push_back(HasElse);
+  Record.push_back(HasVar);
+  Record.push_back(HasInit);
+
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getThen());
-  Record.AddStmt(S->getElse());
+  if (HasElse)
+Record.AddStmt(S->getElse());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+  if (HasInit)
+Record.AddStmt(S->getInit());
+
   Record.AddSourceLocation(S->getIfLoc());
-  Record.AddSourceLocation(S->getElseLoc());
+  if (HasElse)
+Record.AddSourceLocation(S->getElseLoc());
+
   Code = serialization::STMT_IF;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -215,14 +215,24 @@
 
 void ASTStmtReader::VisitIfStmt(IfStmt *S) {
   VisitStmt(S);
+
   S->setConstexpr(Record.readInt());
-  S->setInit(Record.readSubStmt());
-  S->setConditionVariable(R

[PATCH] D53609: [AST] Don't store data for GNU range case statement if not needed.

2018-10-26 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171336.
riccibruno added a reviewer: rsmith.
riccibruno added a comment.

Add a flag in the output of -ast-dump to indicate that
a `CaseStmt` is a GNU range case statement, following
rsmith's comment in https://reviews.llvm.org/D53717


Repository:
  rC Clang

https://reviews.llvm.org/D53609

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/switch-stmt/test.cpp
  test/Misc/ast-dump-color.cpp

Index: test/Misc/ast-dump-color.cpp
===
--- test/Misc/ast-dump-color.cpp
+++ test/Misc/ast-dump-color.cpp
@@ -51,13 +51,11 @@
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| `-[[RESET]][[Blue]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]|   `-[[RESET]][[Blue]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}}
Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -7,10 +7,8 @@
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
@@ -22,11 +20,9 @@
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 // CHECK-NEXT: CaseStmt
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -96,10 +96,13 @@
 
 void ASTStmtWriter::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
+  Record.push_back(S->caseStmtIsGNURange());
   Record.AddStmt(S->getLHS());
-  Record.AddStmt(S->getRHS());
   Record.AddStmt(S->getSubStmt());
-  Record.AddSourceLocation(S->getEllipsisLoc());
+  if (S->caseStmtIsGNURange()) {
+Record.AddStmt(S->getRHS());
+Record.AddSourceLocation(S->getEllipsisLoc());
+  }
   Code = serialization::STMT_CASE;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -177,10 +177,13 @@
 
 void ASTStmtReader::VisitCaseStmt(CaseStmt *S) {
   VisitSwitchCase(S);
+  bool CaseStmtIsGNURange = Record.readInt();
   S->setLHS(Record.readSubExpr());
-  S->setRHS(Record.readSubExpr());
   S->setSubStmt(Record.readSubStmt());
-  S->setEllipsisLoc(ReadSourceLocation());
+  if (CaseStmtIsGNURange) {
+S->setRHS(Record.readSubExpr());
+S->setEllipsisLoc(ReadSourceLocation());
+  }
 }
 
 void ASTStmtReader::VisitDefaultStmt(DefaultStmt *S) {
@@ -2277,7 +2280,9 @@
   break;
 
 case STMT_CASE:
-  S = new 

[PATCH] D53714: [AST] Only store the needed data in SwitchStmt.

2018-10-26 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171337.
riccibruno added a reviewer: rsmith.
riccibruno added a comment.

Add a flag to the output of -ast-dump indicating which sub-statement
a `SwitchStmt` is storing. This removes the ambiguity in the output
of -ast-dump as per rsmith's comment in https://reviews.llvm.org/D53717.


Repository:
  rC Clang

https://reviews.llvm.org/D53714

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/switch-stmt/test.cpp
  test/Misc/ast-dump-color.cpp

Index: test/Misc/ast-dump-color.cpp
===
--- test/Misc/ast-dump-color.cpp
+++ test/Misc/ast-dump-color.cpp
@@ -46,7 +46,6 @@
 //CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]> [[Yellow]]line:9:6[[RESET]][[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void ()'[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[Blue:.\[0;34m]]<<>>[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}}
 //CHECK: {{^}}[[Blue]]| |   `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}}
 //CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}}
Index: test/Import/switch-stmt/test.cpp
===
--- test/Import/switch-stmt/test.cpp
+++ test/Import/switch-stmt/test.cpp
@@ -1,8 +1,6 @@
 // RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
 
 // CHECK: SwitchStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
@@ -22,7 +20,6 @@
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-SAME: varname
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: CompoundStmt
 // CHECK-NEXT: CaseStmt
@@ -37,15 +34,11 @@
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: DefaultStmt
 // CHECK-NEXT: BreakStmt
 
 // CHECK: SwitchStmt
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: NullStmt
 
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -159,12 +159,22 @@
 
 void ASTStmtWriter::VisitSwitchStmt(SwitchStmt *S) {
   VisitStmt(S);
-  Record.AddStmt(S->getInit());
-  Record.AddDeclRef(S->getConditionVariable());
+
+  bool HasInit = S->getInit() != nullptr;
+  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
+  Record.push_back(HasInit);
+  Record.push_back(HasVar);
+  Record.push_back(S->isAllEnumCasesCovered());
+
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getBody());
+  if (HasInit)
+Record.AddStmt(S->getInit());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+
   Record.AddSourceLocation(S->getSwitchLoc());
-  Record.push_back(S->isAllEnumCasesCovered());
+
   for (SwitchCase *SC = S->getSwitchCaseList(); SC;
SC = SC->getNextSwitchCase())
 Record.push_back(Writer.RecordSwitchCaseID(SC));
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -240,13 +240,21 @@
 
 void ASTStmtReader::VisitSwitchStmt(SwitchStmt *S) {
   VisitStmt(S);
-  S->setInit(Record.readSubStmt());
-  S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
+  bool HasInit = Record.readInt();
+  bool HasVar = Record.readInt();
+  bool AllEnumCasesCovered = Record.readInt();
+  if (AllEnumCasesCovered)
+S->setAllEnumCasesCovered();
+
   S->setCond(Record.readSubExpr());
   S->setBody(Record.readSubStmt());
+  if (HasInit)
+S->setInit(Record.readSubStmt());
+  if (HasVar)
+S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
   S->setSwitchLoc(ReadSourceLocation());
-  if (Record.readInt())
-S->setAllEnumCasesCovered();
 
   SwitchCase *PrevSC = nullptr;
   f

[PATCH] D53715: [AST] Only store the needed data in WhileStmt.

2018-10-26 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171338.
riccibruno added a reviewer: rsmith.
riccibruno added a comment.

Add a flag to the output of -ast-dump indicating which sub-statement
a `WhileStmt` is storing.


Repository:
  rC Clang

https://reviews.llvm.org/D53715

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/while-stmt/test.cpp

Index: test/Import/while-stmt/test.cpp
===
--- test/Import/while-stmt/test.cpp
+++ test/Import/while-stmt/test.cpp
@@ -1,12 +1,10 @@
 // RUN: clang-import-test -dump-ast -import %S/Inputs/F.cpp -expression %s | FileCheck %s
 
 // CHECK: WhileStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: NullStmt
 
 // CHECK: WhileStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: CXXBoolLiteralExpr
 // CHECK-NEXT: CompoundStmt
 
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -183,9 +183,15 @@
 
 void ASTStmtWriter::VisitWhileStmt(WhileStmt *S) {
   VisitStmt(S);
-  Record.AddDeclRef(S->getConditionVariable());
+
+  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
+  Record.push_back(HasVar);
+
   Record.AddStmt(S->getCond());
   Record.AddStmt(S->getBody());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+
   Record.AddSourceLocation(S->getWhileLoc());
   Code = serialization::STMT_WHILE;
 }
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -270,10 +270,14 @@
 
 void ASTStmtReader::VisitWhileStmt(WhileStmt *S) {
   VisitStmt(S);
-  S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
+  bool HasVar = Record.readInt();
 
   S->setCond(Record.readSubExpr());
   S->setBody(Record.readSubStmt());
+  if (HasVar)
+S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
   S->setWhileLoc(ReadSourceLocation());
 }
 
@@ -2323,7 +2327,9 @@
   break;
 
 case STMT_WHILE:
-  S = new (Context) WhileStmt(Empty);
+  S = WhileStmt::CreateEmpty(
+  Context,
+  /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 0]);
   break;
 
 case STMT_DO:
Index: lib/Sema/SemaStmt.cpp
===
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -1305,8 +1305,8 @@
   if (isa(Body))
 getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return new (Context)
-  WhileStmt(Context, CondVal.first, CondVal.second, Body, WhileLoc);
+  return WhileStmt::Create(Context, CondVal.first, CondVal.second, Body,
+   WhileLoc);
 }
 
 StmtResult
Index: lib/AST/Stmt.cpp
===
--- lib/AST/Stmt.cpp
+++ lib/AST/Stmt.cpp
@@ -978,32 +978,60 @@
   DeclStmt(DeclGroupRef(V), VarRange.getBegin(), VarRange.getEnd());
 }
 
-WhileStmt::WhileStmt(const ASTContext &C, VarDecl *Var, Expr *cond, Stmt *body,
- SourceLocation WL)
-  : Stmt(WhileStmtClass) {
-  setConditionVariable(C, Var);
-  SubExprs[COND] = cond;
-  SubExprs[BODY] = body;
-  WhileStmtBits.WhileLoc = WL;
+WhileStmt::WhileStmt(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
+ Stmt *Body, SourceLocation WL)
+: Stmt(WhileStmtClass) {
+  bool HasVar = Var != nullptr;
+  WhileStmtBits.HasVar = HasVar;
+
+  setCond(Cond);
+  setBody(Body);
+  if (HasVar)
+setConditionVariable(Ctx, Var);
+
+  setWhileLoc(WL);
 }
 
-VarDecl *WhileStmt::getConditionVariable() const {
-  if (!SubExprs[VAR])
-return nullptr;
+WhileStmt::WhileStmt(EmptyShell Empty, bool HasVar)
+: Stmt(WhileStmtClass, Empty) {
+  WhileStmtBits.HasVar = HasVar;
+}
+
+WhileStmt *WhileStmt::Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond,
+ Stmt *Body, SourceLocation WL) {
+  bool HasVar = Var != nullptr;
+  void *Mem =
+  Ctx.Allocate(totalSizeToAlloc(NumMandatoryStmtPtr + HasVar),
+   alignof(WhileStmt));
+  return new (Mem) WhileStmt(Ctx, Var, Cond, Body, WL);
+}
 
-  auto *DS = cast(SubExprs[VAR]);
+WhileStmt *WhileStmt::CreateEmpty(const ASTContext &Ctx, bool HasVar) {
+  void *Mem =
+  Ctx.Allocate(totalSizeToAlloc(NumMandatoryStmtPtr + HasVar),
+   alignof(WhileStmt));
+  return new (Mem) WhileStmt(EmptyShell(), HasVar);
+}
+
+VarDecl *WhileStmt::getConditionVariable() {
+  auto *DS = getConditionVariableDeclStmt();
+  if (!DS)
+return nullptr;
   return cast(DS->getSingleDecl());
 }
 
-void WhileStmt::setConditionVariable(const ASTContext &C, VarDecl *V) {
+void WhileStmt::setConditionVariable(const ASTContext &Ctx, VarDecl *V

[PATCH] D53717: [AST] Only store the needed data in ForStmt.

2018-10-26 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno updated this revision to Diff 171340.
riccibruno marked 6 inline comments as done.
riccibruno added a comment.

Add a flag in the output of -ast-dump indicating which sub-statement
the `ForStmt` is storing. This removes the ambiguity in the output
of -ast-dump.


Repository:
  rC Clang

https://reviews.llvm.org/D53717

Files:
  include/clang/AST/Stmt.h
  lib/AST/ASTDumper.cpp
  lib/AST/ASTImporter.cpp
  lib/AST/Stmt.cpp
  lib/Sema/SemaStmt.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  test/Import/for-stmt/test.cpp

Index: test/Import/for-stmt/test.cpp
===
--- test/Import/for-stmt/test.cpp
+++ test/Import/for-stmt/test.cpp
@@ -3,21 +3,17 @@
 // CHECK: ForStmt
 // CHECK-NEXT: <>
 // CHECK-NEXT: <>
-// CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: NullStmt
 
 // CHECK: ForStmt
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: IntegerLiteral
 // CHECK-NEXT: <>
 // CHECK-NEXT: <>
-// CHECK-NEXT: <>
 // CHECK-NEXT: ContinueStmt
 
 // CHECK: ForStmt
-// CHECK-NEXT: <>
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: CXXBoolLiteralExpr
@@ -32,7 +28,6 @@
 // CHECK-NEXT: DeclStmt
 // CHECK-NEXT: VarDecl
 // CHECK-NEXT: IntegerLiteral
-// CHECK-NEXT: <>
 
 // CHECK-NEXT: BinaryOperator
 // CHECK-NEXT: ImplicitCastExpr
Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -208,11 +208,20 @@
 
 void ASTStmtWriter::VisitForStmt(ForStmt *S) {
   VisitStmt(S);
-  Record.AddStmt(S->getInit());
+
+  bool HasInit = S->getInit() != nullptr;
+  bool HasVar = S->getConditionVariableDeclStmt() != nullptr;
+  Record.push_back(HasInit);
+  Record.push_back(HasVar);
+
   Record.AddStmt(S->getCond());
-  Record.AddDeclRef(S->getConditionVariable());
   Record.AddStmt(S->getInc());
   Record.AddStmt(S->getBody());
+  if (HasInit)
+Record.AddStmt(S->getInit());
+  if (HasVar)
+Record.AddDeclRef(S->getConditionVariable());
+
   Record.AddSourceLocation(S->getForLoc());
   Record.AddSourceLocation(S->getLParenLoc());
   Record.AddSourceLocation(S->getRParenLoc());
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -292,11 +292,18 @@
 
 void ASTStmtReader::VisitForStmt(ForStmt *S) {
   VisitStmt(S);
-  S->setInit(Record.readSubStmt());
+
+  bool HasInit = Record.readInt();
+  bool HasVar = Record.readInt();
+
   S->setCond(Record.readSubExpr());
-  S->setConditionVariable(Record.getContext(), ReadDeclAs());
   S->setInc(Record.readSubExpr());
   S->setBody(Record.readSubStmt());
+  if (HasInit)
+S->setInit(Record.readSubStmt());
+  if (HasVar)
+S->setConditionVariable(Record.getContext(), ReadDeclAs());
+
   S->setForLoc(ReadSourceLocation());
   S->setLParenLoc(ReadSourceLocation());
   S->setRParenLoc(ReadSourceLocation());
@@ -2342,7 +2349,10 @@
   break;
 
 case STMT_FOR:
-  S = new (Context) ForStmt(Empty);
+  S = ForStmt::CreateEmpty(
+  Context,
+  /* HasInit=*/Record[ASTStmtReader::NumStmtFields + 0],
+  /* HasVar=*/Record[ASTStmtReader::NumStmtFields + 1]);
   break;
 
 case STMT_GOTO:
Index: lib/Sema/SemaStmt.cpp
===
--- lib/Sema/SemaStmt.cpp
+++ lib/Sema/SemaStmt.cpp
@@ -1780,9 +1780,9 @@
   if (isa(Body))
 getCurCompoundScope().setHasEmptyLoopBodies();
 
-  return new (Context)
-  ForStmt(Context, First, Second.get().second, Second.get().first, Third,
-  Body, ForLoc, LParenLoc, RParenLoc);
+  return ForStmt::Create(Context, First, Second.get().second,
+ Second.get().first, Third, Body, ForLoc, LParenLoc,
+ RParenLoc);
 }
 
 /// In an Objective C collection iteration statement:
Index: lib/AST/Stmt.cpp
===
--- lib/AST/Stmt.cpp
+++ lib/AST/Stmt.cpp
@@ -881,36 +881,71 @@
   return isa(getCond());
 }
 
-ForStmt::ForStmt(const ASTContext &C, Stmt *Init, Expr *Cond, VarDecl *condVar,
- Expr *Inc, Stmt *Body, SourceLocation FL, SourceLocation LP,
- SourceLocation RP)
-  : Stmt(ForStmtClass), LParenLoc(LP), RParenLoc(RP)
-{
-  SubExprs[INIT] = Init;
-  setConditionVariable(C, condVar);
-  SubExprs[COND] = Cond;
-  SubExprs[INC] = Inc;
-  SubExprs[BODY] = Body;
-  ForStmtBits.ForLoc = FL;
-}
-
-VarDecl *ForStmt::getConditionVariable() const {
-  if (!SubExprs[CONDVAR])
-return nullptr;
+ForStmt::ForStmt(const ASTContext &Ctx, Stmt *Init, Expr *Cond,
+ VarDecl *CondVar, Expr *Inc, Stmt *Body, SourceLocation FL,
+ SourceLocation LP, SourceLocation RP)
+: Stmt(ForStmtClass), LParenLoc(LP), R

[PATCH] D56006: [AST] Fix a -Wimplicit-fallthrough warning in ScanfFormatString.cpp

2019-01-16 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno abandoned this revision.
riccibruno added a comment.

Nice, thanks!


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56006/new/

https://reviews.llvm.org/D56006



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D54324: [AST] Store the value of CharacterLiteral in the bit-fields of Stmt if possible

2019-01-18 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno abandoned this revision.
riccibruno added a comment.

This is not worth doing.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D54324/new/

https://reviews.llvm.org/D54324



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56959: [AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-19 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: include/clang/AST/Expr.h:5020
   Stmt **SubExprs;
   unsigned NumAssocs, ResultIndex;
   SourceLocation GenericLoc, DefaultLoc, RParenLoc;

I know that this is not part of this patch, but these arrays are begging
to be tail-allocated if you want to have a go at it.



Comment at: include/clang/AST/Expr.h:5047
+bool Selected;
+
+  public:

What about some comments ? I can guess but it is better to have
too much doc than not enough imho.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56959/new/

https://reviews.llvm.org/D56959



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56966: [clang-tidy] misc-non-private-member-variables-in-classes: ignore implicit methods

2019-01-20 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: 
docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst:9
 
-Finds classes that contain non-static data members in addition to non-static
-member functions and diagnose all data members declared with a non-``public``
-access specifier. The data members should be declared as ``private`` and
-accessed through member functions instead of exposed to derived classes or
-class consumers.
+Finds classes that contain non-static data members in addition to user-provided
+non-static member functions and diagnose all data members declared with a

Just a small remark: What do you mean exactly by "user-provided" ?

The term "user-provided" is defined in 11.4.2 [dcl.fct.def.default]/5 as

> A function is user-provided if it is user-declared and not explicitly
> defaulted or deleted on its first declaration.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56966/new/

https://reviews.llvm.org/D56966



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56966: [clang-tidy] misc-non-private-member-variables-in-classes: ignore implicit methods

2019-01-20 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: 
docs/clang-tidy/checks/misc-non-private-member-variables-in-classes.rst:9
 
-Finds classes that contain non-static data members in addition to non-static
-member functions and diagnose all data members declared with a non-``public``
-access specifier. The data members should be declared as ``private`` and
-accessed through member functions instead of exposed to derived classes or
-class consumers.
+Finds classes that contain non-static data members in addition to user-provided
+non-static member functions and diagnose all data members declared with a

lebedev.ri wrote:
> riccibruno wrote:
> > Just a small remark: What do you mean exactly by "user-provided" ?
> > 
> > The term "user-provided" is defined in 11.4.2 [dcl.fct.def.default]/5 as
> > 
> > > A function is user-provided if it is user-declared and not explicitly
> > > defaulted or deleted on its first declaration.
> Yeah, i'm not sure what is the right word to use here,
> suggestions welcomed.
> The previous wording was confusing too, since non-implicit can be read as [[ 
> https://en.cppreference.com/w/cpp/language/explicit | explicit specifier ]] 
> which is not what is meant.
A suggestion without looking at the rest of the patch:

It depends on whether you want to include explicitly defaulted/deleted
member functions. If yes, then use "user-declared" and otherwise
use "user-provided" ?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56966/new/

https://reviews.llvm.org/D56966



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56959: [AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-21 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: include/clang/AST/Expr.h:5068
 
+  Association getAssociation(unsigned I) const {
+return Association(cast(SubExprs[END_EXPR + I]), AssocTypes[I],

aaron.ballman wrote:
> steveire wrote:
> > aaron.ballman wrote:
> > > steveire wrote:
> > > > aaron.ballman wrote:
> > > > > Rather than gin these objects up on demand every time they're needed, 
> > > > > I'd prefer to see the class store `Association` objects directly. I 
> > > > > don't think it will be easy to do that and still support 
> > > > > `getAssocExprs()` and `getAssocTypeSourceInfos()`, so I think those 
> > > > > APIs should be removed in favor of this one. There's currently not 
> > > > > many uses of `getAssocExprs()` or `getAssocTypeSourceInfos()` (I spot 
> > > > > one each in Clang) so migration to the new API should not be onerous.
> > > > > 
> > > > > This should also have a range-based accessor version so that users 
> > > > > aren't required to use iterative loops to access the information (a 
> > > > > lot of the places you're already touching could use that range-based 
> > > > > interface).
> > > > I would prefer that too, but it doesn't seem to be possible. This is a 
> > > > sub-range of the `SubExprs` returned from `children()`. 
> > > > 
> > > > In theory, that could be split into two members, but then you would 
> > > > need a range library to recombine them and implement `children()`: 
> > > > https://godbolt.org/z/ZVamdC
> > > > 
> > > > This seems to be the best approach for now, and AFAIK it excludes a 
> > > > range-accessor.
> > > > I would prefer that too, but it doesn't seem to be possible. This is a 
> > > > sub-range of the SubExprs returned from children().
> > > 
> > > Ugh, you're right. :-(
> > > 
> > > > In theory, that could be split into two members, but then you would 
> > > > need a range library to recombine them and implement children(): 
> > > > https://godbolt.org/z/ZVamdC
> > > 
> > > We have zip iterators that could be used to implement this, I believe. 
> > > (see STLExtras.h)
> > > 
> > > Alternatively, we could tail-allocate the Association objects with 
> > > (perhaps references to) pointers back into the Expr tail-allocated array. 
> > > Not ideal, but does provide a clean interface.
> > > 
> > > @riccibruno may have other ideas on how to pack the arrays, as he's done 
> > > a lot of this work recently.
> > > We have zip iterators that could be used to implement this, I believe.
> > 
> > You're right, there is a `concat` there, but on second thought - because 
> > Association and Stmt don't share a base, I don't think it can work.
> > 
> > > Alternatively, we could tail-allocate the Association objects with 
> > > (perhaps references to) pointers back into the Expr tail-allocated array. 
> > > Not ideal, but does provide a clean interface.
> > 
> > Perhaps this can work, but I don't know how to do it. If you have scope for 
> > it in your part of the efforts, it would be a good way to get this 
> > unblocked.
> > Perhaps this can work, but I don't know how to do it. If you have scope for 
> > it in your part of the efforts, it would be a good way to get this 
> > unblocked.
> 
> I'll put some time into it today and see where it goes. You may be right that 
> this is more work than it's worth, so we'll see.
I don't see what would prevent tail-allocating the array of sub-expression and 
the array of `TypeSourceInfo`, and removing the `getAssocExpr`, 
`getAssocTypeSourceInfo`, `getAssocType` interface in favor of a single 
`getAssociation`. Then create a range version of `getAssociation` using the 
fact that if you know where you are in the sub-expression array, you know where 
is the corresponding `TypeSourceInfo`. To know which index correspond to the 
selected sub-expression you could use one of the low bits in the 
`TypeSourceInfo` pointers.

This means that `children` is still simple to implement, and users can use a 
single unified
interface via `getAssociation` and the range version `associations()`. From the 
point of view of the users it would be like if the `Association` objects were 
stored contiguously.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56959/new/

https://reviews.llvm.org/D56959



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D56959: [AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-21 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

Some small additional remarks if you are already modifying this class.




Comment at: include/clang/AST/Expr.h:5021
   unsigned NumAssocs, ResultIndex;
   SourceLocation GenericLoc, DefaultLoc, RParenLoc;
 

It is possible to stuff one `SourceLocation` in the bit-fields of `Stmt` to 
save one more pointer.



Comment at: include/clang/AST/Expr.h:5113
   SourceLocation getBeginLoc() const LLVM_READONLY { return GenericLoc; }
   SourceLocation getEndLoc() const LLVM_READONLY { return RParenLoc; }
 

I believe these `LLVM_READONLY` are pointless here.



Comment at: include/clang/AST/Expr.h:5125
   }
   friend class ASTStmtReader;
 };

Move this friend decl to the top ?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56959/new/

https://reviews.llvm.org/D56959



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57098: [WIP][AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: aaron.ballman, steveire.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Introduce `GenericSelectionExpr::Association` which wraps an association
expression and its `TypeSourceInfo`. Add the boilerplate necessary to use
ranges of `Associations`.

Additionally pack `GenericSelectionExpr` by tail-allocating the array of
selection expressions and `TypeSourceInfo`.

Note that this is just a draft following D56959 
.


Repository:
  rC Clang

https://reviews.llvm.org/D57098

Files:
  include/clang/AST/Expr.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/Stmt.h
  include/clang/AST/StmtDataCollectors.td
  lib/AST/ASTDumper.cpp
  lib/AST/Expr.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprObjC.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaPseudoObject.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp

Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -968,18 +968,21 @@
 
 void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   VisitExpr(E);
-  Record.push_back(E->getNumAssocs());
 
-  Record.AddStmt(E->getControllingExpr());
-  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
-Record.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I));
-Record.AddStmt(E->getAssocExpr(I));
-  }
+  Record.push_back(E->getNumAssocs());
   Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
-
   Record.AddSourceLocation(E->getGenericLoc());
   Record.AddSourceLocation(E->getDefaultLoc());
   Record.AddSourceLocation(E->getRParenLoc());
+
+  Stmt **Stmts = E->getTrailingObjects();
+  for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
+Record.AddStmt(Stmts[I]);
+
+  TypeSourceInfo **TSIs = E->getTrailingObjects();
+  for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
+Record.AddTypeSourceInfo(TSIs[I]);
+
   Code = serialization::EXPR_GENERIC_SELECTION;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -1022,21 +1022,22 @@
 
 void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   VisitExpr(E);
-  E->NumAssocs = Record.readInt();
-  E->AssocTypes = new (Record.getContext()) TypeSourceInfo*[E->NumAssocs];
-  E->SubExprs =
-   new(Record.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
-
-  E->SubExprs[GenericSelectionExpr::CONTROLLING] = Record.readSubExpr();
-  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
-E->AssocTypes[I] = GetTypeSourceInfo();
-E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Record.readSubExpr();
-  }
-  E->ResultIndex = Record.readInt();
 
-  E->GenericLoc = ReadSourceLocation();
+  unsigned NumAssocs = Record.readInt();
+  assert((NumAssocs == E->getNumAssocs()) && "Wrong NumAssocs!");
+  E->ResultIndex = Record.readInt();
+  E->GenericSelectionExprBits.GenericLoc = ReadSourceLocation();
   E->DefaultLoc = ReadSourceLocation();
   E->RParenLoc = ReadSourceLocation();
+
+  Stmt **Stmts = E->getTrailingObjects();
+  for (unsigned I = 0, N = NumAssocs + 1; I < N; ++I)
+Stmts[I] = Record.readSubExpr();
+
+  TypeSourceInfo **TSIs = E->getTrailingObjects();
+  for (unsigned I = 0, N = NumAssocs; I < N; ++I)
+TSIs[I] = GetTypeSourceInfo();
+  ;
 }
 
 void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
@@ -2675,7 +2676,9 @@
   break;
 
 case EXPR_GENERIC_SELECTION:
-  S = new (Context) GenericSelectionExpr(Empty);
+  S = GenericSelectionExpr::CreateEmpty(
+  Context,
+  /*NumAssocs=*/Record[ASTStmtReader::NumExprFields]);
   break;
 
 case EXPR_OBJC_STRING_LITERAL:
Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -9071,10 +9071,10 @@
 
   SmallVector AssocExprs;
   SmallVector AssocTypes;
-  for (unsigned i = 0; i != E->getNumAssocs(); ++i) {
-TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i);
-if (TS) {
-  TypeSourceInfo *AssocType = getDerived().TransformType(TS);
+  for (GenericSelectionExpr::Association Assoc : E->associations()) {
+TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
+if (TSI) {
+  TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
   if (!AssocType)
 return ExprError();
   AssocTypes.push_back(AssocType);
@@ -9082,7 +9082,8 @@
   AssocTypes.push_back(nullptr);
 }
 
-ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
+ExprResult AssocExpr =
+getDerived().TransformExpr(Assoc.getAssoci

[PATCH] D56959: [AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added inline comments.



Comment at: include/clang/AST/Expr.h:5068
 
+  Association getAssociation(unsigned I) const {
+return Association(cast(SubExprs[END_EXPR + I]), AssocTypes[I],

riccibruno wrote:
> aaron.ballman wrote:
> > steveire wrote:
> > > aaron.ballman wrote:
> > > > steveire wrote:
> > > > > aaron.ballman wrote:
> > > > > > Rather than gin these objects up on demand every time they're 
> > > > > > needed, I'd prefer to see the class store `Association` objects 
> > > > > > directly. I don't think it will be easy to do that and still 
> > > > > > support `getAssocExprs()` and `getAssocTypeSourceInfos()`, so I 
> > > > > > think those APIs should be removed in favor of this one. There's 
> > > > > > currently not many uses of `getAssocExprs()` or 
> > > > > > `getAssocTypeSourceInfos()` (I spot one each in Clang) so migration 
> > > > > > to the new API should not be onerous.
> > > > > > 
> > > > > > This should also have a range-based accessor version so that users 
> > > > > > aren't required to use iterative loops to access the information (a 
> > > > > > lot of the places you're already touching could use that 
> > > > > > range-based interface).
> > > > > I would prefer that too, but it doesn't seem to be possible. This is 
> > > > > a sub-range of the `SubExprs` returned from `children()`. 
> > > > > 
> > > > > In theory, that could be split into two members, but then you would 
> > > > > need a range library to recombine them and implement `children()`: 
> > > > > https://godbolt.org/z/ZVamdC
> > > > > 
> > > > > This seems to be the best approach for now, and AFAIK it excludes a 
> > > > > range-accessor.
> > > > > I would prefer that too, but it doesn't seem to be possible. This is 
> > > > > a sub-range of the SubExprs returned from children().
> > > > 
> > > > Ugh, you're right. :-(
> > > > 
> > > > > In theory, that could be split into two members, but then you would 
> > > > > need a range library to recombine them and implement children(): 
> > > > > https://godbolt.org/z/ZVamdC
> > > > 
> > > > We have zip iterators that could be used to implement this, I believe. 
> > > > (see STLExtras.h)
> > > > 
> > > > Alternatively, we could tail-allocate the Association objects with 
> > > > (perhaps references to) pointers back into the Expr tail-allocated 
> > > > array. Not ideal, but does provide a clean interface.
> > > > 
> > > > @riccibruno may have other ideas on how to pack the arrays, as he's 
> > > > done a lot of this work recently.
> > > > We have zip iterators that could be used to implement this, I believe.
> > > 
> > > You're right, there is a `concat` there, but on second thought - because 
> > > Association and Stmt don't share a base, I don't think it can work.
> > > 
> > > > Alternatively, we could tail-allocate the Association objects with 
> > > > (perhaps references to) pointers back into the Expr tail-allocated 
> > > > array. Not ideal, but does provide a clean interface.
> > > 
> > > Perhaps this can work, but I don't know how to do it. If you have scope 
> > > for it in your part of the efforts, it would be a good way to get this 
> > > unblocked.
> > > Perhaps this can work, but I don't know how to do it. If you have scope 
> > > for it in your part of the efforts, it would be a good way to get this 
> > > unblocked.
> > 
> > I'll put some time into it today and see where it goes. You may be right 
> > that this is more work than it's worth, so we'll see.
> I don't see what would prevent tail-allocating the array of sub-expression 
> and the array of `TypeSourceInfo`, and removing the `getAssocExpr`, 
> `getAssocTypeSourceInfo`, `getAssocType` interface in favor of a single 
> `getAssociation`. Then create a range version of `getAssociation` using the 
> fact that if you know where you are in the sub-expression array, you know 
> where is the corresponding `TypeSourceInfo`. To know which index correspond 
> to the selected sub-expression you could use one of the low bits in the 
> `TypeSourceInfo` pointers.
> 
> This means that `children` is still simple to implement, and users can use a 
> single unified
> interface via `getAssociation` and the range version `associations()`. From 
> the point of view of the users it would be like if the `Association` objects 
> were stored contiguously.
Made a patch which roughly the above idea: D57098


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D56959/new/

https://reviews.llvm.org/D56959



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57098: [WIP][AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno marked 13 inline comments as done.
riccibruno added a comment.

In D57098#1367769 , @aaron.ballman 
wrote:

> This is looking great! I've got some comments, mostly nits. Just to 
> double-check, have you verified that these changes do not break any existing 
> tests (in clang or clang-tools-extra)?


I ran the usual assert build/asan+assert build/msan+assert build.
To be clear I know that there are some changes required but I just wanted to 
put it out here to get
some feedback on the basic idea (which is to use some kind of proxy iterator).

Some added comments inline.




Comment at: include/clang/AST/Expr.h:5026
+  /// result expression in the case where the generic selection expression
+  /// is not result-dependent. The result index is equal to -1u if and only
+  /// if the generic selection expression is result-dependent.

aaron.ballman wrote:
> `~0U` instead of `-1u` so it doesn't suggest a weird type mismatch?
Yes indeed (or `std::numeric_limits::max()` as suggested below).



Comment at: include/clang/AST/Expr.h:5043
+  unsigned numTrailingObjects(OverloadToken) const {
+return 1 + getNumAssocs();
+  }

aaron.ballman wrote:
> I think it would be good to put a comment here like "Add one to account for 
> the controlling expression; the remainder are the associated expressions."
Will do.



Comment at: include/clang/AST/Expr.h:5094
+  public:
+using iterator_category = std::forward_iterator_tag;
+using value_type = AssociationTy;

aaron.ballman wrote:
> It seems like this should be pretty trivial to make into a random access 
> iterator, or am I missing something?
Indeed, at the cost of some boilerplate. I can totally do this but from what I 
understood the motivation was to use this in ranges, and for this a forward 
iterator is good enough (although see the next comment)



Comment at: include/clang/AST/Expr.h:5097
+using difference_type = std::ptrdiff_t;
+using pointer = AssociationTy;
+using reference = AssociationTy;

aaron.ballman wrote:
> Cute, but I suspect this may come back to bite us at some point. For 
> instance, if someone thinks they're working with a real pointer, they're 
> likely to expect pointer arithmetic to work when it won't (at least they'll 
> get compile errors though).
Hmm, but `pointer` is just the return type of `operator->` no ? Is it actually 
required to behave like a pointer ? The only requirement I can find is that 
`It->x` must be equivalent to `(*It).x`, which is true here.

Also looking at the requirements for forward iterators I think that this 
iterator should actually be downgraded to an input iterator, because of the 
requirement that `reference = T&`.



Comment at: include/clang/AST/Expr.h:5101
+AssociationTy operator*() const {
+  return AssociationTy(cast(*E), *TSI,
+  Offset == SelectedOffset);

aaron.ballman wrote:
> This should return `reference` instead.
yes



Comment at: include/clang/AST/Expr.h:5104
+}
+AssociationTy operator->() const { return **this; }
+AssociationIteratorTy &operator++() {

aaron.ballman wrote:
> This should return `pointer` instead.
yes



Comment at: include/clang/AST/Expr.h:5108
+  TSI += 1;
+  Offset += 1;
+  return *this;

yes



Comment at: include/clang/AST/Expr.h:5186
+  /// Whether this generic selection is result-dependent.
+  bool isResultDependent() const { return ResultIndex == -1U; }
 

aaron.ballman wrote:
> `std::numeric_limits::max()`?
yes



Comment at: include/clang/AST/Expr.h:5208
+  ArrayRef getAssocExprs() const {
+return {reinterpret_cast(getTrailingObjects() +
+ASSOC_EXPR_START),

aaron.ballman wrote:
> Do we need to use `reinterpret_cast` here, or can this be done through llvm's 
> casting machinery instead?
I believe that it is needed, because `Stmt **` is not otherwise convertible to 
`Expr **`. This is all over the place in the statement/expression nodes, and 
indeed it depends on the layout of `Expr` and `Stmt`.



Comment at: include/clang/AST/Expr.h:5219
+  Association getAssociation(unsigned I) {
+assert((I < getNumAssocs()) &&
+   "Out-of-range index in GenericSelectionExpr::getAssociation!");

aaron.ballman wrote:
> Spurious parens can be removed.
From the precedence rules yes, but I thought that some gcc bots were
warning about this (or maybe I am mistaken and this is in an other situation) 



Comment at: lib/Sema/SemaPseudoObject.cpp:148
+
+for (GenericSelectionExpr::Association Assoc : gse->associations()) {
+  Expr *assoc = Assoc.getAssociationExpr(

[PATCH] D57098: [WIP][AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno marked an inline comment as done.
riccibruno added inline comments.



Comment at: include/clang/AST/Expr.h:5208
+  ArrayRef getAssocExprs() const {
+return {reinterpret_cast(getTrailingObjects() +
+ASSOC_EXPR_START),

riccibruno wrote:
> aaron.ballman wrote:
> > Do we need to use `reinterpret_cast` here, or can this be done through 
> > llvm's casting machinery instead?
> I believe that it is needed, because `Stmt **` is not otherwise convertible 
> to `Expr **`. This is all over the place in the statement/expression nodes, 
> and indeed it depends on the layout of `Expr` and `Stmt`.
Ugh ignore the comment about the layout. I was thinking about the 
`reinterpret_cast`s between `Stmt *` and `Expr *` in `Stmt.h`


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57098/new/

https://reviews.llvm.org/D57098



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57098: [WIP][AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno added a comment.

In D57098#1367816 , @steveire wrote:

> Thanks for doing this!
>
> It would be easier to review (now and in the future!) if you split it into at 
> least 3 commits
>
> - Refactor use trailing objects without introducing the Association class
> - The change to use bitfields and Stmt.h
> - Introduce new class GenericSelectionExpr::Association
>
>   Thanks,
>
>   Stephen


Is it okay if I split it into:

1. `llvm::TrailingObjects` + bit-fields of `Stmt`
2. Introduce `GenericSelectionExpr::Association`

since using `llvm::TrailingObjects` and using the bit-fields of `Stmt` are 
closely related
and come under the title "[AST] Pack GenericSelectionExpr".


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57098/new/

https://reviews.llvm.org/D57098



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57104: [AST] Pack GenericSelectionExpr

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: aaron.ballman, steveire.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Store the controlling expression, the association expressions and the 
corresponding
`TypeSourceInfo`s as trailing objects.

Additionally use the bit-fields of `Stmt` to store one `SourceLocation`, saving 
one
additional pointer. This saves 3 pointers in total per `GenericSelectionExpr`.


Repository:
  rC Clang

https://reviews.llvm.org/D57104

Files:
  include/clang/AST/Expr.h
  include/clang/AST/Stmt.h
  lib/AST/Expr.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/SemaExprObjC.cpp
  lib/Sema/SemaOverload.cpp
  lib/Sema/SemaPseudoObject.cpp
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp

Index: lib/Serialization/ASTWriterStmt.cpp
===
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -968,18 +968,21 @@
 
 void ASTStmtWriter::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   VisitExpr(E);
-  Record.push_back(E->getNumAssocs());
-
-  Record.AddStmt(E->getControllingExpr());
-  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
-Record.AddTypeSourceInfo(E->getAssocTypeSourceInfo(I));
-Record.AddStmt(E->getAssocExpr(I));
-  }
-  Record.push_back(E->isResultDependent() ? -1U : E->getResultIndex());
 
+  Record.push_back(E->getNumAssocs());
+  Record.push_back(E->ResultIndex);
   Record.AddSourceLocation(E->getGenericLoc());
   Record.AddSourceLocation(E->getDefaultLoc());
   Record.AddSourceLocation(E->getRParenLoc());
+
+  Stmt **Stmts = E->getTrailingObjects();
+  for (unsigned I = 0, N = E->getNumAssocs() + 1; I < N; ++I)
+Record.AddStmt(Stmts[I]);
+
+  TypeSourceInfo **TSIs = E->getTrailingObjects();
+  for (unsigned I = 0, N = E->getNumAssocs(); I < N; ++I)
+Record.AddTypeSourceInfo(TSIs[I]);
+
   Code = serialization::EXPR_GENERIC_SELECTION;
 }
 
Index: lib/Serialization/ASTReaderStmt.cpp
===
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -1022,21 +1022,21 @@
 
 void ASTStmtReader::VisitGenericSelectionExpr(GenericSelectionExpr *E) {
   VisitExpr(E);
-  E->NumAssocs = Record.readInt();
-  E->AssocTypes = new (Record.getContext()) TypeSourceInfo*[E->NumAssocs];
-  E->SubExprs =
-   new(Record.getContext()) Stmt*[GenericSelectionExpr::END_EXPR+E->NumAssocs];
-
-  E->SubExprs[GenericSelectionExpr::CONTROLLING] = Record.readSubExpr();
-  for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) {
-E->AssocTypes[I] = GetTypeSourceInfo();
-E->SubExprs[GenericSelectionExpr::END_EXPR+I] = Record.readSubExpr();
-  }
-  E->ResultIndex = Record.readInt();
 
-  E->GenericLoc = ReadSourceLocation();
+  unsigned NumAssocs = Record.readInt();
+  assert(NumAssocs == E->getNumAssocs() && "Wrong NumAssocs!");
+  E->ResultIndex = Record.readInt();
+  E->GenericSelectionExprBits.GenericLoc = ReadSourceLocation();
   E->DefaultLoc = ReadSourceLocation();
   E->RParenLoc = ReadSourceLocation();
+
+  Stmt **Stmts = E->getTrailingObjects();
+  for (unsigned I = 0, N = NumAssocs + 1; I < N; ++I)
+Stmts[I] = Record.readSubExpr();
+
+  TypeSourceInfo **TSIs = E->getTrailingObjects();
+  for (unsigned I = 0, N = NumAssocs; I < N; ++I)
+TSIs[I] = GetTypeSourceInfo();
 }
 
 void ASTStmtReader::VisitPseudoObjectExpr(PseudoObjectExpr *E) {
@@ -2675,7 +2675,9 @@
   break;
 
 case EXPR_GENERIC_SELECTION:
-  S = new (Context) GenericSelectionExpr(Empty);
+  S = GenericSelectionExpr::CreateEmpty(
+  Context,
+  /*NumAssocs=*/Record[ASTStmtReader::NumExprFields]);
   break;
 
 case EXPR_OBJC_STRING_LITERAL:
Index: lib/Sema/SemaPseudoObject.cpp
===
--- lib/Sema/SemaPseudoObject.cpp
+++ lib/Sema/SemaPseudoObject.cpp
@@ -150,15 +150,10 @@
   assocTypes[i] = gse->getAssocTypeSourceInfo(i);
 }
 
-return new (S.Context) GenericSelectionExpr(S.Context,
-gse->getGenericLoc(),
-gse->getControllingExpr(),
-assocTypes,
-assocs,
-gse->getDefaultLoc(),
-gse->getRParenLoc(),
-  gse->containsUnexpandedParameterPack(),
-resultIndex);
+return GenericSelectionExpr::Create(
+S.Context, gse->getGenericLoc(), gse->getControllingExpr(),
+assocTypes, assocs, gse->getDefaultLoc(), gse->getRParenLoc(),
+gse->containsUnexpandedParameterPack(), resultIndex);
   }
 
   if (ChooseExp

[PATCH] D57106: [AST] Introduce GenericSelectionExpr::Association

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno created this revision.
riccibruno added reviewers: aaron.ballman, steveire.
riccibruno added a project: clang.
Herald added a subscriber: cfe-commits.

Introduce a new class `GenericSelectionExpr::Association` which bundle together
an association expression and its `TypeSourceInfo`.

An iterator `GenericSelectionExpr::AssociationIterator` is additionally added 
to make
it possible to iterator over ranges of `Associations`. This iterator is a kind 
of proxy
iterator which abstract how exactly the expressions and the `TypeSourceInfo`s 
are stored.

Note: I have addressed all but 3 of the inline comments in D57098 
. The unaddressed comments
are still marked "not done" in D57098 .


Repository:
  rC Clang

https://reviews.llvm.org/D57106

Files:
  include/clang/AST/Expr.h
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/StmtDataCollectors.td
  lib/AST/ASTDumper.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/Sema/SemaExprObjC.cpp
  lib/Sema/SemaPseudoObject.cpp
  lib/Sema/TreeTransform.h

Index: lib/Sema/TreeTransform.h
===
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -9071,10 +9071,10 @@
 
   SmallVector AssocExprs;
   SmallVector AssocTypes;
-  for (unsigned i = 0; i != E->getNumAssocs(); ++i) {
-TypeSourceInfo *TS = E->getAssocTypeSourceInfo(i);
-if (TS) {
-  TypeSourceInfo *AssocType = getDerived().TransformType(TS);
+  for (GenericSelectionExpr::Association Assoc : E->associations()) {
+TypeSourceInfo *TSI = Assoc.getTypeSourceInfo();
+if (TSI) {
+  TypeSourceInfo *AssocType = getDerived().TransformType(TSI);
   if (!AssocType)
 return ExprError();
   AssocTypes.push_back(AssocType);
@@ -9082,7 +9082,8 @@
   AssocTypes.push_back(nullptr);
 }
 
-ExprResult AssocExpr = getDerived().TransformExpr(E->getAssocExpr(i));
+ExprResult AssocExpr =
+getDerived().TransformExpr(Assoc.getAssociationExpr());
 if (AssocExpr.isInvalid())
   return ExprError();
 AssocExprs.push_back(AssocExpr.get());
Index: lib/Sema/SemaPseudoObject.cpp
===
--- lib/Sema/SemaPseudoObject.cpp
+++ lib/Sema/SemaPseudoObject.cpp
@@ -140,19 +140,22 @@
 unsigned resultIndex = gse->getResultIndex();
 unsigned numAssocs = gse->getNumAssocs();
 
-SmallVector assocs(numAssocs);
-SmallVector assocTypes(numAssocs);
-
-for (unsigned i = 0; i != numAssocs; ++i) {
-  Expr *assoc = gse->getAssocExpr(i);
-  if (i == resultIndex) assoc = rebuild(assoc);
-  assocs[i] = assoc;
-  assocTypes[i] = gse->getAssocTypeSourceInfo(i);
+SmallVector assocExprs;
+SmallVector assocTypes;
+assocExprs.reserve(numAssocs);
+assocTypes.reserve(numAssocs);
+
+for (GenericSelectionExpr::Association assoc : gse->associations()) {
+  Expr *assocExpr = assoc.getAssociationExpr();
+  if (assoc.isSelected())
+assocExpr = rebuild(assocExpr);
+  assocExprs.push_back(assocExpr);
+  assocTypes.push_back(assoc.getTypeSourceInfo());
 }
 
 return GenericSelectionExpr::Create(
 S.Context, gse->getGenericLoc(), gse->getControllingExpr(),
-assocTypes, assocs, gse->getDefaultLoc(), gse->getRParenLoc(),
+assocTypes, assocExprs, gse->getDefaultLoc(), gse->getRParenLoc(),
 gse->containsUnexpandedParameterPack(), resultIndex);
   }
 
Index: lib/Sema/SemaExprObjC.cpp
===
--- lib/Sema/SemaExprObjC.cpp
+++ lib/Sema/SemaExprObjC.cpp
@@ -4332,14 +4332,16 @@
 assert(!gse->isResultDependent());
 
 unsigned n = gse->getNumAssocs();
-SmallVector subExprs(n);
-SmallVector subTypes(n);
-for (unsigned i = 0; i != n; ++i) {
-  subTypes[i] = gse->getAssocTypeSourceInfo(i);
-  Expr *sub = gse->getAssocExpr(i);
-  if (i == gse->getResultIndex())
+SmallVector subExprs;
+SmallVector subTypes;
+subExprs.reserve(n);
+subTypes.reserve(n);
+for (GenericSelectionExpr::Association assoc : gse->associations()) {
+  subTypes.push_back(assoc.getTypeSourceInfo());
+  Expr *sub = assoc.getAssociationExpr();
+  if (assoc.isSelected())
 sub = stripARCUnbridgedCast(sub);
-  subExprs[i] = sub;
+  subExprs.push_back(sub);
 }
 
 return GenericSelectionExpr::Create(
Index: lib/AST/StmtProfile.cpp
===
--- lib/AST/StmtProfile.cpp
+++ lib/AST/StmtProfile.cpp
@@ -1259,13 +1259,13 @@
 
 void StmtProfiler::VisitGenericSelectionExpr(const GenericSelectionExpr *S) {
   VisitExpr(S);
-  for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
-QualType T = S->getAssocType(i);
+  for (GenericSe

[PATCH] D57098: [WIP][AST] NFC: Introduce new class GenericSelectionExpr::Association

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno marked 18 inline comments as done.
riccibruno added a comment.

In D57098#1367853 , @steveire wrote:

> In D57098#1367852 , @riccibruno 
> wrote:
>
> > In D57098#1367816 , @steveire 
> > wrote:
> >
> > > Thanks for doing this!
> > >
> > > It would be easier to review (now and in the future!) if you split it 
> > > into at least 3 commits
> > >
> > > - Refactor use trailing objects without introducing the Association class
> > > - The change to use bitfields and Stmt.h
> > > - Introduce new class GenericSelectionExpr::Association
> > >
> > >   Thanks,
> > >
> > >   Stephen
> >
> >
> > Is it okay if I split it into:
> >
> > 1. `llvm::TrailingObjects` + bit-fields of `Stmt`
> > 2. Introduce `GenericSelectionExpr::Association`
> >
> >   since using `llvm::TrailingObjects` and using the bit-fields of `Stmt` 
> > are closely related and come under the title "[AST] Pack 
> > GenericSelectionExpr".
>
>
> I didn't realize that, so your proposal sounds good to me!


Split into D57104  and D57106 



Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57098/new/

https://reviews.llvm.org/D57098



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D57104: [AST] Pack GenericSelectionExpr

2019-01-23 Thread Bruno Ricci via Phabricator via cfe-commits
riccibruno marked an inline comment as done.
riccibruno added a comment.

In D57104#1368055 , @steveire wrote:

> Splitting the introduction of and porting to `Create` would significantly 
> reduce the number of files touched by the 'real' change in this commit, and 
> therefore reduce noise in the commit (following the idea of "do one thing per 
> commit" to make the code reviewable in the future).
>
> However, if you're opposed to that, it's not a hard requirement.


To be honest I don't really see the point. This is just the usual pattern of 
having a `Create` function doing the allocation,
which then dispatch to the private constructor with a placement new for the 
initialization.




Comment at: include/clang/AST/Expr.h:5048
+// are the associated expressions.
+return 1 + getNumAssocs();
+  }

steveire wrote:
> Would it be correct to use `ASSOC_EXPR_START` here instead of the magic `1`?
Eh maybe ?


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D57104/new/

https://reviews.llvm.org/D57104



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


  1   2   3   4   5   6   7   >