<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Jun 20, 2015, at 12:24 PM, Aaron Ballman <<a href="mailto:aaron@aaronballman.com" class="">aaron@aaronballman.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">On Fri, Jun 19, 2015 at 2:25 PM, Douglas Gregor <</span><a href="mailto:dgregor@apple.com" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">dgregor@apple.com</a><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">> wrote:</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">Author: dgregor<br class="">Date: Fri Jun 19 13:25:57 2015<br class="">New Revision: 240156<br class=""><br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D240156-26view-3Drev&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=DIMl__g0CwiSLOgV9qLwpu8TJxezEuQCzmOERSTlDN4&e=" class="">http://llvm.org/viewvc/llvm-project?rev=240156&view=rev</a><br class="">Log:<br class="">Introduced pragmas for audited nullability regions.<br class=""><br class="">Introduce the clang pragmas "assume_nonnull begin" and "assume_nonnull<br class="">end" in which we make default assumptions about the nullability of many<br class="">unannotated pointers:<br class=""><br class=""> - Single-level pointers are inferred to __nonnull<br class=""> - NSError** in a (function or method) parameter list is inferred to<br class="">   NSError * __nullable * __nullable.<br class=""> - CFErrorRef * in a (function or method) parameter list is inferred<br class="">   to CFErrorRef __nullable * __nullable.<br class=""> - Other multi-level pointers are never inferred to anything.<br class=""><br class="">Implements <a href="rdar://problem/19191042" class="">rdar://problem/19191042</a>.<br class=""><br class="">Added:<br class="">   cfe/trunk/test/SemaObjCXX/Inputs/nullability-pragmas-1.h   (with props)<br class="">   cfe/trunk/test/SemaObjCXX/Inputs/nullability-pragmas-2.h   (with props)<br class="">   cfe/trunk/test/SemaObjCXX/Inputs/nullability-pragmas-3.h   (with props)<br class="">   cfe/trunk/test/SemaObjCXX/nullability-pragmas.mm<br class="">Modified:<br class="">   cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td<br class="">   cfe/trunk/include/clang/Lex/Preprocessor.h<br class="">   cfe/trunk/include/clang/Parse/Parser.h<br class="">   cfe/trunk/include/clang/Sema/DeclSpec.h<br class="">   cfe/trunk/include/clang/Sema/Sema.h<br class="">   cfe/trunk/lib/Lex/PPDirectives.cpp<br class="">   cfe/trunk/lib/Lex/PPLexerChange.cpp<br class="">   cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br class="">   cfe/trunk/lib/Lex/Pragma.cpp<br class="">   cfe/trunk/lib/Parse/ParseObjc.cpp<br class="">   cfe/trunk/lib/Sema/SemaExprObjC.cpp<br class="">   cfe/trunk/lib/Sema/SemaObjCProperty.cpp<br class="">   cfe/trunk/lib/Sema/SemaType.cpp<br class="">   cfe/trunk/test/SemaObjC/arc-property-decl-attrs.m<br class=""><br class="">Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Basic_DiagnosticLexKinds.td-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=nMdNGhWRpesOFBLs8YBok75yjU3dkVlao84BQPnNLeo&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)<br class="">+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Fri Jun 19 13:25:57 2015<br class="">@@ -646,5 +646,20 @@ def warn_header_guard : Warning<<br class="">  "%0 is used as a header guard here, followed by #define of a different macro">,<br class="">  InGroup<DiagGroup<"header-guard">>;<br class="">def note_header_guard : Note<<br class="">-  "%0 is defined here; did you mean %1?">;<br class="">+  "%0 is defined here; did you mean %1?">;<br class="">+<br class="">+let CategoryName = "Nullability Issue" in {<br class="">+<br class="">+def err_pp_assume_nonnull_syntax : Error<"expected 'begin' or 'end'">;<br class="">+def err_pp_double_begin_of_assume_nonnull : Error<<br class="">+  "already inside '#pragma clang assume_nonnull'">;<br class="">+def err_pp_unmatched_end_of_assume_nonnull : Error<<br class="">+  "not currently inside '#pragma clang assume_nonnull'">;<br class="">+def err_pp_include_in_assume_nonnull : Error<<br class="">+  "cannot #include files inside '#pragma clang assume_nonnull'">;<br class="">+def err_pp_eof_in_assume_nonnull : Error<<br class="">+  "'#pragma clang assume_nonnull' was not ended within this file">;<br class="">+<br class="">+}<br class="">+<br class="">}<br class=""><br class="">Modified: cfe/trunk/include/clang/Lex/Preprocessor.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Lex_Preprocessor.h-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=X_D_kv2m0Jq73ESqcWd9u6TK8_G72ZtZ-N4FTxsjWNY&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/Preprocessor.h?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Lex/Preprocessor.h (original)<br class="">+++ cfe/trunk/include/clang/Lex/Preprocessor.h Fri Jun 19 13:25:57 2015<br class="">@@ -256,6 +256,10 @@ class Preprocessor : public RefCountedBa<br class="">  /// \#pragma clang arc_cf_code_audited begin.<br class="">  SourceLocation PragmaARCCFCodeAuditedLoc;<br class=""><br class="">+  /// \brief The source location of the currently-active<br class="">+  /// \#pragma clang assume_nonnull begin.<br class="">+  SourceLocation PragmaAssumeNonNullLoc;<br class="">+<br class="">  /// \brief True if we hit the code-completion point.<br class="">  bool CodeCompletionReached;<br class=""><br class="">@@ -1250,6 +1254,20 @@ public:<br class="">    PragmaARCCFCodeAuditedLoc = Loc;<br class="">  }<br class=""><br class="">+  /// \brief The location of the currently-active \#pragma clang<br class="">+  /// assume_nonnull begin.<br class="">+  ///<br class="">+  /// Returns an invalid location if there is no such pragma active.<br class="">+  SourceLocation getPragmaAssumeNonNullLoc() const {<br class="">+    return PragmaAssumeNonNullLoc;<br class="">+  }<br class="">+<br class="">+  /// \brief Set the location of the currently-active \#pragma clang<br class="">+  /// assume_nonnull begin.  An invalid location ends the pragma.<br class="">+  void setPragmaAssumeNonNullLoc(SourceLocation Loc) {<br class="">+    PragmaAssumeNonNullLoc = Loc;<br class="">+  }<br class="">+<br class="">  /// \brief Set the directory in which the main file should be considered<br class="">  /// to have been found, if it is not a real file.<br class="">  void setMainFileDir(const DirectoryEntry *Dir) {<br class=""><br class="">Modified: cfe/trunk/include/clang/Parse/Parser.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Parse_Parser.h-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=L7xhq7OM9XqBQW2iAprMrg2k6t3q2mX8OU7lYkPguTg&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Parse/Parser.h (original)<br class="">+++ cfe/trunk/include/clang/Parse/Parser.h Fri Jun 19 13:25:57 2015<br class="">@@ -139,11 +139,6 @@ class Parser : public CodeCompletionHand<br class="">  // used as type traits.<br class="">  llvm::SmallDenseMap<IdentifierInfo *, tok::TokenKind> RevertibleTypeTraits;<br class=""><br class="">-  /// Nullability type specifiers.<br class="">-  IdentifierInfo *Ident___nonnull = nullptr;<br class="">-  IdentifierInfo *Ident___nullable = nullptr;<br class="">-  IdentifierInfo *Ident___null_unspecified = nullptr;<br class="">-<br class="">  std::unique_ptr<PragmaHandler> AlignHandler;<br class="">  std::unique_ptr<PragmaHandler> GCCVisibilityHandler;<br class="">  std::unique_ptr<PragmaHandler> OptionsHandler;<br class="">@@ -308,9 +303,11 @@ public:<br class="">    return true;<br class="">  }<br class=""><br class="">-  /// Retrieve the underscored keyword (__nonnull, __nullable,<br class="">-  /// __null_unspecified) that corresponds to the given nullability kind.<br class="">-  IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability);<br class="">+  /// Retrieve the underscored keyword (__nonnull, __nullable) that corresponds<br class="">+  /// to the given nullability kind.<br class="">+  IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability) {<br class="">+    return Actions.getNullabilityKeyword(nullability);<br class="">+  }<br class=""><br class="">private:<br class="">  //===--------------------------------------------------------------------===//<br class=""><br class="">Modified: cfe/trunk/include/clang/Sema/DeclSpec.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Sema_DeclSpec.h-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=vkMamZB84Y22KrYpc5wqUrzPtaIFmMyQgsXWZEvwVCI&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/DeclSpec.h?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Sema/DeclSpec.h (original)<br class="">+++ cfe/trunk/include/clang/Sema/DeclSpec.h Fri Jun 19 13:25:57 2015<br class="">@@ -1650,7 +1650,13 @@ private:<br class="">  bool InlineParamsUsed;<br class=""><br class="">  /// \brief true if the declaration is preceded by \c __extension__.<br class="">-  bool Extension : 1;<br class="">+  unsigned Extension : 1;<br class="">+<br class="">+  /// Indicates whether this is an Objective-C instance variable.<br class="">+  unsigned ObjCIvar : 1;<br class="">+<br class="">+  /// Indicates whether this is an Objective-C 'weak' property.<br class="">+  unsigned ObjCWeakProperty : 1;<br class=""><br class="">  /// \brief If this is the second or subsequent declarator in this declaration,<br class="">  /// the location of the comma before this declarator.<br class="">@@ -1669,7 +1675,8 @@ public:<br class="">      GroupingParens(false), FunctionDefinition(FDK_Declaration),<br class="">      Redeclaration(false),<br class="">      Attrs(ds.getAttributePool().getFactory()), AsmLabel(nullptr),<br class="">-      InlineParamsUsed(false), Extension(false) {<br class="">+      InlineParamsUsed(false), Extension(false), ObjCIvar(false),<br class="">+      ObjCWeakProperty(false) {<br class="">  }<br class=""><br class="">  ~Declarator() {<br class="">@@ -1747,6 +1754,8 @@ public:<br class="">    Attrs.clear();<br class="">    AsmLabel = nullptr;<br class="">    InlineParamsUsed = false;<br class="">+    ObjCIvar = false;<br class="">+    ObjCWeakProperty = false;<br class="">    CommaLoc = SourceLocation();<br class="">    EllipsisLoc = SourceLocation();<br class="">  }<br class="">@@ -2155,6 +2164,12 @@ public:<br class="">  void setExtension(bool Val = true) { Extension = Val; }<br class="">  bool getExtension() const { return Extension; }<br class=""><br class="">+  void setObjCIvar(bool Val = true) { ObjCIvar = Val; }<br class="">+  bool isObjCIvar() const { return ObjCIvar; }<br class="">+<br class="">+  void setObjCWeakProperty(bool Val = true) { ObjCWeakProperty = Val; }<br class="">+  bool isObjCWeakProperty() const { return ObjCWeakProperty; }<br class="">+<br class="">  void setInvalidType(bool Val = true) { InvalidType = Val; }<br class="">  bool isInvalidType() const {<br class="">    return InvalidType || DS.getTypeSpecType() == DeclSpec::TST_error;<br class=""><br class="">Modified: cfe/trunk/include/clang/Sema/Sema.h<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_Sema_Sema.h-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=jS2H0bLux73UDJWRwG3od5PdRSAIusZyrNNR1VUbEW8&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Sema/Sema.h (original)<br class="">+++ cfe/trunk/include/clang/Sema/Sema.h Fri Jun 19 13:25:57 2015<br class="">@@ -1157,6 +1157,16 @@ public:<br class=""><br class="">  bool CheckFunctionReturnType(QualType T, SourceLocation Loc);<br class=""><br class="">+  unsigned deduceWeakPropertyFromType(QualType T) {<br class="">+    if ((getLangOpts().getGC() != LangOptions::NonGC &&<br class="">+         T.isObjCGCWeak()) ||<br class="">+        (getLangOpts().ObjCAutoRefCount &&<br class="">+         T.getObjCLifetime() == Qualifiers::OCL_Weak))<br class="">+        return ObjCDeclSpec::DQ_PR_weak;<br class="">+    return 0;<br class="">+  }<br class="">+<br class="">+<br class="">  /// \brief Build a function type.<br class="">  ///<br class="">  /// This routine checks the function type according to C++ rules and<br class="">@@ -8782,6 +8792,13 @@ private:<br class="">  mutable IdentifierInfo *Ident_super;<br class="">  mutable IdentifierInfo *Ident___float128;<br class=""><br class="">+  /// Nullability type specifiers.<br class="">+  IdentifierInfo *Ident___nonnull = nullptr;<br class="">+  IdentifierInfo *Ident___nullable = nullptr;<br class="">+  IdentifierInfo *Ident___null_unspecified = nullptr;<br class="">+<br class="">+  IdentifierInfo *Ident_NSError = nullptr;<br class="">+<br class="">protected:<br class="">  friend class Parser;<br class="">  friend class InitializationSequence;<br class="">@@ -8790,6 +8807,15 @@ protected:<br class="">  friend class ASTWriter;<br class=""><br class="">public:<br class="">+  /// Retrieve the keyword associated<br class="">+  IdentifierInfo *getNullabilityKeyword(NullabilityKind nullability);<br class="">+<br class="">+  /// The struct behind the CFErrorRef pointer.<br class="">+  RecordDecl *CFError = nullptr;<br class="">+<br class="">+  /// Retrieve the identifier "NSError".<br class="">+  IdentifierInfo *getNSErrorIdent();<br class="">+<br class="">  /// \brief Retrieve the parser's current scope.<br class="">  ///<br class="">  /// This routine must only be used when it is certain that semantic analysis<br class=""><br class="">Modified: cfe/trunk/lib/Lex/PPDirectives.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Lex_PPDirectives.cpp-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=D0a6a-LmReuPpmAJZ3-TFivsQsn4AFSKAoGtWe4zpes&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPDirectives.cpp?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Lex/PPDirectives.cpp (original)<br class="">+++ cfe/trunk/lib/Lex/PPDirectives.cpp Fri Jun 19 13:25:57 2015<br class="">@@ -1575,6 +1575,15 @@ void Preprocessor::HandleIncludeDirectiv<br class="">    PragmaARCCFCodeAuditedLoc = SourceLocation();<br class="">  }<br class=""><br class="">+  // Complain about attempts to #include files in an assume-nonnull pragma.<br class="">+  if (PragmaAssumeNonNullLoc.isValid()) {<br class="">+    Diag(HashLoc, diag::err_pp_include_in_assume_nonnull);<br class="">+    Diag(PragmaAssumeNonNullLoc, diag::note_pragma_entered_here);<br class="">+<br class="">+    // Immediately leave the pragma.<br class="">+    PragmaAssumeNonNullLoc = SourceLocation();<br class="">+  }<br class="">+<br class="">  if (HeaderInfo.HasIncludeAliasMap()) {<br class="">    // Map the filename with the brackets still attached.  If the name doesn't<br class="">    // map to anything, fall back on the filename we've already gotten the<br class=""><br class="">Modified: cfe/trunk/lib/Lex/PPLexerChange.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Lex_PPLexerChange.cpp-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=RIYcrBX8v9k51VQf1Ch_GYGQQPx9PH8Q6-Ta_BEyH_U&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPLexerChange.cpp?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Lex/PPLexerChange.cpp (original)<br class="">+++ cfe/trunk/lib/Lex/PPLexerChange.cpp Fri Jun 19 13:25:57 2015<br class="">@@ -355,6 +355,17 @@ bool Preprocessor::HandleEndOfFile(Token<br class="">    PragmaARCCFCodeAuditedLoc = SourceLocation();<br class="">  }<br class=""><br class="">+  // Complain about reaching a true EOF within assume_nonnull.<br class="">+  // We don't want to complain about reaching the end of a macro<br class="">+  // instantiation or a _Pragma.<br class="">+  if (PragmaAssumeNonNullLoc.isValid() &&<br class="">+      !isEndOfMacro && !(CurLexer && CurLexer->Is_PragmaLexer)) {<br class="">+    Diag(PragmaAssumeNonNullLoc, diag::err_pp_eof_in_assume_nonnull);<br class="">+<br class="">+    // Recover by leaving immediately.<br class="">+    PragmaAssumeNonNullLoc = SourceLocation();<br class="">+  }<br class="">+<br class="">  // If this is a #include'd file, pop it off the include stack and continue<br class="">  // lexing the #includer file.<br class="">  if (!IncludeMacroStack.empty()) {<br class=""><br class="">Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Lex_PPMacroExpansion.cpp-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=GDy2i02JWly2e3wX93biqJKRppsDmjzST0_IW4m-RmU&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original)<br class="">+++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Jun 19 13:25:57 2015<br class="">@@ -1052,6 +1052,7 @@ static bool HasFeature(const Preprocesso<br class="">      .Case("address_sanitizer",<br class="">            LangOpts.Sanitize.hasOneOf(SanitizerKind::Address |<br class="">                                       SanitizerKind::KernelAddress))<br class="">+      .Case("assume_nonnull", LangOpts.ObjC1 || LangOpts.GNUMode)<br class="">      .Case("attribute_analyzer_noreturn", true)<br class="">      .Case("attribute_availability", true)<br class="">      .Case("attribute_availability_with_message", true)<br class=""><br class="">Modified: cfe/trunk/lib/Lex/Pragma.cpp<br class="">URL: <a href="https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_Lex_Pragma.cpp-3Frev-3D240156-26r1-3D240155-26r2-3D240156-26view-3Ddiff&d=AwMFAg&c=8hUWFZcy2Z-Za5rBPlktOQ&r=BSqEv9KvKMW_Ob8SyngJ70KdZISM_ASROnREeq0cCxk&m=Ru9poBbuYkHTMe4jeFovbdLDTdyUPrDxCxx48uki-78&s=ExgaPEpZ7iScgCMF4uZC201lpvElWObvEOqdtu_ynFw&e=" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Pragma.cpp?rev=240156&r1=240155&r2=240156&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Lex/Pragma.cpp (original)<br class="">+++ cfe/trunk/lib/Lex/Pragma.cpp Fri Jun 19 13:25:57 2015<br class="">@@ -1342,6 +1342,60 @@ struct PragmaARCCFCodeAuditedHandler : p<br class="">  }<br class="">};<br class=""><br class="">+/// PragmaAssumeNonNullHandler -<br class="">+///   \#pragma clang assume_nonnull begin/end<br class="">+struct PragmaAssumeNonNullHandler : public PragmaHandler {<br class="">+  PragmaAssumeNonNullHandler() : PragmaHandler("assume_nonnull") {}<br class="">+  void HandlePragma(Preprocessor &PP, PragmaIntroducerKind Introducer,<br class="">+                    Token &NameTok) override {<br class="">+    SourceLocation Loc = NameTok.getLocation();<br class="">+    bool IsBegin;<br class="">+<br class="">+    Token Tok;<br class="">+<br class="">+    // Lex the 'begin' or 'end'.<br class="">+    PP.LexUnexpandedToken(Tok);<br class="">+    const IdentifierInfo *BeginEnd = Tok.getIdentifierInfo();<br class="">+    if (BeginEnd && BeginEnd->isStr("begin")) {<br class="">+      IsBegin = true;<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Elide braces (here and elsewhere).</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div>FWIW, I find it hideous to elide braces in some parts of an if-else chain and not others.</div><div><br class=""><blockquote type="cite" class=""><div class=""><br class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">+<br class="">+/// Classify the given declarator, whose type-specified is \c type, based on<br class="">+/// what kind of pointer it refers to.<br class="">+///<br class="">+/// This is used to determine the default nullability.<br class="">+static PointerDeclaratorKind classifyPointerDeclarator(Sema &S,<br class="">+                                                       QualType type,<br class="">+                                                       Declarator &declarator) {<br class="">+  unsigned numNormalPointers = 0;<br class="">+<br class="">+  // For any dependent type, we consider it a non-pointer.<br class="">+  if (type->isDependentType())<br class="">+    return PointerDeclaratorKind::NonPointer;<br class="">+<br class="">+  // Look through the declarator chunks to identify pointers.<br class="">+  for (unsigned i = 0, n = declarator.getNumTypeObjects(); i != n; ++i) {<br class="">+    DeclaratorChunk &chunk = declarator.getTypeObject(i);<br class="">+    switch (chunk.Kind) {<br class="">+    case DeclaratorChunk::Array:<br class="">+    case DeclaratorChunk::Function:<br class="">+      break;<br class="">+<br class="">+    case DeclaratorChunk::BlockPointer:<br class="">+    case DeclaratorChunk::MemberPointer:<br class="">+      return numNormalPointers > 0 ? PointerDeclaratorKind::MultiLevelPointer<br class="">+                                   : PointerDeclaratorKind::SingleLevelPointer;<br class="">+<br class="">+    case DeclaratorChunk::Paren:<br class="">+    case DeclaratorChunk::Reference:<br class="">+      continue;<br class="">+<br class="">+    case DeclaratorChunk::Pointer:<br class="">+      ++numNormalPointers;<br class="">+      if (numNormalPointers > 2)<br class=""></blockquote><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px; float: none; display: inline !important;" class="">Why > instead of >=?</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""></div></blockquote><div><br class=""></div>Because of the way we deal with the type-specifier being a pointer (via a typedef), below.</div><div class=""><br class=""></div><div class=""><span class="Apple-tab-span" style="white-space:pre">  </span>- Doug</div><div class=""><br class=""></div></body></html>