llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-modules

Author: Matheus Izvekov (mizvekov)

<details>
<summary>Changes</summary>

This is a small refactor of how DeducedType and it's derived types are 
represented.

The different deduction kinds are spelled out in an enum, and how this is 
tracked is simplified, to allow easier profiling.

How these types are constructed and canonicalized is also brought more in line 
with how it works for the other types.

This fixes a crash reported here: 
https://github.com/llvm/llvm-project/issues/167513#issuecomment-3692962115

---

Patch is 50.83 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/186727.diff


20 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+1) 
- (modified) clang/include/clang/AST/ASTContext.h (+5-18) 
- (modified) clang/include/clang/AST/PropertiesBase.td (+1) 
- (modified) clang/include/clang/AST/TextNodeDumper.h (+1) 
- (modified) clang/include/clang/AST/TypeBase.h (+81-38) 
- (modified) clang/include/clang/AST/TypeProperties.td (+9-18) 
- (modified) clang/lib/AST/ASTContext.cpp (+82-91) 
- (modified) clang/lib/AST/ASTImporter.cpp (+8-8) 
- (modified) clang/lib/AST/TextNodeDumper.cpp (+20-4) 
- (modified) clang/lib/AST/Type.cpp (+48-20) 
- (modified) clang/lib/Sema/SemaDecl.cpp (+2-1) 
- (modified) clang/lib/Sema/SemaTemplate.cpp (+2-1) 
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+14-8) 
- (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+3-3) 
- (modified) clang/lib/Sema/SemaType.cpp (+3-3) 
- (modified) clang/lib/Sema/TreeTransform.h (+14-16) 
- (modified) clang/test/AST/ast-dump-concepts.cpp (+10-4) 
- (modified) clang/test/SemaTemplate/ctad.cpp (+9-1) 
- (modified) clang/unittests/AST/ProfilingTest.cpp (+4-2) 
- (modified) lldb/unittests/Symbol/TestTypeSystemClang.cpp (+3-3) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index cb5d1c235951f..c33c5df978e64 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -344,6 +344,7 @@ Bug Fixes to C++ Support
 - Fixed an incorrect template argument deduction when matching packs of 
template
   template parameters when one of its parameters is also a pack. (#GH181166)
 - Fixed a crash when a default argument is passed to an explicit object 
parameter. (#GH176639)
+- Fixed an alias template CTAD crash.
 - Fixed a crash when diagnosing an invalid static member function with an 
explicit object parameter (#GH177741)
 - Fixed a crash when pack expansions are used as arguments for non-pack 
parameters of built-in templates. (#GH180307)
 - Fixed a bug where captured variables in non-mutable lambdas were incorrectly 
treated as mutable 
diff --git a/clang/include/clang/AST/ASTContext.h 
b/clang/include/clang/AST/ASTContext.h
index 05302c30d18d1..560248ea2224e 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -1839,12 +1839,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
   QualType getFunctionTypeInternal(QualType ResultTy, ArrayRef<QualType> Args,
                                    const FunctionProtoType::ExtProtoInfo &EPI,
                                    bool OnlyWantCanonical) const;
-  QualType
-  getAutoTypeInternal(QualType DeducedType, AutoTypeKeyword Keyword,
-                      bool IsDependent, bool IsPack = false,
-                      TemplateDecl *TypeConstraintConcept = nullptr,
-                      ArrayRef<TemplateArgument> TypeConstraintArgs = {},
-                      bool IsCanon = false) const;
 
 public:
   QualType getTypeDeclType(ElaboratedTypeKeyword Keyword,
@@ -2084,8 +2078,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
 
   /// C++11 deduced auto type.
   QualType
-  getAutoType(QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent,
-              bool IsPack = false,
+  getAutoType(DeducedKind DK, QualType DeducedAsType, AutoTypeKeyword Keyword,
               TemplateDecl *TypeConstraintConcept = nullptr,
               ArrayRef<TemplateArgument> TypeConstraintArgs = {}) const;
 
@@ -2100,17 +2093,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
   QualType getUnconstrainedType(QualType T) const;
 
   /// C++17 deduced class template specialization type.
-  QualType getDeducedTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
-                                                TemplateName Template,
-                                                QualType DeducedType,
-                                                bool IsDependent) const;
-
-private:
-  QualType getDeducedTemplateSpecializationTypeInternal(
-      ElaboratedTypeKeyword Keyword, TemplateName Template,
-      QualType DeducedType, bool IsDependent, QualType Canon) const;
+  QualType getDeducedTemplateSpecializationType(DeducedKind DK,
+                                                QualType DeducedAsType,
+                                                ElaboratedTypeKeyword Keyword,
+                                                TemplateName Template) const;
 
-public:
   /// Return the unique type for "size_t" (C99 7.17), defined in
   /// <stddef.h>.
   ///
diff --git a/clang/include/clang/AST/PropertiesBase.td 
b/clang/include/clang/AST/PropertiesBase.td
index 0011e57ed5ef7..fd3cce10be303 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -77,6 +77,7 @@ def APValueKind : EnumPropertyType<"APValue::ValueKind">;
 def ArraySizeModifier : EnumPropertyType<"ArraySizeModifier">;
 def AttrKind : EnumPropertyType<"attr::Kind">;
 def Attr : PropertyType<"const Attr *">;
+def DeducedKind : EnumPropertyType;
 def AutoTypeKeyword : EnumPropertyType;
 def Bool : PropertyType<"bool">;
 def BuiltinTypeKind : EnumPropertyType<"BuiltinType::Kind">;
diff --git a/clang/include/clang/AST/TextNodeDumper.h 
b/clang/include/clang/AST/TextNodeDumper.h
index ba68063eeae75..32e83ebb5c8eb 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -343,6 +343,7 @@ class TextNodeDumper
   void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T);
   void
   VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T);
+  void VisitDeducedType(const DeducedType *T);
   void VisitAutoType(const AutoType *T);
   void VisitDeducedTemplateSpecializationType(
       const DeducedTemplateSpecializationType *T);
diff --git a/clang/include/clang/AST/TypeBase.h 
b/clang/include/clang/AST/TypeBase.h
index ec7845c3b3adb..8802b15d99034 100644
--- a/clang/include/clang/AST/TypeBase.h
+++ b/clang/include/clang/AST/TypeBase.h
@@ -1794,6 +1794,33 @@ enum RefQualifierKind {
   RQ_RValue
 };
 
+// The kind of type deduction represented by a DeducedType (ie AutoType).
+enum class DeducedKind {
+  /// Not deduced yet. This is for example an 'auto' which was just parsed.
+  Undeduced,
+
+  /// The normal deduced case. For example, an 'auto' which has been deduced to
+  /// 'int' will be of this kind, with 'int' as the deduced-as type. This is 
the
+  /// only case where the node is sugar.
+  Deduced,
+
+  /// This is a special case where the initializer is dependent, so we can't
+  /// deduce a type yet. For example, 'auto x = V' where 'V' is a
+  /// value-dependent expression.
+  /// Formally we can't deduce an initializer which is dependent, because for
+  /// one reason it might be non-instantiable (ie it can contain a placeholder
+  /// dependent type such as DependentTy, which cannot be instantiated).
+  /// In general TreeTransform will turn these back to 'Undeduced' so we can 
try
+  /// to deduce them again.
+  DeducedAsDependent,
+
+  /// Same as above, but additionally this represents a case where the deduced
+  /// entity itself is a pack.
+  /// This currently only happens for a lambda init-capture pack, which always
+  /// uses AutoType.
+  DeducedAsPack,
+};
+
 /// Which keyword(s) were used to create an AutoType.
 enum class AutoTypeKeyword {
   /// auto
@@ -2108,11 +2135,25 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
     unsigned AttrKind : 32 - NumTypeBits;
   };
 
+  class DeducedTypeBitfields {
+    friend class DeducedType;
+
+    // One of the base classes uses the KeywordWrapper, so reserve those bits.
+    LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
+    unsigned : NumTypeWithKeywordBits;
+
+    /// The kind of deduction this type represents, ie 'undeduced' or 
otherwise.
+    LLVM_PREFERRED_TYPE(DeducedKind)
+    unsigned Kind : 2;
+  };
+
+  static constexpr int NumDeducedTypeBits = NumTypeBits + 2;
+
   class AutoTypeBitfields {
     friend class AutoType;
 
-    LLVM_PREFERRED_TYPE(TypeBitfields)
-    unsigned : NumTypeBits;
+    LLVM_PREFERRED_TYPE(DeducedTypeBitfields)
+    unsigned : NumDeducedTypeBits;
 
     /// Was this placeholder type spelled as 'auto', 'decltype(auto)',
     /// or '__auto_type'?  AutoTypeKeyword value.
@@ -2320,6 +2361,7 @@ class alignas(TypeAlignment) Type : public 
ExtQualsTypeCommonBase {
     ArrayTypeBitfields ArrayTypeBits;
     ConstantArrayTypeBitfields ConstantArrayTypeBits;
     AttributedTypeBitfields AttributedTypeBits;
+    DeducedTypeBitfields DeducedTypeBits;
     AutoTypeBitfields AutoTypeBits;
     TypeOfBitfields TypeOfBits;
     TypedefBitfields TypedefBits;
@@ -7232,17 +7274,20 @@ class DeducedType : public Type {
   QualType DeducedAsType;
 
 protected:
-  DeducedType(TypeClass TC, QualType DeducedAsType,
-              TypeDependence ExtraDependence, QualType Canon)
-      : Type(TC, Canon,
-             ExtraDependence | (DeducedAsType.isNull()
-                                    ? TypeDependence::None
-                                    : DeducedAsType->getDependence() &
-                                          ~TypeDependence::VariablyModified)),
-        DeducedAsType(DeducedAsType) {}
+  DeducedType(TypeClass TC, DeducedKind DK, QualType DeducedAsTypeOrCanon);
+
+  static void Profile(llvm::FoldingSetNodeID &ID, DeducedKind DK,
+                      QualType Deduced) {
+    ID.AddInteger(llvm::to_underlying(DK));
+    Deduced.Profile(ID);
+  }
 
 public:
-  bool isSugared() const { return !DeducedAsType.isNull(); }
+  DeducedKind getDeducedKind() const {
+    return static_cast<DeducedKind>(DeducedTypeBits.Kind);
+  }
+
+  bool isSugared() const { return getDeducedKind() == DeducedKind::Deduced; }
   QualType desugar() const {
     return isSugared() ? DeducedAsType : QualType(this, 0);
   }
@@ -7250,9 +7295,7 @@ class DeducedType : public Type {
   /// Get the type deduced for this placeholder type, or null if it
   /// has not been deduced.
   QualType getDeducedType() const { return DeducedAsType; }
-  bool isDeduced() const {
-    return !DeducedAsType.isNull() || isDependentType();
-  }
+  bool isDeduced() const { return getDeducedKind() != DeducedKind::Undeduced; }
 
   static bool classof(const Type *T) {
     return T->getTypeClass() == Auto ||
@@ -7262,13 +7305,13 @@ class DeducedType : public Type {
 
 /// Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained
 /// by a type-constraint.
-class AutoType : public DeducedType {
+class AutoType : public DeducedType, public llvm::FoldingSetNode {
   friend class ASTContext; // ASTContext creates these
 
   TemplateDecl *TypeConstraintConcept;
 
-  AutoType(QualType DeducedAsType, AutoTypeKeyword Keyword,
-           TypeDependence ExtraDependence, QualType Canon, TemplateDecl *CD,
+  AutoType(DeducedKind DK, QualType DeducedAsTypeOrCanon,
+           AutoTypeKeyword Keyword, TemplateDecl *TypeConstraintConcept,
            ArrayRef<TemplateArgument> TypeConstraintArgs);
 
 public:
@@ -7299,9 +7342,8 @@ class AutoType : public DeducedType {
 
   void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context);
   static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context,
-                      QualType Deduced, AutoTypeKeyword Keyword,
-                      bool IsDependent, TemplateDecl *CD,
-                      ArrayRef<TemplateArgument> Arguments);
+                      DeducedKind DK, QualType Deduced, AutoTypeKeyword 
Keyword,
+                      TemplateDecl *CD, ArrayRef<TemplateArgument> Arguments);
 
   static bool classof(const Type *T) {
     return T->getTypeClass() == Auto;
@@ -7316,34 +7358,35 @@ class DeducedTemplateSpecializationType : public 
KeywordWrapper<DeducedType>,
   /// The name of the template whose arguments will be deduced.
   TemplateName Template;
 
-  DeducedTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
-                                    TemplateName Template,
-                                    QualType DeducedAsType,
-                                    bool IsDeducedAsDependent, QualType Canon)
-      : KeywordWrapper(Keyword, DeducedTemplateSpecialization, DeducedAsType,
-                       toTypeDependence(Template.getDependence()) |
-                           (IsDeducedAsDependent
-                                ? TypeDependence::DependentInstantiation
-                                : TypeDependence::None),
-                       Canon),
-        Template(Template) {}
+  DeducedTemplateSpecializationType(DeducedKind DK,
+                                    QualType DeducedAsTypeOrCanon,
+                                    ElaboratedTypeKeyword Keyword,
+                                    TemplateName Template)
+      : KeywordWrapper(Keyword, DeducedTemplateSpecialization, DK,
+                       DeducedAsTypeOrCanon),
+        Template(Template) {
+    auto Dep = toTypeDependence(Template.getDependence());
+    // A deduced AutoType only syntactically depends on its template name.
+    if (DK == DeducedKind::Deduced)
+      Dep = toSyntacticDependence(Dep);
+    addDependence(Dep);
+  }
 
 public:
   /// Retrieve the name of the template that we are deducing.
   TemplateName getTemplateName() const { return Template; }
 
   void Profile(llvm::FoldingSetNodeID &ID) const {
-    Profile(ID, getKeyword(), getTemplateName(), getDeducedType(),
-            isDependentType());
+    Profile(ID, getDeducedKind(), getDeducedType(), getKeyword(),
+            getTemplateName());
   }
 
-  static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword 
Keyword,
-                      TemplateName Template, QualType Deduced,
-                      bool IsDependent) {
+  static void Profile(llvm::FoldingSetNodeID &ID, DeducedKind DK,
+                      QualType Deduced, ElaboratedTypeKeyword Keyword,
+                      TemplateName Template) {
+    DeducedType::Profile(ID, DK, Deduced);
     ID.AddInteger(llvm::to_underlying(Keyword));
     Template.Profile(ID);
-    Deduced.Profile(ID);
-    ID.AddBoolean(IsDependent || Template.isDependent());
   }
 
   static bool classof(const Type *T) {
diff --git a/clang/include/clang/AST/TypeProperties.td 
b/clang/include/clang/AST/TypeProperties.td
index 350b748b804a3..0f3722b36774a 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -513,6 +513,9 @@ let Class = UnaryTransformType in {
 }
 
 let Class = AutoType in {
+  def : Property<"deducedKind", DeducedKind> {
+    let Read = [{ node->getDeducedKind() }];
+  }
   def : Property<"deducedType", Optional<QualType>> {
     let Read = [{ makeOptionalFromNullable(node->getDeducedType()) }];
   }
@@ -526,18 +529,9 @@ let Class = AutoType in {
   def : Property<"typeConstraintArguments", Array<TemplateArgument>> {
     let Read = [{ node->getTypeConstraintArguments() }];
   }
-  // FIXME: better enumerated value
-  // Only really required when the deduced type is null
-  def : Property<"dependence", UInt32> {
-    let Read = [{ !node->getDeducedType().isNull() ? 0 :
-                  node->containsUnexpandedParameterPack() ? 2 :
-                  node->isDependentType() ? 1 : 0 }];
-  }
 
   def : Creator<[{
-    return ctx.getAutoType(makeNullableFromOptional(deducedType), keyword,
-                           /*isDependentWithoutDeducedType*/ dependence > 0,
-                           /*isPackWithoutDeducedType*/ dependence > 1,
+    return ctx.getAutoType(deducedKind, makeNullableFromOptional(deducedType), 
keyword,
                            makePointerFromOptional(typeConstraintConcept),
                            typeConstraintArguments);
   }]>;
@@ -550,19 +544,16 @@ let Class = DeducedTemplateSpecializationType in {
   def : Property<"templateName", Optional<TemplateName>> {
     let Read = [{ makeOptionalFromNullable(node->getTemplateName()) }];
   }
+  def : Property<"deducedKind", DeducedKind> {
+    let Read = [{ node->getDeducedKind() }];
+  }
   def : Property<"deducedType", QualType> {
     let Read = [{ node->getDeducedType() }];
   }
-  // Only really required when the deduced type is null
-  def : Property<"dependent", Bool> {
-    let Read = [{ !node->getDeducedType().isNull()
-                    ? false : node->isDependentType() }];
-  }
 
   def : Creator<[{
-    return ctx.getDeducedTemplateSpecializationType(keyword,
-                                     makeNullableFromOptional(templateName),
-                                     deducedType, dependent);
+    return ctx.getDeducedTemplateSpecializationType(deducedKind, deducedType, 
keyword,
+                                     makeNullableFromOptional(templateName));
   }]>;
 }
 
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4c672a03eb855..3eecd738a517c 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -6791,52 +6791,49 @@ ASTContext::getUnaryTransformType(QualType BaseType, 
QualType UnderlyingType,
   return QualType(UT, 0);
 }
 
-QualType ASTContext::getAutoTypeInternal(
-    QualType DeducedType, AutoTypeKeyword Keyword, bool IsDependent,
-    bool IsPack, TemplateDecl *TypeConstraintConcept,
-    ArrayRef<TemplateArgument> TypeConstraintArgs, bool IsCanon) const {
-  if (DeducedType.isNull() && Keyword == AutoTypeKeyword::Auto &&
-      !TypeConstraintConcept && !IsDependent)
+/// getAutoType - Return the uniqued reference to the 'auto' type which has 
been
+/// deduced to the given type, or to the canonical undeduced 'auto' type, or 
the
+/// canonical deduced-but-dependent 'auto' type.
+QualType
+ASTContext::getAutoType(DeducedKind DK, QualType DeducedAsType,
+                        AutoTypeKeyword Keyword,
+                        TemplateDecl *TypeConstraintConcept,
+                        ArrayRef<TemplateArgument> TypeConstraintArgs) const {
+  if (DK == DeducedKind::Undeduced && Keyword == AutoTypeKeyword::Auto &&
+      !TypeConstraintConcept) {
+    assert(DeducedAsType.isNull() && "");
+    assert(TypeConstraintArgs.empty() && "");
     return getAutoDeductType();
+  }
 
   // Look in the folding set for an existing type.
   llvm::FoldingSetNodeID ID;
-  bool IsDeducedDependent =
-      isa_and_nonnull<TemplateTemplateParmDecl>(TypeConstraintConcept) ||
-      (!DeducedType.isNull() && DeducedType->isDependentType());
-  AutoType::Profile(ID, *this, DeducedType, Keyword,
-                    IsDependent || IsDeducedDependent, TypeConstraintConcept,
-                    TypeConstraintArgs);
+  AutoType::Profile(ID, *this, DK, DeducedAsType, Keyword,
+                    TypeConstraintConcept, TypeConstraintArgs);
   if (auto const AT_iter = AutoTypes.find(ID); AT_iter != AutoTypes.end())
     return QualType(AT_iter->getSecond(), 0);
 
-  QualType Canon;
-  if (!IsCanon) {
-    if (!DeducedType.isNull()) {
-      Canon = DeducedType.getCanonicalType();
-    } else if (TypeConstraintConcept) {
+  if (DK == DeducedKind::Deduced) {
+    assert(!DeducedAsType.isNull() && "deduced type must be provided");
+  } else {
+    assert(DeducedAsType.isNull() && "deduced type must not be provided");
+    if (TypeConstraintConcept) {
       bool AnyNonCanonArgs = false;
       auto *CanonicalConcept =
           cast<TemplateDecl>(TypeConstraintConcept->getCanonicalDecl());
       auto CanonicalConceptArgs = ::getCanonicalTemplateArguments(
           *this, TypeConstraintArgs, AnyNonCanonArgs);
-      if (CanonicalConcept != TypeConstraintConcept || AnyNonCanonArgs) {
-        Canon = getAutoTypeInternal(QualType(), Keyword, IsDependent, IsPack,
-                                    CanonicalConcept, CanonicalConceptArgs,
-                                    /*IsCanon=*/true);
-      }
+      if (TypeConstraintConcept != CanonicalConcept || AnyNonCanonArgs)
+        DeducedAsType = getAutoType(DK, QualType(), Keyword, CanonicalConcept,
+                                    CanonicalConceptArgs);
     }
   }
 
   void *Mem = Allocate(sizeof(AutoType) +
                            sizeof(TemplateArgument) * 
TypeConstraintArgs.size(),
                        alignof(AutoType));
-  auto *AT = new (Mem) AutoType(
-      DeducedType, Keyword,
-      (IsDependent ? TypeDependence::DependentInstantiation
-                   : TypeDependence::None) |
-          (IsPack ? TypeDependence::UnexpandedPack : TypeDependence::None),
-      Canon, TypeConstraintConcept, TypeConstraintArgs);
+  auto *AT = new (Mem) AutoType(DK, DeducedAsType, Keyword,
+                                TypeConstraintConcept, TypeConstraintArgs);
 #ifndef NDEBUG
   llvm::FoldingSetNodeID InsertedID;
   AT->Profile(InsertedID, *this);
@@ -6847,21 +6844,6 @@ QualType ASTContext::getAutoTypeInternal(
   return QualType(AT, 0);
 }
 
-/// getAutoType - Return the uniqued reference to the 'auto' type which has 
been
-/// deduced to the given type, or to the canonical undeduced 'auto' type, or 
the
-/// canonical deduced-but-dependent 'auto' type.
-QualType
-ASTContext::getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
-                        bool IsDependent, bool IsPack,
-                        TemplateDecl *TypeConstraintConcept,
-                        ArrayRef<TemplateArgument> TypeConstraintArgs) const {
-  assert((!IsPack || IsDependent) && "only use IsPack for a dependent pack");
-  assert((!IsDependent || DeducedType.isNull()) &&
-         "A dependent auto should be undeduced");
-  return getAutoTypeInternal(DeducedType, Keyword, IsDependent, IsPack,
-                             TypeConstraintConcept, TypeConstraintArgs);
-}
-
 QualType ASTContext::getUnconstrainedType...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/186727
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to