diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp --- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp +++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp @@ -10,12 +10,12 @@ #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" -using namespace clang::ast_matchers; - namespace clang { namespace tidy { namespace hicpp { +using namespace clang::ast_matchers; + void ExceptionBaseclassCheck::registerMatchers(MatchFinder *Finder) { if (!getLangOpts().CPlusPlus) return; diff --git a/clang/include/clang/AST/DependencyFlags.h b/clang/include/clang/AST/DependencyFlags.h new file mode 100644 --- /dev/null +++ b/clang/include/clang/AST/DependencyFlags.h @@ -0,0 +1,112 @@ +//===--- 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 + +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; + +#define LLVM_COMMON_DEPENDENCE(NAME) \ + struct NAME##Scope { \ + enum NAME { \ + 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(TypeDependence) +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(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. + return toExprDependence(static_cast(TD)); +} +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(D); +} + +inline TemplateArgumentDependence +toTemplateArgumentDependence(TypeDependence D) { + // This works because both classes share the same bit representation. + return static_cast(D); +} +inline TemplateArgumentDependence +toTemplateArgumentDependence(TemplateNameDependence D) { + // This works because both classes share the same bit representation. + return static_cast(D); +} +inline TemplateArgumentDependence +toTemplateArgumentDependence(ExprDependence ED) { + TemplateArgumentDependence TAD = static_cast( + ED & ~(ExprDependence::Type | ExprDependence::Value)); + if (ED & (ExprDependence::Type | ExprDependence::Value)) + TAD |= TemplateArgumentDependence::Dependent; + return TAD; +} + +inline TemplateNameDependence +toTemplateNameDependence(NestedNameSpecifierDependence D) { + return static_cast(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 --- 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 @@ 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(D); ExprBits.ValueKind = VK; ExprBits.ObjectKind = OK; assert(ExprBits.ObjectKind == OK && "truncated kind"); - ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; setType(T); } @@ -148,6 +156,20 @@ TR = t; } + ExprDependence getDependence() const { + return static_cast(ExprBits.Dependent); + } + + void setDependencies(ExprDependence Deps) { + ExprBits.Dependent = static_cast(Deps); + } + void addDependencies(ExprDependence Deps) { + ExprBits.Dependent |= static_cast(Deps); + } + void removeDependencies(ExprDependence Deps) { + ExprBits.Dependent &= ~static_cast(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 @@ /// @code /// template 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(getDependence() & ExprDependence::Value); } /// isTypeDependent - Determines whether this expression is @@ -173,11 +192,8 @@ /// 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(getDependence() & ExprDependence::Type); } /// Whether this expression is instantiation-dependent, meaning that @@ -198,12 +214,7 @@ /// \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(getDependence() & ExprDependence::Instantiation); } /// Whether this expression contains an unexpanded parameter @@ -221,13 +232,7 @@ /// The expressions \c args and \c static_cast(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(getDependence() & ExprDependence::UnexpandedPack); } /// getExprLoc - Return the preferred location for the arrow when diagnosing @@ -1210,10 +1215,6 @@ /// 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, @@ -2553,8 +2554,6 @@ /// 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 @@ -4462,13 +4461,8 @@ 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) + addDependencies(expr->getDependence()); } /// Reserve space for some number of initializers. diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h --- 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 @@ 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 --- 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 @@ 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 --- 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 @@ /// 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 @@ 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 --- 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 @@ /// 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 --- 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 #include #include @@ -1464,20 +1465,12 @@ /// 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; + /// Store information on the type dependency. + /*TypeDependence*/ unsigned Dependence : TypeDependenceBits; /// 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; - /// True if the cache (i.e. the bitfields here starting with /// 'Cache') is valid. mutable unsigned CacheValid : 1; @@ -1823,11 +1816,17 @@ 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; + TypeBits.TC = tc; - TypeBits.Dependent = Dependent; - TypeBits.InstantiationDependent = Dependent || InstantiationDependent; + TypeBits.Dependence = static_cast(Deps); TypeBits.VariablyModified = VariablyModified; - TypeBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; TypeBits.CacheValid = false; TypeBits.CachedLocalOrUnnamed = false; TypeBits.CachedLinkage = NoLinkage; @@ -1838,18 +1837,32 @@ Type *this_() { return this; } void setDependent(bool D = true) { - TypeBits.Dependent = D; - if (D) - TypeBits.InstantiationDependent = true; + if (!D) { + TypeBits.Dependence &= ~static_cast(TypeDependence::Dependent); + return; + } + TypeBits.Dependence |= static_cast(TypeDependence::Dependent | + TypeDependence::Instantiation); } void setInstantiationDependent(bool D = true) { - TypeBits.InstantiationDependent = D; } + if (D) + TypeBits.Dependence |= + static_cast(TypeDependence::Instantiation); + else + TypeBits.Dependence &= + ~static_cast(TypeDependence::Instantiation); + } void setVariablyModified(bool VM = true) { TypeBits.VariablyModified = VM; } void setContainsUnexpandedParameterPack(bool PP = true) { - TypeBits.ContainsUnexpandedParameterPack = PP; + if (PP) + TypeBits.Dependence |= + static_cast(TypeDependence::UnexpandedPack); + else + TypeBits.Dependence &= + ~static_cast(TypeDependence::UnexpandedPack); } public: @@ -1884,7 +1897,7 @@ /// /// 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 @@ -2135,16 +2148,22 @@ /// Given that this is a scalar type, classify it. ScalarTypeKind getScalarTypeKind() const; + TypeDependence getDependence() const { + return static_cast(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 diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -8331,11 +8331,7 @@ // 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->setDependencies(FromE->getDependence()); } // Record the imported statement object. diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp --- 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" @@ -368,13 +369,11 @@ /// 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: @@ -386,36 +385,25 @@ // (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(D)) { - ValueDependent = true; - InstantiationDependent = true; - return; - } + if (isa(D)) + return R | ExprDependence::ValueInstantiation; // (VD) - a constant with integral or enumeration type and is // initialized with an expression that is value-dependent. @@ -432,8 +420,7 @@ Var->getType()->isReferenceType())) { if (const Expr *Init = Var->getAnyInitializer()) if (Init->isValueDependent()) { - ValueDependent = true; - InstantiationDependent = true; + R |= ExprDependence::ValueInstantiation; } } @@ -442,39 +429,21 @@ // 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(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(D) && D->getDeclContext()->isDependentContext()) + R |= ExprDependence::ValueInstantiation; + return R; } DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, @@ -492,7 +461,7 @@ RefersToEnclosingVariableOrCapture; DeclRefExprBits.NonOdrUseReason = NOUR; DeclRefExprBits.Loc = L; - computeDependence(Ctx); + addDependencies(computeDeclRefDependence(Ctx, getDecl(), getType())); } DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, @@ -511,9 +480,9 @@ NestedNameSpecifierLoc(QualifierLoc); auto *NNS = QualifierLoc.getNestedNameSpecifier(); if (NNS->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; + addDependencies(ExprDependence::Instantiation); if (NNS->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; + addDependencies(ExprDependence::UnexpandedPack); } DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0; if (FoundD) @@ -524,22 +493,19 @@ RefersToEnclosingVariableOrCapture; DeclRefExprBits.NonOdrUseReason = NOUR; if (TemplateArgs) { - bool Dependent = false; - bool InstantiationDependent = false; - bool ContainsUnexpandedParameterPack = false; + auto Deps = TemplateArgumentDependence::None; getTrailingObjects()->initializeFrom( TemplateKWLoc, *TemplateArgs, getTrailingObjects(), - 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"); + addDependencies(toExprDependence(Deps)); } else if (TemplateKWLoc.isValid()) { getTrailingObjects()->initializeFrom( TemplateKWLoc); } DeclRefExprBits.HadMultipleCandidates = 0; - - computeDependence(Ctx); + addDependencies(computeDeclRefDependence(Ctx, getDecl(), getType())); } DeclRefExpr *DeclRefExpr::Create(const ASTContext &Context, @@ -1357,11 +1323,11 @@ setCallee(Fn); for (unsigned I = 0; I != NumPreArgs; ++I) { - updateDependenciesFromArg(PreArgs[I]); + addDependencies(PreArgs[I]->getDependence()); setPreArg(I, PreArgs[I]); } for (unsigned I = 0; I != Args.size(); ++I) { - updateDependenciesFromArg(Args[I]); + addDependencies(Args[I]->getDependence()); setArg(I, Args[I]); } for (unsigned I = Args.size(); I != NumArgs; ++I) { @@ -1429,17 +1395,6 @@ } } -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(); @@ -1585,9 +1540,9 @@ for (unsigned i = 0; i != exprs.size(); ++i) { if (exprs[i]->isTypeDependent() || exprs[i]->isValueDependent()) - ExprBits.ValueDependent = true; + addDependencies(ExprDependence::Value); if (exprs[i]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; + addDependencies(ExprDependence ::UnexpandedPack); setIndexExpr(i, exprs[i]); } @@ -1629,8 +1584,7 @@ if (D) { for (const auto *I : D->specific_attrs()) { if (I->isAlignmentDependent()) { - setValueDependent(true); - setInstantiationDependent(true); + addDependencies(ExprDependence::ValueInstantiation); break; } } @@ -1683,20 +1637,19 @@ // dyn_cast_or_null is used to handle objC variables which do not // have a declaration context. CXXRecordDecl *RD = dyn_cast_or_null(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->removeDependencies(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->addDependencies(ExprDependence::TypeValueInstantiation); else if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) - E->setInstantiationDependent(true); + E->addDependencies(ExprDependence::Instantiation); E->MemberExprBits.HasQualifierOrFoundDecl = true; @@ -1710,15 +1663,12 @@ TemplateArgs || TemplateKWLoc.isValid(); if (TemplateArgs) { - bool Dependent = false; - bool InstantiationDependent = false; - bool ContainsUnexpandedParameterPack = false; + auto Deps = TemplateArgumentDependence::None; E->getTrailingObjects()->initializeFrom( TemplateKWLoc, *TemplateArgs, - E->getTrailingObjects(), Dependent, - InstantiationDependent, ContainsUnexpandedParameterPack); - if (InstantiationDependent) - E->setInstantiationDependent(true); + E->getTrailingObjects(), Deps); + if (Deps & TemplateArgumentDependence::Instantiation) + E->addDependencies(ExprDependence::Instantiation); } else if (TemplateKWLoc.isValid()) { E->getTrailingObjects()->initializeFrom( TemplateKWLoc); @@ -2236,16 +2186,8 @@ 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) + addDependencies(initExprs[I]->getDependence()); InitExprs.insert(C, InitExprs.end(), initExprs.begin(), initExprs.end()); } @@ -4159,15 +4101,7 @@ { 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; - + addDependencies(args[i]->getDependence()); SubExprs[i] = args[i]; } } @@ -4311,13 +4245,12 @@ 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; + addDependencies(Deps); // Copy the index expressions into permanent storage. *Child++ = IndexExprs[IndexIdx++]; @@ -4325,19 +4258,11 @@ // 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; + addDependencies(Deps); // Copy the start/end expressions into permanent storage. *Child++ = IndexExprs[IndexIdx++]; @@ -4475,15 +4400,7 @@ 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; - + addDependencies(Exprs[I]->getDependence()); getTrailingObjects()[I] = Exprs[I]; } } @@ -4570,14 +4487,7 @@ 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; + addDependencies(E->getDependence()); if (isa(E)) assert(cast(E)->getSourceExpr() != nullptr && @@ -4618,15 +4528,7 @@ { 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; - + addDependencies(args[i]->getDependence()); SubExprs[i] = args[i]; } } diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -18,6 +18,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.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" @@ -193,36 +194,20 @@ 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) + addDependencies(SizeExpr->getDependence() & ~ExprDependence::Type); getTrailingObjects()[arraySizeOffset()] = *ArraySize; } if (Initializer) { - if (Initializer->isValueDependent()) - ExprBits.ValueDependent = true; - if (Initializer->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; - if (Initializer->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; + addDependencies(Initializer->getDependence() & ~ExprDependence::Type); getTrailingObjects()[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; + addDependencies(PlacementArgs[I]->getDependence() & ~ExprDependence::Type); getTrailingObjects()[placementNewArgsOffset() + I] = PlacementArgs[I]; @@ -473,11 +458,8 @@ // Determine whether this expression is type-dependent. for (UnresolvedSetImpl::const_iterator I = Begin; I != End; ++I) { if ((*I)->getDeclContext()->isDependentContext() || - isa(*I)) { - ExprBits.TypeDependent = true; - ExprBits.ValueDependent = true; - ExprBits.InstantiationDependent = true; - } + isa(*I)) + addDependencies(ExprDependence::TypeValueInstantiation); } // Copy the results to the trailing array past UnresolvedLookupExpr @@ -490,21 +472,11 @@ // 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); + addDependencies(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); } @@ -538,14 +510,11 @@ DependentScopeDeclRefExprBits.HasTemplateKWAndArgsInfo = (Args != nullptr) || TemplateKWLoc.isValid(); if (Args) { - bool Dependent = true; - bool InstantiationDependent = true; - bool ContainsUnexpandedParameterPack - = ExprBits.ContainsUnexpandedParameterPack; + auto Deps = TemplateArgumentDependence::None; getTrailingObjects()->initializeFrom( - TemplateKWLoc, *Args, getTrailingObjects(), - Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); - ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + TemplateKWLoc, *Args, getTrailingObjects(), Deps); + if (Deps & TemplateArgumentDependence::UnexpandedPack) + addDependencies(ExprDependence::UnexpandedPack); } else if (TemplateKWLoc.isValid()) { getTrailingObjects()->initializeFrom( TemplateKWLoc); @@ -1113,13 +1082,7 @@ 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; + addDependencies(Args[I]->getDependence() & ~ExprDependence::Type); TrailingArgs[I] = Args[I]; } @@ -1369,7 +1332,7 @@ auto **StoredArgs = getTrailingObjects(); for (unsigned I = 0; I != Args.size(); ++I) { if (Args[I]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; + addDependencies(ExprDependence::UnexpandedPack); StoredArgs[I] = Args[I]; } @@ -1415,14 +1378,12 @@ CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc; if (TemplateArgs) { - bool Dependent = true; - bool InstantiationDependent = true; - bool ContainsUnexpandedParameterPack = false; + auto Deps = TemplateArgumentDependence::None; getTrailingObjects()->initializeFrom( TemplateKWLoc, *TemplateArgs, getTrailingObjects(), - Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); - if (ContainsUnexpandedParameterPack) - ExprBits.ContainsUnexpandedParameterPack = true; + Deps); + if (Deps & TemplateArgumentDependence::UnexpandedPack) + addDependencies(ExprDependence::UnexpandedPack); } else if (TemplateKWLoc.isValid()) { getTrailingObjects()->initializeFrom( TemplateKWLoc); @@ -1703,13 +1664,8 @@ auto **ToArgs = getTrailingObjects(); 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); - + addDependencies(toExprDependence(Args[I]->getType()->getDependence()) & + ~ExprDependence::Type); ToArgs[I] = Args[I]; } } @@ -1798,24 +1754,22 @@ this->ArgsAsWritten = ArgsAsWritten; std::uninitialized_copy(Converted.begin(), Converted.end(), getTrailingObjects()); - bool IsInstantiationDependent = false; - bool ContainsUnexpandedParameterPack = false; - for (const TemplateArgumentLoc& LocInfo : ArgsAsWritten->arguments()) { - if (LocInfo.getArgument().isInstantiationDependent()) - IsInstantiationDependent = true; - if (LocInfo.getArgument().containsUnexpandedParameterPack()) - ContainsUnexpandedParameterPack = true; - if (ContainsUnexpandedParameterPack && IsInstantiationDependent) + auto Deps = TemplateArgumentDependence::None; + const auto InterestingDeps = TemplateArgumentDependence::Instantiation | + TemplateArgumentDependence::UnexpandedPack; + for (const TemplateArgumentLoc &LocInfo : ArgsAsWritten->arguments()) { + Deps |= LocInfo.getArgument().getDependence() & InterestingDeps; + if (Deps == InterestingDeps) break; } // Currently guaranteed by the fact concepts can only be at namespace-scope. - assert(!NestedNameSpec || - (!NestedNameSpec.getNestedNameSpecifier()->isInstantiationDependent() && - !NestedNameSpec.getNestedNameSpecifier() - ->containsUnexpandedParameterPack())); - setInstantiationDependent(IsInstantiationDependent); - setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack); + assert( + !NestedNameSpec || + (!NestedNameSpec.getNestedNameSpecifier()->isInstantiationDependent() && + !NestedNameSpec.getNestedNameSpecifier() + ->containsUnexpandedParameterPack())); + addDependencies(toExprDependence(Deps & InterestingDeps)); assert((!isValueDependent() || isInstantiationDependent()) && "should not be value-dependent"); } diff --git a/clang/lib/AST/ExprObjC.cpp b/clang/lib/AST/ExprObjC.cpp --- 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 @@ 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; - + addDependencies(turnTypeToValueDependence(Elements[I]->getDependence())); SaveElements[I] = Elements[I]; } } @@ -67,16 +62,11 @@ ExpansionData *Expansions = HasPackExpansions ? getTrailingObjects() : 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; + addDependencies(Deps); KeyValues[I].Key = VK[I].Key; KeyValues[I].Value = VK[I].Value; @@ -183,15 +173,7 @@ 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; - + addDependencies(Args[I]->getDependence()); MyArgs[I] = Args[I]; } diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp --- 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 @@ 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(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 --- 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 @@ 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(getAsType()); + Deps = toTemplateArgumentDependence(getAsType()->getDependence()); + if (isa(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(getAsDecl())) - return DC->isDependentContext(); - return getAsDecl()->getDeclContext()->isDependentContext(); + case Declaration: { + auto *DC = dyn_cast(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(getAsExpr())); + Deps = toTemplateArgumentDependence(getAsExpr()->getDependence()); + if (isa(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(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::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 TemplateArgument::getNumTemplateExpansions() const { @@ -601,20 +547,14 @@ 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().isInstantiationDependent(); - 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 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -13,6 +13,7 @@ #include "clang/AST/TemplateName.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 +169,48 @@ return TemplateName(Decl); } -bool TemplateName::isDependent() const { +TemplateNameDependence TemplateName::getDependence() const { + auto F = TemplateNameDependence::None; + if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { + F |= toTemplateNameDependence(QTN->getQualifier()->getDependence()); + } else if (DependentTemplateName *DTN = getAsDependentTemplateName()) { + if (DTN->getQualifier()) + F |= toTemplateNameDependence(DTN->getQualifier()->getDependence()); + } + if (TemplateDecl *Template = getAsTemplateDecl()) { - if (isa(Template)) - return true; + if (auto *TTP = dyn_cast(Template)) { + F |= TemplateNameDependence::DependentInstantiation; + if (TTP->isParameterPack()) + F |= 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()) + F |= TemplateNameDependence::DependentInstantiation; + } else { + assert(!getAsOverloadedTemplate() && + "overloaded templates shouldn't survive to here"); + F |= TemplateNameDependence::DependentInstantiation; } + if (getAsSubstTemplateTemplateParmPack() != nullptr) + F |= TemplateNameDependence::UnexpandedPack; + return F; +} - 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(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 --- 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" @@ -24,6 +24,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" @@ -12694,9 +12695,7 @@ // base classes. CallExpr *CE = CallExpr::Create(Context, Fn, Args, Context.DependentTy, VK_RValue, RParenLoc); - CE->setTypeDependent(true); - CE->setValueDependent(true); - CE->setInstantiationDependent(true); + CE->addDependencies(ExprDependence::TypeValueInstantiation); *Result = CE; return true; } diff --git a/clang/lib/Serialization/ASTReaderStmt.cpp b/clang/lib/Serialization/ASTReaderStmt.cpp --- 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::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->setDependencies(Deps); + E->setValueKind(static_cast(Record.readInt())); E->setObjectKind(static_cast(Record.readInt())); assert(Record.getIdx() == NumExprFields &&