@@ -433,7 +433,6 @@ namespace clang {
433
433
Decl *From, DeclContext *&ToDC, DeclContext *&ToLexicalDC);
434
434
Error ImportImplicitMethods (const CXXRecordDecl *From, CXXRecordDecl *To);
435
435
436
- Error ImportFieldDeclDefinition (const FieldDecl *From, const FieldDecl *To);
437
436
Expected<CXXCastPath> ImportCastPath (CastExpr *E);
438
437
Expected<APValue> ImportAPValue (const APValue &FromValue);
439
438
@@ -1851,33 +1850,52 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1851
1850
// different values in two distinct translation units.
1852
1851
ChildErrorHandlingStrategy HandleChildErrors (FromDC);
1853
1852
1854
- auto MightNeedReordering = [](const Decl *D) {
1855
- return isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<FriendDecl>(D);
1856
- };
1857
-
1858
- // Import everything that might need reordering first.
1859
1853
Error ChildErrors = Error::success ();
1860
1854
for (auto *From : FromDC->decls ()) {
1861
- if (!MightNeedReordering (From))
1862
- continue ;
1863
-
1864
1855
ExpectedDecl ImportedOrErr = import (From);
1865
1856
1866
1857
// If we are in the process of ImportDefinition(...) for a RecordDecl we
1867
1858
// want to make sure that we are also completing each FieldDecl. There
1868
1859
// are currently cases where this does not happen and this is correctness
1869
1860
// fix since operations such as code generation will expect this to be so.
1870
- if (!ImportedOrErr) {
1861
+ if (ImportedOrErr) {
1862
+ FieldDecl *FieldFrom = dyn_cast_or_null<FieldDecl>(From);
1863
+ Decl *ImportedDecl = *ImportedOrErr;
1864
+ FieldDecl *FieldTo = dyn_cast_or_null<FieldDecl>(ImportedDecl);
1865
+ if (FieldFrom && FieldTo) {
1866
+ RecordDecl *FromRecordDecl = nullptr ;
1867
+ RecordDecl *ToRecordDecl = nullptr ;
1868
+ // If we have a field that is an ArrayType we need to check if the array
1869
+ // element is a RecordDecl and if so we need to import the definition.
1870
+ if (FieldFrom->getType ()->isArrayType ()) {
1871
+ // getBaseElementTypeUnsafe(...) handles multi-dimensonal arrays for us.
1872
+ FromRecordDecl = FieldFrom->getType ()->getBaseElementTypeUnsafe ()->getAsRecordDecl ();
1873
+ ToRecordDecl = FieldTo->getType ()->getBaseElementTypeUnsafe ()->getAsRecordDecl ();
1874
+ }
1875
+
1876
+ if (!FromRecordDecl || !ToRecordDecl) {
1877
+ const RecordType *RecordFrom =
1878
+ FieldFrom->getType ()->getAs <RecordType>();
1879
+ const RecordType *RecordTo = FieldTo->getType ()->getAs <RecordType>();
1880
+
1881
+ if (RecordFrom && RecordTo) {
1882
+ FromRecordDecl = RecordFrom->getDecl ();
1883
+ ToRecordDecl = RecordTo->getDecl ();
1884
+ }
1885
+ }
1886
+
1887
+ if (FromRecordDecl && ToRecordDecl) {
1888
+ if (FromRecordDecl->isCompleteDefinition () &&
1889
+ !ToRecordDecl->isCompleteDefinition ()) {
1890
+ Error Err = ImportDefinition (FromRecordDecl, ToRecordDecl);
1891
+ HandleChildErrors.handleChildImportResult (ChildErrors,
1892
+ std::move (Err));
1893
+ }
1894
+ }
1895
+ }
1896
+ } else {
1871
1897
HandleChildErrors.handleChildImportResult (ChildErrors,
1872
1898
ImportedOrErr.takeError ());
1873
- continue ;
1874
- }
1875
- FieldDecl *FieldFrom = dyn_cast_or_null<FieldDecl>(From);
1876
- Decl *ImportedDecl = *ImportedOrErr;
1877
- FieldDecl *FieldTo = dyn_cast_or_null<FieldDecl>(ImportedDecl);
1878
- if (FieldFrom && FieldTo) {
1879
- Error Err = ImportFieldDeclDefinition (FieldFrom, FieldTo);
1880
- HandleChildErrors.handleChildImportResult (ChildErrors, std::move (Err));
1881
1899
}
1882
1900
}
1883
1901
@@ -1892,7 +1910,7 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1892
1910
// During the import of `a` we import first the dependencies in sequence,
1893
1911
// thus the order would be `c`, `b`, `a`. We will get the normal order by
1894
1912
// first removing the already imported members and then adding them in the
1895
- // order as they appear in the "from" context.
1913
+ // order as they apper in the "from" context.
1896
1914
//
1897
1915
// Keeping field order is vital because it determines structure layout.
1898
1916
//
@@ -1904,6 +1922,9 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1904
1922
// interface in LLDB is implemented by the means of the ASTImporter. However,
1905
1923
// calling an import at this point would result in an uncontrolled import, we
1906
1924
// must avoid that.
1925
+ const auto *FromRD = dyn_cast<RecordDecl>(FromDC);
1926
+ if (!FromRD)
1927
+ return ChildErrors;
1907
1928
1908
1929
auto ToDCOrErr = Importer.ImportContext (FromDC);
1909
1930
if (!ToDCOrErr) {
@@ -1914,70 +1935,26 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1914
1935
DeclContext *ToDC = *ToDCOrErr;
1915
1936
// Remove all declarations, which may be in wrong order in the
1916
1937
// lexical DeclContext and then add them in the proper order.
1917
- for (auto *D : FromDC->decls ()) {
1918
- if (!MightNeedReordering (D))
1919
- continue ;
1920
-
1921
- assert (D && " DC contains a null decl" );
1922
- if (Decl *ToD = Importer.GetAlreadyImportedOrNull (D)) {
1938
+ for (auto *D : FromRD->decls ()) {
1939
+ if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || isa<FriendDecl>(D)) {
1940
+ assert (D && " DC contains a null decl" );
1941
+ Decl *ToD = Importer.GetAlreadyImportedOrNull (D);
1923
1942
// Remove only the decls which we successfully imported.
1924
- assert (ToDC == ToD->getLexicalDeclContext () && ToDC->containsDecl (ToD));
1925
- // Remove the decl from its wrong place in the linked list.
1926
- ToDC->removeDecl (ToD);
1927
- // Add the decl to the end of the linked list.
1928
- // This time it will be at the proper place because the enclosing for
1929
- // loop iterates in the original (good) order of the decls.
1930
- ToDC->addDeclInternal (ToD);
1943
+ if (ToD) {
1944
+ assert (ToDC == ToD->getLexicalDeclContext () && ToDC->containsDecl (ToD));
1945
+ // Remove the decl from its wrong place in the linked list.
1946
+ ToDC->removeDecl (ToD);
1947
+ // Add the decl to the end of the linked list.
1948
+ // This time it will be at the proper place because the enclosing for
1949
+ // loop iterates in the original (good) order of the decls.
1950
+ ToDC->addDeclInternal (ToD);
1951
+ }
1931
1952
}
1932
1953
}
1933
1954
1934
- // Import everything else.
1935
- for (auto *From : FromDC->decls ()) {
1936
- if (MightNeedReordering (From))
1937
- continue ;
1938
-
1939
- ExpectedDecl ImportedOrErr = import (From);
1940
- if (!ImportedOrErr)
1941
- HandleChildErrors.handleChildImportResult (ChildErrors,
1942
- ImportedOrErr.takeError ());
1943
- }
1944
-
1945
1955
return ChildErrors;
1946
1956
}
1947
1957
1948
- Error ASTNodeImporter::ImportFieldDeclDefinition (const FieldDecl *From,
1949
- const FieldDecl *To) {
1950
- RecordDecl *FromRecordDecl = nullptr ;
1951
- RecordDecl *ToRecordDecl = nullptr ;
1952
- // If we have a field that is an ArrayType we need to check if the array
1953
- // element is a RecordDecl and if so we need to import the definition.
1954
- QualType FromType = From->getType ();
1955
- QualType ToType = To->getType ();
1956
- if (FromType->isArrayType ()) {
1957
- // getBaseElementTypeUnsafe(...) handles multi-dimensonal arrays for us.
1958
- FromRecordDecl = FromType->getBaseElementTypeUnsafe ()->getAsRecordDecl ();
1959
- ToRecordDecl = ToType->getBaseElementTypeUnsafe ()->getAsRecordDecl ();
1960
- }
1961
-
1962
- if (!FromRecordDecl || !ToRecordDecl) {
1963
- const RecordType *RecordFrom = FromType->getAs <RecordType>();
1964
- const RecordType *RecordTo = ToType->getAs <RecordType>();
1965
-
1966
- if (RecordFrom && RecordTo) {
1967
- FromRecordDecl = RecordFrom->getDecl ();
1968
- ToRecordDecl = RecordTo->getDecl ();
1969
- }
1970
- }
1971
-
1972
- if (FromRecordDecl && ToRecordDecl) {
1973
- if (FromRecordDecl->isCompleteDefinition () &&
1974
- !ToRecordDecl->isCompleteDefinition ())
1975
- return ImportDefinition (FromRecordDecl, ToRecordDecl);
1976
- }
1977
-
1978
- return Error::success ();
1979
- }
1980
-
1981
1958
Error ASTNodeImporter::ImportDeclContext (
1982
1959
Decl *FromD, DeclContext *&ToDC, DeclContext *&ToLexicalDC) {
1983
1960
auto ToDCOrErr = Importer.ImportContext (FromD->getDeclContext ());
0 commit comments