[cfe-commits] r65391 - in /cfe/trunk: include/clang/AST/ExprObjC.h lib/AST/Expr.cpp lib/AST/ExprConstant.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprConstant.cpp lib/CodeGen/CGExprScalar.cpp lib/CodeGen/CodeGenFunction.h lib/CodeGen/CodeGenModule.cpp lib/CodeGen/CodeGenModule.h lib/Sema/SemaDecl.cpp lib/Sema/SemaExprObjC.cpp test/CodeGenObjC/encode-test-3.m
Chris Lattner
sabre at nondot.org
Tue Feb 24 14:18:40 PST 2009
Author: lattner
Date: Tue Feb 24 16:18:39 2009
New Revision: 65391
URL: http://llvm.org/viewvc/llvm-project?rev=65391&view=rev
Log:
first wave of fixes for @encode sema support. This is part of PR3648.
The big difference here is that (like string literal) @encode has
array type, not pointer type.
Modified:
cfe/trunk/include/clang/AST/ExprObjC.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/AST/ExprConstant.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGExprConstant.cpp
cfe/trunk/lib/CodeGen/CGExprScalar.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/CodeGenObjC/encode-test-3.m
Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Tue Feb 24 16:18:39 2009
@@ -54,7 +54,9 @@
static ObjCStringLiteral* CreateImpl(llvm::Deserializer& D, ASTContext& C);
};
-/// ObjCEncodeExpr, used for @encode in Objective-C.
+/// ObjCEncodeExpr, used for @encode in Objective-C. @encode has the same type
+/// and behavior as StringLiteral except that the string initializer is obtained
+/// from ASTContext with the encoding type as an argument.
class ObjCEncodeExpr : public Expr {
QualType EncType;
SourceLocation AtLoc, RParenLoc;
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Feb 24 16:18:39 2009
@@ -478,7 +478,8 @@
// the type looks fine, now check the expression
switch (getStmtClass()) {
- case StringLiteralClass: // C99 6.5.1p4
+ case StringLiteralClass: // C99 6.5.1p4
+ case ObjCEncodeExprClass: // @encode behaves like its string in every way.
return LV_Valid;
case ArraySubscriptExprClass: // C99 6.5.3p4 (e1[e2] == (*((e1)+(e2))))
// For vectors, make sure base is an lvalue (i.e. not a function call).
@@ -829,6 +830,7 @@
switch (getStmtClass()) {
default: break;
case StringLiteralClass:
+ case ObjCEncodeExprClass:
return true;
case CompoundLiteralExprClass: {
// This handles gcc's extension that allows global initializers like
Modified: cfe/trunk/lib/AST/ExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprConstant.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ExprConstant.cpp (original)
+++ cfe/trunk/lib/AST/ExprConstant.cpp Tue Feb 24 16:18:39 2009
@@ -153,6 +153,7 @@
APValue VisitCompoundLiteralExpr(CompoundLiteralExpr *E);
APValue VisitMemberExpr(MemberExpr *E);
APValue VisitStringLiteral(StringLiteral *E) { return APValue(E, 0); }
+ APValue VisitObjCEncodeExpr(ObjCEncodeExpr *E) { return APValue(E, 0); }
APValue VisitArraySubscriptExpr(ArraySubscriptExpr *E);
APValue VisitUnaryDeref(UnaryOperator *E);
// FIXME: Missing: __extension__, __real__, __imag__, __builtin_choose_expr
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Tue Feb 24 16:18:39 2009
@@ -148,6 +148,8 @@
return EmitPredefinedLValue(cast<PredefinedExpr>(E));
case Expr::StringLiteralClass:
return EmitStringLiteralLValue(cast<StringLiteral>(E));
+ case Expr::ObjCEncodeExprClass:
+ return EmitObjCEncodeExprLValue(cast<ObjCEncodeExpr>(E));
case Expr::CXXConditionDeclExprClass:
return EmitCXXConditionDeclLValue(cast<CXXConditionDeclExpr>(E));
@@ -668,7 +670,8 @@
default: assert(0 && "Unknown unary operator lvalue!");
case UnaryOperator::Deref:
{
- QualType T = E->getSubExpr()->getType()->getAsPointerType()->getPointeeType();
+ QualType T =
+ E->getSubExpr()->getType()->getAsPointerType()->getPointeeType();
LValue LV = LValue::MakeAddr(EmitScalarExpr(E->getSubExpr()),
ExprTy->getAsPointerType()->getPointeeType()
.getCVRQualifiers(),
@@ -697,22 +700,27 @@
return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromLiteral(E), 0);
}
+LValue CodeGenFunction::EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E) {
+ return LValue::MakeAddr(CGM.GetAddrOfConstantStringFromObjCEncode(E), 0);
+}
+
+
LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) {
std::string GlobalVarName;
switch (Type) {
- default:
- assert(0 && "Invalid type");
- case PredefinedExpr::Func:
- GlobalVarName = "__func__.";
- break;
- case PredefinedExpr::Function:
- GlobalVarName = "__FUNCTION__.";
- break;
- case PredefinedExpr::PrettyFunction:
- // FIXME:: Demangle C++ method names
- GlobalVarName = "__PRETTY_FUNCTION__.";
- break;
+ default:
+ assert(0 && "Invalid type");
+ case PredefinedExpr::Func:
+ GlobalVarName = "__func__.";
+ break;
+ case PredefinedExpr::Function:
+ GlobalVarName = "__FUNCTION__.";
+ break;
+ case PredefinedExpr::PrettyFunction:
+ // FIXME:: Demangle C++ method names
+ GlobalVarName = "__PRETTY_FUNCTION__.";
+ break;
}
std::string FunctionName;
Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Tue Feb 24 16:18:39 2009
@@ -76,7 +76,10 @@
cast<llvm::ArrayType>(ConvertType(ILE->getType()));
unsigned NumInitElements = ILE->getNumInits();
// FIXME: Check for wide strings
- if (NumInitElements > 0 && isa<StringLiteral>(ILE->getInit(0)) &&
+ // FIXME: Check for NumInitElements exactly equal to 1??
+ if (NumInitElements > 0 &&
+ (isa<StringLiteral>(ILE->getInit(0)) ||
+ isa<ObjCEncodeExpr>(ILE->getInit(0))) &&
ILE->getType()->getArrayElementTypeNoTypeQual()->isCharType())
return Visit(ILE->getInit(0));
const llvm::Type *ElemTy = AType->getElementType();
@@ -346,12 +349,26 @@
llvm::Constant *VisitStringLiteral(StringLiteral *E) {
assert(!E->getType()->isPointerType() && "Strings are always arrays");
- // Otherwise this must be a string initializing an array in a static
- // initializer. Don't emit it as the address of the string, emit the string
- // data itself as an inline array.
+ // This must be a string initializing an array in a static initializer.
+ // Don't emit it as the address of the string, emit the string data itself
+ // as an inline array.
return llvm::ConstantArray::get(CGM.GetStringForStringLiteral(E), false);
}
+ llvm::Constant *VisitObjCEncodeExpr(ObjCEncodeExpr *E) {
+ // This must be an @encode initializing an array in a static initializer.
+ // Don't emit it as the address of the string, emit the string data itself
+ // as an inline array.
+ std::string Str;
+ CGM.getContext().getObjCEncodingForType(E->getEncodedType(), Str);
+ const ConstantArrayType *CAT = cast<ConstantArrayType>(E->getType());
+
+ // Resize the string to the right size, adding zeros at the end, or
+ // truncating as needed.
+ Str.resize(CAT->getSize().getZExtValue(), '\0');
+ return llvm::ConstantArray::get(Str, false);
+ }
+
llvm::Constant *VisitUnaryExtension(const UnaryOperator *E) {
return Visit(E->getSubExpr());
}
@@ -398,6 +415,8 @@
}
case Expr::StringLiteralClass:
return CGM.GetAddrOfConstantStringFromLiteral(cast<StringLiteral>(E));
+ case Expr::ObjCEncodeExprClass:
+ return CGM.GetAddrOfConstantStringFromObjCEncode(cast<ObjCEncodeExpr>(E));
case Expr::ObjCStringLiteralClass: {
ObjCStringLiteral* SL = cast<ObjCStringLiteral>(E);
std::string S(SL->getString()->getStrData(),
Modified: cfe/trunk/lib/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprScalar.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprScalar.cpp Tue Feb 24 16:18:39 2009
@@ -165,6 +165,10 @@
return EmitLoadOfLValue(E);
}
Value *VisitStringLiteral(Expr *E) { return EmitLValue(E).getAddress(); }
+ Value *VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
+ return EmitLValue(E).getAddress();
+ }
+
Value *VisitPredefinedExpr(Expr *E) { return EmitLValue(E).getAddress(); }
Value *VisitInitListExpr(InitListExpr *E) {
@@ -329,7 +333,6 @@
Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
return CGF.EmitObjCStringLiteral(E);
}
- Value *VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
};
} // end anonymous namespace.
@@ -1385,22 +1388,6 @@
return Builder.CreateLoad(ArgPtr);
}
-Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E) {
- std::string str;
- CGF.getContext().getObjCEncodingForType(E->getEncodedType(), str);
-
- llvm::Constant *C = llvm::ConstantArray::get(str);
- C = new llvm::GlobalVariable(C->getType(), true,
- llvm::GlobalValue::InternalLinkage,
- C, ".str", &CGF.CGM.getModule());
- llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
- llvm::Constant *Zeros[] = { Zero, Zero };
- C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
-
- return C;
-}
-
-
Value *ScalarExprEmitter::VisitBlockExpr(const BlockExpr *BE) {
llvm::Constant *C = CGF.BuildBlockLiteralTmp(BE);
return C;
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Tue Feb 24 16:18:39 2009
@@ -628,6 +628,7 @@
LValue EmitVAArgExprLValue(const VAArgExpr *E);
LValue EmitDeclRefLValue(const DeclRefExpr *E);
LValue EmitStringLiteralLValue(const StringLiteral *E);
+ LValue EmitObjCEncodeExprLValue(const ObjCEncodeExpr *E);
LValue EmitPredefinedFunctionName(unsigned Type);
LValue EmitPredefinedLValue(const PredefinedExpr *E);
LValue EmitUnaryOpLValue(const UnaryOperator *E);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Feb 24 16:18:39 2009
@@ -1098,6 +1098,21 @@
return GetAddrOfConstantString(GetStringForStringLiteral(S));
}
+/// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant
+/// array for the given ObjCEncodeExpr node.
+llvm::Constant *
+CodeGenModule::GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *E) {
+ std::string Str;
+ getContext().getObjCEncodingForType(E->getEncodedType(), Str);
+
+ llvm::Constant *C = llvm::ConstantArray::get(Str);
+ C = new llvm::GlobalVariable(C->getType(), true,
+ llvm::GlobalValue::InternalLinkage,
+ C, ".str", &getModule());
+ return C;
+}
+
+
/// GenerateWritableString -- Creates storage for a string literal.
static llvm::Constant *GenerateStringLiteral(const std::string &str,
bool constant,
@@ -1107,13 +1122,10 @@
llvm::Constant *C = llvm::ConstantArray::get(str, false);
// Create a global variable for this string
- C = new llvm::GlobalVariable(C->getType(), constant,
- llvm::GlobalValue::InternalLinkage,
- C,
- GlobalName ? GlobalName : ".str",
- &CGM.getModule());
-
- return C;
+ return new llvm::GlobalVariable(C->getType(), constant,
+ llvm::GlobalValue::InternalLinkage,
+ C, GlobalName ? GlobalName : ".str",
+ &CGM.getModule());
}
/// GetAddrOfConstantString - Returns a pointer to a character array
@@ -1134,7 +1146,7 @@
ConstantStringMap.GetOrCreateValue(&str[0], &str[str.length()]);
if (Entry.getValue())
- return Entry.getValue();
+ return Entry.getValue();
// Create a global variable for this.
llvm::Constant *C = GenerateStringLiteral(str, true, *this, GlobalName);
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Feb 24 16:18:39 2009
@@ -41,6 +41,7 @@
class ObjCImplementationDecl;
class ObjCCategoryImplDecl;
class ObjCProtocolDecl;
+ class ObjCEncodeExpr;
class BlockExpr;
class Decl;
class Expr;
@@ -212,6 +213,10 @@
/// for the given string literal.
llvm::Constant *GetAddrOfConstantStringFromLiteral(const StringLiteral *S);
+ /// GetAddrOfConstantStringFromObjCEncode - Return a pointer to a constant
+ /// array for the given ObjCEncodeExpr node.
+ llvm::Constant *GetAddrOfConstantStringFromObjCEncode(const ObjCEncodeExpr *);
+
/// GetAddrOfConstantString - Returns a pointer to a character array
/// containing the literal. This contents are exactly that of the given
/// string, i.e. it will not be null terminated automatically; see
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Tue Feb 24 16:18:39 2009
@@ -1178,8 +1178,8 @@
InitListExpr *InitList = dyn_cast<InitListExpr>(Init);
if (!InitList) {
// FIXME: Handle wide strings
- if (StringLiteral *strLiteral = IsStringLiteralInit(Init, DeclType))
- return CheckStringLiteralInit(strLiteral, DeclType);
+ if (StringLiteral *StrLiteral = IsStringLiteralInit(Init, DeclType))
+ return CheckStringLiteralInit(StrLiteral, DeclType);
// C++ [dcl.init]p14:
// -- If the destination type is a (possibly cv-qualified) class
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Feb 24 16:18:39 2009
@@ -95,8 +95,19 @@
SourceLocation RParenLoc) {
QualType EncodedType = QualType::getFromOpaquePtr(ty);
- QualType Ty = Context.getPointerType(Context.CharTy);
- return new (Context) ObjCEncodeExpr(Ty, EncodedType, AtLoc, RParenLoc);
+ 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);
}
Sema::ExprResult Sema::ParseObjCSelectorExpression(Selector Sel,
Modified: cfe/trunk/test/CodeGenObjC/encode-test-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/encode-test-3.m?rev=65391&r1=65390&r2=65391&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenObjC/encode-test-3.m (original)
+++ cfe/trunk/test/CodeGenObjC/encode-test-3.m Tue Feb 24 16:18:39 2009
@@ -2,10 +2,13 @@
// RUN: grep -e "\^i" %t | count 1 &&
// RUN: grep -e "\[0i\]" %t | count 1
-int main()
-{
+int main() {
int n;
const char * inc = @encode(int[]);
const char * vla = @encode(int[n]);
}
+
+// PR3648
+int a[sizeof(@encode(int)) == 2 ? 1 : -1]; // Type is char[2]
+char (*c)[2] = &@encode(int); // @encode is an lvalue
More information about the cfe-commits
mailing list