diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 18 | ||||
-rw-r--r-- | lib/AST/ASTImporter.cpp | 21 | ||||
-rw-r--r-- | lib/AST/ItaniumMangle.cpp | 16 | ||||
-rw-r--r-- | lib/AST/MicrosoftMangle.cpp | 4 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 10 | ||||
-rw-r--r-- | lib/AST/TypePrinter.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/DeclSpec.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 7 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateVariadic.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 59 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 35 | ||||
-rw-r--r-- | lib/Serialization/ASTReader.cpp | 13 | ||||
-rw-r--r-- | lib/Serialization/ASTWriter.cpp | 13 |
17 files changed, 205 insertions, 23 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index e664855067..f356c908e9 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -975,6 +975,9 @@ ASTContext::getTypeInfo(const Type *T) const { return getTypeInfo(cast<DecltypeType>(T)->getUnderlyingExpr()->getType() .getTypePtr()); + case Type::UnaryTransform: + return getTypeInfo(cast<UnaryTransformType>(T)->getUnderlyingType()); + case Type::Elaborated: return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr()); @@ -1605,6 +1608,7 @@ QualType ASTContext::getVariableArrayDecayedType(QualType type) const { case Type::TypeOfExpr: case Type::TypeOf: case Type::Decltype: + case Type::UnaryTransform: case Type::DependentName: case Type::InjectedClassName: case Type::TemplateSpecialization: @@ -2802,6 +2806,20 @@ QualType ASTContext::getDecltypeType(Expr *e) const { return QualType(dt, 0); } +/// getUnaryTransformationType - We don't unique these, since the memory +/// savings are minimal and these are rare. +QualType ASTContext::getUnaryTransformType(QualType BaseType, + QualType UnderlyingType, + UnaryTransformType::UTTKind Kind) + const { + UnaryTransformType *Ty = + new UnaryTransformType (BaseType, UnderlyingType, Kind, + UnderlyingType->isDependentType() ? + QualType() : UnderlyingType); + Types.push_back(Ty); + return QualType(Ty, 0); +} + /// getAutoType - We only unique auto types after they've been deduced. QualType ASTContext::getAutoType(QualType DeducedType) const { void *InsertPos = 0; diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp index dc881ba869..8904a9561c 100644 --- a/lib/AST/ASTImporter.cpp +++ b/lib/AST/ASTImporter.cpp @@ -64,6 +64,7 @@ namespace { // FIXME: DependentTypeOfExprType QualType VisitTypeOfType(const TypeOfType *T); QualType VisitDecltypeType(const DecltypeType *T); + QualType VisitUnaryTransformType(const UnaryTransformType *T); QualType VisitAutoType(const AutoType *T); // FIXME: DependentDecltypeType QualType VisitRecordType(const RecordType *T); @@ -604,7 +605,14 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context, cast<TypeOfType>(T2)->getUnderlyingType())) return false; break; - + + case Type::UnaryTransform: + if (!IsStructurallyEquivalent(Context, + cast<UnaryTransformType>(T1)->getUnderlyingType(), + cast<UnaryTransformType>(T1)->getUnderlyingType())) + return false; + break; + case Type::Decltype: if (!IsStructurallyEquivalent(Context, cast<DecltypeType>(T1)->getUnderlyingExpr(), @@ -1572,6 +1580,17 @@ QualType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) { return Importer.getToContext().getDecltypeType(ToExpr); } +QualType ASTNodeImporter::VisitUnaryTransformType(const UnaryTransformType *T) { + QualType ToBaseType = Importer.Import(T->getBaseType()); + QualType ToUnderlyingType = Importer.Import(T->getUnderlyingType()); + if (ToBaseType.isNull() || ToUnderlyingType.isNull()) + return QualType(); + + return Importer.getToContext().getUnaryTransformType(ToBaseType, + ToUnderlyingType, + T->getUTTKind()); +} + QualType ASTNodeImporter::VisitAutoType(const AutoType *T) { // FIXME: Make sure that the "to" context supports C++0x! QualType FromDeduced = T->getDeducedType(); diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp index e368c8927f..aad6e9c48d 100644 --- a/lib/AST/ItaniumMangle.cpp +++ b/lib/AST/ItaniumMangle.cpp @@ -1939,6 +1939,22 @@ void CXXNameMangler::mangleType(const DecltypeType *T) { Out << 'E'; } +void CXXNameMangler::mangleType(const UnaryTransformType *T) { + // If this is dependent, we need to record that. If not, we simply + // mangle it as the underlying type since they are equivalent. + if (T->isDependentType()) { + Out << 'U'; + + switch (T->getUTTKind()) { + case UnaryTransformType::EnumUnderlyingType: + Out << "3eut"; + break; + } + } + + mangleType(T->getUnderlyingType()); +} + void CXXNameMangler::mangleType(const AutoType *T) { QualType D = T->getDeducedType(); // <builtin-type> ::= Da # dependent auto diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp index 5424bebc81..4f920f9aac 100644 --- a/lib/AST/MicrosoftMangle.cpp +++ b/lib/AST/MicrosoftMangle.cpp @@ -1113,6 +1113,10 @@ void MicrosoftCXXNameMangler::mangleType(const DecltypeType *T) { assert(false && "Don't know how to mangle DecltypeTypes yet!"); } +void MicrosoftCXXNameMangler::mangleType(const UnaryTransformType *T) { + assert(false && "Don't know how to mangle UnaryTransformationTypes yet!"); +} + void MicrosoftCXXNameMangler::mangleType(const AutoType *T) { assert(false && "Don't know how to mangle AutoTypes yet!"); } diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 9f576db535..d287552844 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1535,6 +1535,16 @@ static TagDecl *getInterestingTagDecl(TagDecl *decl) { return decl; } +UnaryTransformType::UnaryTransformType(QualType BaseType, + QualType UnderlyingType, + UTTKind UKind, + QualType CanonicalType) + : Type(UnaryTransform, CanonicalType, UnderlyingType->isDependentType(), + UnderlyingType->isVariablyModifiedType(), + BaseType->containsUnexpandedParameterPack()) + , BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) +{} + TagDecl *TagType::getDecl() const { return getInterestingTagDecl(decl); } diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp index 0c5df7fae6..aad97fb9fc 100644 --- a/lib/AST/TypePrinter.cpp +++ b/lib/AST/TypePrinter.cpp @@ -94,6 +94,7 @@ void TypePrinter::print(const Type *T, Qualifiers Quals, std::string &buffer) { case Type::TypeOfExpr: case Type::TypeOf: case Type::Decltype: + case Type::UnaryTransform: case Type::Record: case Type::Enum: case Type::Elaborated: @@ -512,6 +513,20 @@ void TypePrinter::printDecltype(const DecltypeType *T, std::string &S) { S = "decltype(" + s.str() + ")" + S; } +void TypePrinter::printUnaryTransform(const UnaryTransformType *T, + std::string &S) { + if (!S.empty()) + S = ' ' + S; + std::string Str; + print(T->getBaseType(), Str); + + switch (T->getUTTKind()) { + case UnaryTransformType::EnumUnderlyingType: + S = "__underlying_type(" + Str + ")" + S; + break; + } +} + void TypePrinter::printAuto(const AutoType *T, std::string &S) { // If the type has been deduced, do not print 'auto'. if (T->isDeduced()) { diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index 1c9d91a2e3..6c73865c3c 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -1444,6 +1444,9 @@ static QualType UnwrapTypeForDebugInfo(QualType T) { case Type::Decltype: T = cast<DecltypeType>(T)->getUnderlyingType(); break; + case Type::UnaryTransform: + T = cast<UnaryTransformType>(T)->getUnderlyingType(); + break; case Type::Attributed: T = cast<AttributedType>(T)->getEquivalentType(); break; @@ -1559,6 +1562,7 @@ llvm::DIType CGDebugInfo::CreateTypeNode(QualType Ty, case Type::TypeOfExpr: case Type::TypeOf: case Type::Decltype: + case Type::UnaryTransform: case Type::Auto: llvm_unreachable("type should have been unwrapped!"); return llvm::DIType(); diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index f623c8e5b6..d3b34b922d 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -603,7 +603,7 @@ void Parser::ParseUnderlyingTypeSpecifier(DeclSpec &DS) { const char *PrevSpec = 0; unsigned DiagID; - if (DS.SetTypeSpecType(DeclSpec::TST_underlying_type, StartLoc, PrevSpec, + if (DS.SetTypeSpecType(DeclSpec::TST_underlyingType, StartLoc, PrevSpec, DiagID, Result.release())) Diag(StartLoc, DiagID) << PrevSpec; } diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp index d6f8f91bbf..5be16e7431 100644 --- a/lib/Sema/DeclSpec.cpp +++ b/lib/Sema/DeclSpec.cpp @@ -309,7 +309,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T) { case DeclSpec::TST_typeofExpr: return "typeof"; case DeclSpec::TST_auto: return "auto"; case DeclSpec::TST_decltype: return "(decltype)"; - case DeclSpec::TST_underlying_type: return "__underlying_type"; + case DeclSpec::TST_underlyingType: return "__underlying_type"; case DeclSpec::TST_unknown_anytype: return "__unknown_anytype"; case DeclSpec::TST_error: return "(error)"; } diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 7bcd205b22..41e05d5cdb 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2865,7 +2865,7 @@ static bool RebuildDeclaratorInCurrentInstantiation(Sema &S, Declarator &D, case DeclSpec::TST_typename: case DeclSpec::TST_typeofType: case DeclSpec::TST_decltype: - case DeclSpec::TST_underlying_type: { + case DeclSpec::TST_underlyingType: { // Grab the type from the parser. TypeSourceInfo *TSI = 0; QualType T = S.GetTypeFromParser(DS.getRepAsType(), &TSI); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index 8e7e1a12dd..d978c389b2 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3106,6 +3106,11 @@ bool UnnamedLocalNoLinkageFinder::VisitDecltypeType(const DecltypeType*) { return false; } +bool UnnamedLocalNoLinkageFinder::VisitUnaryTransformType( + const UnaryTransformType*) { + return false; +} + bool UnnamedLocalNoLinkageFinder::VisitAutoType(const AutoType *T) { return Visit(T->getDeducedType()); } diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index f2ec09b132..c4627eb1e3 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -3886,6 +3886,13 @@ MarkUsedTemplateParameters(Sema &SemaRef, QualType T, OnlyDeduced, Depth, Used); break; + case Type::UnaryTransform: + if (!OnlyDeduced) + MarkUsedTemplateParameters(SemaRef, + cast<UnaryTransformType>(T)->getUnderlyingType(), + OnlyDeduced, Depth, Used); + break; + case Type::PackExpansion: MarkUsedTemplateParameters(SemaRef, cast<PackExpansionType>(T)->getPattern(), diff --git a/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp index 100c6a77a0..86d3bc1709 100644 --- a/lib/Sema/SemaTemplateVariadic.cpp +++ b/lib/Sema/SemaTemplateVariadic.cpp @@ -618,7 +618,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { switch (DS.getTypeSpecType()) { case TST_typename: case TST_typeofType: - case TST_underlying_type: { + case TST_underlyingType: { QualType T = DS.getRepAsType().get(); if (!T.isNull() && T->containsUnexpandedParameterPack()) return true; diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 884144f99b..a2433cad51 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -836,26 +836,15 @@ static QualType ConvertDeclSpecToType(Sema &S, TypeProcessingState &state) { } break; } - case DeclSpec::TST_underlying_type: - // FIXME: Preserve type source info? + case DeclSpec::TST_underlyingType: Result = S.GetTypeFromParser(DS.getRepAsType()); assert(!Result.isNull() && "Didn't get a type for __underlying_type?"); - if (!Result->isDependentType()) { - if (Result->isEnumeralType()) { - EnumDecl *ED = Result->getAs<EnumType>()->getDecl(); - S.DiagnoseUseOfDecl(ED, DS.getTypeSpecTypeLoc()); - QualType UnderlyingType = ED->getIntegerType(); - if (UnderlyingType.isNull()) { - declarator.setInvalidType(true); - Result = Context.IntTy; - } else { - Result = UnderlyingType; - } - } else { - S.Diag(DS.getTypeSpecTypeLoc(), - diag::err_only_enums_have_underlying_types); - Result = Context.IntTy; - } + Result = S.BuildUnaryTransformType(Result, + UnaryTransformType::EnumUnderlyingType, + DS.getTypeSpecTypeLoc()); + if (Result.isNull()) { + Result = Context.IntTy; + declarator.setInvalidType(true); } break; @@ -2397,6 +2386,16 @@ namespace { Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); TL.setUnderlyingTInfo(TInfo); } + void VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { + // FIXME: This holds only because we only have one unary transform. + assert(DS.getTypeSpecType() == DeclSpec::TST_underlyingType); + TL.setKWLoc(DS.getTypeSpecTypeLoc()); + TL.setParensRange(DS.getTypeofParensRange()); + assert(DS.getRepAsType()); + TypeSourceInfo *TInfo = 0; + Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo); + TL.setUnderlyingTInfo(TInfo); + } void VisitBuiltinTypeLoc(BuiltinTypeLoc TL) { // By default, use the source location of the type specifier. TL.setBuiltinLoc(DS.getTypeSpecTypeLoc()); @@ -3397,3 +3396,27 @@ QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) { return Context.getDecltypeType(E); } + +QualType Sema::BuildUnaryTransformType(QualType BaseType, + UnaryTransformType::UTTKind UKind, + SourceLocation Loc) { + switch (UKind) { + case UnaryTransformType::EnumUnderlyingType: + if (!BaseType->isDependentType() && !BaseType->isEnumeralType()) { + Diag(Loc, diag::err_only_enums_have_underlying_types); + return QualType(); + } else { + QualType Underlying = BaseType; + if (!BaseType->isDependentType()) { + EnumDecl *ED = BaseType->getAs<EnumType>()->getDecl(); + assert(ED && "EnumType has no EnumDecl"); + DiagnoseUseOfDecl(ED, Loc); + Underlying = ED->getIntegerType(); + } + assert(!Underlying.isNull()); + return Context.getUnaryTransformType(BaseType, Underlying, + UnaryTransformType::EnumUnderlyingType); + } + } + llvm_unreachable("unknown unary transform type"); +} diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index db65e2ba30..396a978260 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -702,6 +702,11 @@ public: /// By default, builds a new TypeOfType with the given underlying type. QualType RebuildTypeOfType(QualType Underlying); + /// \brief Build a new unary transform type. + QualType RebuildUnaryTransformType(QualType BaseType, + UnaryTransformType::UTTKind UKind, + SourceLocation Loc); + /// \brief Build a new C++0x decltype type. /// /// By default, performs semantic analysis when building the decltype type. @@ -4159,6 +4164,29 @@ QualType TreeTransform<Derived>::TransformDecltypeType(TypeLocBuilder &TLB, } template<typename Derived> +QualType TreeTransform<Derived>::TransformUnaryTransformType( + TypeLocBuilder &TLB, + UnaryTransformTypeLoc TL) { + QualType Result = TL.getType(); + if (Result->isDependentType()) { + const UnaryTransformType *T = TL.getTypePtr(); + QualType NewBase = + getDerived().TransformType(TL.getUnderlyingTInfo())->getType(); + Result = getDerived().RebuildUnaryTransformType(NewBase, + T->getUTTKind(), + TL.getKWLoc()); + if (Result.isNull()) + return QualType(); + } + + UnaryTransformTypeLoc NewTL = TLB.push<UnaryTransformTypeLoc>(Result); + NewTL.setKWLoc(TL.getKWLoc()); + NewTL.setParensRange(TL.getParensRange()); + NewTL.setUnderlyingTInfo(TL.getUnderlyingTInfo()); + return Result; +} + +template<typename Derived> QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB, AutoTypeLoc TL) { const AutoType *T = TL.getTypePtr(); @@ -8053,6 +8081,13 @@ QualType TreeTransform<Derived>::RebuildDecltypeType(Expr *E, } template<typename Derived> +QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType, + UnaryTransformType::UTTKind UKind, + SourceLocation Loc) { + return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc); +} + +template<typename Derived> QualType TreeTransform<Derived>::RebuildTemplateSpecializationType( TemplateName Template, SourceLocation TemplateNameLoc, diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 0ab1704b11..240df2cde8 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -3199,6 +3199,13 @@ QualType ASTReader::ReadTypeRecord(unsigned Index) { case TYPE_DECLTYPE: return Context->getDecltypeType(ReadExpr(*Loc.F)); + case TYPE_UNARY_TRANSFORM: { + QualType BaseType = GetType(Record[0]); + QualType UnderlyingType = GetType(Record[1]); + UnaryTransformType::UTTKind UKind = (UnaryTransformType::UTTKind)Record[2]; + return Context->getUnaryTransformType(BaseType, UnderlyingType, UKind); + } + case TYPE_AUTO: return Context->getAutoType(GetType(Record[0])); @@ -3515,6 +3522,12 @@ void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { TL.setNameLoc(ReadSourceLocation(Record, Idx)); } +void TypeLocReader::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { + TL.setKWLoc(ReadSourceLocation(Record, Idx)); + TL.setLParenLoc(ReadSourceLocation(Record, Idx)); + TL.setRParenLoc(ReadSourceLocation(Record, Idx)); + TL.setUnderlyingTInfo(Reader.GetTypeSourceInfo(F, Record, Idx)); +} void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) { TL.setNameLoc(ReadSourceLocation(Record, Idx)); } diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index 9682dfda12..297115c491 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -223,6 +223,13 @@ void ASTTypeWriter::VisitDecltypeType(const DecltypeType *T) { Code = TYPE_DECLTYPE; } +void ASTTypeWriter::VisitUnaryTransformType(const UnaryTransformType *T) { + Writer.AddTypeRef(T->getBaseType(), Record); + Writer.AddTypeRef(T->getUnderlyingType(), Record); + Record.push_back(T->getUTTKind()); + Code = TYPE_UNARY_TRANSFORM; +} + void ASTTypeWriter::VisitAutoType(const AutoType *T) { Writer.AddTypeRef(T->getDeducedType(), Record); Code = TYPE_AUTO; @@ -494,6 +501,12 @@ void TypeLocWriter::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { void TypeLocWriter::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } +void TypeLocWriter::VisitUnaryTransformTypeLoc(UnaryTransformTypeLoc TL) { + Writer.AddSourceLocation(TL.getKWLoc(), Record); + Writer.AddSourceLocation(TL.getLParenLoc(), Record); + Writer.AddSourceLocation(TL.getRParenLoc(), Record); + Writer.AddTypeSourceInfo(TL.getUnderlyingTInfo(), Record); +} void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) { Writer.AddSourceLocation(TL.getNameLoc(), Record); } |