@@ -433,6 +433,7 @@ 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);
436
437
Expected<CXXCastPath> ImportCastPath (CastExpr *E);
437
438
Expected<APValue> ImportAPValue (const APValue &FromValue);
438
439
@@ -1850,52 +1851,33 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1850
1851
// different values in two distinct translation units.
1851
1852
ChildErrorHandlingStrategy HandleChildErrors (FromDC);
1852
1853
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.
1853
1859
Error ChildErrors = Error::success ();
1854
1860
for (auto *From : FromDC->decls ()) {
1861
+ if (!MightNeedReordering (From))
1862
+ continue ;
1863
+
1855
1864
ExpectedDecl ImportedOrErr = import (From);
1856
1865
1857
1866
// If we are in the process of ImportDefinition(...) for a RecordDecl we
1858
1867
// want to make sure that we are also completing each FieldDecl. There
1859
1868
// are currently cases where this does not happen and this is correctness
1860
1869
// fix since operations such as code generation will expect this to be so.
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 {
1870
+ if (!ImportedOrErr) {
1897
1871
HandleChildErrors.handleChildImportResult (ChildErrors,
1898
1872
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));
1899
1881
}
1900
1882
}
1901
1883
@@ -1910,7 +1892,7 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1910
1892
// During the import of `a` we import first the dependencies in sequence,
1911
1893
// thus the order would be `c`, `b`, `a`. We will get the normal order by
1912
1894
// first removing the already imported members and then adding them in the
1913
- // order as they apper in the "from" context.
1895
+ // order as they appear in the "from" context.
1914
1896
//
1915
1897
// Keeping field order is vital because it determines structure layout.
1916
1898
//
@@ -1922,9 +1904,6 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1922
1904
// interface in LLDB is implemented by the means of the ASTImporter. However,
1923
1905
// calling an import at this point would result in an uncontrolled import, we
1924
1906
// must avoid that.
1925
- const auto *FromRD = dyn_cast<RecordDecl>(FromDC);
1926
- if (!FromRD)
1927
- return ChildErrors;
1928
1907
1929
1908
auto ToDCOrErr = Importer.ImportContext (FromDC);
1930
1909
if (!ToDCOrErr) {
@@ -1935,26 +1914,70 @@ ASTNodeImporter::ImportDeclContext(DeclContext *FromDC, bool ForceImport) {
1935
1914
DeclContext *ToDC = *ToDCOrErr;
1936
1915
// Remove all declarations, which may be in wrong order in the
1937
1916
// lexical DeclContext and then add them in the proper order.
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);
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)) {
1942
1923
// Remove only the decls which we successfully imported.
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
- }
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);
1952
1931
}
1953
1932
}
1954
1933
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
+
1955
1945
return ChildErrors;
1956
1946
}
1957
1947
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
+
1958
1981
Error ASTNodeImporter::ImportDeclContext (
1959
1982
Decl *FromD, DeclContext *&ToDC, DeclContext *&ToLexicalDC) {
1960
1983
auto ToDCOrErr = Importer.ImportContext (FromD->getDeclContext ());
0 commit comments