diff options
author | John McCall <rjmccall@apple.com> | 2009-09-05 00:15:47 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-09-05 00:15:47 +0000 |
commit | 7da2431c23ef1ee8acb114e39692246e1801afc2 (patch) | |
tree | 093cb246a8bbcabd5beb9ae84dcfb9f3982665d4 /lib | |
parent | d0e3daf2b980b505e535d35b432c938c6d0208ef (diff) |
Basic support for representing elaborated type specifiers
directly in the AST. The current thinking is to create these
only in C++ mode for efficiency. But for now, they're not being
created at all; patch to follow.
This will let us do things like verify that tags match during
template instantation, as well as signal that an elaborated type
specifier was used for clients that actually care.
Optimally, the TypeLoc hierarchy should be adjusted to carry tag
location information as well.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81057 91177308-0d34-0410-b5e6-96231b3b80d8
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( |