forked from OSchip/llvm-project
1937 lines
81 KiB
Diff
1937 lines
81 KiB
Diff
Index: include/clang/Basic/StmtNodes.td
|
|
===================================================================
|
|
--- include/clang/Basic/StmtNodes.td (revision 152265)
|
|
+++ include/clang/Basic/StmtNodes.td (working copy)
|
|
@@ -133,7 +133,7 @@
|
|
|
|
// Obj-C Expressions.
|
|
def ObjCStringLiteral : DStmt<Expr>;
|
|
-def ObjCNumericLiteral : DStmt<Expr>;
|
|
+def ObjCBoxedExpr : DStmt<Expr>;
|
|
def ObjCArrayLiteral : DStmt<Expr>;
|
|
def ObjCDictionaryLiteral : DStmt<Expr>;
|
|
def ObjCEncodeExpr : DStmt<Expr>;
|
|
Index: include/clang/Basic/DiagnosticSemaKinds.td
|
|
===================================================================
|
|
--- include/clang/Basic/DiagnosticSemaKinds.td (revision 152265)
|
|
+++ include/clang/Basic/DiagnosticSemaKinds.td (working copy)
|
|
@@ -1489,6 +1489,12 @@
|
|
"NSNumber must be available to use Objective-C literals">;
|
|
def err_invalid_nsnumber_type : Error<
|
|
"%0 is not a valid literal type for NSNumber">;
|
|
+def err_undeclared_nsstring : Error<
|
|
+ "cannot box a string value because NSString has not been declared">;
|
|
+def err_objc_illegal_boxed_expression_type : Error<
|
|
+ "illegal type %0 used in a boxed expression">;
|
|
+def err_objc_incomplete_boxed_expression_type : Error<
|
|
+ "incomplete type %0 used in a boxed expression">;
|
|
def err_undeclared_nsarray : Error<
|
|
"NSArray must be available to use Objective-C array literals">;
|
|
def err_undeclared_nsdictionary : Error<
|
|
Index: include/clang/Sema/Sema.h
|
|
===================================================================
|
|
--- include/clang/Sema/Sema.h (revision 152265)
|
|
+++ include/clang/Sema/Sema.h (working copy)
|
|
@@ -519,9 +519,21 @@
|
|
/// \brief The declaration of the Objective-C NSNumber class.
|
|
ObjCInterfaceDecl *NSNumberDecl;
|
|
|
|
+ /// \brief Pointer to NSNumber type (NSNumber *).
|
|
+ QualType NSNumberPointer;
|
|
+
|
|
/// \brief The Objective-C NSNumber methods used to create NSNumber literals.
|
|
ObjCMethodDecl *NSNumberLiteralMethods[NSAPI::NumNSNumberLiteralMethods];
|
|
|
|
+ /// \brief The declaration of the Objective-C NSString class.
|
|
+ ObjCInterfaceDecl *NSStringDecl;
|
|
+
|
|
+ /// \brief Pointer to NSString type (NSString *).
|
|
+ QualType NSStringPointer;
|
|
+
|
|
+ /// \brief The declaration of the stringWithUTF8String: method.
|
|
+ ObjCMethodDecl *StringWithUTF8StringMethod;
|
|
+
|
|
/// \brief The declaration of the Objective-C NSArray class.
|
|
ObjCInterfaceDecl *NSArrayDecl;
|
|
|
|
@@ -3708,7 +3720,7 @@
|
|
|
|
ExprResult BuildObjCStringLiteral(SourceLocation AtLoc, StringLiteral *S);
|
|
|
|
- /// BuildObjCNumericLiteral - builds an ObjCNumericLiteral AST node for the
|
|
+ /// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
|
|
/// numeric literal expression. Type of the expression will be "NSNumber *"
|
|
/// or "id" if NSNumber is unavailable.
|
|
ExprResult BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number);
|
|
@@ -3716,6 +3728,13 @@
|
|
bool Value);
|
|
ExprResult BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements);
|
|
|
|
+ // BuildObjCBoxedExpr - builds an ObjCBoxedExpr AST node for the
|
|
+ // '@' prefixed parenthesized expression. The type of the expression will
|
|
+ // either be "NSNumber *" or "NSString *" depending on the type of
|
|
+ // ValueType, which is allowed to be a built-in numeric type or
|
|
+ // "char *" or "const char *".
|
|
+ ExprResult BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr);
|
|
+
|
|
ExprResult BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
|
|
Expr *IndexExpr,
|
|
ObjCMethodDecl *getterMethod,
|
|
Index: include/clang/AST/ASTImporter.h
|
|
===================================================================
|
|
--- include/clang/AST/ASTImporter.h (revision 152265)
|
|
+++ include/clang/AST/ASTImporter.h (working copy)
|
|
@@ -271,7 +271,8 @@
|
|
|
|
/// \brief Determine whether the given types are structurally
|
|
/// equivalent.
|
|
- bool IsStructurallyEquivalent(QualType From, QualType To);
|
|
+ bool IsStructurallyEquivalent(QualType From, QualType To,
|
|
+ bool Complain = true);
|
|
};
|
|
}
|
|
|
|
Index: include/clang/AST/Type.h
|
|
===================================================================
|
|
--- include/clang/AST/Type.h (revision 152265)
|
|
+++ include/clang/AST/Type.h (working copy)
|
|
@@ -1714,9 +1714,9 @@
|
|
friend class ASTWriter;
|
|
};
|
|
|
|
-template <> inline const TypedefType *Type::getAs() const {
|
|
- return dyn_cast<TypedefType>(this);
|
|
-}
|
|
+/// \brief This will check for a TypedefType by removing any existing sugar
|
|
+/// until it reaches a TypedefType or a non-sugared type.
|
|
+template <> const TypedefType *Type::getAs() const;
|
|
|
|
// We can do canonical leaf types faster, because we don't have to
|
|
// worry about preserving child type decoration.
|
|
Index: include/clang/AST/RecursiveASTVisitor.h
|
|
===================================================================
|
|
--- include/clang/AST/RecursiveASTVisitor.h (revision 152265)
|
|
+++ include/clang/AST/RecursiveASTVisitor.h (working copy)
|
|
@@ -2106,7 +2106,7 @@
|
|
DEF_TRAVERSE_STMT(ImaginaryLiteral, { })
|
|
DEF_TRAVERSE_STMT(StringLiteral, { })
|
|
DEF_TRAVERSE_STMT(ObjCStringLiteral, { })
|
|
-DEF_TRAVERSE_STMT(ObjCNumericLiteral, { })
|
|
+DEF_TRAVERSE_STMT(ObjCBoxedExpr, { })
|
|
DEF_TRAVERSE_STMT(ObjCArrayLiteral, { })
|
|
DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, { })
|
|
|
|
Index: include/clang/AST/ExprObjC.h
|
|
===================================================================
|
|
--- include/clang/AST/ExprObjC.h (revision 152265)
|
|
+++ include/clang/AST/ExprObjC.h (working copy)
|
|
@@ -86,43 +86,45 @@
|
|
child_range children() { return child_range(); }
|
|
};
|
|
|
|
-/// ObjCNumericLiteral - used for objective-c numeric literals;
|
|
-/// as in: @42 or @true (c++/objc++) or @__yes (c/objc)
|
|
-class ObjCNumericLiteral : public Expr {
|
|
- /// Number - expression AST node for the numeric literal
|
|
- Stmt *Number;
|
|
- ObjCMethodDecl *ObjCNumericLiteralMethod;
|
|
- SourceLocation AtLoc;
|
|
+/// ObjCBoxedExpr - used for generalized expression boxing.
|
|
+/// as in: @(strdup("hello world")) or @(random())
|
|
+/// Also used for boxing non-parenthesized numeric literals;
|
|
+/// as in: @42 or @true (c++/objc++) or @__yes (c/objc).
|
|
+class ObjCBoxedExpr : public Expr {
|
|
+ Stmt *SubExpr;
|
|
+ ObjCMethodDecl *BoxingMethod;
|
|
+ SourceRange Range;
|
|
public:
|
|
- ObjCNumericLiteral(Stmt *NL, QualType T, ObjCMethodDecl *method,
|
|
- SourceLocation L)
|
|
- : Expr(ObjCNumericLiteralClass, T, VK_RValue, OK_Ordinary,
|
|
- false, false, false, false), Number(NL),
|
|
- ObjCNumericLiteralMethod(method), AtLoc(L) {}
|
|
- explicit ObjCNumericLiteral(EmptyShell Empty)
|
|
- : Expr(ObjCNumericLiteralClass, Empty) {}
|
|
+ ObjCBoxedExpr(Expr *E, QualType T, ObjCMethodDecl *method,
|
|
+ SourceRange R)
|
|
+ : Expr(ObjCBoxedExprClass, T, VK_RValue, OK_Ordinary,
|
|
+ E->isTypeDependent(), E->isValueDependent(),
|
|
+ E->isInstantiationDependent(), E->containsUnexpandedParameterPack()),
|
|
+ SubExpr(E), BoxingMethod(method), Range(R) {}
|
|
+ explicit ObjCBoxedExpr(EmptyShell Empty)
|
|
+ : Expr(ObjCBoxedExprClass, Empty) {}
|
|
|
|
- Expr *getNumber() { return cast<Expr>(Number); }
|
|
- const Expr *getNumber() const { return cast<Expr>(Number); }
|
|
+ Expr *getSubExpr() { return cast<Expr>(SubExpr); }
|
|
+ const Expr *getSubExpr() const { return cast<Expr>(SubExpr); }
|
|
|
|
- ObjCMethodDecl *getObjCNumericLiteralMethod() const {
|
|
- return ObjCNumericLiteralMethod;
|
|
+ ObjCMethodDecl *getBoxingMethod() const {
|
|
+ return BoxingMethod;
|
|
}
|
|
-
|
|
- SourceLocation getAtLoc() const { return AtLoc; }
|
|
|
|
+ SourceLocation getAtLoc() const { return Range.getBegin(); }
|
|
+
|
|
SourceRange getSourceRange() const {
|
|
- return SourceRange(AtLoc, Number->getSourceRange().getEnd());
|
|
+ return Range;
|
|
}
|
|
-
|
|
+
|
|
static bool classof(const Stmt *T) {
|
|
- return T->getStmtClass() == ObjCNumericLiteralClass;
|
|
+ return T->getStmtClass() == ObjCBoxedExprClass;
|
|
}
|
|
- static bool classof(const ObjCNumericLiteral *) { return true; }
|
|
+ static bool classof(const ObjCBoxedExpr *) { return true; }
|
|
|
|
// Iterators
|
|
- child_range children() { return child_range(&Number, &Number+1); }
|
|
-
|
|
+ child_range children() { return child_range(&SubExpr, &SubExpr+1); }
|
|
+
|
|
friend class ASTStmtReader;
|
|
};
|
|
|
|
Index: include/clang/AST/NSAPI.h
|
|
===================================================================
|
|
--- include/clang/AST/NSAPI.h (revision 152265)
|
|
+++ include/clang/AST/NSAPI.h (working copy)
|
|
@@ -125,10 +125,19 @@
|
|
|
|
/// \brief Determine the appropriate NSNumber factory method kind for a
|
|
/// literal of the given type.
|
|
- static llvm::Optional<NSNumberLiteralMethodKind>
|
|
- getNSNumberFactoryMethodKind(QualType T);
|
|
+ llvm::Optional<NSNumberLiteralMethodKind>
|
|
+ getNSNumberFactoryMethodKind(QualType T) const;
|
|
|
|
+ /// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
|
|
+ bool isObjCBOOLType(QualType T) const;
|
|
+ /// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
|
|
+ bool isObjCNSIntegerType(QualType T) const;
|
|
+ /// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
|
|
+ bool isObjCNSUIntegerType(QualType T) const;
|
|
+
|
|
private:
|
|
+ bool isObjCTypedef(QualType T, StringRef name, IdentifierInfo *&II) const;
|
|
+
|
|
ASTContext &Ctx;
|
|
|
|
mutable IdentifierInfo *ClassIds[NumClassIds];
|
|
@@ -144,6 +153,8 @@
|
|
/// \brief The Objective-C NSNumber selectors used to create NSNumber literals.
|
|
mutable Selector NSNumberClassSelectors[NumNSNumberLiteralMethods];
|
|
mutable Selector NSNumberInstanceSelectors[NumNSNumberLiteralMethods];
|
|
+
|
|
+ mutable IdentifierInfo *BOOLId, *NSIntegerId, *NSUIntegerId;
|
|
};
|
|
|
|
} // end namespace clang
|
|
Index: include/clang/Parse/Parser.h
|
|
===================================================================
|
|
--- include/clang/Parse/Parser.h (revision 152265)
|
|
+++ include/clang/Parse/Parser.h (working copy)
|
|
@@ -1497,6 +1497,7 @@
|
|
ExprResult ParseObjCBooleanLiteral(SourceLocation AtLoc, bool ArgValue);
|
|
ExprResult ParseObjCArrayLiteral(SourceLocation AtLoc);
|
|
ExprResult ParseObjCDictionaryLiteral(SourceLocation AtLoc);
|
|
+ ExprResult ParseObjCBoxedExpr(SourceLocation AtLoc);
|
|
ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
|
|
ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
|
|
ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);
|
|
Index: include/clang/Serialization/ASTBitCodes.h
|
|
===================================================================
|
|
--- include/clang/Serialization/ASTBitCodes.h (revision 152265)
|
|
+++ include/clang/Serialization/ASTBitCodes.h (working copy)
|
|
@@ -1066,7 +1066,7 @@
|
|
/// \brief An ObjCStringLiteral record.
|
|
EXPR_OBJC_STRING_LITERAL,
|
|
|
|
- EXPR_OBJC_NUMERIC_LITERAL,
|
|
+ EXPR_OBJC_BOXED_EXPRESSION,
|
|
EXPR_OBJC_ARRAY_LITERAL,
|
|
EXPR_OBJC_DICTIONARY_LITERAL,
|
|
|
|
Index: docs/LanguageExtensions.html
|
|
===================================================================
|
|
--- docs/LanguageExtensions.html (revision 152265)
|
|
+++ docs/LanguageExtensions.html (working copy)
|
|
@@ -87,7 +87,7 @@
|
|
<li><a href="#objc_instancetype">Related result types</a></li>
|
|
<li><a href="#objc_arc">Automatic reference counting</a></li>
|
|
<li><a href="#objc_fixed_enum">Enumerations with a fixed underlying type</a></li>
|
|
- </ul>
|
|
+ </ul>
|
|
</li>
|
|
<li><a href="#overloading-in-c">Function Overloading in C</a></li>
|
|
<li><a href="#complex-list-init">Initializer lists for complex numbers in C</a></li>
|
|
Index: tools/libclang/IndexBody.cpp
|
|
===================================================================
|
|
--- tools/libclang/IndexBody.cpp (revision 152265)
|
|
+++ tools/libclang/IndexBody.cpp (working copy)
|
|
@@ -90,13 +90,13 @@
|
|
return true;
|
|
}
|
|
|
|
- bool VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
- if (ObjCMethodDecl *MD = E->getObjCNumericLiteralMethod())
|
|
+ bool VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
|
+ if (ObjCMethodDecl *MD = E->getBoxingMethod())
|
|
IndexCtx.handleReference(MD, E->getLocStart(),
|
|
Parent, ParentDC, E, CXIdxEntityRef_Implicit);
|
|
return true;
|
|
}
|
|
-
|
|
+
|
|
bool VisitObjCDictionaryLiteral(ObjCDictionaryLiteral *E) {
|
|
if (ObjCMethodDecl *MD = E->getDictWithObjectsMethod())
|
|
IndexCtx.handleReference(MD, E->getLocStart(),
|
|
Index: tools/libclang/CXCursor.cpp
|
|
===================================================================
|
|
--- tools/libclang/CXCursor.cpp (revision 152265)
|
|
+++ tools/libclang/CXCursor.cpp (working copy)
|
|
@@ -229,7 +229,7 @@
|
|
case Stmt::VAArgExprClass:
|
|
case Stmt::ObjCArrayLiteralClass:
|
|
case Stmt::ObjCDictionaryLiteralClass:
|
|
- case Stmt::ObjCNumericLiteralClass:
|
|
+ case Stmt::ObjCBoxedExprClass:
|
|
case Stmt::ObjCSubscriptRefExprClass:
|
|
K = CXCursor_UnexposedExpr;
|
|
break;
|
|
Index: lib/Rewrite/RewriteModernObjC.cpp
|
|
===================================================================
|
|
--- lib/Rewrite/RewriteModernObjC.cpp (revision 152265)
|
|
+++ lib/Rewrite/RewriteModernObjC.cpp (working copy)
|
|
@@ -309,6 +309,10 @@
|
|
Stmt *RewriteAtSelector(ObjCSelectorExpr *Exp);
|
|
Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
|
|
Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
|
|
+ Stmt *RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp);
|
|
+ Stmt *RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp);
|
|
+ Stmt *RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp);
|
|
+ Stmt *RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp);
|
|
Stmt *RewriteObjCProtocolExpr(ObjCProtocolExpr *Exp);
|
|
void RewriteTryReturnStmts(Stmt *S);
|
|
void RewriteSyncReturnStmts(Stmt *S, std::string buf);
|
|
@@ -2587,6 +2591,435 @@
|
|
return cast;
|
|
}
|
|
|
|
+Stmt *RewriteModernObjC::RewriteObjCBoolLiteralExpr(ObjCBoolLiteralExpr *Exp) {
|
|
+ unsigned IntSize =
|
|
+ static_cast<unsigned>(Context->getTypeSize(Context->IntTy));
|
|
+
|
|
+ Expr *FlagExp = IntegerLiteral::Create(*Context,
|
|
+ llvm::APInt(IntSize, Exp->getValue()),
|
|
+ Context->IntTy, Exp->getLocation());
|
|
+ CastExpr *cast = NoTypeInfoCStyleCastExpr(Context, Context->ObjCBuiltinBoolTy,
|
|
+ CK_BitCast, FlagExp);
|
|
+ ParenExpr *PE = new (Context) ParenExpr(Exp->getLocation(), Exp->getExprLoc(),
|
|
+ cast);
|
|
+ ReplaceStmt(Exp, PE);
|
|
+ return PE;
|
|
+}
|
|
+
|
|
+Stmt *RewriteModernObjC::RewriteObjCBoxedExpr(ObjCBoxedExpr *Exp) {
|
|
+ // synthesize declaration of helper functions needed in this routine.
|
|
+ if (!SelGetUidFunctionDecl)
|
|
+ SynthSelGetUidFunctionDecl();
|
|
+ // use objc_msgSend() for all.
|
|
+ if (!MsgSendFunctionDecl)
|
|
+ SynthMsgSendFunctionDecl();
|
|
+ if (!GetClassFunctionDecl)
|
|
+ SynthGetClassFunctionDecl();
|
|
+
|
|
+ FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
|
|
+ SourceLocation StartLoc = Exp->getLocStart();
|
|
+ SourceLocation EndLoc = Exp->getLocEnd();
|
|
+
|
|
+ // Synthesize a call to objc_msgSend().
|
|
+ SmallVector<Expr*, 4> MsgExprs;
|
|
+ SmallVector<Expr*, 4> ClsExprs;
|
|
+ QualType argType = Context->getPointerType(Context->CharTy);
|
|
+
|
|
+ // Create a call to objc_getClass("<BoxingClass>"). It will be the 1st argument.
|
|
+ ObjCMethodDecl *BoxingMethod = Exp->getBoxingMethod();
|
|
+ ObjCInterfaceDecl *BoxingClass = BoxingMethod->getClassInterface();
|
|
+
|
|
+ IdentifierInfo *clsName = BoxingClass->getIdentifier();
|
|
+ ClsExprs.push_back(StringLiteral::Create(*Context,
|
|
+ clsName->getName(),
|
|
+ StringLiteral::Ascii, false,
|
|
+ argType, SourceLocation()));
|
|
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
|
|
+ &ClsExprs[0],
|
|
+ ClsExprs.size(),
|
|
+ StartLoc, EndLoc);
|
|
+ MsgExprs.push_back(Cls);
|
|
+
|
|
+ // Create a call to sel_registerName("<BoxingMethod>:"), etc.
|
|
+ // it will be the 2nd argument.
|
|
+ SmallVector<Expr*, 4> SelExprs;
|
|
+ SelExprs.push_back(StringLiteral::Create(*Context,
|
|
+ BoxingMethod->getSelector().getAsString(),
|
|
+ StringLiteral::Ascii, false,
|
|
+ argType, SourceLocation()));
|
|
+ CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
|
|
+ &SelExprs[0], SelExprs.size(),
|
|
+ StartLoc, EndLoc);
|
|
+ MsgExprs.push_back(SelExp);
|
|
+
|
|
+ // User provided sub-expression is the 3rd, and last, argument.
|
|
+ Expr *subExpr = Exp->getSubExpr();
|
|
+ if (ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(subExpr)) {
|
|
+ QualType type = ICE->getType();
|
|
+ const Expr *SubExpr = ICE->IgnoreParenImpCasts();
|
|
+ CastKind CK = CK_BitCast;
|
|
+ if (SubExpr->getType()->isIntegralType(*Context) && type->isBooleanType())
|
|
+ CK = CK_IntegralToBoolean;
|
|
+ subExpr = NoTypeInfoCStyleCastExpr(Context, type, CK, subExpr);
|
|
+ }
|
|
+ MsgExprs.push_back(subExpr);
|
|
+
|
|
+ SmallVector<QualType, 4> ArgTypes;
|
|
+ ArgTypes.push_back(Context->getObjCIdType());
|
|
+ ArgTypes.push_back(Context->getObjCSelType());
|
|
+ for (ObjCMethodDecl::param_iterator PI = BoxingMethod->param_begin(),
|
|
+ E = BoxingMethod->param_end(); PI != E; ++PI)
|
|
+ ArgTypes.push_back((*PI)->getType());
|
|
+
|
|
+ QualType returnType = Exp->getType();
|
|
+ // Get the type, we will need to reference it in a couple spots.
|
|
+ QualType msgSendType = MsgSendFlavor->getType();
|
|
+
|
|
+ // Create a reference to the objc_msgSend() declaration.
|
|
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
|
|
+ VK_LValue, SourceLocation());
|
|
+
|
|
+ CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
|
|
+ Context->getPointerType(Context->VoidTy),
|
|
+ CK_BitCast, DRE);
|
|
+
|
|
+ // Now do the "normal" pointer to function cast.
|
|
+ QualType castType =
|
|
+ getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
|
|
+ BoxingMethod->isVariadic());
|
|
+ castType = Context->getPointerType(castType);
|
|
+ cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
|
|
+ cast);
|
|
+
|
|
+ // Don't forget the parens to enforce the proper binding.
|
|
+ ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
|
|
+
|
|
+ const FunctionType *FT = msgSendType->getAs<FunctionType>();
|
|
+ CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
|
|
+ MsgExprs.size(),
|
|
+ FT->getResultType(), VK_RValue,
|
|
+ EndLoc);
|
|
+ ReplaceStmt(Exp, CE);
|
|
+ return CE;
|
|
+}
|
|
+
|
|
+Stmt *RewriteModernObjC::RewriteObjCArrayLiteralExpr(ObjCArrayLiteral *Exp) {
|
|
+ // synthesize declaration of helper functions needed in this routine.
|
|
+ if (!SelGetUidFunctionDecl)
|
|
+ SynthSelGetUidFunctionDecl();
|
|
+ // use objc_msgSend() for all.
|
|
+ if (!MsgSendFunctionDecl)
|
|
+ SynthMsgSendFunctionDecl();
|
|
+ if (!GetClassFunctionDecl)
|
|
+ SynthGetClassFunctionDecl();
|
|
+
|
|
+ FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
|
|
+ SourceLocation StartLoc = Exp->getLocStart();
|
|
+ SourceLocation EndLoc = Exp->getLocEnd();
|
|
+
|
|
+ // Build the expression: __NSContainer_literal(int, ...).arr
|
|
+ QualType IntQT = Context->IntTy;
|
|
+ QualType NSArrayFType =
|
|
+ getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
|
|
+ std::string NSArrayFName("__NSContainer_literal");
|
|
+ FunctionDecl *NSArrayFD = SynthBlockInitFunctionDecl(NSArrayFName);
|
|
+ DeclRefExpr *NSArrayDRE =
|
|
+ new (Context) DeclRefExpr(NSArrayFD, NSArrayFType, VK_RValue,
|
|
+ SourceLocation());
|
|
+
|
|
+ SmallVector<Expr*, 16> InitExprs;
|
|
+ unsigned NumElements = Exp->getNumElements();
|
|
+ unsigned UnsignedIntSize =
|
|
+ static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
|
|
+ Expr *count = IntegerLiteral::Create(*Context,
|
|
+ llvm::APInt(UnsignedIntSize, NumElements),
|
|
+ Context->UnsignedIntTy, SourceLocation());
|
|
+ InitExprs.push_back(count);
|
|
+ for (unsigned i = 0; i < NumElements; i++)
|
|
+ InitExprs.push_back(Exp->getElement(i));
|
|
+ Expr *NSArrayCallExpr =
|
|
+ new (Context) CallExpr(*Context, NSArrayDRE, &InitExprs[0], InitExprs.size(),
|
|
+ NSArrayFType, VK_LValue, SourceLocation());
|
|
+
|
|
+ FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
|
|
+ SourceLocation(),
|
|
+ &Context->Idents.get("arr"),
|
|
+ Context->getPointerType(Context->VoidPtrTy), 0,
|
|
+ /*BitWidth=*/0, /*Mutable=*/true,
|
|
+ /*HasInit=*/false);
|
|
+ MemberExpr *ArrayLiteralME =
|
|
+ new (Context) MemberExpr(NSArrayCallExpr, false, ARRFD,
|
|
+ SourceLocation(),
|
|
+ ARRFD->getType(), VK_LValue,
|
|
+ OK_Ordinary);
|
|
+ QualType ConstIdT = Context->getObjCIdType().withConst();
|
|
+ CStyleCastExpr * ArrayLiteralObjects =
|
|
+ NoTypeInfoCStyleCastExpr(Context,
|
|
+ Context->getPointerType(ConstIdT),
|
|
+ CK_BitCast,
|
|
+ ArrayLiteralME);
|
|
+
|
|
+ // Synthesize a call to objc_msgSend().
|
|
+ SmallVector<Expr*, 32> MsgExprs;
|
|
+ SmallVector<Expr*, 4> ClsExprs;
|
|
+ QualType argType = Context->getPointerType(Context->CharTy);
|
|
+ QualType expType = Exp->getType();
|
|
+
|
|
+ // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
|
|
+ ObjCInterfaceDecl *Class =
|
|
+ expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
|
|
+
|
|
+ IdentifierInfo *clsName = Class->getIdentifier();
|
|
+ ClsExprs.push_back(StringLiteral::Create(*Context,
|
|
+ clsName->getName(),
|
|
+ StringLiteral::Ascii, false,
|
|
+ argType, SourceLocation()));
|
|
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
|
|
+ &ClsExprs[0],
|
|
+ ClsExprs.size(),
|
|
+ StartLoc, EndLoc);
|
|
+ MsgExprs.push_back(Cls);
|
|
+
|
|
+ // Create a call to sel_registerName("arrayWithObjects:count:").
|
|
+ // it will be the 2nd argument.
|
|
+ SmallVector<Expr*, 4> SelExprs;
|
|
+ ObjCMethodDecl *ArrayMethod = Exp->getArrayWithObjectsMethod();
|
|
+ SelExprs.push_back(StringLiteral::Create(*Context,
|
|
+ ArrayMethod->getSelector().getAsString(),
|
|
+ StringLiteral::Ascii, false,
|
|
+ argType, SourceLocation()));
|
|
+ CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
|
|
+ &SelExprs[0], SelExprs.size(),
|
|
+ StartLoc, EndLoc);
|
|
+ MsgExprs.push_back(SelExp);
|
|
+
|
|
+ // (const id [])objects
|
|
+ MsgExprs.push_back(ArrayLiteralObjects);
|
|
+
|
|
+ // (NSUInteger)cnt
|
|
+ Expr *cnt = IntegerLiteral::Create(*Context,
|
|
+ llvm::APInt(UnsignedIntSize, NumElements),
|
|
+ Context->UnsignedIntTy, SourceLocation());
|
|
+ MsgExprs.push_back(cnt);
|
|
+
|
|
+
|
|
+ SmallVector<QualType, 4> ArgTypes;
|
|
+ ArgTypes.push_back(Context->getObjCIdType());
|
|
+ ArgTypes.push_back(Context->getObjCSelType());
|
|
+ for (ObjCMethodDecl::param_iterator PI = ArrayMethod->param_begin(),
|
|
+ E = ArrayMethod->param_end(); PI != E; ++PI)
|
|
+ ArgTypes.push_back((*PI)->getType());
|
|
+
|
|
+ QualType returnType = Exp->getType();
|
|
+ // Get the type, we will need to reference it in a couple spots.
|
|
+ QualType msgSendType = MsgSendFlavor->getType();
|
|
+
|
|
+ // Create a reference to the objc_msgSend() declaration.
|
|
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
|
|
+ VK_LValue, SourceLocation());
|
|
+
|
|
+ CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
|
|
+ Context->getPointerType(Context->VoidTy),
|
|
+ CK_BitCast, DRE);
|
|
+
|
|
+ // Now do the "normal" pointer to function cast.
|
|
+ QualType castType =
|
|
+ getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
|
|
+ ArrayMethod->isVariadic());
|
|
+ castType = Context->getPointerType(castType);
|
|
+ cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
|
|
+ cast);
|
|
+
|
|
+ // Don't forget the parens to enforce the proper binding.
|
|
+ ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
|
|
+
|
|
+ const FunctionType *FT = msgSendType->getAs<FunctionType>();
|
|
+ CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
|
|
+ MsgExprs.size(),
|
|
+ FT->getResultType(), VK_RValue,
|
|
+ EndLoc);
|
|
+ ReplaceStmt(Exp, CE);
|
|
+ return CE;
|
|
+}
|
|
+
|
|
+Stmt *RewriteModernObjC::RewriteObjCDictionaryLiteralExpr(ObjCDictionaryLiteral *Exp) {
|
|
+ // synthesize declaration of helper functions needed in this routine.
|
|
+ if (!SelGetUidFunctionDecl)
|
|
+ SynthSelGetUidFunctionDecl();
|
|
+ // use objc_msgSend() for all.
|
|
+ if (!MsgSendFunctionDecl)
|
|
+ SynthMsgSendFunctionDecl();
|
|
+ if (!GetClassFunctionDecl)
|
|
+ SynthGetClassFunctionDecl();
|
|
+
|
|
+ FunctionDecl *MsgSendFlavor = MsgSendFunctionDecl;
|
|
+ SourceLocation StartLoc = Exp->getLocStart();
|
|
+ SourceLocation EndLoc = Exp->getLocEnd();
|
|
+
|
|
+ // Build the expression: __NSContainer_literal(int, ...).arr
|
|
+ QualType IntQT = Context->IntTy;
|
|
+ QualType NSDictFType =
|
|
+ getSimpleFunctionType(Context->VoidTy, &IntQT, 1, true);
|
|
+ std::string NSDictFName("__NSContainer_literal");
|
|
+ FunctionDecl *NSDictFD = SynthBlockInitFunctionDecl(NSDictFName);
|
|
+ DeclRefExpr *NSDictDRE =
|
|
+ new (Context) DeclRefExpr(NSDictFD, NSDictFType, VK_RValue,
|
|
+ SourceLocation());
|
|
+
|
|
+ SmallVector<Expr*, 16> KeyExprs;
|
|
+ SmallVector<Expr*, 16> ValueExprs;
|
|
+
|
|
+ unsigned NumElements = Exp->getNumElements();
|
|
+ unsigned UnsignedIntSize =
|
|
+ static_cast<unsigned>(Context->getTypeSize(Context->UnsignedIntTy));
|
|
+ Expr *count = IntegerLiteral::Create(*Context,
|
|
+ llvm::APInt(UnsignedIntSize, NumElements),
|
|
+ Context->UnsignedIntTy, SourceLocation());
|
|
+ KeyExprs.push_back(count);
|
|
+ ValueExprs.push_back(count);
|
|
+ for (unsigned i = 0; i < NumElements; i++) {
|
|
+ ObjCDictionaryElement Element = Exp->getKeyValueElement(i);
|
|
+ KeyExprs.push_back(Element.Key);
|
|
+ ValueExprs.push_back(Element.Value);
|
|
+ }
|
|
+
|
|
+ // (const id [])objects
|
|
+ Expr *NSValueCallExpr =
|
|
+ new (Context) CallExpr(*Context, NSDictDRE, &ValueExprs[0], ValueExprs.size(),
|
|
+ NSDictFType, VK_LValue, SourceLocation());
|
|
+
|
|
+ FieldDecl *ARRFD = FieldDecl::Create(*Context, 0, SourceLocation(),
|
|
+ SourceLocation(),
|
|
+ &Context->Idents.get("arr"),
|
|
+ Context->getPointerType(Context->VoidPtrTy), 0,
|
|
+ /*BitWidth=*/0, /*Mutable=*/true,
|
|
+ /*HasInit=*/false);
|
|
+ MemberExpr *DictLiteralValueME =
|
|
+ new (Context) MemberExpr(NSValueCallExpr, false, ARRFD,
|
|
+ SourceLocation(),
|
|
+ ARRFD->getType(), VK_LValue,
|
|
+ OK_Ordinary);
|
|
+ QualType ConstIdT = Context->getObjCIdType().withConst();
|
|
+ CStyleCastExpr * DictValueObjects =
|
|
+ NoTypeInfoCStyleCastExpr(Context,
|
|
+ Context->getPointerType(ConstIdT),
|
|
+ CK_BitCast,
|
|
+ DictLiteralValueME);
|
|
+ // (const id <NSCopying> [])keys
|
|
+ Expr *NSKeyCallExpr =
|
|
+ new (Context) CallExpr(*Context, NSDictDRE, &KeyExprs[0], KeyExprs.size(),
|
|
+ NSDictFType, VK_LValue, SourceLocation());
|
|
+
|
|
+ MemberExpr *DictLiteralKeyME =
|
|
+ new (Context) MemberExpr(NSKeyCallExpr, false, ARRFD,
|
|
+ SourceLocation(),
|
|
+ ARRFD->getType(), VK_LValue,
|
|
+ OK_Ordinary);
|
|
+
|
|
+ CStyleCastExpr * DictKeyObjects =
|
|
+ NoTypeInfoCStyleCastExpr(Context,
|
|
+ Context->getPointerType(ConstIdT),
|
|
+ CK_BitCast,
|
|
+ DictLiteralKeyME);
|
|
+
|
|
+
|
|
+
|
|
+ // Synthesize a call to objc_msgSend().
|
|
+ SmallVector<Expr*, 32> MsgExprs;
|
|
+ SmallVector<Expr*, 4> ClsExprs;
|
|
+ QualType argType = Context->getPointerType(Context->CharTy);
|
|
+ QualType expType = Exp->getType();
|
|
+
|
|
+ // Create a call to objc_getClass("NSArray"). It will be th 1st argument.
|
|
+ ObjCInterfaceDecl *Class =
|
|
+ expType->getPointeeType()->getAs<ObjCObjectType>()->getInterface();
|
|
+
|
|
+ IdentifierInfo *clsName = Class->getIdentifier();
|
|
+ ClsExprs.push_back(StringLiteral::Create(*Context,
|
|
+ clsName->getName(),
|
|
+ StringLiteral::Ascii, false,
|
|
+ argType, SourceLocation()));
|
|
+ CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
|
|
+ &ClsExprs[0],
|
|
+ ClsExprs.size(),
|
|
+ StartLoc, EndLoc);
|
|
+ MsgExprs.push_back(Cls);
|
|
+
|
|
+ // Create a call to sel_registerName("arrayWithObjects:count:").
|
|
+ // it will be the 2nd argument.
|
|
+ SmallVector<Expr*, 4> SelExprs;
|
|
+ ObjCMethodDecl *DictMethod = Exp->getDictWithObjectsMethod();
|
|
+ SelExprs.push_back(StringLiteral::Create(*Context,
|
|
+ DictMethod->getSelector().getAsString(),
|
|
+ StringLiteral::Ascii, false,
|
|
+ argType, SourceLocation()));
|
|
+ CallExpr *SelExp = SynthesizeCallToFunctionDecl(SelGetUidFunctionDecl,
|
|
+ &SelExprs[0], SelExprs.size(),
|
|
+ StartLoc, EndLoc);
|
|
+ MsgExprs.push_back(SelExp);
|
|
+
|
|
+ // (const id [])objects
|
|
+ MsgExprs.push_back(DictValueObjects);
|
|
+
|
|
+ // (const id <NSCopying> [])keys
|
|
+ MsgExprs.push_back(DictKeyObjects);
|
|
+
|
|
+ // (NSUInteger)cnt
|
|
+ Expr *cnt = IntegerLiteral::Create(*Context,
|
|
+ llvm::APInt(UnsignedIntSize, NumElements),
|
|
+ Context->UnsignedIntTy, SourceLocation());
|
|
+ MsgExprs.push_back(cnt);
|
|
+
|
|
+
|
|
+ SmallVector<QualType, 8> ArgTypes;
|
|
+ ArgTypes.push_back(Context->getObjCIdType());
|
|
+ ArgTypes.push_back(Context->getObjCSelType());
|
|
+ for (ObjCMethodDecl::param_iterator PI = DictMethod->param_begin(),
|
|
+ E = DictMethod->param_end(); PI != E; ++PI) {
|
|
+ QualType T = (*PI)->getType();
|
|
+ if (const PointerType* PT = T->getAs<PointerType>()) {
|
|
+ QualType PointeeTy = PT->getPointeeType();
|
|
+ convertToUnqualifiedObjCType(PointeeTy);
|
|
+ T = Context->getPointerType(PointeeTy);
|
|
+ }
|
|
+ ArgTypes.push_back(T);
|
|
+ }
|
|
+
|
|
+ QualType returnType = Exp->getType();
|
|
+ // Get the type, we will need to reference it in a couple spots.
|
|
+ QualType msgSendType = MsgSendFlavor->getType();
|
|
+
|
|
+ // Create a reference to the objc_msgSend() declaration.
|
|
+ DeclRefExpr *DRE = new (Context) DeclRefExpr(MsgSendFlavor, msgSendType,
|
|
+ VK_LValue, SourceLocation());
|
|
+
|
|
+ CastExpr *cast = NoTypeInfoCStyleCastExpr(Context,
|
|
+ Context->getPointerType(Context->VoidTy),
|
|
+ CK_BitCast, DRE);
|
|
+
|
|
+ // Now do the "normal" pointer to function cast.
|
|
+ QualType castType =
|
|
+ getSimpleFunctionType(returnType, &ArgTypes[0], ArgTypes.size(),
|
|
+ DictMethod->isVariadic());
|
|
+ castType = Context->getPointerType(castType);
|
|
+ cast = NoTypeInfoCStyleCastExpr(Context, castType, CK_BitCast,
|
|
+ cast);
|
|
+
|
|
+ // Don't forget the parens to enforce the proper binding.
|
|
+ ParenExpr *PE = new (Context) ParenExpr(StartLoc, EndLoc, cast);
|
|
+
|
|
+ const FunctionType *FT = msgSendType->getAs<FunctionType>();
|
|
+ CallExpr *CE = new (Context) CallExpr(*Context, PE, &MsgExprs[0],
|
|
+ MsgExprs.size(),
|
|
+ FT->getResultType(), VK_RValue,
|
|
+ EndLoc);
|
|
+ ReplaceStmt(Exp, CE);
|
|
+ return CE;
|
|
+}
|
|
+
|
|
+// struct __rw_objc_super {
|
|
+// struct objc_object *object; struct objc_object *superClass;
|
|
+// };
|
|
// struct objc_super { struct objc_object *receiver; struct objc_class *super; };
|
|
QualType RewriteModernObjC::getSuperStructType() {
|
|
if (!SuperStructDecl) {
|
|
@@ -4801,6 +5234,19 @@
|
|
|
|
if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
|
|
return RewriteObjCStringLiteral(AtString);
|
|
+
|
|
+ if (ObjCBoolLiteralExpr *BoolLitExpr = dyn_cast<ObjCBoolLiteralExpr>(S))
|
|
+ return RewriteObjCBoolLiteralExpr(BoolLitExpr);
|
|
+
|
|
+ if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(S))
|
|
+ return RewriteObjCBoxedExpr(BoxedExpr);
|
|
+
|
|
+ if (ObjCArrayLiteral *ArrayLitExpr = dyn_cast<ObjCArrayLiteral>(S))
|
|
+ return RewriteObjCArrayLiteralExpr(ArrayLitExpr);
|
|
+
|
|
+ if (ObjCDictionaryLiteral *DictionaryLitExpr =
|
|
+ dyn_cast<ObjCDictionaryLiteral>(S))
|
|
+ return RewriteObjCDictionaryLiteralExpr(DictionaryLitExpr);
|
|
|
|
if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
|
|
#if 0
|
|
Index: lib/Sema/TreeTransform.h
|
|
===================================================================
|
|
--- lib/Sema/TreeTransform.h (revision 152265)
|
|
+++ lib/Sema/TreeTransform.h (working copy)
|
|
@@ -2211,6 +2211,14 @@
|
|
RParenLoc);
|
|
}
|
|
|
|
+ /// \brief Build a new Objective-C boxed expression.
|
|
+ ///
|
|
+ /// By default, performs semantic analysis to build the new expression.
|
|
+ /// Subclasses may override this routine to provide different behavior.
|
|
+ ExprResult RebuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
|
|
+ return getSema().BuildObjCBoxedExpr(SR, ValueExpr);
|
|
+ }
|
|
+
|
|
/// \brief Build a new Objective-C array literal.
|
|
///
|
|
/// By default, performs semantic analysis to build the new expression.
|
|
@@ -8298,8 +8306,16 @@
|
|
|
|
template<typename Derived>
|
|
ExprResult
|
|
-TreeTransform<Derived>::TransformObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
- return SemaRef.MaybeBindToTemporary(E);
|
|
+TreeTransform<Derived>::TransformObjCBoxedExpr(ObjCBoxedExpr *E) {
|
|
+ ExprResult SubExpr = getDerived().TransformExpr(E->getSubExpr());
|
|
+ if (SubExpr.isInvalid())
|
|
+ return ExprError();
|
|
+
|
|
+ if (!getDerived().AlwaysRebuild() &&
|
|
+ SubExpr.get() == E->getSubExpr())
|
|
+ return SemaRef.Owned(E);
|
|
+
|
|
+ return getDerived().RebuildObjCBoxedExpr(E->getSourceRange(), SubExpr.get());
|
|
}
|
|
|
|
template<typename Derived>
|
|
Index: lib/Sema/SemaExprCXX.cpp
|
|
===================================================================
|
|
--- lib/Sema/SemaExprCXX.cpp (revision 152265)
|
|
+++ lib/Sema/SemaExprCXX.cpp (working copy)
|
|
@@ -4469,8 +4469,8 @@
|
|
ObjCMethodDecl *D = 0;
|
|
if (ObjCMessageExpr *Send = dyn_cast<ObjCMessageExpr>(E)) {
|
|
D = Send->getMethodDecl();
|
|
- } else if (ObjCNumericLiteral *NumLit = dyn_cast<ObjCNumericLiteral>(E)) {
|
|
- D = NumLit->getObjCNumericLiteralMethod();
|
|
+ } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast<ObjCBoxedExpr>(E)) {
|
|
+ D = BoxedExpr->getBoxingMethod();
|
|
} else if (ObjCArrayLiteral *ArrayLit = dyn_cast<ObjCArrayLiteral>(E)) {
|
|
D = ArrayLit->getArrayWithObjectsMethod();
|
|
} else if (ObjCDictionaryLiteral *DictLit
|
|
@@ -4529,6 +4529,17 @@
|
|
if (RD->isInvalidDecl() || RD->isDependentContext())
|
|
return Owned(E);
|
|
|
|
+ if (!RD->getDefinition()) {
|
|
+ if (RD->hasExternalLexicalStorage()) {
|
|
+ ExternalASTSource *ext_source = RD->getASTContext().getExternalSource();
|
|
+ if (ext_source)
|
|
+ ext_source->CompleteType(RD);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (!RD->getDefinition())
|
|
+ return Owned(E);
|
|
+
|
|
bool IsDecltype = ExprEvalContexts.back().IsDecltype;
|
|
CXXDestructorDecl *Destructor = IsDecltype ? 0 : LookupDestructor(RD);
|
|
|
|
Index: lib/Sema/SemaExceptionSpec.cpp
|
|
===================================================================
|
|
--- lib/Sema/SemaExceptionSpec.cpp (revision 152265)
|
|
+++ lib/Sema/SemaExceptionSpec.cpp (working copy)
|
|
@@ -726,4 +726,4 @@
|
|
New->getLocation());
|
|
}
|
|
|
|
-} // end namespace clang
|
|
+}
|
|
Index: lib/Sema/SemaChecking.cpp
|
|
===================================================================
|
|
--- lib/Sema/SemaChecking.cpp (revision 152265)
|
|
+++ lib/Sema/SemaChecking.cpp (working copy)
|
|
@@ -4416,12 +4416,16 @@
|
|
|
|
// Don't consider sizes resulting from macro expansions or template argument
|
|
// substitution to form C89 tail-padded arrays.
|
|
- ConstantArrayTypeLoc TL =
|
|
- cast<ConstantArrayTypeLoc>(FD->getTypeSourceInfo()->getTypeLoc());
|
|
- const Expr *SizeExpr = dyn_cast<IntegerLiteral>(TL.getSizeExpr());
|
|
- if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
|
|
- return false;
|
|
|
|
+ TypeSourceInfo *TInfo = FD->getTypeSourceInfo();
|
|
+ if (TInfo) {
|
|
+ ConstantArrayTypeLoc TL =
|
|
+ cast<ConstantArrayTypeLoc>(TInfo->getTypeLoc());
|
|
+ const Expr *SizeExpr = dyn_cast<IntegerLiteral>(TL.getSizeExpr());
|
|
+ if (!SizeExpr || SizeExpr->getExprLoc().isMacroID())
|
|
+ return false;
|
|
+ }
|
|
+
|
|
const RecordDecl *RD = dyn_cast<RecordDecl>(FD->getDeclContext());
|
|
if (!RD) return false;
|
|
if (RD->isUnion()) return false;
|
|
Index: lib/Sema/SemaExprObjC.cpp
|
|
===================================================================
|
|
--- lib/Sema/SemaExprObjC.cpp (revision 152265)
|
|
+++ lib/Sema/SemaExprObjC.cpp (working copy)
|
|
@@ -111,7 +111,7 @@
|
|
Ty = Context.getObjCIdType();
|
|
}
|
|
} else {
|
|
- IdentifierInfo *NSIdent = &Context.Idents.get("NSString");
|
|
+ IdentifierInfo *NSIdent = NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
|
|
NamedDecl *IF = LookupSingleName(TUScope, NSIdent, AtLoc,
|
|
LookupOrdinaryName);
|
|
if (ObjCInterfaceDecl *StrIF = dyn_cast_or_null<ObjCInterfaceDecl>(IF)) {
|
|
@@ -143,41 +143,70 @@
|
|
/// \brief Retrieve the NSNumber factory method that should be used to create
|
|
/// an Objective-C literal for the given type.
|
|
static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
|
|
- QualType T, QualType ReturnType,
|
|
- SourceRange Range) {
|
|
+ QualType NumberType,
|
|
+ bool isLiteral = false,
|
|
+ SourceRange R = SourceRange()) {
|
|
llvm::Optional<NSAPI::NSNumberLiteralMethodKind> Kind
|
|
- = S.NSAPIObj->getNSNumberFactoryMethodKind(T);
|
|
+ = S.NSAPIObj->getNSNumberFactoryMethodKind(NumberType);
|
|
|
|
if (!Kind) {
|
|
- S.Diag(Loc, diag::err_invalid_nsnumber_type)
|
|
- << T << Range;
|
|
+ if (isLiteral) {
|
|
+ S.Diag(Loc, diag::err_invalid_nsnumber_type)
|
|
+ << NumberType << R;
|
|
+ }
|
|
return 0;
|
|
}
|
|
-
|
|
+
|
|
// If we already looked up this method, we're done.
|
|
if (S.NSNumberLiteralMethods[*Kind])
|
|
return S.NSNumberLiteralMethods[*Kind];
|
|
|
|
Selector Sel = S.NSAPIObj->getNSNumberLiteralSelector(*Kind,
|
|
/*Instance=*/false);
|
|
+
|
|
+ ASTContext &CX = S.Context;
|
|
|
|
+ // Look up the NSNumber class, if we haven't done so already. It's cached
|
|
+ // in the Sema instance.
|
|
+ if (!S.NSNumberDecl) {
|
|
+ IdentifierInfo *NSNumberId = S.NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber);
|
|
+ if (S.getLangOptions().DebuggerObjCLiteral) {
|
|
+ // Create a stub definition of NSNumber.
|
|
+ S.NSNumberDecl = ObjCInterfaceDecl::Create (CX,
|
|
+ CX.getTranslationUnitDecl(),
|
|
+ SourceLocation(), NSNumberId,
|
|
+ 0, SourceLocation());
|
|
+ } else {
|
|
+ // Otherwise, require a declaration of NSNumber.
|
|
+ NamedDecl *IF = S.LookupSingleName(S.TUScope, NSNumberId,
|
|
+ Loc, Sema::LookupOrdinaryName);
|
|
+ S.NSNumberDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
|
|
+ if (!S.NSNumberDecl || !S.NSNumberDecl->hasDefinition()) {
|
|
+ S.Diag(Loc, diag::err_undeclared_nsnumber);
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // generate the pointer to NSNumber type.
|
|
+ S.NSNumberPointer = CX.getObjCObjectPointerType(CX.getObjCInterfaceType(S.NSNumberDecl));
|
|
+ }
|
|
+
|
|
// Look for the appropriate method within NSNumber.
|
|
ObjCMethodDecl *Method = S.NSNumberDecl->lookupClassMethod(Sel);;
|
|
if (!Method && S.getLangOptions().DebuggerObjCLiteral) {
|
|
+ // create a stub definition this NSNumber factory method.
|
|
TypeSourceInfo *ResultTInfo = 0;
|
|
- Method = ObjCMethodDecl::Create(S.Context, SourceLocation(), SourceLocation(), Sel,
|
|
- ReturnType,
|
|
- ResultTInfo,
|
|
- S.Context.getTranslationUnitDecl(),
|
|
- false /*Instance*/, false/*isVariadic*/,
|
|
- /*isSynthesized=*/false,
|
|
- /*isImplicitlyDeclared=*/true, /*isDefined=*/false,
|
|
- ObjCMethodDecl::Required,
|
|
- false);
|
|
+ Method = ObjCMethodDecl::Create(CX, SourceLocation(), SourceLocation(), Sel,
|
|
+ S.NSNumberPointer, ResultTInfo, S.NSNumberDecl,
|
|
+ /*isInstance=*/false, /*isVariadic=*/false,
|
|
+ /*isSynthesized=*/false,
|
|
+ /*isImplicitlyDeclared=*/true,
|
|
+ /*isDefined=*/false, ObjCMethodDecl::Required,
|
|
+ /*HasRelatedResultType=*/false);
|
|
ParmVarDecl *value = ParmVarDecl::Create(S.Context, Method,
|
|
SourceLocation(), SourceLocation(),
|
|
- &S.Context.Idents.get("value"),
|
|
- T, /*TInfo=*/0, SC_None, SC_None, 0);
|
|
+ &CX.Idents.get("value"),
|
|
+ NumberType, /*TInfo=*/0, SC_None, SC_None, 0);
|
|
Method->setMethodParams(S.Context, value, ArrayRef<SourceLocation>());
|
|
}
|
|
|
|
@@ -202,29 +231,9 @@
|
|
return Method;
|
|
}
|
|
|
|
-/// BuildObjCNumericLiteral - builds an ObjCNumericLiteral AST node for the
|
|
-/// numeric literal expression. Type of the expression will be "NSNumber *"
|
|
-/// or "id" if NSNumber is unavailable.
|
|
+/// BuildObjCNumericLiteral - builds an ObjCBoxedExpr AST node for the
|
|
+/// numeric literal expression. Type of the expression will be "NSNumber *".
|
|
ExprResult Sema::BuildObjCNumericLiteral(SourceLocation AtLoc, Expr *Number) {
|
|
- // Look up the NSNumber class, if we haven't done so already.
|
|
- if (!NSNumberDecl) {
|
|
- NamedDecl *IF = LookupSingleName(TUScope,
|
|
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber),
|
|
- AtLoc, LookupOrdinaryName);
|
|
- NSNumberDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
|
|
-
|
|
- if (!NSNumberDecl && getLangOptions().DebuggerObjCLiteral)
|
|
- NSNumberDecl = ObjCInterfaceDecl::Create (Context,
|
|
- Context.getTranslationUnitDecl(),
|
|
- SourceLocation(),
|
|
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSNumber),
|
|
- 0, SourceLocation());
|
|
- if (!NSNumberDecl) {
|
|
- Diag(AtLoc, diag::err_undeclared_nsnumber);
|
|
- return ExprError();
|
|
- }
|
|
- }
|
|
-
|
|
// Determine the type of the literal.
|
|
QualType NumberType = Number->getType();
|
|
if (CharacterLiteral *Char = dyn_cast<CharacterLiteral>(Number)) {
|
|
@@ -249,29 +258,29 @@
|
|
}
|
|
}
|
|
|
|
- ObjCMethodDecl *Method = 0;
|
|
// Look for the appropriate method within NSNumber.
|
|
// Construct the literal.
|
|
- QualType Ty
|
|
- = Context.getObjCObjectPointerType(
|
|
- Context.getObjCInterfaceType(NSNumberDecl));
|
|
- Method = getNSNumberFactoryMethod(*this, AtLoc,
|
|
- NumberType, Ty,
|
|
- Number->getSourceRange());
|
|
-
|
|
+ SourceRange NR(Number->getSourceRange());
|
|
+ ObjCMethodDecl *Method = getNSNumberFactoryMethod(*this, AtLoc, NumberType,
|
|
+ true, NR);
|
|
if (!Method)
|
|
return ExprError();
|
|
|
|
// Convert the number to the type that the parameter expects.
|
|
- QualType ElementT = Method->param_begin()[0]->getType();
|
|
- ExprResult ConvertedNumber = PerformImplicitConversion(Number, ElementT,
|
|
- AA_Sending);
|
|
+ ParmVarDecl *ParamDecl = Method->param_begin()[0];
|
|
+ InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
|
|
+ ParamDecl);
|
|
+ ExprResult ConvertedNumber = PerformCopyInitialization(Entity,
|
|
+ SourceLocation(),
|
|
+ Owned(Number));
|
|
if (ConvertedNumber.isInvalid())
|
|
return ExprError();
|
|
Number = ConvertedNumber.get();
|
|
|
|
+ // Use the effective source range of the literal, including the leading '@'.
|
|
return MaybeBindToTemporary(
|
|
- new (Context) ObjCNumericLiteral(Number, Ty, Method, AtLoc));
|
|
+ new (Context) ObjCBoxedExpr(Number, NSNumberPointer, Method,
|
|
+ SourceRange(AtLoc, NR.getEnd())));
|
|
}
|
|
|
|
ExprResult Sema::ActOnObjCBoolLiteral(SourceLocation AtLoc,
|
|
@@ -385,6 +394,154 @@
|
|
Element->getLocStart(), Element);
|
|
}
|
|
|
|
+ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
|
|
+ if (ValueExpr->isTypeDependent()) {
|
|
+ ObjCBoxedExpr *BoxedExpr =
|
|
+ new (Context) ObjCBoxedExpr(ValueExpr, Context.DependentTy, NULL, SR);
|
|
+ return Owned(BoxedExpr);
|
|
+ }
|
|
+ ObjCMethodDecl *BoxingMethod = NULL;
|
|
+ QualType BoxedType;
|
|
+ // Convert the expression to an RValue, so we can check for pointer types...
|
|
+ ExprResult RValue = DefaultFunctionArrayLvalueConversion(ValueExpr);
|
|
+ if (RValue.isInvalid()) {
|
|
+ return ExprError();
|
|
+ }
|
|
+ ValueExpr = RValue.get();
|
|
+ QualType ValueType(ValueExpr->getType());
|
|
+ if (const PointerType *PT = ValueType->getAs<PointerType>()) {
|
|
+ QualType PointeeType = PT->getPointeeType();
|
|
+ if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
|
|
+ IdentifierInfo *NSStringId =
|
|
+ NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
|
|
+ if (getLangOptions().DebuggerObjCLiteral) {
|
|
+ // Support boxed expressions in the debugger w/o NSString declaration.
|
|
+ NSStringDecl = ObjCInterfaceDecl::Create(Context,
|
|
+ Context.getTranslationUnitDecl(),
|
|
+ SourceLocation(), NSStringId,
|
|
+ 0, SourceLocation());
|
|
+ }
|
|
+ else {
|
|
+ NamedDecl *Decl = LookupSingleName(TUScope, NSStringId,
|
|
+ SR.getBegin(), LookupOrdinaryName);
|
|
+ NSStringDecl = dyn_cast_or_null<ObjCInterfaceDecl>(Decl);
|
|
+
|
|
+ if (!NSStringDecl || !NSStringDecl->hasDefinition()) {
|
|
+ Diag(SR.getBegin(), diag::err_undeclared_nsstring);
|
|
+ return ExprError();
|
|
+ }
|
|
+ }
|
|
+ assert(NSStringDecl && "NSStringDecl should not be NULL");
|
|
+ NSStringPointer =
|
|
+ Context.getObjCObjectPointerType(Context.getObjCInterfaceType(NSStringDecl));
|
|
+
|
|
+ if (!StringWithUTF8StringMethod) {
|
|
+ IdentifierInfo *II = &Context.Idents.get("stringWithUTF8String");
|
|
+ Selector stringWithUTF8String = Context.Selectors.getUnarySelector(II);
|
|
+
|
|
+ // Look for the appropriate method within NSString.
|
|
+ StringWithUTF8StringMethod = NSStringDecl->lookupClassMethod(stringWithUTF8String);
|
|
+ if (!StringWithUTF8StringMethod && getLangOptions().DebuggerObjCLiteral) {
|
|
+ // Debugger needs to work even if NSString hasn't been defined.
|
|
+ TypeSourceInfo *ResultTInfo = 0;
|
|
+ ObjCMethodDecl *M =
|
|
+ ObjCMethodDecl::Create(Context, SourceLocation(), SourceLocation(),
|
|
+ stringWithUTF8String, NSStringPointer,
|
|
+ ResultTInfo, NSStringDecl,
|
|
+ /*isInstance=*/false, /*isVariadic=*/false,
|
|
+ /*isSynthesized=*/false,
|
|
+ /*isImplicitlyDeclared=*/true,
|
|
+ /*isDefined=*/false,
|
|
+ ObjCMethodDecl::Required,
|
|
+ /*HasRelatedResultType=*/false);
|
|
+ ParmVarDecl *value =
|
|
+ ParmVarDecl::Create(Context, M,
|
|
+ SourceLocation(), SourceLocation(),
|
|
+ &Context.Idents.get("value"),
|
|
+ Context.getPointerType(Context.CharTy.withConst()),
|
|
+ /*TInfo=*/0,
|
|
+ SC_None, SC_None, 0);
|
|
+ M->setMethodParams(Context, value, ArrayRef<SourceLocation>());
|
|
+ StringWithUTF8StringMethod = M;
|
|
+ }
|
|
+ assert(StringWithUTF8StringMethod &&
|
|
+ "StringWithUTF8StringMethod should not be NULL");
|
|
+ }
|
|
+
|
|
+ BoxingMethod = StringWithUTF8StringMethod;
|
|
+ BoxedType = NSStringPointer;
|
|
+ }
|
|
+ } else if (ValueType->isBuiltinType()) {
|
|
+ // The other types we support are numeric, char and BOOL/bool. We could also
|
|
+ // provide limited support for structure types, such as NSRange, NSRect, and
|
|
+ // NSSize. See NSValue (NSValueGeometryExtensions) in <Foundation/NSGeometry.h>
|
|
+ // for more details.
|
|
+
|
|
+ // Check for a top-level character literal.
|
|
+ if (const CharacterLiteral *Char =
|
|
+ dyn_cast<CharacterLiteral>(ValueExpr->IgnoreParens())) {
|
|
+ // In C, character literals have type 'int'. That's not the type we want
|
|
+ // to use to determine the Objective-c literal kind.
|
|
+ switch (Char->getKind()) {
|
|
+ case CharacterLiteral::Ascii:
|
|
+ ValueType = Context.CharTy;
|
|
+ break;
|
|
+
|
|
+ case CharacterLiteral::Wide:
|
|
+ ValueType = Context.getWCharType();
|
|
+ break;
|
|
+
|
|
+ case CharacterLiteral::UTF16:
|
|
+ ValueType = Context.Char16Ty;
|
|
+ break;
|
|
+
|
|
+ case CharacterLiteral::UTF32:
|
|
+ ValueType = Context.Char32Ty;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ // FIXME: Do I need to do anything special with BoolTy expressions?
|
|
+
|
|
+ // Look for the appropriate method within NSNumber.
|
|
+ BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(), ValueType);
|
|
+ BoxedType = NSNumberPointer;
|
|
+
|
|
+ } else if (const EnumType *ET = ValueType->getAs<EnumType>()) {
|
|
+ if (!ET->getDecl()->isComplete()) {
|
|
+ Diag(SR.getBegin(), diag::err_objc_incomplete_boxed_expression_type)
|
|
+ << ValueType << ValueExpr->getSourceRange();
|
|
+ return ExprError();
|
|
+ }
|
|
+
|
|
+ BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(),
|
|
+ ET->getDecl()->getIntegerType());
|
|
+ BoxedType = NSNumberPointer;
|
|
+ }
|
|
+
|
|
+ if (!BoxingMethod) {
|
|
+ Diag(SR.getBegin(), diag::err_objc_illegal_boxed_expression_type)
|
|
+ << ValueType << ValueExpr->getSourceRange();
|
|
+ return ExprError();
|
|
+ }
|
|
+
|
|
+ // Convert the expression to the type that the parameter requires.
|
|
+ ParmVarDecl *ParamDecl = BoxingMethod->param_begin()[0];
|
|
+ InitializedEntity Entity = InitializedEntity::InitializeParameter(Context,
|
|
+ ParamDecl);
|
|
+ ExprResult ConvertedValueExpr = PerformCopyInitialization(Entity,
|
|
+ SourceLocation(),
|
|
+ Owned(ValueExpr));
|
|
+ if (ConvertedValueExpr.isInvalid())
|
|
+ return ExprError();
|
|
+ ValueExpr = ConvertedValueExpr.get();
|
|
+
|
|
+ ObjCBoxedExpr *BoxedExpr =
|
|
+ new (Context) ObjCBoxedExpr(ValueExpr, BoxedType,
|
|
+ BoxingMethod, SR);
|
|
+ return MaybeBindToTemporary(BoxedExpr);
|
|
+}
|
|
+
|
|
ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
|
|
Expr *IndexExpr,
|
|
ObjCMethodDecl *getterMethod,
|
|
@@ -417,21 +574,22 @@
|
|
ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
|
|
// Look up the NSArray class, if we haven't done so already.
|
|
if (!NSArrayDecl) {
|
|
- NamedDecl *IF = LookupSingleName(TUScope,
|
|
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
|
|
- SR.getBegin(),
|
|
- LookupOrdinaryName);
|
|
- NSArrayDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
|
|
- if (!NSArrayDecl && getLangOptions().DebuggerObjCLiteral)
|
|
+ if (getLangOptions().DebuggerObjCLiteral) {
|
|
NSArrayDecl = ObjCInterfaceDecl::Create (Context,
|
|
Context.getTranslationUnitDecl(),
|
|
SourceLocation(),
|
|
NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
|
|
0, SourceLocation());
|
|
-
|
|
- if (!NSArrayDecl) {
|
|
- Diag(SR.getBegin(), diag::err_undeclared_nsarray);
|
|
- return ExprError();
|
|
+ } else {
|
|
+ NamedDecl *IF = LookupSingleName(TUScope,
|
|
+ NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
|
|
+ SR.getBegin(),
|
|
+ LookupOrdinaryName);
|
|
+ NSArrayDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
|
|
+ if (!NSArrayDecl) {
|
|
+ Diag(SR.getBegin(), diag::err_undeclared_nsarray);
|
|
+ return ExprError();
|
|
+ }
|
|
}
|
|
}
|
|
|
|
Index: lib/Sema/Sema.cpp
|
|
===================================================================
|
|
--- lib/Sema/Sema.cpp (revision 152265)
|
|
+++ lib/Sema/Sema.cpp (working copy)
|
|
@@ -90,7 +90,9 @@
|
|
PackContext(0), MSStructPragmaOn(false), VisContext(0),
|
|
ExprNeedsCleanups(false), LateTemplateParser(0), OpaqueParser(0),
|
|
IdResolver(pp), StdInitializerList(0), CXXTypeInfoDecl(0), MSVCGuidDecl(0),
|
|
- NSNumberDecl(0), NSArrayDecl(0), ArrayWithObjectsMethod(0),
|
|
+ NSNumberDecl(0),
|
|
+ NSStringDecl(0), StringWithUTF8StringMethod(0),
|
|
+ NSArrayDecl(0), ArrayWithObjectsMethod(0),
|
|
NSDictionaryDecl(0), DictionaryWithObjectsMethod(0),
|
|
GlobalNewDeleteDeclared(false),
|
|
ObjCShouldCallSuperDealloc(false),
|
|
Index: lib/AST/DeclObjC.cpp
|
|
===================================================================
|
|
--- lib/AST/DeclObjC.cpp (revision 152265)
|
|
+++ lib/AST/DeclObjC.cpp (working copy)
|
|
@@ -330,6 +330,10 @@
|
|
LoadExternalDefinition();
|
|
|
|
while (ClassDecl != NULL) {
|
|
+ // FIXME: Should make sure no callers ever do this.
|
|
+ if (!ClassDecl->hasDefinition())
|
|
+ return 0;
|
|
+
|
|
if ((MethodDecl = ClassDecl->getMethod(Sel, isInstance)))
|
|
return MethodDecl;
|
|
|
|
Index: lib/AST/ASTImporter.cpp
|
|
===================================================================
|
|
--- lib/AST/ASTImporter.cpp (revision 152265)
|
|
+++ lib/AST/ASTImporter.cpp (working copy)
|
|
@@ -119,7 +119,8 @@
|
|
bool ImportTemplateArguments(const TemplateArgument *FromArgs,
|
|
unsigned NumFromArgs,
|
|
SmallVectorImpl<TemplateArgument> &ToArgs);
|
|
- bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord);
|
|
+ bool IsStructuralMatch(RecordDecl *FromRecord, RecordDecl *ToRecord,
|
|
+ bool Complain = true);
|
|
bool IsStructuralMatch(EnumDecl *FromEnum, EnumDecl *ToRecord);
|
|
bool IsStructuralMatch(ClassTemplateDecl *From, ClassTemplateDecl *To);
|
|
Decl *VisitDecl(Decl *D);
|
|
@@ -201,12 +202,16 @@
|
|
/// \brief Whether we're being strict about the spelling of types when
|
|
/// unifying two types.
|
|
bool StrictTypeSpelling;
|
|
-
|
|
+
|
|
+ /// \brief Whether to complain about failures.
|
|
+ bool Complain;
|
|
+
|
|
StructuralEquivalenceContext(ASTContext &C1, ASTContext &C2,
|
|
llvm::DenseSet<std::pair<Decl *, Decl *> > &NonEquivalentDecls,
|
|
- bool StrictTypeSpelling = false)
|
|
+ bool StrictTypeSpelling = false,
|
|
+ bool Complain = true)
|
|
: C1(C1), C2(C2), NonEquivalentDecls(NonEquivalentDecls),
|
|
- StrictTypeSpelling(StrictTypeSpelling) { }
|
|
+ StrictTypeSpelling(StrictTypeSpelling), Complain(Complain) { }
|
|
|
|
/// \brief Determine whether the two declarations are structurally
|
|
/// equivalent.
|
|
@@ -223,10 +228,16 @@
|
|
|
|
public:
|
|
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID) {
|
|
+ if (!Complain)
|
|
+ return DiagnosticBuilder(DiagnosticBuilder::Suppress);
|
|
+
|
|
return C1.getDiagnostics().Report(Loc, DiagID);
|
|
}
|
|
|
|
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID) {
|
|
+ if (!Complain)
|
|
+ return DiagnosticBuilder(DiagnosticBuilder::Suppress);
|
|
+
|
|
return C2.getDiagnostics().Report(Loc, DiagID);
|
|
}
|
|
};
|
|
@@ -2050,10 +2061,12 @@
|
|
}
|
|
|
|
bool ASTNodeImporter::IsStructuralMatch(RecordDecl *FromRecord,
|
|
- RecordDecl *ToRecord) {
|
|
+ RecordDecl *ToRecord,
|
|
+ bool Complain) {
|
|
StructuralEquivalenceContext Ctx(Importer.getFromContext(),
|
|
Importer.getToContext(),
|
|
- Importer.getNonEquivalentDecls());
|
|
+ Importer.getNonEquivalentDecls(),
|
|
+ false, Complain);
|
|
return Ctx.IsStructurallyEquivalent(FromRecord, ToRecord);
|
|
}
|
|
|
|
@@ -2333,7 +2346,7 @@
|
|
|
|
// We may already have a record of the same name; try to find and match it.
|
|
RecordDecl *AdoptDecl = 0;
|
|
- if (!DC->isFunctionOrMethod() && SearchName) {
|
|
+ if (!DC->isFunctionOrMethod()) {
|
|
SmallVector<NamedDecl *, 4> ConflictingDecls;
|
|
llvm::SmallVector<NamedDecl *, 2> FoundDecls;
|
|
DC->localUncachedLookup(SearchName, FoundDecls);
|
|
@@ -2349,26 +2362,32 @@
|
|
|
|
if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) {
|
|
if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
|
|
- if (!D->isCompleteDefinition() || IsStructuralMatch(D, FoundDef)) {
|
|
+ if ((SearchName && !D->isCompleteDefinition()) ||
|
|
+ (D->isCompleteDefinition() &&
|
|
+ D->isAnonymousStructOrUnion()
|
|
+ == FoundDef->isAnonymousStructOrUnion() &&
|
|
+ IsStructuralMatch(D, FoundDef, SearchName))) {
|
|
// The record types structurally match, or the "from" translation
|
|
// unit only had a forward declaration anyway; call it the same
|
|
// function.
|
|
// FIXME: For C++, we should also merge methods here.
|
|
return Importer.Imported(D, FoundDef);
|
|
}
|
|
- } else {
|
|
+ } else if (!D->isCompleteDefinition()) {
|
|
// We have a forward declaration of this type, so adopt that forward
|
|
// declaration rather than building a new one.
|
|
AdoptDecl = FoundRecord;
|
|
continue;
|
|
- }
|
|
+ } else if (!SearchName) {
|
|
+ continue;
|
|
+ }
|
|
}
|
|
|
|
ConflictingDecls.push_back(FoundDecls[I]);
|
|
}
|
|
|
|
- if (!ConflictingDecls.empty()) {
|
|
- Name = Importer.HandleNameConflict(Name, DC, IDNS,
|
|
+ if (!ConflictingDecls.empty() && SearchName) {
|
|
+ Name = Importer.HandleNameConflict(SearchName, DC, IDNS,
|
|
ConflictingDecls.data(),
|
|
ConflictingDecls.size());
|
|
}
|
|
@@ -2393,6 +2412,8 @@
|
|
D2->setQualifierInfo(Importer.Import(D->getQualifierLoc()));
|
|
D2->setLexicalDeclContext(LexicalDC);
|
|
LexicalDC->addDeclInternal(D2);
|
|
+ if (D->isAnonymousStructOrUnion())
|
|
+ D2->setAnonymousStructOrUnion(true);
|
|
}
|
|
|
|
Importer.Imported(D, D2);
|
|
@@ -2631,12 +2652,17 @@
|
|
DC->localUncachedLookup(Name, FoundDecls);
|
|
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
|
|
if (FieldDecl *FoundField = dyn_cast<FieldDecl>(FoundDecls[I])) {
|
|
- if (Importer.IsStructurallyEquivalent(D->getType(),
|
|
- FoundField->getType())) {
|
|
+ if (Importer.IsStructurallyEquivalent(D->getType(),
|
|
+ FoundField->getType(),
|
|
+ Name)) {
|
|
Importer.Imported(D, FoundField);
|
|
return FoundField;
|
|
}
|
|
-
|
|
+
|
|
+ // If there are more anonymous fields to check, continue.
|
|
+ if (!Name && I < N-1)
|
|
+ continue;
|
|
+
|
|
Importer.ToDiag(Loc, diag::err_odr_field_type_inconsistent)
|
|
<< Name << D->getType() << FoundField->getType();
|
|
Importer.ToDiag(FoundField->getLocation(), diag::note_odr_value_here)
|
|
@@ -4662,12 +4688,14 @@
|
|
return To;
|
|
}
|
|
|
|
-bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To) {
|
|
+bool ASTImporter::IsStructurallyEquivalent(QualType From, QualType To,
|
|
+ bool Complain) {
|
|
llvm::DenseMap<const Type *, const Type *>::iterator Pos
|
|
= ImportedTypes.find(From.getTypePtr());
|
|
if (Pos != ImportedTypes.end() && ToContext.hasSameType(Import(From), To))
|
|
return true;
|
|
|
|
- StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls);
|
|
+ StructuralEquivalenceContext Ctx(FromContext, ToContext, NonEquivalentDecls,
|
|
+ false, Complain);
|
|
return Ctx.IsStructurallyEquivalent(From, To);
|
|
}
|
|
Index: lib/AST/NSAPI.cpp
|
|
===================================================================
|
|
--- lib/AST/NSAPI.cpp (revision 152265)
|
|
+++ lib/AST/NSAPI.cpp (working copy)
|
|
@@ -13,7 +13,7 @@
|
|
using namespace clang;
|
|
|
|
NSAPI::NSAPI(ASTContext &ctx)
|
|
- : Ctx(ctx), ClassIds() {
|
|
+ : Ctx(ctx), ClassIds(), BOOLId(0), NSIntegerId(0), NSUIntegerId(0) {
|
|
}
|
|
|
|
IdentifierInfo *NSAPI::getNSClassId(NSClassIdKindKind K) const {
|
|
@@ -250,11 +250,22 @@
|
|
}
|
|
|
|
llvm::Optional<NSAPI::NSNumberLiteralMethodKind>
|
|
-NSAPI::getNSNumberFactoryMethodKind(QualType T) {
|
|
+NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
|
|
const BuiltinType *BT = T->getAs<BuiltinType>();
|
|
if (!BT)
|
|
return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
|
|
-
|
|
+
|
|
+ const TypedefType *TDT = T->getAs<TypedefType>();
|
|
+ if (TDT) {
|
|
+ QualType TDTTy = QualType(TDT, 0);
|
|
+ if (isObjCBOOLType(TDTTy))
|
|
+ return NSAPI::NSNumberWithBool;
|
|
+ if (isObjCNSIntegerType(TDTTy))
|
|
+ return NSAPI::NSNumberWithInteger;
|
|
+ if (isObjCNSUIntegerType(TDTTy))
|
|
+ return NSAPI::NSNumberWithUnsignedInteger;
|
|
+ }
|
|
+
|
|
switch (BT->getKind()) {
|
|
case BuiltinType::Char_S:
|
|
case BuiltinType::SChar:
|
|
@@ -309,3 +320,35 @@
|
|
|
|
return llvm::Optional<NSAPI::NSNumberLiteralMethodKind>();
|
|
}
|
|
+
|
|
+/// \brief Returns true if \param T is a typedef of "BOOL" in objective-c.
|
|
+bool NSAPI::isObjCBOOLType(QualType T) const {
|
|
+ return isObjCTypedef(T, "BOOL", BOOLId);
|
|
+}
|
|
+/// \brief Returns true if \param T is a typedef of "NSInteger" in objective-c.
|
|
+bool NSAPI::isObjCNSIntegerType(QualType T) const {
|
|
+ return isObjCTypedef(T, "NSInteger", NSIntegerId);
|
|
+}
|
|
+/// \brief Returns true if \param T is a typedef of "NSUInteger" in objective-c.
|
|
+bool NSAPI::isObjCNSUIntegerType(QualType T) const {
|
|
+ return isObjCTypedef(T, "NSUInteger", NSUIntegerId);
|
|
+}
|
|
+
|
|
+bool NSAPI::isObjCTypedef(QualType T,
|
|
+ StringRef name, IdentifierInfo *&II) const {
|
|
+ if (!Ctx.getLangOptions().ObjC1)
|
|
+ return false;
|
|
+ if (T.isNull())
|
|
+ return false;
|
|
+
|
|
+ if (!II)
|
|
+ II = &Ctx.Idents.get(name);
|
|
+
|
|
+ while (const TypedefType *TDT = T->getAs<TypedefType>()) {
|
|
+ if (TDT->getDecl()->getDeclName().getAsIdentifierInfo() == II)
|
|
+ return true;
|
|
+ T = TDT->desugar();
|
|
+ }
|
|
+
|
|
+ return false;
|
|
+}
|
|
Index: lib/AST/DeclPrinter.cpp
|
|
===================================================================
|
|
--- lib/AST/DeclPrinter.cpp (revision 152265)
|
|
+++ lib/AST/DeclPrinter.cpp (working copy)
|
|
@@ -114,6 +114,8 @@
|
|
BaseType = FTy->getResultType();
|
|
else if (const VectorType *VTy = BaseType->getAs<VectorType>())
|
|
BaseType = VTy->getElementType();
|
|
+ else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
|
|
+ BaseType = RTy->getPointeeType();
|
|
else
|
|
llvm_unreachable("Unknown declarator!");
|
|
}
|
|
Index: lib/AST/Type.cpp
|
|
===================================================================
|
|
--- lib/AST/Type.cpp (revision 152265)
|
|
+++ lib/AST/Type.cpp (working copy)
|
|
@@ -288,6 +288,28 @@
|
|
return T;
|
|
}
|
|
|
|
+/// \brief This will check for a TypedefType by removing any existing sugar
|
|
+/// until it reaches a TypedefType or a non-sugared type.
|
|
+template <> const TypedefType *Type::getAs() const {
|
|
+ const Type *Cur = this;
|
|
+
|
|
+ while (true) {
|
|
+ if (const TypedefType *TDT = dyn_cast<TypedefType>(Cur))
|
|
+ return TDT;
|
|
+ switch (Cur->getTypeClass()) {
|
|
+#define ABSTRACT_TYPE(Class, Parent)
|
|
+#define TYPE(Class, Parent) \
|
|
+ case Class: { \
|
|
+ const Class##Type *Ty = cast<Class##Type>(Cur); \
|
|
+ if (!Ty->isSugared()) return 0; \
|
|
+ Cur = Ty->desugar().getTypePtr(); \
|
|
+ break; \
|
|
+ }
|
|
+#include "clang/AST/TypeNodes.def"
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
/// getUnqualifiedDesugaredType - Pull any qualifiers and syntactic
|
|
/// sugar off the given type. This should produce an object of the
|
|
/// same dynamic type as the canonical type.
|
|
Index: lib/AST/RecordLayoutBuilder.cpp
|
|
===================================================================
|
|
--- lib/AST/RecordLayoutBuilder.cpp (revision 152265)
|
|
+++ lib/AST/RecordLayoutBuilder.cpp (working copy)
|
|
@@ -2313,6 +2313,8 @@
|
|
ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
|
|
const ObjCImplementationDecl *Impl) const {
|
|
// Retrieve the definition
|
|
+ if (D->hasExternalLexicalStorage() && !D->getDefinition())
|
|
+ getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D));
|
|
D = D->getDefinition();
|
|
assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!");
|
|
|
|
Index: lib/AST/ExprConstant.cpp
|
|
===================================================================
|
|
--- lib/AST/ExprConstant.cpp (revision 152265)
|
|
+++ lib/AST/ExprConstant.cpp (working copy)
|
|
@@ -3054,7 +3054,7 @@
|
|
bool VisitUnaryAddrOf(const UnaryOperator *E);
|
|
bool VisitObjCStringLiteral(const ObjCStringLiteral *E)
|
|
{ return Success(E); }
|
|
- bool VisitObjCNumericLiteral(const ObjCNumericLiteral *E)
|
|
+ bool VisitObjCBoxedExpr(const ObjCBoxedExpr *E)
|
|
{ return Success(E); }
|
|
bool VisitAddrLabelExpr(const AddrLabelExpr *E)
|
|
{ return Success(E); }
|
|
@@ -4210,7 +4210,7 @@
|
|
/// character of a string literal.
|
|
template<typename LValue>
|
|
static bool EvaluateBuiltinConstantPForLValue(const LValue &LV) {
|
|
- const Expr *E = LV.getLValueBase().dyn_cast<const Expr*>();
|
|
+ const Expr *E = LV.getLValueBase().template dyn_cast<const Expr*>();
|
|
return E && isa<StringLiteral>(E) && LV.getLValueOffset().isZero();
|
|
}
|
|
|
|
@@ -6259,7 +6259,7 @@
|
|
case Expr::CXXDependentScopeMemberExprClass:
|
|
case Expr::UnresolvedMemberExprClass:
|
|
case Expr::ObjCStringLiteralClass:
|
|
- case Expr::ObjCNumericLiteralClass:
|
|
+ case Expr::ObjCBoxedExprClass:
|
|
case Expr::ObjCArrayLiteralClass:
|
|
case Expr::ObjCDictionaryLiteralClass:
|
|
case Expr::ObjCEncodeExprClass:
|
|
Index: lib/AST/ItaniumMangle.cpp
|
|
===================================================================
|
|
--- lib/AST/ItaniumMangle.cpp (revision 152265)
|
|
+++ lib/AST/ItaniumMangle.cpp (working copy)
|
|
@@ -2374,7 +2374,7 @@
|
|
case Expr::ObjCProtocolExprClass:
|
|
case Expr::ObjCSelectorExprClass:
|
|
case Expr::ObjCStringLiteralClass:
|
|
- case Expr::ObjCNumericLiteralClass:
|
|
+ case Expr::ObjCBoxedExprClass:
|
|
case Expr::ObjCArrayLiteralClass:
|
|
case Expr::ObjCDictionaryLiteralClass:
|
|
case Expr::ObjCSubscriptRefExprClass:
|
|
Index: lib/AST/StmtPrinter.cpp
|
|
===================================================================
|
|
--- lib/AST/StmtPrinter.cpp (revision 152265)
|
|
+++ lib/AST/StmtPrinter.cpp (working copy)
|
|
@@ -1679,9 +1679,9 @@
|
|
VisitStringLiteral(Node->getString());
|
|
}
|
|
|
|
-void StmtPrinter::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
+void StmtPrinter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
|
OS << "@";
|
|
- Visit(E->getNumber());
|
|
+ Visit(E->getSubExpr());
|
|
}
|
|
|
|
void StmtPrinter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
Index: lib/AST/DeclBase.cpp
|
|
===================================================================
|
|
--- lib/AST/DeclBase.cpp (revision 152265)
|
|
+++ lib/AST/DeclBase.cpp (working copy)
|
|
@@ -1153,14 +1153,14 @@
|
|
|
|
// If there's no external storage, just perform a normal lookup and copy
|
|
// the results.
|
|
- if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage()) {
|
|
+ if (!hasExternalVisibleStorage() && !hasExternalLexicalStorage() && Name) {
|
|
lookup_result LookupResults = lookup(Name);
|
|
Results.insert(Results.end(), LookupResults.first, LookupResults.second);
|
|
return;
|
|
}
|
|
|
|
// If we have a lookup table, check there first. Maybe we'll get lucky.
|
|
- if (LookupPtr) {
|
|
+ if (LookupPtr && Name) {
|
|
StoredDeclsMap::iterator Pos = LookupPtr->find(Name);
|
|
if (Pos != LookupPtr->end()) {
|
|
Results.insert(Results.end(),
|
|
Index: lib/AST/StmtProfile.cpp
|
|
===================================================================
|
|
--- lib/AST/StmtProfile.cpp (revision 152265)
|
|
+++ lib/AST/StmtProfile.cpp (working copy)
|
|
@@ -982,7 +982,7 @@
|
|
VisitExpr(S);
|
|
}
|
|
|
|
-void StmtProfiler::VisitObjCNumericLiteral(const ObjCNumericLiteral *E) {
|
|
+void StmtProfiler::VisitObjCBoxedExpr(const ObjCBoxedExpr *E) {
|
|
VisitExpr(E);
|
|
}
|
|
|
|
Index: lib/AST/Expr.cpp
|
|
===================================================================
|
|
--- lib/AST/Expr.cpp (revision 152265)
|
|
+++ lib/AST/Expr.cpp (working copy)
|
|
@@ -2100,7 +2100,7 @@
|
|
case ObjCArrayLiteralClass:
|
|
case ObjCBoolLiteralExprClass:
|
|
case ObjCDictionaryLiteralClass:
|
|
- case ObjCNumericLiteralClass:
|
|
+ case ObjCBoxedExprClass:
|
|
return CT_Can;
|
|
|
|
// Many other things have subexpressions, so we have to test those.
|
|
Index: lib/AST/ExprClassification.cpp
|
|
===================================================================
|
|
--- lib/AST/ExprClassification.cpp (revision 152265)
|
|
+++ lib/AST/ExprClassification.cpp (working copy)
|
|
@@ -158,7 +158,7 @@
|
|
case Expr::ObjCSelectorExprClass:
|
|
case Expr::ObjCProtocolExprClass:
|
|
case Expr::ObjCStringLiteralClass:
|
|
- case Expr::ObjCNumericLiteralClass:
|
|
+ case Expr::ObjCBoxedExprClass:
|
|
case Expr::ObjCArrayLiteralClass:
|
|
case Expr::ObjCDictionaryLiteralClass:
|
|
case Expr::ObjCBoolLiteralExprClass:
|
|
Index: lib/Lex/PPMacroExpansion.cpp
|
|
===================================================================
|
|
--- lib/Lex/PPMacroExpansion.cpp (revision 152265)
|
|
+++ lib/Lex/PPMacroExpansion.cpp (working copy)
|
|
@@ -634,6 +634,7 @@
|
|
.Case("objc_subscripting", LangOpts.ObjCNonFragileABI)
|
|
.Case("objc_array_literals", LangOpts.ObjC2)
|
|
.Case("objc_dictionary_literals", LangOpts.ObjC2)
|
|
+ .Case("objc_boxed_expressions", LangOpts.ObjC2)
|
|
.Case("arc_cf_code_audited", true)
|
|
// C11 features
|
|
.Case("c_alignas", LangOpts.C11)
|
|
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
|
|
===================================================================
|
|
--- lib/StaticAnalyzer/Core/ExprEngine.cpp (revision 152265)
|
|
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp (working copy)
|
|
@@ -590,7 +590,7 @@
|
|
case Stmt::ObjCIsaExprClass:
|
|
case Stmt::ObjCProtocolExprClass:
|
|
case Stmt::ObjCSelectorExprClass:
|
|
- case Expr::ObjCNumericLiteralClass:
|
|
+ case Expr::ObjCBoxedExprClass:
|
|
case Stmt::ParenListExprClass:
|
|
case Stmt::PredefinedExprClass:
|
|
case Stmt::ShuffleVectorExprClass:
|
|
Index: lib/CodeGen/CGExprScalar.cpp
|
|
===================================================================
|
|
--- lib/CodeGen/CGExprScalar.cpp (revision 152265)
|
|
+++ lib/CodeGen/CGExprScalar.cpp (working copy)
|
|
@@ -531,8 +531,8 @@
|
|
Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
|
|
return CGF.EmitObjCStringLiteral(E);
|
|
}
|
|
- Value *VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
- return CGF.EmitObjCNumericLiteral(E);
|
|
+ Value *VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
|
+ return CGF.EmitObjCBoxedExpr(E);
|
|
}
|
|
Value *VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
return CGF.EmitObjCArrayLiteral(E);
|
|
Index: lib/CodeGen/CGObjC.cpp
|
|
===================================================================
|
|
--- lib/CodeGen/CGObjC.cpp (revision 152265)
|
|
+++ lib/CodeGen/CGObjC.cpp (working copy)
|
|
@@ -51,35 +51,36 @@
|
|
return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType()));
|
|
}
|
|
|
|
-/// EmitObjCNumericLiteral - This routine generates code for
|
|
-/// the appropriate +[NSNumber numberWith<Type>:] method.
|
|
+/// EmitObjCBoxedExpr - This routine generates code to call
|
|
+/// the appropriate expression boxing method. This will either be
|
|
+/// one of +[NSNumber numberWith<Type>:], or +[NSString stringWithUTF8String:].
|
|
///
|
|
-llvm::Value *CodeGenFunction::EmitObjCNumericLiteral(const ObjCNumericLiteral *E) {
|
|
+llvm::Value *
|
|
+CodeGenFunction::EmitObjCBoxedExpr(const ObjCBoxedExpr *E) {
|
|
// Generate the correct selector for this literal's concrete type.
|
|
- const Expr *NL = E->getNumber();
|
|
+ const Expr *SubExpr = E->getSubExpr();
|
|
// Get the method.
|
|
- const ObjCMethodDecl *Method = E->getObjCNumericLiteralMethod();
|
|
- assert(Method && "NSNumber method is null");
|
|
- Selector Sel = Method->getSelector();
|
|
+ const ObjCMethodDecl *BoxingMethod = E->getBoxingMethod();
|
|
+ assert(BoxingMethod && "BoxingMethod is null");
|
|
+ assert(BoxingMethod->isClassMethod() && "BoxingMethod must be a class method");
|
|
+ Selector Sel = BoxingMethod->getSelector();
|
|
|
|
// Generate a reference to the class pointer, which will be the receiver.
|
|
- QualType ResultType = E->getType(); // should be NSNumber *
|
|
- const ObjCObjectPointerType *InterfacePointerType =
|
|
- ResultType->getAsObjCInterfacePointerType();
|
|
- ObjCInterfaceDecl *NSNumberDecl =
|
|
- InterfacePointerType->getObjectType()->getInterface();
|
|
+ // Assumes that the method was introduced in the class that should be
|
|
+ // messaged (avoids pulling it out of the result type).
|
|
CGObjCRuntime &Runtime = CGM.getObjCRuntime();
|
|
- llvm::Value *Receiver = Runtime.GetClass(Builder, NSNumberDecl);
|
|
-
|
|
- const ParmVarDecl *argDecl = *Method->param_begin();
|
|
+ const ObjCInterfaceDecl *ClassDecl = BoxingMethod->getClassInterface();
|
|
+ llvm::Value *Receiver = Runtime.GetClass(Builder, ClassDecl);
|
|
+
|
|
+ const ParmVarDecl *argDecl = *BoxingMethod->param_begin();
|
|
QualType ArgQT = argDecl->getType().getUnqualifiedType();
|
|
- RValue RV = EmitAnyExpr(NL);
|
|
+ RValue RV = EmitAnyExpr(SubExpr);
|
|
CallArgList Args;
|
|
Args.add(RV, ArgQT);
|
|
-
|
|
+
|
|
RValue result = Runtime.GenerateMessageSend(*this, ReturnValueSlot(),
|
|
- ResultType, Sel, Receiver, Args,
|
|
- NSNumberDecl, Method);
|
|
+ BoxingMethod->getResultType(), Sel, Receiver, Args,
|
|
+ ClassDecl, BoxingMethod);
|
|
return Builder.CreateBitCast(result.getScalarVal(),
|
|
ConvertType(E->getType()));
|
|
}
|
|
Index: lib/CodeGen/CodeGenTypes.cpp
|
|
===================================================================
|
|
--- lib/CodeGen/CodeGenTypes.cpp (revision 152265)
|
|
+++ lib/CodeGen/CodeGenTypes.cpp (working copy)
|
|
@@ -133,6 +133,14 @@
|
|
// when a class is translated, even though they aren't embedded by-value into
|
|
// the class.
|
|
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
|
|
+ if (!CRD->hasDefinition() && CRD->hasExternalLexicalStorage()) {
|
|
+ ExternalASTSource *EAS = CRD->getASTContext().getExternalSource();
|
|
+ if (!EAS)
|
|
+ return false;
|
|
+ EAS->CompleteType(const_cast<CXXRecordDecl*>(CRD));
|
|
+ if (!CRD->hasDefinition())
|
|
+ return false;
|
|
+ }
|
|
for (CXXRecordDecl::base_class_const_iterator I = CRD->bases_begin(),
|
|
E = CRD->bases_end(); I != E; ++I)
|
|
if (!isSafeToConvert(I->getType()->getAs<RecordType>()->getDecl(),
|
|
Index: lib/CodeGen/CodeGenFunction.h
|
|
===================================================================
|
|
--- lib/CodeGen/CodeGenFunction.h (revision 152265)
|
|
+++ lib/CodeGen/CodeGenFunction.h (working copy)
|
|
@@ -2238,7 +2238,7 @@
|
|
|
|
llvm::Value *EmitObjCProtocolExpr(const ObjCProtocolExpr *E);
|
|
llvm::Value *EmitObjCStringLiteral(const ObjCStringLiteral *E);
|
|
- llvm::Value *EmitObjCNumericLiteral(const ObjCNumericLiteral *E);
|
|
+ llvm::Value *EmitObjCBoxedExpr(const ObjCBoxedExpr *E);
|
|
llvm::Value *EmitObjCArrayLiteral(const ObjCArrayLiteral *E);
|
|
llvm::Value *EmitObjCDictionaryLiteral(const ObjCDictionaryLiteral *E);
|
|
llvm::Value *EmitObjCCollectionLiteral(const Expr *E,
|
|
Index: lib/Parse/ParseObjc.cpp
|
|
===================================================================
|
|
--- lib/Parse/ParseObjc.cpp (revision 152265)
|
|
+++ lib/Parse/ParseObjc.cpp (working copy)
|
|
@@ -2067,6 +2067,10 @@
|
|
// Objective-C dictionary literal
|
|
return ParsePostfixExpressionSuffix(ParseObjCDictionaryLiteral(AtLoc));
|
|
|
|
+ case tok::l_paren:
|
|
+ // Objective-C boxed expression
|
|
+ return ParsePostfixExpressionSuffix(ParseObjCBoxedExpr(AtLoc));
|
|
+
|
|
default:
|
|
if (Tok.getIdentifierInfo() == 0)
|
|
return ExprError(Diag(AtLoc, diag::err_unexpected_at));
|
|
@@ -2581,6 +2585,31 @@
|
|
return Owned(Actions.BuildObjCNumericLiteral(AtLoc, Lit.take()));
|
|
}
|
|
|
|
+/// ParseObjCBoxedExpr -
|
|
+/// objc-box-expression:
|
|
+/// @( assignment-expression )
|
|
+ExprResult
|
|
+Parser::ParseObjCBoxedExpr(SourceLocation AtLoc) {
|
|
+ if (Tok.isNot(tok::l_paren))
|
|
+ return ExprError(Diag(Tok, diag::err_expected_lparen_after) << "@");
|
|
+
|
|
+ BalancedDelimiterTracker T(*this, tok::l_paren);
|
|
+ T.consumeOpen();
|
|
+ ExprResult ValueExpr(ParseAssignmentExpression());
|
|
+ if (T.consumeClose())
|
|
+ return ExprError();
|
|
+
|
|
+ if (ValueExpr.isInvalid())
|
|
+ return ExprError();
|
|
+
|
|
+ // Wrap the sub-expression in a parenthesized expression, to distinguish
|
|
+ // a boxed expression from a literal.
|
|
+ SourceLocation LPLoc = T.getOpenLocation(), RPLoc = T.getCloseLocation();
|
|
+ ValueExpr = Actions.ActOnParenExpr(LPLoc, RPLoc, ValueExpr.take());
|
|
+ return Owned(Actions.BuildObjCBoxedExpr(SourceRange(AtLoc, RPLoc),
|
|
+ ValueExpr.take()));
|
|
+}
|
|
+
|
|
ExprResult Parser::ParseObjCArrayLiteral(SourceLocation AtLoc) {
|
|
ExprVector ElementExprs(Actions); // array elements.
|
|
ConsumeBracket(); // consume the l_square.
|
|
Index: lib/Serialization/ASTReaderStmt.cpp
|
|
===================================================================
|
|
--- lib/Serialization/ASTReaderStmt.cpp (revision 152265)
|
|
+++ lib/Serialization/ASTReaderStmt.cpp (working copy)
|
|
@@ -823,12 +823,12 @@
|
|
E->setAtLoc(ReadSourceLocation(Record, Idx));
|
|
}
|
|
|
|
-void ASTStmtReader::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
+void ASTStmtReader::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
|
VisitExpr(E);
|
|
// could be one of several IntegerLiteral, FloatLiteral, etc.
|
|
- E->Number = Reader.ReadSubStmt();
|
|
- E->ObjCNumericLiteralMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
- E->AtLoc = ReadSourceLocation(Record, Idx);
|
|
+ E->SubExpr = Reader.ReadSubStmt();
|
|
+ E->BoxingMethod = ReadDeclAs<ObjCMethodDecl>(Record, Idx);
|
|
+ E->Range = ReadSourceRange(Record, Idx);
|
|
}
|
|
|
|
void ASTStmtReader::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|
|
@@ -1893,8 +1893,8 @@
|
|
case EXPR_OBJC_STRING_LITERAL:
|
|
S = new (Context) ObjCStringLiteral(Empty);
|
|
break;
|
|
- case EXPR_OBJC_NUMERIC_LITERAL:
|
|
- S = new (Context) ObjCNumericLiteral(Empty);
|
|
+ case EXPR_OBJC_BOXED_EXPRESSION:
|
|
+ S = new (Context) ObjCBoxedExpr(Empty);
|
|
break;
|
|
case EXPR_OBJC_ARRAY_LITERAL:
|
|
S = ObjCArrayLiteral::CreateEmpty(Context,
|
|
Index: lib/Serialization/ASTWriter.cpp
|
|
===================================================================
|
|
--- lib/Serialization/ASTWriter.cpp (revision 152265)
|
|
+++ lib/Serialization/ASTWriter.cpp (working copy)
|
|
@@ -696,7 +696,7 @@
|
|
RECORD(EXPR_BLOCK_DECL_REF);
|
|
RECORD(EXPR_GENERIC_SELECTION);
|
|
RECORD(EXPR_OBJC_STRING_LITERAL);
|
|
- RECORD(EXPR_OBJC_NUMERIC_LITERAL);
|
|
+ RECORD(EXPR_OBJC_BOXED_EXPRESSION);
|
|
RECORD(EXPR_OBJC_ARRAY_LITERAL);
|
|
RECORD(EXPR_OBJC_DICTIONARY_LITERAL);
|
|
RECORD(EXPR_OBJC_ENCODE);
|
|
Index: lib/Serialization/ASTWriterStmt.cpp
|
|
===================================================================
|
|
--- lib/Serialization/ASTWriterStmt.cpp (revision 152265)
|
|
+++ lib/Serialization/ASTWriterStmt.cpp (working copy)
|
|
@@ -783,12 +783,12 @@
|
|
Code = serialization::EXPR_OBJC_STRING_LITERAL;
|
|
}
|
|
|
|
-void ASTStmtWriter::VisitObjCNumericLiteral(ObjCNumericLiteral *E) {
|
|
+void ASTStmtWriter::VisitObjCBoxedExpr(ObjCBoxedExpr *E) {
|
|
VisitExpr(E);
|
|
- Writer.AddStmt(E->getNumber());
|
|
- Writer.AddDeclRef(E->getObjCNumericLiteralMethod(), Record);
|
|
- Writer.AddSourceLocation(E->getAtLoc(), Record);
|
|
- Code = serialization::EXPR_OBJC_NUMERIC_LITERAL;
|
|
+ Writer.AddStmt(E->getSubExpr());
|
|
+ Writer.AddDeclRef(E->getBoxingMethod(), Record);
|
|
+ Writer.AddSourceRange(E->getSourceRange(), Record);
|
|
+ Code = serialization::EXPR_OBJC_BOXED_EXPRESSION;
|
|
}
|
|
|
|
void ASTStmtWriter::VisitObjCArrayLiteral(ObjCArrayLiteral *E) {
|