mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 21:21:48 +03:00
66 lines
1.6 KiB
D
66 lines
1.6 KiB
D
module parser.linkage_location;
|
|
|
|
import dmd.frontend : parseModule, initDMD, deinitializeDMD;
|
|
import dmd.attrib : CPPMangleDeclaration, CPPNamespaceDeclaration, LinkDeclaration;
|
|
import dmd.location;
|
|
import dmd.visitor : SemanticTimeTransitiveVisitor;
|
|
|
|
extern (C++) static class LinkVisitor : SemanticTimeTransitiveVisitor
|
|
{
|
|
alias visit = typeof(super).visit;
|
|
Loc[] locs;
|
|
|
|
override void visit(CPPMangleDeclaration md)
|
|
{
|
|
locs ~= md.loc;
|
|
}
|
|
|
|
override void visit(CPPNamespaceDeclaration nd)
|
|
{
|
|
locs ~= nd.loc;
|
|
|
|
if (nd.decl.length)
|
|
{
|
|
CPPNamespaceDeclaration next = cast(CPPNamespaceDeclaration)nd.decl.pop();
|
|
next.accept(this);
|
|
}
|
|
}
|
|
|
|
override void visit(LinkDeclaration ld)
|
|
{
|
|
locs ~= ld.loc;
|
|
}
|
|
}
|
|
|
|
void testLocs(string src, int[2][] lineCols...)
|
|
{
|
|
initDMD();
|
|
|
|
auto t = parseModule("test.d", src);
|
|
|
|
scope visitor = new LinkVisitor;
|
|
t.module_.accept(visitor);
|
|
|
|
// import std; writeln(visitor.locs.map!SourceLoc);
|
|
|
|
assert(visitor.locs.length == lineCols.length);
|
|
foreach (i, lineCol; lineCols)
|
|
{
|
|
assert(visitor.locs[i].linnum == lineCol[0]);
|
|
assert(visitor.locs[i].charnum == lineCol[1]);
|
|
}
|
|
|
|
deinitializeDMD();
|
|
}
|
|
|
|
unittest
|
|
{
|
|
testLocs("extern (C++, class) struct C {}", [1, 1]);
|
|
testLocs(`extern (C++, "name"~"space") {}`, [1, 1]);
|
|
|
|
testLocs(" extern(C++) int a;", [1, 13]);
|
|
testLocs("alias t = extern(C++) void f();", [1, 11]);
|
|
|
|
testLocs(`extern (C++, "ns1", "ns2", "ns3") {}`, [1, 1], [1, 1], [1, 1]);
|
|
testLocs("extern (C++, 'ns1')\n extern(C++, 'ns2') {}", [1, 1], [2, 3]);
|
|
}
|