aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-03-12 22:20:26 +0000
committerDouglas Gregor <dgregor@apple.com>2009-03-12 22:20:26 +0000
commitc971f8694661776ecdec2ccc33fbe0333eeaf191 (patch)
treed3f2b68258b1409f9b5cee2f406605bbe2a05a9a
parente6fbdf538bc50122876639e08a1401e2bc9555ba (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.h36
-rw-r--r--lib/Sema/SemaTemplate.cpp3
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp16
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");