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,82 @@ +//===--- 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 + +namespace clang { + +/// Bitmask showing whether certain properties (e.g. its type or value) of an +/// AST node depend on template instantiation. +enum class DependencyFlags : uint8_t { + Type = 1, + Value = 2, + Instantiation = 4, + UnexpandedPack = 8, + + // Shorthands for commonly used combinations. + None = 0, + TypeValue = Type | Value, + TypeValueInstantiation = Type | Value | Instantiation, + All = 15, +}; + +static constexpr unsigned DependencyFlagsBits = 4; + +inline DependencyFlags operator~(DependencyFlags F) { + return static_cast( + ~static_cast(F) & static_cast(DependencyFlags::All)); +} + +inline DependencyFlags operator|(DependencyFlags L, DependencyFlags R) { + return static_cast(static_cast(L) | + static_cast(R)); +} + +inline DependencyFlags &operator|=(DependencyFlags &L, DependencyFlags R) { + L = L | R; + return L; +} + +inline DependencyFlags operator&(DependencyFlags L, DependencyFlags R) { + return static_cast(static_cast(L) & + static_cast(R)); +} + +inline DependencyFlags &operator&=(DependencyFlags &L, DependencyFlags R) { + L = L & R; + return L; +} + +inline bool isTypeDependent(DependencyFlags F) { + return (F & DependencyFlags::Type) != DependencyFlags::None; +} +inline bool isValueDependent(DependencyFlags F) { + return (F & DependencyFlags::Value) != DependencyFlags::None; +} +inline bool isInstantiationDependent(DependencyFlags F) { + return (F & DependencyFlags::Instantiation) != DependencyFlags::None; +} +inline bool containsUnexpandedParameterPack(DependencyFlags F) { + return (F & DependencyFlags::UnexpandedPack) != DependencyFlags::None; +} + +inline DependencyFlags turnTypeToValueDependency(DependencyFlags F) { + if (!static_cast(F & DependencyFlags::Type)) + return F; + return (F & ~DependencyFlags::Type) | DependencyFlags::Value; +} +inline DependencyFlags turnTemplArgToExprDependencies(DependencyFlags F) { + if ((F & DependencyFlags::TypeValue) != DependencyFlags::None) + return F | DependencyFlags::TypeValue; + return F; +} + +} // 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; + DependencyFlags D = DependencyFlags::None; + if (TD) + D |= DependencyFlags::Type; + if (VD) + D |= DependencyFlags::Value; + if (ID) + D |= DependencyFlags::Instantiation; + if (ContainsUnexpandedParameterPack) + D |= DependencyFlags::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; } + DependencyFlags getDependencies() const { + return static_cast(ExprBits.Dependent); + } + + void setDependencies(DependencyFlags Deps) { + ExprBits.Dependent = static_cast(Deps); + } + void addDependencies(DependencyFlags Deps) { + ExprBits.Dependent |= static_cast(Deps); + } + void removeDependencies(DependencyFlags 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(getDependencies() & DependencyFlags::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(getDependencies() & DependencyFlags::Type); } /// Whether this expression is instantiation-dependent, meaning that @@ -198,12 +214,8 @@ /// \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(getDependencies() & + DependencyFlags::Instantiation); } /// Whether this expression contains an unexpanded parameter @@ -221,13 +233,8 @@ /// 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(getDependencies() & + DependencyFlags::UnexpandedPack); } /// getExprLoc - Return the preferred location for the arrow when diagnosing @@ -1210,10 +1217,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 +2556,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 @@ -4459,13 +4460,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->getDependencies()); } /// Reserve space for some number of initializers. 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 /*DependencyFlags*/ Dependent : DependencyFlagsBits; }; - enum { NumExprBits = NumStmtBits + 9 }; + enum { NumExprBits = NumStmtBits + 5 + DependencyFlagsBits }; 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; } + DependencyFlags getDependencies() 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,7 @@ TemplateArgumentLoc *OutArgArray); void initializeFrom(SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &List, - TemplateArgumentLoc *OutArgArray, bool &Dependent, - bool &InstantiationDependent, - bool &ContainsUnexpandedParameterPack); + TemplateArgumentLoc *OutArgArray, DependencyFlags &Deps); void initializeFrom(SourceLocation TemplateKWLoc); void copyInto(const TemplateArgumentLoc *ArgArray, 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 @@ -2135,6 +2136,17 @@ /// Given that this is a scalar type, classify it. ScalarTypeKind getScalarTypeKind() const; + DependencyFlags getDependencies() const { + DependencyFlags Deps = DependencyFlags::None; + if (isDependentType()) + Deps |= DependencyFlags::Type; + if (isInstantiationDependentType()) + Deps |= DependencyFlags::Instantiation; + if (containsUnexpandedParameterPack()) + Deps |= DependencyFlags::UnexpandedPack; + return Deps; + } + /// 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; } 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->getDependencies()); } // 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 @@ -368,13 +368,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 DependencyFlags computeDeclRefDependence(const ASTContext &Ctx, + NamedDecl *D, QualType T) { + DependencyFlags R = DependencyFlags::None; + if (D->isParameterPack()) + R |= DependencyFlags::UnexpandedPack; // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -386,36 +384,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 | DependencyFlags::TypeValueInstantiation; + else if (T->isInstantiationDependentType()) + R |= DependencyFlags::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 | DependencyFlags::TypeValueInstantiation; if (T->isInstantiationDependentType()) - InstantiationDependent = true; + R |= DependencyFlags::Instantiation; } // (VD) - the name of a non-type template parameter, - if (isa(D)) { - ValueDependent = true; - InstantiationDependent = true; - return; - } + if (isa(D)) + return R | DependencyFlags::Value | DependencyFlags::Instantiation; // (VD) - a constant with integral or enumeration type and is // initialized with an expression that is value-dependent. @@ -432,8 +419,7 @@ Var->getType()->isReferenceType())) { if (const Expr *Init = Var->getAnyInitializer()) if (Init->isValueDependent()) { - ValueDependent = true; - InstantiationDependent = true; + R |= DependencyFlags::Value | DependencyFlags::Instantiation; } } @@ -442,39 +428,21 @@ // instantiation if (Var->isStaticDataMember() && Var->getDeclContext()->isDependentContext()) { - ValueDependent = true; - InstantiationDependent = true; + R |= DependencyFlags::Value | DependencyFlags::Instantiation; TypeSourceInfo *TInfo = Var->getFirstDecl()->getTypeSourceInfo(); if (TInfo->getType()->isIncompleteArrayType()) - TypeDependent = true; + R |= DependencyFlags::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 |= DependencyFlags::Value | DependencyFlags::Instantiation; + return R; } DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, ValueDecl *D, @@ -492,7 +460,7 @@ RefersToEnclosingVariableOrCapture; DeclRefExprBits.NonOdrUseReason = NOUR; DeclRefExprBits.Loc = L; - computeDependence(Ctx); + addDependencies(computeDeclRefDependence(Ctx, getDecl(), getType())); } DeclRefExpr::DeclRefExpr(const ASTContext &Ctx, @@ -511,9 +479,9 @@ NestedNameSpecifierLoc(QualifierLoc); auto *NNS = QualifierLoc.getNestedNameSpecifier(); if (NNS->isInstantiationDependent()) - ExprBits.InstantiationDependent = true; + addDependencies(DependencyFlags::Instantiation); if (NNS->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; + addDependencies(DependencyFlags::UnexpandedPack); } DeclRefExprBits.HasFoundDecl = FoundD ? 1 : 0; if (FoundD) @@ -524,22 +492,19 @@ RefersToEnclosingVariableOrCapture; DeclRefExprBits.NonOdrUseReason = NOUR; if (TemplateArgs) { - bool Dependent = false; - bool InstantiationDependent = false; - bool ContainsUnexpandedParameterPack = false; + DependencyFlags Deps = DependencyFlags::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(!clang::isTypeDependent(Deps) && !clang::isValueDependent(Deps) && + "built a DeclRefExpr with dependent template args"); + addDependencies(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 +1322,11 @@ setCallee(Fn); for (unsigned I = 0; I != NumPreArgs; ++I) { - updateDependenciesFromArg(PreArgs[I]); + addDependencies(PreArgs[I]->getDependencies()); setPreArg(I, PreArgs[I]); } for (unsigned I = 0; I != Args.size(); ++I) { - updateDependenciesFromArg(Args[I]); + addDependencies(Args[I]->getDependencies()); setArg(I, Args[I]); } for (unsigned I = Args.size(); I != NumArgs; ++I) { @@ -1429,17 +1394,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 +1539,9 @@ for (unsigned i = 0; i != exprs.size(); ++i) { if (exprs[i]->isTypeDependent() || exprs[i]->isValueDependent()) - ExprBits.ValueDependent = true; + addDependencies(DependencyFlags::Value); if (exprs[i]->containsUnexpandedParameterPack()) - ExprBits.ContainsUnexpandedParameterPack = true; + addDependencies(DependencyFlags::UnexpandedPack); setIndexExpr(i, exprs[i]); } @@ -1629,8 +1583,8 @@ if (D) { for (const auto *I : D->specific_attrs()) { if (I->isAlignmentDependent()) { - setValueDependent(true); - setInstantiationDependent(true); + addDependencies(DependencyFlags::Value | + DependencyFlags::Instantiation); 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(DependencyFlags::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(DependencyFlags::TypeValueInstantiation); else if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) - E->setInstantiationDependent(true); + E->addDependencies(DependencyFlags::Instantiation); E->MemberExprBits.HasQualifierOrFoundDecl = true; @@ -1710,15 +1663,11 @@ TemplateArgs || TemplateKWLoc.isValid(); if (TemplateArgs) { - bool Dependent = false; - bool InstantiationDependent = false; - bool ContainsUnexpandedParameterPack = false; + DependencyFlags Deps = DependencyFlags::None; E->getTrailingObjects()->initializeFrom( TemplateKWLoc, *TemplateArgs, - E->getTrailingObjects(), Dependent, - InstantiationDependent, ContainsUnexpandedParameterPack); - if (InstantiationDependent) - E->setInstantiationDependent(true); + E->getTrailingObjects(), Deps); + E->addDependencies(Deps & DependencyFlags::Instantiation); } else if (TemplateKWLoc.isValid()) { E->getTrailingObjects()->initializeFrom( TemplateKWLoc); @@ -2236,16 +2185,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]->getDependencies()); InitExprs.insert(C, InitExprs.end(), initExprs.begin(), initExprs.end()); } @@ -4159,15 +4100,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]->getDependencies()); SubExprs[i] = args[i]; } } @@ -4311,13 +4244,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 dependency flags. + DependencyFlags Deps = Index->getDependencies(); + if (clang::isTypeDependent(Deps) || clang::isValueDependent(Deps)) + Deps |= DependencyFlags::TypeValue; + addDependencies(Deps); // Copy the index expressions into permanent storage. *Child++ = IndexExprs[IndexIdx++]; @@ -4325,19 +4257,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; + DependencyFlags Deps = Start->getDependencies() | End->getDependencies(); + if (clang::isTypeDependent(Deps) || clang::isValueDependent(Deps)) + Deps |= DependencyFlags::TypeValueInstantiation; + addDependencies(Deps); // Copy the start/end expressions into permanent storage. *Child++ = IndexExprs[IndexIdx++]; @@ -4475,15 +4399,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]->getDependencies()); getTrailingObjects()[I] = Exprs[I]; } } @@ -4570,14 +4486,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->getDependencies()); if (isa(E)) assert(cast(E)->getSourceExpr() != nullptr && @@ -4618,15 +4527,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]->getDependencies()); 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 @@ -193,36 +193,21 @@ 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->getDependencies() & ~DependencyFlags::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->getDependencies() & ~DependencyFlags::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]->getDependencies() & + ~DependencyFlags::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(DependencyFlags::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; + DependencyFlags Deps = DependencyFlags::None; getTrailingASTTemplateKWAndArgsInfo()->initializeFrom( - TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(), - Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); + TemplateKWLoc, *TemplateArgs, getTrailingTemplateArgumentLoc(), Deps); + addDependencies(turnTemplArgToExprDependencies(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; + DependencyFlags Deps = DependencyFlags::None; getTrailingObjects()->initializeFrom( - TemplateKWLoc, *Args, getTrailingObjects(), - Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); - ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; + TemplateKWLoc, *Args, getTrailingObjects(), Deps); + if (::containsUnexpandedParameterPack(Deps)) + addDependencies(DependencyFlags::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]->getDependencies() & ~DependencyFlags::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(DependencyFlags::UnexpandedPack); StoredArgs[I] = Args[I]; } @@ -1415,14 +1378,12 @@ CXXDependentScopeMemberExprBits.OperatorLoc = OperatorLoc; if (TemplateArgs) { - bool Dependent = true; - bool InstantiationDependent = true; - bool ContainsUnexpandedParameterPack = false; + DependencyFlags Deps = DependencyFlags::None; getTrailingObjects()->initializeFrom( TemplateKWLoc, *TemplateArgs, getTrailingObjects(), - Dependent, InstantiationDependent, ContainsUnexpandedParameterPack); - if (ContainsUnexpandedParameterPack) - ExprBits.ContainsUnexpandedParameterPack = true; + Deps); + if (::containsUnexpandedParameterPack(Deps)) + addDependencies(DependencyFlags::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( + turnTypeToValueDependency(Args[I]->getType()->getDependencies())); ToArgs[I] = Args[I]; } } @@ -1798,14 +1754,14 @@ this->ArgsAsWritten = ArgsAsWritten; std::uninitialized_copy(Converted.begin(), Converted.end(), getTrailingObjects()); - bool IsInstantiationDependent = false; - bool ContainsUnexpandedParameterPack = false; + DependencyFlags Deps = DependencyFlags::None; for (const TemplateArgumentLoc& LocInfo : ArgsAsWritten->arguments()) { if (LocInfo.getArgument().isInstantiationDependent()) - IsInstantiationDependent = true; + Deps |= DependencyFlags::Instantiation; if (LocInfo.getArgument().containsUnexpandedParameterPack()) - ContainsUnexpandedParameterPack = true; - if (ContainsUnexpandedParameterPack && IsInstantiationDependent) + Deps |= DependencyFlags::UnexpandedPack; + if (Deps == + (DependencyFlags::Instantiation | DependencyFlags::UnexpandedPack)) break; } @@ -1814,8 +1770,7 @@ (!NestedNameSpec.getNestedNameSpecifier()->isInstantiationDependent() && !NestedNameSpec.getNestedNameSpecifier() ->containsUnexpandedParameterPack())); - setInstantiationDependent(IsInstantiationDependent); - setContainsUnexpandedParameterPack(ContainsUnexpandedParameterPack); + addDependencies(Deps); 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 @@ -30,13 +30,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(turnTypeToValueDependency(Elements[I]->getDependencies())); SaveElements[I] = Elements[I]; } } @@ -67,16 +61,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; + DependencyFlags Deps = turnTypeToValueDependency( + VK[I].Key->getDependencies() | VK[I].Value->getDependencies()); + if (VK[I].EllipsisLoc.isValid()) + Deps &= ~DependencyFlags::UnexpandedPack; + addDependencies(Deps); KeyValues[I].Key = VK[I].Key; KeyValues[I].Value = VK[I].Value; @@ -183,15 +172,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]->getDependencies()); MyArgs[I] = Args[I]; } 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 @@ -111,84 +111,65 @@ return TemplateArgument(Args.copy(Context)); } -bool TemplateArgument::isDependent() const { +DependencyFlags TemplateArgument::getDependencies() const { + DependencyFlags Deps = DependencyFlags::None; switch (getKind()) { case Null: llvm_unreachable("Should not have a NULL template argument"); case Type: - return getAsType()->isDependentType() || - isa(getAsType()); + Deps = getAsType()->getDependencies(); + if (isa(getAsType())) + Deps |= DependencyFlags::Type; + return Deps; case Template: - return getAsTemplate().isDependent(); + // FIXME: add TemplateName::getDependencies. + if (getAsTemplate().isDependent()) + Deps |= DependencyFlags::TypeValue; + if (getAsTemplate().isInstantiationDependent()) + Deps |= DependencyFlags::Instantiation; + if (getAsTemplate().containsUnexpandedParameterPack()) + Deps |= DependencyFlags::UnexpandedPack; + return Deps; case TemplateExpansion: - return true; + return DependencyFlags::TypeValueInstantiation; - 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 = DependencyFlags::TypeValueInstantiation; + return Deps; + } case NullPtr: - return false; - case Integral: - // Never dependent - return false; + return DependencyFlags::None; case Expression: - return (getAsExpr()->isTypeDependent() || getAsExpr()->isValueDependent() || - isa(getAsExpr())); + Deps = getAsExpr()->getDependencies(); + if (isa(getAsExpr())) + Deps |= DependencyFlags::TypeValueInstantiation; + return Deps; case Pack: for (const auto &P : pack_elements()) - if (P.isDependent()) - return true; - return false; + Deps |= P.getDependencies(); + return Deps; } + llvm_unreachable("unhandled ArgKind"); +} - llvm_unreachable("Invalid TemplateArgument Kind!"); +bool TemplateArgument::isDependent() const { + auto D = getDependencies(); + return (D & DependencyFlags::TypeValue) != DependencyFlags::None; } 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 ::isInstantiationDependent(getDependencies()); } bool TemplateArgument::isPackExpansion() const { @@ -215,38 +196,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 clang::containsUnexpandedParameterPack(getDependencies()); } Optional TemplateArgument::getNumTemplateExpansions() const { @@ -601,20 +551,14 @@ void ASTTemplateKWAndArgsInfo::initializeFrom( SourceLocation TemplateKWLoc, const TemplateArgumentListInfo &Info, - TemplateArgumentLoc *OutArgArray, bool &Dependent, - bool &InstantiationDependent, bool &ContainsUnexpandedParameterPack) { + TemplateArgumentLoc *OutArgArray, DependencyFlags &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().getDependencies(); new (&OutArgArray[i]) TemplateArgumentLoc(Info[i]); } 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 @@ -12695,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(DependencyFlags::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 @@ -511,10 +511,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(); + DependencyFlags Deps = DependencyFlags::None; + if (TypeDependent) + Deps |= DependencyFlags::Type; + if (ValueDependent) + Deps |= DependencyFlags::Value; + if (InstantiationDependent) + Deps |= DependencyFlags::Instantiation; + if (ContainsUnexpandedTemplateParameters) + Deps |= DependencyFlags::UnexpandedPack; + E->setDependencies(Deps); + E->setValueKind(static_cast(Record.readInt())); E->setObjectKind(static_cast(Record.readInt())); assert(Record.getIdx() == NumExprFields &&