r190016 - Note when a decl is used in AST files.

Eli Friedman eli.friedman at gmail.com
Wed Sep 4 18:07:50 PDT 2013


With this commit, I'm hitting the following assertion:

Assertion failed: (!WritingAST && "Already writing the AST!"), function
DeclarationMarkedUsed, file
/Volumes/storage/llvm/tools/clang/lib/Serialization/ASTWriter.cpp, line
5376.

(Unfortunately, it's going to be a bit difficult to reduce.)

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.

What do you think of moving the loop which call updateOutOfDateIdentifier
out into ASTWriter::WriteAST, before we set WritingAST to true?

-Eli



On Wed, Sep 4, 2013 at 5:02 PM, Eli Friedman <eli.friedman at gmail.com> wrote:

> Author: efriedma
> Date: Wed Sep  4 19:02:25 2013
> New Revision: 190016
>
> URL: http://llvm.org/viewvc/llvm-project?rev=190016&view=rev
> Log:
> Note when a decl is used in AST files.
>
> When an AST file is built based on another AST file, it can use a decl from
> the fist file, and therefore mark the "isUsed" bit.  We need to note this
> in
> the AST file so that the bit is set correctly when the second AST file is
> loaded.
>
> This patch introduces the distinction between setIsUsed() and markUsed() so
> that we don't call into the ASTMutationListener callback when it wouldn't
> be appropriate.
>
> Fixes PR16635.
>
> Added:
>     cfe/trunk/test/Modules/Inputs/pch-used.h
>     cfe/trunk/test/Modules/pch-used.m
> Modified:
>     cfe/trunk/include/clang/AST/ASTMutationListener.h
>     cfe/trunk/include/clang/AST/DeclBase.h
>     cfe/trunk/include/clang/Serialization/ASTWriter.h
>     cfe/trunk/lib/AST/DeclBase.cpp
>     cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
>     cfe/trunk/lib/Sema/SemaDecl.cpp
>     cfe/trunk/lib/Sema/SemaDeclCXX.cpp
>     cfe/trunk/lib/Sema/SemaExpr.cpp
>     cfe/trunk/lib/Sema/SemaLambda.cpp
>     cfe/trunk/lib/Sema/SemaStmt.cpp
>     cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
>     cfe/trunk/lib/Serialization/ASTCommon.h
>     cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
>     cfe/trunk/lib/Serialization/ASTWriter.cpp
>     cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h
>
> Modified: cfe/trunk/include/clang/AST/ASTMutationListener.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTMutationListener.h?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTMutationListener.h (original)
> +++ cfe/trunk/include/clang/AST/ASTMutationListener.h Wed Sep  4 19:02:25
> 2013
> @@ -90,6 +90,11 @@ public:
>                                              const ObjCPropertyDecl
> *OrigProp,
>                                              const ObjCCategoryDecl
> *ClassExt) {}
>
> +  /// \brief A declaration is marked used which was not previously marked
> used.
> +  ///
> +  /// \param D the declaration marked used
> +  virtual void DeclarationMarkedUsed(const Decl *D) {}
> +
>    // NOTE: If new methods are added they should also be added to
>    // MultiplexASTMutationListener.
>  };
>
> Modified: cfe/trunk/include/clang/AST/DeclBase.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/DeclBase.h (original)
> +++ cfe/trunk/include/clang/AST/DeclBase.h Wed Sep  4 19:02:25 2013
> @@ -500,7 +500,16 @@ public:
>    /// whether the function is used.
>    bool isUsed(bool CheckUsedAttr = true) const;
>
> -  void setUsed(bool U = true) { Used = U; }
> +  /// \brief Set whether the declaration is used, in the sense of odr-use.
> +  ///
> +  /// This should only be used immediately after creating a declaration.
> +  void setIsUsed(bool U) { Used = U; }
> +
> +  /// \brief Mark the declaration used, in the sense of odr-use.
> +  ///
> +  /// This notifies any mutation listeners in addition to setting a bit
> +  /// indicating the declaration is used.
> +  void markUsed(ASTContext &C);
>
>    /// \brief Whether this declaration was referenced.
>    bool isReferenced() const;
>
> Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTWriter.h Wed Sep  4 19:02:25
> 2013
> @@ -743,6 +743,7 @@ public:
>    virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl
> *Prop,
>                                              const ObjCPropertyDecl
> *OrigProp,
>                                              const ObjCCategoryDecl
> *ClassExt);
> +  void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE;
>  };
>
>  /// \brief AST and semantic-analysis consumer that generates a
>
> Modified: cfe/trunk/lib/AST/DeclBase.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclBase.cpp (original)
> +++ cfe/trunk/lib/AST/DeclBase.cpp Wed Sep  4 19:02:25 2013
> @@ -291,6 +291,16 @@ bool Decl::isUsed(bool CheckUsedAttr) co
>    return false;
>  }
>
> +void Decl::markUsed(ASTContext &C) {
> +  if (Used)
> +    return;
> +
> +  if (C.getASTMutationListener())
> +    C.getASTMutationListener()->DeclarationMarkedUsed(this);
> +
> +  Used = true;
> +}
> +
>  bool Decl::isReferenced() const {
>    if (Referenced)
>      return true;
>
> Modified: cfe/trunk/lib/Frontend/MultiplexConsumer.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/MultiplexConsumer.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Frontend/MultiplexConsumer.cpp (original)
> +++ cfe/trunk/lib/Frontend/MultiplexConsumer.cpp Wed Sep  4 19:02:25 2013
> @@ -107,6 +107,8 @@ public:
>    virtual void AddedObjCPropertyInClassExtension(const ObjCPropertyDecl
> *Prop,
>                                              const ObjCPropertyDecl
> *OrigProp,
>                                              const ObjCCategoryDecl
> *ClassExt);
> +  void DeclarationMarkedUsed(const Decl *D) LLVM_OVERRIDE;
> +
>  private:
>    std::vector<ASTMutationListener*> Listeners;
>  };
> @@ -175,6 +177,10 @@ void MultiplexASTMutationListener::Added
>    for (size_t i = 0, e = Listeners.size(); i != e; ++i)
>      Listeners[i]->AddedObjCPropertyInClassExtension(Prop, OrigProp,
> ClassExt);
>  }
> +void MultiplexASTMutationListener::DeclarationMarkedUsed(const Decl *D) {
> +  for (size_t i = 0, e = Listeners.size(); i != e; ++i)
> +    Listeners[i]->DeclarationMarkedUsed(D);
> +}
>
>  }  // end namespace clang
>
>
> Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDecl.cpp Wed Sep  4 19:02:25 2013
> @@ -2739,8 +2739,7 @@ bool Sema::MergeCompatibleFunctionDecls(
>      New->setPure();
>
>    // Merge "used" flag.
> -  if (Old->isUsed(false))
> -    New->setUsed();
> +  New->setIsUsed(Old->isUsed(false));
>
>    // Merge attributes from the parameters.  These can mismatch with K&R
>    // declarations.
> @@ -3050,8 +3049,7 @@ void Sema::MergeVarDecl(VarDecl *New, Lo
>    }
>
>    // Merge "used" flag.
> -  if (Old->isUsed(false))
> -    New->setUsed();
> +  New->setIsUsed(Old->isUsed(false));
>
>    // Keep a chain of previous declarations.
>    New->setPreviousDeclaration(Old);
>
> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Sep  4 19:02:25 2013
> @@ -7951,7 +7951,7 @@ void Sema::DefineImplicitDefaultConstruc
>    SourceLocation Loc = Constructor->getLocation();
>    Constructor->setBody(new (Context) CompoundStmt(Loc));
>
> -  Constructor->setUsed();
> +  Constructor->markUsed(Context);
>    MarkVTableUsed(CurrentLocation, ClassDecl);
>
>    if (ASTMutationListener *L = getASTMutationListener()) {
> @@ -8289,7 +8289,7 @@ void Sema::DefineInheritingConstructor(S
>    SourceLocation Loc = Constructor->getLocation();
>    Constructor->setBody(new (Context) CompoundStmt(Loc));
>
> -  Constructor->setUsed();
> +  Constructor->markUsed(Context);
>    MarkVTableUsed(CurrentLocation, ClassDecl);
>
>    if (ASTMutationListener *L = getASTMutationListener()) {
> @@ -8421,7 +8421,7 @@ void Sema::DefineImplicitDestructor(Sour
>
>    SourceLocation Loc = Destructor->getLocation();
>    Destructor->setBody(new (Context) CompoundStmt(Loc));
> -  Destructor->setUsed();
> +  Destructor->markUsed(Context);
>    MarkVTableUsed(CurrentLocation, ClassDecl);
>
>    if (ASTMutationListener *L = getASTMutationListener()) {
> @@ -9117,7 +9117,7 @@ void Sema::DefineImplicitCopyAssignment(
>    if (getLangOpts().CPlusPlus11 && CopyAssignOperator->isImplicit())
>      diagnoseDeprecatedCopyOperation(*this, CopyAssignOperator,
> CurrentLocation);
>
> -  CopyAssignOperator->setUsed();
> +  CopyAssignOperator->markUsed(Context);
>
>    SynthesizedFunctionScope Scope(*this, CopyAssignOperator);
>    DiagnosticErrorTrap Trap(Diags);
> @@ -9562,7 +9562,7 @@ void Sema::DefineImplicitMoveAssignment(
>      return;
>    }
>
> -  MoveAssignOperator->setUsed();
> +  MoveAssignOperator->markUsed(Context);
>
>    SynthesizedFunctionScope Scope(*this, MoveAssignOperator);
>    DiagnosticErrorTrap Trap(Diags);
> @@ -9915,7 +9915,7 @@ void Sema::DefineImplicitCopyConstructor
>          /*isStmtExpr=*/ false).takeAs<Stmt>());
>    }
>
> -  CopyConstructor->setUsed();
> +  CopyConstructor->markUsed(Context);
>    if (ASTMutationListener *L = getASTMutationListener()) {
>      L->CompletedImplicitDefinition(CopyConstructor);
>    }
> @@ -10101,7 +10101,7 @@ void Sema::DefineImplicitMoveConstructor
>          /*isStmtExpr=*/ false).takeAs<Stmt>());
>    }
>
> -  MoveConstructor->setUsed();
> +  MoveConstructor->markUsed(Context);
>
>    if (ASTMutationListener *L = getASTMutationListener()) {
>      L->CompletedImplicitDefinition(MoveConstructor);
> @@ -10119,7 +10119,7 @@ static void markLambdaCallOperatorUsed(S
>          Lambda->lookup(
>
>  S.Context.DeclarationNames.getCXXOperatorName(OO_Call)).front());
>    CallOperator->setReferenced();
> -  CallOperator->setUsed();
> +  CallOperator->markUsed(S.Context);
>  }
>
>  void Sema::DefineImplicitLambdaToFunctionPointerConversion(
> @@ -10131,7 +10131,7 @@ void Sema::DefineImplicitLambdaToFunctio
>    // Make sure that the lambda call operator is marked used.
>    markLambdaCallOperatorUsed(*this, Lambda);
>
> -  Conv->setUsed();
> +  Conv->markUsed(Context);
>
>    SynthesizedFunctionScope Scope(*this, Conv);
>    DiagnosticErrorTrap Trap(Diags);
> @@ -10150,7 +10150,7 @@ void Sema::DefineImplicitLambdaToFunctio
>
>    // Fill in the __invoke function with a dummy implementation. IR
> generation
>    // will fill in the actual details.
> -  Invoke->setUsed();
> +  Invoke->markUsed(Context);
>    Invoke->setReferenced();
>    Invoke->setBody(new (Context) CompoundStmt(Conv->getLocation()));
>
> @@ -10164,7 +10164,7 @@ void Sema::DefineImplicitLambdaToBlockPo
>         SourceLocation CurrentLocation,
>         CXXConversionDecl *Conv)
>  {
> -  Conv->setUsed();
> +  Conv->markUsed(Context);
>
>    SynthesizedFunctionScope Scope(*this, Conv);
>    DiagnosticErrorTrap Trap(Diags);
>
> Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Sep  4 19:02:25 2013
> @@ -9623,7 +9623,7 @@ ExprResult Sema::ActOnUnaryOp(Scope *S,
>  /// ActOnAddrLabel - Parse the GNU address of label extension: "&&foo".
>  ExprResult Sema::ActOnAddrLabel(SourceLocation OpLoc, SourceLocation
> LabLoc,
>                                  LabelDecl *TheDecl) {
> -  TheDecl->setUsed();
> +  TheDecl->markUsed(Context);
>    // Create the AST node.  The address of a label always has type 'void*'.
>    return Owned(new (Context) AddrLabelExpr(OpLoc, LabLoc, TheDecl,
>
> Context.getPointerType(Context.VoidTy)));
> @@ -11097,7 +11097,7 @@ void Sema::MarkFunctionReferenced(Source
>    // decl in the middle of a decl chain. We loop to maintain the invariant
>    // that once a decl is used, all decls after it are also used.
>    for (FunctionDecl *F = Func->getMostRecentDecl();; F =
> F->getPreviousDecl()) {
> -    F->setUsed(true);
> +    F->markUsed(Context);
>      if (F == Func)
>        break;
>    }
> @@ -11172,7 +11172,7 @@ static ExprResult captureInCapturedRegio
>    Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,
>                                            DeclRefType, VK_LValue, Loc);
>    Var->setReferenced(true);
> -  Var->setUsed(true);
> +  Var->markUsed(S.Context);
>
>    return Ref;
>  }
> @@ -11214,7 +11214,7 @@ static ExprResult captureInLambda(Sema &
>    Expr *Ref = new (S.Context) DeclRefExpr(Var, RefersToEnclosingLocal,
>                                            DeclRefType, VK_LValue, Loc);
>    Var->setReferenced(true);
> -  Var->setUsed(true);
> +  Var->markUsed(S.Context);
>
>    // When the field has array type, create index variables for each
>    // dimension of the array. We use these index variables to subscript
> @@ -11660,7 +11660,7 @@ static void MarkVarDeclODRUsed(Sema &Sem
>
>    SemaRef.tryCaptureVariable(Var, Loc);
>
> -  Var->setUsed(true);
> +  Var->markUsed(SemaRef.Context);
>  }
>
>  void Sema::UpdateMarkingForLValueToRValue(Expr *E) {
>
> Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaLambda.cpp Wed Sep  4 19:02:25 2013
> @@ -1105,7 +1105,7 @@ ExprResult Sema::BuildBlockForLambdaConv
>          Lambda->lookup(
>            Context.DeclarationNames.getCXXOperatorName(OO_Call)).front());
>    CallOperator->setReferenced();
> -  CallOperator->setUsed();
> +  CallOperator->markUsed(Context);
>
>    ExprResult Init = PerformCopyInitialization(
>                        InitializedEntity::InitializeBlock(ConvLocation,
>
> Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaStmt.cpp Wed Sep  4 19:02:25 2013
> @@ -2041,7 +2041,7 @@ Sema::BuildCXXForRangeStmt(SourceLocatio
>
>    if (RangeVarType->isDependentType()) {
>      // The range is implicitly used as a placeholder when it is dependent.
> -    RangeVar->setUsed();
> +    RangeVar->markUsed(Context);
>
>      // Deduce any 'auto's in the loop variable as 'DependentTy'. We'll
> fill
>      // them in properly when we instantiate the loop.
> @@ -2284,7 +2284,7 @@ StmtResult Sema::ActOnGotoStmt(SourceLoc
>                                 SourceLocation LabelLoc,
>                                 LabelDecl *TheDecl) {
>    getCurFunction()->setHasBranchIntoScope();
> -  TheDecl->setUsed();
> +  TheDecl->markUsed(Context);
>    return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc));
>  }
>
>
> Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
> +++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Wed Sep  4 19:02:25
> 2013
> @@ -3352,7 +3352,7 @@ void Sema::BuildVariableInstantiation(
>    NewVar->setAccess(OldVar->getAccess());
>
>    if (!OldVar->isStaticDataMember()) {
> -    NewVar->setUsed(OldVar->isUsed(false));
> +    NewVar->setIsUsed(OldVar->isUsed(false));
>      NewVar->setReferenced(OldVar->isReferenced());
>    }
>
>
> Modified: cfe/trunk/lib/Serialization/ASTCommon.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTCommon.h?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTCommon.h (original)
> +++ cfe/trunk/lib/Serialization/ASTCommon.h Wed Sep  4 19:02:25 2013
> @@ -26,7 +26,8 @@ enum DeclUpdateKind {
>    UPD_CXX_ADDED_TEMPLATE_SPECIALIZATION,
>    UPD_CXX_ADDED_ANONYMOUS_NAMESPACE,
>    UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER,
> -  UPD_CXX_DEDUCED_RETURN_TYPE
> +  UPD_CXX_DEDUCED_RETURN_TYPE,
> +  UPD_DECL_MARKED_USED
>  };
>
>  TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
>
> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Sep  4 19:02:25 2013
> @@ -377,7 +377,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {
>      D->setAttrsImpl(Attrs, Reader.getContext());
>    }
>    D->setImplicit(Record[Idx++]);
> -  D->setUsed(Record[Idx++]);
> +  D->setIsUsed(Record[Idx++]);
>    D->setReferenced(Record[Idx++]);
>    D->setTopLevelDeclInObjCContainer(Record[Idx++]);
>    D->setAccess((AccessSpecifier)Record[Idx++]);
> @@ -2838,6 +2838,11 @@ void ASTDeclReader::UpdateDecl(Decl *D,
>            FD, Reader.readType(ModuleFile, Record, Idx));
>        break;
>      }
> +
> +    case UPD_DECL_MARKED_USED: {
> +      D->markUsed(Reader.getContext());
> +      break;
> +    }
>      }
>    }
>  }
>
> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Sep  4 19:02:25 2013
> @@ -4314,6 +4314,7 @@ void ASTWriter::ResolveDeclUpdatesBlocks
>          break;
>
>        case UPD_CXX_INSTANTIATED_STATIC_DATA_MEMBER:
> +      case UPD_DECL_MARKED_USED:
>          ++Idx;
>          break;
>
> @@ -5370,3 +5371,12 @@ void ASTWriter::AddedObjCPropertyInClass
>
>    RewriteDecl(D);
>  }
> +
> +void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
> +  assert(!WritingAST && "Already writing the AST!");
> +  if (!D->isFromASTFile())
> +    return;
> +
> +  UpdateRecord &Record = DeclUpdates[D];
> +  Record.push_back(UPD_DECL_MARKED_USED);
> +}
>
> Modified: cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h?rev=190016&r1=190015&r2=190016&view=diff
>
> ==============================================================================
> --- cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h (original)
> +++ cfe/trunk/test/Modules/Inputs/System/usr/include/stdio.h Wed Sep  4
> 19:02:25 2013
> @@ -1,3 +1,3 @@
>  typedef struct { int id; } FILE;
>  int fprintf(FILE*restrict, const char* restrict format, ...);
> -
> +extern FILE *__stderrp;
>
> Added: cfe/trunk/test/Modules/Inputs/pch-used.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/pch-used.h?rev=190016&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/Modules/Inputs/pch-used.h (added)
> +++ cfe/trunk/test/Modules/Inputs/pch-used.h Wed Sep  4 19:02:25 2013
> @@ -0,0 +1,2 @@
> + at import cstd.stdio;
> +static inline void SPXTrace() { fprintf(__stderrp, ""); }
>
> Added: cfe/trunk/test/Modules/pch-used.m
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pch-used.m?rev=190016&view=auto
>
> ==============================================================================
> --- cfe/trunk/test/Modules/pch-used.m (added)
> +++ cfe/trunk/test/Modules/pch-used.m Wed Sep  4 19:02:25 2013
> @@ -0,0 +1,8 @@
> +// RUN: rm -rf %t
> +// RUN: mkdir %t
> +// 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
> +// 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
> +
> +void f() { SPXTrace(); }
> +
> +// CHECK: define internal void @SPXTrace
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130904/e1cee991/attachment.html>
-------------- next part --------------
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 28a5a42..5cd6dff 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -3805,6 +3805,23 @@ void ASTWriter::WriteAST(Sema &SemaRef,
                          const std::string &OutputFile,
                          Module *WritingModule, StringRef isysroot,
                          bool hasErrors) {
+  // If there are any out-of-date identifiers, bring them up to date.
+  if (ExternalPreprocessorSource *ExtSource = SemaRef.PP.getExternalSource()) {
+    // Find out-of-date identifiers.
+    SmallVector<IdentifierInfo *, 4> OutOfDate;
+    for (IdentifierTable::iterator ID = SemaRef.PP.getIdentifierTable().begin(),
+                                IDEnd = SemaRef.PP.getIdentifierTable().end();
+         ID != IDEnd; ++ID) {
+      if (ID->second->isOutOfDate())
+        OutOfDate.push_back(ID->second);
+    }
+
+    // Update the out-of-date identifiers.
+    for (unsigned I = 0, N = OutOfDate.size(); I != N; ++I) {
+      ExtSource->updateOutOfDateIdentifier(*OutOfDate[I]);
+    }
+  }
+
   WritingAST = true;
   
   ASTHasCompilerErrors = hasErrors;
@@ -3886,23 +3903,6 @@ void ASTWriter::WriteASTCore(Sema &SemaRef,
       getIdentifierRef(&Table.get(BuiltinNames[I]));
   }
 
-  // If there are any out-of-date identifiers, bring them up to date.
-  if (ExternalPreprocessorSource *ExtSource = PP.getExternalSource()) {
-    // Find out-of-date identifiers.
-    SmallVector<IdentifierInfo *, 4> OutOfDate;
-    for (IdentifierTable::iterator ID = PP.getIdentifierTable().begin(),
-                                IDEnd = PP.getIdentifierTable().end();
-         ID != IDEnd; ++ID) {
-      if (ID->second->isOutOfDate())
-        OutOfDate.push_back(ID->second);
-    }
-
-    // Update the out-of-date identifiers.
-    for (unsigned I = 0, N = OutOfDate.size(); I != N; ++I) {
-      ExtSource->updateOutOfDateIdentifier(*OutOfDate[I]);
-    }
-  }
-
   // Build a record containing all of the tentative definitions in this file, in
   // TentativeDefinitions order.  Generally, this record will be empty for
   // headers.


More information about the cfe-commits mailing list