diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-03-12 22:20:26 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-03-12 22:20:26 +0000 |
commit | c971f8694661776ecdec2ccc33fbe0333eeaf191 (patch) | |
tree | d3f2b68258b1409f9b5cee2f406605bbe2a05a9a | |
parent | e6fbdf538bc50122876639e08a1401e2bc9555ba (diff) |
Store the type of the integral value within a TemplateArgument, so that we can more efficiently reconstruct an IntegerLiteral from it during template instantiation
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@66833 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/DeclTemplate.h | 36 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 16 |
3 files changed, 33 insertions, 22 deletions
diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index cc309b4ea5..17e5ad0b67 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -406,7 +406,10 @@ protected: class TemplateArgument { union { uintptr_t TypeOrValue; - char IntegralValue[sizeof(llvm::APInt)]; + struct { + char Value[sizeof(llvm::APInt)]; + void *Type; + } Integer; }; /// \brief Location of the beginning of this template argument. @@ -446,9 +449,11 @@ public: } /// \brief Construct an integral constant template argument. - TemplateArgument(SourceLocation Loc, const llvm::APInt &Value) + TemplateArgument(SourceLocation Loc, const llvm::APInt &Value, + QualType Type) : Kind(Integral) { - new (IntegralValue) llvm::APInt(Value); + new (Integer.Value) llvm::APInt(Value); + Integer.Type = Type.getAsOpaquePtr(); StartLoc = Loc; } @@ -461,8 +466,10 @@ public: /// \brief Copy constructor for a template argument. TemplateArgument(const TemplateArgument &Other) : Kind(Other.Kind) { - if (Kind == Integral) - new (IntegralValue) llvm::APInt(*Other.getAsIntegral()); + if (Kind == Integral) { + new (Integer.Value) llvm::APInt(*Other.getAsIntegral()); + Integer.Type = Other.Integer.Type; + } else TypeOrValue = Other.TypeOrValue; StartLoc = Other.StartLoc; @@ -476,6 +483,7 @@ public: if (Kind == Other.Kind && Kind == Integral) { // Copy integral values. *this->getAsIntegral() = *Other.getAsIntegral(); + Integer.Type = Other.Integer.Type; } else { // Destroy the current integral value, if that's what we're holding. if (Kind == Integral) @@ -483,9 +491,10 @@ public: Kind = Other.Kind; - if (Other.Kind == Integral) - new (IntegralValue) llvm::APInt(*Other.getAsIntegral()); - else + if (Other.Kind == Integral) { + new (Integer.Value) llvm::APInt(*Other.getAsIntegral()); + Integer.Type = Other.Integer.Type; + } else TypeOrValue = Other.TypeOrValue; } StartLoc = Other.StartLoc; @@ -523,13 +532,21 @@ public: llvm::APInt *getAsIntegral() { if (Kind != Integral) return 0; - return reinterpret_cast<llvm::APInt*>(&IntegralValue[0]); + return reinterpret_cast<llvm::APInt*>(&Integer.Value[0]); } const llvm::APInt *getAsIntegral() const { return const_cast<TemplateArgument*>(this)->getAsIntegral(); } + /// \brief Retrieve the type of the integral value. + QualType getIntegralType() const { + if (Kind != Integral) + return QualType(); + + return QualType::getFromOpaquePtr(Integer.Type); + } + /// \brief Retrieve the template argument as an expression. Expr *getAsExpr() const { if (Kind != Expression) @@ -555,6 +572,7 @@ public: case Integral: getAsIntegral()->Profile(ID); + getIntegralType().Profile(ID); break; case Expression: diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index ea91a3836a..6fc4515571 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -1280,7 +1280,8 @@ bool Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, IntegerType->isSignedIntegerType()); CanonicalArg = Value; - Converted->push_back(TemplateArgument(StartLoc, CanonicalArg)); + Converted->push_back(TemplateArgument(StartLoc, CanonicalArg, + Context.getCanonicalType(IntegerType))); } return false; diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 6ed4d9fb44..6252e29e56 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -595,19 +595,11 @@ TemplateExprInstantiator::VisitDeclRefExpr(DeclRefExpr *E) { Decl *D = E->getDecl(); if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(D)) { assert(NTTP->getDepth() == 0 && "No nested templates yet"); - QualType T = NTTP->getType(); - if (T->isDependentType()) { - // FIXME: We'll be doing this instantiation a lot. Should we - // cache this information in the TemplateArgument itself? - T = SemaRef.InstantiateType(T, TemplateArgs, NumTemplateArgs, - E->getSourceRange().getBegin(), - NTTP->getDeclName()); - if (T.isNull()) - return SemaRef.ExprError(); - } + const TemplateArgument &Arg = TemplateArgs[NTTP->getPosition()]; return SemaRef.Owned(new (SemaRef.Context) IntegerLiteral( - *TemplateArgs[NTTP->getPosition()].getAsIntegral(), - T, E->getSourceRange().getBegin())); + *Arg.getAsIntegral(), + Arg.getIntegralType(), + E->getSourceRange().getBegin())); } else assert(false && "Can't handle arbitrary declaration references"); |