diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 23 | ||||
-rw-r--r-- | lib/AST/Type.cpp | 10 | ||||
-rw-r--r-- | lib/CodeGen/CGDebugInfo.cpp | 3 | ||||
-rw-r--r-- | lib/Frontend/PCHReader.cpp | 7 | ||||
-rw-r--r-- | lib/Frontend/PCHWriter.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 20 |
6 files changed, 69 insertions, 0 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 1143b305ad..780b1fdc42 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -733,6 +733,10 @@ ASTContext::getTypeInfo(const Type *T) { break; } + case Type::Elaborated: { + return getTypeInfo(cast<ElaboratedType>(T)->getUnderlyingType().getTypePtr()); + } + case Type::Typedef: { const TypedefDecl *Typedef = cast<TypedefType>(T)->getDecl(); if (const AlignedAttr *Aligned = Typedef->getAttr<AlignedAttr>()) { @@ -1901,6 +1905,25 @@ ASTContext::getTypenameType(NestedNameSpecifier *NNS, return QualType(T, 0); } +QualType +ASTContext::getElaboratedType(QualType UnderlyingType, + ElaboratedType::TagKind Tag) { + llvm::FoldingSetNodeID ID; + ElaboratedType::Profile(ID, UnderlyingType, Tag); + + void *InsertPos = 0; + ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos); + if (T) + return QualType(T, 0); + + QualType Canon = getCanonicalType(UnderlyingType); + + T = new (*this) ElaboratedType(UnderlyingType, Tag, Canon); + Types.push_back(T); + ElaboratedTypes.InsertNode(T, InsertPos); + return QualType(T, 0); +} + /// CmpProtocolNames - Comparison predicate for sorting protocols /// alphabetically. static bool CmpProtocolNames(const ObjCProtocolDecl *LHS, diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index c6ea357fbd..f4dad13f41 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -1674,6 +1674,16 @@ void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString, InnerString = ObjCQIString + InnerString; } +void ElaboratedType::getAsStringInternal(std::string &InnerString, + const PrintingPolicy &Policy) const { + std::string TypeStr; + PrintingPolicy InnerPolicy(Policy); + InnerPolicy.SuppressTagKind = true; + UnderlyingType.getAsStringInternal(InnerString, InnerPolicy); + + InnerString = std::string(getNameForTagKind(getTagKind())) + ' ' + InnerString; +} + void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const { if (Policy.SuppressTag) return; diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index c4759b965c..e53f1fa525 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -792,6 +792,9 @@ llvm::DIType CGDebugInfo::getOrCreateType(QualType Ty, case Type::FunctionProto: case Type::FunctionNoProto: return Slot = CreateType(cast<FunctionType>(Ty), Unit); + case Type::Elaborated: + return Slot = getOrCreateType(cast<ElaboratedType>(Ty)->getUnderlyingType(), + Unit); case Type::ConstantArray: case Type::ConstantArrayWithExpr: diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 4fcf026549..a7e6c0c8f9 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -1941,6 +1941,13 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) { assert(Record.size() == 1 && "incorrect encoding of enum type"); return Context->getTypeDeclType(cast<EnumDecl>(GetDecl(Record[0]))); + case pch::TYPE_ELABORATED: { + assert(Record.size() == 2 && "incorrect encoding of elaborated type"); + unsigned Tag = Record[1]; + return Context->getElaboratedType(GetType(Record[0]), + (ElaboratedType::TagKind) Tag); + } + case pch::TYPE_OBJC_INTERFACE: { unsigned Idx = 0; ObjCInterfaceDecl *ItfD = cast<ObjCInterfaceDecl>(GetDecl(Record[Idx++])); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 4b8847c098..985d99abbe 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -225,6 +225,12 @@ void PCHTypeWriter::VisitEnumType(const EnumType *T) { Code = pch::TYPE_ENUM; } +void PCHTypeWriter::VisitElaboratedType(const ElaboratedType *T) { + Writer.AddTypeRef(T->getUnderlyingType(), Record); + Record.push_back(T->getTagKind()); + Code = pch::TYPE_ELABORATED; +} + void PCHTypeWriter::VisitTemplateSpecializationType( const TemplateSpecializationType *T) { diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 22e01ab581..b49ed5487b 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -441,6 +441,11 @@ public: QualType RebuildEnumType(EnumDecl *Enum) { return SemaRef.Context.getTypeDeclType(Enum); } + + /// \brief Build a new elaborated type. + QualType RebuildElaboratedType(QualType T, ElaboratedType::TagKind Tag) { + return SemaRef.Context.getElaboratedType(T, Tag); + } /// \brief Build a new typeof(expr) type. /// @@ -2328,6 +2333,21 @@ QualType TreeTransform<Derived>::TransformEnumType(const EnumType *T) { return getDerived().RebuildEnumType(Enum); } + +template <typename Derived> +QualType TreeTransform<Derived>::TransformElaboratedType( + const ElaboratedType *T) { + QualType Underlying = getDerived().TransformType(T->getUnderlyingType()); + if (Underlying.isNull()) + return QualType(); + + if (!getDerived().AlwaysRebuild() && + Underlying == T->getUnderlyingType()) + return QualType(T, 0); + + return getDerived().RebuildElaboratedType(Underlying, T->getTagKind()); +} + template<typename Derived> QualType TreeTransform<Derived>::TransformTemplateTypeParmType( |