diff --git lib/Sema/SemaExprObjC.cpp lib/Sema/SemaExprObjC.cpp
index 6cd0626..a08d841 100644
--- lib/Sema/SemaExprObjC.cpp
+++ lib/Sema/SemaExprObjC.cpp
@@ -168,6 +168,43 @@ static bool validateBoxingMethod(Sema &S, SourceLocation Loc,
   return true;
 }
 
+/// \brief Looks up ObjCInterfaceDecl of a given NSClassIdKindKind.
+/// Used to create ObjC literals, such as NSDictionary (@{}),
+/// NSArray (@[]) and Boxed Expressions (@())
+static ObjCInterfaceDecl *LookupObjCLiteralInterfaceDecl(Sema &S,
+                                           SourceLocation Loc,
+                                           NSAPI::NSClassIdKindKind ClassKind) {
+  ObjCInterfaceDecl *Decl = nullptr;
+  IdentifierInfo *II = S.NSAPIObj->getNSClassId(ClassKind);
+  NamedDecl *IF = S.LookupSingleName(S.TUScope, II, Loc,
+                                     Sema::LookupOrdinaryName);
+  Decl = dyn_cast_or_null<ObjCInterfaceDecl>(IF);
+  if (!Decl && S.getLangOpts().DebuggerObjCLiteral) {
+    ASTContext &Context = S.Context;
+    TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
+    Decl = ObjCInterfaceDecl::Create (Context, TU, SourceLocation(), II,
+                                      nullptr, nullptr, SourceLocation());
+  }
+  return Decl;
+}
+
+/// \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, unsigned DiagID) {
+  if (!Decl) {
+    S.Diag(Loc, DiagID);
+    return false;
+  } else if (!Decl->hasDefinition() && !S.getLangOpts().DebuggerObjCLiteral) {
+    S.Diag(Loc, DiagID);
+    S.Diag(Decl->getLocation(), diag::note_forward_class);
+    return false;
+  }
+
+  return true;
+}
+
 /// \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 +234,10 @@ static ObjCMethodDecl *getNSNumberFactoryMethod(Sema &S, SourceLocation Loc,
   // 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);
-    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);
+    S.NSNumberDecl = LookupObjCLiteralInterfaceDecl(S, Loc,
+                                                    NSAPI::ClassId_NSNumber);
+    if (!ValidateObjCLiteralInterfaceDecl(S, S.NSNumberDecl,
+                                          Loc, diag::err_undeclared_nsnumber)) {
       return nullptr;
     }
   }
@@ -457,6 +478,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
   if (RValue.isInvalid()) {
     return ExprError();
   }
+  SourceLocation Loc = SR.getBegin();
   ValueExpr = RValue.get();
   QualType ValueType(ValueExpr->getType());
   if (const PointerType *PT = ValueType->getAs<PointerType>()) {
@@ -464,26 +486,10 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
     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);
-        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);
+        NSStringDecl = LookupObjCLiteralInterfaceDecl(*this, Loc,
+                                                      NSAPI::ClassId_NSString);
+        if (!ValidateObjCLiteralInterfaceDecl(*this, NSStringDecl, Loc,
+                                              diag::err_undeclared_nsstring)) {
           return ExprError();
         }
         assert(NSStringDecl && "NSStringDecl should not be NULL");
@@ -520,7 +526,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
           BoxingMethod = M;
         }
 
-        if (!validateBoxingMethod(*this, SR.getBegin(), NSStringDecl,
+        if (!validateBoxingMethod(*this, Loc, NSStringDecl,
                                   stringWithUTF8String, BoxingMethod))
            return ExprError();
 
@@ -563,16 +569,16 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
     // 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 +588,13 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
     // 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);
-      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);
+      NSValueDecl = LookupObjCLiteralInterfaceDecl(*this, Loc,
+                                                   NSAPI::ClassId_NSValue);
+      if (!ValidateObjCLiteralInterfaceDecl(*this, NSValueDecl, Loc,
+                                            diag::err_undeclared_nsvalue)) {
         return ExprError();
       }
-      
+
       // generate the pointer to NSValue type.
       QualType NSValueObject = Context.getObjCInterfaceType(NSValueDecl);
       NSValuePointer = Context.getObjCObjectPointerType(NSValueObject);
@@ -663,7 +653,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
         BoxingMethod = M;
       }
       
-      if (!validateBoxingMethod(*this, SR.getBegin(), NSValueDecl,
+      if (!validateBoxingMethod(*this, Loc, NSValueDecl,
                                 ValueWithBytesObjCType, BoxingMethod))
         return ExprError();
       
@@ -671,7 +661,7 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
     }
     
     if (!ValueType.isTriviallyCopyableType(Context)) {
-      Diag(SR.getBegin(), 
+      Diag(Loc,
            diag::err_objc_non_trivially_copyable_boxed_expression_type)
         << ValueType << ValueExpr->getSourceRange();
       return ExprError();
@@ -682,12 +672,12 @@ ExprResult Sema::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
   }
 
   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 +736,17 @@ ExprResult Sema::BuildObjCSubscriptExpression(SourceLocation RB, Expr *BaseExpr,
 }
 
 ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
-  // Look up the NSArray class, if we haven't done so already.
+  SourceLocation Loc = SR.getBegin();
+
   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());
-
-    if (!NSArrayDecl) {
-      Diag(SR.getBegin(), diag::err_undeclared_nsarray);
+    NSArrayDecl = LookupObjCLiteralInterfaceDecl(*this, Loc,
+                                                 NSAPI::ClassId_NSArray);
+    if (!ValidateObjCLiteralInterfaceDecl(*this, NSArrayDecl,
+                                          Loc, 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 +782,7 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
       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 +843,17 @@ ExprResult Sema::BuildObjCArrayLiteral(SourceRange SR, MultiExprArg Elements) {
 ExprResult Sema::BuildObjCDictionaryLiteral(SourceRange SR, 
                                             ObjCDictionaryElement *Elements,
                                             unsigned NumElements) {
-  // Look up the NSDictionary class, if we haven't done so already.
+  SourceLocation Loc = SR.getBegin();
+
   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());
-
-    if (!NSDictionaryDecl) {
-      Diag(SR.getBegin(), diag::err_undeclared_nsdictionary);
-      return ExprError();    
+    NSDictionaryDecl = LookupObjCLiteralInterfaceDecl(*this, Loc,
+                                                   NSAPI::ClassId_NSDictionary);
+    if (!ValidateObjCLiteralInterfaceDecl(*this, NSDictionaryDecl, Loc,
+                                          diag::err_undeclared_nsdictionary)) {
+      return ExprError();
     }
   }
-  
+
   // Find the dictionaryWithObjects:forKeys:count: method, if we haven't done
   // so already.
   QualType IdT = Context.getObjCIdType();
diff --git test/SemaObjC/objc-array-literal.m test/SemaObjC/objc-array-literal.m
index 2971fcc..ceb3874 100644
--- test/SemaObjC/objc-array-literal.m
+++ test/SemaObjC/objc-array-literal.m
@@ -14,11 +14,11 @@ void checkNSArrayUnavailableDiagnostic() {
   id arr = @[obj]; // expected-error {{NSArray must be available to use Objective-C array literals}}
 }
 
-@class NSArray;
+@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 {{NSArray must be available to use Objective-C array literals}}
 }
 
 @class NSString;
diff --git test/SemaObjC/objc-dictionary-literal.m test/SemaObjC/objc-dictionary-literal.m
index 87f127f..d4ebd6e 100644
--- test/SemaObjC/objc-dictionary-literal.m
+++ test/SemaObjC/objc-dictionary-literal.m
@@ -11,12 +11,12 @@ void checkNSDictionaryUnavailableDiagnostic() {
   id dict = @{ key : value }; // expected-error {{NSDictionary must be available to use Objective-C dictionary literals}}
 }
 
-@class NSDictionary;
+@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 {{NSDictionary must be available to use Objective-C dictionary literals}}
 }
 
 @interface NSNumber
diff --git test/SemaObjC/objc-literal-nsnumber.m test/SemaObjC/objc-literal-nsnumber.m
index 57bc07b..fd60462 100644
--- test/SemaObjC/objc-literal-nsnumber.m
+++ test/SemaObjC/objc-literal-nsnumber.m
@@ -17,7 +17,7 @@ void checkNSNumberUnavailableDiagnostic() {
                   // expected-error {{illegal type 'int' used in a boxed expression}}
 }
 
-@class NSNumber;
+@class NSNumber; // expected-note {{forward declaration of class here}}
 
 void checkNSNumberFDDiagnostic() {
   id num = @1000; // expected-error {{NSNumber must be available to use Objective-C literals}}
@@ -71,10 +71,10 @@ int main() {
 }
 
 // Dictionary test
-@class NSDictionary;
+@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 {{NSDictionary must be available to use Objective-C dictionary literals}}
 }
 
 @interface NSDate : NSObject
