aboutsummaryrefslogtreecommitdiff
path: root/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST')
-rw-r--r--lib/AST/ASTContext.cpp21
-rw-r--r--lib/AST/DeclTemplate.cpp9
-rw-r--r--lib/AST/Type.cpp111
-rw-r--r--lib/AST/TypeSerialization.cpp25
4 files changed, 95 insertions, 71 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4579fb5a60..a51f432880 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1309,14 +1309,15 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
QualType
ASTContext::getClassTemplateSpecializationType(TemplateDecl *Template,
+ const TemplateArgument *Args,
unsigned NumArgs,
- uintptr_t *Args, bool *ArgIsType,
QualType Canon) {
- Canon = getCanonicalType(Canon);
+ if (!Canon.isNull())
+ Canon = getCanonicalType(Canon);
llvm::FoldingSetNodeID ID;
- ClassTemplateSpecializationType::Profile(ID, Template, NumArgs, Args,
- ArgIsType);
+ ClassTemplateSpecializationType::Profile(ID, Template, Args, NumArgs);
+
void *InsertPos = 0;
ClassTemplateSpecializationType *Spec
= ClassTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -1324,13 +1325,11 @@ ASTContext::getClassTemplateSpecializationType(TemplateDecl *Template,
if (Spec)
return QualType(Spec, 0);
- void *Mem = Allocate(sizeof(ClassTemplateSpecializationType) +
- (sizeof(uintptr_t) *
- (ClassTemplateSpecializationType::
- getNumPackedWords(NumArgs) +
- NumArgs)), 8);
- Spec = new (Mem) ClassTemplateSpecializationType(Template, NumArgs, Args,
- ArgIsType, Canon);
+ void *Mem = Allocate((sizeof(ClassTemplateSpecializationType) +
+ sizeof(TemplateArgument) * NumArgs),
+ 8);
+ Spec = new (Mem) ClassTemplateSpecializationType(Template, Args, NumArgs,
+ Canon);
Types.push_back(Spec);
ClassTemplateSpecializationTypes.InsertNode(Spec, InsertPos);
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp
index ed4fd44e70..ac76c258a7 100644
--- a/lib/AST/DeclTemplate.cpp
+++ b/lib/AST/DeclTemplate.cpp
@@ -145,6 +145,15 @@ SourceLocation TemplateTemplateParmDecl::getDefaultArgumentLoc() const {
}
//===----------------------------------------------------------------------===//
+// TemplateArgument Implementation
+//===----------------------------------------------------------------------===//
+
+TemplateArgument::TemplateArgument(Expr *E) : Kind(Expression) {
+ TypeOrValue = reinterpret_cast<uintptr_t>(E);
+ StartLoc = E->getSourceRange().getBegin();
+}
+
+//===----------------------------------------------------------------------===//
// ClassTemplateSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
ClassTemplateSpecializationDecl::
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 3b06b4ee28..412b0cf834 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -921,59 +921,77 @@ bool EnumType::classof(const TagType *TT) {
return isa<EnumDecl>(TT->getDecl());
}
-void
+bool
ClassTemplateSpecializationType::
-packBooleanValues(unsigned NumArgs, bool *Values, uintptr_t *Words) {
- const unsigned BitsPerWord = sizeof(uintptr_t) * 8;
-
- for (unsigned PW = 0, NumPackedWords = getNumPackedWords(NumArgs), Arg = 0;
- PW != NumPackedWords; ++PW) {
- uintptr_t Word = 0;
- for (unsigned Bit = 0; Bit < BitsPerWord && Arg < NumArgs; ++Bit, ++Arg) {
- Word <<= 1;
- Word |= Values[Arg];
+anyDependentTemplateArguments(const TemplateArgument *Args, unsigned NumArgs) {
+ for (unsigned Idx = 0; Idx < NumArgs; ++Idx) {
+ switch (Args[Idx].getKind()) {
+ case TemplateArgument::Type:
+ if (Args[Idx].getAsType()->isDependentType())
+ return true;
+ break;
+
+ case TemplateArgument::Declaration:
+ case TemplateArgument::Integral:
+ // Never dependent
+ break;
+
+ case TemplateArgument::Expression:
+ if (Args[Idx].getAsExpr()->isTypeDependent() ||
+ Args[Idx].getAsExpr()->isValueDependent())
+ return true;
+ break;
}
- Words[PW] = Word;
}
+
+ return false;
}
ClassTemplateSpecializationType::
-ClassTemplateSpecializationType(TemplateDecl *T, unsigned NumArgs,
- uintptr_t *Args, bool *ArgIsType,
- QualType Canon)
- : Type(ClassTemplateSpecialization, Canon, /*FIXME:Dependent=*/false),
- Template(T), NumArgs(NumArgs)
+ClassTemplateSpecializationType(TemplateDecl *T, const TemplateArgument *Args,
+ unsigned NumArgs, QualType Canon)
+ : Type(ClassTemplateSpecialization,
+ Canon.isNull()? QualType(this, 0) : Canon,
+ /*FIXME: Check for dependent template */
+ anyDependentTemplateArguments(Args, NumArgs)),
+ Template(T), NumArgs(NumArgs)
{
- uintptr_t *Data = reinterpret_cast<uintptr_t *>(this + 1);
+ assert((!Canon.isNull() ||
+ anyDependentTemplateArguments(Args, NumArgs)) &&
+ "No canonical type for non-dependent class template specialization");
- // Pack the argument-is-type values into the words just after the
- // class template specialization type.
- packBooleanValues(NumArgs, ArgIsType, Data);
-
- // Copy the template arguments after the packed words.
- Data += getNumPackedWords(NumArgs);
+ TemplateArgument *TemplateArgs
+ = reinterpret_cast<TemplateArgument *>(this + 1);
for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
- Data[Arg] = Args[Arg];
+ new (&TemplateArgs[Arg]) TemplateArgument(Args[Arg]);
}
void ClassTemplateSpecializationType::Destroy(ASTContext& C) {
for (unsigned Arg = 0; Arg < NumArgs; ++Arg)
- if (!isArgType(Arg))
- getArgAsExpr(Arg)->Destroy(C);
+ if (Expr *E = getArg(Arg).getAsExpr())
+ E->Destroy(C);
+}
+
+ClassTemplateSpecializationType::iterator
+ClassTemplateSpecializationType::end() const {
+ return begin() + getNumArgs();
}
-uintptr_t
-ClassTemplateSpecializationType::getArgAsOpaqueValue(unsigned Arg) const {
- const uintptr_t *Data = reinterpret_cast<const uintptr_t *>(this + 1);
- Data += getNumPackedWords(NumArgs);
- return Data[Arg];
+const TemplateArgument &
+ClassTemplateSpecializationType::getArg(unsigned Idx) const {
+ assert(Idx < getNumArgs() && "Template argument out of range");
+ return getArgs()[Idx];
}
-bool ClassTemplateSpecializationType::isArgType(unsigned Arg) const {
- const unsigned BitsPerWord = sizeof(uintptr_t) * 8;
- const uintptr_t *Data = reinterpret_cast<const uintptr_t *>(this + 1);
- Data += Arg / BitsPerWord;
- return (*Data >> ((NumArgs - Arg) % BitsPerWord - 1)) & 0x01;
+void
+ClassTemplateSpecializationType::Profile(llvm::FoldingSetNodeID &ID,
+ TemplateDecl *T,
+ const TemplateArgument *Args,
+ unsigned NumArgs) {
+ ID.AddPointer(T);
+
+ for (unsigned Idx = 0; Idx < NumArgs; ++Idx)
+ Args[Idx].Profile(ID);
}
//===----------------------------------------------------------------------===//
@@ -1280,11 +1298,24 @@ getAsStringInternal(std::string &InnerString) const {
// Print the argument into a string.
std::string ArgString;
- if (isArgType(Arg))
- getArgAsType(Arg).getAsStringInternal(ArgString);
- else {
+ switch (getArg(Arg).getKind()) {
+ case TemplateArgument::Type:
+ getArg(Arg).getAsType().getAsStringInternal(ArgString);
+ break;
+
+ case TemplateArgument::Declaration:
+ ArgString = cast<NamedDecl>(getArg(Arg).getAsDecl())->getNameAsString();
+ break;
+
+ case TemplateArgument::Integral:
+ ArgString = getArg(Arg).getAsIntegral()->toString(10, true);
+ break;
+
+ case TemplateArgument::Expression: {
llvm::raw_string_ostream s(ArgString);
- getArgAsExpr(Arg)->printPretty(s);
+ getArg(Arg).getAsExpr()->printPretty(s);
+ break;
+ }
}
// If this is the first argument and its string representation
diff --git a/lib/AST/TypeSerialization.cpp b/lib/AST/TypeSerialization.cpp
index b7a8f1a366..1b9fed4866 100644
--- a/lib/AST/TypeSerialization.cpp
+++ b/lib/AST/TypeSerialization.cpp
@@ -390,13 +390,7 @@ void ClassTemplateSpecializationType::EmitImpl(Serializer& S) const {
S.Emit(getCanonicalTypeInternal());
S.EmitPtr(Template);
S.EmitInt(NumArgs);
- for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
- S.EmitBool(isArgType(Arg));
- if (isArgType(Arg))
- S.Emit(getArgAsType(Arg));
- else
- S.EmitOwnedPtr(getArgAsExpr(Arg));
- }
+ // FIXME: Serialize class template specialization types
}
Type*
@@ -409,19 +403,10 @@ CreateImpl(ASTContext& Context, Deserializer& D) {
TemplateDecl *Template = cast<TemplateDecl>(D.ReadPtr<Decl>());
unsigned NumArgs = D.ReadInt();
- for (unsigned Arg = 0; Arg < NumArgs; ++Arg) {
- bool IsType = D.ReadBool();
- ArgIsType.push_back(IsType);
- if (IsType)
- Args.push_back(
- reinterpret_cast<uintptr_t>(QualType::ReadVal(D).getAsOpaquePtr()));
- else
- Args.push_back(reinterpret_cast<uintptr_t>(D.ReadOwnedPtr<Expr>(Context)));
- }
-
- return Context.getClassTemplateSpecializationType(Template, NumArgs,
- &Args[0], &ArgIsType[0],
- Canon).getTypePtr();
+ // FIXME: De-serialize class template specialization types
+ (void)Template;
+ (void)NumArgs;
+ return 0;
}
//===----------------------------------------------------------------------===//