forked from OSchip/llvm-project
Teach the ASTImporter to cope with cases where we have already
imported a forward declaration, but later the full definition of the same entity becomes available. When this happens, import the definition. llvm-svn: 136537
This commit is contained in:
parent
92eac7f501
commit
d451ea9ca9
|
@ -83,10 +83,14 @@ namespace {
|
||||||
bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
|
bool ImportDeclParts(NamedDecl *D, DeclContext *&DC,
|
||||||
DeclContext *&LexicalDC, DeclarationName &Name,
|
DeclContext *&LexicalDC, DeclarationName &Name,
|
||||||
SourceLocation &Loc);
|
SourceLocation &Loc);
|
||||||
|
void ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD = 0);
|
||||||
void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
|
void ImportDeclarationNameLoc(const DeclarationNameInfo &From,
|
||||||
DeclarationNameInfo& To);
|
DeclarationNameInfo& To);
|
||||||
void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
|
void ImportDeclContext(DeclContext *FromDC, bool ForceImport = false);
|
||||||
bool ImportDefinition(RecordDecl *From, RecordDecl *To, bool ForceImport = false);
|
bool ImportDefinition(RecordDecl *From, RecordDecl *To,
|
||||||
|
bool ForceImport = false);
|
||||||
|
bool ImportDefinition(EnumDecl *From, EnumDecl *To,
|
||||||
|
bool ForceImport = false);
|
||||||
TemplateParameterList *ImportTemplateParameterList(
|
TemplateParameterList *ImportTemplateParameterList(
|
||||||
TemplateParameterList *Params);
|
TemplateParameterList *Params);
|
||||||
TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
|
TemplateArgument ImportTemplateArgument(const TemplateArgument &From);
|
||||||
|
@ -1731,6 +1735,35 @@ bool ASTNodeImporter::ImportDeclParts(NamedDecl *D, DeclContext *&DC,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ASTNodeImporter::ImportDefinitionIfNeeded(Decl *FromD, Decl *ToD) {
|
||||||
|
if (!FromD)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!ToD) {
|
||||||
|
ToD = Importer.Import(FromD);
|
||||||
|
if (!ToD)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RecordDecl *FromRecord = dyn_cast<RecordDecl>(FromD)) {
|
||||||
|
if (RecordDecl *ToRecord = cast_or_null<RecordDecl>(ToD)) {
|
||||||
|
if (FromRecord->getDefinition() && !ToRecord->getDefinition()) {
|
||||||
|
ImportDefinition(FromRecord, ToRecord);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (EnumDecl *FromEnum = dyn_cast<EnumDecl>(FromD)) {
|
||||||
|
if (EnumDecl *ToEnum = cast_or_null<EnumDecl>(ToD)) {
|
||||||
|
if (FromEnum->getDefinition() && !ToEnum->getDefinition()) {
|
||||||
|
ImportDefinition(FromEnum, ToEnum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
|
ASTNodeImporter::ImportDeclarationNameLoc(const DeclarationNameInfo &From,
|
||||||
DeclarationNameInfo& To) {
|
DeclarationNameInfo& To) {
|
||||||
|
@ -1778,8 +1811,9 @@ void ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
|
||||||
Importer.Import(*From);
|
Importer.Import(*From);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, bool ForceImport) {
|
bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To,
|
||||||
if (To->getDefinition())
|
bool ForceImport) {
|
||||||
|
if (To->getDefinition() || To->isBeingDefined())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
To->startDefinition();
|
To->startDefinition();
|
||||||
|
@ -1801,7 +1835,10 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, bool Fo
|
||||||
SourceLocation EllipsisLoc;
|
SourceLocation EllipsisLoc;
|
||||||
if (Base1->isPackExpansion())
|
if (Base1->isPackExpansion())
|
||||||
EllipsisLoc = Importer.Import(Base1->getEllipsisLoc());
|
EllipsisLoc = Importer.Import(Base1->getEllipsisLoc());
|
||||||
|
|
||||||
|
// Ensure that we have a definition for the base.
|
||||||
|
ImportDefinitionIfNeeded(Base1->getType()->getAsCXXRecordDecl());
|
||||||
|
|
||||||
Bases.push_back(
|
Bases.push_back(
|
||||||
new (Importer.getToContext())
|
new (Importer.getToContext())
|
||||||
CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
|
CXXBaseSpecifier(Importer.Import(Base1->getSourceRange()),
|
||||||
|
@ -1820,6 +1857,31 @@ bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, bool Fo
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ASTNodeImporter::ImportDefinition(EnumDecl *From, EnumDecl *To,
|
||||||
|
bool ForceImport) {
|
||||||
|
if (To->getDefinition() || To->isBeingDefined())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
To->startDefinition();
|
||||||
|
|
||||||
|
QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(From));
|
||||||
|
if (T.isNull())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
QualType ToPromotionType = Importer.Import(From->getPromotionType());
|
||||||
|
if (ToPromotionType.isNull())
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ImportDeclContext(From, ForceImport);
|
||||||
|
|
||||||
|
// FIXME: we might need to merge the number of positive or negative bits
|
||||||
|
// if the enumerator lists don't match.
|
||||||
|
To->completeDefinition(T, ToPromotionType,
|
||||||
|
From->getNumPositiveBits(),
|
||||||
|
From->getNumNegativeBits());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
|
TemplateParameterList *ASTNodeImporter::ImportTemplateParameterList(
|
||||||
TemplateParameterList *Params) {
|
TemplateParameterList *Params) {
|
||||||
SmallVector<NamedDecl *, 4> ToParams;
|
SmallVector<NamedDecl *, 4> ToParams;
|
||||||
|
@ -2154,25 +2216,9 @@ Decl *ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
|
||||||
D2->setIntegerType(ToIntegerType);
|
D2->setIntegerType(ToIntegerType);
|
||||||
|
|
||||||
// Import the definition
|
// Import the definition
|
||||||
if (D->isDefinition()) {
|
if (D->isDefinition() && ImportDefinition(D, D2))
|
||||||
QualType T = Importer.Import(Importer.getFromContext().getTypeDeclType(D));
|
return 0;
|
||||||
if (T.isNull())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
QualType ToPromotionType = Importer.Import(D->getPromotionType());
|
|
||||||
if (ToPromotionType.isNull())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
D2->startDefinition();
|
|
||||||
ImportDeclContext(D);
|
|
||||||
|
|
||||||
// FIXME: we might need to merge the number of positive or negative bits
|
|
||||||
// if the enumerator lists don't match.
|
|
||||||
D2->completeDefinition(T, ToPromotionType,
|
|
||||||
D->getNumPositiveBits(),
|
|
||||||
D->getNumNegativeBits());
|
|
||||||
}
|
|
||||||
|
|
||||||
return D2;
|
return D2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4021,13 +4067,17 @@ Decl *ASTImporter::Import(Decl *FromD) {
|
||||||
if (!FromD)
|
if (!FromD)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
ASTNodeImporter Importer(*this);
|
||||||
|
|
||||||
// Check whether we've already imported this declaration.
|
// Check whether we've already imported this declaration.
|
||||||
llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
|
llvm::DenseMap<Decl *, Decl *>::iterator Pos = ImportedDecls.find(FromD);
|
||||||
if (Pos != ImportedDecls.end())
|
if (Pos != ImportedDecls.end()) {
|
||||||
return Pos->second;
|
Decl *ToD = Pos->second;
|
||||||
|
Importer.ImportDefinitionIfNeeded(FromD, ToD);
|
||||||
|
return ToD;
|
||||||
|
}
|
||||||
|
|
||||||
// Import the type
|
// Import the type
|
||||||
ASTNodeImporter Importer(*this);
|
|
||||||
Decl *ToD = Importer.Visit(FromD);
|
Decl *ToD = Importer.Visit(FromD);
|
||||||
if (!ToD)
|
if (!ToD)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -4311,7 +4361,15 @@ void ASTImporter::ImportDefinition(Decl *From) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (EnumDecl *ToEnum = dyn_cast<EnumDecl>(To)) {
|
||||||
|
if (!ToEnum->getDefinition()) {
|
||||||
|
Importer.ImportDefinition(cast<EnumDecl>(FromDC), ToEnum,
|
||||||
|
/*ForceImport=*/true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Importer.ImportDeclContext(FromDC, true);
|
Importer.ImportDeclContext(FromDC, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue