diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/ASTContext.cpp | 24 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 16 | ||||
-rw-r--r-- | lib/Basic/SourceManager.cpp | 3 | ||||
-rw-r--r-- | lib/Basic/Targets.cpp | 15 | ||||
-rw-r--r-- | lib/CodeGen/CGBuiltin.cpp | 23 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 1 | ||||
-rw-r--r-- | lib/Frontend/RewriteBlocks.cpp | 8 | ||||
-rw-r--r-- | lib/Headers/emmintrin.h | 2 | ||||
-rw-r--r-- | lib/Parse/AttributeList.cpp | 4 | ||||
-rw-r--r-- | lib/Parse/ParseDecl.cpp | 54 | ||||
-rw-r--r-- | lib/Parse/ParseDeclCXX.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/Sema.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 10 | ||||
-rw-r--r-- | lib/Sema/SemaExprObjC.cpp | 37 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateDeduction.cpp | 31 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateExpr.cpp | 25 |
16 files changed, 157 insertions, 103 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index e6dea7cca955..fb28fd436700 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -2838,30 +2838,6 @@ QualType::GCAttrTypes ASTContext::getObjCGCAttrKind(const QualType &Ty) const { // Type Compatibility Testing //===----------------------------------------------------------------------===// -/// typesAreBlockCompatible - This routine is called when comparing two -/// block types. Types must be strictly compatible here. For example, -/// C unfortunately doesn't produce an error for the following: -/// -/// int (*emptyArgFunc)(); -/// int (*intArgList)(int) = emptyArgFunc; -/// -/// For blocks, we will produce an error for the following (similar to C++): -/// -/// int (^emptyArgBlock)(); -/// int (^intArgBlock)(int) = emptyArgBlock; -/// -/// FIXME: When the dust settles on this integration, fold this into mergeTypes. -/// -bool ASTContext::typesAreBlockCompatible(QualType lhs, QualType rhs) { - const FunctionType *lbase = lhs->getAsFunctionType(); - const FunctionType *rbase = rhs->getAsFunctionType(); - const FunctionProtoType *lproto = dyn_cast<FunctionProtoType>(lbase); - const FunctionProtoType *rproto = dyn_cast<FunctionProtoType>(rbase); - if (lproto && rproto == 0) - return false; - return !mergeTypes(lhs, rhs).isNull(); -} - /// areCompatVectorTypes - Return true if the two specified vector types are /// compatible. static bool areCompatVectorTypes(const VectorType *LHS, diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 4a53a4123d11..c12dd6747c6d 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1556,6 +1556,22 @@ ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo, RBracloc = RBrac; } +ObjCStringLiteral* ObjCStringLiteral::Clone(ASTContext &C) const { + // Clone the string literal. + StringLiteral *NewString = + String ? cast<StringLiteral>(String)->Clone(C) : 0; + + return new (C) ObjCStringLiteral(NewString, getType(), AtLoc); +} + +ObjCSelectorExpr *ObjCSelectorExpr::Clone(ASTContext &C) const { + return new (C) ObjCSelectorExpr(getType(), SelName, AtLoc, RParenLoc); +} + +ObjCProtocolExpr *ObjCProtocolExpr::Clone(ASTContext &C) const { + return new (C) ObjCProtocolExpr(getType(), Protocol, AtLoc, RParenLoc); +} + // constructor for class messages. // FIXME: clsName should be typed to ObjCInterfaceType ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 7d2d0ae17253..ed5eb46c2847 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -347,9 +347,6 @@ FileID SourceManager::createFileID(const ContentCache *File, SrcMgr::CharacteristicKind FileCharacter, unsigned PreallocatedID, unsigned Offset) { - SLocEntry NewEntry = SLocEntry::get(NextOffset, - FileInfo::get(IncludePos, File, - FileCharacter)); if (PreallocatedID) { // If we're filling in a preallocated ID, just load in the file // entry and return. diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp index 120d52543c0c..b4e32e9d9f37 100644 --- a/lib/Basic/Targets.cpp +++ b/lib/Basic/Targets.cpp @@ -244,6 +244,11 @@ static void GetDarwinLanguageOptions(LangOptions &Opts, Opts.ObjCNonFragileABI = 1; } +/// GetWindowsLanguageOptions - Set the default language options for Windows. +static void GetWindowsLanguageOptions(LangOptions &Opts, + const char *Triple) { + Opts.Microsoft = true; +} //===----------------------------------------------------------------------===// // Specific target implementations. @@ -924,9 +929,8 @@ public: WindowsX86_32TargetInfo(const std::string& triple) : X86_32TargetInfo(triple) { TLSSupported = false; - // FIXME: Fix wchar_t. - // FIXME: We should probably enable -fms-extensions by default for - // this target. + WCharType = SignedShort; + WCharWidth = WCharAlign = 16; } virtual void getTargetDefines(const LangOptions &Opts, std::vector<char> &Defines) const { @@ -938,6 +942,11 @@ public: Define(Defines, "_X86_"); Define(Defines, "__MSVCRT__"); } + + virtual void getDefaultLangOptions(LangOptions &Opts) { + X86_32TargetInfo::getDefaultLangOptions(Opts); + GetWindowsLanguageOptions(Opts, getTargetTriple()); + } }; } // end anonymous namespace diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index 3c7c5e539879..f9c44c89656e 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -782,29 +782,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); return Builder.CreateStore(Ops[1], Ops[0]); } - case X86::BI__builtin_ia32_loadlv4si: { - // load i64 - const llvm::Type *EltTy = llvm::Type::Int64Ty; - llvm::Type *PtrTy = llvm::PointerType::getUnqual(EltTy); - Ops[0] = Builder.CreateBitCast(Ops[0], PtrTy); - Ops[0] = Builder.CreateLoad(Ops[0], "load"); - - // scalar to vector: insert i64 into 2 x i64 undef - llvm::Type *VecTy = llvm::VectorType::get(EltTy, 2); - llvm::Value *Zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0); - Ops[0] = Builder.CreateInsertElement(llvm::UndefValue::get(VecTy), - Ops[0], Zero, "s2v"); - - // shuffle into zero vector. - std::vector<llvm::Constant *>Elts; - Elts.resize(2, llvm::ConstantInt::get(EltTy, 0)); - llvm::Value *ZV = ConstantVector::get(Elts); - Ops[0] = EmitShuffleVector(ZV, Ops[0], 2, 1, "loadl"); - - // bitcast to result. - return Builder.CreateBitCast(Ops[0], - llvm::VectorType::get(llvm::Type::Int32Ty, 4)); - } } } diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 01729fad5e72..6cff75daf3cb 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -310,7 +310,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI, // Filter out some microsoft extensions when trying to parse in ms-compat // mode. if (LangOpts.Microsoft) { - DefineBuiltinMacro(Buf, "_cdecl=__cdecl"); DefineBuiltinMacro(Buf, "__int8=__INT8_TYPE__"); DefineBuiltinMacro(Buf, "__int16=__INT16_TYPE__"); DefineBuiltinMacro(Buf, "__int32=__INT32_TYPE__"); diff --git a/lib/Frontend/RewriteBlocks.cpp b/lib/Frontend/RewriteBlocks.cpp index 9d73d90554ce..8393574d1e66 100644 --- a/lib/Frontend/RewriteBlocks.cpp +++ b/lib/Frontend/RewriteBlocks.cpp @@ -1011,9 +1011,7 @@ Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) { CI != E; ++CI) if (*CI) { if (BlockExpr *CBE = dyn_cast<BlockExpr>(*CI)) { - Stmt *newStmt = RewriteFunctionBody(CBE->getBody()); - if (newStmt) - *CI = newStmt; + RewriteFunctionBody(CBE->getBody()); // We've just rewritten the block body in place. // Now we snarf the rewritten text and stash it away for later use. @@ -1023,9 +1021,7 @@ Stmt *RewriteBlocks::RewriteFunctionBody(Stmt *S) { // Do the rewrite, using S.size() which contains the rewritten size. ReplaceText(CBE->getLocStart(), S.size(), Init.c_str(), Init.size()); } else { - Stmt *newStmt = RewriteFunctionBody(*CI); - if (newStmt) - *CI = newStmt; + RewriteFunctionBody(*CI); } } // Handle specific things. diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h index 23a61a0b893f..72710be6b79a 100644 --- a/lib/Headers/emmintrin.h +++ b/lib/Headers/emmintrin.h @@ -1020,7 +1020,7 @@ _mm_loadu_si128(__m128i const *p) static inline __m128i __attribute__((__always_inline__, __nodebug__)) _mm_loadl_epi64(__m128i const *p) { - return (__m128i)__builtin_ia32_loadlv4si((__v2si *)p); + return (__m128i) { *(long long*)p, 0}; } static inline __m128i __attribute__((__always_inline__, __nodebug__)) diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index 0170a0671db7..3fb6f950efc4 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -18,9 +18,9 @@ using namespace clang; AttributeList::AttributeList(IdentifierInfo *aName, SourceLocation aLoc, IdentifierInfo *pName, SourceLocation pLoc, ActionBase::ExprTy **ExprList, unsigned numArgs, - AttributeList *n) + AttributeList *n, bool declspec) : AttrName(aName), AttrLoc(aLoc), ParmName(pName), ParmLoc(pLoc), - NumArgs(numArgs), Next(n) { + NumArgs(numArgs), Next(n), DeclspecAttribute(declspec) { if (numArgs == 0) Args = 0; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 39eaf36c9574..9aab3b9e790d 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -200,18 +200,50 @@ AttributeList *Parser::ParseAttributes(SourceLocation *EndLoc) { return CurrAttr; } -/// FuzzyParseMicrosoftDeclSpec. When -fms-extensions is enabled, this -/// routine is called to skip/ignore tokens that comprise the MS declspec. -void Parser::FuzzyParseMicrosoftDeclSpec() { +/// ParseMicrosoftDeclSpec - Parse an __declspec construct +/// +/// [MS] decl-specifier: +/// __declspec ( extended-decl-modifier-seq ) +/// +/// [MS] extended-decl-modifier-seq: +/// extended-decl-modifier[opt] +/// extended-decl-modifier extended-decl-modifier-seq + +AttributeList* Parser::ParseMicrosoftDeclSpec() { assert(Tok.is(tok::kw___declspec) && "Not a declspec!"); + + AttributeList *CurrAttr = 0; ConsumeToken(); - if (Tok.is(tok::l_paren)) { - unsigned short savedParenCount = ParenCount; - do { - ConsumeAnyToken(); - } while (ParenCount > savedParenCount && Tok.isNot(tok::eof)); - } - return; + if (ExpectAndConsume(tok::l_paren, diag::err_expected_lparen_after, + "declspec")) { + SkipUntil(tok::r_paren, true); // skip until ) or ; + return CurrAttr; + } + while (Tok.is(tok::identifier) || Tok.is(tok::kw_restrict)) { + IdentifierInfo *AttrName = Tok.getIdentifierInfo(); + SourceLocation AttrNameLoc = ConsumeToken(); + if (Tok.is(tok::l_paren)) { + ConsumeParen(); + // FIXME: This doesn't parse __declspec(property(get=get_func_name)) + // correctly. + OwningExprResult ArgExpr(ParseAssignmentExpression()); + if (!ArgExpr.isInvalid()) { + ExprTy* ExprList = ArgExpr.take(); + CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, + SourceLocation(), &ExprList, 1, + CurrAttr, true); + } + if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) + SkipUntil(tok::r_paren, false); + } else { + CurrAttr = new AttributeList(AttrName, AttrNameLoc, 0, SourceLocation(), + 0, 0, CurrAttr, true); + } + } + if (ExpectAndConsume(tok::r_paren, diag::err_expected_rparen)) + SkipUntil(tok::r_paren, false); + // FIXME: Return the attributes once we have some Sema support! + return 0; } /// ParseDeclaration - Parse a full 'declaration', which consists of @@ -809,7 +841,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, case tok::kw___declspec: if (!PP.getLangOptions().Microsoft) goto DoneWithDeclSpec; - FuzzyParseMicrosoftDeclSpec(); + DS.AddAttributes(ParseMicrosoftDeclSpec()); continue; // Microsoft single token adornments. diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp index 809dc10c3ab8..0e8eebce5c7c 100644 --- a/lib/Parse/ParseDeclCXX.cpp +++ b/lib/Parse/ParseDeclCXX.cpp @@ -410,7 +410,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind, // If declspecs exist after tag, parse them. if (Tok.is(tok::kw___declspec) && PP.getLangOptions().Microsoft) - FuzzyParseMicrosoftDeclSpec(); + // FIXME: Need to do something with the attributes! + ParseMicrosoftDeclSpec(); // Parse the (optional) nested-name-specifier. CXXScopeSpec SS; diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index d3bfef67cbc8..c5582935db7f 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -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, diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index ee5132a7d8e0..da32d4ec1061 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3003,8 +3003,8 @@ QualType Sema::CheckConditionalOperands(Expr *&Cond, Expr *&LHS, Expr *&RHS, compositeType = Context.getObjCIdType(); } else if (LHSBPT || RHSBPT) { if (!sameKind - || !Context.typesAreBlockCompatible(lhptee.getUnqualifiedType(), - rhptee.getUnqualifiedType())) + || !Context.typesAreCompatible(lhptee.getUnqualifiedType(), + rhptee.getUnqualifiedType())) Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy << LHS->getSourceRange() << RHS->getSourceRange(); return QualType(); @@ -3218,7 +3218,7 @@ Sema::CheckBlockPointerTypesForAssignment(QualType lhsType, if (lhptee.getCVRQualifiers() != rhptee.getCVRQualifiers()) ConvTy = CompatiblePointerDiscardsQualifiers; - if (!Context.typesAreBlockCompatible(lhptee, rhptee)) + if (!Context.typesAreCompatible(lhptee, rhptee)) return IncompatibleBlockPointer; return ConvTy; } @@ -3978,7 +3978,7 @@ QualType Sema::CheckCompareOperands(Expr *&lex, Expr *&rex, SourceLocation Loc, QualType rpointee = rType->getAsBlockPointerType()->getPointeeType(); if (!LHSIsNull && !RHSIsNull && - !Context.typesAreBlockCompatible(lpointee, rpointee)) { + !Context.typesAreCompatible(lpointee, rpointee)) { Diag(Loc, diag::err_typecheck_comparison_of_distinct_blocks) << lType << rType << lex->getSourceRange() << rex->getSourceRange(); } @@ -5220,7 +5220,7 @@ Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, QualType BlockTy; if (!BSI->hasPrototype) - BlockTy = Context.getFunctionNoProtoType(RetTy); + BlockTy = Context.getFunctionType(RetTy, 0, 0, false, 0); else BlockTy = Context.getFunctionType(RetTy, ArgTypes.data(), ArgTypes.size(), BSI->isVariadic, 0); diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp index eabc87d7f3b8..b6cf9d8e738c 100644 --- a/lib/Sema/SemaExprObjC.cpp +++ b/lib/Sema/SemaExprObjC.cpp @@ -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, diff --git a/lib/Sema/SemaTemplateDeduction.cpp b/lib/Sema/SemaTemplateDeduction.cpp index 812b319804d7..db7e622f7f68 100644 --- a/lib/Sema/SemaTemplateDeduction.cpp +++ b/lib/Sema/SemaTemplateDeduction.cpp @@ -265,6 +265,37 @@ static bool DeduceTemplateArguments(ASTContext &Context, QualType Param, return false; } + case Type::FunctionProto: { + const FunctionProtoType *FunctionProtoArg = + dyn_cast<FunctionProtoType>(Arg); + if (!FunctionProtoArg) + return false; + + const FunctionProtoType *FunctionProtoParam = + cast<FunctionProtoType>(Param); + + // Check return types. + if (!DeduceTemplateArguments(Context, + FunctionProtoParam->getResultType(), + FunctionProtoArg->getResultType(), + Deduced)) + return false; + + if (FunctionProtoParam->getNumArgs() != FunctionProtoArg->getNumArgs()) + return false; + + for (unsigned I = 0, N = FunctionProtoParam->getNumArgs(); I != N; ++I) { + // Check argument types. + if (!DeduceTemplateArguments(Context, + FunctionProtoParam->getArgType(I), + FunctionProtoArg->getArgType(I), + Deduced)) + return false; + } + + return true; + } + default: break; } diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index 5ba42f2e5af9..fa5fdee2c13c 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -1216,15 +1216,22 @@ TemplateExprInstantiator::VisitCXXUnresolvedMemberExpr( // Objective-C Expressions //---------------------------------------------------------------------------- Sema::OwningExprResult -TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) { - assert(false && "FIXME: Template instantiations for ObjC expressions"); - return SemaRef.ExprError(); +TemplateExprInstantiator::VisitObjCStringLiteral(ObjCStringLiteral *E) { + return SemaRef.Owned(E->Clone(SemaRef.Context)); } 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 @@ -1235,14 +1242,12 @@ TemplateExprInstantiator::VisitObjCMessageExpr(ObjCMessageExpr *E) { Sema::OwningExprResult TemplateExprInstantiator::VisitObjCSelectorExpr(ObjCSelectorExpr *E) { - assert(false && "FIXME: Template instantiations for ObjC expressions"); - return SemaRef.ExprError(); + return SemaRef.Owned(E->Clone(SemaRef.Context)); } Sema::OwningExprResult TemplateExprInstantiator::VisitObjCProtocolExpr(ObjCProtocolExpr *E) { - assert(false && "FIXME: Template instantiations for ObjC expressions"); - return SemaRef.ExprError(); + return SemaRef.Owned(E->Clone(SemaRef.Context)); } Sema::OwningExprResult |