зеркало из https://github.com/microsoft/clang-1.git
Start fleshing out ASTMutationListener; notify when a tag definition is completed.
In that case a chained PCH will record the updates to the DefinitionData pointer of forward references. If a forward reference mutated into a definition re-write it into the chained PCH, this is too big of a change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@117239 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
ba901b507f
Коммит
565bf30bf5
|
@ -14,6 +14,7 @@
|
|||
#define LLVM_CLANG_AST_ASTMUTATIONLISTENER_H
|
||||
|
||||
namespace clang {
|
||||
class TagDecl;
|
||||
class CXXRecordDecl;
|
||||
class CXXMethodDecl;
|
||||
|
||||
|
@ -23,6 +24,9 @@ namespace clang {
|
|||
class ASTMutationListener {
|
||||
public:
|
||||
virtual ~ASTMutationListener();
|
||||
|
||||
/// \brief A new TagDecl definition was completed.
|
||||
virtual void CompletedTagDefinition(const TagDecl *D) { }
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
|
|
@ -511,6 +511,9 @@ public:
|
|||
void DeclRead(serialization::DeclID ID, const Decl *D);
|
||||
void SelectorRead(serialization::SelectorID ID, Selector Sel);
|
||||
void MacroDefinitionRead(serialization::MacroID ID, MacroDefinition *MD);
|
||||
|
||||
// ASTMutationListener implementation.
|
||||
virtual void CompletedTagDefinition(const TagDecl *D);
|
||||
};
|
||||
|
||||
/// \brief AST and semantic-analysis consumer that generates a
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "clang/AST/Expr.h"
|
||||
#include "clang/AST/ExprCXX.h"
|
||||
#include "clang/AST/PrettyPrinter.h"
|
||||
#include "clang/AST/ASTMutationListener.h"
|
||||
#include "clang/Basic/Builtins.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/Specifiers.h"
|
||||
|
@ -1713,6 +1714,9 @@ void TagDecl::completeDefinition() {
|
|||
|
||||
IsDefinition = true;
|
||||
IsBeingDefined = false;
|
||||
|
||||
if (ASTMutationListener *L = getASTMutationListener())
|
||||
L->CompletedTagDefinition(this);
|
||||
}
|
||||
|
||||
TagDecl* TagDecl::getDefinition() const {
|
||||
|
|
|
@ -20,6 +20,10 @@ namespace clang {
|
|||
|
||||
namespace serialization {
|
||||
|
||||
enum DeclUpdateKind {
|
||||
UPD_CXX_SET_DEFINITIONDATA
|
||||
};
|
||||
|
||||
TypeIdx TypeIdxFromBuiltin(const BuiltinType *BT);
|
||||
|
||||
template <typename IdxForTypeTy>
|
||||
|
|
|
@ -1588,5 +1588,17 @@ Decl *ASTReader::ReadDeclRecord(unsigned Index, DeclID ID) {
|
|||
}
|
||||
|
||||
void ASTDeclReader::UpdateDecl(Decl *D, const RecordData &Record) {
|
||||
// No update is tracked yet.
|
||||
unsigned Idx = 0;
|
||||
while (Idx < Record.size()) {
|
||||
switch ((DeclUpdateKind)Record[Idx++]) {
|
||||
case UPD_CXX_SET_DEFINITIONDATA: {
|
||||
CXXRecordDecl *RD = cast<CXXRecordDecl>(D);
|
||||
CXXRecordDecl *
|
||||
DefinitionDecl = cast<CXXRecordDecl>(Reader.GetDecl(Record[Idx++]));
|
||||
assert(!RD->DefinitionData && "DefinitionData is already set!");
|
||||
InitializeCXXDefinitionData(RD, DefinitionDecl, Record, Idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3297,3 +3297,32 @@ void ASTWriter::MacroDefinitionRead(serialization::MacroID ID,
|
|||
MacroDefinition *MD) {
|
||||
MacroDefinitions[MD] = ID;
|
||||
}
|
||||
|
||||
void ASTWriter::CompletedTagDefinition(const TagDecl *D) {
|
||||
assert(D->isDefinition());
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
|
||||
// We are interested when a PCH decl is modified.
|
||||
if (RD->getPCHLevel() > 0) {
|
||||
// A forward reference was mutated into a definition. Rewrite it.
|
||||
// FIXME: This happens during template instantiation, should we
|
||||
// have created a new definition decl instead ?
|
||||
DeclsToRewrite.insert(RD);
|
||||
}
|
||||
|
||||
for (CXXRecordDecl::redecl_iterator
|
||||
I = RD->redecls_begin(), E = RD->redecls_end(); I != E; ++I) {
|
||||
CXXRecordDecl *Redecl = cast<CXXRecordDecl>(*I);
|
||||
if (Redecl == RD)
|
||||
continue;
|
||||
|
||||
// We are interested when a PCH decl is modified.
|
||||
if (Redecl->getPCHLevel() > 0) {
|
||||
UpdateRecord &Record = DeclUpdates[Redecl];
|
||||
Record.push_back(UPD_CXX_SET_DEFINITIONDATA);
|
||||
assert(Redecl->DefinitionData);
|
||||
assert(Redecl->DefinitionData->Definition == D);
|
||||
AddDeclRef(D, Record); // the DefinitionDecl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
// RUN: %clang_cc1 -x c++-header -emit-pch -o %t1 %s
|
||||
// RUN: %clang_cc1 -x c++-header -emit-pch -o %t2 %s -include-pch %t1 -chained-pch
|
||||
// RUN: %clang_cc1 -fsyntax-only -verify -include-pch %t2 %s
|
||||
// XFAIL: *
|
||||
|
||||
#ifndef HEADER1
|
||||
#define HEADER1
|
||||
|
|
Загрузка…
Ссылка в новой задаче