<div dir="ltr">With this commit, I'm hitting the following assertion:<div><br></div><div><p style="margin:0px;font-size:11px;font-family:Menlo">Assertion failed: (!WritingAST && "Already writing the AST!"), function DeclarationMarkedUsed, file /Volumes/storage/llvm/tools/clang/lib/Serialization/ASTWriter.cpp, line 5376.</p>
</div><div><br></div><div>(Unfortunately, it's going to be a bit difficult to reduce.)</div><div><br></div>Basically, what happens is that ASTWriter::WriteASTCore() calls ASTReader::updateOutOfDateIdentifier(), which eventually calls ASTDeclReader::UpdateDecl, which explodes because we're updating the AST in the middle of writing it.<div>
<br></div><div>What do you think of moving the loop which call updateOutOfDateIdentifier out into ASTWriter::WriteAST, before we set WritingAST to true?</div><div><br></div><div>-Eli</div><div><br></div></div><div class="gmail_extra">
<br><br><div class="gmail_quote">On Wed, Sep 4, 2013 at 5:02 PM, Eli Friedman <span dir="ltr"><<a href="mailto:eli.friedman@gmail.com" target="_blank">eli.friedman@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: efriedma<br>
Date: Wed Sep  4 19:02:25 2013<br>
New Revision: 190016<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=190016&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=190016&view=rev</a><br>
Log:<br>
Note when a decl is used in AST files.<br>
<br>
When an AST file is built based on another AST file, it can use a decl from<br>
the fist file, and therefore mark the "isUsed" bit.  We need to note this in<br>
the AST file so that the bit is set correctly when the second AST file is<br>
loaded.<br>
<br>
This patch introduces the distinction between setIsUsed() and markUsed() so<br>
that we don't call into the ASTMutationListener callback when it wouldn't<br>
be appropriate.<br>
<br>
Fixes PR16635.<br>
<br>
Added:<br>
    cfe/trunk/test/Modules/Inputs/pch-used.h<br>
    cfe/trunk/test/Modules/pch-used.m<br>
Modified:<br>
    cfe/trunk/include/clang/AST/ASTMutationListener.h<br>
    cfe/trunk/include/clang/AST/DeclBase.h<br>
    cfe/trunk/include/clang/Serialization/ASTWriter.h<br>
    cfe/trunk/lib/AST/DeclBase.cpp<br>
    cfe/trunk/lib/Frontend/MultiplexConsumer.cpp<br>
    cfe/trunk/lib/Sema/SemaDecl.cpp<br>
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
    cfe/trunk/lib/Sema/SemaExpr.cpp<br>
    cfe/trunk/lib/Sema/SemaLambda.cpp<br>
    cfe/trunk/lib/Sema/SemaStmt.cpp<br>
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
    cfe/trunk/lib/Serialization/ASTCommon.h<br>
    cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
    cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h<br>
<br>
Modified: cfe/trunk/include/clang/AST/ASTMutationListener.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/ASTMutationListener.h (original)<br>
+++ cfe/trunk/include/clang/AST/ASTMutationListener.h Wed Sep  4 19:02:25 2013<br>
@@ -90,6 +90,11 @@ public:<br>
                                             const ObjCPropertyDecl *OrigProp,<br>
                                             const ObjCCategoryDecl *ClassExt) {}<br>
<br>
+  /// \brief A declaration is marked used which was not previously marked used.<br>
+  ///<br>
+  /// \param D the declaration marked used<br>
+  virtual void DeclarationMarkedUsed(const Decl *D) {}<br>
+<br>
   // NOTE: If new methods are added they should also be added to<br>
   // MultiplexASTMutationListener.<br>
 };<br>
<br>
Modified: cfe/trunk/include/clang/AST/DeclBase.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/AST/DeclBase.h (original)<br>
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Sep  4 19:02:25 2013<br>
@@ -500,7 +500,16 @@ public:<br>
   /// whether the function is used.<br>
   bool isUsed(bool CheckUsedAttr = true) const;<br>
<br>
-  void setUsed(bool U = true) { Used = U; }<br>
+  /// \brief Set whether the declaration is used, in the sense of odr-use.<br>
+  ///<br>
+  /// This should only be used immediately after creating a declaration.<br>
+  void setIsUsed(bool U) { Used = U; }<br>
+<br>
+  /// \brief Mark the declaration used, in the sense of odr-use.<br>
+  ///<br>
+  /// This notifies any mutation listeners in addition to setting a bit<br>
+  /// indicating the declaration is used.<br>
+  void markUsed(ASTContext &C);<br>
<br>
   /// \brief Whether this declaration was referenced.<br>
   bool isReferenced() const;<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Wed Sep  4 19:02:25 2013<br>
@@ -743,6 +743,7 @@ public:<br>
   virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,<br>
                                             const ObjCPropertyDecl *OrigProp,<br>
                                             const ObjCCategoryDecl *ClassExt);<br>
+  void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE;<br>
 };<br>
<br>
 /// \brief AST and semantic-analysis consumer that generates a<br>
<br>
Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Sep  4 19:02:25 2013<br>
@@ -291,6 +291,16 @@ bool Decl::isUsed(bool CheckUsedAttr) co<br>
   return false;<br>
 }<br>
<br>
+void Decl::markUsed(ASTContext &C) {<br>
+  if (Used)<br>
+    return;<br>
+<br>
+  if (C.getASTMutationListener())<br>
+    C.getASTMutationListener()->DeclarationMarkedUsed(this);<br>
+<br>
+  Used = true;<br>
+}<br>
+<br>
 bool Decl::isReferenced() const {<br>
   if (Referenced)<br>
     return true;<br>
<br>
Modified: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Wed Sep  4 19:02:25 2013<br>
@@ -107,6 +107,8 @@ public:<br>
   virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop,<br>
                                             const ObjCPropertyDecl *OrigProp,<br>
                                             const ObjCCategoryDecl *ClassExt);<br>
+  void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE;<br>
+<br>
 private:<br>
   std::vector<ASTMutationListener*> Listeners;<br>
 };<br>
@@ -175,6 +177,10 @@ void MultiplexASTMutationListener::Added<br>
   for (size_t i = 0, e = Listeners.size(); i != e; ++i)<br>
     Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp, ClassExt);<br>
 }<br>
+void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) {<br>
+  for (size_t i = 0, e = Listeners.size(); i != e; ++i)<br>
+    Listeners[i]->DeclarationMarkedUsed(D);<br>
+}<br>
<br>
 }  // end namespace clang<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Sep  4 19:02:25 2013<br>
@@ -2739,8 +2739,7 @@ bool Sema::MergeCompatibleFunctionDecls(<br>
     New->setPure();<br>
<br>
   // Merge "used" flag.<br>
-  if (Old->isUsed(false))<br>
-    New->setUsed();<br>
+  New->setIsUsed(Old->isUsed(false));<br>
<br>
   // Merge attributes from the parameters.  These can mismatch with K&R<br>
   // declarations.<br>
@@ -3050,8 +3049,7 @@ void Sema::MergeVarDecl(VarDecl *New, Lo<br>
   }<br>
<br>
   // Merge "used" flag.<br>
-  if (Old->isUsed(false))<br>
-    New->setUsed();<br>
+  New->setIsUsed(Old->isUsed(false));<br>
<br>
   // Keep a chain of previous declarations.<br>
   New->setPreviousDeclaration(Old);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep  4 19:02:25 2013<br>
@@ -7951,7 +7951,7 @@ void Sema::DefineImplicitDefaultConstruc<br>
   SourceLocation Loc = Constructor->getLocation();<br>
   Constructor->setBody(new (Context) CompoundStmt(Loc));<br>
<br>
-  Constructor->setUsed();<br>
+  Constructor->markUsed(Context);<br>
   MarkVTableUsed(CurrentLocation, ClassDecl);<br>
<br>
   if (ASTMutationListener *L = getASTMutationListener()) {<br>
@@ -8289,7 +8289,7 @@ void Sema::DefineInheritingConstructor(S<br>
   SourceLocation Loc = Constructor->getLocation();<br>
   Constructor->setBody(new (Context) CompoundStmt(Loc));<br>
<br>
-  Constructor->setUsed();<br>
+  Constructor->markUsed(Context);<br>
   MarkVTableUsed(CurrentLocation, ClassDecl);<br>
<br>
   if (ASTMutationListener *L = getASTMutationListener()) {<br>
@@ -8421,7 +8421,7 @@ void Sema::DefineImplicitDestructor(Sour<br>
<br>
   SourceLocation Loc = Destructor->getLocation();<br>
   Destructor->setBody(new (Context) CompoundStmt(Loc));<br>
-  Destructor->setUsed();<br>
+  Destructor->markUsed(Context);<br>
   MarkVTableUsed(CurrentLocation, ClassDecl);<br>
<br>
   if (ASTMutationListener *L = getASTMutationListener()) {<br>
@@ -9117,7 +9117,7 @@ void Sema::DefineImplicitCopyAssignment(<br>
   if (getLangOpts().CPlusPlus11 && CopyAssignOperator->isImplicit())<br>
     diagnoseDeprecatedCopyOperation(*this, CopyAssignOperator, CurrentLocation);<br>
<br>
-  CopyAssignOperator->setUsed();<br>
+  CopyAssignOperator->markUsed(Context);<br>
<br>
   SynthesizedFunctionScope Scope(*this, CopyAssignOperator);<br>
   DiagnosticErrorTrap Trap(Diags);<br>
@@ -9562,7 +9562,7 @@ void Sema::DefineImplicitMoveAssignment(<br>
     return;<br>
   }<br>
<br>
-  MoveAssignOperator->setUsed();<br>
+  MoveAssignOperator->markUsed(Context);<br>
<br>
   SynthesizedFunctionScope Scope(*this, MoveAssignOperator);<br>
   DiagnosticErrorTrap Trap(Diags);<br>
@@ -9915,7 +9915,7 @@ void Sema::DefineImplicitCopyConstructor<br>
         /*isStmtExpr=*/ false).takeAs<Stmt>());<br>
   }<br>
<br>
-  CopyConstructor->setUsed();<br>
+  CopyConstructor->markUsed(Context);<br>
   if (ASTMutationListener *L = getASTMutationListener()) {<br>
     L->CompletedImplicitDefinition(CopyConstructor);<br>
   }<br>
@@ -10101,7 +10101,7 @@ void Sema::DefineImplicitMoveConstructor<br>
         /*isStmtExpr=*/ false).takeAs<Stmt>());<br>
   }<br>
<br>
-  MoveConstructor->setUsed();<br>
+  MoveConstructor->markUsed(Context);<br>
<br>
   if (ASTMutationListener *L = getASTMutationListener()) {<br>
     L->CompletedImplicitDefinition(MoveConstructor);<br>
@@ -10119,7 +10119,7 @@ static void markLambdaCallOperatorUsed(S<br>
         Lambda->lookup(<br>
           S.Context.DeclarationNames.getCXXOperatorName(OO_Call)).front());<br>
   CallOperator->setReferenced();<br>
-  CallOperator->setUsed();<br>
+  CallOperator->markUsed(S.Context);<br>
 }<br>
<br>
 void Sema::DefineImplicitLambdaToFunctionPointerConversion(<br>
@@ -10131,7 +10131,7 @@ void Sema::DefineImplicitLambdaToFunctio<br>
   // Make sure that the lambda call operator is marked used.<br>
   markLambdaCallOperatorUsed(*this, Lambda);<br>
<br>
-  Conv->setUsed();<br>
+  Conv->markUsed(Context);<br>
<br>
   SynthesizedFunctionScope Scope(*this, Conv);<br>
   DiagnosticErrorTrap Trap(Diags);<br>
@@ -10150,7 +10150,7 @@ void Sema::DefineImplicitLambdaToFunctio<br>
<br>
   // Fill in the __invoke function with a dummy implementation. IR generation<br>
   // will fill in the actual details.<br>
-  Invoke->setUsed();<br>
+  Invoke->markUsed(Context);<br>
   Invoke->setReferenced();<br>
   Invoke->setBody(new (Context) CompoundStmt(Conv->getLocation()));<br>
<br>
@@ -10164,7 +10164,7 @@ void Sema::DefineImplicitLambdaToBlockPo<br>
        SourceLocation CurrentLocation,<br>
        CXXConversionDecl *Conv)<br>
 {<br>
-  Conv->setUsed();<br>
+  Conv->markUsed(Context);<br>
<br>
   SynthesizedFunctionScope Scope(*this, Conv);<br>
   DiagnosticErrorTrap Trap(Diags);<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Sep  4 19:02:25 2013<br>
@@ -9623,7 +9623,7 @@ ExprResult Sema::ActOnUnaryOp(Scope *S,<br>
 /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".<br>
 ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation LabLoc,<br>
                                 LabelDecl *TheDecl) {<br>
-  TheDecl->setUsed();<br>
+  TheDecl->markUsed(Context);<br>
   // Create the AST node.  The address of a label always has type 'void*'.<br>
   return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,<br>
                                        Context.getPointerType(Context.VoidTy)));<br>
@@ -11097,7 +11097,7 @@ void Sema::MarkFunctionReferenced(Source<br>
   // decl in the middle of a decl chain. We loop to maintain the invariant<br>
   // that once a decl is used, all decls after it are also used.<br>
   for (FunctionDecl *F = Func->getMostRecentDecl();; F = F->getPreviousDecl()) {<br>
-    F->setUsed(true);<br>
+    F->markUsed(Context);<br>
     if (F == Func)<br>
       break;<br>
   }<br>
@@ -11172,7 +11172,7 @@ static ExprResult captureInCapturedRegio<br>
   Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,<br>
                                           DeclRefType, VK_LValue, Loc);<br>
   Var->setReferenced(true);<br>
-  Var->setUsed(true);<br>
+  Var->markUsed(S.Context);<br>
<br>
   return Ref;<br>
 }<br>
@@ -11214,7 +11214,7 @@ static ExprResult captureInLambda(Sema &<br>
   Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,<br>
                                           DeclRefType, VK_LValue, Loc);<br>
   Var->setReferenced(true);<br>
-  Var->setUsed(true);<br>
+  Var->markUsed(S.Context);<br>
<br>
   // When the field has array type, create index variables for each<br>
   // dimension of the array. We use these index variables to subscript<br>
@@ -11660,7 +11660,7 @@ static void MarkVarDeclODRUsed(Sema &Sem<br>
<br>
   SemaRef.tryCaptureVariable(Var, Loc);<br>
<br>
-  Var->setUsed(true);<br>
+  Var->markUsed(SemaRef.Context);<br>
 }<br>
<br>
 void Sema::UpdateMarkingForLValueToRValue(Expr *E) {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Wed Sep  4 19:02:25 2013<br>
@@ -1105,7 +1105,7 @@ ExprResult Sema::BuildBlockForLambdaConv<br>
         Lambda->lookup(<br>
           Context.DeclarationNames.getCXXOperatorName(OO_Call)).front());<br>
   CallOperator->setReferenced();<br>
-  CallOperator->setUsed();<br>
+  CallOperator->markUsed(Context);<br>
<br>
   ExprResult Init = PerformCopyInitialization(<br>
                       InitializedEntity::InitializeBlock(ConvLocation,<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed Sep  4 19:02:25 2013<br>
@@ -2041,7 +2041,7 @@ Sema::BuildCXXForRangeStmt(SourceLocatio<br>
<br>
   if (RangeVarType->isDependentType()) {<br>
     // The range is implicitly used as a placeholder when it is dependent.<br>
-    RangeVar->setUsed();<br>
+    RangeVar->markUsed(Context);<br>
<br>
     // Deduce any 'auto's in the loop variable as 'DependentTy'. We'll fill<br>
     // them in properly when we instantiate the loop.<br>
@@ -2284,7 +2284,7 @@ StmtResult Sema::ActOnGotoStmt(SourceLoc<br>
                                SourceLocation LabelLoc,<br>
                                LabelDecl *TheDecl) {<br>
   getCurFunction()->setHasBranchIntoScope();<br>
-  TheDecl->setUsed();<br>
+  TheDecl->markUsed(Context);<br>
   return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc));<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Sep  4 19:02:25 2013<br>
@@ -3352,7 +3352,7 @@ void Sema::BuildVariableInstantiation(<br>
   NewVar->setAccess(OldVar->getAccess());<br>
<br>
   if (!OldVar->isStaticDataMember()) {<br>
-    NewVar->setUsed(OldVar->isUsed(false));<br>
+    NewVar->setIsUsed(OldVar->isUsed(false));<br>
     NewVar->setReferenced(OldVar->isReferenced());<br>
   }<br>
<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTCommon.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTCommon.h (original)<br>
+++ cfe/trunk/lib/Serialization/ASTCommon.h Wed Sep  4 19:02:25 2013<br>
@@ -26,7 +26,8 @@ enum DeclUpdateKind {<br>
   UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,<br>
   UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,<br>
   UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,<br>
-  UPD_CXX_DEDUCED_RETURN_TYPE<br>
+  UPD_CXX_DEDUCED_RETURN_TYPE,<br>
+  UPD_DECL_MARKED_USED<br>
 };<br>
<br>
 TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Sep  4 19:02:25 2013<br>
@@ -377,7 +377,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {<br>
     D->setAttrsImpl(Attrs, Reader.getContext());<br>
   }<br>
   D->setImplicit(Record[Idx++]);<br>
-  D->setUsed(Record[Idx++]);<br>
+  D->setIsUsed(Record[Idx++]);<br>
   D->setReferenced(Record[Idx++]);<br>
   D->setTopLevelDeclInObjCContainer(Record[Idx++]);<br>
   D->setAccess((AccessSpecifier)Record[Idx++]);<br>
@@ -2838,6 +2838,11 @@ void ASTDeclReader::UpdateDecl(Decl *D,<br>
           FD, Reader.readType(ModuleFile, Record, Idx));<br>
       break;<br>
     }<br>
+<br>
+    case UPD_DECL_MARKED_USED: {<br>
+      D->markUsed(Reader.getContext());<br>
+      break;<br>
+    }<br>
     }<br>
   }<br>
 }<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Sep  4 19:02:25 2013<br>
@@ -4314,6 +4314,7 @@ void ASTWriter::ResolveDeclUpdatesBlocks<br>
         break;<br>
<br>
       case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:<br>
+      case UPD_DECL_MARKED_USED:<br>
         ++Idx;<br>
         break;<br>
<br>
@@ -5370,3 +5371,12 @@ void ASTWriter::AddedObjCPropertyInClass<br>
<br>
   RewriteDecl(D);<br>
 }<br>
+<br>
+void ASTWriter::DeclarationMarkedUsed(const Decl *D) {<br>
+  assert(!WritingAST && "Already writing the AST!");<br>
+  if (!D->isFromASTFile())<br>
+    return;<br>
+<br>
+  UpdateRecord &Record = DeclUpdates[D];<br>
+  Record.push_back(UPD_DECL_MARKED_USED);<br>
+}<br>
<br>
Modified: cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h?rev=190016&r1=190015&r2=190016&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h?rev=190016&r1=190015&r2=190016&view=diff</a><br>

==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h (original)<br>
+++ cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h Wed Sep  4 19:02:25 2013<br>
@@ -1,3 +1,3 @@<br>
 typedef struct { int id; } FILE;<br>
 int fprintf(FILE*restrict, const char* restrict format, ...);<br>
-<br>
+extern FILE *__stderrp;<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/pch-used.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/pch-used.h?rev=190016&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/pch-used.h?rev=190016&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/pch-used.h (added)<br>
+++ cfe/trunk/test/Modules/Inputs/pch-used.h Wed Sep  4 19:02:25 2013<br>
@@ -0,0 +1,2 @@<br>
+@import cstd.stdio;<br>
+static inline void SPXTrace() { fprintf(__stderrp, ""); }<br>
<br>
Added: cfe/trunk/test/Modules/pch-used.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pch-used.m?rev=190016&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pch-used.m?rev=190016&view=auto</a><br>

==============================================================================<br>
--- cfe/trunk/test/Modules/pch-used.m (added)<br>
+++ cfe/trunk/test/Modules/pch-used.m Wed Sep  4 19:02:25 2013<br>
@@ -0,0 +1,8 @@<br>
+// RUN: rm -rf %t<br>
+// RUN: mkdir %t<br>
+// RUN: %clang_cc1 -x objective-c-header -emit-pch %S/Inputs/pch-used.h -o %t/pch-used.h.pch -fmodules -fmodules-cache-path=%t/cache -O0 -isystem %S/Inputs/System/usr/include<br>
+// RUN: %clang_cc1 %s -include-pch %t/pch-used.h.pch -fmodules -fmodules-cache-path=%t/cache -O0 -isystem %S/Inputs/System/usr/include -emit-llvm -o - | FileCheck %s<br>
+<br>
+void f() { SPXTrace(); }<br>
+<br>
+// CHECK: define internal void @SPXTrace<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div>