Template instantiation support for Obj-C @encode expressions.

llvm-svn: 73034
This commit is contained in:
Anders Carlsson 2009-06-07 18:45:35 +00:00
parent aaa86d07a0
commit 315d2294f8
5 changed files with 53 additions and 17 deletions

View File

@ -64,7 +64,8 @@ class ObjCEncodeExpr : public Expr {
public:
ObjCEncodeExpr(QualType T, QualType ET,
SourceLocation at, SourceLocation rp)
: Expr(ObjCEncodeExprClass, T), EncType(ET), AtLoc(at), RParenLoc(rp) {}
: Expr(ObjCEncodeExprClass, T, ET->isDependentType(),
ET->isDependentType()), EncType(ET), AtLoc(at), RParenLoc(rp) {}
explicit ObjCEncodeExpr(EmptyShell Empty) : Expr(ObjCEncodeExprClass, Empty){}

View File

@ -1696,6 +1696,10 @@ public:
virtual ExprResult ParseObjCStringLiteral(SourceLocation *AtLocs,
ExprTy **Strings,
unsigned NumStrings);
Expr *BuildObjCEncodeExpression(SourceLocation AtLoc,
QualType EncodedType,
SourceLocation RParenLoc);
virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,
SourceLocation LParenLoc,

View File

@ -92,6 +92,29 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
return new (Context) ObjCStringLiteral(S, Ty, AtLocs[0]);
}
Expr *Sema::BuildObjCEncodeExpression(SourceLocation AtLoc,
QualType EncodedType,
SourceLocation RParenLoc) {
QualType StrTy;
if (EncodedType->isDependentType())
StrTy = Context.DependentTy;
else {
std::string Str;
Context.getObjCEncodingForType(EncodedType, Str);
// The type of @encode is the same as the type of the corresponding string,
// which is an array type.
StrTy = Context.CharTy;
// A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
if (getLangOptions().CPlusPlus)
StrTy.addConst();
StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
ArrayType::Normal, 0);
}
return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
}
Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation EncodeLoc,
SourceLocation LParenLoc,
@ -99,19 +122,7 @@ Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,
SourceLocation RParenLoc) {
QualType EncodedType = QualType::getFromOpaquePtr(ty);
std::string Str;
Context.getObjCEncodingForType(EncodedType, Str);
// The type of @encode is the same as the type of the corresponding string,
// which is an array type.
QualType StrTy = Context.CharTy;
// A C++ string literal has a const-qualified element type (C++ 2.13.4p1).
if (getLangOptions().CPlusPlus)
StrTy.addConst();
StrTy = Context.getConstantArrayType(StrTy, llvm::APInt(32, Str.size()+1),
ArrayType::Normal, 0);
return new (Context) ObjCEncodeExpr(StrTy, EncodedType, AtLoc, RParenLoc);
return BuildObjCEncodeExpression(AtLoc, EncodedType, RParenLoc);
}
Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,

View File

@ -1222,9 +1222,17 @@ TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) {
}
Sema::OwningExprResult
TemplateExprInstantiator::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
assert(false && "FIXME: Template instantiations for ObjC expressions");
return SemaRef.ExprError();
TemplateExprInstantiator::VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
QualType EncodedType = SemaRef.InstantiateType(E->getEncodedType(),
TemplateArgs,
/*FIXME:*/E->getAtLoc(),
DeclarationName());
if (EncodedType.isNull())
return SemaRef.ExprError();
return SemaRef.Owned(SemaRef.BuildObjCEncodeExpression(E->getAtLoc(),
EncodedType,
E->getRParenLoc()));
}
Sema::OwningExprResult

View File

@ -0,0 +1,12 @@
// RUN: clang-cc -fsyntax-only -verify %s
// @encode expressions
template <typename T> struct Encode {
static const char *encode(T t) {
return @encode(T);
}
};
template struct Encode<int>;
template struct Encode<double>;