summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-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
5 files changed, 81 insertions, 0 deletions
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