diff options
| author | Eli Friedman <eli.friedman@gmail.com> | 2013-09-05 00:02:25 +0000 |
|---|---|---|
| committer | Eli Friedman <eli.friedman@gmail.com> | 2013-09-05 00:02:25 +0000 |
| commit | 276dd188c428d4fb1b3e887fe70a929a71892bf9 (patch) | |
| tree | eb49076c4c96fbb6f2efe12c9410cfe119af18e0 /clang/lib | |
| parent | 5c30024fd42868e0850cec1e822671187315c8df (diff) | |
| download | bcm5719-llvm-276dd188c428d4fb1b3e887fe70a929a71892bf9.tar.gz bcm5719-llvm-276dd188c428d4fb1b3e887fe70a929a71892bf9.zip | |
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.
llvm-svn: 190016
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/AST/DeclBase.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Frontend/MultiplexConsumer.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDecl.cpp | 6 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 22 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 10 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaLambda.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 4 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTCommon.h | 3 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 7 | ||||
| -rw-r--r-- | clang/lib/Serialization/ASTWriter.cpp | 10 |
11 files changed, 56 insertions, 26 deletions
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index e46d671682f..e4d4e77942d 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -291,6 +291,16 @@ bool Decl::isUsed(bool CheckUsedAttr) const { 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; diff --git a/clang/lib/Frontend/MultiplexConsumer.cpp b/clang/lib/Frontend/MultiplexConsumer.cpp index f8ee36a50dc..9cf68a5e9b2 100644 --- a/clang/lib/Frontend/MultiplexConsumer.cpp +++ b/clang/lib/Frontend/MultiplexConsumer.cpp @@ -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::AddedObjCPropertyInClassExtension( 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 diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 78942afcc9a..68df00dec44 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2739,8 +2739,7 @@ bool Sema::MergeCompatibleFunctionDecls(FunctionDecl *New, FunctionDecl *Old, 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, LookupResult &Previous) { } // Merge "used" flag. - if (Old->isUsed(false)) - New->setUsed(); + New->setIsUsed(Old->isUsed(false)); // Keep a chain of previous declarations. New->setPreviousDeclaration(Old); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 71b32e570b4..01f3b7cb491 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -7951,7 +7951,7 @@ void Sema::DefineImplicitDefaultConstructor(SourceLocation CurrentLocation, 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(SourceLocation CurrentLocation, 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(SourceLocation CurrentLocation, 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(SourceLocation CurrentLocation, 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(SourceLocation CurrentLocation, return; } - MoveAssignOperator->setUsed(); + MoveAssignOperator->markUsed(Context); SynthesizedFunctionScope Scope(*this, MoveAssignOperator); DiagnosticErrorTrap Trap(Diags); @@ -9915,7 +9915,7 @@ void Sema::DefineImplicitCopyConstructor(SourceLocation CurrentLocation, /*isStmtExpr=*/ false).takeAs<Stmt>()); } - CopyConstructor->setUsed(); + CopyConstructor->markUsed(Context); if (ASTMutationListener *L = getASTMutationListener()) { L->CompletedImplicitDefinition(CopyConstructor); } @@ -10101,7 +10101,7 @@ void Sema::DefineImplicitMoveConstructor(SourceLocation CurrentLocation, /*isStmtExpr=*/ false).takeAs<Stmt>()); } - MoveConstructor->setUsed(); + MoveConstructor->markUsed(Context); if (ASTMutationListener *L = getASTMutationListener()) { L->CompletedImplicitDefinition(MoveConstructor); @@ -10119,7 +10119,7 @@ static void markLambdaCallOperatorUsed(Sema &S, CXXRecordDecl *Lambda) { 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::DefineImplicitLambdaToFunctionPointerConversion( // 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::DefineImplicitLambdaToFunctionPointerConversion( // 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::DefineImplicitLambdaToBlockPointerConversion( SourceLocation CurrentLocation, CXXConversionDecl *Conv) { - Conv->setUsed(); + Conv->markUsed(Context); SynthesizedFunctionScope Scope(*this, Conv); DiagnosticErrorTrap Trap(Diags); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 4fc54bd7f70..464d5877e84 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -9623,7 +9623,7 @@ ExprResult Sema::ActOnUnaryOp(Scope *S, SourceLocation OpLoc, /// 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(SourceLocation Loc, FunctionDecl *Func) { // 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 captureInCapturedRegion(Sema &S, CapturedRegionScopeInfo *RSI, 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 &S, LambdaScopeInfo *LSI, 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 &SemaRef, VarDecl *Var, SemaRef.tryCaptureVariable(Var, Loc); - Var->setUsed(true); + Var->markUsed(SemaRef.Context); } void Sema::UpdateMarkingForLValueToRValue(Expr *E) { diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp index 242105f789c..3a796ad9025 100644 --- a/clang/lib/Sema/SemaLambda.cpp +++ b/clang/lib/Sema/SemaLambda.cpp @@ -1105,7 +1105,7 @@ ExprResult Sema::BuildBlockForLambdaConversion(SourceLocation CurrentLocation, Lambda->lookup( Context.DeclarationNames.getCXXOperatorName(OO_Call)).front()); CallOperator->setReferenced(); - CallOperator->setUsed(); + CallOperator->markUsed(Context); ExprResult Init = PerformCopyInitialization( InitializedEntity::InitializeBlock(ConvLocation, diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 861c1c8bd03..ef2202f3374 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -2041,7 +2041,7 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation ColonLoc, 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(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl) { getCurFunction()->setHasBranchIntoScope(); - TheDecl->setUsed(); + TheDecl->markUsed(Context); return Owned(new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc)); } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 5d6847fdf0e..cc9cb6317a1 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -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()); } diff --git a/clang/lib/Serialization/ASTCommon.h b/clang/lib/Serialization/ASTCommon.h index fa3ef58a1c0..ef81e690324 100644 --- a/clang/lib/Serialization/ASTCommon.h +++ b/clang/lib/Serialization/ASTCommon.h @@ -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); diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 67ca94bbf8e..b16966530e8 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -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, ModuleFile &ModuleFile, FD, Reader.readType(ModuleFile, Record, Idx)); break; } + + case UPD_DECL_MARKED_USED: { + D->markUsed(Reader.getContext()); + break; + } } } } diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp index f8e8b5d7ada..28a5a423fdf 100644 --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -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::AddedObjCPropertyInClassExtension(const ObjCPropertyDecl *Prop, 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); +} |

