summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-09-29 19:42:55 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2009-09-29 19:42:55 +0000
commita7a36dfdb6583fb2bb469d3b9403a8c380a4d0ff (patch)
tree9d760f311df41161398b5b89b5e62179428a1dbc
parent5ec645b4945358feb67b379552bcfdcb89285ba6 (diff)
downloadbcm5719-llvm-a7a36dfdb6583fb2bb469d3b9403a8c380a4d0ff.tar.gz
bcm5719-llvm-a7a36dfdb6583fb2bb469d3b9403a8c380a4d0ff.zip
Introduce ObjCProtocolListType type subclass.
This is used only for keeping detailed type source information for protocol references, it should not participate in the semantics of the type system. Its protocol list is not canonicalized. llvm-svn: 83093
-rw-r--r--clang/include/clang/AST/ASTContext.h5
-rw-r--r--clang/include/clang/AST/Type.h40
-rw-r--r--clang/include/clang/AST/TypeNodes.def1
-rw-r--r--clang/include/clang/Frontend/PCHBitCodes.h10
-rw-r--r--clang/lib/AST/ASTContext.cpp23
-rw-r--r--clang/lib/AST/Type.cpp31
-rw-r--r--clang/lib/Frontend/PCHReader.cpp10
-rw-r--r--clang/lib/Frontend/PCHWriter.cpp10
-rw-r--r--clang/lib/Sema/TreeTransform.h7
9 files changed, 133 insertions, 4 deletions
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index bdd87be369c..bb9e3861be0 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -86,6 +86,7 @@ class ASTContext {
llvm::FoldingSet<TypenameType> TypenameTypes;
llvm::FoldingSet<ObjCInterfaceType> ObjCInterfaceTypes;
llvm::FoldingSet<ObjCObjectPointerType> ObjCObjectPointerTypes;
+ llvm::FoldingSet<ObjCProtocolListType> ObjCProtocolListTypes;
llvm::FoldingSet<ElaboratedType> ElaboratedTypes;
llvm::FoldingSet<QualifiedTemplateName> QualifiedTemplateNames;
@@ -510,6 +511,10 @@ public:
ObjCProtocolDecl **ProtocolList = 0,
unsigned NumProtocols = 0);
+ QualType getObjCProtocolListType(QualType T,
+ ObjCProtocolDecl **Protocols,
+ unsigned NumProtocols);
+
/// getTypeOfType - GCC extension.
QualType getTypeOfExprType(Expr *e);
QualType getTypeOfType(QualType t);
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 952671915f2..cef52175d19 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -2443,6 +2443,46 @@ public:
static bool classof(const ObjCObjectPointerType *) { return true; }
};
+/// \brief An ObjC Protocol list that qualifies a type.
+///
+/// This is used only for keeping detailed type source information, it should
+/// not participate in the semantics of the type system.
+/// The protocol list is not canonicalized.
+class ObjCProtocolListType : public Type, public llvm::FoldingSetNode {
+ QualType BaseType;
+
+ // List of protocols for this protocol conforming object type.
+ llvm::SmallVector<ObjCProtocolDecl*, 4> Protocols;
+
+ ObjCProtocolListType(QualType T, ObjCProtocolDecl **Protos, unsigned NumP) :
+ Type(ObjCProtocolList, QualType(), /*Dependent=*/false),
+ BaseType(T), Protocols(Protos, Protos+NumP) { }
+ friend class ASTContext; // ASTContext creates these.
+
+public:
+ QualType getBaseType() const { return BaseType; }
+
+ /// \brief Provides access to the list of protocols qualifying the base type.
+ typedef llvm::SmallVector<ObjCProtocolDecl*, 4>::const_iterator qual_iterator;
+
+ qual_iterator qual_begin() const { return Protocols.begin(); }
+ qual_iterator qual_end() const { return Protocols.end(); }
+ bool qual_empty() const { return Protocols.size() == 0; }
+
+ /// \brief Return the number of qualifying protocols.
+ unsigned getNumProtocols() const { return Protocols.size(); }
+
+ void Profile(llvm::FoldingSetNodeID &ID);
+ static void Profile(llvm::FoldingSetNodeID &ID, QualType T,
+ ObjCProtocolDecl **protocols, unsigned NumProtocols);
+ virtual void getAsStringInternal(std::string &InnerString,
+ const PrintingPolicy &Policy) const;
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == ObjCProtocolList;
+ }
+ static bool classof(const ObjCProtocolListType *) { return true; }
+};
+
/// A qualifier set is used to build a set of qualifiers.
class QualifierCollector : public Qualifiers {
ASTContext *Context;
diff --git a/clang/include/clang/AST/TypeNodes.def b/clang/include/clang/AST/TypeNodes.def
index a2feb513a89..6c6bd20e852 100644
--- a/clang/include/clang/AST/TypeNodes.def
+++ b/clang/include/clang/AST/TypeNodes.def
@@ -87,6 +87,7 @@ NON_CANONICAL_TYPE(QualifiedName, Type)
DEPENDENT_TYPE(Typename, Type)
TYPE(ObjCInterface, Type)
TYPE(ObjCObjectPointer, Type)
+NON_CANONICAL_TYPE(ObjCProtocolList, Type)
// These types are always leaves in the type hierarchy.
#ifdef LEAF_TYPE
diff --git a/clang/include/clang/Frontend/PCHBitCodes.h b/clang/include/clang/Frontend/PCHBitCodes.h
index f0eea414f18..2655217a833 100644
--- a/clang/include/clang/Frontend/PCHBitCodes.h
+++ b/clang/include/clang/Frontend/PCHBitCodes.h
@@ -394,14 +394,16 @@ namespace clang {
TYPE_OBJC_INTERFACE = 21,
/// \brief An ObjCObjectPointerType record.
TYPE_OBJC_OBJECT_POINTER = 22,
+ /// \brief An ObjCProtocolListType record.
+ TYPE_OBJC_PROTOCOL_LIST = 23,
/// \brief a DecltypeType record.
- TYPE_DECLTYPE = 23,
+ TYPE_DECLTYPE = 24,
/// \brief A ConstantArrayWithExprType record.
- TYPE_CONSTANT_ARRAY_WITH_EXPR = 24,
+ TYPE_CONSTANT_ARRAY_WITH_EXPR = 25,
/// \brief A ConstantArrayWithoutExprType record.
- TYPE_CONSTANT_ARRAY_WITHOUT_EXPR = 25,
+ TYPE_CONSTANT_ARRAY_WITHOUT_EXPR = 26,
/// \brief An ElaboratedType record.
- TYPE_ELABORATED = 26
+ TYPE_ELABORATED = 27
};
/// \brief The type IDs for special types constructed by semantic
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index e0223b009f6..1fa492c874b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -551,6 +551,10 @@ ASTContext::getTypeInfo(const Type *T) {
assert(false && "Should not see dependent types");
break;
+ case Type::ObjCProtocolList:
+ assert(false && "Should not see protocol list types");
+ break;
+
case Type::FunctionNoProto:
case Type::FunctionProto:
// GCC extension: alignof(function) = 32 bits
@@ -1989,6 +1993,25 @@ QualType ASTContext::getObjCInterfaceType(const ObjCInterfaceDecl *Decl,
return QualType(QType, 0);
}
+QualType ASTContext::getObjCProtocolListType(QualType T,
+ ObjCProtocolDecl **Protocols,
+ unsigned NumProtocols) {
+ llvm::FoldingSetNodeID ID;
+ ObjCProtocolListType::Profile(ID, T, Protocols, NumProtocols);
+
+ void *InsertPos = 0;
+ if (ObjCProtocolListType *QT =
+ ObjCProtocolListTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(QT, 0);
+
+ // No Match;
+ ObjCProtocolListType *QType = new (*this, TypeAlignment)
+ ObjCProtocolListType(T, Protocols, NumProtocols);
+ Types.push_back(QType);
+ ObjCProtocolListTypes.InsertNode(QType, InsertPos);
+ return QualType(QType, 0);
+}
+
/// getTypeOfExprType - Unlike many "get<Type>" functions, we can't unique
/// TypeOfExprType AST's (since expression's are never shared). For example,
/// multiple declarations that refer to "typeof(x)" all contain different
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index c3eade2cb96..70b9fa59462 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -752,6 +752,18 @@ void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
Profile(ID, getPointeeType(), 0, 0);
}
+void ObjCProtocolListType::Profile(llvm::FoldingSetNodeID &ID,
+ QualType OIT, ObjCProtocolDecl **protocols,
+ unsigned NumProtocols) {
+ ID.AddPointer(OIT.getAsOpaquePtr());
+ for (unsigned i = 0; i != NumProtocols; i++)
+ ID.AddPointer(protocols[i]);
+}
+
+void ObjCProtocolListType::Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getBaseType(), &Protocols[0], getNumProtocols());
+}
+
/// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
/// potentially looking through *all* consequtive typedefs. This returns the
/// sum of the type qualifiers, so if you have:
@@ -1490,6 +1502,25 @@ void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
InnerString = ObjCQIString + InnerString;
}
+void ObjCProtocolListType::getAsStringInternal(std::string &InnerString,
+ const PrintingPolicy &Policy) const {
+ if (!InnerString.empty()) // Prefix the basic type, e.g. 'typedefname X'.
+ InnerString = ' ' + InnerString;
+
+ std::string ObjCQIString = getBaseType().getAsString(Policy);
+ ObjCQIString += '<';
+ bool isFirst = true;
+ for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
+ if (isFirst)
+ isFirst = false;
+ else
+ ObjCQIString += ',';
+ ObjCQIString += (*I)->getNameAsString();
+ }
+ ObjCQIString += '>';
+ InnerString = ObjCQIString + InnerString;
+}
+
void ElaboratedType::getAsStringInternal(std::string &InnerString,
const PrintingPolicy &Policy) const {
std::string TypeStr;
diff --git a/clang/lib/Frontend/PCHReader.cpp b/clang/lib/Frontend/PCHReader.cpp
index 73c0b8d9911..ead00ee75ff 100644
--- a/clang/lib/Frontend/PCHReader.cpp
+++ b/clang/lib/Frontend/PCHReader.cpp
@@ -1970,6 +1970,16 @@ QualType PCHReader::ReadTypeRecord(uint64_t Offset) {
Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
return Context->getObjCObjectPointerType(OIT, Protos.data(), NumProtos);
}
+
+ case pch::TYPE_OBJC_PROTOCOL_LIST: {
+ unsigned Idx = 0;
+ QualType OIT = GetType(Record[Idx++]);
+ unsigned NumProtos = Record[Idx++];
+ llvm::SmallVector<ObjCProtocolDecl*, 4> Protos;
+ for (unsigned I = 0; I != NumProtos; ++I)
+ Protos.push_back(cast<ObjCProtocolDecl>(GetDecl(Record[Idx++])));
+ return Context->getObjCProtocolListType(OIT, Protos.data(), NumProtos);
+ }
}
// Suppress a GCC warning
return QualType();
diff --git a/clang/lib/Frontend/PCHWriter.cpp b/clang/lib/Frontend/PCHWriter.cpp
index 8ef846f7672..08a1661e1d3 100644
--- a/clang/lib/Frontend/PCHWriter.cpp
+++ b/clang/lib/Frontend/PCHWriter.cpp
@@ -255,6 +255,15 @@ PCHTypeWriter::VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
Code = pch::TYPE_OBJC_OBJECT_POINTER;
}
+void PCHTypeWriter::VisitObjCProtocolListType(const ObjCProtocolListType *T) {
+ Writer.AddTypeRef(T->getBaseType(), Record);
+ Record.push_back(T->getNumProtocols());
+ for (ObjCProtocolListType::qual_iterator I = T->qual_begin(),
+ E = T->qual_end(); I != E; ++I)
+ Writer.AddDeclRef(*I, Record);
+ Code = pch::TYPE_OBJC_PROTOCOL_LIST;
+}
+
//===----------------------------------------------------------------------===//
// PCHWriter Implementation
//===----------------------------------------------------------------------===//
@@ -425,6 +434,7 @@ void PCHWriter::WriteBlockInfoBlock() {
RECORD(TYPE_ENUM);
RECORD(TYPE_OBJC_INTERFACE);
RECORD(TYPE_OBJC_OBJECT_POINTER);
+ RECORD(TYPE_OBJC_PROTOCOL_LIST);
// Statements and Exprs can occur in the Types block.
AddStmtsExprs(Stream, Record);
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index ffbf69b51aa..ec5c6676f5d 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -2485,6 +2485,13 @@ QualType TreeTransform<Derived>::TransformObjCObjectPointerType(
return QualType(T, 0);
}
+template<typename Derived>
+QualType TreeTransform<Derived>::TransformObjCProtocolListType(
+ const ObjCProtocolListType *T) {
+ assert(false && "Should not see ObjCProtocolList types");
+ return QualType(T, 0);
+}
+
//===----------------------------------------------------------------------===//
// Statement transformation
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud