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

Eli Friedman eli.friedman at gmail.com
Wed Sep 4 17:02:25 PDT 2013


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





More information about the cfe-commits mailing list