summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp38
-rw-r--r--clang/lib/AST/ASTImporter.cpp17
-rw-r--r--clang/lib/AST/ItaniumMangle.cpp1
-rw-r--r--clang/lib/AST/Type.cpp27
-rw-r--r--clang/lib/AST/TypeLoc.cpp11
-rw-r--r--clang/lib/AST/TypePrinter.cpp23
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.cpp14
-rw-r--r--clang/lib/CodeGen/CGDebugInfo.h2
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp1
-rw-r--r--clang/lib/Sema/SemaExpr.cpp1
-rw-r--r--clang/lib/Sema/SemaType.cpp23
-rw-r--r--clang/lib/Sema/TreeTransform.h52
-rw-r--r--clang/lib/Serialization/ASTReader.cpp19
-rw-r--r--clang/lib/Serialization/ASTWriter.cpp17
14 files changed, 246 insertions, 0 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 697d4c1a526..2ea0f516ea8 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1860,6 +1860,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Paren:
return getTypeInfo(cast<ParenType>(T)->getInnerType().getTypePtr());
+ case Type::ObjCTypeParam:
+ return getTypeInfo(cast<ObjCTypeParamType>(T)->desugar().getTypePtr());
+
case Type::Typedef: {
const TypedefNameDecl *Typedef = cast<TypedefType>(T)->getDecl();
TypeInfo Info = getTypeInfo(Typedef->getUnderlyingType().getTypePtr());
@@ -3941,6 +3944,41 @@ ASTContext::applyObjCProtocolQualifiers(QualType type,
return type;
}
+QualType
+ASTContext::getObjCTypeParamType(const ObjCTypeParamDecl *Decl,
+ ArrayRef<ObjCProtocolDecl *> protocols,
+ QualType Canonical) const {
+ // Look in the folding set for an existing type.
+ llvm::FoldingSetNodeID ID;
+ ObjCTypeParamType::Profile(ID, Decl, protocols);
+ void *InsertPos = nullptr;
+ if (ObjCTypeParamType *TypeParam =
+ ObjCTypeParamTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(TypeParam, 0);
+
+ if (Canonical.isNull()) {
+ // We canonicalize to the underlying type.
+ Canonical = getCanonicalType(Decl->getUnderlyingType());
+ if (!protocols.empty()) {
+ // Apply the protocol qualifers.
+ bool hasError;
+ Canonical = applyObjCProtocolQualifiers(Canonical, protocols, hasError,
+ true/*allowOnPointerType*/);
+ assert(!hasError && "Error when apply protocol qualifier to bound type");
+ }
+ }
+
+ unsigned size = sizeof(ObjCTypeParamType);
+ size += protocols.size() * sizeof(ObjCProtocolDecl *);
+ void *mem = Allocate(size, TypeAlignment);
+ ObjCTypeParamType *newType = new (mem)
+ ObjCTypeParamType(Decl, Canonical, protocols);
+
+ Types.push_back(newType);
+ ObjCTypeParamTypes.InsertNode(newType, InsertPos);
+ return QualType(newType, 0);
+}
+
/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's
/// protocol list adopt all protocols in QT's qualified-id protocol
/// list.
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 76b495f84d5..7c0a87d0163 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -897,6 +897,23 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
+ case Type::ObjCTypeParam: {
+ const ObjCTypeParamType *Obj1 = cast<ObjCTypeParamType>(T1);
+ const ObjCTypeParamType *Obj2 = cast<ObjCTypeParamType>(T2);
+ if (!IsStructurallyEquivalent(Context, Obj1->getDecl(),
+ Obj2->getDecl()))
+ return false;
+
+ if (Obj1->getNumProtocols() != Obj2->getNumProtocols())
+ return false;
+ for (unsigned I = 0, N = Obj1->getNumProtocols(); I != N; ++I) {
+ if (!IsStructurallyEquivalent(Context,
+ Obj1->getProtocol(I),
+ Obj2->getProtocol(I)))
+ return false;
+ }
+ break;
+ }
case Type::ObjCObject: {
const ObjCObjectType *Obj1 = cast<ObjCObjectType>(T1);
const ObjCObjectType *Obj2 = cast<ObjCObjectType>(T2);
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 67d217e7a66..2f9123cc001 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -1839,6 +1839,7 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
+ case Type::ObjCTypeParam:
case Type::Atomic:
case Type::Pipe:
llvm_unreachable("type is illegal as a nested name specifier");
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 2629aecbe59..556d225612a 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -531,6 +531,18 @@ bool Type::isObjCInertUnsafeUnretainedType() const {
}
}
+ObjCTypeParamType::ObjCTypeParamType(const ObjCTypeParamDecl *D,
+ QualType can,
+ ArrayRef<ObjCProtocolDecl *> protocols)
+ : Type(ObjCTypeParam, can, can->isDependentType(),
+ can->isInstantiationDependentType(),
+ can->isVariablyModifiedType(),
+ /*ContainsUnexpandedParameterPack=*/false),
+ OTPDecl(const_cast<ObjCTypeParamDecl*>(D))
+{
+ initialize(protocols);
+}
+
ObjCObjectType::ObjCObjectType(QualType Canonical, QualType Base,
ArrayRef<QualType> typeArgs,
ArrayRef<ObjCProtocolDecl *> protocols,
@@ -879,6 +891,7 @@ public:
}
TRIVIAL_TYPE_CLASS(Typedef)
+ TRIVIAL_TYPE_CLASS(ObjCTypeParam)
QualType VisitAdjustedType(const AdjustedType *T) {
QualType originalType = recurse(T->getOriginalType());
@@ -3208,6 +3221,20 @@ void ObjCObjectTypeImpl::Profile(llvm::FoldingSetNodeID &ID) {
isKindOfTypeAsWritten());
}
+void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID,
+ const ObjCTypeParamDecl *OTPDecl,
+ ArrayRef<ObjCProtocolDecl *> protocols) {
+ ID.AddPointer(OTPDecl);
+ ID.AddInteger(protocols.size());
+ for (auto proto : protocols)
+ ID.AddPointer(proto);
+}
+
+void ObjCTypeParamType::Profile(llvm::FoldingSetNodeID &ID) {
+ Profile(ID, getDecl(),
+ llvm::makeArrayRef(qual_begin(), getNumProtocols()));
+}
+
namespace {
/// \brief The cached properties of a type.
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index b5c7271b99f..7b94a0e067b 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -388,6 +388,17 @@ TypeLoc TypeLoc::findExplicitQualifierLoc() const {
return TypeLoc();
}
+void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
+ SourceLocation Loc) {
+ setNameLoc(Loc);
+ if (!getNumProtocols()) return;
+
+ setProtocolLAngleLoc(Loc);
+ setProtocolRAngleLoc(Loc);
+ for (unsigned i = 0, e = getNumProtocols(); i != e; ++i)
+ setProtocolLoc(i, Loc);
+}
+
void ObjCObjectTypeLoc::initializeLocal(ASTContext &Context,
SourceLocation Loc) {
setHasBaseTypeAsWritten(true);
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 065a2db0914..6d5e8787c2e 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -194,6 +194,7 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::DependentName:
case Type::DependentTemplateSpecialization:
case Type::ObjCObject:
+ case Type::ObjCTypeParam:
case Type::ObjCInterface:
case Type::Atomic:
case Type::Pipe:
@@ -1368,6 +1369,28 @@ void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,
void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,
raw_ostream &OS) { }
+void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,
+ raw_ostream &OS) {
+ OS << T->getDecl()->getName();
+ if (!T->qual_empty()) {
+ bool isFirst = true;
+ OS << '<';
+ for (const auto *I : T->quals()) {
+ if (isFirst)
+ isFirst = false;
+ else
+ OS << ',';
+ OS << I->getName();
+ }
+ OS << '>';
+ }
+
+ spaceBeforePlaceHolder(OS);
+}
+
+void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,
+ raw_ostream &OS) { }
+
void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,
raw_ostream &OS) {
if (T->qual_empty() && T->isUnspecializedAsWritten() &&
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 5e3e975a778..6016c82d25a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1829,6 +1829,18 @@ llvm::DIType *CGDebugInfo::CreateType(const ObjCObjectType *Ty,
return getOrCreateType(Ty->getBaseType(), Unit);
}
+llvm::DIType *CGDebugInfo::CreateType(const ObjCTypeParamType *Ty,
+ llvm::DIFile *Unit) {
+ // Ignore protocols.
+ SourceLocation Loc = Ty->getDecl()->getLocation();
+
+ // Use Typedefs to represent ObjCTypeParamType.
+ return DBuilder.createTypedef(
+ getOrCreateType(Ty->getDecl()->getUnderlyingType(), Unit),
+ Ty->getDecl()->getName(), getOrCreateFile(Loc), getLineNumber(Loc),
+ getDeclContextDescriptor(Ty->getDecl()));
+}
+
/// \return true if Getter has the default name for the property PD.
static bool hasDefaultGetterName(const ObjCPropertyDecl *PD,
const ObjCMethodDecl *Getter) {
@@ -2481,6 +2493,8 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
return CreateType(cast<ObjCObjectPointerType>(Ty), Unit);
case Type::ObjCObject:
return CreateType(cast<ObjCObjectType>(Ty), Unit);
+ case Type::ObjCTypeParam:
+ return CreateType(cast<ObjCTypeParamType>(Ty), Unit);
case Type::ObjCInterface:
return CreateType(cast<ObjCInterfaceType>(Ty), Unit);
case Type::Builtin:
diff --git a/clang/lib/CodeGen/CGDebugInfo.h b/clang/lib/CodeGen/CGDebugInfo.h
index 486eb2a3fa4..cc9bb995f9d 100644
--- a/clang/lib/CodeGen/CGDebugInfo.h
+++ b/clang/lib/CodeGen/CGDebugInfo.h
@@ -156,6 +156,8 @@ class CGDebugInfo {
llvm::DIFile *F);
/// Get Objective-C object type.
llvm::DIType *CreateType(const ObjCObjectType *Ty, llvm::DIFile *F);
+ llvm::DIType *CreateType(const ObjCTypeParamType *Ty, llvm::DIFile *Unit);
+
llvm::DIType *CreateType(const VectorType *Ty, llvm::DIFile *F);
llvm::DIType *CreateType(const ArrayType *Ty, llvm::DIFile *F);
llvm::DIType *CreateType(const LValueReferenceType *Ty, llvm::DIFile *F);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 116079e4a7f..0b9fe29a9ce 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -1717,6 +1717,7 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::Enum:
case Type::Elaborated:
case Type::TemplateSpecialization:
+ case Type::ObjCTypeParam:
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ce371e023c9..31db29a18e3 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3876,6 +3876,7 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
case Type::ObjCObject:
case Type::ObjCInterface:
case Type::ObjCObjectPointer:
+ case Type::ObjCTypeParam:
case Type::Pipe:
llvm_unreachable("type class is never variably-modified!");
case Type::Adjusted:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 696586af9a2..9ce7f95e555 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1000,6 +1000,29 @@ static QualType applyObjCTypeArgs(Sema &S, SourceLocation loc, QualType type,
return S.Context.getObjCObjectType(type, finalTypeArgs, { }, false);
}
+QualType Sema::BuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
+ SourceLocation ProtocolLAngleLoc,
+ ArrayRef<ObjCProtocolDecl *> Protocols,
+ ArrayRef<SourceLocation> ProtocolLocs,
+ SourceLocation ProtocolRAngleLoc,
+ bool FailOnError) {
+ QualType Result = QualType(Decl->getTypeForDecl(), 0);
+ if (!Protocols.empty()) {
+ bool HasError;
+ Result = Context.applyObjCProtocolQualifiers(Result, Protocols,
+ HasError);
+ if (HasError) {
+ Diag(SourceLocation(), diag::err_invalid_protocol_qualifiers)
+ << SourceRange(ProtocolLAngleLoc, ProtocolRAngleLoc);
+ if (FailOnError) Result = QualType();
+ }
+ if (FailOnError && Result.isNull())
+ return QualType();
+ }
+
+ return Result;
+}
+
QualType Sema::BuildObjCObjectType(QualType BaseType,
SourceLocation Loc,
SourceLocation TypeArgsLAngleLoc,
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index c53505d10ab..ef3740b7177 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -699,6 +699,12 @@ public:
QualType RebuildMemberPointerType(QualType PointeeType, QualType ClassType,
SourceLocation Sigil);
+ QualType RebuildObjCTypeParamType(const ObjCTypeParamDecl *Decl,
+ SourceLocation ProtocolLAngleLoc,
+ ArrayRef<ObjCProtocolDecl *> Protocols,
+ ArrayRef<SourceLocation> ProtocolLocs,
+ SourceLocation ProtocolRAngleLoc);
+
/// \brief Build an Objective-C object type.
///
/// By default, performs semantic analysis when building the object type.
@@ -5944,6 +5950,39 @@ TreeTransform<Derived>::TransformObjCInterfaceType(TypeLocBuilder &TLB,
template<typename Derived>
QualType
+TreeTransform<Derived>::TransformObjCTypeParamType(TypeLocBuilder &TLB,
+ ObjCTypeParamTypeLoc TL) {
+ const ObjCTypeParamType *T = TL.getTypePtr();
+ ObjCTypeParamDecl *OTP = cast_or_null<ObjCTypeParamDecl>(
+ getDerived().TransformDecl(T->getDecl()->getLocation(), T->getDecl()));
+ if (!OTP)
+ return QualType();
+
+ QualType Result = TL.getType();
+ if (getDerived().AlwaysRebuild() ||
+ OTP != T->getDecl()) {
+ Result = getDerived().RebuildObjCTypeParamType(OTP,
+ TL.getProtocolLAngleLoc(),
+ llvm::makeArrayRef(TL.getTypePtr()->qual_begin(),
+ TL.getNumProtocols()),
+ TL.getProtocolLocs(),
+ TL.getProtocolRAngleLoc());
+ if (Result.isNull())
+ return QualType();
+ }
+
+ ObjCTypeParamTypeLoc NewTL = TLB.push<ObjCTypeParamTypeLoc>(Result);
+ if (TL.getNumProtocols()) {
+ NewTL.setProtocolLAngleLoc(TL.getProtocolLAngleLoc());
+ for (unsigned i = 0, n = TL.getNumProtocols(); i != n; ++i)
+ NewTL.setProtocolLoc(i, TL.getProtocolLoc(i));
+ NewTL.setProtocolRAngleLoc(TL.getProtocolRAngleLoc());
+ }
+ return Result;
+}
+
+template<typename Derived>
+QualType
TreeTransform<Derived>::TransformObjCObjectType(TypeLocBuilder &TLB,
ObjCObjectTypeLoc TL) {
// Transform base type.
@@ -11501,6 +11540,19 @@ TreeTransform<Derived>::RebuildMemberPointerType(QualType PointeeType,
}
template<typename Derived>
+QualType TreeTransform<Derived>::RebuildObjCTypeParamType(
+ const ObjCTypeParamDecl *Decl,
+ SourceLocation ProtocolLAngleLoc,
+ ArrayRef<ObjCProtocolDecl *> Protocols,
+ ArrayRef<SourceLocation> ProtocolLocs,
+ SourceLocation ProtocolRAngleLoc) {
+ return SemaRef.BuildObjCTypeParamType(Decl,
+ ProtocolLAngleLoc, Protocols,
+ ProtocolLocs, ProtocolRAngleLoc,
+ /*FailOnError=*/true);
+}
+
+template<typename Derived>
QualType TreeTransform<Derived>::RebuildObjCObjectType(
QualType BaseType,
SourceLocation Loc,
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 96a2693ade1..9b51f3dae52 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5638,6 +5638,16 @@ QualType ASTReader::readTypeRecord(unsigned Index) {
return Context.getObjCInterfaceType(ItfD->getCanonicalDecl());
}
+ case TYPE_OBJC_TYPE_PARAM: {
+ unsigned Idx = 0;
+ ObjCTypeParamDecl *Decl
+ = ReadDeclAs<ObjCTypeParamDecl>(*Loc.F, Record, Idx);
+ unsigned NumProtos = Record[Idx++];
+ SmallVector<ObjCProtocolDecl*, 4> Protos;
+ for (unsigned I = 0; I != NumProtos; ++I)
+ Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx));
+ return Context.getObjCTypeParamType(Decl, Protos);
+ }
case TYPE_OBJC_OBJECT: {
unsigned Idx = 0;
QualType Base = readType(*Loc.F, Record, Idx);
@@ -6070,6 +6080,15 @@ void TypeLocReader::VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
TL.setNameLoc(ReadSourceLocation(Record, Idx));
}
+void TypeLocReader::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+ if (TL.getNumProtocols()) {
+ TL.setProtocolLAngleLoc(ReadSourceLocation(Record, Idx));
+ TL.setProtocolRAngleLoc(ReadSourceLocation(Record, Idx));
+ }
+ for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+ TL.setProtocolLoc(i, ReadSourceLocation(Record, Idx));
+}
+
void TypeLocReader::VisitObjCObjectTypeLoc(ObjCObjectTypeLoc TL) {
TL.setHasBaseTypeAsWritten(Record[Idx++]);
TL.setTypeArgsLAngleLoc(ReadSourceLocation(Record, Idx));
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index be93ca6f4d2..0866e3a81c6 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -481,6 +481,14 @@ void ASTTypeWriter::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
Code = TYPE_OBJC_INTERFACE;
}
+void ASTTypeWriter::VisitObjCTypeParamType(const ObjCTypeParamType *T) {
+ Record.AddDeclRef(T->getDecl());
+ Record.push_back(T->getNumProtocols());
+ for (const auto *I : T->quals())
+ Record.AddDeclRef(I);
+ Code = TYPE_OBJC_TYPE_PARAM;
+}
+
void ASTTypeWriter::VisitObjCObjectType(const ObjCObjectType *T) {
Record.AddTypeRef(T->getBaseType());
Record.push_back(T->getTypeArgsAsWritten().size());
@@ -636,6 +644,14 @@ void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
Record.AddSourceLocation(TL.getNameLoc());
}
+void TypeLocWriter::VisitObjCTypeParamTypeLoc(ObjCTypeParamTypeLoc TL) {
+ if (TL.getNumProtocols()) {
+ Record.AddSourceLocation(TL.getProtocolLAngleLoc());
+ Record.AddSourceLocation(TL.getProtocolRAngleLoc());
+ }
+ for (unsigned i = 0, e = TL.getNumProtocols(); i != e; ++i)
+ Record.AddSourceLocation(TL.getProtocolLoc(i));
+}
void TypeLocWriter::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
Record.AddSourceLocation(TL.getTypeofLoc());
Record.AddSourceLocation(TL.getLParenLoc());
@@ -1137,6 +1153,7 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(TYPE_ATOMIC);
RECORD(TYPE_DECAYED);
RECORD(TYPE_ADJUSTED);
+ RECORD(TYPE_OBJC_TYPE_PARAM);
RECORD(LOCAL_REDECLARATIONS);
RECORD(DECL_TYPEDEF);
RECORD(DECL_TYPEALIAS);
OpenPOWER on IntegriCloud