diff options
Diffstat (limited to 'lib/AST')
-rw-r--r-- | lib/AST/ASTContext.cpp | 21 | ||||
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 9 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 111 | ||||
-rw-r--r-- | lib/AST/TypeSerialization.cpp | 25 |
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; } //===----------------------------------------------------------------------===// |