diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-07-01 01:22:09 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-07-01 01:22:09 +0000 |
commit | 678d76c02671e0584d81eee03702f54b2a02633a (patch) | |
tree | e24b7139f60bb9c95ed2bbb25c317032df148c4f /clang/lib/AST | |
parent | f2bcad972d5c0605199ecc8423a7d5120e48911a (diff) | |
download | bcm5719-llvm-678d76c02671e0584d81eee03702f54b2a02633a.tar.gz bcm5719-llvm-678d76c02671e0584d81eee03702f54b2a02633a.zip |
Introduce the notion of instantiation dependence into Clang's AST. A
type/expression/template argument/etc. is instantiation-dependent if
it somehow involves a template parameter, even if it doesn't meet the
requirements for the more common kinds of dependence (dependent type,
type-dependent expression, value-dependent expression).
When we see an instantiation-dependent type, we know we always need to
perform substitution into that instantiation-dependent type. This
keeps us from short-circuiting evaluation in places where we
shouldn't, and lets us properly implement C++0x [temp.type]p2.
In theory, this would also allow us to properly mangle
instantiation-dependent-but-not-dependent decltype types per the
Itanium C++ ABI, but we aren't quite there because we still mangle
based on the canonical type in cases like, e.g.,
template<unsigned> struct A { };
template<typename T>
void f(A<sizeof(sizeof(decltype(T() + T())))>) { }
template void f<int>(A<sizeof(sizeof(int))>);
and therefore get the wrong answer.
llvm-svn: 134225
Diffstat (limited to 'clang/lib/AST')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 7 | ||||
-rw-r--r-- | clang/lib/AST/DeclarationName.cpp | 22 | ||||
-rw-r--r-- | clang/lib/AST/Expr.cpp | 141 | ||||
-rw-r--r-- | clang/lib/AST/ExprCXX.cpp | 55 | ||||
-rw-r--r-- | clang/lib/AST/NestedNameSpecifier.cpp | 22 | ||||
-rw-r--r-- | clang/lib/AST/TemplateBase.cpp | 39 | ||||
-rw-r--r-- | clang/lib/AST/TemplateName.cpp | 9 | ||||
-rw-r--r-- | clang/lib/AST/Type.cpp | 77 |
8 files changed, 317 insertions, 55 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index ec064fc2f4f..4c42393365b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2802,7 +2802,12 @@ static QualType getDecltypeForExpr(const Expr *e, const ASTContext &Context) { /// on canonical type's (which are always unique). QualType ASTContext::getDecltypeType(Expr *e) const { DecltypeType *dt; - if (e->isTypeDependent()) { + + // C++0x [temp.type]p2: + // If an expression e involves a template parameter, decltype(e) denotes a + // unique dependent type. Two such decltype-specifiers refer to the same + // type only if their expressions are equivalent (14.5.6.1). + if (e->isInstantiationDependent()) { llvm::FoldingSetNodeID ID; DependentDecltypeType::Profile(ID, *this, e); diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp index cef54e97c93..72c0e9da7f1 100644 --- a/clang/lib/AST/DeclarationName.cpp +++ b/clang/lib/AST/DeclarationName.cpp @@ -533,6 +533,28 @@ bool DeclarationNameInfo::containsUnexpandedParameterPack() const { llvm_unreachable("All name kinds handled."); } +bool DeclarationNameInfo::isInstantiationDependent() const { + switch (Name.getNameKind()) { + case DeclarationName::Identifier: + case DeclarationName::ObjCZeroArgSelector: + case DeclarationName::ObjCOneArgSelector: + case DeclarationName::ObjCMultiArgSelector: + case DeclarationName::CXXOperatorName: + case DeclarationName::CXXLiteralOperatorName: + case DeclarationName::CXXUsingDirective: + return false; + + case DeclarationName::CXXConstructorName: + case DeclarationName::CXXDestructorName: + case DeclarationName::CXXConversionFunctionName: + if (TypeSourceInfo *TInfo = LocInfo.NamedType.TInfo) + return TInfo->getType()->isInstantiationDependentType(); + + return Name.getCXXNameType()->isInstantiationDependentType(); + } + llvm_unreachable("All name kinds handled."); +} + std::string DeclarationNameInfo::getAsString() const { std::string Result; llvm::raw_string_ostream OS(Result); diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 1d0319f6014..3002e305ac5 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -142,9 +142,10 @@ void ExplicitTemplateArgumentList::initializeFrom( } void ExplicitTemplateArgumentList::initializeFrom( - const TemplateArgumentListInfo &Info, - bool &Dependent, - bool &ContainsUnexpandedParameterPack) { + const TemplateArgumentListInfo &Info, + bool &Dependent, + bool &InstantiationDependent, + bool &ContainsUnexpandedParameterPack) { LAngleLoc = Info.getLAngleLoc(); RAngleLoc = Info.getRAngleLoc(); NumTemplateArgs = Info.size(); @@ -152,6 +153,8 @@ void ExplicitTemplateArgumentList::initializeFrom( TemplateArgumentLoc *ArgBuffer = getTemplateArgs(); 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(); @@ -178,14 +181,16 @@ std::size_t ExplicitTemplateArgumentList::sizeFor( return sizeFor(Info.size()); } -/// \brief Compute the type- and value-dependence of a declaration reference +/// \brief Compute the type-, value-, and instantiation-dependence of a +/// declaration reference /// based on the declaration being referenced. static void computeDeclRefDependence(NamedDecl *D, QualType T, bool &TypeDependent, - bool &ValueDependent) { + bool &ValueDependent, + bool &InstantiationDependent) { TypeDependent = false; ValueDependent = false; - + InstantiationDependent = false; // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -200,20 +205,31 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, if (T->isDependentType()) { TypeDependent = true; ValueDependent = true; + InstantiationDependent = true; return; + } else if (T->isInstantiationDependentType()) { + InstantiationDependent = true; } // (TD) - a conversion-function-id that specifies a dependent type if (D->getDeclName().getNameKind() - == DeclarationName::CXXConversionFunctionName && - D->getDeclName().getCXXNameType()->isDependentType()) { - TypeDependent = true; - ValueDependent = true; - return; + == DeclarationName::CXXConversionFunctionName) { + QualType T = D->getDeclName().getCXXNameType(); + if (T->isDependentType()) { + TypeDependent = true; + ValueDependent = true; + InstantiationDependent = true; + return; + } + + if (T->isInstantiationDependentType()) + InstantiationDependent = true; } + // (VD) - the name of a non-type template parameter, if (isa<NonTypeTemplateParmDecl>(D)) { ValueDependent = true; + InstantiationDependent = true; return; } @@ -223,16 +239,20 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, if (Var->getType()->isIntegralOrEnumerationType() && Var->getType().getCVRQualifiers() == Qualifiers::Const) { if (const Expr *Init = Var->getAnyInitializer()) - if (Init->isValueDependent()) + if (Init->isValueDependent()) { ValueDependent = true; + InstantiationDependent = true; + } } // (VD) - FIXME: Missing from the standard: // - a member function or a static data member of the current // instantiation else if (Var->isStaticDataMember() && - Var->getDeclContext()->isDependentContext()) + Var->getDeclContext()->isDependentContext()) { ValueDependent = true; + InstantiationDependent = true; + } return; } @@ -242,6 +262,7 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, // instantiation if (isa<CXXMethodDecl>(D) && D->getDeclContext()->isDependentContext()) { ValueDependent = true; + InstantiationDependent = true; return; } } @@ -249,7 +270,9 @@ static void computeDeclRefDependence(NamedDecl *D, QualType T, void DeclRefExpr::computeDependence() { bool TypeDependent = false; bool ValueDependent = false; - computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent); + bool InstantiationDependent = false; + computeDeclRefDependence(getDecl(), getType(), TypeDependent, ValueDependent, + InstantiationDependent); // (TD) C++ [temp.dep.expr]p3: // An id-expression is type-dependent if it contains: @@ -262,13 +285,16 @@ void DeclRefExpr::computeDependence() { hasExplicitTemplateArgs() && TemplateSpecializationType::anyDependentTemplateArguments( getTemplateArgs(), - getNumTemplateArgs())) { + getNumTemplateArgs(), + InstantiationDependent)) { TypeDependent = true; ValueDependent = true; + InstantiationDependent = true; } ExprBits.TypeDependent = TypeDependent; ExprBits.ValueDependent = ValueDependent; + ExprBits.InstantiationDependent = InstantiationDependent; // Is the declaration a parameter pack? if (getDecl()->isParameterPack()) @@ -280,7 +306,7 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, NamedDecl *FoundD, const TemplateArgumentListInfo *TemplateArgs, QualType T, ExprValueKind VK) - : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false), + : Expr(DeclRefExprClass, T, VK, OK_Ordinary, false, false, false, false), D(D), Loc(NameInfo.getLoc()), DNLoc(NameInfo.getInfo()) { DeclRefExprBits.HasQualifier = QualifierLoc ? 1 : 0; if (QualifierLoc) @@ -289,9 +315,17 @@ DeclRefExpr::DeclRefExpr(NestedNameSpecifierLoc QualifierLoc, if (FoundD) getInternalFoundDecl() = FoundD; DeclRefExprBits.HasExplicitTemplateArgs = TemplateArgs ? 1 : 0; - if (TemplateArgs) - getExplicitTemplateArgs().initializeFrom(*TemplateArgs); - + if (TemplateArgs) { + bool Dependent = false; + bool InstantiationDependent = false; + bool ContainsUnexpandedParameterPack = false; + getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); + if (InstantiationDependent) + setInstantiationDependent(true); + } + computeDependence(); } @@ -670,6 +704,7 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, : Expr(SC, t, VK, OK_Ordinary, fn->isTypeDependent(), fn->isValueDependent(), + fn->isInstantiationDependent(), fn->containsUnexpandedParameterPack()), NumArgs(numargs) { @@ -680,6 +715,8 @@ CallExpr::CallExpr(ASTContext& C, StmtClass SC, Expr *fn, unsigned NumPreArgs, ExprBits.TypeDependent = true; if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -695,6 +732,7 @@ CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, : Expr(CallExprClass, t, VK, OK_Ordinary, fn->isTypeDependent(), fn->isValueDependent(), + fn->isInstantiationDependent(), fn->containsUnexpandedParameterPack()), NumArgs(numargs) { @@ -705,6 +743,8 @@ CallExpr::CallExpr(ASTContext& C, Expr *fn, Expr **args, unsigned numargs, ExprBits.TypeDependent = true; if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -862,6 +902,7 @@ OffsetOfExpr::OffsetOfExpr(ASTContext &C, QualType type, : Expr(OffsetOfExprClass, type, VK_RValue, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/tsi->getType()->isDependentType(), + tsi->getType()->isInstantiationDependentType(), tsi->getType()->containsUnexpandedParameterPack()), OperatorLoc(OperatorLoc), RParenLoc(RParenLoc), TSInfo(tsi), NumComps(numComps), NumExprs(numExprs) @@ -917,7 +958,12 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, if (QualifierLoc && QualifierLoc.getNestedNameSpecifier()->isDependent()) { E->setValueDependent(true); E->setTypeDependent(true); - } + E->setInstantiationDependent(true); + } + else if (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) + E->setInstantiationDependent(true); + E->HasQualifierOrFoundDecl = true; MemberNameQualifier *NQ = E->getMemberQualifier(); @@ -926,8 +972,15 @@ MemberExpr *MemberExpr::Create(ASTContext &C, Expr *base, bool isarrow, } if (targs) { + bool Dependent = false; + bool InstantiationDependent = false; + bool ContainsUnexpandedParameterPack = false; E->HasExplicitTemplateArgumentList = true; - E->getExplicitTemplateArgs().initializeFrom(*targs); + E->getExplicitTemplateArgs().initializeFrom(*targs, Dependent, + InstantiationDependent, + ContainsUnexpandedParameterPack); + if (InstantiationDependent) + E->setInstantiationDependent(true); } return E; @@ -1251,7 +1304,7 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, Expr **initExprs, unsigned numInits, SourceLocation rbraceloc) : Expr(InitListExprClass, QualType(), VK_RValue, OK_Ordinary, false, false, - false), + false, false), InitExprs(C, numInits), LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), HadArrayRangeDesignator(false) @@ -1261,6 +1314,8 @@ InitListExpr::InitListExpr(ASTContext &C, SourceLocation lbraceloc, ExprBits.TypeDependent = true; if (initExprs[I]->isValueDependent()) ExprBits.ValueDependent = true; + if (initExprs[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (initExprs[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; } @@ -2575,6 +2630,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, /*TypeDependent=*/false, /*ValueDependent=*/false, + /*InstantiationDependent=*/false, /*ContainsUnexpandedParameterPack=*/false), NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass), HasMethod(Method != 0), IsDelegateInitCall(false), SuperLoc(SuperLoc), @@ -2597,7 +2653,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, Expr **Args, unsigned NumArgs, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, T->isDependentType(), - T->isDependentType(), T->containsUnexpandedParameterPack()), + T->isDependentType(), T->isInstantiationDependentType(), + T->containsUnexpandedParameterPack()), NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0), IsDelegateInitCall(false), SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method @@ -2611,6 +2668,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprBits.TypeDependent = true; if (Args[I]->isValueDependent()) ExprBits.ValueDependent = true; + if (Args[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (Args[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2629,6 +2688,7 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, SourceLocation RBracLoc) : Expr(ObjCMessageExprClass, T, VK, OK_Ordinary, Receiver->isTypeDependent(), Receiver->isTypeDependent(), + Receiver->isInstantiationDependent(), Receiver->containsUnexpandedParameterPack()), NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0), IsDelegateInitCall(false), @@ -2643,6 +2703,8 @@ ObjCMessageExpr::ObjCMessageExpr(QualType T, ExprBits.TypeDependent = true; if (Args[I]->isValueDependent()) ExprBits.ValueDependent = true; + if (Args[I]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (Args[I]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2784,6 +2846,7 @@ ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, SourceLocation RP) : Expr(ShuffleVectorExprClass, Type, VK_RValue, OK_Ordinary, Type->isDependentType(), Type->isDependentType(), + Type->isInstantiationDependentType(), Type->containsUnexpandedParameterPack()), BuiltinLoc(BLoc), RParenLoc(RP), NumExprs(nexpr) { @@ -2793,6 +2856,8 @@ ShuffleVectorExpr::ShuffleVectorExpr(ASTContext &C, Expr **args, unsigned nexpr, ExprBits.TypeDependent = true; if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2822,6 +2887,7 @@ GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context, AssocExprs[ResultIndex]->getObjectKind(), AssocExprs[ResultIndex]->isTypeDependent(), AssocExprs[ResultIndex]->isValueDependent(), + AssocExprs[ResultIndex]->isInstantiationDependent(), ContainsUnexpandedParameterPack), AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), @@ -2842,8 +2908,9 @@ GenericSelectionExpr::GenericSelectionExpr(ASTContext &Context, Context.DependentTy, VK_RValue, OK_Ordinary, - /*isTypeDependent=*/ true, - /*isValueDependent=*/ true, + /*isTypeDependent=*/true, + /*isValueDependent=*/true, + /*isInstantiationDependent=*/true, ContainsUnexpandedParameterPack), AssocTypes(new (Context) TypeSourceInfo*[NumAssocs]), SubExprs(new (Context) Stmt*[END_EXPR+NumAssocs]), NumAssocs(NumAssocs), @@ -2877,6 +2944,7 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, : Expr(DesignatedInitExprClass, Ty, Init->getValueKind(), Init->getObjectKind(), Init->isTypeDependent(), Init->isValueDependent(), + Init->isInstantiationDependent(), Init->containsUnexpandedParameterPack()), EqualOrColonLoc(EqualOrColonLoc), GNUSyntax(GNUSyntax), NumDesignators(NumDesignators), NumSubExprs(NumIndexExprs + 1) { @@ -2897,7 +2965,8 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, Expr *Index = IndexExprs[IndexIdx]; if (Index->isTypeDependent() || Index->isValueDependent()) ExprBits.ValueDependent = true; - + if (Index->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; // Propagate unexpanded parameter packs. if (Index->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -2909,9 +2978,14 @@ DesignatedInitExpr::DesignatedInitExpr(ASTContext &C, QualType Ty, Expr *Start = IndexExprs[IndexIdx]; Expr *End = IndexExprs[IndexIdx + 1]; if (Start->isTypeDependent() || Start->isValueDependent() || - End->isTypeDependent() || End->isValueDependent()) + End->isTypeDependent() || End->isValueDependent()) { ExprBits.ValueDependent = true; - + ExprBits.InstantiationDependent = true; + } else if (Start->isInstantiationDependent() || + End->isInstantiationDependent()) { + ExprBits.InstantiationDependent = true; + } + // Propagate unexpanded parameter packs. if (Start->containsUnexpandedParameterPack() || End->containsUnexpandedParameterPack()) @@ -3035,7 +3109,7 @@ ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, Expr **exprs, unsigned nexprs, SourceLocation rparenloc, QualType T) : Expr(ParenListExprClass, T, VK_RValue, OK_Ordinary, - false, false, false), + false, false, false, false), NumExprs(nexprs), LParenLoc(lparenloc), RParenLoc(rparenloc) { assert(!T.isNull() && "ParenListExpr must have a valid type"); Exprs = new (C) Stmt*[nexprs]; @@ -3044,6 +3118,8 @@ ParenListExpr::ParenListExpr(ASTContext& C, SourceLocation lparenloc, ExprBits.TypeDependent = true; if (exprs[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (exprs[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (exprs[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -3108,13 +3184,16 @@ Stmt::child_range ObjCMessageExpr::children() { BlockDeclRefExpr::BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK, SourceLocation l, bool ByRef, bool constAdded) - : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, + : Expr(BlockDeclRefExprClass, t, VK, OK_Ordinary, false, false, false, d->isParameterPack()), D(d), Loc(l), IsByRef(ByRef), ConstQualAdded(constAdded) { bool TypeDependent = false; bool ValueDependent = false; - computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent); + bool InstantiationDependent = false; + computeDeclRefDependence(D, getType(), TypeDependent, ValueDependent, + InstantiationDependent); ExprBits.TypeDependent = TypeDependent; ExprBits.ValueDependent = ValueDependent; + ExprBits.InstantiationDependent = InstantiationDependent; } diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index 1a1a0a36a65..32209f6be6a 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -57,6 +57,7 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, SourceLocation constructorRParen) : Expr(CXXNewExprClass, ty, VK_RValue, OK_Ordinary, ty->isDependentType(), ty->isDependentType(), + ty->isInstantiationDependentType(), ty->containsUnexpandedParameterPack()), GlobalNew(globalNew), Initializer(initializer), UsualArrayDeleteWantsSize(usualArrayDeleteWantsSize), @@ -68,6 +69,9 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, AllocateArgsArray(C, arraySize != 0, numPlaceArgs, numConsArgs); unsigned i = 0; if (Array) { + if (arraySize->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; + if (arraySize->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -75,6 +79,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, } for (unsigned j = 0; j < NumPlacementArgs; ++j) { + if (placementArgs[j]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (placementArgs[j]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -82,6 +88,8 @@ CXXNewExpr::CXXNewExpr(ASTContext &C, bool globalNew, FunctionDecl *operatorNew, } for (unsigned j = 0; j < NumConstructorArgs; ++j) { + if (constructorArgs[j]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (constructorArgs[j]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -144,6 +152,14 @@ CXXPseudoDestructorExpr::CXXPseudoDestructorExpr(ASTContext &Context, (DestroyedType.getTypeSourceInfo() && DestroyedType.getTypeSourceInfo()->getType()->isDependentType())), /*isValueDependent=*/Base->isValueDependent(), + (Base->isInstantiationDependent() || + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent()) || + (ScopeType && + ScopeType->getType()->isInstantiationDependentType()) || + (DestroyedType.getTypeSourceInfo() && + DestroyedType.getTypeSourceInfo()->getType() + ->isInstantiationDependentType())), // ContainsUnexpandedParameterPack (Base->containsUnexpandedParameterPack() || (QualifierLoc && @@ -212,9 +228,14 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, UnresolvedSetIterator Begin, UnresolvedSetIterator End, bool KnownDependent, + bool KnownInstantiationDependent, bool KnownContainsUnexpandedParameterPack) : Expr(K, C.OverloadTy, VK_LValue, OK_Ordinary, KnownDependent, KnownDependent, + (KnownInstantiationDependent || + NameInfo.isInstantiationDependent() || + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (KnownContainsUnexpandedParameterPack || NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && @@ -246,14 +267,18 @@ OverloadExpr::OverloadExpr(StmtClass K, ASTContext &C, // expansions. if (TemplateArgs) { bool Dependent = false; + bool InstantiationDependent = false; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + InstantiationDependent, ContainsUnexpandedParameterPack); if (Dependent) { - ExprBits.TypeDependent = true; - ExprBits.ValueDependent = true; - } + ExprBits.TypeDependent = true; + ExprBits.ValueDependent = true; + } + if (InstantiationDependent) + ExprBits.InstantiationDependent = true; if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; } @@ -291,6 +316,9 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, const TemplateArgumentListInfo *Args) : Expr(DependentScopeDeclRefExprClass, T, VK_LValue, OK_Ordinary, true, true, + (NameInfo.isInstantiationDependent() || + (QualifierLoc && + QualifierLoc.getNestedNameSpecifier()->isInstantiationDependent())), (NameInfo.containsUnexpandedParameterPack() || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() @@ -300,11 +328,14 @@ DependentScopeDeclRefExpr::DependentScopeDeclRefExpr(QualType T, { if (Args) { bool Dependent = true; + bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = ExprBits.ContainsUnexpandedParameterPack; reinterpret_cast<ExplicitTemplateArgumentList*>(this+1) - ->initializeFrom(*Args, Dependent, ContainsUnexpandedParameterPack); + ->initializeFrom(*Args, Dependent, InstantiationDependent, + ContainsUnexpandedParameterPack); + ExprBits.ContainsUnexpandedParameterPack = ContainsUnexpandedParameterPack; } } @@ -632,6 +663,7 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, SourceRange ParenRange) : Expr(SC, T, VK_RValue, OK_Ordinary, T->isDependentType(), T->isDependentType(), + T->isInstantiationDependentType(), T->containsUnexpandedParameterPack()), Constructor(D), Loc(Loc), ParenRange(ParenRange), Elidable(elidable), ZeroInitialization(ZeroInitialization), ConstructKind(ConstructKind), @@ -645,6 +677,8 @@ CXXConstructExpr::CXXConstructExpr(ASTContext &C, StmtClass SC, QualType T, if (args[i]->isValueDependent()) ExprBits.ValueDependent = true; + if (args[i]->isInstantiationDependent()) + ExprBits.InstantiationDependent = true; if (args[i]->containsUnexpandedParameterPack()) ExprBits.ContainsUnexpandedParameterPack = true; @@ -660,6 +694,7 @@ ExprWithCleanups::ExprWithCleanups(ASTContext &C, : Expr(ExprWithCleanupsClass, subexpr->getType(), subexpr->getValueKind(), subexpr->getObjectKind(), subexpr->isTypeDependent(), subexpr->isValueDependent(), + subexpr->isInstantiationDependent(), subexpr->containsUnexpandedParameterPack()), SubExpr(subexpr), Temps(0), NumTemps(0) { if (numtemps) { @@ -691,7 +726,7 @@ CXXUnresolvedConstructExpr::CXXUnresolvedConstructExpr(TypeSourceInfo *Type, : Expr(CXXUnresolvedConstructExprClass, Type->getType().getNonReferenceType(), VK_LValue, OK_Ordinary, - Type->getType()->isDependentType(), true, + Type->getType()->isDependentType(), true, true, Type->getType()->containsUnexpandedParameterPack()), Type(Type), LParenLoc(LParenLoc), @@ -740,7 +775,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, DeclarationNameInfo MemberNameInfo, const TemplateArgumentListInfo *TemplateArgs) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true, + VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier() @@ -753,8 +788,10 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, MemberNameInfo(MemberNameInfo) { if (TemplateArgs) { bool Dependent = true; + bool InstantiationDependent = true; bool ContainsUnexpandedParameterPack = false; getExplicitTemplateArgs().initializeFrom(*TemplateArgs, Dependent, + InstantiationDependent, ContainsUnexpandedParameterPack); if (ContainsUnexpandedParameterPack) ExprBits.ContainsUnexpandedParameterPack = true; @@ -769,7 +806,7 @@ CXXDependentScopeMemberExpr::CXXDependentScopeMemberExpr(ASTContext &C, NamedDecl *FirstQualifierFoundInScope, DeclarationNameInfo MemberNameInfo) : Expr(CXXDependentScopeMemberExprClass, C.DependentTy, - VK_LValue, OK_Ordinary, true, true, + VK_LValue, OK_Ordinary, true, true, true, ((Base && Base->containsUnexpandedParameterPack()) || (QualifierLoc && QualifierLoc.getNestedNameSpecifier()-> @@ -874,6 +911,8 @@ UnresolvedMemberExpr::UnresolvedMemberExpr(ASTContext &C, // Dependent ((Base && Base->isTypeDependent()) || BaseType->isDependentType()), + ((Base && Base->isInstantiationDependent()) || + BaseType->isInstantiationDependentType()), // Contains unexpanded parameter pack ((Base && Base->containsUnexpandedParameterPack()) || BaseType->containsUnexpandedParameterPack())), @@ -962,7 +1001,7 @@ SubstNonTypeTemplateParmPackExpr(QualType T, SourceLocation NameLoc, const TemplateArgument &ArgPack) : Expr(SubstNonTypeTemplateParmPackExprClass, T, VK_RValue, OK_Ordinary, - true, false, true), + true, true, true, true), Param(Param), Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()), NameLoc(NameLoc) { } diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp index 2878dff3edc..f6d4f2513ce 100644 --- a/clang/lib/AST/NestedNameSpecifier.cpp +++ b/clang/lib/AST/NestedNameSpecifier.cpp @@ -174,6 +174,28 @@ bool NestedNameSpecifier::isDependent() const { return false; } +/// \brief 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: + return false; + + case TypeSpec: + case TypeSpecWithTemplate: + return getAsType()->isInstantiationDependentType(); + } + + // Necessary to suppress a GCC warning. + return false; +} + bool NestedNameSpecifier::containsUnexpandedParameterPack() const { switch (getKind()) { case Identifier: diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp index 103da1d8a47..56c6e7bc47c 100644 --- a/clang/lib/AST/TemplateBase.cpp +++ b/clang/lib/AST/TemplateBase.cpp @@ -104,6 +104,45 @@ bool TemplateArgument::isDependent() const { return false; } +bool TemplateArgument::isInstantiationDependent() const { + switch (getKind()) { + case Null: + assert(false && "Should not have a NULL template argument"); + return false; + + case Type: + return getAsType()->isInstantiationDependentType(); + + case Template: + return getAsTemplate().isInstantiationDependent(); + + case TemplateExpansion: + return true; + + case Declaration: + if (DeclContext *DC = dyn_cast<DeclContext>(getAsDecl())) + return DC->isDependentContext(); + return getAsDecl()->getDeclContext()->isDependentContext(); + + case Integral: + // Never dependent + return false; + + case Expression: + return getAsExpr()->isInstantiationDependent(); + + case Pack: + for (pack_iterator P = pack_begin(), PEnd = pack_end(); P != PEnd; ++P) { + if (P->isInstantiationDependent()) + return true; + } + + return false; + } + + return false; +} + bool TemplateArgument::isPackExpansion() const { switch (getKind()) { case Null: diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index b22e4b4c0d6..1f7b19aae47 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -99,6 +99,15 @@ bool TemplateName::isDependent() const { return true; } +bool TemplateName::isInstantiationDependent() const { + if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) { + if (QTN->getQualifier()->isInstantiationDependent()) + return true; + } + + return isDependent(); +} + bool TemplateName::containsUnexpandedParameterPack() const { if (TemplateDecl *Template = getAsTemplateDecl()) { if (TemplateTemplateParmDecl *TTP diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 1569173df7d..ca63ec87b11 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -110,6 +110,7 @@ DependentSizedExtVectorType::DependentSizedExtVectorType(const Expr *SizeExpr, SourceLocation loc) : Type(DependentSizedExtVector, can, /*Dependent=*/true, + /*InstantiationDependent=*/true, ElementType->isVariablyModifiedType(), (ElementType->containsUnexpandedParameterPack() || (SizeExpr && SizeExpr->containsUnexpandedParameterPack()))), @@ -129,6 +130,7 @@ DependentSizedExtVectorType::Profile(llvm::FoldingSetNodeID &ID, VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, VectorKind vecKind) : Type(Vector, canonType, vecType->isDependentType(), + vecType->isInstantiationDependentType(), vecType->isVariablyModifiedType(), vecType->containsUnexpandedParameterPack()), ElementType(vecType) @@ -140,6 +142,7 @@ VectorType::VectorType(QualType vecType, unsigned nElements, QualType canonType, VectorType::VectorType(TypeClass tc, QualType vecType, unsigned nElements, QualType canonType, VectorKind vecKind) : Type(tc, canonType, vecType->isDependentType(), + vecType->isInstantiationDependentType(), vecType->isVariablyModifiedType(), vecType->containsUnexpandedParameterPack()), ElementType(vecType) @@ -387,7 +390,7 @@ const RecordType *Type::getAsUnionType() const { ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base, ObjCProtocolDecl * const *Protocols, unsigned NumProtocols) - : Type(ObjCObject, Canonical, false, false, false), + : Type(ObjCObject, Canonical, false, false, false, false), BaseType(Base) { ObjCObjectTypeBits.NumProtocols = NumProtocols; @@ -1350,7 +1353,7 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType( NestedNameSpecifier *NNS, const IdentifierInfo *Name, unsigned NumArgs, const TemplateArgument *Args, QualType Canon) - : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, + : TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true, /*VariablyModified=*/false, NNS && NNS->containsUnexpandedParameterPack()), NNS(NNS), Name(Name), NumArgs(NumArgs) { @@ -1485,6 +1488,7 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, : FunctionType(FunctionProto, result, epi.Variadic, epi.TypeQuals, epi.RefQualifier, canonical, result->isDependentType(), + result->isInstantiationDependentType(), result->isVariablyModifiedType(), result->containsUnexpandedParameterPack(), epi.ExtInfo), @@ -1497,7 +1501,9 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, for (unsigned i = 0; i != numArgs; ++i) { if (args[i]->isDependentType()) setDependent(); - + else if (args[i]->isInstantiationDependentType()) + setInstantiationDependent(); + if (args[i]->containsUnexpandedParameterPack()) setContainsUnexpandedParameterPack(); @@ -1510,7 +1516,9 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, for (unsigned i = 0, e = epi.NumExceptions; i != e; ++i) { if (epi.Exceptions[i]->isDependentType()) setDependent(); - + else if (epi.Exceptions[i]->isInstantiationDependentType()) + setInstantiationDependent(); + if (epi.Exceptions[i]->containsUnexpandedParameterPack()) setContainsUnexpandedParameterPack(); @@ -1520,6 +1528,14 @@ FunctionProtoType::FunctionProtoType(QualType result, const QualType *args, // Store the noexcept expression and context. Expr **noexSlot = reinterpret_cast<Expr**>(argSlot + numArgs); *noexSlot = epi.NoexceptExpr; + + if (epi.NoexceptExpr) { + if (epi.NoexceptExpr->isValueDependent() + || epi.NoexceptExpr->isTypeDependent()) + setDependent(); + else if (epi.NoexceptExpr->isInstantiationDependent()) + setInstantiationDependent(); + } } if (epi.ConsumedArguments) { @@ -1623,6 +1639,7 @@ QualType TypedefType::desugar() const { TypeOfExprType::TypeOfExprType(Expr *E, QualType can) : Type(TypeOfExpr, can, E->isTypeDependent(), + E->isInstantiationDependent(), E->getType()->isVariablyModifiedType(), E->containsUnexpandedParameterPack()), TOExpr(E) { @@ -1639,6 +1656,7 @@ void DependentTypeOfExprType::Profile(llvm::FoldingSetNodeID &ID, DecltypeType::DecltypeType(Expr *E, QualType underlyingType, QualType can) : Type(Decltype, can, E->isTypeDependent(), + E->isInstantiationDependent(), E->getType()->isVariablyModifiedType(), E->containsUnexpandedParameterPack()), E(E), @@ -1654,7 +1672,9 @@ void DependentDecltypeType::Profile(llvm::FoldingSetNodeID &ID, } TagType::TagType(TypeClass TC, const TagDecl *D, QualType can) - : Type(TC, can, D->isDependentType(), /*VariablyModified=*/false, + : Type(TC, can, D->isDependentType(), + /*InstantiationDependent=*/D->isDependentType(), + /*VariablyModified=*/false, /*ContainsUnexpandedParameterPack=*/false), decl(const_cast<TagDecl*>(D)) {} @@ -1674,6 +1694,7 @@ UnaryTransformType::UnaryTransformType(QualType BaseType, UTTKind UKind, QualType CanonicalType) : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(), + UnderlyingType->isInstantiationDependentType(), UnderlyingType->isVariablyModifiedType(), BaseType->containsUnexpandedParameterPack()) , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) @@ -1707,7 +1728,8 @@ SubstTemplateTypeParmPackType:: SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, QualType Canon, const TemplateArgument &ArgPack) - : Type(SubstTemplateTypeParmPack, Canon, true, false, true), Replaced(Param), + : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), + Replaced(Param), Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) { } @@ -1732,23 +1754,39 @@ void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID, } bool TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgumentListInfo &Args) { - return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size()); +anyDependentTemplateArguments(const TemplateArgumentListInfo &Args, + bool &InstantiationDependent) { + return anyDependentTemplateArguments(Args.getArgumentArray(), Args.size(), + InstantiationDependent); } bool TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N) { - for (unsigned i = 0; i != N; ++i) - if (Args[i].getArgument().isDependent()) +anyDependentTemplateArguments(const TemplateArgumentLoc *Args, unsigned N, + bool &InstantiationDependent) { + for (unsigned i = 0; i != N; ++i) { + if (Args[i].getArgument().isDependent()) { + InstantiationDependent = true; return true; + } + + if (Args[i].getArgument().isInstantiationDependent()) + InstantiationDependent = true; + } return false; } bool TemplateSpecializationType:: -anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N) { - for (unsigned i = 0; i != N; ++i) - if (Args[i].isDependent()) +anyDependentTemplateArguments(const TemplateArgument *Args, unsigned N, + bool &InstantiationDependent) { + for (unsigned i = 0; i != N; ++i) { + if (Args[i].isDependent()) { + InstantiationDependent = true; return true; + } + + if (Args[i].isInstantiationDependent()) + InstantiationDependent = true; + } return false; } @@ -1759,6 +1797,8 @@ TemplateSpecializationType(TemplateName T, : Type(TemplateSpecialization, Canon.isNull()? QualType(this, 0) : Canon, Canon.isNull()? T.isDependent() : Canon->isDependentType(), + Canon.isNull()? T.isDependent() + : Canon->isInstantiationDependentType(), false, T.containsUnexpandedParameterPack()), Template(T), NumArgs(NumArgs) { assert(!T.getAsDependentTemplateName() && @@ -1767,8 +1807,12 @@ TemplateSpecializationType(TemplateName T, T.getKind() == TemplateName::SubstTemplateTemplateParm || T.getKind() == TemplateName::SubstTemplateTemplateParmPack) && "Unexpected template name for TemplateSpecializationType"); + bool InstantiationDependent; + (void)InstantiationDependent; assert((!Canon.isNull() || - T.isDependent() || anyDependentTemplateArguments(Args, NumArgs)) && + T.isDependent() || + anyDependentTemplateArguments(Args, NumArgs, + InstantiationDependent)) && "No canonical type for non-dependent class template specialization"); TemplateArgument *TemplateArgs @@ -1782,6 +1826,9 @@ TemplateSpecializationType(TemplateName T, // U<T> is always non-dependent, irrespective of the type T. if (Canon.isNull() && Args[Arg].isDependent()) setDependent(); + else if (Args[Arg].isInstantiationDependent()) + setInstantiationDependent(); + if (Args[Arg].getKind() == TemplateArgument::Type && Args[Arg].getAsType()->isVariablyModifiedType()) setVariablyModified(); |