r243092 - Cleanup ObjCInterfaceDecl lookup for ObjC literals
Alex Denisov
1101.debian at gmail.com
Thu Jul 23 22:09:41 PDT 2015
Author: alexdenisov
Date: Fri Jul 24 00:09:40 2015
New Revision: 243092
URL: http://llvm.org/viewvc/llvm-project?rev=243092&view=rev
Log:
Cleanup ObjCInterfaceDecl lookup for ObjC literals
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExprObjC.cpp
cfe/trunk/test/SemaObjC/objc-array-literal.m
cfe/trunk/test/SemaObjC/objc-boxed-expressions-nsvalue.m
cfe/trunk/test/SemaObjC/objc-dictionary-literal.m
cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m
cfe/trunk/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=243092&r1=243091&r2=243092&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Jul 24 00:09:40 2015
@@ -2101,25 +2101,18 @@ def err_field_with_address_space : Error
"field may not be qualified with an address space">;
def err_attr_objc_ownership_redundant : Error<
"the type %0 is already explicitly ownership-qualified">;
-def err_undeclared_nsnumber : Error<
- "NSNumber must be available to use Objective-C literals">;
-def err_undeclared_nsvalue : Error<
- "NSValue must be available to use Objective-C boxed expressions">;
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_non_trivially_copyable_boxed_expression_type : Error<
"non-trivially copyable type %0 cannot be 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<
- "NSDictionary must be available to use Objective-C dictionary "
- "literals">;
+def err_undeclared_objc_literal_class : Error<
+ "definition of class %0 must be available to use Objective-C "
+ "%select{array literals|dictionary literals|numeric literals|boxed expressions|"
+ "string literals}1">;
def err_undeclared_boxing_method : Error<
"declaration of %0 is missing in %1 class">;
def err_objc_literal_method_sig : Error<
Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=243092&r1=243091&r2=243092&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Fri Jul 24 00:09:40 2015
@@ -168,6 +168,76 @@ static bool validateBoxingMethod(Sema &S
return true;
}
+/// \brief Maps ObjCLiteralKind to NSClassIdKindKind
+static NSAPI::NSClassIdKindKind ClassKindFromLiteralKind(
+ Sema::ObjCLiteralKind LiteralKind) {
+ switch (LiteralKind) {
+ case Sema::LK_Array:
+ return NSAPI::ClassId_NSArray;
+ case Sema::LK_Dictionary:
+ return NSAPI::ClassId_NSDictionary;
+ case Sema::LK_Numeric:
+ return NSAPI::ClassId_NSNumber;
+ case Sema::LK_String:
+ return NSAPI::ClassId_NSString;
+ case Sema::LK_Boxed:
+ return NSAPI::ClassId_NSValue;
+
+ // there is no corresponding matching
+ // between LK_None/LK_Block and NSClassIdKindKind
+ case Sema::LK_Block:
+ case Sema::LK_None:
+ llvm_unreachable("LiteralKind can't be converted into a ClassKind");
+ }
+}
+
+/// \brief Validates ObjCInterfaceDecl availability.
+/// ObjCInterfaceDecl, used to create ObjC literals, should be defined
+/// if clang not in a debugger mode.
+static bool ValidateObjCLiteralInterfaceDecl(Sema &S, ObjCInterfaceDecl *Decl,
+ SourceLocation Loc,
+ Sema::ObjCLiteralKind LiteralKind) {
+ if (!Decl) {
+ NSAPI::NSClassIdKindKind Kind = ClassKindFromLiteralKind(LiteralKind);
+ IdentifierInfo *II = S.NSAPIObj->getNSClassId(Kind);
+ S.Diag(Loc, diag::err_undeclared_objc_literal_class)
+ << II->getName() << LiteralKind;
+ return false;
+ } else if (!Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
+ S.Diag(Loc, diag::err_undeclared_objc_literal_class)
+ << Decl->getName() << LiteralKind;
+ S.Diag(Decl->getLocation(), diag::note_forward_class);
+ return false;
+ }
+
+ return true;
+}
+
+/// \brief Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
+/// Used to create ObjC literals, such as NSDictionary (@{}),
+/// NSArray (@[]) and Boxed Expressions (@())
+static ObjCInterfaceDecl *LookupObjCInterfaceDeclForLiteral(Sema &S,
+ SourceLocation Loc,
+ Sema::ObjCLiteralKind LiteralKind) {
+ NSAPI::NSClassIdKindKind ClassKind = ClassKindFromLiteralKind(LiteralKind);
+ IdentifierInfo *II = S.NSAPIObj->getNSClassId(ClassKind);
+ NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc,
+ Sema::LookupOrdinaryName);
+ ObjCInterfaceDecl *ID = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
+ if (!ID && S.getLangOpts().DebuggerObjCLiteral) {
+ ASTContext &Context = S.Context;
+ TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+ ID = ObjCInterfaceDecl::Create (Context, TU, SourceLocation(), II,
+ nullptr, nullptr, SourceLocation());
+ }
+
+ if (!ValidateObjCLiteralInterfaceDecl(S, ID, Loc, LiteralKind)) {
+ ID = nullptr;
+ }
+
+ return ID;
+}
+
/// \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,
@@ -197,26 +267,9 @@ static ObjCMethodDecl *getNSNumberFactor
// 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);
- NamedDecl *IF = S.LookupSingleName(S.TUScope, NSNumberId,
- Loc, Sema::LookupOrdinaryName);
- S.NSNumberDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
+ S.NSNumberDecl = LookupObjCInterfaceDeclForLiteral(S, Loc,
+ Sema::LK_Numeric);
if (!S.NSNumberDecl) {
- if (S.getLangOpts().DebuggerObjCLiteral) {
- // Create a stub definition of NSNumber.
- S.NSNumberDecl = ObjCInterfaceDecl::Create(CX,
- CX.getTranslationUnitDecl(),
- SourceLocation(), NSNumberId,
- nullptr, nullptr,
- SourceLocation());
- } else {
- // Otherwise, require a declaration of NSNumber.
- S.Diag(Loc, diag::err_undeclared_nsnumber);
- return nullptr;
- }
- } else if (!S.NSNumberDecl->hasDefinition()) {
- S.Diag(Loc, diag::err_undeclared_nsnumber);
return nullptr;
}
}
@@ -457,6 +510,7 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
if (RValue.isInvalid()) {
return ExprError();
}
+ SourceLocation Loc = SR.getBegin();
ValueExpr = RValue.get();
QualType ValueType(ValueExpr->getType());
if (const PointerType *PT = ValueType->getAs<PointerType>()) {
@@ -464,29 +518,11 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
if (Context.hasSameUnqualifiedType(PointeeType, Context.CharTy)) {
if (!NSStringDecl) {
- IdentifierInfo *NSStringId =
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSString);
- NamedDecl *Decl = LookupSingleName(TUScope, NSStringId,
- SR.getBegin(), LookupOrdinaryName);
- NSStringDecl = dyn_cast_or_null<ObjCInterfaceDecl>(Decl);
+ NSStringDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
+ Sema::LK_String);
if (!NSStringDecl) {
- if (getLangOpts().DebuggerObjCLiteral) {
- // Support boxed expressions in the debugger w/o NSString declaration.
- DeclContext *TU = Context.getTranslationUnitDecl();
- NSStringDecl = ObjCInterfaceDecl::Create(Context, TU,
- SourceLocation(),
- NSStringId,
- nullptr, nullptr,
- SourceLocation());
- } else {
- Diag(SR.getBegin(), diag::err_undeclared_nsstring);
- return ExprError();
- }
- } else if (!NSStringDecl->hasDefinition()) {
- Diag(SR.getBegin(), diag::err_undeclared_nsstring);
return ExprError();
}
- assert(NSStringDecl && "NSStringDecl should not be NULL");
QualType NSStringObject = Context.getObjCInterfaceType(NSStringDecl);
NSStringPointer = Context.getObjCObjectPointerType(NSStringObject);
}
@@ -520,7 +556,7 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
BoxingMethod = M;
}
- if (!validateBoxingMethod(*this, SR.getBegin(), NSStringDecl,
+ if (!validateBoxingMethod(*this, Loc, NSStringDecl,
stringWithUTF8String, BoxingMethod))
return ExprError();
@@ -563,16 +599,16 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
// FIXME: Do I need to do anything special with BoolTy expressions?
// Look for the appropriate method within NSNumber.
- BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(), ValueType);
+ BoxingMethod = getNSNumberFactoryMethod(*this, Loc, 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)
+ Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
<< ValueType << ValueExpr->getSourceRange();
return ExprError();
}
- BoxingMethod = getNSNumberFactoryMethod(*this, SR.getBegin(),
+ BoxingMethod = getNSNumberFactoryMethod(*this, Loc,
ET->getDecl()->getIntegerType());
BoxedType = NSNumberPointer;
} else if (ValueType->isObjCBoxableRecordType()) {
@@ -582,29 +618,12 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
// Look up the NSValue class, if we haven't done so already. It's cached
// in the Sema instance.
if (!NSValueDecl) {
- IdentifierInfo *NSValueId =
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSValue);
- NamedDecl *IF = LookupSingleName(TUScope, NSValueId,
- SR.getBegin(), Sema::LookupOrdinaryName);
- NSValueDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
+ NSValueDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
+ Sema::LK_Boxed);
if (!NSValueDecl) {
- if (getLangOpts().DebuggerObjCLiteral) {
- // Create a stub definition of NSValue.
- DeclContext *TU = Context.getTranslationUnitDecl();
- NSValueDecl = ObjCInterfaceDecl::Create(Context, TU,
- SourceLocation(), NSValueId,
- nullptr, nullptr,
- SourceLocation());
- } else {
- // Otherwise, require a declaration of NSValue.
- Diag(SR.getBegin(), diag::err_undeclared_nsvalue);
- return ExprError();
- }
- } else if (!NSValueDecl->hasDefinition()) {
- Diag(SR.getBegin(), diag::err_undeclared_nsvalue);
return ExprError();
}
-
+
// generate the pointer to NSValue type.
QualType NSValueObject = Context.getObjCInterfaceType(NSValueDecl);
NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);
@@ -663,7 +682,7 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
BoxingMethod = M;
}
- if (!validateBoxingMethod(*this, SR.getBegin(), NSValueDecl,
+ if (!validateBoxingMethod(*this, Loc, NSValueDecl,
ValueWithBytesObjCType, BoxingMethod))
return ExprError();
@@ -671,8 +690,7 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
}
if (!ValueType.isTriviallyCopyableType(Context)) {
- Diag(SR.getBegin(),
- diag::err_objc_non_trivially_copyable_boxed_expression_type)
+ Diag(Loc, diag::err_objc_non_trivially_copyable_boxed_expression_type)
<< ValueType << ValueExpr->getSourceRange();
return ExprError();
}
@@ -682,12 +700,12 @@ ExprResult Sema::BuildObjCBoxedExpr(Sour
}
if (!BoxingMethod) {
- Diag(SR.getBegin(), diag::err_objc_illegal_boxed_expression_type)
+ Diag(Loc, diag::err_objc_illegal_boxed_expression_type)
<< ValueType << ValueExpr->getSourceRange();
return ExprError();
}
- DiagnoseUseOfDecl(BoxingMethod, SR.getBegin());
+ DiagnoseUseOfDecl(BoxingMethod, Loc);
ExprResult ConvertedValueExpr;
if (ValueType->isObjCBoxableRecordType()) {
@@ -746,26 +764,16 @@ ExprResult Sema::BuildObjCSubscriptExpre
}
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 && getLangOpts().DebuggerObjCLiteral)
- NSArrayDecl = ObjCInterfaceDecl::Create (Context,
- Context.getTranslationUnitDecl(),
- SourceLocation(),
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSArray),
- nullptr, nullptr, SourceLocation());
+ SourceLocation Loc = SR.getBegin();
+ if (!NSArrayDecl) {
+ NSArrayDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
+ Sema::LK_Array);
if (!NSArrayDecl) {
- Diag(SR.getBegin(), diag::err_undeclared_nsarray);
return ExprError();
}
}
-
+
// Find the arrayWithObjects:count: method, if we haven't done so already.
QualType IdT = Context.getObjCIdType();
if (!ArrayWithObjectsMethod) {
@@ -801,7 +809,7 @@ ExprResult Sema::BuildObjCArrayLiteral(S
Method->setMethodParams(Context, Params, None);
}
- if (!validateBoxingMethod(*this, SR.getBegin(), NSArrayDecl, Sel, Method))
+ if (!validateBoxingMethod(*this, Loc, NSArrayDecl, Sel, Method))
return ExprError();
// Dig out the type that all elements should be converted to.
@@ -862,25 +870,16 @@ ExprResult Sema::BuildObjCArrayLiteral(S
ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR,
ObjCDictionaryElement *Elements,
unsigned NumElements) {
- // Look up the NSDictionary class, if we haven't done so already.
- if (!NSDictionaryDecl) {
- NamedDecl *IF = LookupSingleName(TUScope,
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSDictionary),
- SR.getBegin(), LookupOrdinaryName);
- NSDictionaryDecl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
- if (!NSDictionaryDecl && getLangOpts().DebuggerObjCLiteral)
- NSDictionaryDecl = ObjCInterfaceDecl::Create (Context,
- Context.getTranslationUnitDecl(),
- SourceLocation(),
- NSAPIObj->getNSClassId(NSAPI::ClassId_NSDictionary),
- nullptr, nullptr, SourceLocation());
+ SourceLocation Loc = SR.getBegin();
+ if (!NSDictionaryDecl) {
+ NSDictionaryDecl = LookupObjCInterfaceDeclForLiteral(*this, Loc,
+ Sema::LK_Dictionary);
if (!NSDictionaryDecl) {
- Diag(SR.getBegin(), diag::err_undeclared_nsdictionary);
- return ExprError();
+ return ExprError();
}
}
-
+
// Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
// so already.
QualType IdT = Context.getObjCIdType();
Modified: cfe/trunk/test/SemaObjC/objc-array-literal.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-array-literal.m?rev=243092&r1=243091&r2=243092&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objc-array-literal.m (original)
+++ cfe/trunk/test/SemaObjC/objc-array-literal.m Fri Jul 24 00:09:40 2015
@@ -11,14 +11,14 @@ typedef unsigned int NSUInteger;
void checkNSArrayUnavailableDiagnostic() {
id obj;
- id arr = @[obj]; // expected-error {{NSArray must be available to use Objective-C array literals}}
+ id arr = @[obj]; // expected-error {{definition of class NSArray must be available to use Objective-C array literals}}
}
- at class NSArray;
+ at class NSArray; // expected-note {{forward declaration of class here}}
void checkNSArrayFDDiagnostic() {
id obj;
- id arr = @[obj]; // expected-error {{declaration of 'arrayWithObjects:count:' is missing in NSArray class}}
+ id arr = @[obj]; // expected-error {{definition of class NSArray must be available to use Objective-C array literals}}
}
@class NSString;
Modified: cfe/trunk/test/SemaObjC/objc-boxed-expressions-nsvalue.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-boxed-expressions-nsvalue.m?rev=243092&r1=243091&r2=243092&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objc-boxed-expressions-nsvalue.m (original)
+++ cfe/trunk/test/SemaObjC/objc-boxed-expressions-nsvalue.m Fri Jul 24 00:09:40 2015
@@ -46,7 +46,7 @@ typedef union BOXABLE _BoxableUnion {
void checkNSValueDiagnostic() {
NSRect rect;
- id value = @(rect); // expected-error{{NSValue must be available to use Objective-C boxed expressions}}
+ id value = @(rect); // expected-error{{definition of class NSValue must be available to use Objective-C boxed expressions}}
}
@interface NSValue
Modified: cfe/trunk/test/SemaObjC/objc-dictionary-literal.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-dictionary-literal.m?rev=243092&r1=243091&r2=243092&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objc-dictionary-literal.m (original)
+++ cfe/trunk/test/SemaObjC/objc-dictionary-literal.m Fri Jul 24 00:09:40 2015
@@ -8,15 +8,15 @@
void checkNSDictionaryUnavailableDiagnostic() {
id key;
id value;
- id dict = @{ key : value }; // expected-error {{NSDictionary must be available to use Objective-C dictionary literals}}
+ id dict = @{ key : value }; // expected-error {{definition of class NSDictionary must be available to use Objective-C dictionary literals}}
}
- at class NSDictionary;
+ at class NSDictionary; // expected-note {{forward declaration of class here}}
void checkNSDictionaryFDDiagnostic() {
id key;
id value;
- id dic = @{ key : value }; // expected-error {{declaration of 'dictionaryWithObjects:forKeys:count:' is missing in NSDictionary class}}
+ id dic = @{ key : value }; // expected-error {{definition of class NSDictionary must be available to use Objective-C dictionary literals}}
}
@interface NSNumber
Modified: cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m?rev=243092&r1=243091&r2=243092&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m (original)
+++ cfe/trunk/test/SemaObjC/objc-literal-nsnumber.m Fri Jul 24 00:09:40 2015
@@ -10,20 +10,20 @@ typedef int NSInteger;
#endif
void checkNSNumberUnavailableDiagnostic() {
- id num = @1000; // expected-error {{NSNumber must be available to use Objective-C literals}}
+ id num = @1000; // expected-error {{definition of class NSNumber must be available to use Objective-C numeric literals}}
int x = 1000;
- id num1 = @(x); // expected-error {{NSNumber must be available to use Objective-C literals}}\
+ id num1 = @(x); // expected-error {{definition of class NSNumber must be available to use Objective-C numeric literals}}\
// expected-error {{illegal type 'int' used in a boxed expression}}
}
- at class NSNumber;
+ at class NSNumber; // expected-note 2 {{forward declaration of class here}}
void checkNSNumberFDDiagnostic() {
- id num = @1000; // expected-error {{NSNumber must be available to use Objective-C literals}}
+ id num = @1000; // expected-error {{definition of class NSNumber must be available to use Objective-C numeric literals}}
int x = 1000;
- id num1 = @(x); // expected-error {{declaration of 'numberWithInt:' is missing in NSNumber class}}\
+ id num1 = @(x); // expected-error {{definition of class NSNumber must be available to use Objective-C numeric literals}}\
// expected-error {{illegal type 'int' used in a boxed expression}}
}
@@ -71,10 +71,10 @@ int main() {
}
// Dictionary test
- at class NSDictionary;
+ at class NSDictionary; // expected-note {{forward declaration of class here}}
NSDictionary *err() {
- return @{@"name" : @"value"}; // expected-error {{declaration of 'dictionaryWithObjects:forKeys:count:' is missing in NSDictionary class}}
+ return @{@"name" : @"value"}; // expected-error {{definition of class NSDictionary must be available to use Objective-C dictionary literals}}
}
@interface NSDate : NSObject
Modified: cfe/trunk/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm?rev=243092&r1=243091&r2=243092&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm (original)
+++ cfe/trunk/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm Fri Jul 24 00:09:40 2015
@@ -48,7 +48,7 @@ struct BOXABLE NonTriviallyCopyable {
void checkNSValueDiagnostic() {
NSRect rect;
- id value = @(rect); // expected-error{{NSValue must be available to use Objective-C boxed expressions}}
+ id value = @(rect); // expected-error{{definition of class NSValue must be available to use Objective-C boxed expressions}}
}
@interface NSValue
More information about the cfe-commits
mailing list