You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A major source of headaches and probably the source ldc-developers#1 of mapping failures for sophisticated C++ libraries has been the restrictions of D template instantiation scope. Those restrictions are totally necessary and work great in D, and Clang adding "sugar" to its types made it possible to comply with them... most of the time.
One particular wall was hit while trying to map the MSVC standard library. For type_traits's conjunction<_Is_character<char>, _Is_character<char>>, the base class in Clang's AST is:
TemplateSpecializationType 0xdfaed30 '_Conjunction<struct std::_Is_character<char>, struct std::_Is_character<char> >' sugar _Conjunction
| -TemplateArgument type 'struct std::_Is_character<char>':'struct std::_Is_character<char>'
| SubstTemplateTypeParmType 0xdda9f20 'struct std::_Is_character<char>' sugar
| -TemplateTypeParmType 0xa7ce0f0 '_Traits' dependent contains_unexpanded_pack depth 0 index 0 pack
| `-TemplateTypeParm 0xa7ce0c0 '_Traits'
`-RecordType 0xa9079d0 'struct std::_Is_character<char>'
`-ClassTemplateSpecialization 0xa907930 '_Is_character'
| -TemplateArgument type 'struct std::_Is_character<char>' : 'struct std::_Is_character<char>'
| SubstTemplateTypeParmType 0xdda9f20 'struct std::_Is_character<char>' sugar (...same as above....)
`-RecordType 0xdfaed10 'struct std::_Conjunction<struct std::_Is_character<char>, struct std::_Is_character<char> >'
`-ClassTemplateSpecialization 0xdfaec78 '_Conjunction'
This is one of those rare cases where Clang has lost pack information and no simple/good heuristic to guess when two or more arguments come from the same pack appears to be possible. Hence either Clang needs to be modified to preserve pack info, or a complicated check/heuristic is needed, or we've got to stop trying to stick to DMD's way.
The third option was chosen because there's actually no good reason to comply with those restrictions. Reflection doesn't get improved, and while instantiation from C++ modules, every referenced symbol is from C++ modules.
So from now on:
- Every type gets desugared before being mapped in non-dependent contexts.
- C++ modules now have access to the "C++ global namespace" during name lookups, through a special type of global import.
This allows to discard the C++ symbol collector and substitution complicated hack when mapping template arguments deduced by Sema.
Copy file name to clipboardExpand all lines: dmd2/cpp/cppdeclaration.h
-2Lines changed: 0 additions & 2 deletions
Original file line number
Diff line number
Diff line change
@@ -208,7 +208,6 @@ class DeclReferencer : public clang::RecursiveASTVisitor<DeclReferencer>
208
208
DeclReferencer() : expmap(mapper)
209
209
{
210
210
mapper.addImplicitDecls = false;
211
-
mapper.cppPrefix = false;
212
211
}
213
212
214
213
voidTraverse(Loc loc, Scope *sc, clang::Stmt *S);
@@ -221,7 +220,6 @@ class DeclReferencer : public clang::RecursiveASTVisitor<DeclReferencer>
221
220
};
222
221
223
222
extern DeclReferencer declReferencer;
224
-
Scope *globalScope(::Module *m);
225
223
226
224
const clang::Decl *getCanonicalDecl(const clang::Decl *D); // the only difference with D->getCanonicalDecl() is that if the canonical decl is an out-of-ilne friend' decl and the actual decl is declared, this returns the latter instead of the former
if (/*!interpret || */SNTTP->isValueDependent()) // NOTE/FIXME(?): this doesn't work with packs, which get added n times if they have n elements, and Clang doesn't store pack info in the SNTTP
482
-
e = fromExpressionNonTypeTemplateParm(loc,
483
-
SNTTP->getParameter());
481
+
if (SNTTP->isValueDependent())
482
+
e = fromExpressionNonTypeTemplateParm(loc, SNTTP->getParameter());
0 commit comments