svn commit: r357099 - in projects/clang1000-import/contrib/llvm-project: clang/include/clang/AST clang/include/clang/Basic clang/include/clang/Driver clang/include/clang/Parse clang/include/clang/S...

Dimitry Andric dim at FreeBSD.org
Fri Jan 24 22:15:40 UTC 2020


Author: dim
Date: Fri Jan 24 22:15:36 2020
New Revision: 357099
URL: https://svnweb.freebsd.org/changeset/base/357099

Log:
  Merge ^/vendor/lvm-project/release-10.x up to its last change (upstream
  commit llvmorg-10-init-17538-gd11abddb32f).

Added:
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h
     - copied unchanged from r357098, vendor/llvm-project/release-10.x/clang/include/clang/AST/ExprConcepts.h
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ExprConcepts.cpp
     - copied unchanged from r357098, vendor/llvm-project/release-10.x/clang/lib/AST/ExprConcepts.cpp
Modified:
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/Stmt.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/TemplateBase.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/Type.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/TypeLoc.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/TypeProperties.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/AttrDocs.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/Builtins.def
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/CodeGenOptions.def
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/DeclNodes.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/DiagnosticDriverKinds.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/DiagnosticFrontendKinds.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/DiagnosticParseKinds.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/DiagnosticSemaKinds.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/LangOptions.def
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/StmtNodes.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Basic/TokenKinds.def
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Driver/CC1Options.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Driver/Driver.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Driver/Options.td
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Parse/Parser.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Sema/DeclSpec.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Sema/ParsedTemplate.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Sema/Scope.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Sema/ScopeInfo.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Sema/Sema.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Sema/SemaConcept.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Sema/TemplateDeduction.h
  projects/clang1000-import/contrib/llvm-project/clang/include/clang/Serialization/ASTBitCodes.h
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ASTConcept.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ASTContext.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ASTImporter.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ASTStructuralEquivalence.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/DeclBase.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/DeclCXX.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/DeclTemplate.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/Expr.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ExprCXX.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ExprClassification.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ExprConstant.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ItaniumMangle.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/ODRHash.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/Stmt.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/StmtPrinter.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/StmtProfile.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/TemplateBase.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/TextNodeDumper.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/Type.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/TypeLoc.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/AST/TypePrinter.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Basic/IdentifierTable.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/CodeGen/CGBuiltin.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/CodeGen/CGDecl.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/CodeGen/CGExprScalar.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/CodeGen/CodeGenFunction.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Driver/Compilation.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Driver/Job.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Driver/ToolChain.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Driver/ToolChains/Clang.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Driver/ToolChains/HIP.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Format/TokenAnnotator.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Frontend/CompilerInvocation.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Frontend/FrontendActions.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Frontend/InitPreprocessor.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Headers/ppc_wrappers/emmintrin.h
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/ParseCXXInlineMethods.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/ParseDecl.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/ParseDeclCXX.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/ParseExpr.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/ParseExprCXX.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/ParseTemplate.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/ParseTentative.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Parse/Parser.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/DeclSpec.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/Sema.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaConcept.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaDecl.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaDeclAttr.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaDeclCXX.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaExceptionSpec.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaExpr.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaExprCXX.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaLambda.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaLookup.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaStmt.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaTemplate.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaTemplateDeduction.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiate.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/SemaType.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Sema/TreeTransform.h
  projects/clang1000-import/contrib/llvm-project/clang/lib/Serialization/ASTCommon.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Serialization/ASTReader.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Serialization/ASTReaderDecl.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Serialization/ASTReaderStmt.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Serialization/ASTWriter.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Serialization/ASTWriterDecl.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/Serialization/ASTWriterStmt.cpp
  projects/clang1000-import/contrib/llvm-project/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp
  projects/clang1000-import/contrib/llvm-project/clang/tools/driver/driver.cpp
  projects/clang1000-import/contrib/llvm-project/libcxx/include/__config
  projects/clang1000-import/contrib/llvm-project/libcxx/include/__threading_support
  projects/clang1000-import/contrib/llvm-project/lld/COFF/InputFiles.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/PPC.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/PPC64.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Arch/RISCV.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Config.h
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Driver.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Relocations.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Symbols.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Target.cpp
  projects/clang1000-import/contrib/llvm-project/lld/ELF/Writer.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/include/llvm/BinaryFormat/ELFRelocs/PowerPC64.def
  projects/clang1000-import/contrib/llvm-project/llvm/include/llvm/CodeGen/AsmPrinter.h
  projects/clang1000-import/contrib/llvm-project/llvm/include/llvm/MC/MCAsmBackend.h
  projects/clang1000-import/contrib/llvm-project/llvm/include/llvm/MC/MCFixupKindInfo.h
  projects/clang1000-import/contrib/llvm-project/llvm/include/llvm/Target/Target.td
  projects/clang1000-import/contrib/llvm-project/llvm/include/llvm/Transforms/Utils/SizeOpts.h
  projects/clang1000-import/contrib/llvm-project/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/CodeGen/CodeGenPrepare.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/CodeGen/PatchableFunction.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/CodeGen/StackColoring.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/CodeGen/TargetPassConfig.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/IR/Verifier.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/MC/MCAssembler.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64AsmPrinter.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/AArch64/AArch64LoadStoreOptimizer.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/ARM/ARMMCInstLower.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVAsmBackend.h
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMCExpr.h
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Target/RISCV/RISCVInstrInfo.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
  projects/clang1000-import/contrib/llvm-project/llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp
Directory Properties:
  projects/clang1000-import/contrib/llvm-project/   (props changed)
  projects/clang1000-import/contrib/llvm-project/clang/   (props changed)
  projects/clang1000-import/contrib/llvm-project/libcxx/   (props changed)
  projects/clang1000-import/contrib/llvm-project/lld/   (props changed)
  projects/clang1000-import/contrib/llvm-project/llvm/   (props changed)

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTConcept.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -22,10 +22,25 @@
 #include <utility>
 namespace clang {
 class ConceptDecl;
+class ConceptSpecializationExpr;
 
-/// \brief The result of a constraint satisfaction check, containing the
-/// necessary information to diagnose an unsatisfied constraint.
-struct ConstraintSatisfaction {
+/// The result of a constraint satisfaction check, containing the necessary
+/// information to diagnose an unsatisfied constraint.
+class ConstraintSatisfaction : public llvm::FoldingSetNode {
+  // The template-like entity that 'owns' the constraint checked here (can be a
+  // constrained entity or a concept).
+  NamedDecl *ConstraintOwner = nullptr;
+  llvm::SmallVector<TemplateArgument, 4> TemplateArgs;
+
+public:
+
+  ConstraintSatisfaction() = default;
+
+  ConstraintSatisfaction(NamedDecl *ConstraintOwner,
+                         ArrayRef<TemplateArgument> TemplateArgs) :
+      ConstraintOwner(ConstraintOwner), TemplateArgs(TemplateArgs.begin(),
+                                                     TemplateArgs.end()) { }
+
   using SubstitutionDiagnostic = std::pair<SourceLocation, StringRef>;
   using Detail = llvm::PointerUnion<Expr *, SubstitutionDiagnostic *>;
 
@@ -37,9 +52,13 @@ struct ConstraintSatisfaction {
   /// invalid expression.
   llvm::SmallVector<std::pair<const Expr *, Detail>, 4> Details;
 
-  // This can leak if used in an AST node, use ASTConstraintSatisfaction
-  // instead.
-  void *operator new(size_t bytes, ASTContext &C) = delete;
+  void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C) {
+    Profile(ID, C, ConstraintOwner, TemplateArgs);
+  }
+
+  static void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &C,
+                      NamedDecl *ConstraintOwner,
+                      ArrayRef<TemplateArgument> TemplateArgs);
 };
 
 /// Pairs of unsatisfied atomic constraint expressions along with the

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTContext.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTContext.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTContext.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -88,6 +88,7 @@ class AtomicExpr;
 class BlockExpr;
 class BuiltinTemplateDecl;
 class CharUnits;
+class ConceptDecl;
 class CXXABI;
 class CXXConstructorDecl;
 class CXXMethodDecl;
@@ -211,7 +212,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
   mutable llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
   mutable llvm::FoldingSet<DependentUnaryTransformType>
     DependentUnaryTransformTypes;
-  mutable llvm::FoldingSet<AutoType> AutoTypes;
+  mutable llvm::ContextualFoldingSet<AutoType, ASTContext&> AutoTypes;
   mutable llvm::FoldingSet<DeducedTemplateSpecializationType>
     DeducedTemplateSpecializationTypes;
   mutable llvm::FoldingSet<AtomicType> AtomicTypes;
@@ -1542,7 +1543,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
 
   /// C++11 deduced auto type.
   QualType getAutoType(QualType DeducedType, AutoTypeKeyword Keyword,
-                       bool IsDependent, bool IsPack = false) const;
+                       bool IsDependent, bool IsPack = false,
+                       ConceptDecl *TypeConstraintConcept = nullptr,
+                       ArrayRef<TemplateArgument> TypeConstraintArgs ={}) const;
 
   /// C++11 deduction pattern for 'auto' type.
   QualType getAutoDeductType() const;

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ASTNodeTraverser.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -548,8 +548,8 @@ class ASTNodeTraverser (public)
   }
 
   void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
-    if (const auto *TC = D->getPlaceholderTypeConstraint())
-      Visit(TC->getImmediatelyDeclaredConstraint());
+    if (const auto *E = D->getPlaceholderTypeConstraint())
+      Visit(E);
     if (D->hasDefaultArgument())
       Visit(D->getDefaultArgument(), SourceRange(),
             D->getDefaultArgStorage().getInheritedFrom(),

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclCXX.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -1893,6 +1893,37 @@ class CXXDeductionGuideDecl : public FunctionDecl { (p
   static bool classofKind(Kind K) { return K == CXXDeductionGuide; }
 };
 
+/// \brief Represents the body of a requires-expression.
+///
+/// This decl exists merely to serve as the DeclContext for the local
+/// parameters of the requires expression as well as other declarations inside
+/// it.
+///
+/// \code
+/// template<typename T> requires requires (T t) { {t++} -> regular; }
+/// \endcode
+///
+/// In this example, a RequiresExpr object will be generated for the expression,
+/// and a RequiresExprBodyDecl will be created to hold the parameter t and the
+/// template argument list imposed by the compound requirement.
+class RequiresExprBodyDecl : public Decl, public DeclContext {
+  RequiresExprBodyDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
+      : Decl(RequiresExprBody, DC, StartLoc), DeclContext(RequiresExprBody) {}
+
+public:
+  friend class ASTDeclReader;
+  friend class ASTDeclWriter;
+
+  static RequiresExprBodyDecl *Create(ASTContext &C, DeclContext *DC,
+                                      SourceLocation StartLoc);
+
+  static RequiresExprBodyDecl *CreateDeserialized(ASTContext &C, unsigned ID);
+
+  // Implement isa/cast/dyncast/etc.
+  static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+  static bool classofKind(Kind K) { return K == RequiresExprBody; }
+};
+
 /// Represents a static or instance method of a struct/union/class.
 ///
 /// In the terminology of the C++ Standard, these are the (static and

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/DeclTemplate.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -1102,6 +1102,17 @@ class FunctionTemplateDecl : public RedeclarableTempla
   /// template.
   ArrayRef<TemplateArgument> getInjectedTemplateArgs();
 
+  /// Return whether this function template is an abbreviated function template,
+  /// e.g. `void foo(auto x)` or `template<typename T> void foo(auto x)`
+  bool isAbbreviated() const {
+    // Since the invented template parameters generated from 'auto' parameters
+    // are either appended to the end of the explicit template parameter list or
+    // form a new template paramter list, we can simply observe the last
+    // parameter to determine if such a thing happened.
+    const TemplateParameterList *TPL = getTemplateParameters();
+    return TPL->getParam(TPL->size() - 1)->isImplicit();
+  }
+
   /// Merge \p Prev with our RedeclarableTemplateDecl::Common.
   void mergePrevDecl(FunctionTemplateDecl *Prev);
 
@@ -1215,7 +1226,6 @@ class TemplateTypeParmDecl final : public TypeDecl, (p
                                       bool ParameterPack,
                                       bool HasTypeConstraint = false,
                                       Optional<unsigned> NumExpanded = None);
-
   static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
                                                   unsigned ID);
   static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C,
@@ -1374,7 +1384,8 @@ class NonTypeTemplateParmDecl final
     : public DeclaratorDecl,
       protected TemplateParmPosition,
       private llvm::TrailingObjects<NonTypeTemplateParmDecl,
-                                    std::pair<QualType, TypeSourceInfo *>> {
+                                    std::pair<QualType, TypeSourceInfo *>,
+                                    Expr *> {
   friend class ASTDeclReader;
   friend TrailingObjects;
 
@@ -1429,10 +1440,12 @@ class NonTypeTemplateParmDecl final
          ArrayRef<TypeSourceInfo *> ExpandedTInfos);
 
   static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
-                                                     unsigned ID);
+                                                     unsigned ID,
+                                                     bool HasTypeConstraint);
   static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C,
                                                      unsigned ID,
-                                                     unsigned NumExpandedTypes);
+                                                     unsigned NumExpandedTypes,
+                                                     bool HasTypeConstraint);
 
   using TemplateParmPosition::getDepth;
   using TemplateParmPosition::setDepth;
@@ -1543,20 +1556,22 @@ class NonTypeTemplateParmDecl final
     return TypesAndInfos[I].second;
   }
 
-  /// Return the type-constraint in the placeholder type of this non-type
+  /// Return the constraint introduced by the placeholder type of this non-type
   /// template parameter (if any).
-  TypeConstraint *getPlaceholderTypeConstraint() const {
-    // TODO: Concepts: Implement once we have actual placeholders with type
-    //                 constraints.
-    return nullptr;
+  Expr *getPlaceholderTypeConstraint() const {
+    return hasPlaceholderTypeConstraint() ? *getTrailingObjects<Expr *>() :
+        nullptr;
   }
 
+  void setPlaceholderTypeConstraint(Expr *E) {
+    *getTrailingObjects<Expr *>() = E;
+  }
+
   /// Determine whether this non-type template parameter's type has a
   /// placeholder with a type-constraint.
   bool hasPlaceholderTypeConstraint() const {
-    // TODO: Concepts: Implement once we have actual placeholders with type
-    //                 constraints.
-    return false;
+    auto *AT = getType()->getContainedAutoType();
+    return AT && AT->isConstrained();
   }
 
   /// \brief Get the associated-constraints of this template parameter.
@@ -1566,8 +1581,8 @@ class NonTypeTemplateParmDecl final
   /// Use this instead of getPlaceholderImmediatelyDeclaredConstraint for
   /// concepts APIs that accept an ArrayRef of constraint expressions.
   void getAssociatedConstraints(llvm::SmallVectorImpl<const Expr *> &AC) const {
-    if (TypeConstraint *TC = getPlaceholderTypeConstraint())
-      AC.push_back(TC->getImmediatelyDeclaredConstraint());
+    if (Expr *E = getPlaceholderTypeConstraint())
+      AC.push_back(E);
   }
 
   // Implement isa/cast/dyncast/etc.

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ExprCXX.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -14,7 +14,6 @@
 #ifndef LLVM_CLANG_AST_EXPRCXX_H
 #define LLVM_CLANG_AST_EXPRCXX_H
 
-#include "clang/AST/ASTConcept.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
@@ -4833,99 +4832,6 @@ class BuiltinBitCastExpr final (public)
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() == BuiltinBitCastExprClass;
-  }
-};
-
-/// \brief Represents the specialization of a concept - evaluates to a prvalue
-/// of type bool.
-///
-/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
-/// specialization of a concept results in a prvalue of type bool.
-class ConceptSpecializationExpr final : public Expr, public ConceptReference,
-      private llvm::TrailingObjects<ConceptSpecializationExpr,
-                                    TemplateArgument> {
-  friend class ASTStmtReader;
-  friend TrailingObjects;
-public:
-  using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
-
-protected:
-  /// \brief The number of template arguments in the tail-allocated list of
-  /// converted template arguments.
-  unsigned NumTemplateArgs;
-
-  /// \brief Information about the satisfaction of the named concept with the
-  /// given arguments. If this expression is value dependent, this is to be
-  /// ignored.
-  ASTConstraintSatisfaction *Satisfaction;
-
-  ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
-                            SourceLocation TemplateKWLoc,
-                            DeclarationNameInfo ConceptNameInfo,
-                            NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
-                            const ASTTemplateArgumentListInfo *ArgsAsWritten,
-                            ArrayRef<TemplateArgument> ConvertedArgs,
-                            const ConstraintSatisfaction *Satisfaction);
-
-  ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
-
-public:
-
-  static ConceptSpecializationExpr *
-  Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
-         SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
-         NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
-         const ASTTemplateArgumentListInfo *ArgsAsWritten,
-         ArrayRef<TemplateArgument> ConvertedArgs,
-         const ConstraintSatisfaction *Satisfaction);
-
-  static ConceptSpecializationExpr *
-  Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
-
-  ArrayRef<TemplateArgument> getTemplateArguments() const {
-    return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
-                                      NumTemplateArgs);
-  }
-
-  /// \brief Set new template arguments for this concept specialization.
-  void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
-
-  /// \brief Whether or not the concept with the given arguments was satisfied
-  /// when the expression was created.
-  /// The expression must not be dependent.
-  bool isSatisfied() const {
-    assert(!isValueDependent()
-           && "isSatisfied called on a dependent ConceptSpecializationExpr");
-    return Satisfaction->IsSatisfied;
-  }
-
-  /// \brief Get elaborated satisfaction info about the template arguments'
-  /// satisfaction of the named concept.
-  /// The expression must not be dependent.
-  const ASTConstraintSatisfaction &getSatisfaction() const {
-    assert(!isValueDependent()
-           && "getSatisfaction called on dependent ConceptSpecializationExpr");
-    return *Satisfaction;
-  }
-
-  static bool classof(const Stmt *T) {
-    return T->getStmtClass() == ConceptSpecializationExprClass;
-  }
-
-  SourceLocation getBeginLoc() const LLVM_READONLY {
-    return ConceptName.getBeginLoc();
-  }
-
-  SourceLocation getEndLoc() const LLVM_READONLY {
-    return ArgsAsWritten->RAngleLoc;
-  }
-
-  // Iterators
-  child_range children() {
-    return child_range(child_iterator(), child_iterator());
-  }
-  const_child_range children() const {
-    return const_child_range(const_child_iterator(), const_child_iterator());
   }
 };
 

Copied: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h (from r357098, vendor/llvm-project/release-10.x/clang/include/clang/AST/ExprConcepts.h)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/ExprConcepts.h	Fri Jan 24 22:15:36 2020	(r357099, copy of r357098, vendor/llvm-project/release-10.x/clang/include/clang/AST/ExprConcepts.h)
@@ -0,0 +1,540 @@
+//===- ExprConcepts.h - C++2a Concepts expressions --------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines Expressions and AST nodes for C++2a concepts.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_EXPRCONCEPTS_H
+#define LLVM_CLANG_AST_EXPRCONCEPTS_H
+
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTConcept.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/DeclarationName.h"
+#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/Expr.h"
+#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/TemplateBase.h"
+#include "clang/AST/Type.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/Support/TrailingObjects.h"
+#include <utility>
+#include <string>
+
+namespace clang {
+class ASTStmtReader;
+class ASTStmtWriter;
+
+/// \brief Represents the specialization of a concept - evaluates to a prvalue
+/// of type bool.
+///
+/// According to C++2a [expr.prim.id]p3 an id-expression that denotes the
+/// specialization of a concept results in a prvalue of type bool.
+class ConceptSpecializationExpr final : public Expr, public ConceptReference,
+      private llvm::TrailingObjects<ConceptSpecializationExpr,
+                                    TemplateArgument> {
+  friend class ASTStmtReader;
+  friend TrailingObjects;
+public:
+  using SubstitutionDiagnostic = std::pair<SourceLocation, std::string>;
+
+protected:
+  /// \brief The number of template arguments in the tail-allocated list of
+  /// converted template arguments.
+  unsigned NumTemplateArgs;
+
+  /// \brief Information about the satisfaction of the named concept with the
+  /// given arguments. If this expression is value dependent, this is to be
+  /// ignored.
+  ASTConstraintSatisfaction *Satisfaction;
+
+  ConceptSpecializationExpr(const ASTContext &C, NestedNameSpecifierLoc NNS,
+                            SourceLocation TemplateKWLoc,
+                            DeclarationNameInfo ConceptNameInfo,
+                            NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+                            const ASTTemplateArgumentListInfo *ArgsAsWritten,
+                            ArrayRef<TemplateArgument> ConvertedArgs,
+                            const ConstraintSatisfaction *Satisfaction);
+
+  ConceptSpecializationExpr(EmptyShell Empty, unsigned NumTemplateArgs);
+
+public:
+
+  static ConceptSpecializationExpr *
+  Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
+         SourceLocation TemplateKWLoc, DeclarationNameInfo ConceptNameInfo,
+         NamedDecl *FoundDecl, ConceptDecl *NamedConcept,
+         const ASTTemplateArgumentListInfo *ArgsAsWritten,
+         ArrayRef<TemplateArgument> ConvertedArgs,
+         const ConstraintSatisfaction *Satisfaction);
+
+  static ConceptSpecializationExpr *
+  Create(ASTContext &C, EmptyShell Empty, unsigned NumTemplateArgs);
+
+  ArrayRef<TemplateArgument> getTemplateArguments() const {
+    return ArrayRef<TemplateArgument>(getTrailingObjects<TemplateArgument>(),
+                                      NumTemplateArgs);
+  }
+
+  /// \brief Set new template arguments for this concept specialization.
+  void setTemplateArguments(ArrayRef<TemplateArgument> Converted);
+
+  /// \brief Whether or not the concept with the given arguments was satisfied
+  /// when the expression was created.
+  /// The expression must not be dependent.
+  bool isSatisfied() const {
+    assert(!isValueDependent()
+           && "isSatisfied called on a dependent ConceptSpecializationExpr");
+    return Satisfaction->IsSatisfied;
+  }
+
+  /// \brief Get elaborated satisfaction info about the template arguments'
+  /// satisfaction of the named concept.
+  /// The expression must not be dependent.
+  const ASTConstraintSatisfaction &getSatisfaction() const {
+    assert(!isValueDependent()
+           && "getSatisfaction called on dependent ConceptSpecializationExpr");
+    return *Satisfaction;
+  }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == ConceptSpecializationExprClass;
+  }
+
+  SourceLocation getBeginLoc() const LLVM_READONLY {
+    return ConceptName.getBeginLoc();
+  }
+
+  SourceLocation getEndLoc() const LLVM_READONLY {
+    return ArgsAsWritten->RAngleLoc;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+};
+
+namespace concepts {
+
+/// \brief A static requirement that can be used in a requires-expression to
+/// check properties of types and expression.
+class Requirement {
+public:
+  // Note - simple and compound requirements are both represented by the same
+  // class (ExprRequirement).
+  enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested };
+private:
+  const RequirementKind Kind;
+  bool Dependent : 1;
+  bool ContainsUnexpandedParameterPack : 1;
+  bool Satisfied : 1;
+public:
+  struct SubstitutionDiagnostic {
+    StringRef SubstitutedEntity;
+    // FIXME: Store diagnostics semantically and not as prerendered strings.
+    //  Fixing this probably requires serialization of PartialDiagnostic
+    //  objects.
+    SourceLocation DiagLoc;
+    StringRef DiagMessage;
+  };
+
+  Requirement(RequirementKind Kind, bool IsDependent,
+              bool ContainsUnexpandedParameterPack, bool IsSatisfied = true) :
+      Kind(Kind), Dependent(IsDependent),
+      ContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack),
+      Satisfied(IsSatisfied) {}
+
+  RequirementKind getKind() const { return Kind; }
+
+  bool isSatisfied() const {
+    assert(!Dependent &&
+           "isSatisfied can only be called on non-dependent requirements.");
+    return Satisfied;
+  }
+
+  void setSatisfied(bool IsSatisfied) {
+    assert(!Dependent &&
+           "setSatisfied can only be called on non-dependent requirements.");
+    Satisfied = IsSatisfied;
+  }
+
+  void setDependent(bool IsDependent) { Dependent = IsDependent; }
+  bool isDependent() const { return Dependent; }
+
+  void setContainsUnexpandedParameterPack(bool Contains) {
+    ContainsUnexpandedParameterPack = Contains;
+  }
+  bool containsUnexpandedParameterPack() const {
+    return ContainsUnexpandedParameterPack;
+  }
+};
+
+/// \brief A requires-expression requirement which queries the existence of a
+/// type name or type template specialization ('type' requirements).
+class TypeRequirement : public Requirement {
+public:
+  enum SatisfactionStatus {
+      SS_Dependent,
+      SS_SubstitutionFailure,
+      SS_Satisfied
+  };
+private:
+  llvm::PointerUnion<SubstitutionDiagnostic *, TypeSourceInfo *> Value;
+  SatisfactionStatus Status;
+public:
+  friend ASTStmtReader;
+  friend ASTStmtWriter;
+
+  /// \brief Construct a type requirement from a type. If the given type is not
+  /// dependent, this indicates that the type exists and the requirement will be
+  /// satisfied. Otherwise, the SubstitutionDiagnostic constructor is to be
+  /// used.
+  TypeRequirement(TypeSourceInfo *T);
+
+  /// \brief Construct a type requirement when the nested name specifier is
+  /// invalid due to a bad substitution. The requirement is unsatisfied.
+  TypeRequirement(SubstitutionDiagnostic *Diagnostic) :
+      Requirement(RK_Type, false, false, false), Value(Diagnostic),
+      Status(SS_SubstitutionFailure) {}
+
+  SatisfactionStatus getSatisfactionStatus() const { return Status; }
+  void setSatisfactionStatus(SatisfactionStatus Status) {
+    this->Status = Status;
+  }
+
+  bool isSubstitutionFailure() const {
+    return Status == SS_SubstitutionFailure;
+  }
+
+  SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
+    assert(Status == SS_SubstitutionFailure &&
+           "Attempted to get substitution diagnostic when there has been no "
+           "substitution failure.");
+    return Value.get<SubstitutionDiagnostic *>();
+  }
+
+  TypeSourceInfo *getType() const {
+    assert(!isSubstitutionFailure() &&
+           "Attempted to get type when there has been a substitution failure.");
+    return Value.get<TypeSourceInfo *>();
+  }
+
+  static bool classof(const Requirement *R) {
+    return R->getKind() == RK_Type;
+  }
+};
+
+/// \brief A requires-expression requirement which queries the validity and
+/// properties of an expression ('simple' and 'compound' requirements).
+class ExprRequirement : public Requirement {
+public:
+  enum SatisfactionStatus {
+      SS_Dependent,
+      SS_ExprSubstitutionFailure,
+      SS_NoexceptNotMet,
+      SS_TypeRequirementSubstitutionFailure,
+      SS_ConstraintsNotSatisfied,
+      SS_Satisfied
+  };
+  class ReturnTypeRequirement {
+      llvm::PointerIntPair<
+          llvm::PointerUnion<TemplateParameterList *, SubstitutionDiagnostic *>,
+          1, bool>
+          TypeConstraintInfo;
+  public:
+      friend ASTStmtReader;
+      friend ASTStmtWriter;
+
+      /// \brief No return type requirement was specified.
+      ReturnTypeRequirement() : TypeConstraintInfo(nullptr, 0) {}
+
+      /// \brief A return type requirement was specified but it was a
+      /// substitution failure.
+      ReturnTypeRequirement(SubstitutionDiagnostic *SubstDiag) :
+          TypeConstraintInfo(SubstDiag, 0) {}
+
+      /// \brief A 'type constraint' style return type requirement.
+      /// \param TPL an invented template parameter list containing a single
+      /// type parameter with a type-constraint.
+      // TODO: Can we maybe not save the whole template parameter list and just
+      //  the type constraint? Saving the whole TPL makes it easier to handle in
+      //  serialization but is less elegant.
+      ReturnTypeRequirement(TemplateParameterList *TPL);
+
+      bool isDependent() const {
+        return TypeConstraintInfo.getInt();
+      }
+
+      bool containsUnexpandedParameterPack() const {
+        if (!isTypeConstraint())
+          return false;
+        return getTypeConstraintTemplateParameterList()
+                ->containsUnexpandedParameterPack();
+      }
+
+      bool isEmpty() const {
+        return TypeConstraintInfo.getPointer().isNull();
+      }
+
+      bool isSubstitutionFailure() const {
+        return !isEmpty() &&
+            TypeConstraintInfo.getPointer().is<SubstitutionDiagnostic *>();
+      }
+
+      bool isTypeConstraint() const {
+        return !isEmpty() &&
+            TypeConstraintInfo.getPointer().is<TemplateParameterList *>();
+      }
+
+      SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
+        assert(isSubstitutionFailure());
+        return TypeConstraintInfo.getPointer().get<SubstitutionDiagnostic *>();
+      }
+
+      const TypeConstraint *getTypeConstraint() const;
+
+      TemplateParameterList *getTypeConstraintTemplateParameterList() const {
+        assert(isTypeConstraint());
+        return TypeConstraintInfo.getPointer().get<TemplateParameterList *>();
+      }
+  };
+private:
+  llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
+  SourceLocation NoexceptLoc; // May be empty if noexcept wasn't specified.
+  ReturnTypeRequirement TypeReq;
+  ConceptSpecializationExpr *SubstitutedConstraintExpr;
+  SatisfactionStatus Status;
+public:
+  friend ASTStmtReader;
+  friend ASTStmtWriter;
+
+  /// \brief Construct a compound requirement.
+  /// \param E the expression which is checked by this requirement.
+  /// \param IsSimple whether this was a simple requirement in source.
+  /// \param NoexceptLoc the location of the noexcept keyword, if it was
+  /// specified, otherwise an empty location.
+  /// \param Req the requirement for the type of the checked expression.
+  /// \param Status the satisfaction status of this requirement.
+  ExprRequirement(
+      Expr *E, bool IsSimple, SourceLocation NoexceptLoc,
+      ReturnTypeRequirement Req, SatisfactionStatus Status,
+      ConceptSpecializationExpr *SubstitutedConstraintExpr = nullptr);
+
+  /// \brief Construct a compound requirement whose expression was a
+  /// substitution failure. The requirement is not satisfied.
+  /// \param E the diagnostic emitted while instantiating the original
+  /// expression.
+  /// \param IsSimple whether this was a simple requirement in source.
+  /// \param NoexceptLoc the location of the noexcept keyword, if it was
+  /// specified, otherwise an empty location.
+  /// \param Req the requirement for the type of the checked expression (omit
+  /// if no requirement was specified).
+  ExprRequirement(SubstitutionDiagnostic *E, bool IsSimple,
+                  SourceLocation NoexceptLoc, ReturnTypeRequirement Req = {});
+
+  bool isSimple() const { return getKind() == RK_Simple; }
+  bool isCompound() const { return getKind() == RK_Compound; }
+
+  bool hasNoexceptRequirement() const { return NoexceptLoc.isValid(); }
+  SourceLocation getNoexceptLoc() const { return NoexceptLoc; }
+
+  SatisfactionStatus getSatisfactionStatus() const { return Status; }
+
+  bool isExprSubstitutionFailure() const {
+    return Status == SS_ExprSubstitutionFailure;
+  }
+
+  const ReturnTypeRequirement &getReturnTypeRequirement() const {
+    return TypeReq;
+  }
+
+  ConceptSpecializationExpr *
+  getReturnTypeRequirementSubstitutedConstraintExpr() const {
+    assert(Status >= SS_TypeRequirementSubstitutionFailure);
+    return SubstitutedConstraintExpr;
+  }
+
+  SubstitutionDiagnostic *getExprSubstitutionDiagnostic() const {
+    assert(isExprSubstitutionFailure() &&
+           "Attempted to get expression substitution diagnostic when there has "
+           "been no expression substitution failure");
+    return Value.get<SubstitutionDiagnostic *>();
+  }
+
+  Expr *getExpr() const {
+    assert(!isExprSubstitutionFailure() &&
+           "ExprRequirement has no expression because there has been a "
+           "substitution failure.");
+    return Value.get<Expr *>();
+  }
+
+  static bool classof(const Requirement *R) {
+    return R->getKind() == RK_Compound || R->getKind() == RK_Simple;
+  }
+};
+
+/// \brief A requires-expression requirement which is satisfied when a general
+/// constraint expression is satisfied ('nested' requirements).
+class NestedRequirement : public Requirement {
+  llvm::PointerUnion<Expr *, SubstitutionDiagnostic *> Value;
+  const ASTConstraintSatisfaction *Satisfaction = nullptr;
+
+public:
+  friend ASTStmtReader;
+  friend ASTStmtWriter;
+
+  NestedRequirement(SubstitutionDiagnostic *SubstDiag) :
+      Requirement(RK_Nested, /*Dependent=*/false,
+                  /*ContainsUnexpandedParameterPack*/false,
+                  /*Satisfied=*/false), Value(SubstDiag) {}
+
+  NestedRequirement(Expr *Constraint) :
+      Requirement(RK_Nested, /*Dependent=*/true,
+                  Constraint->containsUnexpandedParameterPack()),
+      Value(Constraint) {
+    assert(Constraint->isInstantiationDependent() &&
+           "Nested requirement with non-dependent constraint must be "
+           "constructed with a ConstraintSatisfaction object");
+  }
+
+  NestedRequirement(ASTContext &C, Expr *Constraint,
+                    const ConstraintSatisfaction &Satisfaction) :
+      Requirement(RK_Nested, Constraint->isInstantiationDependent(),
+                  Constraint->containsUnexpandedParameterPack(),
+                  Satisfaction.IsSatisfied),
+      Value(Constraint),
+      Satisfaction(ASTConstraintSatisfaction::Create(C, Satisfaction)) {}
+
+  bool isSubstitutionFailure() const {
+    return Value.is<SubstitutionDiagnostic *>();
+  }
+
+  SubstitutionDiagnostic *getSubstitutionDiagnostic() const {
+    assert(isSubstitutionFailure() &&
+           "getSubstitutionDiagnostic() may not be called when there was no "
+           "substitution failure.");
+    return Value.get<SubstitutionDiagnostic *>();
+  }
+
+  Expr *getConstraintExpr() const {
+    assert(!isSubstitutionFailure() && "getConstraintExpr() may not be called "
+                                       "on nested requirements with "
+                                       "substitution failures.");
+    return Value.get<Expr *>();
+  }
+
+  const ASTConstraintSatisfaction &getConstraintSatisfaction() const {
+    assert(!isSubstitutionFailure() && "getConstraintSatisfaction() may not be "
+                                       "called on nested requirements with "
+                                       "substitution failures.");
+    return *Satisfaction;
+  }
+
+  static bool classof(const Requirement *R) {
+    return R->getKind() == RK_Nested;
+  }
+};
+
+} // namespace concepts
+
+/// C++2a [expr.prim.req]:
+///     A requires-expression provides a concise way to express requirements on
+///     template arguments. A requirement is one that can be checked by name
+///     lookup (6.4) or by checking properties of types and expressions.
+///     [...]
+///     A requires-expression is a prvalue of type bool [...]
+class RequiresExpr final : public Expr,
+    llvm::TrailingObjects<RequiresExpr, ParmVarDecl *,
+                          concepts::Requirement *> {
+  friend TrailingObjects;
+  friend class ASTStmtReader;
+
+  unsigned NumLocalParameters;
+  unsigned NumRequirements;
+  RequiresExprBodyDecl *Body;
+  SourceLocation RBraceLoc;
+
+  unsigned numTrailingObjects(OverloadToken<ParmVarDecl *>) const {
+    return NumLocalParameters;
+  }
+
+  unsigned numTrailingObjects(OverloadToken<concepts::Requirement *>) const {
+    return NumRequirements;
+  }
+
+  RequiresExpr(ASTContext &C, SourceLocation RequiresKWLoc,
+               RequiresExprBodyDecl *Body,
+               ArrayRef<ParmVarDecl *> LocalParameters,
+               ArrayRef<concepts::Requirement *> Requirements,
+               SourceLocation RBraceLoc);
+  RequiresExpr(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
+               unsigned NumRequirements);
+
+public:
+  static RequiresExpr *
+  Create(ASTContext &C, SourceLocation RequiresKWLoc,
+         RequiresExprBodyDecl *Body, ArrayRef<ParmVarDecl *> LocalParameters,
+         ArrayRef<concepts::Requirement *> Requirements,
+         SourceLocation RBraceLoc);
+  static RequiresExpr *
+  Create(ASTContext &C, EmptyShell Empty, unsigned NumLocalParameters,
+         unsigned NumRequirements);
+
+  ArrayRef<ParmVarDecl *> getLocalParameters() const {
+    return {getTrailingObjects<ParmVarDecl *>(), NumLocalParameters};
+  }
+
+  RequiresExprBodyDecl *getBody() const { return Body; }
+
+  ArrayRef<concepts::Requirement *> getRequirements() const {
+    return {getTrailingObjects<concepts::Requirement *>(), NumRequirements};
+  }
+
+  /// \brief Whether or not the requires clause is satisfied.
+  /// The expression must not be dependent.
+  bool isSatisfied() const {
+    assert(!isValueDependent()
+           && "isSatisfied called on a dependent RequiresExpr");
+    return RequiresExprBits.IsSatisfied;
+  }
+
+  SourceLocation getRequiresKWLoc() const {
+    return RequiresExprBits.RequiresKWLoc;
+  }
+
+  SourceLocation getRBraceLoc() const { return RBraceLoc; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == RequiresExprClass;
+  }
+
+  SourceLocation getBeginLoc() const LLVM_READONLY {
+    return RequiresExprBits.RequiresKWLoc;
+  }
+  SourceLocation getEndLoc() const LLVM_READONLY {
+    return RBraceLoc;
+  }
+
+  // Iterators
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+};
+
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_EXPRCONCEPTS_H
\ No newline at end of file

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/PropertiesBase.td	Fri Jan 24 22:15:36 2020	(r357099)
@@ -99,6 +99,8 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenW
     SubclassPropertyType<"TagDecl", DeclRef>;
   def TemplateDeclRef :
     SubclassPropertyType<"TemplateDecl", DeclRef>;
+  def ConceptDeclRef :
+    SubclassPropertyType<"ConceptDecl", DeclRef>;
   def TemplateTypeParmDeclRef :
     SubclassPropertyType<"TemplateTypeParmDecl", DeclRef>;
   def TemplateTemplateParmDeclRef :

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/RecursiveASTVisitor.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -23,6 +23,7 @@
 #include "clang/AST/DeclOpenMP.h"
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
+#include "clang/AST/ExprConcepts.h"
 #include "clang/AST/ExprCXX.h"
 #include "clang/AST/ExprObjC.h"
 #include "clang/AST/ExprOpenMP.h"
@@ -1039,7 +1040,13 @@ DEF_TRAVERSE_TYPE(UnaryTransformType, {
   TRY_TO(TraverseType(T->getUnderlyingType()));
 })
 
-DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
+DEF_TRAVERSE_TYPE(AutoType, {
+  TRY_TO(TraverseType(T->getDeducedType()));
+  if (T->isConstrained()) {
+    TRY_TO(TraverseDecl(T->getTypeConstraintConcept()));
+    TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
+  }
+})
 DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
   TRY_TO(TraverseTemplateName(T->getTemplateName()));
   TRY_TO(TraverseType(T->getDeducedType()));
@@ -1286,6 +1293,12 @@ DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
 
 DEF_TRAVERSE_TYPELOC(AutoType, {
   TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
+  if (TL.isConstrained()) {
+    TRY_TO(TraverseNestedNameSpecifierLoc(TL.getNestedNameSpecifierLoc()));
+    TRY_TO(TraverseDeclarationNameInfo(TL.getConceptNameInfo()));
+    for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+      TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
+  }
 })
 
 DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
@@ -2138,6 +2151,8 @@ DEF_TRAVERSE_DECL(ParmVarDecl, {
     TRY_TO(TraverseStmt(D->getDefaultArg()));
 })
 
+DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
+
 #undef DEF_TRAVERSE_DECL
 
 // ----------------- Stmt traversal -----------------
@@ -2707,6 +2722,28 @@ DEF_TRAVERSE_STMT(CoyieldExpr, {
 
 DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
   TRY_TO(TraverseConceptReference(*S));
+})
+
+DEF_TRAVERSE_STMT(RequiresExpr, {
+  TRY_TO(TraverseDecl(S->getBody()));
+  for (ParmVarDecl *Parm : S->getLocalParameters())
+    TRY_TO(TraverseDecl(Parm));
+  for (concepts::Requirement *Req : S->getRequirements())
+    if (auto *TypeReq = dyn_cast<concepts::TypeRequirement>(Req)) {
+      if (!TypeReq->isSubstitutionFailure())
+        TRY_TO(TraverseTypeLoc(TypeReq->getType()->getTypeLoc()));
+    } else if (auto *ExprReq = dyn_cast<concepts::ExprRequirement>(Req)) {
+      if (!ExprReq->isExprSubstitutionFailure())
+        TRY_TO(TraverseStmt(ExprReq->getExpr()));
+      auto &RetReq = ExprReq->getReturnTypeRequirement();
+      if (RetReq.isTypeConstraint())
+        TRY_TO(TraverseTemplateParameterListHelper(
+                   RetReq.getTypeConstraintTemplateParameterList()));
+    } else {
+      auto *NestedReq = cast<concepts::NestedRequirement>(Req);
+      if (!NestedReq->isSubstitutionFailure())
+        TRY_TO(TraverseStmt(NestedReq->getConstraintExpr()));
+    }
 })
 
 // These literals (all of them) do not need any action.

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/Stmt.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/Stmt.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/Stmt.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -910,6 +910,17 @@ class alignas(void *) Stmt { (protected)
     SourceLocation NameLoc;
   };
 
+  class RequiresExprBitfields {
+    friend class ASTStmtReader;
+    friend class ASTStmtWriter;
+    friend class RequiresExpr;
+
+    unsigned : NumExprBits;
+
+    unsigned IsSatisfied : 1;
+    SourceLocation RequiresKWLoc;
+  };
+
   //===--- C++ Coroutines TS bitfields classes ---===//
 
   class CoawaitExprBitfields {
@@ -1008,6 +1019,7 @@ class alignas(void *) Stmt { (protected)
     UnresolvedMemberExprBitfields UnresolvedMemberExprBits;
     CXXNoexceptExprBitfields CXXNoexceptExprBits;
     SubstNonTypeTemplateParmExprBitfields SubstNonTypeTemplateParmExprBits;
+    RequiresExprBitfields RequiresExprBits;
 
     // C++ Coroutines TS expressions
     CoawaitExprBitfields CoawaitBits;

Modified: projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h
==============================================================================
--- projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h	Fri Jan 24 22:13:08 2020	(r357098)
+++ projects/clang1000-import/contrib/llvm-project/clang/include/clang/AST/StmtVisitor.h	Fri Jan 24 22:15:36 2020	(r357099)
@@ -13,6 +13,7 @@
 #ifndef LLVM_CLANG_AST_STMTVISITOR_H
 #define LLVM_CLANG_AST_STMTVISITOR_H

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-projects mailing list