<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
<div class="moz-cite-prefix">r267882.<br>
On 28/04/16 15:23, Nico Weber wrote:<br>
</div>
<blockquote
cite="mid:CAMGbLiHXqYudw29rf8QaimDdB68iWVqRb5N6QkRFBQy8L8wumQ@mail.gmail.com"
type="cite">
<p dir="ltr">I'd reland with the fix, and with an additional test
that catches the problem this introduced.</p>
<div class="gmail_quote">On Apr 28, 2016 8:16 AM, "Vassil Vassilev
via cfe-commits" <<a moz-do-not-send="true"
href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a>>
wrote:<br type="attribution">
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Nico,<br>
I have a fix. What is the right way of putting it in? Shall
I revert the "revert" and commit the fix afterwards?<br>
Many thanks<br>
Vassil<br>
On 27/04/16 19:26, Nico Weber via cfe-commits wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
Author: nico<br>
Date: Wed Apr 27 12:26:08 2016<br>
New Revision: 267744<br>
<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project?rev=267744&view=rev"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project?rev=267744&view=rev</a><br>
Log:<br>
Revert r267691, it caused PR27535.<br>
<br>
Removed:<br>
cfe/trunk/test/Modules/Inputs/PR27401/<br>
cfe/trunk/test/Modules/pr27401.cpp<br>
Modified:<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/Sema/SemaExpr.cpp<br>
cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br>
<br>
Modified: cfe/trunk/include/clang/AST/DeclBase.h<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=267744&r1=267743&r2=267744&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclBase.h?rev=267744&r1=267743&r2=267744&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/AST/DeclBase.h (original)<br>
+++ cfe/trunk/include/clang/AST/DeclBase.h Wed Apr 27
12:26:08 2016<br>
@@ -518,8 +518,8 @@ public:<br>
bool isImplicit() const { return Implicit; }<br>
void setImplicit(bool I = true) { Implicit = I; }<br>
- /// \brief Whether *any* (re-)declaration of the entity
was used, meaning that<br>
- /// a definition is required.<br>
+ /// \brief Whether this declaration was used, meaning
that a definition<br>
+ /// is required.<br>
///<br>
/// \param CheckUsedAttr When true, also consider the
"used" attribute<br>
/// (in addition to the "used" bit set by \c setUsed())
when determining<br>
@@ -529,8 +529,7 @@ public:<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>
- /// It intentionally doesn't notify any listeners.<br>
- void setIsUsed() { getCanonicalDecl()->Used = true; }<br>
+ void setIsUsed() { Used = true; }<br>
/// \brief Mark the declaration used, in the sense of
odr-use.<br>
///<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=267744&r1=267743&r2=267744&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=267744&r1=267743&r2=267744&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTWriter.h
(original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Wed
Apr 27 12:26:08 2016<br>
@@ -565,17 +565,6 @@ public:<br>
/// decl.<br>
const Decl *getFirstLocalDecl(const Decl *D);<br>
- /// \brief Is this a local declaration (that is, one
that will be written to<br>
- /// our AST file)? This is the case for declarations that
are neither imported<br>
- /// from another AST file nor predefined.<br>
- bool IsLocalDecl(const Decl *D) {<br>
- if (D->isFromASTFile())<br>
- return false;<br>
- auto I = DeclIDs.find(D);<br>
- return (I == DeclIDs.end() ||<br>
- I->second >=
serialization::NUM_PREDEF_DECL_IDS);<br>
- };<br>
-<br>
/// \brief Emit a reference to a declaration.<br>
void AddDeclRef(const Decl *D, RecordDataImpl
&Record);<br>
<br>
Modified: cfe/trunk/lib/AST/DeclBase.cpp<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=267744&r1=267743&r2=267744&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclBase.cpp?rev=267744&r1=267743&r2=267744&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/AST/DeclBase.cpp (original)<br>
+++ cfe/trunk/lib/AST/DeclBase.cpp Wed Apr 27 12:26:08 2016<br>
@@ -340,29 +340,25 @@ unsigned Decl::getMaxAlignment() const
{<br>
return Align;<br>
}<br>
-bool Decl::isUsed(bool CheckUsedAttr) const {<br>
- const Decl *CanonD = getCanonicalDecl();<br>
- if (CanonD->Used)<br>
+bool Decl::isUsed(bool CheckUsedAttr) const {<br>
+ if (Used)<br>
return true;<br>
-<br>
+<br>
// Check for used attribute.<br>
- // Ask the most recent decl, since attributes accumulate
in the redecl chain.<br>
- if (CheckUsedAttr &&
getMostRecentDecl()->hasAttr<UsedAttr>())<br>
+ if (CheckUsedAttr && hasAttr<UsedAttr>())<br>
return true;<br>
- // The information may have not been deserialized yet.
Force deserialization<br>
- // to complete the needed information.<br>
- return
getMostRecentDecl()->getCanonicalDecl()->Used;<br>
+ return false;<br>
}<br>
void Decl::markUsed(ASTContext &C) {<br>
- if (isUsed())<br>
+ if (Used)<br>
return;<br>
if (C.getASTMutationListener())<br>
C.getASTMutationListener()->DeclarationMarkedUsed(this);<br>
- setIsUsed();<br>
+ Used = true;<br>
}<br>
bool Decl::isReferenced() const {<br>
<br>
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=267744&r1=267743&r2=267744&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=267744&r1=267743&r2=267744&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)<br>
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Wed Apr 27 12:26:08 2016<br>
@@ -13011,7 +13011,17 @@ void
Sema::MarkFunctionReferenced(Source<br>
UndefinedButUsed.insert(std::make_pair(Func->getCanonicalDecl(),
Loc));<br>
}<br>
- Func->markUsed(Context);<br>
+ // Normally the most current decl is marked used while
processing the use and<br>
+ // any subsequent decls are marked used by decl merging.
This fails with<br>
+ // template instantiation since marking can happen at the
end of the file<br>
+ // and, because of the two phase lookup, this function is
called with at<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->markUsed(Context);<br>
+ if (F == Func)<br>
+ break;<br>
+ }<br>
}<br>
static void<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=267744&r1=267743&r2=267744&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=267744&r1=267743&r2=267744&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Wed Apr 27
12:26:08 2016<br>
@@ -51,11 +51,6 @@ namespace clang {<br>
bool HasPendingBody;<br>
- ///\brief A flag to carry the information for a decl
from the entity is<br>
- /// used. We use it to delay the marking of the
canonical decl as used until<br>
- /// the entire declaration is deserialized and merged.<br>
- bool IsDeclMarkedUsed;<br>
-<br>
uint64_t GetCurrentCursorOffset();<br>
uint64_t ReadLocalOffset(const RecordData &R,
unsigned &I) {<br>
@@ -222,8 +217,7 @@ namespace clang {<br>
: Reader(Reader), F(*Loc.F), Offset(Loc.Offset),
ThisDeclID(thisDeclID),<br>
ThisDeclLoc(ThisDeclLoc), Record(Record),
Idx(Idx),<br>
TypeIDForTypeDecl(0), NamedDeclForTagDecl(0),<br>
- TypedefNameForLinkage(nullptr),
HasPendingBody(false),<br>
- IsDeclMarkedUsed(false) {}<br>
+ TypedefNameForLinkage(nullptr),
HasPendingBody(false) {}<br>
template <typename DeclT><br>
static Decl
*getMostRecentDeclImpl(Redeclarable<DeclT> *D);<br>
@@ -450,11 +444,6 @@ uint64_t
ASTDeclReader::GetCurrentCursor<br>
void ASTDeclReader::Visit(Decl *D) {<br>
DeclVisitor<ASTDeclReader, void>::Visit(D);<br>
- // At this point we have deserialized and merged the
decl and it is safe to<br>
- // update its canonical decl to signal that the entire
entity is used.<br>
- D->getCanonicalDecl()->Used |= IsDeclMarkedUsed;<br>
- IsDeclMarkedUsed = false;<br>
-<br>
if (DeclaratorDecl *DD =
dyn_cast<DeclaratorDecl>(D)) {<br>
if (DD->DeclInfo) {<br>
DeclaratorDecl::ExtInfo *Info =<br>
@@ -535,7 +524,6 @@ void ASTDeclReader::VisitDecl(Decl *D) {<br>
}<br>
D->setImplicit(Record[Idx++]);<br>
D->Used = Record[Idx++];<br>
- IsDeclMarkedUsed |= D->Used;<br>
D->setReferenced(Record[Idx++]);<br>
D->setTopLevelDeclInObjCContainer(Record[Idx++]);<br>
D->setAccess((AccessSpecifier)Record[Idx++]);<br>
@@ -560,7 +548,7 @@ void ASTDeclReader::VisitDecl(Decl *D) {<br>
if (Owner->NameVisibility != Module::AllVisible)
{<br>
// The owning module is not visible. Mark this
declaration as hidden.<br>
D->Hidden = true;<br>
-<br>
+<br>
// Note that this declaration was hidden because
its owning module is<br>
// not yet visible.<br>
Reader.HiddenNamesMap[Owner].push_back(D);<br>
@@ -2367,8 +2355,6 @@ void
ASTDeclReader::mergeRedeclarable(Re<br>
// appropriate canonical declaration.<br>
D->RedeclLink =
Redeclarable<T>::PreviousDeclLink(ExistingCanon);<br>
D->First = ExistingCanon;<br>
- ExistingCanon->Used |= D->Used;<br>
- D->Used = false;<br>
// When we merge a namespace, update its pointer to
the first namespace.<br>
// We cannot have loaded any redeclarations of this
declaration yet, so<br>
@@ -3126,6 +3112,11 @@ void
ASTDeclReader::attachPreviousDecl(A<br>
Previous->IdentifierNamespace &<br>
(Decl::IDNS_Ordinary | Decl::IDNS_Tag |
Decl::IDNS_Type);<br>
+ // If the previous declaration is marked as used, then
this declaration should<br>
+ // be too.<br>
+ if (Previous->Used)<br>
+ D->Used = true;<br>
+<br>
// If the declaration declares a template, it may
inherit default arguments<br>
// from the previous declaration.<br>
if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D))<br>
@@ -3874,7 +3865,7 @@ void ASTDeclReader::UpdateDecl(Decl
*D,<br>
// ASTMutationListeners other than an ASTWriter.<br>
// Maintain AST consistency: any later
redeclarations are used too.<br>
- D->setIsUsed();<br>
+ forAllLaterRedecls(D, [](Decl *D) { D->Used =
true; });<br>
break;<br>
}<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=267744&r1=267743&r2=267744&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=267744&r1=267743&r2=267744&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Wed Apr 27
12:26:08 2016<br>
@@ -5784,13 +5784,8 @@ void
ASTWriter::AddedObjCCategoryToInter<br>
void ASTWriter::DeclarationMarkedUsed(const Decl *D) {<br>
assert(!WritingAST && "Already writing the
AST!");<br>
-<br>
- // If there is *any* declaration of the entity that's not
from an AST file,<br>
- // we can skip writing the update record. We make sure
that isUsed() triggers<br>
- // completion of the redeclaration chain of the entity.<br>
- for (auto Prev = D->getMostRecentDecl(); Prev; Prev =
Prev->getPreviousDecl())<br>
- if (IsLocalDecl(Prev))<br>
- return;<br>
+ if (!D->isFromASTFile())<br>
+ return;<br>
DeclUpdates[D].push_back(DeclUpdate(UPD_DECL_MARKED_USED));<br>
}<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriterDecl.cpp<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=267744&r1=267743&r2=267744&view=diff"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterDecl.cpp?rev=267744&r1=267743&r2=267744&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriterDecl.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriterDecl.cpp Wed Apr 27
12:26:08 2016<br>
@@ -1541,6 +1541,16 @@ void
ASTDeclWriter::VisitDeclContext(Dec<br>
}<br>
const Decl *ASTWriter::getFirstLocalDecl(const Decl *D)
{<br>
+ /// \brief Is this a local declaration (that is, one that
will be written to<br>
+ /// our AST file)? This is the case for declarations that
are neither imported<br>
+ /// from another AST file nor predefined.<br>
+ auto IsLocalDecl = [&](const Decl *D) -> bool {<br>
+ if (D->isFromASTFile())<br>
+ return false;<br>
+ auto I = DeclIDs.find(D);<br>
+ return (I == DeclIDs.end() || I->second >=
NUM_PREDEF_DECL_IDS);<br>
+ };<br>
+<br>
assert(IsLocalDecl(D) && "expected a local
declaration");<br>
const Decl *Canon = D->getCanonicalDecl();<br>
<br>
Removed: cfe/trunk/test/Modules/pr27401.cpp<br>
URL: <a moz-do-not-send="true"
href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pr27401.cpp?rev=267743&view=auto"
rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/pr27401.cpp?rev=267743&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/pr27401.cpp (original)<br>
+++ cfe/trunk/test/Modules/pr27401.cpp (removed)<br>
@@ -1,38 +0,0 @@<br>
-// RUN: rm -rf %t<br>
-// RUN: %clang_cc1 -std=c++11 -I%S/Inputs/PR27401 -verify
%s<br>
-// RUN: %clang_cc1 -std=c++11 -fmodules
-fmodule-map-file=%S/Inputs/PR27401/module.modulemap
-fmodules-cache-path=%t -I%S/Inputs/PR27401 -verify %s<br>
-<br>
-#include "a.h"<br>
-#define _LIBCPP_VECTOR<br>
-template <class, class _Allocator><br>
-class __vector_base {<br>
-protected:<br>
- _Allocator __alloc() const;<br>
- __vector_base(_Allocator);<br>
-};<br>
-<br>
-template <class _Tp, class _Allocator = allocator><br>
-class vector : __vector_base<_Tp, _Allocator> {<br>
-public:<br>
- vector()
noexcept(is_nothrow_default_constructible<_Allocator>::value);<br>
- vector(const vector &);<br>
- vector(vector &&)<br>
-
noexcept(is_nothrow_move_constructible<_Allocator>::value);<br>
-};<br>
-<br>
-template <class _Tp, class _Allocator><br>
-vector<_Tp, _Allocator>::vector(const vector
&__x) : __vector_base<_Tp,
_Allocator>(__x.__alloc()) {}<br>
-<br>
- struct CommentOptions {<br>
- vector<char> ParseAllComments;<br>
- CommentOptions() {}<br>
- };<br>
- struct PrintingPolicy {<br>
- PrintingPolicy(CommentOptions LO) : LangOpts(LO) {}<br>
- CommentOptions LangOpts;<br>
- };<br>
-<br>
-#include "b.h"<br>
-CommentOptions fn1() { return fn1(); }<br>
-<br>
-// expected-no-diagnostics<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a moz-do-not-send="true"
href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a moz-do-not-send="true"
href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits"
rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a moz-do-not-send="true"
href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@lists.llvm.org</a><br>
<a moz-do-not-send="true"
href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits"
rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
</blockquote>
</div>
</blockquote>
<br>
</body>
</html>