Properly implement pointer types
- special DCD pointer symbols are actually inserted now - they are implicitly dereferenced (max 1 deref) for member access - index accessing them yields proper types (one pointer removed) - they return standard type properties on pointer pointers
This commit is contained in:
parent
795ea87f80
commit
690d6254db
|
@ -40,6 +40,11 @@ TTree!(DSymbol*, SymbolsAllocator, true, "a < b") classSymbols;
|
|||
*/
|
||||
TTree!(DSymbol*, SymbolsAllocator, true, "a < b") enumSymbols;
|
||||
|
||||
/**
|
||||
* Pointer properties (when not implicitly dereferencing)
|
||||
*/
|
||||
TTree!(DSymbol*, SymbolsAllocator, true, "a < b") pointerSymbols;
|
||||
|
||||
/**
|
||||
* Variadic template parameters properties
|
||||
*/
|
||||
|
@ -191,6 +196,12 @@ static this()
|
|||
aggregateSymbols.insert(stringof_);
|
||||
aggregateSymbols.insert(init);
|
||||
|
||||
pointerSymbols.insert(mangleof_);
|
||||
pointerSymbols.insert(alignof_);
|
||||
pointerSymbols.insert(sizeof_);
|
||||
pointerSymbols.insert(stringof_);
|
||||
pointerSymbols.insert(init);
|
||||
|
||||
classSymbols.insert(makeSymbol("classinfo", CompletionKind.variableName));
|
||||
classSymbols.insert(tupleof);
|
||||
classSymbols.insert(makeSymbol("__vptr", CompletionKind.variableName));
|
||||
|
@ -283,6 +294,7 @@ static ~this()
|
|||
destroy(aggregateSymbols);
|
||||
destroy(classSymbols);
|
||||
destroy(enumSymbols);
|
||||
destroy(pointerSymbols);
|
||||
|
||||
foreach (sym; symbolsMadeHere[])
|
||||
destroy(*sym);
|
||||
|
|
|
@ -1129,9 +1129,7 @@ private:
|
|||
|
||||
foreach (suffix; type.typeSuffixes)
|
||||
{
|
||||
if (suffix.star != tok!"")
|
||||
continue;
|
||||
else if (suffix.type)
|
||||
if (suffix.type)
|
||||
lookup.breadcrumbs.insert(ASSOC_ARRAY_SYMBOL_NAME);
|
||||
else if (suffix.array)
|
||||
lookup.breadcrumbs.insert(ARRAY_SYMBOL_NAME);
|
||||
|
|
|
@ -180,29 +180,30 @@ do
|
|||
while (!lookup.breadcrumbs.empty)
|
||||
{
|
||||
auto back = lookup.breadcrumbs.back;
|
||||
immutable bool isArr = back == ARRAY_SYMBOL_NAME;
|
||||
immutable bool isAssoc = back == ASSOC_ARRAY_SYMBOL_NAME;
|
||||
immutable bool isFunction = back == FUNCTION_SYMBOL_NAME;
|
||||
if (back == POINTER_SYMBOL_NAME)
|
||||
{
|
||||
lastSuffix.isPointer = true;
|
||||
lookup.breadcrumbs.popBack();
|
||||
continue;
|
||||
}
|
||||
if (!isArr && !isAssoc && !isFunction)
|
||||
break;
|
||||
immutable qualifier = isAssoc ? SymbolQualifier.assocArray
|
||||
: (isFunction ? SymbolQualifier.func : SymbolQualifier.array);
|
||||
SymbolQualifier qualifier;
|
||||
if (back == ARRAY_SYMBOL_NAME) qualifier = SymbolQualifier.array;
|
||||
else if (back == ASSOC_ARRAY_SYMBOL_NAME) qualifier = SymbolQualifier.assocArray;
|
||||
else if (back == FUNCTION_SYMBOL_NAME) qualifier = SymbolQualifier.func;
|
||||
else if (back == POINTER_SYMBOL_NAME) qualifier = SymbolQualifier.pointer;
|
||||
else break;
|
||||
|
||||
lastSuffix = GCAllocator.instance.make!DSymbol(back, CompletionKind.dummy, lastSuffix);
|
||||
lastSuffix.qualifier = qualifier;
|
||||
lastSuffix.ownType = true;
|
||||
if (isFunction)
|
||||
|
||||
final switch (qualifier)
|
||||
{
|
||||
case SymbolQualifier.none:
|
||||
case SymbolQualifier.selectiveImport:
|
||||
assert(false, "this should never be generated");
|
||||
case SymbolQualifier.func:
|
||||
lookup.breadcrumbs.popBack();
|
||||
lastSuffix.callTip = lookup.breadcrumbs.back();
|
||||
break;
|
||||
case SymbolQualifier.array: lastSuffix.addChildren(arraySymbols[], false); break;
|
||||
case SymbolQualifier.assocArray: lastSuffix.addChildren(assocArraySymbols[], false); break;
|
||||
case SymbolQualifier.pointer: lastSuffix.addChildren(pointerSymbols[], false); break;
|
||||
}
|
||||
else
|
||||
lastSuffix.addChildren(isArr ? arraySymbols[] : assocArraySymbols[], false);
|
||||
|
||||
if (suffix is null)
|
||||
suffix = lastSuffix;
|
||||
|
@ -454,9 +455,10 @@ void resolveTypeFromInitializer(DSymbol* symbol, TypeLookup* lookup,
|
|||
if (currentSymbol is null)
|
||||
return;
|
||||
|
||||
// Index expressions can be an array index or an AA index
|
||||
// Index expressions can be on a pointer, an array or an AA
|
||||
if (currentSymbol.qualifier == SymbolQualifier.array
|
||||
|| currentSymbol.qualifier == SymbolQualifier.assocArray
|
||||
|| currentSymbol.qualifier == SymbolQualifier.pointer
|
||||
|| currentSymbol.kind == CompletionKind.aliasName)
|
||||
{
|
||||
if (currentSymbol.type !is null)
|
||||
|
|
|
@ -131,6 +131,8 @@ enum SymbolQualifier : ubyte
|
|||
func,
|
||||
/// Selective import
|
||||
selectiveImport,
|
||||
/// The symbol is a pointer
|
||||
pointer,
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -228,6 +230,11 @@ struct DSymbol
|
|||
return;
|
||||
visited.insert(cast(size_t) &this);
|
||||
|
||||
// pointers are implicitly dereferenced on members (a single layer)
|
||||
if (qualifier == SymbolQualifier.pointer
|
||||
&& this.type.qualifier != SymbolQualifier.pointer)
|
||||
return type.getParts!OR(name, app, visited, onlyOne);
|
||||
|
||||
if (name is null)
|
||||
{
|
||||
foreach (part; parts[].filter!(a => a.name != IMPORT_SYMBOL_NAME))
|
||||
|
@ -427,10 +434,14 @@ struct DSymbol
|
|||
// dfmt off
|
||||
mixin(bitfields!(bool, "ownType", 1,
|
||||
bool, "skipOver", 1,
|
||||
bool, "isPointer", 1,
|
||||
ubyte, "", 5));
|
||||
ubyte, "", 6));
|
||||
// dfmt on
|
||||
|
||||
deprecated bool isPointer()
|
||||
{
|
||||
return qualifier == SymbolQualifier.pointer;
|
||||
}
|
||||
|
||||
/// Protection level for this symbol
|
||||
IdType protection;
|
||||
|
||||
|
|
|
@ -381,7 +381,8 @@ DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
|||
case tok!"[":
|
||||
if (symbols.length == 0)
|
||||
break loop;
|
||||
if (symbols[0].qualifier == SymbolQualifier.array)
|
||||
if (symbols[0].qualifier == SymbolQualifier.array
|
||||
|| symbols[0].qualifier == SymbolQualifier.pointer)
|
||||
{
|
||||
skip(tok!"[", tok!"]");
|
||||
if (!isSliceExpression(tokens, i))
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
identifiers
|
||||
alignof k
|
||||
init k
|
||||
mangleof k
|
||||
member v int member stdin 16 int
|
||||
sizeof k
|
||||
stringof k
|
||||
tupleof k
|
||||
identifiers
|
||||
alignof k
|
||||
init k
|
||||
mangleof k
|
||||
member v int member stdin 16 int
|
||||
sizeof k
|
||||
stringof k
|
||||
tupleof k
|
||||
identifiers
|
||||
alignof k
|
||||
init k
|
||||
mangleof k
|
||||
sizeof k
|
||||
stringof k
|
||||
identifiers
|
||||
alignof k
|
||||
init k
|
||||
mangleof k
|
||||
member v int member stdin 16 int
|
||||
sizeof k
|
||||
stringof k
|
||||
tupleof k
|
|
@ -0,0 +1,28 @@
|
|||
struct S
|
||||
{
|
||||
int member;
|
||||
}
|
||||
|
||||
void test()
|
||||
{
|
||||
S itemA;
|
||||
itemA.
|
||||
}
|
||||
|
||||
void test2()
|
||||
{
|
||||
S* itemPtr = &itemA;
|
||||
itemPtr.
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
S** itemPtrPtr = &itemA;
|
||||
itemPtrPtr.
|
||||
}
|
||||
|
||||
void test3()
|
||||
{
|
||||
S** itemPtrPtr = &itemA;
|
||||
itemPtrPtr[10].
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
set -e
|
||||
set -u
|
||||
|
||||
../../bin/dcd-client $1 file.d -x -c58 > actual1.txt
|
||||
../../bin/dcd-client $1 file.d -x -c108 >> actual1.txt
|
||||
../../bin/dcd-client $1 file.d -x -c165 >> actual1.txt
|
||||
../../bin/dcd-client $1 file.d -x -c226 >> actual1.txt
|
||||
diff actual1.txt expected1.txt --strip-trailing-cr
|
Loading…
Reference in New Issue