Hi Hokein, Ilya, Clang warns on this code when compiled without asserts:
../../clang/lib/AST/TemplateName.cpp:189:3: error: unannotated fall- through between switch labels [-Werror,-Wimplicit-fallthrough] default: ^ ../../clang/lib/AST/TemplateName.cpp:189:3: note: insert 'break;' to avoid fall-through default: ^ break; 1 error generated. The code is case TemplateName::NameKind::OverloadedTemplate: assert(false && "overloaded templates shouldn't survive to here."); default: I'm not sure if there should be a break after the assert (not sure if someone would warn about that) or should there be a LLVM_FALLTHROUGH; or should the assert perhaps be an llvm_unreachable? /Mikael On Wed, 2020-03-04 at 02:25 -0800, Haojian Wu via cfe-commits wrote: > Author: Ilya Biryukov > Date: 2020-03-04T11:25:17+01:00 > New Revision: ec3060c72de6ab6992269318d92764199856e5fe > > URL: > https://github.com/llvm/llvm-project/commit/ec3060c72de6ab6992269318d92764199856e5fe > DIFF: > https://github.com/llvm/llvm-project/commit/ec3060c72de6ab6992269318d92764199856e5fe.diff > > LOG: [AST] Refactor propagation of dependency bits. NFC > > Summary: > This changes introduces an enum to represent dependencies as a > bitmask > and extract common patterns from code that computes dependency bits > into > helper functions. > > Reviewers: rsmith, martong, shafik, ilya-biryukov, hokein > > Subscribers: hokein, sammccall, Mordante, riccibruno, > merge_guards_bot, rnkovacs, cfe-commits > > Tags: #clang > > Differential Revision: https://reviews.llvm.org/D71920 > > Added: > clang/include/clang/AST/DependencyFlags.h > > Modified: > clang/include/clang/AST/Expr.h > clang/include/clang/AST/ExprConcepts.h > clang/include/clang/AST/NestedNameSpecifier.h > clang/include/clang/AST/Stmt.h > clang/include/clang/AST/TemplateBase.h > clang/include/clang/AST/TemplateName.h > clang/include/clang/AST/Type.h > clang/lib/AST/ASTImporter.cpp > clang/lib/AST/Expr.cpp > clang/lib/AST/ExprCXX.cpp > clang/lib/AST/ExprConcepts.cpp > clang/lib/AST/ExprObjC.cpp > clang/lib/AST/NestedNameSpecifier.cpp > clang/lib/AST/TemplateBase.cpp > clang/lib/AST/TemplateName.cpp > clang/lib/Sema/SemaOverload.cpp > clang/lib/Serialization/ASTReaderStmt.cpp > > Removed: > > > > ##################################################################### > ########### > diff --git a/clang/include/clang/AST/DependencyFlags.h > b/clang/include/clang/AST/DependencyFlags.h > new file mode 100644 > index 000000000000..c27016aa9aec > --- /dev/null > +++ b/clang/include/clang/AST/DependencyFlags.h > @@ -0,0 +1,138 @@ > +//===--- DependencyFlags.h --------------------------------------- > ---------===// > +// > +// 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 > +// > +//===--------------------------------------------------------------- > -------===// > +#ifndef LLVM_CLANG_AST_DEPENDENCYFLAGS_H > +#define LLVM_CLANG_AST_DEPENDENCYFLAGS_H > + > +#include "clang/Basic/BitmaskEnum.h" > +#include "llvm/ADT/BitmaskEnum.h" > +#include <cstdint> > + > +namespace clang { > +struct ExprDependenceScope { > + enum ExprDependence : uint8_t { > + UnexpandedPack = 1, > + Instantiation = 2, > + Type = 4, > + Value = 8, > + > + None = 0, > + All = 15, > + > + TypeInstantiation = Type | Instantiation, > + ValueInstantiation = Value | Instantiation, > + TypeValueInstantiation = Type | Value | Instantiation, > + > + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Value) > + }; > +}; > +using ExprDependence = ExprDependenceScope::ExprDependence; > +static constexpr unsigned ExprDependenceBits = 4; > + > +struct TypeDependenceScope { > + enum TypeDependence : uint8_t { > + /// Whether this type contains an unexpanded parameter pack > + /// (for C++11 variadic templates) > + UnexpandedPack = 1, > + /// Whether this type somehow involves a template parameter, > even > + /// if the resolution of the type does not depend on a template > parameter. > + Instantiation = 2, > + /// Whether this type is a dependent type (C++ [temp.dep.type]). > + Dependent = 4, > + /// Whether this type is a variably-modified type (C99 6.7.5). > + VariablyModified = 8, > + > + None = 0, > + All = 15, > + > + DependentInstantiation = Dependent | Instantiation, > + > + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/VariablyModified) > + }; > +}; > +using TypeDependence = TypeDependenceScope::TypeDependence; > +static constexpr unsigned TypeDependenceBits = 4; > + > +#define > LLVM_COMMON_DEPENDENCE(NAME) > \ > + struct NAME##Scope > { \ > + enum NAME : uint8_t > { \ > + UnexpandedPack = > 1, \ > + Instantiation = > 2, \ > + Dependent = > 4, \ > + > \ > + None = > 0, \ > + DependentInstantiation = Dependent | > Instantiation, \ > + All = > 7, \ > + > \ > + LLVM_MARK_AS_BITMASK_ENUM(/*LargestValue=*/Dependent) > \ > + }; > \ > + }; > \ > + using NAME = > NAME##Scope::NAME; \ > + static constexpr unsigned NAME##Bits = 3; > + > +LLVM_COMMON_DEPENDENCE(NestedNameSpecifierDependence) > +LLVM_COMMON_DEPENDENCE(TemplateNameDependence) > +LLVM_COMMON_DEPENDENCE(TemplateArgumentDependence) > +#undef LLVM_COMMON_DEPENDENCE > + > +/// Computes dependencies of a reference with the name having > template arguments > +/// with \p TA dependencies. > +inline ExprDependence toExprDependence(TemplateArgumentDependence > TA) { > + auto E = > + static_cast<ExprDependence>(TA & > ~TemplateArgumentDependence::Dependent); > + if (TA & TemplateArgumentDependence::Dependent) > + return E | ExprDependence::Type | ExprDependence::Value; > + return E; > +} > +inline ExprDependence toExprDependence(TypeDependence TD) { > + // This hack works because TypeDependence and > TemplateArgumentDependence > + // share the same bit representation, apart from variably- > modified. > + return toExprDependence(static_cast<TemplateArgumentDependence>( > + TD & ~TypeDependence::VariablyModified)); > +} > +inline ExprDependence turnTypeToValueDependence(ExprDependence D) { > + // Type-dependent expressions are always be value-dependent, so we > simply drop > + // type dependency. > + return D & ~ExprDependence::Type; > +} > + > +inline NestedNameSpecifierDependence > +toNestedNameSpecifierDependendence(TypeDependence D) { > + // This works because both classes share the same bit > representation. > + return static_cast<NestedNameSpecifierDependence>( > + D & ~TypeDependence::VariablyModified); > +} > + > +inline TemplateArgumentDependence > +toTemplateArgumentDependence(TypeDependence D) { > + // This works because both classes share the same bit > representation. > + return static_cast<TemplateArgumentDependence>( > + D & ~TypeDependence::VariablyModified); > +} > +inline TemplateArgumentDependence > +toTemplateArgumentDependence(TemplateNameDependence D) { > + // This works because both classes share the same bit > representation. > + return static_cast<TemplateArgumentDependence>(D); > +} > +inline TemplateArgumentDependence > +toTemplateArgumentDependence(ExprDependence ED) { > + TemplateArgumentDependence TAD = > static_cast<TemplateArgumentDependence>( > + ED & ~(ExprDependence::Type | ExprDependence::Value)); > + if (ED & (ExprDependence::Type | ExprDependence::Value)) > + TAD |= TemplateArgumentDependence::Dependent; > + return TAD; > +} > + > +inline TemplateNameDependence > +toTemplateNameDependence(NestedNameSpecifierDependence D) { > + return static_cast<TemplateNameDependence>(D); > +} > + > +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); > + > +} // namespace clang > +#endif > > diff --git a/clang/include/clang/AST/Expr.h > b/clang/include/clang/AST/Expr.h > index 87f9b883486a..ffc1f54fe82d 100644 > --- a/clang/include/clang/AST/Expr.h > +++ b/clang/include/clang/AST/Expr.h > @@ -17,6 +17,7 @@ > #include "clang/AST/ASTVector.h" > #include "clang/AST/Decl.h" > #include "clang/AST/DeclAccessPair.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/OperationKinds.h" > #include "clang/AST/Stmt.h" > #include "clang/AST/TemplateBase.h" > @@ -28,10 +29,10 @@ > #include "clang/Basic/TypeTraits.h" > #include "llvm/ADT/APFloat.h" > #include "llvm/ADT/APSInt.h" > -#include "llvm/ADT/iterator.h" > -#include "llvm/ADT/iterator_range.h" > #include "llvm/ADT/SmallVector.h" > #include "llvm/ADT/StringRef.h" > +#include "llvm/ADT/iterator.h" > +#include "llvm/ADT/iterator_range.h" > #include "llvm/Support/AtomicOrdering.h" > #include "llvm/Support/Compiler.h" > #include "llvm/Support/TrailingObjects.h" > @@ -120,13 +121,20 @@ class Expr : public ValueStmt { > bool TD, bool VD, bool ID, bool > ContainsUnexpandedParameterPack) > : ValueStmt(SC) > { > - ExprBits.TypeDependent = TD; > - ExprBits.ValueDependent = VD; > - ExprBits.InstantiationDependent = ID; > + auto D = ExprDependence::None; > + if (TD) > + D |= ExprDependence::Type; > + if (VD) > + D |= ExprDependence::Value; > + if (ID) > + D |= ExprDependence::Instantiation; > + if (ContainsUnexpandedParameterPack) > + D |= ExprDependence::UnexpandedPack; > + > + ExprBits.Dependent = static_cast<unsigned>(D); > ExprBits.ValueKind = VK; > ExprBits.ObjectKind = OK; > assert(ExprBits.ObjectKind == OK && "truncated kind"); > - ExprBits.ContainsUnexpandedParameterPack = > ContainsUnexpandedParameterPack; > setType(T); > } > > @@ -148,6 +156,20 @@ class Expr : public ValueStmt { > TR = t; > } > > + ExprDependence getDependence() const { > + return static_cast<ExprDependence>(ExprBits.Dependent); > + } > + > + void setDependence(ExprDependence Deps) { > + ExprBits.Dependent = static_cast<unsigned>(Deps); > + } > + void addDependence(ExprDependence Deps) { > + ExprBits.Dependent |= static_cast<unsigned>(Deps); > + } > + void removeDependence(ExprDependence Deps) { > + ExprBits.Dependent &= ~static_cast<unsigned>(Deps); > + } > + > /// isValueDependent - Determines whether this expression is > /// value-dependent (C++ [temp.dep.constexpr]). For example, the > /// array bound of "Chars" in the following example is > @@ -155,11 +177,8 @@ class Expr : public ValueStmt { > /// @code > /// template<int Size, char (&Chars)[Size]> struct meta_string; > /// @endcode > - bool isValueDependent() const { return ExprBits.ValueDependent; } > - > - /// Set whether this expression is value-dependent or not. > - void setValueDependent(bool VD) { > - ExprBits.ValueDependent = VD; > + bool isValueDependent() const { > + return static_cast<bool>(getDependence() & > ExprDependence::Value); > } > > /// isTypeDependent - Determines whether this expression is > @@ -173,11 +192,8 @@ class Expr : public ValueStmt { > /// x + y; > /// } > /// @endcode > - bool isTypeDependent() const { return ExprBits.TypeDependent; } > - > - /// Set whether this expression is type-dependent or not. > - void setTypeDependent(bool TD) { > - ExprBits.TypeDependent = TD; > + bool isTypeDependent() const { > + return static_cast<bool>(getDependence() & > ExprDependence::Type); > } > > /// Whether this expression is instantiation-dependent, meaning > that > @@ -198,12 +214,7 @@ class Expr : public ValueStmt { > /// \endcode > /// > bool isInstantiationDependent() const { > - return ExprBits.InstantiationDependent; > - } > - > - /// Set whether this expression is instantiation-dependent or not. > - void setInstantiationDependent(bool ID) { > - ExprBits.InstantiationDependent = ID; > + return static_cast<bool>(getDependence() & > ExprDependence::Instantiation); > } > > /// Whether this expression contains an unexpanded parameter > @@ -221,13 +232,7 @@ class Expr : public ValueStmt { > /// The expressions \c args and \c static_cast<Types&&>(args) both > /// contain parameter packs. > bool containsUnexpandedParameterPack() const { > - return ExprBits.ContainsUnexpandedParameterPack; > - } > - > - /// Set the bit that describes whether this expression > - /// contains an unexpanded parameter pack. > - void setContainsUnexpandedParameterPack(bool PP = true) { > - ExprBits.ContainsUnexpandedParameterPack = PP; > + return static_cast<bool>(getDependence() & > ExprDependence::UnexpandedPack); > } > > /// getExprLoc - Return the preferred location for the arrow when > diagnosing > @@ -1215,10 +1220,6 @@ class DeclRefExpr final > /// Construct an empty declaration reference expression. > explicit DeclRefExpr(EmptyShell Empty) : Expr(DeclRefExprClass, > Empty) {} > > - /// Computes the type- and value-dependence flags for this > - /// declaration reference expression. > - void computeDependence(const ASTContext &Ctx); > - > public: > DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, > bool RefersToEnclosingVariableOrCapture, QualType T, > @@ -2558,8 +2559,6 @@ class CallExpr : public Expr { > /// the derived classes of CallExpr. > SourceLocation RParenLoc; > > - void updateDependenciesFromArg(Expr *Arg); > - > // CallExpr store some data in trailing objects. However since > CallExpr > // is used a base of other expression classes we cannot use > // llvm::TrailingObjects. Instead we manually perform the pointer > arithmetic > @@ -4467,13 +4466,8 @@ class InitListExpr : public Expr { > assert(Init < getNumInits() && "Initializer access out of > range!"); > InitExprs[Init] = expr; > > - if (expr) { > - ExprBits.TypeDependent |= expr->isTypeDependent(); > - ExprBits.ValueDependent |= expr->isValueDependent(); > - ExprBits.InstantiationDependent |= expr- > >isInstantiationDependent(); > - ExprBits.ContainsUnexpandedParameterPack |= > - expr->containsUnexpandedParameterPack(); > - } > + if (expr) > + addDependence(expr->getDependence()); > } > > /// Reserve space for some number of initializers. > > diff --git a/clang/include/clang/AST/ExprConcepts.h > b/clang/include/clang/AST/ExprConcepts.h > index 6137e0e4082b..2a88ed5175d2 100644 > --- a/clang/include/clang/AST/ExprConcepts.h > +++ b/clang/include/clang/AST/ExprConcepts.h > @@ -149,6 +149,7 @@ class Requirement { > enum RequirementKind { RK_Type, RK_Simple, RK_Compound, RK_Nested > }; > private: > const RequirementKind Kind; > + // FIXME: use RequirementDependence to model dependence? > bool Dependent : 1; > bool ContainsUnexpandedParameterPack : 1; > bool Satisfied : 1; > > diff --git a/clang/include/clang/AST/NestedNameSpecifier.h > b/clang/include/clang/AST/NestedNameSpecifier.h > index c6fae6f465ff..e465c33e2cc5 100644 > --- a/clang/include/clang/AST/NestedNameSpecifier.h > +++ b/clang/include/clang/AST/NestedNameSpecifier.h > @@ -14,6 +14,7 @@ > #ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H > #define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H > > +#include "clang/AST/DependencyFlags.h" > #include "clang/Basic/Diagnostic.h" > #include "clang/Basic/SourceLocation.h" > #include "llvm/ADT/FoldingSet.h" > @@ -199,6 +200,8 @@ class NestedNameSpecifier : public > llvm::FoldingSetNode { > return nullptr; > } > > + NestedNameSpecifierDependence getDependence() const; > + > /// Whether this nested name specifier refers to a dependent > /// type or not. > bool isDependent() const; > > diff --git a/clang/include/clang/AST/Stmt.h > b/clang/include/clang/AST/Stmt.h > index 5cc4eb8a46df..5191a8261f86 100644 > --- a/clang/include/clang/AST/Stmt.h > +++ b/clang/include/clang/AST/Stmt.h > @@ -14,6 +14,7 @@ > #define LLVM_CLANG_AST_STMT_H > > #include "clang/AST/DeclGroup.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/StmtIterator.h" > #include "clang/Basic/CapturedStmt.h" > #include "clang/Basic/IdentifierTable.h" > @@ -315,12 +316,9 @@ class alignas(void *) Stmt { > > unsigned ValueKind : 2; > unsigned ObjectKind : 3; > - unsigned TypeDependent : 1; > - unsigned ValueDependent : 1; > - unsigned InstantiationDependent : 1; > - unsigned ContainsUnexpandedParameterPack : 1; > + unsigned /*ExprDependence*/ Dependent : ExprDependenceBits; > }; > - enum { NumExprBits = NumStmtBits + 9 }; > + enum { NumExprBits = NumStmtBits + 5 + ExprDependenceBits }; > > class ConstantExprBitfields { > friend class ASTStmtReader; > > diff --git a/clang/include/clang/AST/TemplateBase.h > b/clang/include/clang/AST/TemplateBase.h > index 93f7b62b8aea..e5fd1ca9dd46 100644 > --- a/clang/include/clang/AST/TemplateBase.h > +++ b/clang/include/clang/AST/TemplateBase.h > @@ -14,6 +14,7 @@ > #ifndef LLVM_CLANG_AST_TEMPLATEBASE_H > #define LLVM_CLANG_AST_TEMPLATEBASE_H > > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/NestedNameSpecifier.h" > #include "clang/AST/TemplateName.h" > #include "clang/AST/Type.h" > @@ -236,6 +237,8 @@ class TemplateArgument { > /// Determine whether this template argument has no value. > bool isNull() const { return getKind() == Null; } > > + TemplateArgumentDependence getDependence() const; > + > /// Whether this template argument is dependent on a template > /// parameter such that its result can change from one > instantiation to > /// another. > @@ -668,9 +671,8 @@ struct alignas(void *) ASTTemplateKWAndArgsInfo { > TemplateArgumentLoc *OutArgArray); > void initializeFrom(SourceLocation TemplateKWLoc, > const TemplateArgumentListInfo &List, > - TemplateArgumentLoc *OutArgArray, bool > &Dependent, > - bool &InstantiationDependent, > - bool &ContainsUnexpandedParameterPack); > + TemplateArgumentLoc *OutArgArray, > + TemplateArgumentDependence &Deps); > void initializeFrom(SourceLocation TemplateKWLoc); > > void copyInto(const TemplateArgumentLoc *ArgArray, > > diff --git a/clang/include/clang/AST/TemplateName.h > b/clang/include/clang/AST/TemplateName.h > index e1315facc966..bf917788477f 100644 > --- a/clang/include/clang/AST/TemplateName.h > +++ b/clang/include/clang/AST/TemplateName.h > @@ -13,6 +13,7 @@ > #ifndef LLVM_CLANG_AST_TEMPLATENAME_H > #define LLVM_CLANG_AST_TEMPLATENAME_H > > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/NestedNameSpecifier.h" > #include "clang/Basic/LLVM.h" > #include "llvm/ADT/FoldingSet.h" > @@ -295,6 +296,8 @@ class TemplateName { > /// the template, including any default template arguments. > TemplateName getNameToSubstitute() const; > > + TemplateNameDependence getDependence() const; > + > /// Determines whether this is a dependent template name. > bool isDependent() const; > > > diff --git a/clang/include/clang/AST/Type.h > b/clang/include/clang/AST/Type.h > index e8248147f9ad..e589d3fa4e64 100644 > --- a/clang/include/clang/AST/Type.h > +++ b/clang/include/clang/AST/Type.h > @@ -17,6 +17,7 @@ > #ifndef LLVM_CLANG_AST_TYPE_H > #define LLVM_CLANG_AST_TYPE_H > > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/NestedNameSpecifier.h" > #include "clang/AST/TemplateName.h" > #include "clang/Basic/AddressSpaces.h" > @@ -44,8 +45,8 @@ > #include "llvm/Support/Compiler.h" > #include "llvm/Support/ErrorHandling.h" > #include "llvm/Support/PointerLikeTypeTraits.h" > -#include "llvm/Support/type_traits.h" > #include "llvm/Support/TrailingObjects.h" > +#include "llvm/Support/type_traits.h" > #include <cassert> > #include <cstddef> > #include <cstdint> > @@ -1465,19 +1466,8 @@ class alignas(8) Type : public > ExtQualsTypeCommonBase { > /// TypeClass bitfield - Enum that specifies what subclass this > belongs to. > unsigned TC : 8; > > - /// Whether this type is a dependent type (C++ [temp.dep.type]). > - unsigned Dependent : 1; > - > - /// Whether this type somehow involves a template parameter, > even > - /// if the resolution of the type does not depend on a template > parameter. > - unsigned InstantiationDependent : 1; > - > - /// Whether this type is a variably-modified type (C99 6.7.5). > - unsigned VariablyModified : 1; > - > - /// Whether this type contains an unexpanded parameter pack > - /// (for C++11 variadic templates). > - unsigned ContainsUnexpandedParameterPack : 1; > + /// Store information on the type dependency. > + /*TypeDependence*/ unsigned Dependence : TypeDependenceBits; > > /// True if the cache (i.e. the bitfields here starting with > /// 'Cache') is valid. > @@ -1833,11 +1823,18 @@ class alignas(8) Type : public > ExtQualsTypeCommonBase { > bool ContainsUnexpandedParameterPack) > : ExtQualsTypeCommonBase(this, > canon.isNull() ? QualType(this_(), 0) > : canon) { > + auto Deps = TypeDependence::None; > + if (Dependent) > + Deps |= TypeDependence::Dependent | > TypeDependence::Instantiation; > + if (InstantiationDependent) > + Deps |= TypeDependence::Instantiation; > + if (ContainsUnexpandedParameterPack) > + Deps |= TypeDependence::UnexpandedPack; > + if (VariablyModified) > + Deps |= TypeDependence::VariablyModified; > + > TypeBits.TC = tc; > - TypeBits.Dependent = Dependent; > - TypeBits.InstantiationDependent = Dependent || > InstantiationDependent; > - TypeBits.VariablyModified = VariablyModified; > - TypeBits.ContainsUnexpandedParameterPack = > ContainsUnexpandedParameterPack; > + TypeBits.Dependence = static_cast<unsigned>(Deps); > TypeBits.CacheValid = false; > TypeBits.CachedLocalOrUnnamed = false; > TypeBits.CachedLinkage = NoLinkage; > @@ -1848,18 +1845,39 @@ class alignas(8) Type : public > ExtQualsTypeCommonBase { > Type *this_() { return this; } > > void setDependent(bool D = true) { > - TypeBits.Dependent = D; > - if (D) > - TypeBits.InstantiationDependent = true; > + if (!D) { > + TypeBits.Dependence &= > ~static_cast<unsigned>(TypeDependence::Dependent); > + return; > + } > + TypeBits.Dependence |= > static_cast<unsigned>(TypeDependence::Dependent | > + TypeDependence::Ins > tantiation); > } > > void setInstantiationDependent(bool D = true) { > - TypeBits.InstantiationDependent = D; } > + if (D) > + TypeBits.Dependence |= > + static_cast<unsigned>(TypeDependence::Instantiation); > + else > + TypeBits.Dependence &= > + ~static_cast<unsigned>(TypeDependence::Instantiation); > + } > > - void setVariablyModified(bool VM = true) { > TypeBits.VariablyModified = VM; } > + void setVariablyModified(bool VM = true) { > + if (VM) > + TypeBits.Dependence |= > + static_cast<unsigned>(TypeDependence::VariablyModified); > + else > + TypeBits.Dependence &= > + ~static_cast<unsigned>(TypeDependence::VariablyModified); > + } > > void setContainsUnexpandedParameterPack(bool PP = true) { > - TypeBits.ContainsUnexpandedParameterPack = PP; > + if (PP) > + TypeBits.Dependence |= > + static_cast<unsigned>(TypeDependence::UnexpandedPack); > + else > + TypeBits.Dependence &= > + ~static_cast<unsigned>(TypeDependence::UnexpandedPack); > } > > public: > @@ -1894,7 +1912,7 @@ class alignas(8) Type : public > ExtQualsTypeCommonBase { > /// > /// Note that this routine does not specify which > bool containsUnexpandedParameterPack() const { > - return TypeBits.ContainsUnexpandedParameterPack; > + return getDependence() & TypeDependence::UnexpandedPack; > } > > /// Determines if this type would be canonical if it had no > further > @@ -2145,16 +2163,22 @@ class alignas(8) Type : public > ExtQualsTypeCommonBase { > /// Given that this is a scalar type, classify it. > ScalarTypeKind getScalarTypeKind() const; > > + TypeDependence getDependence() const { > + return static_cast<TypeDependence>(TypeBits.Dependence); > + } > + > /// Whether this type is a dependent type, meaning that its > definition > /// somehow depends on a template parameter (C++ [temp.dep.type]). > - bool isDependentType() const { return TypeBits.Dependent; } > + bool isDependentType() const { > + return getDependence() & TypeDependence::Dependent; > + } > > /// Determine whether this type is an instantiation-dependent > type, > /// meaning that the type involves a template parameter (even if > the > /// definition does not actually depend on the type substituted > for that > /// template parameter). > bool isInstantiationDependentType() const { > - return TypeBits.InstantiationDependent; > + return getDependence() & TypeDependence::Instantiation; > } > > /// Determine whether this type is an undeduced type, meaning that > @@ -2163,7 +2187,9 @@ class alignas(8) Type : public > ExtQualsTypeCommonBase { > bool isUndeducedType() const; > > /// Whether this type is a variably-modified type (C99 6.7.5). > - bool isVariablyModifiedType() const { return > TypeBits.VariablyModified; } > + bool isVariablyModifiedType() const { > + return getDependence() & TypeDependence::VariablyModified; > + } > > /// Whether this type involves a variable-length array type > /// with a definite size. > > diff --git a/clang/lib/AST/ASTImporter.cpp > b/clang/lib/AST/ASTImporter.cpp > index 0cf00f6ca15b..ddbd3699bdc2 100644 > --- a/clang/lib/AST/ASTImporter.cpp > +++ b/clang/lib/AST/ASTImporter.cpp > @@ -8221,11 +8221,7 @@ Expected<Stmt *> ASTImporter::Import(Stmt > *FromS) { > // constructors. > ToE->setValueKind(FromE->getValueKind()); > ToE->setObjectKind(FromE->getObjectKind()); > - ToE->setTypeDependent(FromE->isTypeDependent()); > - ToE->setValueDependent(FromE->isValueDependent()); > - ToE->setInstantiationDependent(FromE- > >isInstantiationDependent()); > - ToE->setContainsUnexpandedParameterPack( > - FromE->containsUnexpandedParameterPack()); > + ToE->setDependence(FromE->getDependence()); > } > > // Record the imported statement object. > > diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp > index 7e8808f84ead..79f9f42224d0 100644 > --- a/clang/lib/AST/Expr.cpp > +++ b/clang/lib/AST/Expr.cpp > @@ -17,6 +17,7 @@ > #include "clang/AST/DeclCXX.h" > #include "clang/AST/DeclObjC.h" > #include "clang/AST/DeclTemplate.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/EvaluatedExprVisitor.h" > #include "clang/AST/ExprCXX.h" > #include "clang/AST/Mangle.h" > @@ -371,13 +372,11 @@ APValue ConstantExpr::getAPValueResult() const > { > /// Compute the type-, value-, and instantiation-dependence of a > /// declaration reference > /// based on the declaration being referenced. > -static void computeDeclRefDependence(const ASTContext &Ctx, > NamedDecl *D, > - QualType T, bool > &TypeDependent, > - bool &ValueDependent, > - bool &InstantiationDependent) { > - TypeDependent = false; > - ValueDependent = false; > - InstantiationDependent = false; > +static ExprDependence computeDeclRefDependence(const ASTContext > &Ctx, > + NamedDecl *D, > QualType T) { > + auto R = ExprDependence::None; > + if (D->isParameterPack()) > + R |= ExprDependence::UnexpandedPack; > > // (TD) C++ [temp.dep.expr]p3: > // An id-expression is type-dependent if it contains: > @@ -389,36 +388,25 @@ static void computeDeclRefDependence(const > ASTContext &Ctx, NamedDecl *D, > > // (TD) - an identifier that was declared with dependent type > // (VD) - a name declared with a dependent type, > - if (T->isDependentType()) { > - TypeDependent = true; > - ValueDependent = true; > - InstantiationDependent = true; > - return; > - } else if (T->isInstantiationDependentType()) { > - InstantiationDependent = true; > - } > + if (T->isDependentType()) > + return R | ExprDependence::TypeValueInstantiation; > + else if (T->isInstantiationDependentType()) > + R |= ExprDependence::Instantiation; > > // (TD) - a conversion-function-id that specifies a dependent > type > if (D->getDeclName().getNameKind() > == > DeclarationName::CXXConversionFunctionName) { > QualType T = D->getDeclName().getCXXNameType(); > - if (T->isDependentType()) { > - TypeDependent = true; > - ValueDependent = true; > - InstantiationDependent = true; > - return; > - } > + if (T->isDependentType()) > + return R | ExprDependence::TypeValueInstantiation; > > if (T->isInstantiationDependentType()) > - InstantiationDependent = true; > + R |= ExprDependence::Instantiation; > } > > // (VD) - the name of a non-type template parameter, > - if (isa<NonTypeTemplateParmDecl>(D)) { > - ValueDependent = true; > - InstantiationDependent = true; > - return; > - } > + if (isa<NonTypeTemplateParmDecl>(D)) > + return R | ExprDependence::ValueInstantiation; > > // (VD) - a constant with integral or enumeration type and is > // initialized with an expression that is value-dependent. > @@ -435,8 +423,7 @@ static void computeDeclRefDependence(const > ASTContext &Ctx, NamedDecl *D, > Var->getType()->isReferenceType())) { > if (const Expr *Init = Var->getAnyInitializer()) > if (Init->isValueDependent()) { > - ValueDependent = true; > - InstantiationDependent = true; > + R |= ExprDependence::ValueInstantiation; > } > } > > @@ -445,39 +432,21 @@ static void computeDeclRefDependence(const > ASTContext &Ctx, NamedDecl *D, > // instantiation > if (Var->isStaticDataMember() && > Var->getDeclContext()->isDependentContext()) { > - ValueDependent = true; > - InstantiationDependent = true; > + R |= ExprDependence::ValueInstantiation; > TypeSourceInfo *TInfo = Var->getFirstDecl()- > >getTypeSourceInfo(); > if (TInfo->getType()->isIncompleteArrayType()) > - TypeDependent = true; > + R |= ExprDependence::Type; > } > > - return; > + return R; > } > > // (VD) - FIXME: Missing from the standard: > // - a member function or a static data member of the > current > // instantiation > - if (isa<CXXMethodDecl>(D) && D->getDeclContext()- > >isDependentContext()) { > - ValueDependent = true; > - InstantiationDependent = true; > - } > -} > - > -void DeclRefExpr::computeDependence(const ASTContext &Ctx) { > - bool TypeDependent = false; > - bool ValueDependent = false; > - bool InstantiationDependent = false; > - computeDeclRefDependence(Ctx, getDecl(), getType(), TypeDependent, > - ValueDependent, InstantiationDependent); > - > - ExprBits.TypeDependent |= TypeDependent; > - ExprBits.ValueDependent |= ValueDependent; > - ExprBits.InstantiationDependent |= InstantiationDependent; > - > - // Is the declaration a parameter pack? > - if (getDecl()->isParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + if (isa<CXXMethodDecl>(D) && D->getDeclContext()- > >isDependentContext()) > + R |= ExprDependence::ValueInstantiation; > + return R; > } > > DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, > @@ -495,7 +464,7 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, > ValueDecl *D, > RefersToEnclosingVariableOrCapture; > DeclRefExprBits.NonOdrUseReason = NOUR; > DeclRefExprBits.Loc = L; > - computeDependence(Ctx); > + addDependence(computeDeclRefDependence(Ctx, getDecl(), > getType())); > } > > DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, > @@ -514,9 +483,9 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, > NestedNameSpecifierLoc(QualifierLoc); > auto *NNS = QualifierLoc.getNestedNameSpecifier(); > if (NNS->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > + addDependence(ExprDependence::Instantiation); > if (NNS->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + addDependence(ExprDependence::UnexpandedPack); > } > DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0; > if (FoundD) > @@ -527,22 +496,19 @@ DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, > RefersToEnclosingVariableOrCapture; > DeclRefExprBits.NonOdrUseReason = NOUR; > if (TemplateArgs) { > - bool Dependent = false; > - bool InstantiationDependent = false; > - bool ContainsUnexpandedParameterPack = false; > + auto Deps = TemplateArgumentDependence::None; > getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( > TemplateKWLoc, *TemplateArgs, > getTrailingObjects<TemplateArgumentLoc>(), > - Dependent, InstantiationDependent, > ContainsUnexpandedParameterPack); > - assert(!Dependent && "built a DeclRefExpr with dependent > template args"); > - ExprBits.InstantiationDependent |= InstantiationDependent; > - ExprBits.ContainsUnexpandedParameterPack |= > ContainsUnexpandedParameterPack; > + Deps); > + assert(!(Deps & TemplateArgumentDependence::Dependent) && > + "built a DeclRefExpr with dependent template args"); > + addDependence(toExprDependence(Deps)); > } else if (TemplateKWLoc.isValid()) { > getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( > TemplateKWLoc); > } > DeclRefExprBits.HadMultipleCandidates = 0; > - > - computeDependence(Ctx); > + addDependence(computeDeclRefDependence(Ctx, getDecl(), > getType())); > } > > DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context, > @@ -1360,11 +1326,11 @@ CallExpr::CallExpr(StmtClass SC, Expr *Fn, > ArrayRef<Expr *> PreArgs, > > setCallee(Fn); > for (unsigned I = 0; I != NumPreArgs; ++I) { > - updateDependenciesFromArg(PreArgs[I]); > + addDependence(PreArgs[I]->getDependence()); > setPreArg(I, PreArgs[I]); > } > for (unsigned I = 0; I != Args.size(); ++I) { > - updateDependenciesFromArg(Args[I]); > + addDependence(Args[I]->getDependence()); > setArg(I, Args[I]); > } > for (unsigned I = Args.size(); I != NumArgs; ++I) { > @@ -1432,17 +1398,6 @@ unsigned > CallExpr::offsetToTrailingObjects(StmtClass SC) { > } > } > > -void CallExpr::updateDependenciesFromArg(Expr *Arg) { > - if (Arg->isTypeDependent()) > - ExprBits.TypeDependent = true; > - if (Arg->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (Arg->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (Arg->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > -} > - > Decl *Expr::getReferencedDeclOfCallee() { > Expr *CEE = IgnoreParenImpCasts(); > > @@ -1580,9 +1535,9 @@ OffsetOfExpr::OffsetOfExpr(const ASTContext &C, > QualType type, > > for (unsigned i = 0; i != exprs.size(); ++i) { > if (exprs[i]->isTypeDependent() || exprs[i]->isValueDependent()) > - ExprBits.ValueDependent = true; > + addDependence(ExprDependence::Value); > if (exprs[i]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + addDependence(ExprDependence ::UnexpandedPack); > > setIndexExpr(i, exprs[i]); > } > @@ -1624,8 +1579,7 @@ > UnaryExprOrTypeTraitExpr::UnaryExprOrTypeTraitExpr( > if (D) { > for (const auto *I : D->specific_attrs<AlignedAttr>()) { > if (I->isAlignmentDependent()) { > - setValueDependent(true); > - setInstantiationDependent(true); > + addDependence(ExprDependence::ValueInstantiation); > break; > } > } > @@ -1678,25 +1632,23 @@ MemberExpr *MemberExpr::Create( > // dyn_cast_or_null is used to handle objC variables which do > not > // have a declaration context. > CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(DC); > - if (RD && RD->isDependentContext() && RD- > >isCurrentInstantiation(DC)) > - E->setTypeDependent(T->isDependentType()); > - > + if (RD && RD->isDependentContext() && RD- > >isCurrentInstantiation(DC)) { > + if (E->isTypeDependent() && !T->isDependentType()) > + E->removeDependence(ExprDependence::Type); > + } > // Bitfield with value-dependent width is type-dependent. > FieldDecl *FD = dyn_cast<FieldDecl>(MemberDecl); > if (FD && FD->isBitField() && FD->getBitWidth()- > >isValueDependent()) > - E->setTypeDependent(true); > + E->addDependence(ExprDependence::Type); > } > > if (HasQualOrFound) { > // FIXME: Wrong. We should be looking at the member declaration > we found. > - if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()- > >isDependent()) { > - E->setValueDependent(true); > - E->setTypeDependent(true); > - E->setInstantiationDependent(true); > - } > + if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()- > >isDependent()) > + E->addDependence(ExprDependence::TypeValueInstantiation); > else if (QualifierLoc && > QualifierLoc.getNestedNameSpecifier()- > >isInstantiationDependent()) > - E->setInstantiationDependent(true); > + E->addDependence(ExprDependence::Instantiation); > > E->MemberExprBits.HasQualifierOrFoundDecl = true; > > @@ -1710,15 +1662,12 @@ MemberExpr *MemberExpr::Create( > TemplateArgs || TemplateKWLoc.isValid(); > > if (TemplateArgs) { > - bool Dependent = false; > - bool InstantiationDependent = false; > - bool ContainsUnexpandedParameterPack = false; > + auto Deps = TemplateArgumentDependence::None; > E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()- > >initializeFrom( > TemplateKWLoc, *TemplateArgs, > - E->getTrailingObjects<TemplateArgumentLoc>(), Dependent, > - InstantiationDependent, ContainsUnexpandedParameterPack); > - if (InstantiationDependent) > - E->setInstantiationDependent(true); > + E->getTrailingObjects<TemplateArgumentLoc>(), Deps); > + if (Deps & TemplateArgumentDependence::Instantiation) > + E->addDependence(ExprDependence::Instantiation); > } else if (TemplateKWLoc.isValid()) { > E->getTrailingObjects<ASTTemplateKWAndArgsInfo>()- > >initializeFrom( > TemplateKWLoc); > @@ -2236,16 +2185,8 @@ InitListExpr::InitListExpr(const ASTContext > &C, SourceLocation lbraceloc, > LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), AltForm(nullptr, > true) > { > sawArrayRangeDesignator(false); > - for (unsigned I = 0; I != initExprs.size(); ++I) { > - if (initExprs[I]->isTypeDependent()) > - ExprBits.TypeDependent = true; > - if (initExprs[I]->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (initExprs[I]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (initExprs[I]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > - } > + for (unsigned I = 0; I != initExprs.size(); ++I) > + addDependence(initExprs[I]->getDependence()); > > InitExprs.insert(C, InitExprs.end(), initExprs.begin(), > initExprs.end()); > } > @@ -4167,15 +4108,7 @@ ShuffleVectorExpr::ShuffleVectorExpr(const > ASTContext &C, ArrayRef<Expr*> args, > { > SubExprs = new (C) Stmt*[args.size()]; > for (unsigned i = 0; i != args.size(); i++) { > - if (args[i]->isTypeDependent()) > - ExprBits.TypeDependent = true; > - if (args[i]->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (args[i]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (args[i]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > - > + addDependence(args[i]->getDependence()); > SubExprs[i] = args[i]; > } > } > @@ -4319,13 +4252,12 @@ DesignatedInitExpr::DesignatedInitExpr(const > ASTContext &C, QualType Ty, > if (this->Designators[I].isArrayDesignator()) { > // Compute type- and value-dependence. > Expr *Index = IndexExprs[IndexIdx]; > - if (Index->isTypeDependent() || Index->isValueDependent()) > - ExprBits.TypeDependent = ExprBits.ValueDependent = true; > - if (Index->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - // Propagate unexpanded parameter packs. > - if (Index->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + > + // Propagate dependence flags. > + auto Deps = Index->getDependence(); > + if (Deps & (ExprDependence::Type | ExprDependence::Value)) > + Deps |= ExprDependence::Type | ExprDependence::Value; > + addDependence(Deps); > > // Copy the index expressions into permanent storage. > *Child++ = IndexExprs[IndexIdx++]; > @@ -4333,19 +4265,11 @@ DesignatedInitExpr::DesignatedInitExpr(const > ASTContext &C, QualType Ty, > // Compute type- and value-dependence. > Expr *Start = IndexExprs[IndexIdx]; > Expr *End = IndexExprs[IndexIdx + 1]; > - if (Start->isTypeDependent() || Start->isValueDependent() || > - End->isTypeDependent() || End->isValueDependent()) { > - ExprBits.TypeDependent = ExprBits.ValueDependent = true; > - ExprBits.InstantiationDependent = true; > - } else if (Start->isInstantiationDependent() || > - End->isInstantiationDependent()) { > - ExprBits.InstantiationDependent = true; > - } > > - // Propagate unexpanded parameter packs. > - if (Start->containsUnexpandedParameterPack() || > - End->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + auto Deps = Start->getDependence() | End->getDependence(); > + if (Deps & (ExprDependence::Type | ExprDependence::Value)) > + Deps |= ExprDependence::TypeValueInstantiation; > + addDependence(Deps); > > // Copy the start/end expressions into permanent storage. > *Child++ = IndexExprs[IndexIdx++]; > @@ -4483,15 +4407,7 @@ ParenListExpr::ParenListExpr(SourceLocation > LParenLoc, ArrayRef<Expr *> Exprs, > ParenListExprBits.NumExprs = Exprs.size(); > > for (unsigned I = 0, N = Exprs.size(); I != N; ++I) { > - if (Exprs[I]->isTypeDependent()) > - ExprBits.TypeDependent = true; > - if (Exprs[I]->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (Exprs[I]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (Exprs[I]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > - > + addDependence(Exprs[I]->getDependence()); > getTrailingObjects<Stmt *>()[I] = Exprs[I]; > } > } > @@ -4578,14 +4494,7 @@ PseudoObjectExpr::PseudoObjectExpr(QualType > type, ExprValueKind VK, > Expr *E = (i == 0 ? syntax : semantics[i-1]); > getSubExprsBuffer()[i] = E; > > - if (E->isTypeDependent()) > - ExprBits.TypeDependent = true; > - if (E->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (E->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (E->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + addDependence(E->getDependence()); > > if (isa<OpaqueValueExpr>(E)) > assert(cast<OpaqueValueExpr>(E)->getSourceExpr() != nullptr && > @@ -4626,15 +4535,7 @@ AtomicExpr::AtomicExpr(SourceLocation BLoc, > ArrayRef<Expr*> args, > { > assert(args.size() == getNumSubExprs(op) && "wrong number of > subexpressions"); > for (unsigned i = 0; i != args.size(); i++) { > - if (args[i]->isTypeDependent()) > - ExprBits.TypeDependent = true; > - if (args[i]->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (args[i]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (args[i]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > - > + addDependence(args[i]->getDependence()); > SubExprs[i] = args[i]; > } > } > > diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp > index e4bd218ae2d3..38cdfcf752df 100644 > --- a/clang/lib/AST/ExprCXX.cpp > +++ b/clang/lib/AST/ExprCXX.cpp > @@ -19,6 +19,7 @@ > #include "clang/AST/DeclCXX.h" > #include "clang/AST/DeclTemplate.h" > #include "clang/AST/DeclarationName.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/Expr.h" > #include "clang/AST/LambdaCapture.h" > #include "clang/AST/NestedNameSpecifier.h" > @@ -194,36 +195,20 @@ CXXNewExpr::CXXNewExpr(bool IsGlobalNew, > FunctionDecl *OperatorNew, > CXXNewExprBits.NumPlacementArgs = PlacementArgs.size(); > > if (ArraySize) { > - if (Expr *SizeExpr = *ArraySize) { > - if (SizeExpr->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (SizeExpr->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (SizeExpr->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > - } > + if (Expr *SizeExpr = *ArraySize) > + addDependence(SizeExpr->getDependence() & > ~ExprDependence::Type); > > getTrailingObjects<Stmt *>()[arraySizeOffset()] = *ArraySize; > } > > if (Initializer) { > - if (Initializer->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (Initializer->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (Initializer->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + addDependence(Initializer->getDependence() & > ~ExprDependence::Type); > > getTrailingObjects<Stmt *>()[initExprOffset()] = Initializer; > } > > for (unsigned I = 0; I != PlacementArgs.size(); ++I) { > - if (PlacementArgs[I]->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (PlacementArgs[I]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (PlacementArgs[I]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + addDependence(PlacementArgs[I]->getDependence() & > ~ExprDependence::Type); > > getTrailingObjects<Stmt *>()[placementNewArgsOffset() + I] = > PlacementArgs[I]; > @@ -474,11 +459,8 @@ OverloadExpr::OverloadExpr(StmtClass SC, const > ASTContext &Context, > // Determine whether this expression is type-dependent. > for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) > { > if ((*I)->getDeclContext()->isDependentContext() || > - isa<UnresolvedUsingValueDecl>(*I)) { > - ExprBits.TypeDependent = true; > - ExprBits.ValueDependent = true; > - ExprBits.InstantiationDependent = true; > - } > + isa<UnresolvedUsingValueDecl>(*I)) > + addDependence(ExprDependence::TypeValueInstantiation); > } > > // Copy the results to the trailing array past > UnresolvedLookupExpr > @@ -491,21 +473,11 @@ OverloadExpr::OverloadExpr(StmtClass SC, const > ASTContext &Context, > // template arguments and whether they contain any unexpanded pack > // expansions. > if (TemplateArgs) { > - bool Dependent = false; > - bool InstantiationDependent = false; > - bool ContainsUnexpandedParameterPack = false; > + auto Deps = TemplateArgumentDependence::None; > getTrailingASTTemplateKWAndArgsInfo()->initializeFrom( > - TemplateKWLoc, *TemplateArgs, > getTrailingTemplateArgumentLoc(), > - Dependent, InstantiationDependent, > ContainsUnexpandedParameterPack); > + TemplateKWLoc, *TemplateArgs, > getTrailingTemplateArgumentLoc(), Deps); > + addDependence(toExprDependence(Deps)); > > - if (Dependent) { > - ExprBits.TypeDependent = true; > - ExprBits.ValueDependent = true; > - } > - if (InstantiationDependent) > - ExprBits.InstantiationDependent = true; > - if (ContainsUnexpandedParameterPack) > - ExprBits.ContainsUnexpandedParameterPack = true; > } else if (TemplateKWLoc.isValid()) { > getTrailingASTTemplateKWAndArgsInfo()- > >initializeFrom(TemplateKWLoc); > } > @@ -539,14 +511,11 @@ > DependentScopeDeclRefExpr::DependentScopeDeclRefExpr( > DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo = > (Args != nullptr) || TemplateKWLoc.isValid(); > if (Args) { > - bool Dependent = true; > - bool InstantiationDependent = true; > - bool ContainsUnexpandedParameterPack > - = ExprBits.ContainsUnexpandedParameterPack; > + auto Deps = TemplateArgumentDependence::None; > getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( > - TemplateKWLoc, *Args, > getTrailingObjects<TemplateArgumentLoc>(), > - Dependent, InstantiationDependent, > ContainsUnexpandedParameterPack); > - ExprBits.ContainsUnexpandedParameterPack = > ContainsUnexpandedParameterPack; > + TemplateKWLoc, *Args, > getTrailingObjects<TemplateArgumentLoc>(), Deps); > + if (Deps & TemplateArgumentDependence::UnexpandedPack) > + addDependence(ExprDependence::UnexpandedPack); > } else if (TemplateKWLoc.isValid()) { > getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( > TemplateKWLoc); > @@ -1114,13 +1083,7 @@ CXXConstructExpr::CXXConstructExpr( > Stmt **TrailingArgs = getTrailingArgs(); > for (unsigned I = 0, N = Args.size(); I != N; ++I) { > assert(Args[I] && "NULL argument in CXXConstructExpr!"); > - > - if (Args[I]->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (Args[I]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (Args[I]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + addDependence(Args[I]->getDependence() & ~ExprDependence::Type); > > TrailingArgs[I] = Args[I]; > } > @@ -1370,7 +1333,7 @@ > CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo > *TSI, > auto **StoredArgs = getTrailingObjects<Expr *>(); > for (unsigned I = 0; I != Args.size(); ++I) { > if (Args[I]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > + addDependence(ExprDependence::UnexpandedPack); > > StoredArgs[I] = Args[I]; > } > @@ -1416,14 +1379,12 @@ > CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr( > CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc; > > if (TemplateArgs) { > - bool Dependent = true; > - bool InstantiationDependent = true; > - bool ContainsUnexpandedParameterPack = false; > + auto Deps = TemplateArgumentDependence::None; > getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( > TemplateKWLoc, *TemplateArgs, > getTrailingObjects<TemplateArgumentLoc>(), > - Dependent, InstantiationDependent, > ContainsUnexpandedParameterPack); > - if (ContainsUnexpandedParameterPack) > - ExprBits.ContainsUnexpandedParameterPack = true; > + Deps); > + if (Deps & TemplateArgumentDependence::UnexpandedPack) > + addDependence(ExprDependence::UnexpandedPack); > } else if (TemplateKWLoc.isValid()) { > getTrailingObjects<ASTTemplateKWAndArgsInfo>()->initializeFrom( > TemplateKWLoc); > @@ -1704,13 +1665,8 @@ TypeTraitExpr::TypeTraitExpr(QualType T, > SourceLocation Loc, TypeTrait Kind, > auto **ToArgs = getTrailingObjects<TypeSourceInfo *>(); > > for (unsigned I = 0, N = Args.size(); I != N; ++I) { > - if (Args[I]->getType()->isDependentType()) > - setValueDependent(true); > - if (Args[I]->getType()->isInstantiationDependentType()) > - setInstantiationDependent(true); > - if (Args[I]->getType()->containsUnexpandedParameterPack()) > - setContainsUnexpandedParameterPack(true); > - > + addDependence(toExprDependence(Args[I]->getType()- > >getDependence()) & > + ~ExprDependence::Type); > ToArgs[I] = Args[I]; > } > } > > diff --git a/clang/lib/AST/ExprConcepts.cpp > b/clang/lib/AST/ExprConcepts.cpp > index b5a3686dc99a..42cc4576562e 100644 > --- a/clang/lib/AST/ExprConcepts.cpp > +++ b/clang/lib/AST/ExprConcepts.cpp > @@ -11,11 +11,12 @@ > //===--------------------------------------------------------------- > -------===// > > #include "clang/AST/ExprConcepts.h" > -#include "clang/AST/ASTContext.h" > #include "clang/AST/ASTConcept.h" > +#include "clang/AST/ASTContext.h" > #include "clang/AST/Decl.h" > -#include "clang/AST/DeclarationName.h" > #include "clang/AST/DeclTemplate.h" > +#include "clang/AST/DeclarationName.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/Expr.h" > #include "clang/AST/NestedNameSpecifier.h" > #include "clang/AST/TemplateBase.h" > @@ -23,8 +24,8 @@ > #include "clang/Basic/SourceLocation.h" > #include "llvm/Support/TrailingObjects.h" > #include <algorithm> > -#include <utility> > #include <string> > +#include <utility> > > using namespace clang; > > @@ -46,14 +47,12 @@ > ConceptSpecializationExpr::ConceptSpecializationExpr(const ASTContext > &C, > ASTConstraintSatisfaction::Create(C, > *Satisfaction) : > nullptr) { > setTemplateArguments(ConvertedArgs); > - bool IsInstantiationDependent = false; > - bool ContainsUnexpandedParameterPack = false; > + auto Deps = TemplateArgumentDependence::None; > + const auto InterestingDeps = > TemplateArgumentDependence::Instantiation | > + TemplateArgumentDependence::Unexpande > dPack; > for (const TemplateArgumentLoc& ArgLoc : ArgsAsWritten- > >arguments()) { > - if (ArgLoc.getArgument().isInstantiationDependent()) > - IsInstantiationDependent = true; > - if (ArgLoc.getArgument().containsUnexpandedParameterPack()) > - ContainsUnexpandedParameterPack = true; > - if (ContainsUnexpandedParameterPack && IsInstantiationDependent) > + Deps |= ArgLoc.getArgument().getDependence() & InterestingDeps; > + if (Deps == InterestingDeps) > break; > } > > @@ -62,8 +61,7 @@ > ConceptSpecializationExpr::ConceptSpecializationExpr(const ASTContext > &C, > (!NestedNameSpec.getNestedNameSpecifier()- > >isInstantiationDependent() && > !NestedNameSpec.getNestedNameSpecifier() > ->containsUnexpandedParameterPack())); > - setInstantiationDependent(IsInstantiationDependent); > - setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack > ); > + addDependence(toExprDependence(Deps)); > assert((!isValueDependent() || isInstantiationDependent()) && > "should not be value-dependent"); > } > @@ -182,9 +180,14 @@ RequiresExpr::RequiresExpr(ASTContext &C, > SourceLocation RequiresKWLoc, > std::copy(Requirements.begin(), Requirements.end(), > getTrailingObjects<concepts::Requirement *>()); > RequiresExprBits.IsSatisfied |= Dependent; > - setValueDependent(Dependent); > - setInstantiationDependent(Dependent); > - setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack > ); > + if (ContainsUnexpandedParameterPack) > + addDependence(ExprDependence::UnexpandedPack); > + // FIXME: this is incorrect for cases where we have a non- > dependent > + // requirement, but its parameters are instantiation-dependent. > RequiresExpr > + // should be instantiation-dependent if it has instantiation- > dependent > + // parameters. > + if (Dependent) > + addDependence(ExprDependence::ValueInstantiation); > } > > RequiresExpr::RequiresExpr(ASTContext &C, EmptyShell Empty, > > diff --git a/clang/lib/AST/ExprObjC.cpp b/clang/lib/AST/ExprObjC.cpp > index 53d0e873f8c9..6d98429bc89d 100644 > --- a/clang/lib/AST/ExprObjC.cpp > +++ b/clang/lib/AST/ExprObjC.cpp > @@ -12,6 +12,7 @@ > > #include "clang/AST/ExprObjC.h" > #include "clang/AST/ASTContext.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/SelectorLocationsKind.h" > #include "clang/AST/Type.h" > #include "clang/AST/TypeLoc.h" > @@ -30,13 +31,7 @@ ObjCArrayLiteral::ObjCArrayLiteral(ArrayRef<Expr > *> Elements, QualType T, > NumElements(Elements.size()), Range(SR), > ArrayWithObjectsMethod(Method) { > Expr **SaveElements = getElements(); > for (unsigned I = 0, N = Elements.size(); I != N; ++I) { > - if (Elements[I]->isTypeDependent() || Elements[I]- > >isValueDependent()) > - ExprBits.ValueDependent = true; > - if (Elements[I]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (Elements[I]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > - > + addDependence(turnTypeToValueDependence(Elements[I]- > >getDependence())); > SaveElements[I] = Elements[I]; > } > } > @@ -67,16 +62,11 @@ > ObjCDictionaryLiteral::ObjCDictionaryLiteral(ArrayRef<ObjCDictionaryE > lement> VK, > ExpansionData *Expansions = > HasPackExpansions ? getTrailingObjects<ExpansionData>() : > nullptr; > for (unsigned I = 0; I < NumElements; I++) { > - if (VK[I].Key->isTypeDependent() || VK[I].Key- > >isValueDependent() || > - VK[I].Value->isTypeDependent() || VK[I].Value- > >isValueDependent()) > - ExprBits.ValueDependent = true; > - if (VK[I].Key->isInstantiationDependent() || > - VK[I].Value->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (VK[I].EllipsisLoc.isInvalid() && > - (VK[I].Key->containsUnexpandedParameterPack() || > - VK[I].Value->containsUnexpandedParameterPack())) > - ExprBits.ContainsUnexpandedParameterPack = true; > + auto Deps = turnTypeToValueDependence(VK[I].Key->getDependence() > | > + VK[I].Value- > >getDependence()); > + if (VK[I].EllipsisLoc.isValid()) > + Deps &= ~ExprDependence::UnexpandedPack; > + addDependence(Deps); > > KeyValues[I].Key = VK[I].Key; > KeyValues[I].Value = VK[I].Value; > @@ -183,15 +173,7 @@ void > ObjCMessageExpr::initArgsAndSelLocs(ArrayRef<Expr *> Args, > setNumArgs(Args.size()); > Expr **MyArgs = getArgs(); > for (unsigned I = 0; I != Args.size(); ++I) { > - if (Args[I]->isTypeDependent()) > - ExprBits.TypeDependent = true; > - if (Args[I]->isValueDependent()) > - ExprBits.ValueDependent = true; > - if (Args[I]->isInstantiationDependent()) > - ExprBits.InstantiationDependent = true; > - if (Args[I]->containsUnexpandedParameterPack()) > - ExprBits.ContainsUnexpandedParameterPack = true; > - > + addDependence(Args[I]->getDependence()); > MyArgs[I] = Args[I]; > } > > > diff --git a/clang/lib/AST/NestedNameSpecifier.cpp > b/clang/lib/AST/NestedNameSpecifier.cpp > index 06008b2f32ac..8cd65a857beb 100644 > --- a/clang/lib/AST/NestedNameSpecifier.cpp > +++ b/clang/lib/AST/NestedNameSpecifier.cpp > @@ -16,6 +16,7 @@ > #include "clang/AST/Decl.h" > #include "clang/AST/DeclCXX.h" > #include "clang/AST/DeclTemplate.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/PrettyPrinter.h" > #include "clang/AST/TemplateName.h" > #include "clang/AST/Type.h" > @@ -197,75 +198,49 @@ CXXRecordDecl > *NestedNameSpecifier::getAsRecordDecl() const { > llvm_unreachable("Invalid NNS Kind!"); > } > > -/// Whether this nested name specifier refers to a dependent > -/// type or not. > -bool NestedNameSpecifier::isDependent() const { > +NestedNameSpecifierDependence NestedNameSpecifier::getDependence() > const { > switch (getKind()) { > - case Identifier: > + case Identifier: { > // Identifier specifiers always represent dependent types > - return true; > + auto F = NestedNameSpecifierDependence::Dependent | > + NestedNameSpecifierDependence::Instantiation; > + // Prefix can contain unexpanded template parameters. > + if (getPrefix()) > + return F | getPrefix()->getDependence(); > + return F; > + } > > case Namespace: > case NamespaceAlias: > case Global: > - return false; > + return NestedNameSpecifierDependence::None; > > case Super: { > CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier); > for (const auto &Base : RD->bases()) > if (Base.getType()->isDependentType()) > - return true; > - > - return false; > + // FIXME: must also be instantiation-dependent. > + return NestedNameSpecifierDependence::Dependent; > + return NestedNameSpecifierDependence::None; > } > > case TypeSpec: > case TypeSpecWithTemplate: > - return getAsType()->isDependentType(); > + return toNestedNameSpecifierDependendence(getAsType()- > >getDependence()); > } > - > llvm_unreachable("Invalid NNS Kind!"); > } > > -/// Whether this nested name specifier refers to a dependent > -/// type or not. > -bool NestedNameSpecifier::isInstantiationDependent() const { > - switch (getKind()) { > - case Identifier: > - // Identifier specifiers always represent dependent types > - return true; > - > - case Namespace: > - case NamespaceAlias: > - case Global: > - case Super: > - return false; > - > - case TypeSpec: > - case TypeSpecWithTemplate: > - return getAsType()->isInstantiationDependentType(); > - } > +bool NestedNameSpecifier::isDependent() const { > + return getDependence() & NestedNameSpecifierDependence::Dependent; > +} > > - llvm_unreachable("Invalid NNS Kind!"); > +bool NestedNameSpecifier::isInstantiationDependent() const { > + return getDependence() & > NestedNameSpecifierDependence::Instantiation; > } > > bool NestedNameSpecifier::containsUnexpandedParameterPack() const { > - switch (getKind()) { > - case Identifier: > - return getPrefix() && getPrefix()- > >containsUnexpandedParameterPack(); > - > - case Namespace: > - case NamespaceAlias: > - case Global: > - case Super: > - return false; > - > - case TypeSpec: > - case TypeSpecWithTemplate: > - return getAsType()->containsUnexpandedParameterPack(); > - } > - > - llvm_unreachable("Invalid NNS Kind!"); > + return getDependence() & > NestedNameSpecifierDependence::UnexpandedPack; > } > > /// Print this nested name specifier to the given output > > diff --git a/clang/lib/AST/TemplateBase.cpp > b/clang/lib/AST/TemplateBase.cpp > index 6f0ebf232e77..3c550bddaff8 100644 > --- a/clang/lib/AST/TemplateBase.cpp > +++ b/clang/lib/AST/TemplateBase.cpp > @@ -16,6 +16,7 @@ > #include "clang/AST/Decl.h" > #include "clang/AST/DeclBase.h" > #include "clang/AST/DeclTemplate.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/Expr.h" > #include "clang/AST/ExprCXX.h" > #include "clang/AST/PrettyPrinter.h" > @@ -111,84 +112,60 @@ TemplateArgument::CreatePackCopy(ASTContext > &Context, > return TemplateArgument(Args.copy(Context)); > } > > -bool TemplateArgument::isDependent() const { > +TemplateArgumentDependence TemplateArgument::getDependence() const { > + auto Deps = TemplateArgumentDependence::None; > switch (getKind()) { > case Null: > llvm_unreachable("Should not have a NULL template argument"); > > case Type: > - return getAsType()->isDependentType() || > - isa<PackExpansionType>(getAsType()); > + Deps = toTemplateArgumentDependence(getAsType()- > >getDependence()); > + if (isa<PackExpansionType>(getAsType())) > + Deps |= TemplateArgumentDependence::Dependent; > + return Deps; > > case Template: > - return getAsTemplate().isDependent(); > + return > toTemplateArgumentDependence(getAsTemplate().getDependence()); > > case TemplateExpansion: > - return true; > + return TemplateArgumentDependence::Dependent | > + TemplateArgumentDependence::Instantiation; > > - case Declaration: > - if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) > - return DC->isDependentContext(); > - return getAsDecl()->getDeclContext()->isDependentContext(); > + case Declaration: { > + auto *DC = dyn_cast<DeclContext>(getAsDecl()); > + if (!DC) > + DC = getAsDecl()->getDeclContext(); > + if (DC->isDependentContext()) > + Deps = TemplateArgumentDependence::Dependent | > + TemplateArgumentDependence::Instantiation; > + return Deps; > + } > > case NullPtr: > - return false; > - > case Integral: > - // Never dependent > - return false; > + return TemplateArgumentDependence::None; > > case Expression: > - return (getAsExpr()->isTypeDependent() || getAsExpr()- > >isValueDependent() || > - isa<PackExpansionExpr>(getAsExpr())); > + Deps = toTemplateArgumentDependence(getAsExpr()- > >getDependence()); > + if (isa<PackExpansionExpr>(getAsExpr())) > + Deps |= TemplateArgumentDependence::Dependent | > + TemplateArgumentDependence::Instantiation; > + return Deps; > > case Pack: > for (const auto &P : pack_elements()) > - if (P.isDependent()) > - return true; > - return false; > + Deps |= P.getDependence(); > + return Deps; > } > + llvm_unreachable("unhandled ArgKind"); > +} > > - llvm_unreachable("Invalid TemplateArgument Kind!"); > +bool TemplateArgument::isDependent() const { > + return getDependence() & TemplateArgumentDependence::Dependent; > } > > bool TemplateArgument::isInstantiationDependent() const { > - switch (getKind()) { > - case Null: > - llvm_unreachable("Should not have a NULL template argument"); > - > - case Type: > - return getAsType()->isInstantiationDependentType(); > - > - case Template: > - return getAsTemplate().isInstantiationDependent(); > - > - case TemplateExpansion: > - return true; > - > - case Declaration: > - if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) > - return DC->isDependentContext(); > - return getAsDecl()->getDeclContext()->isDependentContext(); > - > - case NullPtr: > - return false; > - > - case Integral: > - // Never dependent > - return false; > - > - case Expression: > - return getAsExpr()->isInstantiationDependent(); > - > - case Pack: > - for (const auto &P : pack_elements()) > - if (P.isInstantiationDependent()) > - return true; > - return false; > - } > - > - llvm_unreachable("Invalid TemplateArgument Kind!"); > + return getDependence() & > TemplateArgumentDependence::Instantiation; > } > > bool TemplateArgument::isPackExpansion() const { > @@ -215,38 +192,7 @@ bool TemplateArgument::isPackExpansion() const { > } > > bool TemplateArgument::containsUnexpandedParameterPack() const { > - switch (getKind()) { > - case Null: > - case Declaration: > - case Integral: > - case TemplateExpansion: > - case NullPtr: > - break; > - > - case Type: > - if (getAsType()->containsUnexpandedParameterPack()) > - return true; > - break; > - > - case Template: > - if (getAsTemplate().containsUnexpandedParameterPack()) > - return true; > - break; > - > - case Expression: > - if (getAsExpr()->containsUnexpandedParameterPack()) > - return true; > - break; > - > - case Pack: > - for (const auto &P : pack_elements()) > - if (P.containsUnexpandedParameterPack()) > - return true; > - > - break; > - } > - > - return false; > + return getDependence() & > TemplateArgumentDependence::UnexpandedPack; > } > > Optional<unsigned> TemplateArgument::getNumTemplateExpansions() > const { > @@ -601,20 +547,14 @@ void > ASTTemplateKWAndArgsInfo::initializeFrom(SourceLocation > TemplateKWLoc) { > > void ASTTemplateKWAndArgsInfo::initializeFrom( > SourceLocation TemplateKWLoc, const TemplateArgumentListInfo > &Info, > - TemplateArgumentLoc *OutArgArray, bool &Dependent, > - bool &InstantiationDependent, bool > &ContainsUnexpandedParameterPack) { > + TemplateArgumentLoc *OutArgArray, TemplateArgumentDependence > &Deps) { > this->TemplateKWLoc = TemplateKWLoc; > LAngleLoc = Info.getLAngleLoc(); > RAngleLoc = Info.getRAngleLoc(); > NumTemplateArgs = Info.size(); > > for (unsigned i = 0; i != NumTemplateArgs; ++i) { > - Dependent = Dependent || Info[i].getArgument().isDependent(); > - InstantiationDependent = InstantiationDependent || > - Info[i].getArgument().isInstantiationDe > pendent(); > - ContainsUnexpandedParameterPack = > - ContainsUnexpandedParameterPack || > - Info[i].getArgument().containsUnexpandedParameterPack(); > + Deps |= Info[i].getArgument().getDependence(); > > new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); > } > > diff --git a/clang/lib/AST/TemplateName.cpp > b/clang/lib/AST/TemplateName.cpp > index 06e1dcec7449..afabc575b164 100644 > --- a/clang/lib/AST/TemplateName.cpp > +++ b/clang/lib/AST/TemplateName.cpp > @@ -11,8 +11,10 @@ > //===--------------------------------------------------------------- > -------===// > > #include "clang/AST/TemplateName.h" > +#include "clang/AST/Decl.h" > #include "clang/AST/DeclBase.h" > #include "clang/AST/DeclTemplate.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/NestedNameSpecifier.h" > #include "clang/AST/PrettyPrinter.h" > #include "clang/AST/TemplateBase.h" > @@ -168,52 +170,54 @@ TemplateName > TemplateName::getNameToSubstitute() const { > return TemplateName(Decl); > } > > -bool TemplateName::isDependent() const { > +TemplateNameDependence TemplateName::getDependence() const { > + auto D = TemplateNameDependence::None; > + switch (getKind()) { > + case TemplateName::NameKind::QualifiedTemplate: > + D |= toTemplateNameDependence( > + getAsQualifiedTemplateName()->getQualifier()- > >getDependence()); > + break; > + case TemplateName::NameKind::DependentTemplate: > + D |= toTemplateNameDependence( > + getAsDependentTemplateName()->getQualifier()- > >getDependence()); > + break; > + case TemplateName::NameKind::SubstTemplateTemplateParmPack: > + D |= TemplateNameDependence::UnexpandedPack; > + break; > + case TemplateName::NameKind::OverloadedTemplate: > + assert(false && "overloaded templates shouldn't survive to > here."); > + default: > + break; > + } > if (TemplateDecl *Template = getAsTemplateDecl()) { > - if (isa<TemplateTemplateParmDecl>(Template)) > - return true; > + if (auto *TTP = dyn_cast<TemplateTemplateParmDecl>(Template)) { > + D |= TemplateNameDependence::DependentInstantiation; > + if (TTP->isParameterPack()) > + D |= TemplateNameDependence::UnexpandedPack; > + } > // FIXME: Hack, getDeclContext() can be null if Template is > still > // initializing due to PCH reading, so we check it before using > it. > // Should probably modify TemplateSpecializationType to allow > constructing > // it without the isDependent() checking. > - return Template->getDeclContext() && > - Template->getDeclContext()->isDependentContext(); > + if (Template->getDeclContext() && > + Template->getDeclContext()->isDependentContext()) > + D |= TemplateNameDependence::DependentInstantiation; > + } else { > + D |= TemplateNameDependence::DependentInstantiation; > } > + return D; > +} > > - assert(!getAsOverloadedTemplate() && > - "overloaded templates shouldn't survive to here"); > - > - return true; > +bool TemplateName::isDependent() const { > + return getDependence() & TemplateNameDependence::Dependent; > } > > bool TemplateName::isInstantiationDependent() const { > - if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { > - if (QTN->getQualifier()->isInstantiationDependent()) > - return true; > - } > - > - return isDependent(); > + return getDependence() & TemplateNameDependence::Instantiation; > } > > bool TemplateName::containsUnexpandedParameterPack() const { > - if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { > - if (QTN->getQualifier()->containsUnexpandedParameterPack()) > - return true; > - } > - > - if (TemplateDecl *Template = getAsTemplateDecl()) { > - if (TemplateTemplateParmDecl *TTP > - = > dyn_cast<TemplateTemplateParmDecl>(Template)) > - return TTP->isParameterPack(); > - > - return false; > - } > - > - if (DependentTemplateName *DTN = getAsDependentTemplateName()) > - return DTN->getQualifier() && > - DTN->getQualifier()->containsUnexpandedParameterPack(); > - > - return getAsSubstTemplateTemplateParmPack() != nullptr; > + return getDependence() & TemplateNameDependence::UnexpandedPack; > } > > void > > diff --git a/clang/lib/Sema/SemaOverload.cpp > b/clang/lib/Sema/SemaOverload.cpp > index b4be10deda32..9ecf5867e966 100644 > --- a/clang/lib/Sema/SemaOverload.cpp > +++ b/clang/lib/Sema/SemaOverload.cpp > @@ -10,10 +10,10 @@ > // > //===--------------------------------------------------------------- > -------===// > > -#include "clang/Sema/Overload.h" > #include "clang/AST/ASTContext.h" > #include "clang/AST/CXXInheritance.h" > #include "clang/AST/DeclObjC.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/Expr.h" > #include "clang/AST/ExprCXX.h" > #include "clang/AST/ExprObjC.h" > @@ -25,6 +25,7 @@ > #include "clang/Basic/TargetInfo.h" > #include "clang/Sema/Initialization.h" > #include "clang/Sema/Lookup.h" > +#include "clang/Sema/Overload.h" > #include "clang/Sema/SemaInternal.h" > #include "clang/Sema/Template.h" > #include "clang/Sema/TemplateDeduction.h" > @@ -12719,9 +12720,7 @@ bool Sema::buildOverloadedCallSet(Scope *S, > Expr *Fn, > // base classes. > CallExpr *CE = CallExpr::Create(Context, Fn, Args, > Context.DependentTy, > VK_RValue, RParenLoc); > - CE->setTypeDependent(true); > - CE->setValueDependent(true); > - CE->setInstantiationDependent(true); > + CE->addDependence(ExprDependence::TypeValueInstantiation); > *Result = CE; > return true; > } > > diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp > b/clang/lib/Serialization/ASTReaderStmt.cpp > index fc83dc42d4d1..42803b1a3918 100644 > --- a/clang/lib/Serialization/ASTReaderStmt.cpp > +++ b/clang/lib/Serialization/ASTReaderStmt.cpp > @@ -11,7 +11,6 @@ > // > //===--------------------------------------------------------------- > -------===// > > -#include "clang/Serialization/ASTRecordReader.h" > #include "clang/AST/ASTConcept.h" > #include "clang/AST/ASTContext.h" > #include "clang/AST/AttrIterator.h" > @@ -22,6 +21,7 @@ > #include "clang/AST/DeclObjC.h" > #include "clang/AST/DeclTemplate.h" > #include "clang/AST/DeclarationName.h" > +#include "clang/AST/DependencyFlags.h" > #include "clang/AST/Expr.h" > #include "clang/AST/ExprCXX.h" > #include "clang/AST/ExprObjC.h" > @@ -49,6 +49,7 @@ > #include "clang/Basic/TypeTraits.h" > #include "clang/Lex/Token.h" > #include "clang/Serialization/ASTBitCodes.h" > +#include "clang/Serialization/ASTRecordReader.h" > #include "llvm/ADT/DenseMap.h" > #include "llvm/ADT/SmallString.h" > #include "llvm/ADT/SmallVector.h" > @@ -511,10 +512,23 @@ void > ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) { > void ASTStmtReader::VisitExpr(Expr *E) { > VisitStmt(E); > E->setType(Record.readType()); > - E->setTypeDependent(Record.readInt()); > - E->setValueDependent(Record.readInt()); > - E->setInstantiationDependent(Record.readInt()); > - E->ExprBits.ContainsUnexpandedParameterPack = Record.readInt(); > + > + // FIXME: write and read all DependentFlags with a single call. > + bool TypeDependent = Record.readInt(); > + bool ValueDependent = Record.readInt(); > + bool InstantiationDependent = Record.readInt(); > + bool ContainsUnexpandedTemplateParameters = Record.readInt(); > + auto Deps = ExprDependence::None; > + if (TypeDependent) > + Deps |= ExprDependence::Type; > + if (ValueDependent) > + Deps |= ExprDependence::Value; > + if (InstantiationDependent) > + Deps |= ExprDependence::Instantiation; > + if (ContainsUnexpandedTemplateParameters) > + Deps |= ExprDependence::UnexpandedPack; > + E->setDependence(Deps); > + > E->setValueKind(static_cast<ExprValueKind>(Record.readInt())); > E->setObjectKind(static_cast<ExprObjectKind>(Record.readInt())); > assert(Record.getIdx() == NumExprFields && > > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits